ATTN: g++ maintainer: Using string instances to pass arguments to dlls
Hello, I noticed the following problem while porting an internal C++ application from linux to Cygwin. If a std::string instance created in one module (exe or dll) is passed to another say as an argument of a function call, the program crashes or hangs. I did debug for a while and it turned out that it is not the program itself that causes the crash - the cause lies in the std::string implementation, the fact that libstdc++ is provided as a static archive and that it is compiled without _GLIBCXX_FULLY_DYNAMIC_STRING defined. What happens is that each module which links agains libstdc++ get its very personal copy of the class member _S_empty_rep_storage. Now since _GLIBCXX_FULLY_DYNAMIC_STRING is not defined an empty string instance i.e. one that is created by the default constructor of std::string gets a pointer to _S_empty_rep_storage i.e. the actual allocation of memory is delayed until memory is really needed. If _GLIBCXX_FULLY_DYNAMIC_STRING is defined each string instance would get a pointer to a newly heap allocated block of memory instead . Now look at the ouput of gdb and nm used on the attached testcase: [EMAIL PROTECTED] ~/src/testcase/tc $ nm dll.dll | grep _S_empty_rep_storage 1000c030 d .data$_ZNSs4_Rep20_S_empty_rep_storageE 1000c030 D __ZNSs4_Rep20_S_empty_rep_storageE [EMAIL PROTECTED] ~/src/testcase/tc $ nm main.exe | grep _S_empty_rep_storage 00442120 d .data$_ZNSs4_Rep20_S_empty_rep_storageE 00442120 D __ZNSs4_Rep20_S_empty_rep_storageE === Breakpoint 1, main (argc=1, argv=0x10042980) at main.cc:9 9 { (gdb) n 10string s, s1; (gdb) 12export1 (s); (gdb) print s $1 = {static npos = 4294967295, _M_dataplus = {> = {> = {}, }, _M_p = 0x44212c ""}} (gdb) print s1 $2 = {static npos = 4294967295, _M_dataplus = {> = {> = {}, }, _M_p = 0x44212c ""}} === Here the two strings share _S_empty_rep_storage. === (gdb) step export1 ([EMAIL PROTECTED]) at dll.cc:7 7 string s1; (gdb) n 9 s1.push_back ('A'); (gdb) n 10s.push_back ('A'); (gdb) print s $3 = (string &) @0x22eea0: {static npos = 4294967295, _M_dataplus = {> = {> = {}, }, _M_p = 0x44212c ""}} (gdb) print s1 $4 = {static npos = 4294967295, _M_dataplus = {> = {> = {}, }, _M_p = 0x10042aec "A"}} (gdb) === Here s1 points to the dll local _S_empty_rep_storage. The _M_p member of _M_dataplus is pointing to different copies of _S_empty_rep_storage - one stored in the executable which calls the dll and another one in the dll itself. Now the second push_back() call in export1 () will end up calling _M_mutate() to actually allocate storage. _M_mutate() will call _M_rep()->_M_dispose() which will end up free()-ing the memory reserved for _S_empty_rep_storage in the main exe. There is a check to prevent free()-ing _S_empty_rep_storage: #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING if (__builtin_expect(this != &_S_empty_rep(), false)) #endif ... but it doesn't work well in the case when a string instance created in one module is passed to another and libstdc++ is statically linked because of the fact that each module has its own copy _S_empty_rep_storage. Can we get this fixed ? dllstr.tar.bz2 Description: Binary data -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
Pavel Tsekov wrote: Can we get this fixed ? I entered a bugreport: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24196 Gerrit -- =^..^= -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
Does fixing this bug require upstream intervention, or can you just develop a patch, and submit it to upstream? Anecdotal evidence [1] exists that this issue may be what prevents compiling a working version of octave 2.1.71 with gcc 3.4.4. This comes from John Ewing (octave upstream), who states that he is able to compile a working version with gcc 3.4.4 only if it is statically linked. John also wonders [2] why libstdc++ is static as opposed to shared on cygwin. I have searched the archives, and verified its static nature, but was unable to find an explanation. [1] http://www.octave.org/mailing-lists/help-octave/2005/3734 [2] http://www.octave.org/mailing-lists/help-octave/2005/3738 jrp -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
James R. Phillips wrote: John also wonders [2] why libstdc++ is static as opposed to shared on cygwin. I have searched the archives, and verified its static nature, but was unable to find an explanation. [1] http://www.octave.org/mailing-lists/help-octave/2005/3734 [2] http://www.octave.org/mailing-lists/help-octave/2005/3738 IIRC this is what mathematicians call a "hard problem". :-) gcc is fully autotoolized: it uses autoconf, automake, and libtool when building. However, you really only get decent cygwin support for DLLs from libtool of 1.5.x series or better. BUT, this requires at least automake-1.7.x or better, which in turn requires autoconf-2.5x or better. Until "recently" (circa last 18 months or so), gcc used MUCH older versions of these tools: autoconf-2.13, automake???, and (worst of all) a privately hacked version of libtool-1.4.x. However, over the last year or more, several dedicated people have been slowly moving gcc's build system over to more modern autotools. I do not know if that process is complete, but it is a necessary (but not sufficient) step for building the runtime libraries as DLLs under cygwin. There has been sporadic interest in correcting this problem, and convincing gcc to build dll runtimes under cygwin, but: (1) as I said, this is a "hard" problem (2) and it hasn't been very pressing issue: C doesn't have this problem; only C++, Fortran, (maybe others) need additional runtime libs other than cygwin1.dll -- and C is the 800 lb gorilla of open source software. C++, Fortran, etc, are often afterthoughts unfortunately (except in specialized fields like hardcore numerics). FWIW, Nicholas Wourms has expresses recent interest on this list in trying to resolve this issue (and IIRC he was active with the gcc team ~18 months ago, and has just recently 'returned'). Nick? -- Chuck -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
On Tue, 4 Oct 2005, James R. Phillips wrote: > Does fixing this bug require upstream intervention, or can you just develop a > patch, and submit it to upstream? If it is only the std::string implementation that uses the described optimization the problem can be worked around by just rebuilding libstdc++ with _GLIBCXX_FULLY_DYNAMIC_STRING defined. If other classes provided by libstdc++ use similiar techniques the best solution would be to get libstdc++ built as shared library which according to Charles Wilson is unfortunately a "hard problem" :( I'll try to rebuild libstdc++ now with _GLIBCXX_FULLY_DYNAMIC_STRING defined and will report back if there is interest. I would like to help to get this issue resolved. -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
James R. Phillips wrote: Does fixing this bug require upstream intervention, or can you just develop a patch, and submit it to upstream? A patch would be nice! Anecdotal evidence [1] exists that this issue may be what prevents compiling a working version of octave 2.1.71 with gcc 3.4.4. This comes from John Ewing (octave upstream), who states that he is able to compile a working version with gcc 3.4.4 only if it is statically linked. John also wonders [2] why libstdc++ is static as opposed to shared on cygwin. I have searched the archives, and verified its static nature, but was unable to find an explanation. [1] http://www.octave.org/mailing-lists/help-octave/2005/3734 [2] http://www.octave.org/mailing-lists/help-octave/2005/3738 As long as GCC does not support recent libtool versions it is not easy to build dynamic libraries. Gerrit -- =^..^= -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
Pavel Tsekov wrote: On Tue, 4 Oct 2005, James R. Phillips wrote: Does fixing this bug require upstream intervention, or can you just develop a patch, and submit it to upstream? If it is only the std::string implementation that uses the described optimization the problem can be worked around by just rebuilding libstdc++ with _GLIBCXX_FULLY_DYNAMIC_STRING defined. If other classes provided by libstdc++ use similiar techniques the best solution would be to get libstdc++ built as shared library which according to Charles Wilson is unfortunately a "hard problem" :( I'll try to rebuild libstdc++ now with _GLIBCXX_FULLY_DYNAMIC_STRING defined and will report back if there is interest. I would like to help to get this issue resolved. Yes, much appreciated. Please CC me when you report back! Gerrit -- =^..^= -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
On Wed, 5 Oct 2005, Gerrit P. Haase wrote: > Pavel Tsekov wrote: > > > I'll try to rebuild libstdc++ now with _GLIBCXX_FULLY_DYNAMIC_STRING > > defined and will report back if there is interest. I would like to help > > to get this issue resolved. > > Yes, much appreciated. Please CC me when you report back! I rebuilt libstdc++ with --enable-fully-dynamic-string and preliminary testing showed that both the testcase and the program that I am porting behave fine. I'll do more testing in the next few days. I haven't done any benchmarks so far. Any suggestions/ideas on how to test whether the speed has decreased due to --enable-fully-dynamic-string ? -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
Pavel Tsekov wrote: On Wed, 5 Oct 2005, Gerrit P. Haase wrote: Pavel Tsekov wrote: I'll try to rebuild libstdc++ now with _GLIBCXX_FULLY_DYNAMIC_STRING defined and will report back if there is interest. I would like to help to get this issue resolved. Yes, much appreciated. Please CC me when you report back! I rebuilt libstdc++ with --enable-fully-dynamic-string and preliminary testing showed that both the testcase and the program that I am porting behave fine. I'll do more testing in the next few days. I haven't done any benchmarks so far. Any suggestions/ideas on how to test whether the speed has decreased due to --enable-fully-dynamic-string ? Maybe you find some more hints at: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16612 I will probably use the flag to rebuild gcc with this changed libstdc++, regardless if there is a performance issue or not. Gerrit -- =^..^= -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
On Thu, 6 Oct 2005, Gerrit P. Haase wrote: > I will probably use the flag to rebuild gcc with this changed libstdc++, > regardless if there is a performance issue or not. What about Danny Smith's suggestion ? http://www.cygwin.com/ml/cygwin/2005-10/msg00080.html -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Gerrit P. Haase wrote: > As long as GCC does not support recent libtool versions it is not easy > to build dynamic libraries. What about just replacing the autogenerated libtool script with a newer one (manually hacked if necessary for options) after configure? GNOME 1.4 has similar problems, and that's how I've managed to work around it; but then again building gcc is *much* more complicated. Yaakov -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.1 (Cygwin) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFDRZQzpiWmPGlmQSMRAikvAJwKVd/qmNvhIEftgey8rsdXGKfXMACg/TpB JFfJFTN6F4lq+D+qrVHR4ts= =B0cn -END PGP SIGNATURE- -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: ATTN: g++ maintainer: Using string instances to pass arguments to dlls
Yaakov S (Cygwin Ports) wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Gerrit P. Haase wrote: As long as GCC does not support recent libtool versions it is not easy to build dynamic libraries. What about just replacing the autogenerated libtool script with a newer one (manually hacked if necessary for options) after configure? GNOME 1.4 has similar problems, and that's how I've managed to work around it; but then again building gcc is *much* more complicated. Unfortunately this doesn't work very good with GCC. Gerrit -- =^..^= -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/