UMBC CMSC 313 -- Assembly Language Segment Previous | Next


Debug Session

Need A Program To Debug

When you wish to debug a program, obviously you must have an executable file to run! Normally, when you are using C/C++, you have to use the -g option to generate the debug info that you will need in the debug session. Unfortunately, that option does not do anything for us when using NASM and Linux! I use the option to create a habit that is portable to other systems. It does not really cost anything, so it does not matter. The bad news is that NASM does not output the information that gdb needs to be as useful as it could.

[~/courses/umbc/CMSC313/spring04/lectures/Lect03]$ make
nasm -l datatypes.lst -g -f elf datatypes.asm
gcc  -o datatypes datatypes.o
[~/courses/umbc/CMSC313/spring04/lectures/Lect03]$

Options

Start the debugger

When you wish to run a debugger, what command do you use? Well, there are choices. Basically, they all use gdb (GNU debugger) which uses a text interface. The other choices have a GUI to make it easier to use! However, unless you have a X-Windows server, you can not use the GUI version.

We will focus on gdb since you can figure out how to use the GUI ones real easy, once you understand gdb.

We have to tell it which file has the executable and the session on my personal computer starts with:

[~/courses/umbc/CMSC313/spring04/lectures/Lect03]$ gdb datatypes
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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"...
(gdb)

That was easy!

Getting Out Of The Debugger!

I think the first thing to learn is how to get in, the second thing to learn is how to get out! To terminate the session is simple:

[~/courses/umbc/CMSC313/spring04/lectures/Lect03]$ gdb datatypes
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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"...
(gdb) quit
[~/courses/umbc/CMSC313/spring04/lectures/Lect03]$

Once again, it was simple!

Debugger Is Running, Program Is Not

Notice that there are two separate things, is the debugger running and is the program to be debugged running. So far we have seen the debugger get started. For this program, execution will start at main. Some versions of the debugger have a bug and to get things to work correctly, you will need the instruction NOP as the first instruction. This instruction specifies that "No Operation" is to be performed. Sometimes this is a good thing. Anyway, we want the program to run to that instruction, execute it, and stop. To do that, we must specify a breakpoint at the address of main + 1.

(gdb) break *main+1
Breakpoint 1 at 0x8048301: file datatypes.asm, line 28.
(gdb) run
Starting program: /home/burt/courses/umbc/CMSC313/spring04/lectures/Lect03/datatypes

Breakpoint 1, main () at datatypes.asm:28
28              mov     eax, 5
(gdb)
This shows us that the next instruction to be executed is line 28 in the source file. All this does is really give us control over how the program will now execute. Without the breakpoint, the program would run to completion:

(gdb) run
Starting program: /home/burt/courses/umbc/CMSC313/spring04/lectures/Lect03/datatypes

Program exited normally.
(gdb)

We do not need a debugger for that!!! So we want the program to run to some point of interest and stop. What is a point of interest, it is only the first instruction we want to see how it behaves. That changes probably every time!

Some times we want to do one instruction and see what has changed. (Note:There is a help command in gdb to tell you what a command does:

(gdb) help step
Step program until it reaches a different source line.
Argument N means do this N times (or till program stops for another reason).
(gdb) help stepi
Step one instruction exactly.
Argument N means do this N times (or till program stops for another reason).

We can use s for step.

To be able to see what is happening to a register, we can print it out (Note that the dollar sign must be in front of the register name):

(gdb) print/x $eax
$2 = 0x5
(gdb) print/d $eax
$3 = 5
(gdb) print/t $eax
$4 = 101
(The /x is for hex format, /c is for decimal format, and /t is for binary format.)

To print out the memory, we use the x command:

(gdb) x/17xb &junkb
0x8049400 :    0xfe    0xff    0xff    0xfc    0xff    0xff    0xff    0x00
0x8049408 :    0x00    0x00    0x00    0x00    0x00    0x20    0xc0    0x10
0x8049410 :    0x00
(gdb) x/11xb &foob
0x8049508 :    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x8049510 :    0x00    0x00    0x00

OK, relate that to what we asked for:

     4 00000000 FE                      junkb:    db    -2
     5 00000001 FFFF                    junkw:    dw	-1
     6 00000003 FCFFFFFF                junkd:    dd    -4
     7 00000007 00000000000020C0        junkq:    dq    -8.0  
     8 0000000F 1000                    junk1:    dw    10h
     9 00000011 1000                    junk2:    dw    0x10
    10                                  
    11                                  ;; [ The .bss section ]
    12                                  section .bss
    13 00000000                         foob:	resb	1
    14 00000001                         foow:	resw 	1
    15 00000003                         food:	resd	1
    16 00000007                         fooq:	resq	1

It does look like the uninitialized data was set to zero! Do not assume the uninitialized data has a value until you give it one!

OK, Run The Program!

OK, let's run the program an instruction at a time and see what changes:


(gdb) run
Starting program: /home/burt/courses/umbc/CMSC313/spring04/lectures/Lect03/datatypes

Breakpoint 1, main () at datatypes.asm:28
28              mov     eax, 5
(gdb) s
29              inc     eax
(gdb) print/x $eax
$1 = 0x5
(gdb) s
30              mov     [foow], eax
(gdb) print/x $eax
$2 = 0x6
(gdb) s
31              mov     [foow], word 10h
(gdb) x/1xw &foow
0x8049509 :       0x00000006
(gdb) s
32              mov     [food], dword 0x20
(gdb) x/1xw &foow
0x8049509 :       0x00000010
(gdb) s
33              mov     [foob], byte 48
(gdb) x/1xd &food
0x804950b :       32
(gdb) s
34              mov     bx, 0fedch        ; Hex values must start with a number!
(gdb) s
35              mov     ebx, 0
(gdb) print/x $bx
$1 = Value can't be converted to integer.
(gdb) print/x $ebx
$2 = 0x4213fedc
(gdb) s
36              mov     bx, 0fedch
(gdb) print/x $ebx
$3 = 0x0
(gdb) s
37              dec     bx
(gdb) print/x $ebx
$4 = 0xfedc
(gdb) s
38              mov     [junkw], bx
(gdb) print/x $ebx
$5 = 0xfedb
(gdb) s
49              mov     ebx,0   ;successful termination of program
(gdb) x/1xw
0x0:    Cannot access memory at address 0x0
(gdb) print/x $ebx
$6 = 0xfedb
(gdb) s
50              mov     eax,1   ;system call number (sys_exit)
(gdb) print/x $ebx
$7 = 0x0
(gdb) s
51              int     0x80    ;call kernel
(gdb) print/x $eax
$8 = 0x1
(gdb) s

Program exited normally.
(gdb)

The Authority

For more information, see info gdb


©2004, Gary L. Burt

Previous | Next