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 @@ 2016 2017 2018 + 2019 + 2020 The 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 Debuggers 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. - 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 main Skip the set-up code +Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef lldb puts breakpoint at main() +(lldb) process launch Run 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-over Go 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-in step 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) up Move 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 i Show 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) up Move 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) up Move up call stack #1 0x1625 in main () at temp.c:11 gdb displays stack frame (gdb) p i Show 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! +