|
Packit |
6c4009 |
Standard debugger interface
|
|
Packit |
6c4009 |
===========================
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The run-time linker exposes a rendezvous structure to allow debuggers
|
|
Packit |
6c4009 |
to interface with it. This structure, r_debug, is defined in link.h.
|
|
Packit |
6c4009 |
If the executable's dynamic section has a DT_DEBUG element, the
|
|
Packit |
6c4009 |
run-time linker sets that element's value to the address where this
|
|
Packit |
6c4009 |
structure can be found.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The r_debug structure contains (amongst others) the following fields:
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
struct link_map *r_map:
|
|
Packit |
6c4009 |
A linked list of loaded objects.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state:
|
|
Packit |
6c4009 |
The current state of the r_map list. RT_CONSISTENT means that r_map
|
|
Packit |
6c4009 |
is not currently being modified and may safely be inspected. RT_ADD
|
|
Packit |
6c4009 |
means that an object is being added to r_map, and that the list is
|
|
Packit |
6c4009 |
not guaranteed to be consistent. Likewise RT_DELETE means that an
|
|
Packit |
6c4009 |
object is being removed from the list.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
ElfW(Addr) r_brk:
|
|
Packit |
6c4009 |
The address of a function internal to the run-time linker which is
|
|
Packit |
6c4009 |
called whenever r_state is changed. The debugger should set a
|
|
Packit |
6c4009 |
breakpoint at this address if it wants to notice mapping changes.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
This protocol is widely supported, but somewhat limited in that it
|
|
Packit |
6c4009 |
has no provision to provide access to multiple namespaces, and that
|
|
Packit |
6c4009 |
the notifications (via r_brk) only refer to changes to r_map--the
|
|
Packit |
6c4009 |
debugger is notified that a new object has been added, for instance,
|
|
Packit |
6c4009 |
but there is no way for the debugger to discover whether any of the
|
|
Packit |
6c4009 |
objects in the link-map have been relocated or not.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
Probe-based debugger interface
|
|
Packit |
6c4009 |
==============================
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
Systemtap is a dynamic tracing/instrumenting tool available on Linux.
|
|
Packit |
6c4009 |
Probes that are not fired at run time have close to zero overhead.
|
|
Packit |
6c4009 |
glibc contains a number of probes that debuggers can set breakpoints
|
|
Packit |
6c4009 |
on in order to notice certain events.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
All rtld probes have the following arguments:
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
arg1: Lmid_t lmid:
|
|
Packit |
6c4009 |
The link-map ID of the link-map list that the object was loaded
|
|
Packit |
6c4009 |
into. This will be LM_ID_BASE for the application's main link-map
|
|
Packit |
6c4009 |
list, or some other value for different namespaces.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
arg2: struct r_debug *r_debug:
|
|
Packit |
6c4009 |
A pointer to the r_debug structure containing the link-map list
|
|
Packit |
6c4009 |
that the object was loaded into. This will be the value stored in
|
|
Packit |
6c4009 |
DT_DEBUG for the application's main link-map list, or some other
|
|
Packit |
6c4009 |
value for different namespaces.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
map_complete and reloc_complete may have the following additional
|
|
Packit |
6c4009 |
argument:
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
arg3: struct link_map *new:
|
|
Packit |
6c4009 |
A pointer which, if not NULL, points to the entry in the specified
|
|
Packit |
6c4009 |
r_debug structure's link-map list corresponding to the first new
|
|
Packit |
6c4009 |
object to have been mapped or relocated, with new->l_next pointing
|
|
Packit |
6c4009 |
to the link-map of the next new object to have been mapped or
|
|
Packit |
6c4009 |
relocated, and so on. Note that because `new' is an entry in a
|
|
Packit |
6c4009 |
larger list, new->l_prev (if not NULL) will point to what was the
|
|
Packit |
6c4009 |
last link-map in the link-map list prior to the new objects being
|
|
Packit |
6c4009 |
mapped or relocated.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The following probes are available:
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
init_start:
|
|
Packit |
6c4009 |
This is called once, when the linker is about to fill in the main
|
|
Packit |
6c4009 |
r_debug structure at application startup. init_start always has
|
|
Packit |
6c4009 |
lmid set to LM_ID_BASE and r_debug set to the value stored in
|
|
Packit |
6c4009 |
DT_DEBUG. r_debug is not guaranteed to be consistent until
|
|
Packit |
6c4009 |
init_complete is fired.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
init_complete:
|
|
Packit |
6c4009 |
This is called once, when the linker has filled in the main
|
|
Packit |
6c4009 |
r_debug structure at application startup. init_complete always
|
|
Packit |
6c4009 |
has lmid set to LM_ID_BASE and r_debug set to the value stored
|
|
Packit |
6c4009 |
in DT_DEBUG. The r_debug structure is consistent and may be
|
|
Packit |
6c4009 |
inspected, and all objects in the link-map are guaranteed to
|
|
Packit |
6c4009 |
have been relocated.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
map_start:
|
|
Packit |
6c4009 |
The linker is about to map new objects into the specified
|
|
Packit |
6c4009 |
namespace. The namespace's r_debug structure is not guaranteed
|
|
Packit |
6c4009 |
to be consistent until a corresponding map_complete is fired.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
map_complete:
|
|
Packit |
6c4009 |
The linker has finished mapping new objects into the specified
|
|
Packit |
6c4009 |
namespace. The namespace's r_debug structure is consistent and
|
|
Packit |
6c4009 |
may be inspected, although objects in the namespace's link-map
|
|
Packit |
6c4009 |
are not guaranteed to have been relocated.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
map_failed:
|
|
Packit |
6c4009 |
The linker failed while attempting to map new objects into
|
|
Packit |
6c4009 |
the specified namespace. The namespace's r_debug structure
|
|
Packit |
6c4009 |
is consistent and may be inspected.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
reloc_start:
|
|
Packit |
6c4009 |
The linker is about to relocate all unrelocated objects in the
|
|
Packit |
6c4009 |
specified namespace. The namespace's r_debug structure is not
|
|
Packit |
6c4009 |
guaranteed to be consistent until a corresponding reloc_complete
|
|
Packit |
6c4009 |
is fired.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
reloc_complete:
|
|
Packit |
6c4009 |
The linker has relocated all objects in the specified namespace.
|
|
Packit |
6c4009 |
The namespace's r_debug structure is consistent and may be
|
|
Packit |
6c4009 |
inspected, and all objects in the namespace's link-map are
|
|
Packit |
6c4009 |
guaranteed to have been relocated.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
unmap_start:
|
|
Packit |
6c4009 |
The linker is about to remove objects from the specified
|
|
Packit |
6c4009 |
namespace. The namespace's r_debug structure is not guaranteed to
|
|
Packit |
6c4009 |
be consistent until a corresponding unmap_complete is fired.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
unmap_complete:
|
|
Packit |
6c4009 |
The linker has finished removing objects into the specified
|
|
Packit |
6c4009 |
namespace. The namespace's r_debug structure is consistent and
|
|
Packit |
6c4009 |
may be inspected.
|