749 lines
33 KiB
HTML
749 lines
33 KiB
HTML
<HTML>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<!-- Created on October, 18 2002 by texi2html 1.64 -->
|
|
<!--
|
|
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
|
|
Karl Berry <karl@freefriends.org>
|
|
Olaf Bachmann <obachman@mathematik.uni-kl.de>
|
|
and many others.
|
|
Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
|
|
Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
|
|
|
|
-->
|
|
<HEAD>
|
|
<TITLE>GDB Internals: Algorithms</TITLE>
|
|
|
|
<META NAME="description" CONTENT="GDB Internals: Algorithms">
|
|
<META NAME="keywords" CONTENT="GDB Internals: Algorithms">
|
|
<META NAME="resource-type" CONTENT="document">
|
|
<META NAME="distribution" CONTENT="global">
|
|
<META NAME="Generator" CONTENT="texi2html 1.64">
|
|
|
|
</HEAD>
|
|
|
|
<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
|
|
|
|
<A NAME="SEC6"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_2.html#SEC5"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC7"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H1> 3. Algorithms </H1>
|
|
<!--docid::SEC6::-->
|
|
<P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC7"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC8"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.1 Frames </H2>
|
|
<!--docid::SEC7::-->
|
|
<P>
|
|
|
|
<A NAME="IDX3"></A>
|
|
<A NAME="IDX4"></A>
|
|
A frame is a construct that GDB uses to keep track of calling
|
|
and called functions.
|
|
</P><P>
|
|
|
|
<A NAME="IDX5"></A>
|
|
<A NAME="IDX6"></A>
|
|
<CODE>FRAME_FP</CODE> 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:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>create_new_frame (read_register (FP_REGNUM), read_pc ()));
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
<A NAME="IDX7"></A>
|
|
Other than that, all the meaning imparted to <CODE>FP_REGNUM</CODE> is
|
|
imparted by the machine-dependent code. So, <CODE>FP_REGNUM</CODE> can have
|
|
any value that is convenient for the code that creates new frames.
|
|
(<CODE>create_new_frame</CODE> calls <CODE>INIT_EXTRA_FRAME_INFO</CODE> if it is
|
|
defined; that is where you should use the <CODE>FP_REGNUM</CODE> value, if
|
|
your frames are nonstandard.)
|
|
</P><P>
|
|
|
|
<A NAME="IDX8"></A>
|
|
Given a GDB frame, define <CODE>FRAME_CHAIN</CODE> to determine the
|
|
address of the calling function's frame. This will be used to create
|
|
a new GDB frame struct, and then <CODE>INIT_EXTRA_FRAME_INFO</CODE>
|
|
and <CODE>INIT_FRAME_PC</CODE> will be called for the new frame.
|
|
</P><P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC8"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC7"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC9"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC9"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.2 Breakpoint Handling </H2>
|
|
<!--docid::SEC8::-->
|
|
<P>
|
|
|
|
<A NAME="IDX9"></A>
|
|
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.
|
|
</P><P>
|
|
|
|
There are two main ways to implement breakpoints; either as "hardware"
|
|
breakpoints or as "software" breakpoints.
|
|
</P><P>
|
|
|
|
<A NAME="IDX10"></A>
|
|
<A NAME="IDX11"></A>
|
|
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 <EM>program counter</EM>)
|
|
ever matches a value in a breakpoint registers, the CPU raises an
|
|
exception and reports it to GDB.
|
|
</P><P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
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.)
|
|
</P><P>
|
|
|
|
<A NAME="IDX12"></A>
|
|
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.
|
|
</P><P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
<A NAME="IDX13"></A>
|
|
The basic definition of the software breakpoint is the macro
|
|
<CODE>BREAKPOINT</CODE>.
|
|
</P><P>
|
|
|
|
Basic breakpoint object handling is in <TT>`breakpoint.c'</TT>. However,
|
|
much of the interesting breakpoint action is in <TT>`infrun.c'</TT>.
|
|
</P><P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC9"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC8"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC10"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC10"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.3 Single Stepping </H2>
|
|
<!--docid::SEC9::-->
|
|
<P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC10"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC9"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC11"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC11"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.4 Signal Handling </H2>
|
|
<!--docid::SEC10::-->
|
|
<P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC11"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC10"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC12"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC12"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.5 Thread Handling </H2>
|
|
<!--docid::SEC11::-->
|
|
<P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC12"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC11"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC13"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC13"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.6 Inferior Function Calls </H2>
|
|
<!--docid::SEC12::-->
|
|
<P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC13"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC12"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC14"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC14"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.7 Longjmp Support </H2>
|
|
<!--docid::SEC13::-->
|
|
<P>
|
|
|
|
<A NAME="IDX14"></A>
|
|
GDB has support for figuring out that the target is doing a
|
|
<CODE>longjmp</CODE> 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 <SAMP>`maint info breakpoint'</SAMP>
|
|
command.
|
|
</P><P>
|
|
|
|
<A NAME="IDX15"></A>
|
|
To make this work, you need to define a macro called
|
|
<CODE>GET_LONGJMP_TARGET</CODE>, which will examine the <CODE>jmp_buf</CODE>
|
|
structure and extract the longjmp target address. Since <CODE>jmp_buf</CODE>
|
|
is target specific, you will need to define it in the appropriate
|
|
<TT>`tm-<VAR>target</VAR>.h'</TT> file. Look in <TT>`tm-sun4os4.h'</TT> and
|
|
<TT>`sparc-tdep.c'</TT> for examples of how to do this.
|
|
</P><P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC14"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC13"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC15"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 3.8 Watchpoints </H2>
|
|
<!--docid::SEC14::-->
|
|
<P>
|
|
|
|
Watchpoints are a special kind of breakpoints (see section <A HREF="gdbint_3.html#SEC6">breakpoints</A>) 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.
|
|
</P><P>
|
|
|
|
<A NAME="IDX16"></A>
|
|
<A NAME="IDX17"></A>
|
|
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:
|
|
</P><P>
|
|
|
|
<UL>
|
|
<LI>
|
|
The watched memory region is too large for the underlying hardware
|
|
watchpoint support. For example, each x86 debug register can watch up
|
|
to 4 bytes of memory, so trying to watch data structures whose size is
|
|
more than 16 bytes will cause GDB to use software
|
|
watchpoints.
|
|
<P>
|
|
|
|
<LI>
|
|
The value of the expression to be watched depends on data held in
|
|
registers (as opposed to memory).
|
|
<P>
|
|
|
|
<LI>
|
|
Too many different watchpoints requested. (On some architectures,
|
|
this situation is impossible to detect until the debugged program is
|
|
resumed.) Note that x86 debug registers are used both for hardware
|
|
breakpoints and for watchpoints, so setting too many hardware
|
|
breakpoints might cause watchpoint insertion to fail.
|
|
<P>
|
|
|
|
<LI>
|
|
No hardware-assisted watchpoints provided by the target
|
|
implementation.
|
|
</UL>
|
|
<P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
GDB uses several macros and primitives to support hardware
|
|
watchpoints:
|
|
</P><P>
|
|
|
|
<DL COMPACT>
|
|
<A NAME="IDX18"></A>
|
|
<DT><CODE>TARGET_HAS_HARDWARE_WATCHPOINTS</CODE>
|
|
<DD>If defined, the target supports hardware watchpoints.
|
|
<P>
|
|
|
|
<A NAME="IDX19"></A>
|
|
<DT><CODE>TARGET_CAN_USE_HARDWARE_WATCHPOINT (<VAR>type</VAR>, <VAR>count</VAR>, <VAR>other</VAR>)</CODE>
|
|
<DD>Return the number of hardware watchpoints of type <VAR>type</VAR> that are
|
|
possible to be set. The value is positive if <VAR>count</VAR> watchpoints
|
|
of this type can be set, zero if setting watchpoints of this type is
|
|
not supported, and negative if <VAR>count</VAR> is more than the maximum
|
|
number of watchpoints of type <VAR>type</VAR> that can be set. <VAR>other</VAR>
|
|
is non-zero if other types of watchpoints are currently enabled (there
|
|
are architectures which cannot set watchpoints of different types at
|
|
the same time).
|
|
<P>
|
|
|
|
<A NAME="IDX20"></A>
|
|
<DT><CODE>TARGET_REGION_OK_FOR_HW_WATCHPOINT (<VAR>addr</VAR>, <VAR>len</VAR>)</CODE>
|
|
<DD>Return non-zero if hardware watchpoints can be used to watch a region
|
|
whose address is <VAR>addr</VAR> and whose length in bytes is <VAR>len</VAR>.
|
|
<P>
|
|
|
|
<A NAME="IDX21"></A>
|
|
<DT><CODE>TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (<VAR>size</VAR>)</CODE>
|
|
<DD>Return non-zero if hardware watchpoints can be used to watch a region
|
|
whose size is <VAR>size</VAR>. GDB only uses this macro as a
|
|
fall-back, in case <CODE>TARGET_REGION_OK_FOR_HW_WATCHPOINT</CODE> is not
|
|
defined.
|
|
<P>
|
|
|
|
<A NAME="IDX22"></A>
|
|
<DT><CODE>TARGET_DISABLE_HW_WATCHPOINTS (<VAR>pid</VAR>)</CODE>
|
|
<DD>Disables watchpoints in the process identified by <VAR>pid</VAR>. This is
|
|
used, e.g., on HP-UX which provides operations to disable and enable
|
|
the page-level memory protection that implements hardware watchpoints
|
|
on that platform.
|
|
<P>
|
|
|
|
<A NAME="IDX23"></A>
|
|
<DT><CODE>TARGET_ENABLE_HW_WATCHPOINTS (<VAR>pid</VAR>)</CODE>
|
|
<DD>Enables watchpoints in the process identified by <VAR>pid</VAR>. This is
|
|
used, e.g., on HP-UX which provides operations to disable and enable
|
|
the page-level memory protection that implements hardware watchpoints
|
|
on that platform.
|
|
<P>
|
|
|
|
<A NAME="IDX24"></A>
|
|
<A NAME="IDX25"></A>
|
|
<DT><CODE>target_insert_watchpoint (<VAR>addr</VAR>, <VAR>len</VAR>, <VAR>type</VAR>)</CODE>
|
|
<DD><DT><CODE>target_remove_watchpoint (<VAR>addr</VAR>, <VAR>len</VAR>, <VAR>type</VAR>)</CODE>
|
|
<DD>Insert or remove a hardware watchpoint starting at <VAR>addr</VAR>, for
|
|
<VAR>len</VAR> bytes. <VAR>type</VAR> is the watchpoint type, one of the
|
|
possible values of the enumerated data type <CODE>target_hw_bp_type</CODE>,
|
|
defined by <TT>`breakpoint.h'</TT> as follows:
|
|
<P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre> 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 */
|
|
};
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
These two macros should return 0 for success, non-zero for failure.
|
|
</P><P>
|
|
|
|
<A NAME="IDX26"></A>
|
|
<A NAME="IDX27"></A>
|
|
<A NAME="IDX28"></A>
|
|
<DT><CODE>target_remove_hw_breakpoint (<VAR>addr</VAR>, <VAR>shadow</VAR>)</CODE>
|
|
<DD><DT><CODE>target_insert_hw_breakpoint (<VAR>addr</VAR>, <VAR>shadow</VAR>)</CODE>
|
|
<DD>Insert or remove a hardware-assisted breakpoint at address <VAR>addr</VAR>.
|
|
Returns zero for success, non-zero for failure. <VAR>shadow</VAR> is the
|
|
real contents of the byte where the breakpoint has been inserted; it
|
|
is generally not valid when hardware breakpoints are used, but since
|
|
no other code touches these values, the implementations of the above
|
|
two macros can use them for their internal purposes.
|
|
<P>
|
|
|
|
<A NAME="IDX29"></A>
|
|
<DT><CODE>target_stopped_data_address ()</CODE>
|
|
<DD>If the inferior has some watchpoint that triggered, return the address
|
|
associated with that watchpoint. Otherwise, return zero.
|
|
<P>
|
|
|
|
<A NAME="IDX30"></A>
|
|
<DT><CODE>DECR_PC_AFTER_HW_BREAK</CODE>
|
|
<DD>If defined, GDB decrements the program counter by the value
|
|
of <CODE>DECR_PC_AFTER_HW_BREAK</CODE> after a hardware break-point. This
|
|
overrides the value of <CODE>DECR_PC_AFTER_BREAK</CODE> when a breakpoint
|
|
that breaks is a hardware-assisted breakpoint.
|
|
<P>
|
|
|
|
<A NAME="IDX31"></A>
|
|
<DT><CODE>HAVE_STEPPABLE_WATCHPOINT</CODE>
|
|
<DD>If defined to a non-zero value, it is not necessary to disable a
|
|
watchpoint to step over it.
|
|
<P>
|
|
|
|
<A NAME="IDX32"></A>
|
|
<DT><CODE>HAVE_NONSTEPPABLE_WATCHPOINT</CODE>
|
|
<DD>If defined to a non-zero value, GDB should disable a
|
|
watchpoint to step the inferior over it.
|
|
<P>
|
|
|
|
<A NAME="IDX33"></A>
|
|
<DT><CODE>HAVE_CONTINUABLE_WATCHPOINT</CODE>
|
|
<DD>If defined to a non-zero value, it is possible to continue the
|
|
inferior after a watchpoint has been hit.
|
|
<P>
|
|
|
|
<A NAME="IDX34"></A>
|
|
<DT><CODE>CANNOT_STEP_HW_WATCHPOINTS</CODE>
|
|
<DD>If this is defined to a non-zero value, GDB will remove all
|
|
watchpoints before stepping the inferior.
|
|
<P>
|
|
|
|
<A NAME="IDX35"></A>
|
|
<DT><CODE>STOPPED_BY_WATCHPOINT (<VAR>wait_status</VAR>)</CODE>
|
|
<DD>Return non-zero if stopped by a watchpoint. <VAR>wait_status</VAR> is of
|
|
the type <CODE>struct target_waitstatus</CODE>, defined by <TT>`target.h'</TT>.
|
|
</DL>
|
|
<P>
|
|
|
|
<HR SIZE="6">
|
|
<A NAME="SEC15"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC14"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC14"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H3> 3.8.1 x86 Watchpoints </H3>
|
|
<!--docid::SEC15::-->
|
|
<P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
To use the generic x86 watchpoint support, a port should do the
|
|
following:
|
|
</P><P>
|
|
|
|
<UL>
|
|
<A NAME="IDX36"></A>
|
|
<LI>
|
|
Define the macro <CODE>I386_USE_GENERIC_WATCHPOINTS</CODE> somewhere in the
|
|
target-dependent headers.
|
|
<P>
|
|
|
|
<LI>
|
|
Include the <TT>`config/i386/nm-i386.h'</TT> header file <EM>after</EM>
|
|
defining <CODE>I386_USE_GENERIC_WATCHPOINTS</CODE>.
|
|
<P>
|
|
|
|
<LI>
|
|
Add <TT>`i386-nat.o'</TT> to the value of the Make variable
|
|
<CODE>NATDEPFILES</CODE> (see section <A HREF="gdbint_11.html#SEC95">NATDEPFILES</A>) or
|
|
<CODE>TDEPFILES</CODE> (see section <A HREF="gdbint_9.html#SEC67">TDEPFILES</A>).
|
|
<P>
|
|
|
|
<LI>
|
|
Provide implementations for the <CODE>I386_DR_LOW_*</CODE> macros described
|
|
below. Typically, each macro should call a target-specific function
|
|
which does the real work.
|
|
</UL>
|
|
<P>
|
|
|
|
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:
|
|
</P><P>
|
|
|
|
<DL COMPACT>
|
|
<A NAME="IDX37"></A>
|
|
<DT><CODE>I386_DR_LOW_SET_CONTROL (<VAR>val</VAR>)</CODE>
|
|
<DD>Set the Debug Control (DR7) register to the value <VAR>val</VAR>.
|
|
<P>
|
|
|
|
<A NAME="IDX38"></A>
|
|
<DT><CODE>I386_DR_LOW_SET_ADDR (<VAR>idx</VAR>, <VAR>addr</VAR>)</CODE>
|
|
<DD>Put the address <VAR>addr</VAR> into the debug register number <VAR>idx</VAR>.
|
|
<P>
|
|
|
|
<A NAME="IDX39"></A>
|
|
<DT><CODE>I386_DR_LOW_RESET_ADDR (<VAR>idx</VAR>)</CODE>
|
|
<DD>Reset (i.e. zero out) the address stored in the debug register
|
|
number <VAR>idx</VAR>.
|
|
<P>
|
|
|
|
<A NAME="IDX40"></A>
|
|
<DT><CODE>I386_DR_LOW_GET_STATUS</CODE>
|
|
<DD>Return the value of the Debug Status (DR6) register. This value is
|
|
used immediately after it is returned by
|
|
<CODE>I386_DR_LOW_GET_STATUS</CODE>, so as to support per-thread status
|
|
register values.
|
|
</DL>
|
|
<P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
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.
|
|
</P><P>
|
|
|
|
The generic x86 watchpoint support provides the following API for the
|
|
GDB's application code:
|
|
</P><P>
|
|
|
|
<DL COMPACT>
|
|
<A NAME="IDX41"></A>
|
|
<DT><CODE>i386_region_ok_for_watchpoint (<VAR>addr</VAR>, <VAR>len</VAR>)</CODE>
|
|
<DD>The macro <CODE>TARGET_REGION_OK_FOR_HW_WATCHPOINT</CODE> 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.
|
|
<P>
|
|
|
|
<A NAME="IDX42"></A>
|
|
<DT><CODE>i386_stopped_data_address (void)</CODE>
|
|
<DD>The macros <CODE>STOPPED_BY_WATCHPOINT</CODE> and
|
|
<CODE>target_stopped_data_address</CODE> are set to call this function. The
|
|
argument passed to <CODE>STOPPED_BY_WATCHPOINT</CODE> is ignored. This
|
|
function examines the breakpoint condition bits in the DR6 Debug
|
|
Status register, as returned by the <CODE>I386_DR_LOW_GET_STATUS</CODE>
|
|
macro, and returns the address associated with the first bit that is
|
|
set in DR6.
|
|
<P>
|
|
|
|
<A NAME="IDX43"></A>
|
|
<A NAME="IDX44"></A>
|
|
<DT><CODE>i386_insert_watchpoint (<VAR>addr</VAR>, <VAR>len</VAR>, <VAR>type</VAR>)</CODE>
|
|
<DD><DT><CODE>i386_remove_watchpoint (<VAR>addr</VAR>, <VAR>len</VAR>, <VAR>type</VAR>)</CODE>
|
|
<DD>Insert or remove a watchpoint. The macros
|
|
<CODE>target_insert_watchpoint</CODE> and <CODE>target_remove_watchpoint</CODE>
|
|
are set to call these functions. <CODE>i386_insert_watchpoint</CODE> 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 <VAR>addr</VAR>, sets the mirrored value of DR7 Debug Control
|
|
register as appropriate for the <VAR>len</VAR> and <VAR>type</VAR> parameters,
|
|
and then passes the new values of the debug register and DR7 to the
|
|
inferior by calling <CODE>I386_DR_LOW_SET_ADDR</CODE> and
|
|
<CODE>I386_DR_LOW_SET_CONTROL</CODE>. If more than one debug register is
|
|
required to cover the given region, the above process is repeated for
|
|
each debug register.
|
|
<P>
|
|
|
|
<CODE>i386_remove_watchpoint</CODE> 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 <CODE>I386_DR_LOW_RESET_ADDR</CODE> and
|
|
<CODE>I386_DR_LOW_SET_CONTROL</CODE>. If a register is shared by several
|
|
watchpoints, each time a <CODE>i386_remove_watchpoint</CODE> is called, it
|
|
decrements the reference count, and only calls
|
|
<CODE>I386_DR_LOW_RESET_ADDR</CODE> and <CODE>I386_DR_LOW_SET_CONTROL</CODE> when
|
|
the count goes to zero.
|
|
</P><P>
|
|
|
|
<A NAME="IDX45"></A>
|
|
<A NAME="IDX46"></A>
|
|
<DT><CODE>i386_insert_hw_breakpoint (<VAR>addr</VAR>, <VAR>shadow</VAR></CODE>
|
|
<DD><DT><CODE>i386_remove_hw_breakpoint (<VAR>addr</VAR>, <VAR>shadow</VAR>)</CODE>
|
|
<DD>These functions insert and remove hardware-assisted breakpoints. The
|
|
macros <CODE>target_insert_hw_breakpoint</CODE> and
|
|
<CODE>target_remove_hw_breakpoint</CODE> are set to call these functions.
|
|
These functions work like <CODE>i386_insert_watchpoint</CODE> and
|
|
<CODE>i386_remove_watchpoint</CODE>, respectively, except that they set up
|
|
the debug registers to watch instruction execution, and each
|
|
hardware-assisted breakpoint always requires exactly one debug
|
|
register.
|
|
<P>
|
|
|
|
<A NAME="IDX47"></A>
|
|
<DT><CODE>i386_stopped_by_hwbp (void)</CODE>
|
|
<DD>This function returns non-zero if the inferior has some watchpoint or
|
|
hardware breakpoint that triggered. It works like
|
|
<CODE>i386_stopped_data_address</CODE>, except that it doesn't return the
|
|
address whose watchpoint triggered.
|
|
<P>
|
|
|
|
<A NAME="IDX48"></A>
|
|
<DT><CODE>i386_cleanup_dregs (void)</CODE>
|
|
<DD>This function clears all the reference counts, addresses, and control
|
|
bits in the mirror images of the debug registers. It doesn't affect
|
|
the actual debug registers in the inferior process.
|
|
</DL>
|
|
<P>
|
|
|
|
<STRONG>Notes:</STRONG>
|
|
<OL>
|
|
<LI>
|
|
x86 processors support setting watchpoints on I/O reads or writes.
|
|
However, since no target supports this (as of March 2001), and since
|
|
<CODE>enum target_hw_bp_type</CODE> doesn't even have an enumeration for I/O
|
|
watchpoints, this feature is not yet available to GDB running
|
|
on x86.
|
|
<P>
|
|
|
|
<LI>
|
|
x86 processors can enable watchpoints locally, for the current task
|
|
only, or globally, for all the tasks. For each debug register,
|
|
there's a bit in the DR7 Debug Control register that determines
|
|
whether the associated address is watched locally or globally. The
|
|
current implementation of x86 watchpoint support in GDB
|
|
always sets watchpoints to be locally enabled, since global
|
|
watchpoints might interfere with the underlying OS and are probably
|
|
unavailable in many platforms.
|
|
</OL>
|
|
<P>
|
|
|
|
<A NAME="User Interface"></A>
|
|
</P><P>
|
|
|
|
<HR SIZE="6">
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_3.html#SEC6"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_4.html#SEC16"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_19.html#SEC186">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="gdbint_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<BR>
|
|
<FONT SIZE="-1">
|
|
|
|
<address>
|
|
|
|
<p>Please send FSF & GNU inquiries & questions to <a
|
|
href="mailto:gnu@gnu.org">gnu@gnu.org</a>. There are also <a
|
|
href="http://www.gnu.org/home.html#ContactInfo">other ways to
|
|
contact</a> the FSF.</p>
|
|
|
|
<p>These pages are maintained by <a
|
|
href="http://www.gnu.org/software/gdb/">the GDB developers</a>.</p>
|
|
|
|
<p>Copyright Free Software Foundation, Inc., 59 Temple Place - Suite
|
|
330, Boston, MA 02111, USA.</p>
|
|
|
|
<p>Verbatim copying and distribution of this entire article is
|
|
permitted in any medium, provided this notice is preserved.</p>
|
|
|
|
</address>
|
|
|
|
This document was generated
|
|
by <I>GDB Administrator</I> on <I>October, 18 2002</I>
|
|
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
|
|
"><I>texi2html</I></A>
|
|
|
|
</BODY>
|
|
</HTML>
|