📄 ch27.htm
字号:
see a screen that resembles the following:</P>
<PRE><FONT COLOR="#0066FF">GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.14 (i486-slakware-linux), Copyright 1995 Free Software Foundation, Inc.
(gdb)
</FONT></PRE>
<P>When you start <TT>gdb</TT>, there are a number of options that you can specify
on the command line. You will probably run <TT>gdb</TT> in the following way:</P>
<PRE><FONT COLOR="#0066FF">gdb <fname>
</FONT></PRE>
<P>When you invoke <TT>gdb</TT> in this way, you are specifying the executable file
that you want to debug. This tells <TT>gdb</TT> to load the executable file with
the name fname. There are also ways of starting <TT>gdb</TT> that tell it to inspect
a core file that was created by the executable file being examined, or to attach
<TT>gdb</TT> to a currently running process. To get a listing and brief description
of each of these other options, you can refer to the <TT>gdb</TT> man page or type
<TT>gdb -h</TT> at the command line.
<H4 ALIGN="CENTER"><A NAME="Heading12<FONT COLOR="#000077">Compiling Code for
Debugging</FONT></H4>
<P>To get <TT>gdb</TT> to work properly, you must compile your programs so that debugging
information will be generated by the compiler. The debugging information that is
generated contains the types for each of the variables in your program as well as
the mapping between the addresses in the executable program and the line numbers
in the source code. <TT>gdb</TT> uses this information to relate the executable code
to the source code.</P>
<P>To compile a program with the debugging information turned on, use the <TT>-g</TT>
compiler option.
<H4 ALIGN="CENTER"><A NAME="Heading13<FONT COLOR="#000077">gdb Basic Commands</FONT></H4>
<P>The <TT>gdb</TT> supports many commands that enable you to perform different debugging
operations. These commands range in complexity from very simple file-loading commands
to complicated commands that allow you to examine the contents of the call stack.
Table 27.1 describes the commands that you will need to get up and debugging with
<TT>gdb</TT>. To get a description of all of the <TT>gdb</TT> commands, refer to
the <TT>gdb</TT> manual page. </P>
<CENTER>
<P><FONT SIZE="4"><B>Table 27.1. Basic gdb commands. </B></FONT>
<TABLE BORDER="0">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><I>Command</I></TD>
<TD ALIGN="LEFT"><I>Description</I></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>file</TT></TD>
<TD ALIGN="LEFT">Loads the executable file that is to be debugged</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>kill</TT></TD>
<TD ALIGN="LEFT">Terminates the program that you are currently debugging</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>list</TT></TD>
<TD ALIGN="LEFT">Lists sections of the source code used to generate the executable file</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>next</TT></TD>
<TD ALIGN="LEFT">Advances one line of source code in the current function, without stepping into other
functions</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>step</TT></TD>
<TD ALIGN="LEFT">Advances one line of source code in the current function, and does step into other
functions</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>run</TT></TD>
<TD ALIGN="LEFT">Executes the program that is currently being debugged</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>quit</TT></TD>
<TD ALIGN="LEFT">Terminates <TT>gdb</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>watch</TT></TD>
<TD ALIGN="LEFT">Enables you to examine the value of a program variable whenever the value changes</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>break</TT></TD>
<TD ALIGN="LEFT">Sets a breakpoint in the code; this causes the execution of the program to be suspended
whenever this point is reached</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>make</TT></TD>
<TD ALIGN="LEFT">Enables you to remake the executable program without quitting <TT>gdb</TT> or using
another window</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>shell</TT></TD>
<TD ALIGN="LEFT">Enables you to execute UNIX shell commands without leaving <TT>gdb</TT> </TD>
</TR>
</TABLE>
</P>
</CENTER>
<P>The <TT>gdb</TT> environment supports many of the same command-editing features
as the UNIX shell programs do. You can tell <TT>gdb</TT> to complete unique commands
by pressing the Tab key just as you do when you are using <TT>bash</TT> or <TT>tcsh</TT>.
If what you have typed in is not unique, you can make <TT>gdb</TT> print a list of
all the commands that match what you have typed in so far by pressing the Tab key
again. You can also scroll up and down through the commands that you have entered
previously by pressing the up and down arrow keys.
<CENTER>
<H4><A NAME="Heading14<FONT COLOR="#000077">Sample gdb Session</FONT></H4>
</CENTER>
<P>This section takes you step by step through a sample <TT>gdb</TT> session. The
sample program that is being debugged is quite simple, but it is sufficient to illustrate
how <TT>gdb</TT> is typically used.</P>
<P>We will start by showing a listing of the program that is to be debugged. The
program is called <TT>greeting</TT> and is supposed to display a simple greeting
followed by the greeting printed in reverse order.</P>
<PRE><FONT COLOR="#0066FF">#include <stdio.h>
main ()
{
char my_string[] = "hello there";
my_print (my_string);
my_print2 (my_string);
}
void my_print (char *string)
{
printf ("The string is %s\n", string);
}
void my_print2 (char *string)
{
char *string2;
int size, i;
size = strlen (string);
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++)
string2[size - i] = string[i];
string2[size+1] = `\0';
printf ("The string printed backward is %s\n", string2);
}
</FONT></PRE>
<P>You can compile the preceding program using the <TT>gcc</TT> command followed
by the filename. If you want to rename the generated binary (instead of using the
default <TT>a.out</TT> filename), use the <TT>-o</TT> option followed by the binary
name, like this:</P>
<PRE><FONT COLOR="#0066FF">gcc -o test test.c
</FONT></PRE>
<P>The program, when executed, displays the following output:</P>
<PRE><FONT COLOR="#0066FF">The string is hello there
The string printed backward is
</FONT></PRE>
<P>The first line of output comes out correctly, but the second line prints something
that was unexpected. We intended the second line of output to be</P>
<PRE><FONT COLOR="#0066FF">The string printed backward is ereht olleh
</FONT></PRE>
<P>For some reason the <TT>my_print2</TT> function is not working properly. Let's
take a look at the problem using <TT>gdb</TT>. First you need to start <TT>gdb</TT>,
specifying the <TT>greeting</TT> program as the one to debug. You do this by typing
the following command:</P>
<PRE><FONT COLOR="#0066FF">gdb greeting
</FONT></PRE>
<DL>
<DT><FONT COLOR="#0066FF"></FONT></DT>
</DL>
<DL>
<DD>
<HR>
<A NAME="Heading15<FONT COLOR="#000077"><B>NOTE:</B> </FONT>Remember that you
must compile the <TT>greeting</TT> program with the compiler debug options turned
on.
<HR>
</DL>
<P>If you forget to pass the program to debug as a parameter to <TT>gdb</TT>, you
can load it in after <TT>gdb</TT> is started by using the file command at the <TT>gdb</TT>
prompt:</P>
<PRE><FONT COLOR="#0066FF">(gdb) file greeting
</FONT></PRE>
<P>This command will load the <TT>greeting</TT> executable just as if you had told
<TT>gdb</TT> to load it on the command line.</P>
<P>You can now run <TT>greeting</TT> by entering the <TT>gdb</TT> run command. When
the program is executed from within <TT>gdb</TT>, the result should resemble the
following:</P>
<PRE><FONT COLOR="#0066FF">(gdb) run
Starting program: /root/greeting
The string is hello there
The string printed backward is
Program exited with code 041
</FONT></PRE>
<P>The output of the <TT>greeting</TT> program is the same as when we executed the
program outside of <TT>gdb</TT>. The question is, why is the backward print not working?
To find the problem we can set a breakpoint at the line after the <TT>for</TT> statement
in the <TT>my_print2</TT> function. To do this, list the source file by entering
the <TT>list</TT> command three times at the <TT>gdb</TT> prompt:</P>
<PRE><FONT COLOR="#0066FF">(gdb) list
(gdb) list
(gdb) list
</FONT></PRE>
<DL>
<DT><FONT COLOR="#0066FF"></FONT></DT>
</DL>
<DL>
<DD>
<HR>
<A NAME="Heading16<FONT COLOR="#000077"><B>TIP:</B> </FONT>Pressing Enter by
itself at the <TT>gdb</TT> prompt will repeat the last command that was entered.
<HR>
</DL>
<P>The first time you enter the <TT>list</TT> command, you get output that resembles
the following:</P>
<PRE><FONT COLOR="#0066FF">1 #include <stdio.h>
2
3 main ()
4 {
5 char my_string[] = "hello there";
6
7 my_print (my_string);
8 my_print2 (my_string);
9 }
10
</FONT></PRE>
<P>If you press Enter, <TT>gdb</TT> will execute the <TT>list</TT> command again,
giving you the following output:</P>
<PRE><FONT COLOR="#0066FF">11 my_print (char *string)
12 {
13 printf ("The string is %s\n", string);
14 }
15
16 my_print2 (char *string)
17 {
18 char *string2;
19 int size, i;
20
</FONT></PRE>
<P>Pressing Enter one more time will list the rest of the <TT>greeting</TT> program:</P>
<PRE><FONT COLOR="#0066FF">21 size = strlen (string);
22 string2 = (char *) malloc (size + 1);
23 for (i = 0; i < size; i++)
24 string2[size - i] = string[i];
25 string2[size+1] = `\0';
26 printf ("The string printed backward is %s\n", string2);
27 }
</FONT></PRE>
<P>By listing the file you can see that the place where you want to set the breakpoint
is line 24. Now, to set the breakpoint, type the following command at the <TT>gdb</TT>
command prompt:</P>
<PRE><FONT COLOR="#0066FF">(gdb) break 24
</FONT></PRE>
<P><TT>gdb</TT> should now print a response resembling the following:</P>
<PRE><FONT COLOR="#0066FF">Breakpoint 1 at 0x139: file greeting.c, line 24
(gdb)
</FONT></PRE>
<P>Now you can run the program again by typing the <TT>run</TT> command. This command
will generate the following output:</P>
<PRE><FONT COLOR="#0066FF">Starting program: /root/greeting
The string is hello there
Breakpoint 1, my_print2 (string = 0xbfffdc4 "hello there") at greeting.c :24
24 string2[size-i]=string[i]
</FONT></PRE>
<P>You can see what is actually going wrong with your program by setting a watch
to tell you the value of the <TT>string2[size - i]</TT> variable expression.</P>
<P>To do this, type</P>
<PRE><FONT COLOR="#0066FF">(gdb) watch string2[size - i]
</FONT></PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -