[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GDB uses a number of debugging-specific algorithms. They are often not very complicated, but get lost in the thicket of special cases and real-world issues. This chapter describes the basic algorithms and mentions some of the specific target definitions that they use.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A frame is a construct that GDB uses to keep track of calling and called functions.
FRAME_FP
in the machine description has no meaning to the
machine-independent part of GDB, except that it is used when
setting up a new frame from scratch, as follows:
create_new_frame (read_register (FP_REGNUM), read_pc ())); |
Other than that, all the meaning imparted to FP_REGNUM
is
imparted by the machine-dependent code. So, FP_REGNUM
can have
any value that is convenient for the code that creates new frames.
(create_new_frame
calls INIT_EXTRA_FRAME_INFO
if it is
defined; that is where you should use the FP_REGNUM
value, if
your frames are nonstandard.)
Given a GDB frame, define FRAME_CHAIN
to determine the
address of the calling function's frame. This will be used to create
a new GDB frame struct, and then INIT_EXTRA_FRAME_INFO
and INIT_FRAME_PC
will be called for the new frame.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In general, a breakpoint is a user-designated location in the program where the user wants to regain control if program execution ever reaches that location.
There are two main ways to implement breakpoints; either as "hardware" breakpoints or as "software" breakpoints.
Hardware breakpoints are sometimes available as a builtin debugging features with some chips. Typically these work by having dedicated register into which the breakpoint address may be stored. If the PC (shorthand for program counter) ever matches a value in a breakpoint registers, the CPU raises an exception and reports it to GDB.
Another possibility is when an emulator is in use; many emulators include circuitry that watches the address lines coming out from the processor, and force it to stop if the address matches a breakpoint's address.
A third possibility is that the target already has the ability to do breakpoints somehow; for instance, a ROM monitor may do its own software breakpoints. So although these are not literally "hardware breakpoints", from GDB's point of view they work the same; GDB need not do nothing more than set the breakpoint and wait for something to happen.
Since they depend on hardware resources, hardware breakpoints may be limited in number; when the user asks for more, GDB will start trying to set software breakpoints. (On some architectures, notably the 32-bit x86 platforms, GDB cannot always know whether there's enough hardware resources to insert all the hardware breakpoints and watchpoints. On those platforms, GDB prints an error message only when the program being debugged is continued.)
Software breakpoints require GDB to do somewhat more work. The basic theory is that GDB will replace a program instruction with a trap, illegal divide, or some other instruction that will cause an exception, and then when it's encountered, GDB will take the exception and stop the program. When the user says to continue, GDB will restore the original instruction, single-step, re-insert the trap, and continue on.
Since it literally overwrites the program being tested, the program area must be writable, so this technique won't work on programs in ROM. It can also distort the behavior of programs that examine themselves, although such a situation would be highly unusual.
Also, the software breakpoint instruction should be the smallest size of instruction, so it doesn't overwrite an instruction that might be a jump target, and cause disaster when the program jumps into the middle of the breakpoint instruction. (Strictly speaking, the breakpoint must be no larger than the smallest interval between instructions that may be jump targets; perhaps there is an architecture where only even-numbered instructions may jumped to.) Note that it's possible for an instruction set not to have any instructions usable for a software breakpoint, although in practice only the ARC has failed to define such an instruction.
The basic definition of the software breakpoint is the macro
BREAKPOINT
.
Basic breakpoint object handling is in `breakpoint.c'. However, much of the interesting breakpoint action is in `infrun.c'.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GDB has support for figuring out that the target is doing a
longjmp
and for stopping at the target of the jump, if we are
stepping. This is done with a few specialized internal breakpoints,
which are visible in the output of the `maint info breakpoint'
command.
To make this work, you need to define a macro called
GET_LONGJMP_TARGET
, which will examine the jmp_buf
structure and extract the longjmp target address. Since jmp_buf
is target specific, you will need to define it in the appropriate
`tm-target.h' file. Look in `tm-sun4os4.h' and
`sparc-tdep.c' for examples of how to do this.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Watchpoints are a special kind of breakpoints (see section breakpoints) which break when data is accessed rather than when some instruction is executed. When you have data which changes without your knowing what code does that, watchpoints are the silver bullet to hunt down and kill such bugs.
Watchpoints can be either hardware-assisted or not; the latter type is known as "software watchpoints." GDB always uses hardware-assisted watchpoints if they are available, and falls back on software watchpoints otherwise. Typical situations where GDB will use software watchpoints are:
Software watchpoints are very slow, since GDB needs to single-step the program being debugged and test the value of the watched expression(s) after each instruction. The rest of this section is mostly irrelevant for software watchpoints.
GDB uses several macros and primitives to support hardware watchpoints:
TARGET_HAS_HARDWARE_WATCHPOINTS
TARGET_CAN_USE_HARDWARE_WATCHPOINT (type, count, other)
TARGET_REGION_OK_FOR_HW_WATCHPOINT (addr, len)
TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (size)
TARGET_REGION_OK_FOR_HW_WATCHPOINT
is not
defined.
TARGET_DISABLE_HW_WATCHPOINTS (pid)
TARGET_ENABLE_HW_WATCHPOINTS (pid)
target_insert_watchpoint (addr, len, type)
target_remove_watchpoint (addr, len, type)
target_hw_bp_type
,
defined by `breakpoint.h' as follows:
enum target_hw_bp_type { hw_write = 0, /* Common (write) HW watchpoint */ hw_read = 1, /* Read HW watchpoint */ hw_access = 2, /* Access (read or write) HW watchpoint */ hw_execute = 3 /* Execute HW breakpoint */ }; |
These two macros should return 0 for success, non-zero for failure.
target_remove_hw_breakpoint (addr, shadow)
target_insert_hw_breakpoint (addr, shadow)
target_stopped_data_address ()
DECR_PC_AFTER_HW_BREAK
DECR_PC_AFTER_HW_BREAK
after a hardware break-point. This
overrides the value of DECR_PC_AFTER_BREAK
when a breakpoint
that breaks is a hardware-assisted breakpoint.
HAVE_STEPPABLE_WATCHPOINT
HAVE_NONSTEPPABLE_WATCHPOINT
HAVE_CONTINUABLE_WATCHPOINT
CANNOT_STEP_HW_WATCHPOINTS
STOPPED_BY_WATCHPOINT (wait_status)
struct target_waitstatus
, defined by `target.h'.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The 32-bit Intel x86 (a.k.a. ia32) processors feature special debug registers designed to facilitate debugging. GDB provides a generic library of functions that x86-based ports can use to implement support for watchpoints and hardware-assisted breakpoints. This subsection documents the x86 watchpoint facilities in GDB.
To use the generic x86 watchpoint support, a port should do the following:
I386_USE_GENERIC_WATCHPOINTS
somewhere in the
target-dependent headers.
I386_USE_GENERIC_WATCHPOINTS
.
NATDEPFILES
(see section NATDEPFILES) or
TDEPFILES
(see section TDEPFILES).
I386_DR_LOW_*
macros described
below. Typically, each macro should call a target-specific function
which does the real work.
The x86 watchpoint support works by maintaining mirror images of the debug registers. Values are copied between the mirror images and the real debug registers via a set of macros which each target needs to provide:
I386_DR_LOW_SET_CONTROL (val)
I386_DR_LOW_SET_ADDR (idx, addr)
I386_DR_LOW_RESET_ADDR (idx)
I386_DR_LOW_GET_STATUS
I386_DR_LOW_GET_STATUS
, so as to support per-thread status
register values.
For each one of the 4 debug registers (whose indices are from 0 to 3) that store addresses, a reference count is maintained by GDB, to allow sharing of debug registers by several watchpoints. This allows users to define several watchpoints that watch the same expression, but with different conditions and/or commands, without wasting debug registers which are in short supply. GDB maintains the reference counts internally, targets don't have to do anything to use this feature.
The x86 debug registers can each watch a region that is 1, 2, or 4 bytes long. The ia32 architecture requires that each watched region be appropriately aligned: 2-byte region on 2-byte boundary, 4-byte region on 4-byte boundary. However, the x86 watchpoint support in GDB can watch unaligned regions and regions larger than 4 bytes (up to 16 bytes) by allocating several debug registers to watch a single region. This allocation of several registers per a watched region is also done automatically without target code intervention.
The generic x86 watchpoint support provides the following API for the GDB's application code:
i386_region_ok_for_watchpoint (addr, len)
TARGET_REGION_OK_FOR_HW_WATCHPOINT
is set to call
this function. It counts the number of debug registers required to
watch a given region, and returns a non-zero value if that number is
less than 4, the number of debug registers available to x86
processors.
i386_stopped_data_address (void)
STOPPED_BY_WATCHPOINT
and
target_stopped_data_address
are set to call this function. The
argument passed to STOPPED_BY_WATCHPOINT
is ignored. This
function examines the breakpoint condition bits in the DR6 Debug
Status register, as returned by the I386_DR_LOW_GET_STATUS
macro, and returns the address associated with the first bit that is
set in DR6.
i386_insert_watchpoint (addr, len, type)
i386_remove_watchpoint (addr, len, type)
target_insert_watchpoint
and target_remove_watchpoint
are set to call these functions. i386_insert_watchpoint
first
looks for a debug register which is already set to watch the same
region for the same access types; if found, it just increments the
reference count of that debug register, thus implementing debug
register sharing between watchpoints. If no such register is found,
the function looks for a vacant debug register, sets its mirrored
value to addr, sets the mirrored value of DR7 Debug Control
register as appropriate for the len and type parameters,
and then passes the new values of the debug register and DR7 to the
inferior by calling I386_DR_LOW_SET_ADDR
and
I386_DR_LOW_SET_CONTROL
. If more than one debug register is
required to cover the given region, the above process is repeated for
each debug register.
i386_remove_watchpoint
does the opposite: it resets the address
in the mirrored value of the debug register and its read/write and
length bits in the mirrored value of DR7, then passes these new
values to the inferior via I386_DR_LOW_RESET_ADDR
and
I386_DR_LOW_SET_CONTROL
. If a register is shared by several
watchpoints, each time a i386_remove_watchpoint
is called, it
decrements the reference count, and only calls
I386_DR_LOW_RESET_ADDR
and I386_DR_LOW_SET_CONTROL
when
the count goes to zero.
i386_insert_hw_breakpoint (addr, shadow
i386_remove_hw_breakpoint (addr, shadow)
target_insert_hw_breakpoint
and
target_remove_hw_breakpoint
are set to call these functions.
These functions work like i386_insert_watchpoint
and
i386_remove_watchpoint
, respectively, except that they set up
the debug registers to watch instruction execution, and each
hardware-assisted breakpoint always requires exactly one debug
register.
i386_stopped_by_hwbp (void)
i386_stopped_data_address
, except that it doesn't return the
address whose watchpoint triggered.
i386_cleanup_dregs (void)
Notes:
enum target_hw_bp_type
doesn't even have an enumeration for I/O
watchpoints, this feature is not yet available to GDB running
on x86.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Please send FSF & GNU inquiries & questions to gnu@gnu.org. There are also other ways to contact the FSF.
These pages are maintained by the GDB developers.
Copyright Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
This document was generated by GDB Administrator on October, 18 2002 using texi2html