On linux, the default for egcs is to have vtable-thunks on. However, there are known bugs with the vtable-thunks and egcs. The problem causes code that uses virtual inheritance to segfault at run time. Fresco, TargetJr, and the IUE all suffer from this bug. There may be other packages as well, and it is very difficult to debug. Since it is the default for linux, all of the std libraries like libstdc++ are all compiled with -fvtable-thunks as well. To get programs to work, you have to re-compile with -fno-vtable-thunks, you also have to re-compile all the standard libraries. There should be an RPM with egcs built with -fno-vtable-thunks. -Bill Hoffman This is from the egcs bugs list: >>>>> Lee Iverson <leei.com> writes: > The following code fails to execute properly unless -fno-vtable-thunks > is used with egcs-1.1.1 on linux. Is this a known problem? Yep. It will be fixed in the ABI overhaul, whenever that is. Jason
I have done some more work on this and would like to add the following plea for help: From: Rick Lerner <rick> To: iue-help, mrs, hjl.mit.edu, egcs-bugs.com, leei.com, hoffman.com Subject: Error with vtable thunks in EGCS under Linux Date: Wed, 10 Feb 1999 14:17:43 -0500 This message describes my unsuccessful attempts to work around the vtable-thunks bug in EGCS v1.1.1 on Linux (RedHat 5.1). This is a very serious bug for us any anyone considering using virtual inheritance, EGCS, and Linux. In summary, -fvtable-thunks are known to be broken, and it seems impossible to use -fno-vtable-thunks under Linux. Does anyone have any idea how to get code to compile with -fno-vtable-thunks on Linux? Thanks in advance, Rick ---------- Rick Lerner, Ph.D. 20 Industrial Drive East Senior Principal Software Engineer Northampton, MA 01060 Amerinex Applied Imaging (413) 582-9600 rick EGCS v1.1.1 on Linux sets -fvtable-thunks by default. Unfortunately, the generated thunks are incorrect when using virtual dispatch from a virtual base class. To avoid this problem, we tried to compile our application libraries with -fno-vtable-thunks. This fixed the virtual dispatch problem, but we now get a segmentation fault during a delete of an ofstream as shown in the following program: ---------------------------------------------------------------------- foo.cc ---------------------------------------------------------------------- // segfaults at delete if compiled with: // c++ -fno-vtable-thunks -o foo foo.cc #include <fstream.h> int main () { char *fileName = "foo.txt"; ostream* strm; strm = new ofstream(fileName); delete strm; return 0; } ---------------------------------------------------------------------- I first tried to recompile the EGCS release with -fno-vtable-thunks as the default. I made the following changes: config/mt-linux: change -fvtable-thunks to -fno-vtable-thunks gcc/config/linux.h: replace #define DEFAULT_VTABLE_THUNKS 1 with #define DEFAULT_VTABLE_THUNKS 0 After rebuilding EGCS from scratch: mkdir /usr/gnu/Linux2/egcs-1.1.1 cd /usr/gnu/Linux2/egcs-1.1.1 /usr/gnu/src/egcs-1.1.1/configure --prefix=/usr/gnu make bootstrap make install I was unable to link the above program because stdstrbufs.o contained the following undefined symbol, which is still using thunk naming conventions: nm stdstrbufs.o | grep vt U __vt_7filebuf nm filebuf.o | grep vt U _vt.7filebuf nm streambuf.o | grep vt | grep filebuf 00000000 R _vt.7filebuf I traced this back to the fact that libio under Linux uses /usr/include/_G_config.h rather than one created within EGCS. Specifically, the file libio/config/linux.mt contains the following lines: ---------------------------------------------------------------------- # Use the libio which comes with the local libc. # Comment this out to avoid including the stdio functions in libiostream.a: # LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS) # LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list # LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list` # Comment the above and uncomment the below to use the code in the Linux libc: # We have _G_config.h in /usr/include. _G_CONFIG_H= # We must not see the libio.h file from this library. LIBIO_INCLUDE= ---------------------------------------------------------------------- I then hacked the asm statement in stdstrbufs.C to use the proper non-thunk symbol. This resulted in a segfault as shown in the following backtrace: (gdb) bt #0 0x4006666d in __libc_free (mem=0x80545c0) at malloc.c:2866 #1 0x8051241 in __builtin_delete (ptr=0x80545c0) #2 0x804de56 in streambuf::~streambuf (this=0x80545c0, __in_chrg=-1) at /usr/gnu/src/egcs-1.1.1/libio/streambuf.cc:224 #3 0x804ec61 in filebuf::~filebuf (this=0x80545c0, __in_chrg=-1) at /usr/gnu/src/egcs-1.1.1/libio/filebuf.cc:76 #4 0x40063da0 in __overflow (f=0x80545c0, ch=-1) at genops.c:162 #5 0x40063ae7 in _IO_file_xsputn (f=0x80545c0, data=0x8052e6b, n=4) at fileops.c:681 #6 0x804eea4 in filebuf::xsputn (this=0x80545c0, s=0x8052e6b "mid ", n=4) at /usr/gnu/src/egcs-1.1.1/libio/filebuf.cc:205 #7 0x804bd7b in ostream::operator<< (this=0x80546c0, s=0x8052e6b "mid ") at /usr/gnu/src/egcs-1.1.1/libio/iostream.cc:784 #8 0x804a235 in mid::mid (this=0x8058508, __in_chrg=0) at fred.cc:37 #9 0x804a2b5 in leaf::leaf (this=0x8058508, __in_chrg=1) at fred.cc:44 #10 0x804a35a in main () at fred.cc:50 I then attempted to have EGCS use its own _G_config.h and stdio files by swapping the commented sections in libio/config/linux.mt. This had two ill-effects, first the libio makefile did not find a rule to make stdio.list and the generated _G_config.h file used the undefined type sigset_t. At this point I gave up and commented out the offending "delete strm" statement from my program. The following program demonstrates the vtable-thunk bug. ---------------------------------------------------------------------- fred.cc ---------------------------------------------------------------------- // compile this file with c++ -fvtable-thunks -o fred fred.cc // note the different values of this in the last call to doit. // In a larger program all but the first call to doit exhibit // the erroneous behavior. #include <iostream.h> class super { public: virtual void doit(const char*) =0; }; class top : virtual public super { public: virtual void doit(const char*); }; class mid : public top { public: mid(); }; class leaf : public mid { public: leaf(); int i; }; void top::doit(const char* msg) { cout << "top::doit (from " << msg << ")- \tthis: " << this << endl; } mid::mid() { cout << "mid- \t\t\t\t\tthis: " << this << endl; top::doit("mid top::doit"); doit("mid doit"); this->doit("mid this->doit"); top* hackptr = this; cout << "mid- \t\t\t\t\thackptr: " << hackptr << endl; hackptr->doit("mid hackptr->doit"); // <<<<<******** incorrectly adjusts "this" by size of leaf } leaf::leaf() { cout << "leaf- \t\t\t\t\tthis: " << this << endl; } int main () { leaf* l = new leaf(); return 0; }
Cristian, here is the output from his sample program under egcs 1.1.2, so it is still a problem: [pbrown@pip pbrown]$ c++ -fvtable-thunks -o fred fred.cc [pbrown@pip pbrown]$ ./fred mid- this: 0x804a280 top::doit (from mid top::doit)- this: 0x804a280 top::doit (from mid doit)- this: 0x804a280 top::doit (from mid this->doit)- this: 0x804a280 mid- hackptr: 0x804a280 top::doit (from mid hackptr->doit)- this: 0x804a284 leaf- this: 0x804a280 Are we going to be able to do anything about this for 6.0 time? ------- Email Received From "William A. Hoffman" <hoffman.ge.com> 03/30/99 11:09 -------
It should be easy enough to make egcs not use vtable thunks on linux. In fact linux is the ONLY place where egcs uses vtable thunks. The problem for me is that since the vtable thunks stuff is compiled into libio, which is used by linux system libc. I would have to recompile ALL of the linux application on my machine to not use it. For a new version of linux it would be a great idea to get rid of this. Although it does bring up an interesting problem. If I did want to use vtable-thunks in the future, I would not be able to. Is there some way to separate libio for linux from libstdc++ ? -Bill
This is way too late to change now for the next release. Hopefully we will be able to get the compiler problems fixed in time. ------- Email Received From "William A. Hoffman" <hoffman.ge.com> 03/30/99 12:08 -------
Are you still seeing this bug with egcs-1.1.2-12 (distributed with 6.0)? Reopen this bug if you are still seeing these problems.