Move comment on the 'stepping over resolver' mechanism to the internals manual.
This whole comment is now a bit out of place. I looked into moving it to handle_inferior_event, close to where in_solib_dynsym_resolve_code is used, but then there are 3 such places. I then looked at fragmenting it, pushing bits closer to the definitions of in_solib_dynsym_resolve_code and gdbarch_skip_solib_resolver, but then we'd lose the main advantage which is the overview. In the end, I realized this can fit nicely as internals manual material. This could possibly be a subsection of a new "run control", or "source stepping" or "stepping" or some such a bit more general section, but we can do that when we have more related content... Even the "single stepping" section is presently empty... gdb/doc/ 2013-06-27 Pedro Alves <palves@redhat.com> * gdbint.texinfo (Algorithms) <Stepping over runtime loader dynamic symbol resolution code>: New section, based on infrun.c comment. gdb/ 2013-06-27 Pedro Alves <palves@redhat.com> * infrun.c: Remove comment describing the 'stepping over runtime loader dynamic symbol resolution code' mechanism; moved to gdbint.texinfo.
This commit is contained in:
parent
a8c97a8765
commit
e5823f1cb5
4 changed files with 57 additions and 40 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2013-06-27 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* infrun.c: Remove comment describing the 'stepping over runtime
|
||||||
|
loader dynamic symbol resolution code' mechanism; moved to
|
||||||
|
gdbint.texinfo.
|
||||||
|
|
||||||
2013-06-27 Pedro Alves <palves@redhat.com>
|
2013-06-27 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* exceptions.c (catch_command_errors): Remove spurious space.
|
* exceptions.c (catch_command_errors): Remove spurious space.
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2013-06-27 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* gdbint.texinfo (Algorithms) <Stepping over runtime loader
|
||||||
|
dynamic symbol resolution code>: New section, based on infrun.c
|
||||||
|
comment.
|
||||||
|
|
||||||
2013-06-26 Tom Tromey <tromey@redhat.com>
|
2013-06-26 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* gdbint.texinfo (Versions and Branches): Use common/version.in.
|
* gdbint.texinfo (Versions and Branches): Use common/version.in.
|
||||||
|
|
|
@ -592,6 +592,51 @@ but @code{placed_size} may be.
|
||||||
|
|
||||||
@section Single Stepping
|
@section Single Stepping
|
||||||
|
|
||||||
|
@section Stepping over runtime loader dynamic symbol resolution code
|
||||||
|
@cindex Procedure Linkage Table, stepping over
|
||||||
|
@cindex PLT, stepping over
|
||||||
|
@cindex resolver, stepping over
|
||||||
|
|
||||||
|
If the program uses ELF-style shared libraries, then calls to
|
||||||
|
functions in shared libraries go through stubs, which live in a table
|
||||||
|
called the PLT (@dfn{Procedure Linkage Table}). The first time the
|
||||||
|
function is called, the stub sends control to the dynamic linker,
|
||||||
|
which looks up the function's real address, patches the stub so that
|
||||||
|
future calls will go directly to the function, and then passes control
|
||||||
|
to the function.
|
||||||
|
|
||||||
|
If we are stepping at the source level, we don't want to see any of
|
||||||
|
this --- we just want to skip over the stub and the dynamic linker.
|
||||||
|
The simple approach is to single-step until control leaves the dynamic
|
||||||
|
linker.
|
||||||
|
|
||||||
|
However, on some systems (e.g., Red Hat's 5.2 distribution) the
|
||||||
|
dynamic linker calls functions in the shared C library, so you can't
|
||||||
|
tell from the PC alone whether the dynamic linker is still running.
|
||||||
|
In this case, we use a step-resume breakpoint to get us past the
|
||||||
|
dynamic linker, as if we were using @code{next} to step over a
|
||||||
|
function call.
|
||||||
|
|
||||||
|
The @code{in_solib_dynsym_resolve_code} function says whether we're in
|
||||||
|
the dynamic linker code or not. Normally, this means we single-step.
|
||||||
|
However, if @code{gdbarch_skip_solib_resolver} then returns non-zero,
|
||||||
|
then its value is an address where we can place a step-resume
|
||||||
|
breakpoint to get past the linker's symbol resolution function.
|
||||||
|
|
||||||
|
The @code{in_dynsym_resolve_code} hook of the @code{target_so_ops}
|
||||||
|
vector can generally be implemented in a pretty portable way, by
|
||||||
|
comparing the PC against the address ranges of the dynamic linker's
|
||||||
|
sections.
|
||||||
|
|
||||||
|
The @code{gdbarch_skip_solib_resolver} implementation is generally
|
||||||
|
going to be system-specific, since it depends on internal details of
|
||||||
|
the dynamic linker. It's usually not too hard to figure out where to
|
||||||
|
put a breakpoint, but it certainly isn't portable.
|
||||||
|
@code{gdbarch_skip_solib_resolver} should do plenty of sanity
|
||||||
|
checking. If it can't figure things out, returning zero and getting
|
||||||
|
the (possibly confusing) stepping behavior is better than signaling an
|
||||||
|
error, which will obscure the change in the inferior's state. */
|
||||||
|
|
||||||
@section Signal Handling
|
@section Signal Handling
|
||||||
|
|
||||||
@section Thread Handling
|
@section Thread Handling
|
||||||
|
|
40
gdb/infrun.c
40
gdb/infrun.c
|
@ -181,46 +181,6 @@ set_disable_randomization (char *args, int from_tty,
|
||||||
"this platform."));
|
"this platform."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If the program uses ELF-style shared libraries, then calls to
|
|
||||||
functions in shared libraries go through stubs, which live in a
|
|
||||||
table called the PLT (Procedure Linkage Table). The first time the
|
|
||||||
function is called, the stub sends control to the dynamic linker,
|
|
||||||
which looks up the function's real address, patches the stub so
|
|
||||||
that future calls will go directly to the function, and then passes
|
|
||||||
control to the function.
|
|
||||||
|
|
||||||
If we are stepping at the source level, we don't want to see any of
|
|
||||||
this --- we just want to skip over the stub and the dynamic linker.
|
|
||||||
The simple approach is to single-step until control leaves the
|
|
||||||
dynamic linker.
|
|
||||||
|
|
||||||
However, on some systems (e.g., Red Hat's 5.2 distribution) the
|
|
||||||
dynamic linker calls functions in the shared C library, so you
|
|
||||||
can't tell from the PC alone whether the dynamic linker is still
|
|
||||||
running. In this case, we use a step-resume breakpoint to get us
|
|
||||||
past the dynamic linker, as if we were using "next" to step over a
|
|
||||||
function call.
|
|
||||||
|
|
||||||
in_solib_dynsym_resolve_code() says whether we're in the dynamic
|
|
||||||
linker code or not. Normally, this means we single-step. However,
|
|
||||||
if gdbarch_skip_solib_resolver then returns non-zero, then its
|
|
||||||
value is an address where we can place a step-resume breakpoint to
|
|
||||||
get past the linker's symbol resolution function.
|
|
||||||
|
|
||||||
The in_dynsym_resolve_code hook of the target_so_ops vector can
|
|
||||||
generally be implemented in a pretty portable way, by comparing the
|
|
||||||
PC against the address ranges of the dynamic linker's sections.
|
|
||||||
|
|
||||||
The gdbarch_skip_solib_resolver implementation is generally going
|
|
||||||
to be system-specific, since it depends on internal details of the
|
|
||||||
dynamic linker. It's usually not too hard to figure out where to
|
|
||||||
put a breakpoint, but it certainly isn't portable.
|
|
||||||
gdbarch_skip_solib_resolver should do plenty of sanity checking.
|
|
||||||
If it can't figure things out, returning zero and getting the
|
|
||||||
(possibly confusing) stepping behavior is better than signaling an
|
|
||||||
error, which will obscure the change in the inferior's state. */
|
|
||||||
|
|
||||||
/* "Observer mode" is somewhat like a more extreme version of
|
/* "Observer mode" is somewhat like a more extreme version of
|
||||||
non-stop, in which all GDB operations that might affect the
|
non-stop, in which all GDB operations that might affect the
|
||||||
target's execution have been disabled. */
|
target's execution have been disabled. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue