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,18 +1325,7 @@
Debugging
- The Debugger
-
- The debugger that comes with FreeBSD is called
- gdb (GNU
- debugger). You start it up by typing
-
- &prompt.user; gdb progname
-
- although many people prefer to run it inside
- Emacs. You can do this by:
-
- M-x gdb RET progname RET
+ Introduction to Available DebuggersUsing 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.
- 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
- (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.
+ 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, you do not have 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.
+
+
+ lldb is available for
+ &os; &rel1.current; from ports or
+ packages as devel/llvm80. If
+ installed that way, the command name to invoke it is
+ lldb80 instead of
+ lldb and you will need to use that
+ command name everywhere below.
+
+
+ The other debugger available with &os; is called
+ gdb (GNU
+ debugger). Unlike lldb, it is not installed
+ by default on &os; &rel121.current;; you need to install
+ devel/gdb from ports or
+ packages. It is, however, installed by default on &os;
+ &rel1.current;. gdb 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 you are
+ familiar with one only, use that one. If you are familiar
+ with neither or both but want to use one from inside
+ Emacs, you should use
+ gdb as lldb is
+ unsupported by Emacs. Otherwise,
+ you could try both and see which one you prefer.
- Running a Program in the Debugger
-
- You will need to have compiled 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:
-
- … (no debugging symbols found) …
-
- when gdb starts up, you will know 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.
-
- Here is a simple example of how to spot a mistake in a
- program with gdb. This is our program
- (with a deliberate mistake):
-
- #include <stdio.h>
+ Using lldb
+
+
+ Starting lldb
+
+ You start up lldb by typing
+
+ &prompt.user; lldb -- progname
+
+
+
+ Running a Program with lldb
+
+ Ensure you have compiled the program with
+ to get the most out of using
+ lldb. 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:
+
+ Breakpoint 1: where = temp`main, address = …
+
+ (without an indication of source code filename and line
+ number) when setting a breakpoint, you will know that the
+ program was not compiled with .
+
+ At the lldb prompt, type
+ breakpoint set -n 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 process launch 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 typing thread step-over. If you
+ get to a function call, you can step into it by typing
+ thread step-in. Once you are in a
+ function call, you can return from it by typing
+ thread step-out. You can also use
+ up and down to
+ take a quick look at the caller.
+
+
+ Most lldb commands have shorter
+ forms that you can use instead. The longer forms are
+ used here for clarity.
+
+
+ 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);
@@ -1416,22 +1455,303 @@
return anint;
}
- This program sets i to be
- 5 and passes it to a function
- bazz() which prints out the number we
- gave it.
-
- When we compile and run the program we get
-
- &prompt.user; cc -g -o temp temp.c
+ This program sets i to be
+ 5 and passes it to a function
+ bazz() which prints out the number we
+ gave it.
+
+ When we compile and run the program we get
+
+ &prompt.user; cc -g -o temp temp.c
&prompt.user; ./temp
This is my program
anint = 4231
- That was not what we expected! Time to see what is going
- on!
-
- &prompt.user; gdb temp
+ That was not what we 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 gdb 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? Did we not set it to be
+ 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.
+
+
+ lldb 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, you need to 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
+
+ You should see 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. We cannot see why the
+ program crashed or where. For this, we need to use
+ thread backtrace all. This will also
+ tell us 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, we would need to look at the
+ source code at line 10 of file temp2.c, in
+ bazz(). The backtrace also tells us
+ that in this case, the bazz() function
+ 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 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 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.
+
+ 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):
+
+ …
+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 you have 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
+
+ You start up gdb by typing
+
+ &prompt.user; gdb progname
+
+ although many people prefer to run it inside
+ Emacs. You can do this
+ by:
+
+ M-x gdb RET progname RET
+
+ Finally, if you find its text-based command-prompt style
+ off-putting, there is a graphical front-end for it
+ (devel/xxgdb) in the Ports
+ Collection.
+
+
+
+
+ Running a Program with gdb
+
+ You will need to have compiled 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:
+
+ … (no debugging symbols found) …
+
+ when gdb starts up, you will know
+ 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.
+
+ Here is a simple example of how to spot a mistake in a
+ program with gdb. 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.
+
+ When we compile and run the program we get
+
+ &prompt.user; cc -g -o temp temp.c
+&prompt.user; ./temp
+This is my program
+anint = 4231
+
+ That was not what we expected! Time to see what is going
+ on!
+
+ &prompt.user; gdb temp
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 gdb displays stack frame
(gdb)
- Hang on a minute! How did anint get to be
- 4231? Did we not we set it to be
- 5 in main()? Let us
- move up to main() and have a look.
-
- (gdb) upMove up call stack
+ Hang on a minute! How did anint get to
+ be 4231? Did we not set it to be
+ 5 in main()? Let us
+ move up to main() and have a
+ look.
+
+ (gdb) upMove up call stack
#1 0x1625 in main () at temp.c:11 gdb displays stack frame
(gdb) p iShow us the value of i
$1 = 4231 gdb displays 4231
- Oh dear! Looking at the code, we forgot to initialize
- i. We meant to put
-
- …
+ Oh dear! Looking at the code, we forgot to initialize
+ i. We meant to put
+
+ …
main() {
int i;
@@ -1469,51 +1790,52 @@
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
- 4231.
-
-
- gdb 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
-
- 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, start up gdb in
- the usual way. Instead of typing break or
- run, type
-
- (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:
-
- &prompt.user; gdb a.out
+ 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
+ 4231.
+
+
+ gdb 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 gdb
+
+ 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, start up gdb
+ in the usual way. Instead of typing
+ break or run,
+ type
+
+ (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:
+
+ &prompt.user; gdb a.out
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)
- In this case, the program was called
- a.out, so the core file is called
- a.out.core. 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
- bazz.
-
- 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. bt
- causes gdb to print out a back-trace of the
- call stack:
-
- (gdb) bt
+ In this case, the program was called
+ a.out, so the core file is called
+ a.out.core. 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
+ bazz.
+
+ 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. bt
+ causes gdb to print out a back-trace of
+ the call stack:
+
+ (gdb) bt
#0 0x164a in bazz (anint=0x5) at temp.c:17
#1 0xefbfd888 in end ()
#2 0x162c in main () at temp.c:11
(gdb)
- The end() function is called when a
- program crashes; in this case, the bazz()
- function was called from main().
-
-
-
- Attaching to a Running Program
-
- One 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,
- use ps to find the process ID for the
- child, and do
-
- (gdb) attach pid
-
- 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):
-
- …
+ The end() function is called when a
+ program crashes; in this case, the
+ bazz() function was called from
+ main().
+
+
+
+ Attaching to a Running Program with gdb
+
+ One 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,
+ use ps to find the process ID for the
+ child, and do
+
+ (gdb) attach pid
+
+ 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):
+
+ …
if ((pid = fork()) < 0) /* _Always_ check this */
error();
else if (pid == 0) { /* child */
@@ -1585,9 +1909,10 @@
} else { /* parent */
…
- Now all you have to do is attach to the child, set
- PauseMode to 0, and wait
- for the sleep() call to return!
+ Now all you have to do is attach to the child, set
+ PauseMode to 0, and wait
+ for the sleep() call to return!
+