How To Debug Linux C Programs Effectively Using The Debugger
Introduction
The purpose of this blog is to provide a guide to Linux C (and C++) programmers as to how to use the Gnu DebuGger, GDB, effectively.
My reasons for writing this are because I participate a great deal in the Linux Questions site and view, plus respond to a number of questions in the Programming forum, and I notice that programmers of various experience seem to be lacking in either experience+knowledge, or initiative, to use the debugger.
This blog entry is a complement to my earlier blog Debugging C Programs Using GDB (Including core dumps!)
Audience and Prerequisites
Programmers writing C and C++ user space applications for Linux.
You must have Linux running, you must have the GDB tools installed, such as the build-essential package, and you should use emacs.
I fully understand that the reader may not like emacs. I didn't say you "must", I said you "should".
You absolutely do not have to use emacs, however for the purposes of this blog, I'll show you two examples, the first one using the command line only and a second one using emacs illustrating the benefits of having that user interface available.
Command Line Example From Start To Finish
Code to test:
Note:
Code does not require any standard libraries, we're not printing anything, we're not doing anything crazy here, and 2 raised to the 8th, by the way, is 256.
Raw Steps. More details to be shown later. Command line steps only. Items to enter are listed in bold:
How do you do these feats? By putting in commands at the (gdb) prompt like this:
p a
p b
s
p b
c
p a
p b
<and etc>
Explanation of the commands to the (gdb) prompt:
p a = print a
p b = print b
s = step
p b = print b
c = continue either forever until you loop forever, hit a breakpoint, or complete the program.
quit = quit the debugger and terminate any program in progress.
Please proceed and duplicate the commands to print variables, step, continue, and eventually quit once the program completes. Note that if you didn't cut/paste the sample program exactly, or if you added lines to it, such as additional lines for comments or for other lines reasons, then the breakpoint may have to be at a different line than line #8. Please check the line number where the b = b * 2; resides in your copy. If you copy/pasted exactly and didn't add anything, then it will be at line #8.
You can run GDB from within emacs and it will provide you with a graphical debug capability which will show the source file, an indicator where your point of execution is stopped at (when it is stopped). It can show you a variable watch window, a call stack window, along with other typical debug windows. It also gives you a command line interface to type the very same commands you used above, and will update the source frame to show progress as you hit breakpoints, or step through a program.
The primary benefit for me is that I can see my code as I step through it, and see the variable names, and the emacs interface automatically updates the source position.
How to use GDB from within emacs:
The purpose of this blog is to provide a guide to Linux C (and C++) programmers as to how to use the Gnu DebuGger, GDB, effectively.
My reasons for writing this are because I participate a great deal in the Linux Questions site and view, plus respond to a number of questions in the Programming forum, and I notice that programmers of various experience seem to be lacking in either experience+knowledge, or initiative, to use the debugger.
This blog entry is a complement to my earlier blog Debugging C Programs Using GDB (Including core dumps!)
Audience and Prerequisites
Programmers writing C and C++ user space applications for Linux.
You must have Linux running, you must have the GDB tools installed, such as the build-essential package, and you should use emacs.
I fully understand that the reader may not like emacs. I didn't say you "must", I said you "should".
You absolutely do not have to use emacs, however for the purposes of this blog, I'll show you two examples, the first one using the command line only and a second one using emacs illustrating the benefits of having that user interface available.
Command Line Example From Start To Finish
Code to test:
Code:
void main(void) { int a, b; b = 1; for (a = 0; a < 8; a++ ) { b = b * 2; } }
Code does not require any standard libraries, we're not printing anything, we're not doing anything crazy here, and 2 raised to the 8th, by the way, is 256.
Raw Steps. More details to be shown later. Command line steps only. Items to enter are listed in bold:
- Use your favorite editor and copy/paste or type in the program above, please name it raise.c.
- Use the following command to compile: $ gcc -o raise -ggdb raise.c this should compile the program.Quote:Key Detail: -ggdb enables debugging
- Use GDB to debug the program. $ gdb raise you should get a (gdb) prompt.
- Set a breakpoint for line 8, the one stating b = b * 2; (gdb) b 8 the result should be the string, "Breakpoint 1 at 0x4004ea: file raise.c, line 8.", the hex address will be different on your machine.
- Run the program, (gdb) r the result will be some text, "Starting program: /home/rt/testcode/raise
Breakpoint 1, main () at raise.c:8
8 b = b * 2;"
How do you do these feats? By putting in commands at the (gdb) prompt like this:
p a
p b
s
p b
c
p a
p b
<and etc>
Explanation of the commands to the (gdb) prompt:
p a = print a
p b = print b
s = step
p b = print b
c = continue either forever until you loop forever, hit a breakpoint, or complete the program.
quit = quit the debugger and terminate any program in progress.
Please proceed and duplicate the commands to print variables, step, continue, and eventually quit once the program completes. Note that if you didn't cut/paste the sample program exactly, or if you added lines to it, such as additional lines for comments or for other lines reasons, then the breakpoint may have to be at a different line than line #8. Please check the line number where the b = b * 2; resides in your copy. If you copy/pasted exactly and didn't add anything, then it will be at line #8.
- The breakpoint is within a loop.
- When you run the program and hit the breakpoint, it is during the first iteration of that loop.
- You can hit c to continue up to 7 more times and hit the same breakpoint.
- If/when you hit c an 8th time, it will exit the loop and exit the program.
- You'll see a report saying that an inferior process (process id # shown) has exited with code <number>.
- Seeing as this is a void return function, the code value is not interesting for this case. The tools are extremely useful, but you need to "think" if what they are telling you is purposeful. All you needed here was that the program exited.
You can run GDB from within emacs and it will provide you with a graphical debug capability which will show the source file, an indicator where your point of execution is stopped at (when it is stopped). It can show you a variable watch window, a call stack window, along with other typical debug windows. It also gives you a command line interface to type the very same commands you used above, and will update the source frame to show progress as you hit breakpoints, or step through a program.
The primary benefit for me is that I can see my code as I step through it, and see the variable names, and the emacs interface automatically updates the source position.
How to use GDB from within emacs:
- Enter emacs and have the source file open for editing.
- Enter the emacs command mode, using ESC-x (hitting ESCAPE and then pressing 'x') you'll get a command prompt that appears like "M-x "
- Type in gdb and hit return, the command prompt line will appear like "Run gdb (like this): gdb -i=mi raise" implying that you are asking to run GDB of the code.
- Hitting return at this point will start GDB and get you a new emacs buffer showing the (gdb) prompt.
- From this point, you can type in the commands desired. For instance using the Gud menu to add breakpoints, watchpoints, and other items to perform symbolic debugging using a fairly good Integrated Development Environment (IDE).
- I myself have not used too many utilities from within emacs, I type a lot in the emacs command prompt and mainly view the source as it updates with a dual display of the source and the command line. You can however open a watch window, or view the call stack in a window. The full capabilities are things you can explore in more detail as you use the interface more.
Total Comments 1
Comments
-
OMG, one could spend a lifetime learning emacs and still only scratch the surface. I'd never tried the gdb integration before. I've been missing out, it's awesome.
Thanks for prompting me to try it.Posted 02-20-2019 at 06:32 PM by GazL