Bugs item #1229226, was opened at 2005-06-29 06:40
Message generated for change (Comment added) made by dannysmith
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1229226&group_id=2435
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: MinGW
>Group: IINR - Include In Next Release
>Status: Closed
>Resolution: Fixed
Priority: 5
Submitted By: Lubo Doleel (lubosdolezel)
Assigned to: Danny Smith (dannysmith)
Summary: Internal compiler error with gtkmm/treeviewcolumn.h
Initial Comment:
Hello,
I am trying to use GTKmm in a closed-source
cross-platform application.
Failure No 1:
MainWindow.cc: variable 'VTT for Gtk::TreeViewColumn'
can't be auto-imported. Please read the documentation
for ld's --enable-auto-import for details.
In order to avoid auto-import failed message with
TreeViewColumn, I've edited gtkmm's treeviewcolumn.h:
class TreeViewColumn : public Gtk::Object
-to-
class __declspec(dllimport) TreeViewColumn : public
Gtk::Object
But now I get internal compiler error:
/opt/xmingw/i386-mingw32msvc/include/gtkmm-2.4/gtkmm/treeviewcolumn.h:
In constructor
`Gtk::TreeViewColumn::TreeViewColumn(const
Glib::ustring&, const
Gtk::TreeModelColumn<ColumnType>&) [with
T_ModelColumnType = Glib::RefPtr<Gdk::Pixbuf>]':
/opt/xmingw/i386-mingw32msvc/include/gtkmm-2.4/gtkmm/treeviewcolumn.h:795:
internal compiler error: in rest_of_handle_final, at
toplev.c:2064
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://www.mingw.org/bugs.shtml> for instructions.
make: *** [win32/MainWindow.o] Error 1
It crashes both under win32 and under linux (cross
compilation on Gentoo), using latest stable MinGW.
The crashing code is something like this:
///// Header file of MainWindow class /////
class MainWindow : public MainWindow_glade
{
// ... other stuff
enum TreeItemType { TypeNone, TypeSettings, TypeServer,
TypeMachine, TypeMachineActual, TypeMachineHistory };
class TreeColumns : public Gtk::TreeModel::ColumnRecord
{
public:
TreeColumns()
{
add(m_icon);
add(m_strText);
add(m_type);
add(m_guidMajor);
add(m_guidMinor);
}
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > m_icon;
Gtk::TreeModelColumn<Glib::ustring> m_strText;
Gtk::TreeModelColumn<guid::GUID> m_guidMajor,
m_guidMinor;
Gtk::TreeModelColumn<TreeItemType> m_type;
} m_columns;
// ... other stuff
}
///// Crashing line in CPP file of MainWindow class /////
treeMain->append_column("", m_columns.m_icon);
/////
treeMain's declaration:
Gtk::TreeView * treeMain; //(generated by glademm)
It would be great if this bug is fixed. Any workaround
would be really appreciated too.
Thanks
----------------------------------------------------------------------
>Comment By: Danny Smith (dannysmith)
Date: 2005-10-19 11:17
Message:
Logged In: YES
user_id=11494
Fixed in GCC-4.1
Danny
----------------------------------------------------------------------
Comment By: Lubo Doleel (lubosdolezel)
Date: 2005-08-11 23:45
Message:
Logged In: YES
user_id=1090631
And I would appreciate a patch if it is already done so I
can re-emerge my cross compiler ;-)
----------------------------------------------------------------------
Comment By: Bob Jamison (ishmal)
Date: 2005-08-11 23:37
Message:
Logged In: YES
user_id=427063
I hate "me, too" posts, but "me, too." We build Inkscape
with Gtkmm, and we have been hitting several problems with
this class. One person's invocation of that class/template
can cause the ICE, while another person's code does not,
with no discernable difference in the pattern. The Gtkmm
guys have certainly designed an acid test for gcc on Win32.
;-) Yes, it would be very nice indeed if there were a
temporary copy of a tweaked cc1plus.exe somwhere. Thanks
muchly.
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-07-12 19:41
Message:
Logged In: YES
user_id=11494
Hello haleykd,
Hey, your testcase was just the ticket. The specific problem
in thatbtestcase was with template members, but it also gave
me an idea on how to fix vaguely-related bug (same ICE
message but different reason) with cloned constructors and
destructors.
I'll upload your testcase for archival purposes.
If you like I can upload a cc1plus.exe (or post privately) that
fixes the template member bug (and also the ctor/dtor bug)
for 3.4.4. The gcc-trunk problems turn out to be much easier
to fix (but harder to get sensible diagnostic output ), but I'm
still cleaning up the patch/testsuite additions for that before I
do a formal patch submission.
Again. thanks for your input.
Danny
----------------------------------------------------------------------
Comment By: lost-coder (haleykd)
Date: 2005-07-03 16:02
Message:
Logged In: YES
user_id=485500
Danny,
I finally got a test case for the ICE. Since I can't attach
it myself I'll mail it to you.
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-07-02 14:40
Message:
Logged In: YES
user_id=11494
haleykd wrote:
My thought was to make a, hopefully, simple change to the
heuristics so that if g++ emits a TI table for foo2 then it
also emits TI tables for all its base classes (foo). This
naturally chains up till there are no more bases.
That should already happen when those tables are needed by
the current translation unit. (unless told its not wanted by use
of a '#pragma interface').
Anyway, I still have not seen a testcase that reeproduces the
ICE reported by OP.
Danny
----------------------------------------------------------------------
Comment By: Earnie Boyd (earnie)
Date: 2005-07-02 13:43
Message:
Logged In: YES
user_id=15438
Try building a dll with the verbose mode of cl and you will
see that an import lib is created and then used to build the
dll. It is where I got the idea to create the import lib first.
I have a support request open that has an example you can
download and try. You'll find it here
http://sourceforge.net/tracker/index.php?func=detail&aid=1040825&group_id=2435&atid=202435.
Earnie
----------------------------------------------------------------------
Comment By: lost-coder (haleykd)
Date: 2005-07-02 09:10
Message:
Logged In: YES
user_id=485500
Danny,
My thought was to make a, hopefully, simple change to the
heuristics so that if g++ emits a TI table for foo2 then it
also emits TI tables for all its base classes (foo). This
naturally chains up till there are no more bases.
Earnie,
Lets see if I understand this. gettext has __declspec(?)
bar in some header. bar is defined in one file & used in
another. gettext won't link without an implib specifying
bar? That's a bug somewhere. It's no different from
exporting a function and using it in the same dll. Since
it's marked export when building gettext ld should treat it
like any other extern data.
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-07-02 08:20
Message:
Logged In: YES
user_id=11494
Earnie asked:
If an import liibrary is built from the non-archived objects
prior to building the dll and then using the import library
in the build of the dll would that help this issue?
No.
If you have to do that, something else is wrong with usage of
dllimport.
Danny
----------------------------------------------------------------------
Comment By: Earnie Boyd (earnie)
Date: 2005-07-02 02:08
Message:
Logged In: YES
user_id=15438
If an import liibrary is built from the non-archived objects
prior to building the dll and then using the import library
in the build of the dll would that help this issue?
I know that for instance the gettext package explicitly
specifies the dllimport for data objects. It also uses
those data objects within the dll itself. In order for the
dll to build I have to first create the import library from
the objects of the library with dlltool and then specify
that library to the linker for the resolutoin of the extern
dllimport references that are also exported from itself.
Earnie
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-07-01 20:41
Message:
Logged In: YES
user_id=11494
>Hmm, so g++ is creating a new TI table and putting it into
>the whatever (could be exe or another dll). Can't you just
>do that for all classes? How does g++ know when it needs to
>generate a TI table?
G++ uses heuristics (based upon published C++ ABI spec
for IA64) to determine when to emit vtables and typeinfo
tables.
Basically, if a polymorphic class has a "key method" (a non-
inline virtual method that is defined in *this translation unit)
then vtable and TI tables are emitted (with "vague" linkage, if
possible). The heuristics are designed to prevent code bloat,
but ensure that the artificial objects are always available when
needed..
These heuristics don't work all that well with dllimport. The
problem. in part, is that dllimport's live in a different symbol
space. __declspec (dllimport) int foo gets translated to:
extern int* _imp__foo;
int foo = *_imp__foo; // foo needs to be "constructed" at
runtime
Compounding this is the MSVC semantics which says that a
definition or redeclaration of a dllimport causes the dllimport
attribute to be lost.
So there can be real problem with something like this:
extern __declspec (dllimport) int foo;
int* z = &foo; // requires a "constructor" because of non-
constant address
// redeclaration and definition as a non-dllimport
int foo = 1;
int* x = &foo; // a simple initialization to a constant
Maybe that isn't the real issue, but I'm pre-occupied with it
now (when I'm not pre-occupied with feeding the children,
painting the house, beating the dog, etc) since it completely
breaks dllimport of C++ classes on gcc trunk at the moment.
> Couldn't ld detect and remove
> duplicate TI tables?
Yes, it can and does. On windows, it uses "linkonce"
section flag to achieve vague linkage. That's why the rule
of "always add a TI table for dllimported classes" works.
But if you don't specify __declspec(dllimport), g++ currently
just uses its usual heiristics.
Hmm, I see what your saying now...
#ifdef MULTIPLE_SYMBOL_SPACES
always_export_TI_tables() // regardless of dllimport
#else
use_normal_heuristics()
#endif
OK, I'll see where that leads.
That doesn't solve the problem of redeclarations, but it should
avoid the auto-import attempts to tell lies to the loader.
If I'm confusing you, I apologise. If you really want to be
confused try all this with export template<> class declspec
(__dllimport) std::ctype<char>;
Danny
----------------------------------------------------------------------
Comment By: lost-coder (haleykd)
Date: 2005-07-01 18:31
Message:
Logged In: YES
user_id=485500
I think you meant -Wl,--export-all ;) So export-all acts as
if __declspec(dllexport) were specified. However, g++ needs
__declspec(dllimport) in order to do the right thing when
linking to the dll.
Hmm, so g++ is creating a new TI table and putting it into
the whatever (could be exe or another dll). Can't you just
do that for all classes? How does g++ know when it needs to
generate a TI table? Couldn't ld detect and remove
duplicate TI tables?
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-07-01 09:24
Message:
Logged In: YES
user_id=11494
The follow testcase works for me, using:
g++ -shared -ofoo.dll dll.cc
g++ -omain.exe main.cc -L. foo.dll
It will fail if you try to use auto-import (ie, leave out the
__declspec (dllimport) in main.cc), and you will get this:
Info: resolving vtable for fooby linking to __imp___ZTV3foo
(auto-importC:\TEMP/ccaUbaaa.o:main.cc:
(.text$_ZN3fooC2Ev[foo::foo()]+0x4): variable 'vtable for foo'
can't be auto-imported. Please read the documentation for
ld's --enable-auto-import for details.
C:\TEMP/ccaUbaaa.o:main.cc:(.rdata$_ZTI4foo2[typeinfo for
foo2]+0x8): undefined reference to `typeinfo for foo)
It will compoile and link with no warnings with:
g++ -shared --export-all -ofoo.dll dll.cc
g++ -omain.exe main.cc -Wl,--enable-runtime-pseudo-reloc -
L. foo.dll
But will fail if you try to actually execute main.exe,
with "failure to initialize" OS error
typinfo tables are not exported/imported from the dll. Why
not? dllimports do not have a constant compile time
address. They are resolved indirectly by getprocaddress-like
magic at load-time or run-time. Since they do not have a
constant address, they cannot be used as initializers in TI
tables of derived classes.
eg the TI table for foo2 looks like this:
.globl __ZTI4foo2
.section .rdata$_ZTI4foo2,"dr"
.linkonce same_size
.align 4
__ZTI4foo2:
.long
__ZTVN10__cxxabiv120__si_class_type_infoE+8
.long __ZTS4foo2
.long __ZTI3foo <<< TI table for base class
Note that the TI tables are in .rdata sections. Auto-import
magic depends upon the linker being able to insert new
symbols that thunk to the import. We can't write into rdata
without the loader getting very upset (you get a a failue to
initialize OS error)
So what G++ does is that ensures that if a class is imported
from a dll, (as flagged by the dllimport attribute) the TI table
for that class is emitted as a link-once comdat symbol, so it
doesn't need to try to import it.
In the example testcase, this means that _ZTI3foo will be
emitted by main.cc.
If you're really interested, have a look in gcc sources in
gcc/cp/decl2.c
There is another way to get dllimports of virtual classes to
work, ie: Never import vtables either, but try to emit as link-
once comdat instead. That has drawbacks, namely it creates
huge problems for multiple inheritance.
Also we could change the rules and say, don't put constant
data into .rdata, but put in .text instead. It is possible to
make .text writeable, and that is what auto-import actually
does. I do not like the idea of getting rid of .rdata sections
just to allow the auto-import deceit to work.
Danny
=========================================
// dll.h
#ifndef EXPORT
#define EXPORT
#endif
class EXPORT foo
{
int i;
public:
foo(){};
virtual ~foo();
virtual void do_foo();
};
=========================================
// dll.cc
#define EXPORT __declspec (dllexport)
#include "dll.h"
foo::~foo()
{
++i;
}
void foo::do_foo()
{
++i;
}
============================================
// main.cc
#define EXPORT __declspec (dllimport)
#include "dll.h"
class foo2: public foo
{
public:
foo2(){};
~foo2(){};
};
int main()
{
foo2 f;
return 0;
}
----------------------------------------------------------------------
Comment By: lost-coder (haleykd)
Date: 2005-06-30 21:10
Message:
Logged In: YES
user_id=485500
If I could figure out how, I would post my original
test-case. Anyway here is the small change my test needed.
dll.h:
class foo
{
int i;
public:
foo(){};
virtual ~foo();
virtual void do_foo();
};
dll.cc:
foo::~foo()
{
++i;
}
void foo::do_foo()
{
++i;
}
The SF docs mention two view modes for trackers,
unfortunately I'm stuck in the one that can't attach files.
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-06-30 18:40
Message:
Logged In: YES
user_id=11494
Thanks haleykd,
I think you've simplified too much. If all the "exported"
methods are inline, then they won't be exported
I've attached three files from the g++.dg testsuite (as
dll_vtt.zip) The comments in the .C files should explain how
to to use.
Could you tweak these to show the bug.
Danny
----------------------------------------------------------------------
Comment By: lost-coder (haleykd)
Date: 2005-06-30 17:33
Message:
Logged In: YES
user_id=485500
I guess my comment wasn't clear enough. The template is a
red-herring. The problem is the VTT and vtable are not
exported. Since I can't seem to post a testcase I'll try to
describe it.
In DLL:
class foo
{
public:
foo(){};
virtual ~foo(){};
};
In main app:
class foo2: public foo
{
public:
foo2(){}
~foo2(){};
}
int main()
{
foo2 f;
reutrn 0;
}
That should produce the error. If not just add another
virtual function to foo.
----------------------------------------------------------------------
Comment By: Lubo Doleel (lubosdolezel)
Date: 2005-06-30 08:37
Message:
Logged In: YES
user_id=1090631
Here you are.
The problematic code is referenced in window1.ii
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-06-30 08:23
Message:
Logged In: YES
user_id=11494
I can't really use that testcase without downloading external
headers.
Could you please compile the offending module with -save-
temps flag and upload the preprocessed source (the .ii file)
That will provide a self-contained testcase.
Thanks
Danny
----------------------------------------------------------------------
Comment By: Lubo Doleel (lubosdolezel)
Date: 2005-06-29 23:55
Message:
Logged In: YES
user_id=1090631
I've created a very simple bug testcase. I am doing
cross-compiling "by hand" = custom makefiles and I currently
have no Windows available.
=>
No configure = hardcoded paths. So you'll have to edit the
makefile for your system.
----------------------------------------------------------------------
Comment By: Danny Smith (dannysmith)
Date: 2005-06-29 18:54
Message:
Logged In: YES
user_id=11494
A self-contained testcase would be much appreciated. These
types of errors with dllimport of classes are a real and
persistent prblem. On gcc-trunk they an even bigger prpblem
than in an earlier versions, becaise much of the optmization
is done earlier (at tree level rather than RTL), before class
members are actually marked as dllimport. I'm working on
apatch that fixes gcc-truunk, so would really like to see if I've
missed something.
halekd suggests that is is related to import of an instance of
a templated class. Can you provide a testcase?
Danny
----------------------------------------------------------------------
Comment By: lost-coder (haleykd)
Date: 2005-06-29 17:49
Message:
Logged In: YES
user_id=485500
The original problem is triggered by a templateized
constructor for TreeViewColumn. The actuall problem is not
being able to derive from a class that's in a dll.
To test, create a class in a dll with a virtual function.
Then try to create a derived class in the main executable.
----------------------------------------------------------------------
Comment By: Lubo Doleel (lubosdolezel)
Date: 2005-06-29 06:57
Message:
Logged In: YES
user_id=1090631
Version information:
Reading specs from
/opt/xmingw/lib/gcc/i386-mingw32msvc/3.4.2/specs
Configured with: ./configure --target=i386-mingw32msvc
--prefix=/opt/xmingw --enable-languages=c,c++,f77
--disable-shared --disable-nls --enable-threads --with-gcc
--with-gnu-ld --with-gnu-as --disable-win32-registry
--enable-sjlj-exceptions --without-x --without-newlib
--disable-debug
Thread model: win32
gcc version 3.4.2 (mingw-special)
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1229226&group_id=2435
|