This is the mail archive of the archer@sourceware.org mailing list for the Archer 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]

PR 2488 status and some unwinder questions


I've been doing some investigation on gnats PR 2488 and wanted to give a
brief status, and gather some suggestions on approach so far. This bug
manifests itself when a user invokes the "next" command over a C++
"throw" statement. This will cause GDB to lose control of the inferior.

The cause of this bug is that the "next" command uses setjmp/longjmp
breakpoints to detect completion, and return control to GDB; however the
unwinder does not use this method to invoke context changes and GDB
cannot detect that change. Anyway, control of the inferior is lost until
it hits another (unrelated) breakpoint, or it exits.

So for the last while I've been looking at placing a breakpoint
somewhere convenient in the unwinder, in addition to the existing
longjmp breakpoints. This will allow one to deduce from the unwind
structures where the correct stopping place is. The most convenient
place for this is in uw_install_context() function. This is called from
UnwindRaise_Exception() in all cases. (It also seems to be called in
many other cases, and would also provide a convenient side benefit of
catching all context changes invoked by the unwinder.) In any case, this
is always called in the raise exception code - whether that context is
to a clean-up, or to an exception handler. The uw_install_context()
function is passed two _Unwind_Context structures: one of which is the
current context and the other a "this" context. I find these names a bit
confusing - and please if my logic is wandering into the weeds, let me
know. But the current context structure is the source of where the
uw_install_context() will install the context too (i.e. where we are
going), and the "this" context is where we are right now. How
uw_install_context() does this is not relevant to this email, but among
the information in these _Unwind_Context data structures is the
location of where we'll end up after the context is installed.

So far so good.

Unfortunately I found that I cannot place a breakpoint in
uw_install_context() as it is not exported. I cannot find it via:

readelf --syms /usr/lib64/libstdc++.so.6.

And other attempts do not provide anything promising on my Fedora box.
It is exposed via debug-info however:

eu-readelf --symbols libgcc_s-4.3.0-20080428.so.1.debug | grep
uw_install_context
  152: 000000000000ef80    313 FUNC    LOCAL  DEFAULT       12
uw_install_context_1

(uw_install_context is a macro that among other things calls
uw_install_context_1. When I talk about placing a breakpoint in
uw_install_context, I really mean in the "actual" function
uw_install_function_1.)

However requiring GCC debug-info to be installed for correct operation
of C++ debugging in GDB is a bit of a non-starter. So bit disappointed
there. I could ask for uw_install_context(_1) to be exported. Is there a
strong case for/against? Is there another place where we can intercept
the context change before it happens, and mine the data for the context
change location? Or is this (breakpoint in the unwinder) just the wrong
approach?

Another approach I'm going to look at is mining the FDE entries in
.eh_frame to try to piece together where uw_install_context() would
install the context too (from the current $pc). However, something Tom
mentioned about avoiding reimplementing the unwinder in GDB gave me some
pause ;)

Regards

Phil





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