Program abort and dlopen()
Bill Moseley
moseley@hank.org
Mon Jun 3 11:15:00 GMT 2002
Hello,
I'm looking for clues. I hope someone here can help. If this is the wrong
list, please feel free to tell me where to go. ;)
My primary question is: does libstdc++ call dlopen() during an exception,
or does it call any functions that might cause dlopen() to be called?
My secondary question is: how do I debug this problem?
Some basics:
- I'm running Debian Woody with some Sid
- gcc version 2.95.4 20011002 (Debian prerelease)
- glibc 2.2.5.
- libstdc++2.10
- My debugging skills are poor.
- (thus...) I've been debugging this, off and on, for weeks ;)
I have a Perl module that is a simple xs (C code) interface to the aspell
library. The aspell library is c++ code.
Aspell attempts to open an optional config file. On "file not found" it
throws an exception which is caught and ignored. This is normal behavior
and works fine.
When perl runs my module with "make test" the exception is thrown, the
exception's constructor is run to completion, but the program aborts before
the catch block executes.
But, it doesn't always abort -- it depends on how it's run from perl.
Perl sets a environment variable PERL_DL_NONLAZY=1 when running "make
test". If I run the test code without setting PERL_DL_NONLAZY "make test"
runs fine.
PERL_DL_NONLAZY sets the flag RTLD_NOW on dlopen() calls. At face value,
it would seem that aspell is throwing an exception, then (perhaps??)
libstdc++ is calling dlopen() and failing since RTLD_NOW is enabled.
I'd expect RTLD_NOW to be set every time dlopen() is called, but it doesn't
look that way from these tests:
Perl has a standard module called Dynaloader. It is used to load binary
perl extensions (such as my module) into perl at runtime. Dynaloader uses
PERL_DL_NONLAZY to set the RTLD_NOW flag when calling dlopen() to load the
module.
The Dynaloader code looks basically like:
mode = RTLD_LAZY;
if (dl_nonlazy)
mode = RTLD_NOW;
...
handle = dlopen(filename, mode);
If I comment out:
// if (dl_nonlazy)
// mode = RTLD_NOW;
The program no longer aborts. Again, the program is NOT aborting in that
code (Dynaloader), it's aborting after the exception is thrown while in the
aspell library code, way after Dynaloader runs.
If I hack up Dynaloader like:
mode = RTLD_NOW;
mode2 = RTLD_LAZY;
handle = dlopen(filename, mode) ;
handle = dlopen(filename, mode2 );
the program does not abort.
<wild guess>
To me, that implies that RTLD_NOW is sticky, and that later when some other
code (while Aspell is running) calls dlopen() for a library where all
symbols are not resolved that it returns false and the program aborts.
The other option is that dlopen() has some side effect due to the RTLD_NOW
flag that is causing the problem.
</wild guess>
So, I'm stuck at this point. I just don't have the skills or understanding
to debug this farther. Any suggestions are very much appreciated.
Back traces from gdb don't show enough detail. And if I single step from a
breakpoint in the exception constructor I don't see anything of interest,
either.
I've downloaded glibc 2.2.5 source and installed locally. I thought that
might help with tracing in gdb. But it seems now like I need libstdc++,
too. I do have the debugging version from Debian, but I don't have the
source. But it seems like I'd need to install gcc 3.0x to get the source.
Clearly, I'm stabbing in the dark at this point.
The other thing that's hard about this problem is that on other platforms
the problem doesn't exist. It's lucky, really, that on Debian I can change
the behavior of the problem with PERL_DL_NONLAZY.
It works fine one SuSE 6.2 with
gcc version 2.95.3 20010315 (release)
libc.so.6
libstdc++.so.2.9
libstdc++-2-libc6.1-1-2.9.0.so
(not sure the difference between those two)
It works fine on Solaris 2.6
gcc version 2.95.1 19990816 (release)
And on BSD 4.5 it always fails, regardless of PERL_DL_NONLAZY, and in the
same place as on Debian.
gcc version 2.95.3 20010315 (release) [FreeBSD]
/usr/lib/libstdc++.so.3
/usr/lib/libc.so.4
So, what can I do next?
Thanks very much,
--
Bill Moseley
mailto:moseley@hank.org
More information about the Libstdc++
mailing list