Boost logo

Boost :

From: Raoul Gough (RaoulGough_at_[hidden])
Date: 2002-04-28 11:42:39


Executive summary:

0. boost::thread doesn't work under cygwin/mingw
1. The libgcc.a supplied with cygwin gcc isn't thread-enabled.
2. I managed to fix this by patching libgcc.a and specs
3. test_thread then got a SEGV in on_thread_exit (in list::push_front)
4. In threadmon.obj, DllMain is getting name-mangled
5. I added extern "C" to the definition of DllMain in threadmon.cpp
6. test_thread now runs to completion with "no errors detected"

further details follow

From: "William E. Kempf" <williamkempf_at_[hidden]>
> From: "Raoul Gough" <RaoulGough_at_[hidden]>
> > I've just managed to compile and link the release 1_27_0 boost threads
> > library with gcc -mno-cygwin option under cygwin (i.e. mingw32) but
> > test_thread crashes during exit from the function condition_test_thread.
I
> > had to fiddle a bit to get the boost libraries to compile and link, so I
> > assume this is not a widely used platform (cygwin in mingw mode, boost
> > 1_27_0 and STLport-4.5.3).
>
> Actually, I do compile with this, so I'm a little surprised that you had
to
> make any changes to get it compiling. Well, to be precise, I compile with
> the mingw compiler not the cygwin compiler, but I wouldn't expect there'd
be
> any differences here. So, I'd be interested in hearing what changes you
had
> to make and why.

The cygwin-supplied gcc needs to be kicked into submission by using
the -mno-cygwin flag. Doing this then requires an alternate STL, since the
cygnus-supplied binaries all use the Unix-API emulation. I ended up with the
following:

actions mingw-Link-action bind NEEDLIBS
{
    $(MINGW_BIN_DIRECTORY)g++ -mno-cygwin -mthreads $(IMPLIB_COMMAND)$(<[2])
$(LINKFLAGS) -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)"
"$(NEEDLIBS)" -l$(FINDLIBS) -Wl,-rpath-link,. -lstlport_mingw32_mt_debug
}

actions mingw-C++-action
{

$(MINGW_BIN_DIRECTORY)g++ -c -Wall -ftemplate-depth-100 -U$(UNDEFS) -D$(DEFI
NES) -mno-cygwin -fvtable-thunks -mthreads -D_STLP_USE_DYNAMIC_LIB -I
f:/stlport/STLport-4.5.3/stlport -I f:/Python21/include $(CFLAGS)
$(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)"
}

I use the STLport library as a DLL built with "thunks" to allow COM and
DirectX stuff to work (and, of course, this has to be consistent throughout
an executable). Obviously, you could do this other ways, but -mno-cygwin and
some kind of replacement STL are required.

>
> That said, though I compile with this compiler I've yet to get the bugs
> worked out. There are a few issues that I'm having problems diagnosing
and
> fixing, since I'm not a gcc user. The gdb output and other means of
> diagnosing the problems have yet to enlighten me to the errors. If you've
> got experience with these tools and can help to fix the bugs I'd be much
> appreciative.
>
> > ;; Some kind of exception handler context stuff (?)
> > lea 0x4(%ebx),%edx
> > mov (%edx),%eax
> > add $0x4,%eax
> > mov (%eax),%edx
> > mov (%edx),%ecx ;; <--- SEGV here, $edx is 0
> > mov %ecx,(%eax)
[snip]
>
> I could be wrong, but this sounds like it's caused by not including
> the -mthreads command option while compiling/linking. This was a problem
in
> the gcc-tools.jam at the time of release of Boost 1_27_0. I believe this
> has been fixed in the current CVS snapshot, so I might suggest checking
out
> the latest stuff from CVS before attempting to debug any problems.

The thread-safe bits in libgcc.a are missing in cygwin, so it doesn't have
a per-thread exception handling context. I had a look into the gcc-2.95.3
sources (from SuSE Linux), and the gcc library code includes a function
eh_context_specific, but only if it is compiled on a platform with gcc
thread support. This function is most definitely missing from my libgcc.a
(file _eh.o). Looks like the frame.o object is also different dependant on
multi-thread support.

After poking around on the web for a bit, I've discovered that this problem
arose in earlier versions of gcc on Windows. Mumit Khan provided the
necessary support at some stage (around 1999, I think), but it obviously
didn't make it into the cygwin release of gcc. Using the mingw gcc binary
release, I created a new libgcc_hybrid.a which includes the mingw
thread-enabled _eh.o and frame.o. I then updated
/cygwin/lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs as follows:

*libgcc:
%{mno-cygwin: %{mthreads:-lmingwthrd} -lmingw32 -lgcc_hybrid}
%{!mno-cygwin:-lgcc} %{mno-cygwin:-lmoldname -lmsvcrt}

This is probably a very reckless sort of thing to do, but it seems to work
so far.

>
> > Before I spend too long chasing this, has anybody else seen anything
> similar
> > to this? Is anybody using the threads library with mingw and cygwin? I
got
> > pretty much exactly the same crash in my own test code as well.
>
> Nobody is using it (unless they're either using pthreads-win32 or have
fixed
> the bugs with out reporting to me). But I'm very interested in getting
> things to work for this compiler.

Hopefully you were just seeing the same problem caused by DllMain having the
wrong name and not being called. I spent a long time fooling around in the
debugger before I realised that DllMain actually wasn't *ever* being called
(I still don't know how to get gdb to breakpoint during Dll loading).
Anyway, eventually objdump -t threadmon.obj revealed the problem, and simply
adding extern "C" to DllMain in threadmon.cpp does the trick.

Regards,
Raoul Gough.

_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk