This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [LONG] RF{C,D,A,H}: pe-x86 DLLs (shared libstdc++ and others) vs C++ RTTI vs LD


Dave Korn wrote:

> Adding "-Wl,--enable-auto-import" to the compile command line suppresses the
> warning and informational messages, but the compiled executable fails in the
> exact same way nonetheless.
> ...
> So, I think that having the typeinfo imported from the DLL rather than
> statically linked in a COMDAT section is likely to be the cause of the
> early pre-initialisation failure seen during the what-2.cc testcase shown
> above.

But when --e-a-i is specified the special .xa version of the linker
script is used instead of the default one, which casuses .rdata to be
put into .data making it writable.  And regardless of whether --e-a-i
was specified, the presence of an auto-import site in .text
automatically causes the linker to emit .text with write permission.  So
whatever the reason for the crash during process loading, it shouldn't
be due to trying to write to a readonly page -- if it is, then that's
the bug to fix.

Can you find out more detail of the STATUS_ACCESS_EXCEPTION?  In the
past I've used ollydbg for this as it makes it pretty easy to determine
the precise address that NTLDR was trying to modify at the time of the
fault, and from there you can figure out what section that corresponds
to.

> They both fail when trying to throw an object based on a string :-(

In both of these cases, the fault seems to be a NULL pointer dereference
in get_adjusted_ptr, at the line:

  if (catch_type->__do_catch (throw_type, &thrown_ptr, 1))

In both of your backtraces, catch_type is 0x409..., i.e. this is the
typeinfo object from the .text section of the executable that got
statically linked in from the import lib, not the typeinfo object in the
DLL.  The __do_catch method is a virtual method of std::type_info, and
it appears that in this second copy the vtable is never initialized
(rightfully, as the DLL has no idea of its existance), and thus the NULL
dereference.  I really think having multiple copies of the typeinfo is a
bad path to go down.

> linked into the application will have their own copies.  I think the RTTI
> system is able to handle this situation - that's why it has the options to
> perform typeid comparisons based on fully matching the type name strings
> rather than just comparing the name string pointers for equality, see the
> use of __GXX_MERGED_TYPEINFO_NAMES in libsupc++ for details.  Normally this

That's interesting to know, as I thought that pointer comparisons for
rtti was the only option.   Is __GXX_MERGED_TYPEINFO_NAMES correctly
being set to 0 (and __GXX_TYPEINFO_EQUALITY_INLINE to 0 as well it would
seem) for this target then?

> that it leads to the crash above.  Maybe I should just be relocating it
> within the DLL to a non-read-only section?  But the comment in winnt-cxx.c
> seemed quite adamant that it needs to be COMDAT, and I imagine that whoever
> wrote it would have considered that option, if it really was that simple.

I think that auto-import should be the answer here.  The comment in
winnt-cxx.c is correct insomuch as explicit dllimport isn't possible
because then it can't be used as a static initializer, but leaving off
dllimport and relying on auto-import is OK for static initializers (just
so long as they are made writable, which --e-a-i does), so it should be
fine.  Perhaps the comment was written before the feature was added to
the linker ca. 2001-08-02.

> Thirdly, do I maybe need to turn on auto-import always when linking against
> C++ DLLs?  I'm not really clear what would be the pros and cons of doing so,
> but I'm still getting some excess error failures in the testsuite, with
> stuff like:

For the purposes of the dejagnu testsuite, either -Wl,--e-a-i needs to
be added to the flags for the C++ tests, or the harness needs to be
taught to ignore the Info: lines.

But outside the testsuite, if the user gets all this noise when linking
normal C++ code it's a quality issue.  I think this really speaks more
to the general problem of this option's very existance than anything
else.  In my ideal world, the linker should be smart enough to do the
right thing with neither a bunch informational spew nor user
intervention.  That means if it processes an auto-import in .rdata, it
should be smart enough to mark the section writable without the user
needing to specify a flag.  At the same time, you don't want to
pessimise every program by eliminating the optimization of having
readonly data in a sharable segment, so you also don't want to just
unconditionally turn on -Wl,--e-a-i in the g++ driver specs either.

> that front, plus general comments on the design approach I've taken to the
> task; before I go any further, I need to know if I'm barking up completely
> the wrong tree!

I'd really like to know why auto-import is failing before going down
that road.

Brian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]