|<Linux gnu gcc, g++ and gdb 1 | Main | Linux gnu as and ld 3 >|Site Index |Download |


 

 

 

 

MODULE 000-2

GCC, G++, GDB AND FRIENDS 2

 

 

 

 

 

 

My Training Period: xx hours   

 

 

 

 

The gdb - A GNU Debugger

 

gdb

The GNU Debugger. 

The purpose of a debugger such as GDB is to allow you to see what is going on inside another program while it executes or what another program was doing at the moment it crashed.

GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:

 

  1. Start your program, specifying anything that might affect its behavior.

  2. Make your program stop on specified conditions.

  3. Examine what has happened, when your program has stopped.

  4. Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.

 

You can use GDB to debug programs written in C, C++, and Modula-2.  Fortran support will be added when a GNU Fortran compiler is ready.

GDB is invoked with the shell command gdb.  Once started, it reads commands from the terminal until you tell it to exit with the GDB command quit.  You can get online help from gdb itself by using the command help.  You  can  run  gdb  with no arguments or options; but the most usual way to start GDB is with one argument or two, specifying an executable program as the argument:

 

      gdb program

 

You can also start with both an executable program and a core file specified:

 

      gdb program core

 

You can, instead, specify a process ID as a second argument, if you want to debug a running process:

 

      gdb program 1234

 

Would attach GDB to process 1234 (unless you also have a file named 1234; GDB does check for a core file first).

Usage:

gdb [options] [executable-file [core-file or process-id]]

gdb [options] --args executable-file [inferior-arguments ...]

Options:

--args

Arguments after executable-file are passed to inferior.

--[no]async

Enable (disable) asynchronous version of CLI.

-b BAUDRATE

Set serial port baud rate used for remote debugging.

--batch

Exit after processing options.

--cd=DIR

Change current directory to DIR.

--command=FILE

Execute GDB commands from FILE.

--core=COREFILE

Analyze the core dump COREFILE.

--pid=PID

Attach to running process PID.

--dbx

DBX compatibility mode.

--directory=DIR

Search for source files in DIR.

--epoch

Output information used by epoch emacs-GDB interface.

--exec=EXECFILE

Use EXECFILE as the executable.

--fullname

Output information used by emacs-GDB interface.

--help

Print this message.

--interpreter=INTERP

Select a specific interpreter / user interface

--mapped

Use mapped symbol files if supported on this system.

--nw

Do not use a window interface.

--nx

Do not read .gdbinit file.

--quiet

Do not print version number on startup.

--readnow

Fully read symbol files on first access.

  --se=FILE

Use FILE as symbol file and executable file.

--symbols=SYMFILE

Read symbols from SYMFILE.

--tty=TTY

Use TTY for input/output by the program being debugged.

--tui

Use a terminal user interface.

--version

Print version information and then exit.

-w

Use a window interface.

--write

Set writing into executable and core files.

--xdb

XDB compatibility mode.

For more information, type "help" from within GDB, or consult the GDB manual (available as on-line info or a printed manual).

 

Internal gdb Commands And Examples

 

Command Example

Description

gdb executable_file_name

Running the gdb.

(gdb) break main

(gdb) b main

Set a breakpoint at the main()

(gdb) clear main

Clear the breakpoint at main()

(gdb) breakADDRESS

Set a breakpoint at the specifiedADDRESS

(gdb) break [function_name]

Set a breakpoint at the [function_name]

(gdb) clear [function_name]

Clear a break point at the [function_name]

(gdb) break [line_number]

Set a breakpoint at the [line_number]

(gdb) clear [line_number]

Clear a breakpoint at the [line_number]

(gdb) break 0x800050b

e.g: Set a breakpoint at 0x800050b

(gdb) run

(gdb) r

Run the program in gdb

(gdb) run [argv[1] ]

(gdb) run 12345

Run the program in gdb with command line argument.

Run the program in gdb with 1234 as a command line argument.

(gdb) help info

Help for info command.

(gdb) info stack

Backtrace of the stack

(gdb) info frame

Display the information about the current stack frame

(gdb) info registers

(gdb) i r

To view register contents.

(gdb) info reg ebp

Info for ebp register.

(gdb) info break

To see what breakpoints are currently defined and their conditions.

(gdb) disass main

(gdb) disass [function_name]

(gdb) disassCopyData

Disassemble the main().

Disassemble the [function_name]

Disassemble the CopyData function.

(gdb) step

(gdb) stepi

Execute one machine code instruction

(gdb) stepi <n>

Execute n instructions

(gdb) next

(gdb) nexti

Like stepi, but will proceed through subroutine calls

(gdb) cont

(gdb) continue

(gdb) c

Resume execution

