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

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.)

This question is related to linux assembly gdb x86 linux-kernel

The answer is


The most useful thing you can do here is display/i $pc, before using stepi as already suggested in R Samuel Klatchko's answer. This tells gdb to disassemble the current instruction just before printing the prompt each time; then you can just keep hitting Enter to repeat the stepi command.

(See my answer to another question for more detail - the context of that question was different, but the principle is the same.)


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)

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to assembly

Why does C++ code for testing the Collatz conjecture run faster than hand-written assembly? While, Do While, For loops in Assembly Language (emu8086) Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviations with _mm_popcnt_u64 on Intel CPUs How to run a program without an operating system? Difference between "move" and "li" in MIPS assembly language Carry Flag, Auxiliary Flag and Overflow Flag in Assembly How do AX, AH, AL map onto EAX? JNZ & CMP Assembly Instructions Difference between JE/JNE and JZ/JNZ The point of test %eax %eax

Examples related to gdb

How to install gdb (debugger) in Mac OSX El Capitan? Step out of current function with GDB How do I get the backtrace for all the threads in GDB? Counter exit code 139 when running, but gdb make it through gdb: how to print the current line or find the current line number? How do I pass a command line argument while starting up GDB in Linux? GDB: break if variable equal value How to attach a process in gdb gdb fails with "Unable to find Mach task port for process-id" error gdb: "No symbol table is loaded"

Examples related to x86

How to compile Tensorflow with SSE4.2 and AVX instructions? Why does C++ code for testing the Collatz conjecture run faster than hand-written assembly? Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviations with _mm_popcnt_u64 on Intel CPUs How to install ia32-libs in Ubuntu 14.04 LTS (Trusty Tahr) How to run a program without an operating system? Carry Flag, Auxiliary Flag and Overflow Flag in Assembly How do AX, AH, AL map onto EAX? JNZ & CMP Assembly Instructions How does the ARM architecture differ from x86? Difference between JE/JNE and JZ/JNZ

Examples related to linux-kernel

How to fix: fatal error: openssl/opensslv.h: No such file or directory in RedHat 7 How do I delete virtual interface in Linux? Image vs zImage vs uImage iptables v1.4.14: can't initialize iptables table `nat': Table does not exist (do you need to insmod?) IOCTL Linux device driver How to solve "Kernel panic - not syncing - Attempted to kill init" -- without erasing any user data What is ":-!!" in C code? What is the difference between the kernel space and the user space? What does "make oldconfig" do exactly in the Linux kernel makefile? "FATAL: Module not found error" using modprobe