Debugging with gdb. The gnu Source-Level Debugger. Ninth Edition, for gdb version cvs. (Sourcery G++ Lite q). Richard Stallman . GDB, short for GNU Debugger, is the most popular debugger for UNIX This tutorial provides a brief introduction on how to use GDB commands to ensure. GDB Tutorial. A Walkthrough with Examples. CMSC - Spring Last modified March 22, GDB Tutorial.
|Language:||English, Spanish, German|
|Genre:||Politics & Laws|
|Distribution:||Free* [*Registration needed]|
The material in this tutorial is condensed from the on-line GNU GDB manual. The Use the run (abbreviated r) command to start your program under GDB. Start GDB (with optional core dump). # gdb --args Start GDB and pass arguments. # gdb --pid. Start GDB and attach to process. You can use GDB to debug programs written in C or C++. For more Michael Tiemann is the author of most of the gnu C++ support in GDB, with significant.
Running the dispatcher And killing the application. Waiting for the thread to die Understand the Situation: The Downwards Investigation In the first part of the investigation, we'll try to understand why the application is blocked.
We'll dive into the code to figure out what drives the execution into that bug. Let's run the application with GDB. Sleeping for 2 seconds New lead: why the dispatcher thread doesn't quit the dispatching loop?
Don't pay attention to that, it's because of compiler optimizations. Recompile libevent with -O0 flag or ignore it!
With a quick search in event. Is it ever called? That's the probe effect we see here. So that's certainly a dead-end. That could also be the reason of the bug, but the fact that the debugger interrupt makes the application finish properly tells me to let that idea aside.
Next candidate? New lead: How is epoll supposed to quit its polling loop? Damn, it's gone, that's the probe effect So timeout remains Clue 2: The dispatcher thread waits for a notification. We saw something like that earlier on, where was that But the name looks like a preprocessor macro If you can recompile the code, you can add a error to ensure it: error "Compilation will crash if we pass here.
Now it makes sense: Intermediate conclusion regarding the visible error: the dispatcher thread is blocked forever: and waits for an epoll notification that never comes, then it should check a flag for breaking its listening loop the main thread sets the loop-breaking flag, but fails to notify epoll, so the dispatcher thread never checks the flag then it waits forever for the dispatcher thread completion.
Problem solved! Or maybe not, maybe we just understood the situation. Understanding the Reason of the Invalid State: Backwards Investigation Now that we are at the bottom of the callstacks, we need to go backwards in time: The state of the application is invalid, the notify function pointer has to be set, so why is it empty?
Is this function ever called?
New lead: How to 'make the base notifiable'? It also sort of assumes that you basically know what debugging is and that you have used a debugger on another system. Source code To help illustrate some of the debugging principles I will use a running example of a buggy program. As you progress through this tutorial, you will use the debugger to locate and fix errors in the code.
The code can be downloaded here and a simple Makefile for the program can be downloaded here. The code is very simple and consists of two class definitions, a node and a linked list. There is also a simple driver to test the list.
All of the code was placed into a single file to make illustrating the process of debugging a little easier. Preparations Environment settings gdb is in the gnu package on CEC machines. If you don't have this package loaded then type pkgadd gnu at a shell prompt. For Sun CC users, there is the dbx debugger which is very similar to gdb.
For even more information, the -ggdb switch can be used which includes debugging symbols which are specific to gdb. The makefile for this tutorial uses the -ggdb switch. Debugging When to use a debugger Debugging is something that can't be avoided. Every programmer will at one point in their programming career have to debug a section of code. There are many ways to go about debugging, from printing out messages to the screen, using a debugger, or just thinking about what the program is doing and making an educated guess as to what the problem is.
Before a bug can be fixed, the source of the bug must be located. For example, with segmentation faults, it is useful to know on which line of code the seg fault is occuring. Once the line of code in question has been found, it is useful to know about the values in that method, who called the method, and why specifically the error is occuring.
Using a debugger makes finding all of this information very simple. Go ahead and make the program for this tutorial, and run the program. The program will print out some messages, and then it will print that it has received a segmentation fault signal, resulting in a program crash. Given the information on the screen at this point, it is near impossible to determine why the program crashed, much less how to fix the problem.
We will now begin to debug this program.
Loading a program So you now have an executable file in this case main and you want to debug it. First you must launch the debugger. The debugger is called gdb and you can tell it which file to debug at the shell prompt. So to debug main we want to type gdb main.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-solaris2. Then Emacs will split into two windows, where the second window will show the source code with a cursor at the current instruction.
I haven't actually used gdb this way, but I have been told by a very reliable source that this will work. We need to run the program so that the debugger can help us see what happens when the program crashes.
Type run at the gdb prompt. Inspecting crashes So already we can see the that the program was at line 28 of main.
But we also want to know who called this method and we would like to be able to examine values in the calling methods. This can be done using the x command using the address as a parameter. We have now narrowed the problem down to a specific function and a specific value for the parameter.
Conditional breakpoints Now that we know where and when the segfault is occuring, we want to watch what the program is doing right before it crashes. One way to do this is to step through, one at a time, every statement of the program until we get to the point of execution where we want to see what is happening.