Page MenuHomeFreeBSD

D25139.id72696.diff
No OneTemporary

D25139.id72696.diff

Index: en_US.ISO8859-1/books/developers-handbook/book.xml
===================================================================
--- en_US.ISO8859-1/books/developers-handbook/book.xml
+++ en_US.ISO8859-1/books/developers-handbook/book.xml
@@ -36,6 +36,8 @@
<year>2016</year>
<year>2017</year>
<year>2018</year>
+ <year>2019</year>
+ <year>2020</year>
<holder>The FreeBSD Documentation Project</holder>
</copyright>
Index: en_US.ISO8859-1/books/developers-handbook/tools/chapter.xml
===================================================================
--- en_US.ISO8859-1/books/developers-handbook/tools/chapter.xml
+++ en_US.ISO8859-1/books/developers-handbook/tools/chapter.xml
@@ -832,7 +832,7 @@
</question>
<answer>
- <para>Use <command>gdb</command> to analyze the core (see
+ <para>Use a debugger to analyze the core (see
<xref linkend="debugging"/>).</para>
</answer>
</qandaentry>
@@ -1325,18 +1325,7 @@
<title>Debugging</title>
<sect2>
- <title>The Debugger</title>
-
- <para>The debugger that comes with FreeBSD is called
- <command>gdb</command> (<application>GNU
- debugger</application>). You start it up by typing</para>
-
- <screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
-
- <para>although many people prefer to run it inside
- <application>Emacs</application>. You can do this by:</para>
-
- <screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
+ <title>Introduction to Available Debuggers</title>
<para>Using a debugger allows you to run the program under more
controlled circumstances. Typically, you can step through the
@@ -1348,58 +1337,108 @@
kernel, though that is a little trickier than the user
applications we will be discussing in this section.</para>
- <para><command>gdb</command> has quite good on-line help, as
- well as a set of info pages, so this section will concentrate
- on a few of the basic commands.</para>
-
- <para>Finally, if you find its text-based command-prompt style
- off-putting, there is a graphical front-end for it
- (<package>devel/xxgdb</package>) in the Ports
- Collection.</para>
-
- <para>This section is intended to be an introduction to using
- <command>gdb</command> and does not cover specialized topics
- such as debugging the kernel.</para>
+ <para>This section is intended to be a quick introduction to
+ using debuggers and does not cover specialized topics such as
+ debugging the kernel. For more information about that, refer
+ to <xref linkend="kerneldebug" />.</para>
+
+ <para>The standard debugger supplied with
+ &os;&nbsp;&rel121.current; is called <command>lldb</command>
+ (<application>LLVM debugger</application>). As it is part of
+ the standard installation for that release, you do not have to
+ do anything special to use it. It has good command help,
+ accessible via the <userinput>help</userinput> command, as
+ well as <link xlink:href="https://lldb.llvm.org/">a web
+ tutorial and documentation</link>.</para>
+
+ <note>
+ <para><command>lldb</command> is available for
+ &os;&nbsp;&rel1.current; <link
+ xlink:href="&url.books.handbook;/ports.html">from ports or
+ packages as <package>devel/llvm80</package></link>. If
+ installed that way, the command name to invoke it is
+ <userinput>lldb80</userinput> instead of
+ <userinput>lldb</userinput> and you will need to use that
+ command name everywhere below.</para>
+ </note>
+
+ <para>The other debugger available with &os; is called
+ <command>gdb</command> (<application>GNU
+ debugger</application>). Unlike lldb, it is not installed
+ by default on &os;&nbsp;&rel121.current;; you need to <link
+ xlink:href="&url.books.handbook;/ports.html">install
+ <package>devel/gdb</package> from ports or
+ packages</link>. It is, however, installed by default on &os;
+ &rel1.current;. <command>gdb</command> has quite good
+ on-line help, as well as a set of info pages.</para>
+
+ <para>Which one to use is largely a matter of taste. If you are
+ familiar with one only, use that one. If you are familiar
+ with neither or both but want to use one from inside
+ <application>Emacs</application>, you should use
+ <command>gdb</command> as <command>lldb</command> is
+ unsupported by <application>Emacs</application>. Otherwise,
+ you could try both and see which one you prefer.</para>
</sect2>
<sect2>
- <title>Running a Program in the Debugger</title>
-
- <para>You will need to have compiled the program with
- <option>-g</option> to get the most out of using
- <command>gdb</command>. It will work without, but you will
- only see the name of the function you are in, instead of the
- source code. If you see a line like:</para>
-
- <screen>&hellip; (no debugging symbols found) &hellip;</screen>
-
- <para>when <command>gdb</command> starts up, you will know that
- the program was not compiled with <option>-g</option>.</para>
-
- <para>At the <command>gdb</command> prompt, type
- <userinput>break main</userinput>. This will tell the
- debugger that you are not interested in watching the
- preliminary set-up code in the program being run, and that it
- should stop execution at the beginning of your code. Now type
- <userinput>run</userinput> to start the program&mdash;it will
- start at the beginning of the set-up code and then get stopped
- by the debugger when it calls <function>main()</function>.
- (If you have ever wondered where <function>main()</function>
- gets called from, now you know!).</para>
-
- <para>You can now step through the program, a line at a time, by
- pressing <command>n</command>. If you get to a function call,
- you can step into it by pressing <command>s</command>. Once
- you are in a function call, you can return from stepping into
- a function call by pressing <command>f</command>. You can
- also use <command>up</command> and <command>down</command> to
- take a quick look at the caller.</para>
-
- <para>Here is a simple example of how to spot a mistake in a
- program with <command>gdb</command>. This is our program
- (with a deliberate mistake):</para>
-
- <programlisting>#include &lt;stdio.h&gt;
+ <title>Using lldb</title>
+
+ <sect3>
+ <title>Starting lldb</title>
+
+ <para>You start up lldb by typing</para>
+
+ <screen>&prompt.user; <userinput>lldb -- <replaceable>progname</replaceable></userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Running a Program with lldb</title>
+
+ <para>Ensure you have compiled the program with
+ <option>-g</option> to get the most out of using
+ <command>lldb</command>. It will work without, but you will
+ only see the name of the function you are in, instead of the
+ source code. If you see a line like:</para>
+
+ <screen>Breakpoint 1: where = temp`main, address = &hellip;</screen>
+
+ <para>(without an indication of source code filename and line
+ number) when setting a breakpoint, you will know that the
+ program was not compiled with <option>-g</option>.</para>
+
+ <para>At the <command>lldb</command> prompt, type
+ <userinput>breakpoint set -n main</userinput>. This will
+ tell the debugger that you are not interested in watching
+ the preliminary set-up code in the program being run, and
+ that it should stop execution at the beginning of your code.
+ Now type <userinput>process launch</userinput> to start the
+ program&mdash; it will start at the beginning of the set-up
+ code and then get stopped by the debugger when it calls
+ <function>main()</function>. (If you have ever wondered
+ where <function>main()</function> gets called from, now you
+ know!).</para>
+
+ <para>You can now step through the program, a line at a time,
+ by typing <userinput>thread step-over</userinput>. If you
+ get to a function call, you can step into it by typing
+ <userinput>thread step-in</userinput>. Once you are in a
+ function call, you can return from it by typing
+ <userinput>thread step-out</userinput>. You can also use
+ <userinput>up</userinput> and <userinput>down</userinput> to
+ take a quick look at the caller.</para>
+
+ <tip>
+ <para>Most <command>lldb</command> commands have shorter
+ forms that you can use instead. The longer forms are
+ used here for clarity.</para>
+ </tip>
+
+ <para>Here is a simple example of how to spot a mistake in a
+ program with <command>lldb</command>. This is our program
+ (with a deliberate mistake):</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
int bazz(int anint);
@@ -1416,22 +1455,303 @@
return anint;
}</programlisting>
- <para>This program sets <symbol>i</symbol> to be
- <literal>5</literal> and passes it to a function
- <function>bazz()</function> which prints out the number we
- gave it.</para>
-
- <para>When we compile and run the program we get</para>
-
- <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
+ <para>This program sets <symbol>i</symbol> to be
+ <literal>5</literal> and passes it to a function
+ <function>bazz()</function> which prints out the number we
+ gave it.</para>
+
+ <para>When we compile and run the program we get</para>
+
+ <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
&prompt.user; <userinput>./temp</userinput>
This is my program
anint = 4231</screen>
- <para>That was not what we expected! Time to see what is going
- on!</para>
-
- <screen>&prompt.user; <userinput>gdb temp</userinput>
+ <para>That was not what we expected! Time to see what is going
+ on!</para>
+
+ <screen>&prompt.user; <userinput>lldb -- temp</userinput>
+(lldb) target create "temp"
+Current executable set to 'temp' (x86_64).
+(lldb) <userinput>breakpoint set -n main</userinput> <lineannotation>Skip the set-up code</lineannotation>
+Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef <lineannotation>lldb puts breakpoint at main()</lineannotation>
+(lldb) <userinput>process launch</userinput> <lineannotation>Run as far as main()</lineannotation>
+Process 9992 launching
+Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64) <lineannotation>Program starts running</lineannotation>
+
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = breakpoint 1.1 <lineannotation>lldb stops at main()</lineannotation>
+ frame #0: 0x00000000002012ef temp`main at temp.c:8:2
+ 5 main() {
+ 6 int i;
+ 7
+-> 8 printf("This is my program\n"); <lineannotation>Indicates the line where it stopped</lineannotation>
+ 9 bazz(i);
+ 10 return 0;
+ 11 }
+(lldb) <userinput>thread step-over</userinput> <lineannotation>Go to next line</lineannotation>
+This is my program <lineannotation>Program prints out</lineannotation>
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step over
+ frame #0: 0x0000000000201300 temp`main at temp.c:9:7
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) <userinput>thread step-in</userinput> <lineannotation>step into bazz()</lineannotation>
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step in
+ frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29 <lineannotation>gdb displays stack frame</lineannotation>
+ 11 }
+ 12
+ 13 int bazz(int anint) {
+-> 14 printf("You gave me %d\n", anint);
+ 15 return anint;
+ 16 }
+(lldb)</screen>
+
+ <para>Hang on a minute! How did <symbol>anint</symbol> get to
+ be <literal>-5360</literal>? Did we not set it to be
+ <literal>5</literal> in <function>main()</function>? Let us
+ move up to <function>main()</function> and have a
+ look.</para>
+
+ <screen>(lldb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
+frame #1: 0x000000000020130b temp`main at temp.c:9:2 <lineannotation>lldb displays stack frame</lineannotation>
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) <userinput>frame variable i</userinput> <lineannotation>Show us the value of i</lineannotation>
+(int) i = -5360 <lineannotation>lldb displays -5360</lineannotation></screen>
+
+ <para>Oh dear! Looking at the code, we forgot to initialize
+ <symbol>i</symbol>. We meant to put</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+<lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>but we left the <literal>i=5;</literal> line out. As we
+ did not initialize <symbol>i</symbol>, it had whatever
+ number happened to be in that area of memory when the
+ program ran, which in this case happened to be
+ <literal>-5360</literal>.</para>
+
+ <note>
+ <para><command>lldb</command> displays the stack frame every
+ time we go into or out of a function, even if we are using
+ <userinput>up</userinput> and <userinput>down</userinput>
+ to move around the call stack. This shows the name of the
+ function and the values of its arguments, which helps us
+ keep track of where we are and what is going on. (The
+ stack is a storage area where the program stores
+ information about the arguments passed to functions and
+ where to go when it returns from a function call.)</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Examining a Core File with lldb</title>
+
+ <para>A core file is basically a file which contains the
+ complete state of the process when it crashed. In
+ <quote>the good old days</quote>, programmers had to print
+ out hex listings of core files and sweat over machine code
+ manuals, but now life is a bit easier. Incidentally, under
+ FreeBSD and other 4.4BSD systems, a core file is called
+ <filename><replaceable>progname</replaceable>.core</filename>
+ instead of just <filename>core</filename>, to make it
+ clearer which program a core file belongs to.</para>
+
+ <para>To examine a core file, you need to specify the name of
+ the core file in addition to the program itself. Instead of
+ starting up <command>lldb</command> in the usual way, type
+ <userinput>lldb -c <replaceable>progname</replaceable>.core -- <replaceable>progname</replaceable></userinput></para>
+
+ <para>You should see something like this:</para>
+
+ <screen>&prompt.user; <userinput>lldb -c a.out.core -- a.out</userinput>
+(lldb) target create "a.out" --core "a.out.core"
+Core file '/home/pauamma/tmp/a.out.core' (x86_64) was loaded.
+(lldb)</screen>
+
+ <para>In this case, the program was called
+ <filename>a.out</filename>, so the core file is called
+ <filename>a.out.core</filename>. We cannot see why the
+ program crashed or where. For this, we need to use
+ <userinput>thread backtrace all</userinput>. This will also
+ tell us how the function where the program dumped core was
+ called.</para>
+
+ <screen>(lldb) <userinput>thread backtrace all</userinput>
+* thread #1, name = 'a.out', stop reason = signal SIGSEGV
+ * frame #0: 0x0000000000201347 a.out`bazz(anint=5) at temp2.c:17:10
+ frame #1: 0x0000000000201312 a.out`main at temp2.c:10:2
+ frame #2: 0x000000000020110f a.out`_start(ap=&lt;unavailable&gt;, cleanup=&lt;unavailable&gt;) at crt1.c:76:7
+(lldb)</screen>
+
+ <para><literal>SIGSEGV</literal> indicates that the program
+ tried to access memory (run code or read/write data usually)
+ at a location that does not belong to it, but does not give
+ any specifics. For that, we would need to look at the
+ source code at line 10 of file temp2.c, in
+ <function>bazz()</function>. The backtrace also tells us
+ that in this case, the <function>bazz()</function> function
+ was called from <function>main()</function>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Attaching to a Running Program with lldb</title>
+
+ <para>One of the neatest features about
+ <command>lldb</command> is that it can attach to a program
+ that is already running. Of course, that assumes you have
+ sufficient permissions to do so. A common problem is when
+ you are stepping through a program that forks, and you want
+ to trace the child, but the debugger will only let you trace
+ the parent.</para>
+
+ <para>What you do is start up another <command>lldb</command>,
+ use <command>ps</command> to find the process ID for the
+ child, and do</para>
+
+ <screen>(lldb) <userinput>process attach -p <replaceable>pid</replaceable></userinput></screen>
+
+ <para>in <command>lldb</command>, and then debug as
+ usual.</para>
+
+ <para><quote>That is all very well,</quote> you are probably
+ thinking, <quote>but by the time I have done that, the child
+ process will be over the hill and far away</quote>. Fear
+ not, gentle reader, here is how to do it (courtesy of the
+ <command>gdb</command> info pages):</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+if ((pid = fork()) &lt; 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ <lineannotation>&hellip;</lineannotation>
+} else { /* parent */
+ <lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>Now all you have to do is attach to the child, set
+ <symbol>PauseMode</symbol> to <literal>0</literal> with
+ <userinput>expr PauseMode = 0</userinput> and wait
+ for the <function>sleep()</function> call to return!</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Using gdb</title>
+
+ <sect3>
+ <title>Starting gdb</title>
+
+ <para>You start up gdb by typing</para>
+
+ <screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
+
+ <para>although many people prefer to run it inside
+ <application>Emacs</application>. You can do this
+ by:</para>
+
+ <screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
+
+ <para>Finally, if you find its text-based command-prompt style
+ off-putting, there is a graphical front-end for it
+ (<package>devel/xxgdb</package>) in the Ports
+ Collection.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>Running a Program with gdb</title>
+
+ <para>You will need to have compiled the program with
+ <option>-g</option> to get the most out of using
+ <command>gdb</command>. It will work without, but you will
+ only see the name of the function you are in, instead of the
+ source code. If you see a line like:</para>
+
+ <screen>&hellip; (no debugging symbols found) &hellip;</screen>
+
+ <para>when <command>gdb</command> starts up, you will know
+ that the program was not compiled with
+ <option>-g</option>.</para>
+
+ <para>At the <command>gdb</command> prompt, type
+ <userinput>break main</userinput>. This will tell the
+ debugger that you are not interested in watching the
+ preliminary set-up code in the program being run, and that
+ it should stop execution at the beginning of your code. Now
+ type <userinput>run</userinput> to start the program&mdash;
+ it will start at the beginning of the set-up code and then
+ get stopped by the debugger when it calls
+ <function>main()</function>. (If you have ever wondered
+ where <function>main()</function> gets called from, now you
+ know!).</para>
+
+ <para>You can now step through the program, a line at a time,
+ by pressing <command>n</command>. If you get to a function
+ call, you can step into it by pressing <command>s</command>.
+ Once you are in a function call, you can return from
+ stepping into a function call by pressing
+ <command>f</command>. You can also use
+ <command>up</command> and <command>down</command> to take
+ a quick look at the caller.</para>
+
+ <para>Here is a simple example of how to spot a mistake in a
+ program with <command>gdb</command>. This is our program
+ (with a deliberate mistake):</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+
+int bazz(int anint);
+
+main() {
+ int i;
+
+ printf("This is my program\n");
+ bazz(i);
+ return 0;
+}
+
+int bazz(int anint) {
+ printf("You gave me %d\n", anint);
+ return anint;
+}</programlisting>
+
+ <para>This program sets <symbol>i</symbol> to be
+ <literal>5</literal> and passes it to a function
+ <function>bazz()</function> which prints out the number we
+ gave it.</para>
+
+ <para>When we compile and run the program we get</para>
+
+ <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
+&prompt.user; <userinput>./temp</userinput>
+This is my program
+anint = 4231</screen>
+
+ <para>That was not what we expected! Time to see what is going
+ on!</para>
+
+ <screen>&prompt.user; <userinput>gdb temp</userinput>
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.
@@ -1448,20 +1768,21 @@
bazz (anint=4231) at temp.c:17 <lineannotation>gdb displays stack frame</lineannotation>
(gdb)</screen>
- <para>Hang on a minute! How did <symbol>anint</symbol> get to be
- <literal>4231</literal>? Did we not we set it to be
- <literal>5</literal> in <function>main()</function>? Let us
- move up to <function>main()</function> and have a look.</para>
-
- <screen>(gdb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
+ <para>Hang on a minute! How did <symbol>anint</symbol> get to
+ be <literal>4231</literal>? Did we not set it to be
+ <literal>5</literal> in <function>main()</function>? Let us
+ move up to <function>main()</function> and have a
+ look.</para>
+
+ <screen>(gdb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
#1 0x1625 in main () at temp.c:11 <lineannotation>gdb displays stack frame</lineannotation>
(gdb) <userinput>p i</userinput> <lineannotation>Show us the value of i</lineannotation>
$1 = 4231 <lineannotation>gdb displays 4231</lineannotation></screen>
- <para>Oh dear! Looking at the code, we forgot to initialize
- <symbol>i</symbol>. We meant to put</para>
-
- <programlisting><lineannotation>&hellip;</lineannotation>
+ <para>Oh dear! Looking at the code, we forgot to initialize
+ <symbol>i</symbol>. We meant to put</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
main() {
int i;
@@ -1469,51 +1790,52 @@
printf("This is my program\n");
<lineannotation>&hellip;</lineannotation></programlisting>
- <para>but we left the <literal>i=5;</literal> line out. As we
- did not initialize <symbol>i</symbol>, it had whatever number
- happened to be in that area of memory when the program ran,
- which in this case happened to be
- <literal>4231</literal>.</para>
-
- <note>
- <para><command>gdb</command> displays the stack frame every
- time we go into or out of a function, even if we are using
- <command>up</command> and <command>down</command> to move
- around the call stack. This shows the name of the function
- and the values of its arguments, which helps us keep track
- of where we are and what is going on. (The stack is a
- storage area where the program stores information about the
- arguments passed to functions and where to go when it
- returns from a function call).</para>
- </note>
- </sect2>
-
- <sect2>
- <title>Examining a Core File</title>
-
- <para>A core file is basically a file which contains the
- complete state of the process when it crashed. In <quote>the
- good old days</quote>, programmers had to print out hex
- listings of core files and sweat over machine code manuals,
- but now life is a bit easier. Incidentally, under FreeBSD and
- other 4.4BSD systems, a core file is called
- <filename><replaceable>progname</replaceable>.core</filename>
- instead of just <filename>core</filename>, to make it clearer
- which program a core file belongs to.</para>
-
- <para>To examine a core file, start up <command>gdb</command> in
- the usual way. Instead of typing <command>break</command> or
- <command>run</command>, type</para>
-
- <screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
-
- <para>If you are not in the same directory as the core file, you
- will have to do <userinput>dir /path/to/core/file</userinput>
- first.</para>
-
- <para>You should see something like this:</para>
-
- <screen>&prompt.user; <userinput>gdb a.out</userinput>
+ <para>but we left the <literal>i=5;</literal> line out. As we
+ did not initialize <symbol>i</symbol>, it had whatever
+ number happened to be in that area of memory when the
+ program ran, which in this case happened to be
+ <literal>4231</literal>.</para>
+
+ <note>
+ <para><command>gdb</command> displays the stack frame every
+ time we go into or out of a function, even if we are using
+ <command>up</command> and <command>down</command> to move
+ around the call stack. This shows the name of the
+ function and the values of its arguments, which helps us
+ keep track of where we are and what is going on. (The
+ stack is a storage area where the program stores
+ information about the arguments passed to functions and
+ where to go when it returns from a function call.)</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Examining a Core File with gdb</title>
+
+ <para>A core file is basically a file which contains the
+ complete state of the process when it crashed. In
+ <quote>the good old days</quote>, programmers had to print
+ out hex listings of core files and sweat over machine code
+ manuals, but now life is a bit easier. Incidentally, under
+ FreeBSD and other 4.4BSD systems, a core file is called
+ <filename><replaceable>progname</replaceable>.core</filename>
+ instead of just <filename>core</filename>, to make it
+ clearer which program a core file belongs to.</para>
+
+ <para>To examine a core file, start up <command>gdb</command>
+ in the usual way. Instead of typing
+ <command>break</command> or <command>run</command>,
+ type</para>
+
+ <screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
+
+ <para>If you are not in the same directory as the core file,
+ you will have to do <userinput>dir
+ /path/to/core/file</userinput> first.</para>
+
+ <para>You should see something like this:</para>
+
+ <screen>&prompt.user; <userinput>gdb a.out</userinput>
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.
@@ -1525,55 +1847,57 @@
#0 0x164a in bazz (anint=0x5) at temp.c:17
(gdb)</screen>
- <para>In this case, the program was called
- <filename>a.out</filename>, so the core file is called
- <filename>a.out.core</filename>. We can see that the program
- crashed due to trying to access an area in memory that was not
- available to it in a function called
- <function>bazz</function>.</para>
-
- <para>Sometimes it is useful to be able to see how a function
- was called, as the problem could have occurred a long way up
- the call stack in a complex program. <command>bt</command>
- causes <command>gdb</command> to print out a back-trace of the
- call stack:</para>
-
- <screen>(gdb) <userinput>bt</userinput>
+ <para>In this case, the program was called
+ <filename>a.out</filename>, so the core file is called
+ <filename>a.out.core</filename>. We can see that the
+ program crashed due to trying to access an area in memory
+ that was not available to it in a function called
+ <function>bazz</function>.</para>
+
+ <para>Sometimes it is useful to be able to see how a function
+ was called, as the problem could have occurred a long way up
+ the call stack in a complex program. <command>bt</command>
+ causes <command>gdb</command> to print out a back-trace of
+ the call stack:</para>
+
+ <screen>(gdb) <userinput>bt</userinput>
#0 0x164a in bazz (anint=0x5) at temp.c:17
#1 0xefbfd888 in end ()
#2 0x162c in main () at temp.c:11
(gdb)</screen>
- <para>The <function>end()</function> function is called when a
- program crashes; in this case, the <function>bazz()</function>
- function was called from <function>main()</function>.</para>
- </sect2>
-
- <sect2>
- <title>Attaching to a Running Program</title>
-
- <para>One of the neatest features about <command>gdb</command>
- is that it can attach to a program that is already running.
- Of course, that assumes you have sufficient permissions to do
- so. A common problem is when you are stepping through a
- program that forks, and you want to trace the child, but the
- debugger will only let you trace the parent.</para>
-
- <para>What you do is start up another <command>gdb</command>,
- use <command>ps</command> to find the process ID for the
- child, and do</para>
-
- <screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
-
- <para>in <command>gdb</command>, and then debug as usual.</para>
-
- <para><quote>That is all very well,</quote> you are probably
- thinking, <quote>but by the time I have done that, the child
- process will be over the hill and far away</quote>. Fear
- not, gentle reader, here is how to do it (courtesy of the
- <command>gdb</command> info pages):</para>
-
- <programlisting><lineannotation>&hellip;</lineannotation>
+ <para>The <function>end()</function> function is called when a
+ program crashes; in this case, the
+ <function>bazz()</function> function was called from
+ <function>main()</function>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Attaching to a Running Program with gdb</title>
+
+ <para>One of the neatest features about <command>gdb</command>
+ is that it can attach to a program that is already running.
+ Of course, that assumes you have sufficient permissions to
+ do so. A common problem is when you are stepping through a
+ program that forks, and you want to trace the child, but the
+ debugger will only let you trace the parent.</para>
+
+ <para>What you do is start up another <command>gdb</command>,
+ use <command>ps</command> to find the process ID for the
+ child, and do</para>
+
+ <screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
+
+ <para>in <command>gdb</command>, and then debug as
+ usual.</para>
+
+ <para><quote>That is all very well,</quote> you are probably
+ thinking, <quote>but by the time I have done that, the child
+ process will be over the hill and far away</quote>. Fear
+ not, gentle reader, here is how to do it (courtesy of the
+ <command>gdb</command> info pages):</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
if ((pid = fork()) &lt; 0) /* _Always_ check this */
error();
else if (pid == 0) { /* child */
@@ -1585,9 +1909,10 @@
} else { /* parent */
<lineannotation>&hellip;</lineannotation></programlisting>
- <para>Now all you have to do is attach to the child, set
- <symbol>PauseMode</symbol> to <literal>0</literal>, and wait
- for the <function>sleep()</function> call to return!</para>
+ <para>Now all you have to do is attach to the child, set
+ <symbol>PauseMode</symbol> to <literal>0</literal>, and wait
+ for the <function>sleep()</function> call to return!</para>
+ </sect3>
</sect2>
</sect1>

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 13, 1:46 PM (12 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35034659
Default Alt Text
D25139.id72696.diff (31 KB)

Event Timeline