(gdb) x/3bcx

Examine in range (3), binary format char format, hex format.

(gdb) x/5xw 0xbffffc04

Examine in hex with word size with the range of 5 starting at 0xbffffc04.

(gdb) x/bx 0xbffffc04

Examine by byte size in hex format at address 0xbffffc04

(gdb) x/s 0xbffffc01

Examine the string at address 0xbffffc01

(gdb) x/i setuid

Examine in assembly format thesetuid() function

(gdb) x/i system

Examine in assembly format thesystem() function

(gdb) x/4w 0xbffcec54

Examine in range of 4 with word size at 0xbffcec54

(gdb) x/10i $eip

Examine the next 10 address in assembly code format instead of ASCII or hex, starting from the address the register eip is pointing to.

(gdb) x ADDR

Prints the contents of the address ADDR in memory

(gdb) x /20b address

Then, the next 20 bytes 

(gdb) x /20c address

Then, the next 20 characters

(gdb) p/x $eax

Prints the value in the eax register in hex.

(gdb) print $esp

Prints the value in the esp register in hex.

(gdb) print $esp + 4

Prints the value in the esp+4 register in hex.

(gdb) print TheData

Prints the value in the TheData variable.

(gdb) printf "%s\n", 0x8048552

Prints the string value at address 0x8048552.

(gdb) l

List the program source code.

(gdb) frame

(gdb) frame 0

Display the current frame (stack frame).

Display the frame 0 (stack frame 0).

(gdb) backtrace

(gdb) b

Print the current address and the stack frame.

(gdb) q

(gdb) quit

Quit the gdb

 

 

Playing With The gdb (You can try the X version, ddd)

 

Invoking the gdb, gdb the testbuff program (the executable file).

 

[bodo@bakawali testbed5]$ gdb testbuff

GNU gdb Red Hat Linux (6.1post-1.20040607.43rh)

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or 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.

This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

 

 

 

 

 

 

List the testbuff source code.

 

(gdb) l

5       {

6       char buff[4];

7       printf("Some input: ");

8       gets(buff);

9       puts(buff);

10      }

11

12      int main(int argc, char *argv[])

13      {

14      Test();

(gdb)

15      return 0;

16      }

 

Set the breakpoint at main(), means if you run, that does not include line of the breakpoint.

 

(gdb) break main

Breakpoint 1 at 0x8048422: file testbuff.c, line 14.

 

Run the program in gdb without the argument(s).

 

(gdb) run

Starting program: /home/bodo/testbed5/testbuff

 

Breakpoint 1, main (argc=1, argv=0xbff92b14) at testbuff.c:14

14      Test();

 

Stepping up the running.

 

(gdb) step

Test () at testbuff.c:7

7       printf("Some input: ");

(gdb)

8       gets(buff);

(gdb)

Some input: 123

9       puts(buff);

(gdb)

123

10      }

 

Continue running until the end of program.

 

(gdb) c

Continuing.

Program exited normally.

(gdb)

 

gdb the testbuff program without printing the version of thegdb.

 

[bodo@bakawali testbed5]$ gdb -q testbuff

Using host libthread_db library "/lib/tls/libthread_db.so.1".

 

Disassemble the main().

 

(gdb) disass main

Dump of assembler code for function main:

0x08048406 <main+0>:            push          %ebp

0x08048407 <main+1>:            mov           %esp,  %ebp

0x08048409 <main+3>:            sub           $0x8,  %esp

0x0804840c <main+6>:            and           $0xfffffff0,  %esp

0x0804840f <main+9>:             mov           $0x0,  %eax

0x08048414 <main+14>:          add           $0xf,  %eax

0x08048417 <main+17>:          add           $0xf,  %eax

0x0804841a <main+20>:          shr           $0x4,  %eax

0x0804841d <main+23>:          shl           $0x4,  %eax

0x08048420 <main+26>:          sub           %eax,  %esp

0x08048422 <main+28>:          call          0x80483d0 <Test>

0x08048427 <main+33>:          mov           $0x0,  %eax

0x0804842c <main+38>:          leave

0x0804842d <main+39>:          ret

End of assembler dump.

 

Disassemble the Test() function.  Then don’t forget, you can also disassemble any function in the glibc library.

 

(gdb) disass Test

Dump of assembler code for function Test:

0x080483d0 <Test+0>:              push          %ebp

0x080483d1 <Test+1>:              mov           %esp, %ebp

0x080483d3 <Test+3>:              sub           $0x8, %esp

0x080483d6 <Test+6>:              sub           $0xc, %esp

0x080483d9 <Test+9>:              push          $0x8048510

0x080483de <Test+14>:            call          0x8048318 <_init+88>

