How To Use Gdb Debugger
[LUPG Abode] [Tutorials] [Related Fabric] [Essays] [Project Ideas] [Send Comments]
Debugging "C" And "C++" Programs Using "gdb"
Tabular array Of Contents:- Why Use A Debugger?
- Invoking the "gdb" Debugger
- Running A Program Within The Debugger
- Setting Breakpoints
- Stepping A Control At A Fourth dimension
- Printing Variables And Expressions
- Examining The Function Call Stack
- Attaching To an Already Running Process
- Debugging A Crashed Program
- Getting More Info About Debugging
Why Use A Debugger?
This might audio silly, but I've heard of many programmers that claim they do not need a debugger. They just don't create bugs. Well, one thing is sure - either they've no thought what they are proverb, or they merely never put their code to existent examination. Or maybe they're indeed every bit gifted as they merits. Unfortunately, most of us tend to take bugs in our code. We could employ printing commands to test our lawmaking, or we could use a debugger. Many times our lawmaking might seem to piece of work correctly, because we didn't examination it under plenty scenarios. Other times nosotros know there's a issues, but by just reading the code we don't notice information technology is there. Thus, we should develop a addiction of launching a debugger when we become into trouble. Information technology shouldn't come instead of making an effort to write correct lawmaking, to add together many tests in the lawmaking for invalid part arguments, Zilch pointers, etc. But when we're in trouble, it'south probably our best shot.
The explanations given here are specific to the "gdb" debugger, since there are no existent standards regarding the activation and usage of debuggers, but once you know what features to expect from a debugger, information technology's not too difficult to adapt your knowledge to different debuggers.
Invoking the "gdb" Debugger
Before invoking the debugger. brand sure you compiled your programme (all its modules, as well every bit during linking) with the "-g" flag. Otherwise, life will be tough. Lets compile the "debug_me.c" program, so invoke "gdb" to debug it:
gcc -g debug_me.c -o debug_me gdb debug_me
Note that nosotros run the program from the same directory it was compiled in, otherwise gdb won't find the source file, and thus won't be able to show united states where in the code we are at a given point. Information technology is possible to enquire gdb to search for extra source files in some directory subsequently launching it, but for now, it'southward easier to only invoke it from the right directory.
Running A Program Inside The Debugger
One time we invoked the debugger, we tin can run the plan using the command "run". If the program requires command line parameters (like our debug_me programme does), we can supply them to the "run" control of gdb. For case:
run "hello, world" "goodbye, world"
Note that we used quotation marks to denote that "how-do-you-do, globe" is a single parameter, and not to separate parameters (the debugger assumes white-infinite separates the parameters).
Setting Breakpoints
The trouble with merely running the code is that information technology keeps on running until the program exits, which is unremarkably besides belatedly. For this, breakpoints are introduced. A break point is a command for the debugger to stop the execution of the program before executing a specific source line.We can fix break points using ii methods:
- Specifying a specific line of code to cease in:
break debug_me.c:9
Will insert a suspension point right before checking the command line arguments in our program (encounter the file supplied with this tutorial).
- Specifying a function name, to break every time it is being chosen:
break chief
this will fix a break point right when starting the plan (equally the function "master" gets executed automatically on the beginning of any C or C++ program).
Stepping A Command At A Time
So lets see, we've invoked gdb, and then typed:
break main run "howdy, globe" "farewell, globe"
Then the debugger gave something like the post-obit:
Starting programme: /usr/home/choo/work/c-on-unix/debug_me warning: Unable to find dynamic linker breakpoint function. warning: GDB volition be unable to debug shared library initializers warning: and track explicitly loaded dynamic code. Breakpoint 1, main (argc=i, argv=0xbffffba4) at debug_me.c:9 9 if (argc < 2) { /* 2 - one for program name (argv[0]) and one for a param. */ (gdb)
Note that you won't e'er get the warnings i got - it just goes to show you how lousy my system setup is. In any case, these warnings are not relevant to our code, as nosotros exercise non intend to debug whatsoever shared libraries.
Now we want to outset running the program slowly, step by pace. There are ii options for that:
- "side by side" - causes the debugger to execute the current command, and stop again, showing the next command in the code to be executed.
- "pace" - causes the debugger to execute the current control, and if it is a function call - interruption at the beginning of that function. This is useful for debugging nested code.
Printing Variables And Expressions
Without being able to examine variables contents during program execution, the whole idea of using a debugger is quite lost. Yous can print the contents of a variable with a command like this:
impress i
And then you'll get a bulletin like:
$1 = 0
which means that "i" contains the number "0".
Notation that this requires "i" to be in scope, or you lot'll get a message such equally:
No symbol "i" in current context.
For example, if you lot break inside the "print_string" function and try to print the value of "i", you'll get this message.
You lot may also try to impress more complex expressions, like "i*ii", or "argv[3]", or "argv[argc]", and so on. In fact, you may likewise utilize type casts, call functions found in the program, and whatsoever your sick listen could imagine (well, virtually). Once more, this is a good fourth dimension to try this out.
Examining The Function Call Stack
In one case nosotros got into a break-point and examined some variables, nosotros might too wish to see "where we are". That is, what office is being executed at present, which office chosen it, and so on. This tin can exist washed using the "where"
command. At the gdb command prompt, just type "where", and you'll run into something like this:
#0 print_string (num=1, string=0xbffffc9a "hello") at debug_me.c:7 #1 0x80484e3 in main (argc=1, argv=0xbffffba4) at debug_me.c:23
This means the currently executing function is "print_string", at file "debug_me.c", line seven. The function that called it is "main". Nosotros likewise see which arguments each function had received. If there were more functions in the call chain, we'd see them listed in order. This list is as well chosen "a stack trace", since it shows u.s. the structure of the execution stack at this betoken in the programme'due south life.
Only as we tin can meet contents of variables in the current function, we tin can see contents of variables local to the calling role, or to any other function on the stack. For example, if we desire to come across the contents of variable "i" in function "main", we can blazon the post-obit 2 commands:
frame 1 print i
The "frame" command tells the debugger to switch to the given stack frame ('0' is the frame of the currently executing function). At that stage, any print control invoked volition utilise the context of that stack frame. Of-form, if nosotros issue a "step" or "next" command, the plan will keep at the elevation frame, not at the frame we requested to see. After all, the debugger cannot "undo" all the calls and go along from at that place.
Attaching To an Already Running Process
Information technology might exist that nosotros'll want to debug a program that cannot be launched from the command line. This may exist because the program is launched from some arrangement daemon (such as a CGI plan on the web), and we are besides lazy to make it possible to run information technology direct from the command line. Or mayhap the program takes very long time to run its initialization code, and starting it with a debugger attached to information technology will cause this startup fourth dimension to be much much longer. There are also other reasons, only hopefully you got the betoken. In order to exercise that, nosotros volition launch the debugger in this way:
gdb debug_me 9561
Here we assume that "debug_me" is the proper name of the program executed, and that 9561 is the procedure id (PID) of the procedure we want to debug.
What happens is that gdb first tries looking for a "core" file named "9561" (we'll run into what core files are in the next section), and when it won't detect it, it'll presume the supplied number is a process ID, and attempt to attach to information technology. If in that location process executes exactly the same plan whose path nosotros gave to gdb (not a re-create of the file. it must be the exact same file that the process runs), it'll adhere to the program, pause its execution, and will let us continue debugging it as if we started the programme from inside the debugger. Doing a "where" correct when nosotros get gdb'southward prompt will show united states of america the stack trace of the process, and nosotros can continue from there. Once we exit the debugger, It volition detach itself from the process, and the process will proceed execution from where we left information technology.
Debugging A Crashed Program
One of the problems virtually debugging programs, has to do with Murphy's law: A program will crash when least expected. This phrase simply means that after yous take the program out as production code, information technology volition crash. And the bugs won't necessarily be easy to reproduce. Luckily, in that location is some aid for us, in the paradigm of "core files".
A core file contains the memory image of a procedure, and (assuming the plan within the process contains debug info) its stack trace, contents of variables, so on. A programme is normally prepare to generate a core file containing its memory image when it crashes due to signals such as SEGV or BUS. Provided that the vanquish invoking the program was not gear up to limit the size of this core file, we will detect this file in the working directory of the process (either the directory from which it was started, or the directory it terminal switched to using the chdir
system call).
Once we get such a core file, we tin can look at it by issuing the following control:
gdb /path/to/plan/debug_me core
This assumes the program was launched using this path, and the core file is in the current directory. If information technology is not, we can requite the path to the core file. When we get the debugger's prompt (assuming the core file was successfully read), we can issue commands such equally "impress", "where" or "frame X". We can not issue commands that imply execution (such every bit "adjacent", or the invocation of function calls). In some situations, nosotros volition be able to see what acquired the crash.
One should notation that if the program crashed due to invalid memory address access, this will imply that the memory of the programme was decadent, and thus that the core file is corrupt also, and thus contains bad retention contents, invalid stack frames, etc. Thus, we should encounter the core file's contents as one possible past, out of many likely pasts (this makes cadre file analysis rather like to quantum theory. almost).
Getting More Info Near Debugging
Information technology is now probably time to become play around with your programs and your debugger. It is suggested to try "help" inside gdb, to learn more most its commands. Especially the "dir" command, that enables debugging programs whose source code is split over several directories.
In one case you feel that gdb is too limiting, you can try out whatever of various graphical debuggers. Try to bank check if you have "xxgdb" installed - this is a graphical interface running on top of gdb. If you lot find it too ugly, you can try out "ddd". Its main advantage over xxgdb is that it allows you to graphically view the contents of pointers, linked lists and other circuitous data structures. Information technology might non exist installed on your system, and thus y'all'll demand to download it from the network.
If yous're running on a SunOs or Solaris environment, at that place is a plan named "gcore", that allows taking the core of a running procedure, without stopping it. This is useful if the procedure is running in an infinite loop, and you want to take a core file to keep aside, or you want to debug a running process without interrupting it for likewise long.
[LUPG Home] [Tutorials] [Related Material] [Essays] [Project Ideas] [Ship Comments]
This document is copyright (c) 1998-2002 by guy keren.
The material in this document is provided Every bit IS, without any expressed or implied warranty, or claim of fettle for a particular purpose. Neither the author nor any contributers vanquish exist liable for any amercement incured directly or indirectly by using the fabric independent in this document.
permission to copy this document (electronically or on paper, for personal or system internal utilise) or publish it on-line is hereby granted, provided that the document is copied as-is, this copyright notice is preserved, and a link to the original certificate is written in the certificate's body, or in the folio linking to the copy of this document.
Permission to brand translations of this document is too granted, nether these terms - bold the translation preserves the meaning of the text, the copyright observe is preserved equally-is, and a link to the original document is written in the document's body, or in the page linking to the copy of this document.
For whatsoever questions nearly the document and its license, please contact the author.
How To Use Gdb Debugger,
Source: https://www.classes.cs.uchicago.edu/archive/2017/winter/51081-1/LabFAQ/lab2/gdb.html
Posted by: gasparddienteor.blogspot.com
0 Response to "How To Use Gdb Debugger"
Post a Comment