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 @@
201620172018
+ 2019
+ 2020The FreeBSD Documentation Project
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 @@
- Use gdb to analyze the core (see
+ Use a debugger to analyze the core (see
).
@@ -1325,75 +1325,386 @@
Debugging
- The Debugger
-
- The debugger that comes with FreeBSD is called
+ Introduction to Available Debuggers
+
+ Using a debugger allows running the program under more
+ controlled circumstances. Typically, it is possible to step
+ through the program a line at a time, inspect the value of
+ variables, change them, tell the debugger to run up to a
+ certain point and then stop, and so on. It is also possible
+ to attach to a program that is already running, or load a core
+ file to investigate why the program crashed. It is even
+ possible to debug the kernel, though that is a little trickier
+ than the user applications we will be discussing in this
+ section.
+
+ 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 .
+
+ The standard debugger supplied with
+ &os; &rel121.current; is called lldb
+ (LLVM debugger). As it is part of
+ the standard installation for that release, there is no need
+ to do anything special to use it. It has good command help,
+ accessible via the help command, as
+ well as a web
+ tutorial and documentation.
+
+
+ The lldb command is available for
+ &os; &rel1.current; from
+ ports or packages as
+ devel/llvm. This will install the
+ default version of lldb (currently 9.0).
+
+
+ The other debugger available with &os; is called
gdb (GNU
- debugger). You start it up by typing
+ debugger). Unlike lldb, it is not installed
+ by default on &os; &rel121.current;; to use it, install
+ devel/gdb from ports or packages. The
+ version installed by default on &os; &rel1.current; is
+ old and you should install devel/gdb there
+ as well. It has quite good on-line help, as well as a set of
+ info pages.
+
+ Which one to use is largely a matter of taste. If
+ familiar with one only, use that one. People familiar
+ with neither or both but wanting to use one from inside
+ Emacs will need to use
+ gdb as lldb is
+ unsupported by Emacs. Otherwise,
+ try both and see which one you prefer.
+
+
+
+ Using lldb
+
+
+ Starting lldb
+
+ Start up lldb by typing
+
+ &prompt.user; lldb -- progname
+
+
+
+ Running a Program with lldb
+
+ Compile the program with to get the
+ most out of using lldb. It will work
+ without, but will only display the name of the function
+ currently running, instead of the source code. If it
+ displays a line like:
+
+ Breakpoint 1: where = temp`main, address = …
+
+ (without an indication of source code filename and line
+ number) when setting a breakpoint, this means that the
+ program was not compiled with .
+
+
+ Most lldb commands have shorter
+ forms that can be used instead. The longer forms are
+ used here for clarity.
+
+
+ At the lldb prompt, type
+ breakpoint set -n main. This will
+ tell the debugger not to display the preliminary set-up code
+ in the program being run and to stop execution at the
+ beginning of your code. Now type
+ process launch to actually start the
+ program— it will start at the beginning of the set-up
+ code and then get stopped by the debugger when it calls
+ main().
+
+ To step through the program a line at a time, type
+ thread step-over. When the program
+ gets to a function call, step into it by typing
+ thread step-in. Once in a function
+ call, return from it by typing
+ thread step-out or use
+ up and down to
+ take a quick look at the caller.
+
+ Here is a simple example of how to spot a mistake in a
+ program with lldb. This is our program
+ (with a deliberate mistake):
+
+ #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;
+}
+
+ This program sets i to be
+ 5 and passes it to a function
+ bazz() which prints out the number we
+ gave it.
+
+ Compiling and running the program displays
+
+ &prompt.user; cc -g -o temp temp.c
+&prompt.user; ./temp
+This is my program
+anint = -5360
+
+ That is not what was expected! Time to see what is going
+ on!
+
+ &prompt.user; lldb -- temp
+(lldb) target create "temp"
+Current executable set to 'temp' (x86_64).
+(lldb) breakpoint set -n mainSkip the set-up code
+Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef lldb puts breakpoint at main()
+(lldb) process launchRun as far as main()
+Process 9992 launching
+Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64) Program starts running
+
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = breakpoint 1.1 lldb stops at main()
+ frame #0: 0x00000000002012ef temp`main at temp.c:8:2
+ 5 main() {
+ 6 int i;
+ 7
+-> 8 printf("This is my program\n"); Indicates the line where it stopped
+ 9 bazz(i);
+ 10 return 0;
+ 11 }
+(lldb) thread step-overGo to next line
+This is my program Program prints out
+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) thread step-instep into bazz()
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step in
+ frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29 lldb displays stack frame
+ 11 }
+ 12
+ 13 int bazz(int anint) {
+-> 14 printf("You gave me %d\n", anint);
+ 15 return anint;
+ 16 }
+(lldb)
+
+ Hang on a minute! How did anint get to
+ be -5360? Was it not set to
+ 5 in main()? Let us
+ move up to main() and have a
+ look.
+
+ (lldb) upMove up call stack
+frame #1: 0x000000000020130b temp`main at temp.c:9:2 lldb displays stack frame
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) frame variable iShow us the value of i
+(int) i = -5360 lldb displays -5360
+
+ Oh dear! Looking at the code, we forgot to initialize
+ i. We meant to put
+
+ …
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+…
+
+ but we left the i=5; line out. As we
+ did not initialize i, it had whatever
+ number happened to be in that area of memory when the
+ program ran, which in this case happened to be
+ -5360.
+
+
+ The lldb command displays the stack
+ frame every time we go into or out of a function, even if
+ we are using up and
+ down 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.)
+
+
+
+
+ Examining a Core File with lldb
+
+ A core file is basically a file which contains the
+ complete state of the process when it crashed. In
+ the good old days, 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
+ progname.core
+ instead of just core, to make it
+ clearer which program a core file belongs to.
+
+ To examine a core file, specify the name of the core
+ file in addition to the program itself. Instead of starting
+ up lldb in the usual way, type
+ lldb -c progname.core -- progname
+
+ The debugger will display something like this:
+
+ &prompt.user; lldb -c a.out.core -- a.out
+(lldb) target create "a.out" --core "a.out.core"
+Core file '/home/pauamma/tmp/a.out.core' (x86_64) was loaded.
+(lldb)
+
+ In this case, the program was called
+ a.out, so the core file is called
+ a.out.core. The debugger does not
+ display why the program crashed or where. For this, use
+ thread backtrace all. This will also
+ show how the function where the program dumped core was
+ called.
+
+ (lldb) thread backtrace all
+* 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)
+
+ SIGSEGV 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, look at the source code at line 10
+ of file temp2.c, in bazz(). The
+ backtrace also says that in this case,
+ bazz() was called from
+ main().
+
+
+
+ Attaching to a Running Program with lldb
+
+ One of the neatest features about
+ lldb is that it can attach to a program
+ that is already running. Of course, that requires
+ sufficient permissions to do so. A common problem is
+ stepping through a program that forks and wanting to trace
+ the child, but the debugger will only trace the
+ parent.
+
+ To do that, start up another lldb,
+ use ps to find the process ID for the
+ child, and do
+
+ (lldb) process attach -p pid
+
+ in lldb, and then debug as
+ usual.
+
+ For that to work well, the code that
+ forks the child needs to do something
+ like the following (courtesy of the gdb
+ info pages):
+
+ …
+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 */
+ …
+} else { /* parent */
+ …
+
+ Now all that is needed to do is attach to the child, set
+ PauseMode to 0 with
+ expr PauseMode = 0 and wait
+ for the sleep() call to return.
+
+
+
+
+ Using gdb
+
+
+ Starting gdb
+
+ Start up gdb by typing&prompt.user; gdb prognamealthough many people prefer to run it inside
- Emacs. You can do this by:
+ Emacs. To do this, type:
M-x gdb RET progname RET
- Using a debugger allows you to run the program under more
- controlled circumstances. Typically, you can step through the
- program a line at a time, inspect the value of variables,
- change them, tell the debugger to run up to a certain point
- and then stop, and so on. You can even attach to a program
- that is already running, or load a core file to investigate
- why the program crashed. It is even possible to debug the
- kernel, though that is a little trickier than the user
- applications we will be discussing in this section.
-
- gdb 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.
-
- Finally, if you find its text-based command-prompt style
- off-putting, there is a graphical front-end for it
+ Finally, for those finding its text-based command-prompt
+ style off-putting, there is a graphical front-end for it
(devel/xxgdb) in the Ports
Collection.
- This section is intended to be an introduction to using
- gdb and does not cover specialized topics
- such as debugging the kernel.
-
-
-
- Running a Program in the Debugger
-
- You will need to have compiled the program with
+
+
+
+ Running a Program with gdb
+
+ Compile the program with
to get the most out of using
- gdb. 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:
+ gdb. It will work without, but will
+ only display the name of the function you are in, instead of the
+ source code. A line like:… (no debugging symbols found) …
- when gdb starts up, you will know that
- the program was not compiled with .
+ when gdb starts up means that the
+ program was not compiled with .At the gdb prompt, type
break main. 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
- run 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 main().
- (If you have ever wondered where main()
- gets called from, now you know!).
-
- You can now step through the program, a line at a time, by
- pressing n. If you get to a function call,
- you can step into it by pressing s. Once
- you are in a function call, you can return from stepping into
- a function call by pressing f. You can
- also use up and down to
- take a quick look at the caller.
+ debugger to skip the preliminary set-up code in the program
+ being run and to stop execution at the beginning of your
+ code. Now type run 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
+ main().
+
+ To step through the program a line at a time, press
+ n. When at a function call, step into it
+ by pressing s. Once in a function call,
+ return from it by pressing f, or use
+ up and down to take
+ a quick look at the caller.Here is a simple example of how to spot a mistake in a
program with gdb. This is our program
@@ -1421,7 +1732,7 @@
bazz() which prints out the number we
gave it.
- When we compile and run the program we get
+ Compiling and running the program displays&prompt.user; cc -g -o temp temp.c
&prompt.user; ./temp
@@ -1449,7 +1760,7 @@
(gdb)Hang on a minute! How did anint get to be
- 4231? Did we not we set it to be
+ 4231? Was it not set to
5 in main()? Let us
move up to main() and have a look.
@@ -1476,7 +1787,7 @@
4231.
- gdb displays the stack frame every
+ The gdb command displays the stack frame every
time we go into or out of a function, even if we are using
up and down to move
around the call stack. This shows the name of the function
@@ -1484,12 +1795,12 @@
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).
+ returns from a function call.)
-
-
-
- Examining a Core File
+
+
+
+ Examining a Core File with gdbA core file is basically a file which contains the
complete state of the process when it crashed. In the
@@ -1507,11 +1818,10 @@
(gdb) core progname.core
- If you are not in the same directory as the core file, you
- will have to do dir /path/to/core/file
- first.
-
- You should see something like this:
+ If the core file is not in the current directory, type
+ dir /path/to/core/file first.
+
+ The debugger should display something like this:&prompt.user; gdb a.out
GDB is free software and you are welcome to distribute copies of it
@@ -1547,19 +1857,19 @@
The end() function is called when a
program crashes; in this case, the bazz()
function was called from main().
-
-
-
- Attaching to a Running Program
+
+
+
+ Attaching to a Running Program with gdbOne of the neatest features about gdb
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.
-
- What you do is start up another gdb,
+ Of course, that requires sufficient permissions to do
+ so. A common problem is stepping through a program that forks and
+ wanting to trace the child, but the
+ debugger will only trace the parent.
+
+ To do that, start up another gdb,
use ps to find the process ID for the
child, and do
@@ -1567,11 +1877,10 @@
in gdb, and then debug as usual.
- That is all very well, you are probably
- thinking, but by the time I have done that, the child
- process will be over the hill and far away. Fear
- not, gentle reader, here is how to do it (courtesy of the
- gdb info pages):
+ For that to work well, the code that
+ forks the child needs to do something
+ like the following (courtesy of the gdb
+ info pages):…
if ((pid = fork()) < 0) /* _Always_ check this */
@@ -1585,9 +1894,10 @@
} else { /* parent */
…
- Now all you have to do is attach to the child, set
+ Now all that is needed to do is attach to the child, set
PauseMode to 0, and wait
for the sleep() call to return!
+