0x080483e3 <Test+19>:            add           $0x10, %esp

0x080483e6 <Test+22>:            sub           $0xc, %esp

0x080483e9 <Test+25>:            lea           0xfffffffc(%ebp), %eax

0x080483ec <Test+28>:            push          %eax

0x080483ed <Test+29>:            call          0x80482e8 <_init+40>

0x080483f2 <Test+34>:             add           $0x10, %esp

0x080483f5 <Test+37>:             sub           $0xc, %esp

0x080483f8 <Test+40>:             lea           0xfffffffc(%ebp), %eax

0x080483fb <Test+43>:             push          %eax

0x080483fc <Test+44>:             call          0x80482f8 <_init+56>

0x08048401 <Test+49>:            add           $0x10, %esp

0x08048404 <Test+52>:            leave

0x08048405 <Test+53>:            ret

End of assembler dump.

 

Set the breakpoint at main().

 

(gdb) break main

Breakpoint 1 at 0x8048422: file testbuff.c, line 14.

 

Run the program until the breakpoint main().

 

(gdb) run

Starting program: /home/bodo/testbed5/testbuff

 

Breakpoint 1, main (argc=1, argv=0xbfeb3ce4) at testbuff.c:14

14      Test();

 

Stepping up running.  Just press the Carriage Return/Enter key to repeat the last gdb command.

 

(gdb) s

Test () at testbuff.c:7

7       printf("Some input: ");

(gdb)

8       gets(buff);

(gdb)

Some input: 123

9       puts(buff);

 

 

 

 

 

 

Backtrace the stack frame, here we have 2 frames: The Test() and the main() functions frames.  Test() is frame #0 and main() is frame #1

 

(gdb) backtrace

#0  Test () at testbuff.c:9

#1  0x08048427 in main (argc=1, argv=0xbfeb3ce4) at testbuff.c:14

 

Currently we are at what frame? Surely theTest() frame, the stack frame #0.

 

(gdb) frame

#0  Test () at testbuff.c:9

9       puts(buff);

 

If needed, we can switch among frames.  Switching to frame #0.

 

(gdb) frame 0

#0  Test () at testbuff.c:9

9       puts(buff);

 

In frame Test() we have buff variable.  Then, examining the string in buff variable.

 

(gdb) x/s buff

0xbfeb3c34:      "123"

 

Switch to frame #1, the main().  Try examining the buff variable.  Surely, thebuff variable not in this frame.

 

(gdb) frame 1

#1  0x08048427 in main (argc=1, argv=0xbfeb3ce4) at testbuff.c:14

14      Test();

(gdb) x/s buff

No symbol "buff" in current context.

 

Examining the 10 in range, in word size starting at the ebp address.

 

(gdb) x/10w $ebp

0xbfeb3c58:      "¸<ë¿3\236h"

0xbfeb3c60:      "\001"

0xbfeb3c62:      ""

0xbfeb3c63:      ""

0xbfeb3c64:      "ä<ë¿ì<ë¿F;f"

0xbfeb3c70:      "ô¯y"

0xbfeb3c74:      ""

0xbfeb3c75:      ""

0xbfeb3c76:      ""

0xbfeb3c77:      ""

 

Examining the 10 in range, in word size starting at the esp address.

 

(gdb) x/10w $esp

0xbfeb3c40:      ""

0xbfeb3c41:      ""

0xbfeb3c42:      ""

0xbfeb3c43:      ""

0xbfeb3c44:      "ô¯y"

0xbfeb3c48:      "$\225\004\bô¯y"

0xbfeb3c50:      ""

0xbfeb3c51:      ""

0xbfeb3c52:      ""

0xbfeb3c53:      ""

 

Examining the string at address 0xbfeb3c48.

 

(gdb) x/s 0xbfeb3c48

0xbfeb3c48:      "$\225\004\bô¯y"

 

Examining the hex at address 0xbfeb3c48.

 

(gdb) x/x 0xbfeb3c48

0xbfeb3c48:     0x08049524

 

Another try, examining the string at address0x08049524.

 

(gdb) x/s 0x08049524

0x8049524 <__CTOR_LIST__>:       "ÿÿÿÿ"

 

Examining the assembly at address 0xbfeb3c48.

 

(gdb) x/i printf

0x6b75b0 <printf>:      push   %ebp

 

Examining the byte of the buff variable.  Surely we can’t because we are in frame #1.

 

(gdb) x/b buff

No symbol "buff" in current context.

 

Switching to frame #0

 

(gdb) frame 0

#0  Test () at testbuff.c:9

9       puts(buff);

 

Then, examining the byte of the buff variable.

 

(gdb) x/b buff

0xbfeb3c34:     0x31

 

