‘The Journey’ is all about the different tastes and flavours…. wandering among the virtual streets…different Paths and Destinations… from Technology to Gadgets… from Humor to Practical Lessons…from Truth to Fictions… from current issues to market conditions… and wat’s not…
Friday, April 23, 2010
Debugging with LINUX environment
Introduction
Linux environment generally used the GNU debugger, or gdb to the shell. Gdb lets you see the internal structure of a program, print out variable values, set breakpoints and single step through source code. It makes an extremely powerful tool for fixing problems in program code. In this article , Let's discuss how to use the .
The Linux development environment has several debugging alternatives. This
article I also explore debugging tools available for debugging applications, ranging
from simple print-statement to specialized tools (e.g. memory-debugging).
Print statements
Addition of printf() statements to your code is a traditional and time-honored way
to debug code. Downside is that you will need to modify and recompile the code
whenever you want more or less debug information.
Strace utility
Strace will output all the kernel calls that the application does and is a great way to find
e.g. what file the program is trying to access and whether it succeeded. For instance
calls to read() and write() will show how much data program tried to read/write and
how much actually was transferred, it also shows the beginning of the data in question.
You can use this without recompilations and it works on any program which you can
run.
Ltrace utility
Ltrace will output all the dynamic library function calls that the application does. It
can also show system calls like ’strace’.
Using GDB debugger
With gdb debugger you can examine all the symbols in the program and program runtime
state and follow program function calls. If trace utilities and the source code don’t
give you enough information to solve the problem, debugger is the next step. Gdb is
a console tool, but there are some nice debugging GUIs available that work on top of
gdb. One such is ddd.
Gdb can help with debugging programs written in C, C++, Fortran, Java, Chill, assembly
and Modula-2. You need to have compiled these programs with the gnu compiler
collection (gcc) tools.
Besides supporting multiple languages gdb also supports multiple hardware architectures,
including several embedded hardware architectures. It’s also possible to compile
a special version of GDB for debugging (Linux) kernel code.
Running gdb
Gdb is run from the shell with the command 'gdb' with the program name as a parameter, for example 'gdb file, or you can use the file command once inside gdb to load a program for debugging, for example 'file file. Both of these assume you execute the commands from the same directory as the program. Once loaded, the program can be started with the gdb command 'run'.
Preparing for GDB use
You need to compile all the C/C++ code you want to debug with debugging information
included into the binary (use ’-g’ and do not use ’-fomit-frame-pointer’ option when
compiling the code) and the code may not be stripped of symbols (do not use ’-s’ flag
in the compilation). Note that all the libraries used by the program should also be
compiled this way as missing stack frame pointer can confuse GDB.
It’s better if you use static linking (e.g. use ’-static’ option in your Makefile) because
that way gdb won’t have trouble finding the symbols for the libraries program uses (for
example if you use different libraries with your program than what your compilation
machine normally uses).
Before you can get started, the program you want to debug has to be compiled with debugging information in it. This is so gdb can work out the variables, lines and functions being used. To do this, compile your program under gcc (or g++) with an extra '-g' option:
gcc -g file.cpp -o file
Using GDB
There are two ways to use a debugger:
- Using debugger to examine the code runtime behavior. You start ’gdb’ with the
program binary (’gdb ’) in the program directory. Then you can either
run the program inside the gdb with ’run ’ or attach to an
already running instance of the program with ’attach ’. Latter is handy
when you don’t have working gdb inside the debugging environment. Then you
can set breakpoints, examine the code, variables, stack etc and call the program
functions.
- Using debugger to examine a process post-mortem ’core’ dump. You start ’gdb’
with the program binary and core dump (’gdb ’) in the program
code directory. You can examine where the program crashed and what was the
state of all the program variables. If your program crashes, but doesn’t produce
a core file, check ’ulimit -a’ to see whether your environment allows core files
and fix it with ’ulimit -c unlimited’.
The downside of debugger approach is that debug versions of the binaries are large and
statically linked debug ones are huge. If the target doesn’t have enough memory for
this, you can use ’gdbserver’ and stripped binaries on the target. On the host on which
you do the debugging, you use gdb with ’target remote’ option and give the host gdb
the binary with all the debugging symbols.
Short introduction to use of gdb
You get back to GDB prompt when your program either:
- Crashes.
- Code execution reaches a breakpoint.
- You suspend or otherwise send a signal to the program.
On latter two cases you can use ’cont’ to continue the program execution.
In the GDB prompt you can do one of the following:
- Set a breakpoint with ’break ’. You can delete breakpoint by
saying ’delete ’.
- Examine current program execution trace with ’bt’, which will show you where
the program execution was interrupted (see above), how it got there and what
were the function arguments.
- Move up and down in the execution stack frame by typing ’up’ or ’down’.
- Examine program state with either ’info locals’ which shows you the state of
variables in the current context (function) or use ’print ’ to show
you a value of given variable or function. Any valid C expression can be used,
even function calls!
- View your program code with ’list ’ which will list code of the
given function.
You can ’step’ through the program code with following commands:
- ’step’ will execute the current line and go to next command. If code line is a
function call, step will enter the function.
- ’next’ works like ’step’ but function calls are executed as single instruction.
- ’finish’ will execute to the end of current scope (function).
- ’cont’ will continue program execution.
Typing return will repeat the previous command. Gdb can also complete function and
variable names with TAB key.
Gdb problems
When optimization is used in code compilation, variable values shown by gdb may
sometimes be valid only for variables used on the line that program executed lastly 1,
not for the whole scope in where the variables are declared. Use of inlines especially
in C++ code (e.g. methods with their body in the header file) may confuse gdb so that
it shows either a wrong filename or line for the fault.
In these cases it’s better not to optimize the code so much, use only ’-O’ optimization
flag, and forbid inlining completely with the ’-fno-default-inline’ compilation flag.
Subscribe to:
Post Comments (Atom)
Health Benefits of Cashews
Benefits of Cashews. Healthy food is an integral part of healthy body. Regular exercises such as Yoga and healthy diet is important to...
-
Convert a string to double (atof and _wtof), integer (atoi, _atoi64, _wtoi and _wtoi64), or long integer (atol and _wtol). double atof( c...
-
CEdit Class Provides the functionality of a Windows edit control. class CEdit : public CWnd Details: An edit control is a rectangula...
-
Beware of SPAMS............ _________________________________________________________________________________ THE UNITED NATIONS m...
No comments:
Post a Comment