This article introduces the basic commands required to debug assembly language in gdb.
Note: If you would like to understand an assembly language listing, jump to this article first.
The disassemble command provides the assembly language listing of a program and works even when a program is not running. The command works for a function name / an address / an address range.
disassemble function_name disassembles the function called function_name.
disassemble mainDump of assembler code for function main: 0x00401180 <main+0>: lea 0x4(%esp),%ecx 0x00401184 <main+4>: and $0xfffffff0,%esp 0x00401187 <main+7>: pushl -0x4(%ecx) 0x0040118a <main+10>: push %ebp 0x0040118b <main+11>: mov %esp,%ebp 0x0040118d <main+13>: push %esi 0x0040118e <main+14>: push %ebx ------8<---------<snip>---------8<---------------
The disassemble command can also be used for a specific address.
At times the disassembly listing of a function can get very long and to limit it, an address range can be provided as shown below.
disassemble <from_address1> <to_address2>
disassemble main main+20
disassemble 0x004011ce 0x004011f7
Developers who have debugged in assembly on various debuggers on the Windows platform may prefer the Intel instruction set instead instead of the At&T set which is the default in gdb. The listing can be changed to use the Intel instruction set instead by setting the disassembly-flavor.
set disassembly-flavor intel
disassembleDump of assembler code for function main: 0x00401180 <main+0>: lea ecx,[esp+0x4] 0x00401184 <main+4>: and esp,0xfffffff0 0x00401187 <main+7>: push DWORD PTR [ecx-0x4] 0x0040118a <main+10>: push ebp 0x0040118b <main+11>: mov ebp,esp 0x0040118d <main+13>: push esi 0x0040118e <main+14>: push ebx -----8<---------<snip>---------8<--------------
Controlling The Flow Of Program Execution
An instruction breakpoint can be set at a particular address using the breakpoint command.
Take note of the asterix just before the address above.
To step into the assembly language one instruction at a time use the command:
Note that this will step into function calls that the program encounters.
To step over a function call, one can use the command:
To return from a function call that one is current stepping through, use the command:
To know about the values of the registers of the program being debugged use the following command:
$pc holds the program counter and it can also be used to find the instruction that will be executed next.
x/i $pc0x40124e <main+206>: mov eax,ebx
Similar to regular debugging, the backtrace command prints the callstack.
To get a list of the shared libraries that are loaded for the current program being debugged the following command is handy to use:
info sharedlibraryFrom To Syms Read Shared Object Library 0x779e1000 0x77b1bc3c Yes /cygdrive/c/Windows/system32/ntdll.dll 0x77901000 0x779d30c0 Yes /cygdrive/c/Windows/system32/kernel32.dll 0x75c41000 0x75c895d0 Yes /cygdrive/c/Windows/system32/KernelBase.dll 0x61001000 0x61450000 Yes /usr/bin/cygwin1.dll -----8<---------<snip>---------8<--------------
Note: A handy tip on using the display command during assembly language debugging with gdb was shared in a previous blog entry here.