Next, examining the 10 in range in byte starting at the buff variable.

 

(gdb) x/10b buff

0xbfeb3c34:     0x31    0x32    0x33    0x00    0x58    0x3c    0xeb    0xbf

0xbfeb3c3c:     0x27    0x84

 

Next, examining the 10 in range in characters starting at the buff variable.

 

(gdb) x/10c buff

0xbfeb3c34:     49 '1'  50 '2'  51 '3'  0 '\0'  88 'X'  60 '<'  -21 'ë' -65 '¿'

0xbfeb3c3c:     39 '\'' -124 '\204'

 

Examining in assembly the beginning of thesystem() function.

 

(gdb) x/i system

0x6a96f0 <system>:      push   %ebp

 

Examining in assembly the beginning of theTest() function.

 

(gdb) x/i Test

0x80483d0 <Test>:       push   %ebp

 

Examining in assembly the 10 in range beginning at the Test() function.

 

(gdb) x/10i Test

0x80483d0 <Test>:            push          %ebp

0x80483d1 <Test+1>:        mov           %esp, %ebp

0x80483d3 <Test+3>:        sub           $0x8, %esp

0x80483d6 <Test+6>:        sub           $0xc, %esp

0x80483d9 <Test+9>:        push          $0x8048510

0x80483de <Test+14>:      call          0x8048318 <_init+88>

0x80483e3 <Test+19>:      add           $0x10, %esp

0x80483e6 <Test+22>:      sub           $0xc, %esp

0x80483e9 <Test+25>:      lea           0xfffffffc(%ebp), %eax

0x80483ec <Test+28>:      push          %eax

 

Registers information.  What is in the processor’s register?

 

(gdb) i r

eax            0xbfeb3c34       -1075102668

ecx            0x79b720 7976736

edx            0x79c7ac 7980972

ebx            0x79aff4 7974900

esp            0xbfeb3c30       0xbfeb3c30

ebp            0xbfeb3c38       0xbfeb3c38

esi            0xbfeb3ce4       -1075102492

edi            0xbfeb3c70       -1075102608

eip            0x80483f5        0x80483f5

eflags         0x386    902

cs             0x73     115

ss             0x7b     123

ds             0x7b     123

es             0x7b     123

fs             0x0      0

gs             0x33     51

 

Stack frame information.  Stack frame for function.

 

(gdb) i s

#0  Test () at testbuff.c:9

#1  0x08048427 in main (argc=1, argv=0xbfeb3ce4) at testbuff.c:14

 

Examining the 5 in range in word starting at the esp.

 

(gdb) x/5w $esp

0xbfeb3c30:     0x00000000      0x00333231      0xbfeb3c58      0x08048427

0xbfeb3c40:     0x00000000

 

Examining the 5 in range, in word starting at theeip.

 

(gdb) x/5w $eip

0x80483f5 <Test+37>:    0x8d0cec83      0xe850fc45      0xfffffef7      0xc910c483

0x8048405 <Test+53>:    0xe58955c3

 

Examining the 5 in range, in byte starting at theeip.

 

(gdb) x/5b $eip

0x80483f5 <Test+37>:    0x83    0xec    0x0c    0x8d    0x45

 

Examining the 5 in range, in byte starting at theesp.

 

(gdb) x/5b $esp

0xbfeb3c30:     0x00    0x00    0x00    0x00    0x31

 

Examining the 5 in range, in characters starting at the eip.

 

(gdb) x/5c $esp

0xbfeb3c30:     0 '\0'  0 '\0'  0 '\0'  0 '\0'  49 '1'

(gdb)

 

-------------------------------------more------------------------------------------------

 

The testbuff is an executable file.

 

[bodo@bakawali testbed5]$ gdb -q testbuff

Using host libthread_db library "/lib/tls/libthread_db.so.1".

 

Set breakpoint at main().

 

(gdb) b main

Breakpoint 1 at 0x8048422: file testbuff.c, line 14.

 

Running the program with 123 as an argument.

 

(gdb) r 123

Starting program: /home/bodo/testbed5/testbuff 123

 

Breakpoint 1, main (argc=2, argv=0xbfeb2f54) at testbuff.c:14

14      Test();

(gdb)

 

 

 

 

 

Further related reading:

 

  1. Check the best selling C / C++, Networking, Linux and Open Source books at Amazon.com.

  2. Linux Socket programming tutorial.

  3. C, Buffer overflow and stack frame (construction and destruction).

  4. C, Compiler, Assembler and Linker.

 

 

 

 

 |<Linux gnu gcc and g++ 1 | Main | Linux gnu as and ld 3 >|Site Index |Download |


C & Linux GNU Related Utilities: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6