Using gdb to single-step assembly code outside specified executable causes error "cannot find bounds of current function"

Paul picture Paul · Mar 10, 2010 · Viewed 101.8k times · Source

I'm outside gdb's target executable and I don't even have a stack that corresponds to that target. I want to single-step anyway, so that I can verify what's going on in my assembly code, because I'm not an expert at x86 assembly. Unfortunately, gdb refuses to do this simple assembly-level debugging. It allows me to set and stop on appropriate breakpoint, but as soon as I try to single-step onwards, gdb reports the error "Cannot find bounds of current function" and the EIP doesn't change.

Additional details:

The machine code was generated by gcc asm statements and I copied it to the kernel memory location where it's executing, from the output of objdump -d. I wouldn't mind a simple way to use a loader to load my object code to a relocated address, but bear in mind the loading has to be done in a kernel module.

I suppose another alternative would be to produce a fake kernel module or debug info file to give to gdb, to cause it to believe this area is within the program code. gdb works fine on the kernel executable itself.

(For those who really want to know, I'm inserting code at runtime into Linux kernel data space inside a VMware VM and debugging it from gdb remote debugging the kernel via VMware Workstation's built-in gdb stub. Note I'm not writing kernel exploits; I'm a security graduate student writing a prototype.)

(I can set a breakpoint on each instruction inside my assembly. This works but would get quite laborious after a while, since the size of x86 assembly instructions varies and the location of the assembly will change every time I reboot.)

Answer

ephemient picture ephemient · Mar 11, 2010

Instead of gdb, run gdbtui. Or run gdb with the -tui switch. Or press C-x C-a after entering gdb. Now you're in GDB's TUI mode.

Enter layout asm to make the upper window display assembly -- this will automatically follow your instruction pointer, although you can also change frames or scroll around while debugging. Press C-x s to enter SingleKey mode, where run continue up down finish etc. are abbreviated to a single key, allowing you to walk through your program very quickly.

   +---------------------------------------------------------------------------+
B+>|0x402670 <main>         push   %r15                                        |
   |0x402672 <main+2>       mov    %edi,%r15d                                  |
   |0x402675 <main+5>       push   %r14                                        |
   |0x402677 <main+7>       push   %r13                                        |
   |0x402679 <main+9>       mov    %rsi,%r13                                   |
   |0x40267c <main+12>      push   %r12                                        |
   |0x40267e <main+14>      push   %rbp                                        |
   |0x40267f <main+15>      push   %rbx                                        |
   |0x402680 <main+16>      sub    $0x438,%rsp                                 |
   |0x402687 <main+23>      mov    (%rsi),%rdi                                 |
   |0x40268a <main+26>      movq   $0x402a10,0x400(%rsp)                       |
   |0x402696 <main+38>      movq   $0x0,0x408(%rsp)                            |
   |0x4026a2 <main+50>      movq   $0x402510,0x410(%rsp)                       |
   +---------------------------------------------------------------------------+
child process 21518 In: main                            Line: ??   PC: 0x402670
(gdb) file /opt/j64-602/bin/jconsole
Reading symbols from /opt/j64-602/bin/jconsole...done.
(no debugging symbols found)...done.
(gdb) layout asm
(gdb) start
(gdb)