Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162368465
D25139.id72696.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
31 KB
Referenced Files
None
Subscribers
None
D25139.id72696.diff
View Options
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; &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; &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; &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>… (no debugging symbols found) …</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—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 <stdio.h>
+ <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 = …</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— 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 <stdio.h>
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>…</lineannotation>
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+<lineannotation>…</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=<unavailable>, cleanup=<unavailable>) 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>…</lineannotation>
+if ((pid = fork()) < 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ <lineannotation>…</lineannotation>
+} else { /* parent */
+ <lineannotation>…</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>… (no debugging symbols found) …</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—
+ 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 <stdio.h>
+
+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>…</lineannotation>
+ <para>Oh dear! Looking at the code, we forgot to initialize
+ <symbol>i</symbol>. We meant to put</para>
+
+ <programlisting><lineannotation>…</lineannotation>
main() {
int i;
@@ -1469,51 +1790,52 @@
printf("This is my program\n");
<lineannotation>…</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>…</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>…</lineannotation>
if ((pid = fork()) < 0) /* _Always_ check this */
error();
else if (pid == 0) { /* child */
@@ -1585,9 +1909,10 @@
} else { /* parent */
<lineannotation>…</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
Details
Attached
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)
Attached To
Mode
D25139: Add lldb version of gdb mini-tutorial.
Attached
Detach File
Event Timeline
Log In to Comment