views:

461

answers:

1

Yesterday, I got bit by a rather annoying crash when using DLLs compiled with GCC under Cygwin. Basically, as soon as you run with a debugger, you may end up landing in a debugging trap caused by RtlFreeHeap() receiving an address to something it did not allocate.

This is a known bug with GCC 3.4 on Cygwin. The situation arises because the libstdc++ library includes a "clever" optimization for empty strings. I spare you the details (see the references throughout this post), but whenever you allocate memory in one DLL for an std::string object that "belongs" to another DLL, you end up giving one heap a chunk to free that came from another heap. Hence the SIGTRAP in RtlFreeHeap().

There are other problems reported when exceptions are thrown across DLL boundaries.

This makes GCC 3.4 on Windows an unacceptable solution as soon as your project is based on DLLs and the STL. I have a few options to move past this option, many of which are very time-consuming and/or annoying:

I cannot (yet) switch to another compiler either, because of some other tools I'm using. The comments I find from some GCC people is that "it's almost never reported, so it's probably not a problem", which annoys me even more.

Does anyone have some news about this? I can't find any clear announcement that this has been fixed (the bug is still marked as "assigned"), except one comment on the GNU Radio bug tracker.

Thanks!

+1  A: 

The general problem you're running into is that C++ was never really meant as a component language. It was really designed to be used to create complete standalone applications. Things like shared libraries and other such mechanisms were created by vendors on their own. Think of this example: suppose you created a C++ component that returns a C++ object. How is the C++ component know that it will be used by a C++ caller? And if the caller is a C++ application, why not just use the library directly?

Of course, the above information doesn't really help you.

Instead, I would create the shared libraries/DLLs such that you follow a couple of rules:

  1. Any object created by a component is also destroyed by the same component.
  2. A component can be safely unloaded when all of its created objects are destroyed.

You may have to create additional APIs in your component to ensure these rules, but by following these rules, it will ensure that problems like the one described won't happen.

Tommy Hui
Oh, how i wish i had that insight one time about fifteen years ago, when i was trying to use C++ as a component-making language!
DarenW
@Tommy: I'm not actually trying to use C++ as a component language, I just want to split up my project into separate DLLs to reduce compilation and link times for development. GCC 3 is my vendor here, and it's not doing it's job, because it creates broken DLLs on Windows.
Carl Seleborg
@Carl: If there is anything more than a single binary application, then there is a component. A DLL (Dynamic Link Library) is a component, similar to a Shared Object on Linux. Whether you realize it or not, this is a component.
Tommy Hui