kennyluck
kennyluck

Reputation: 99

In gdb, how do I disassemble the previous instruction of an address?

We know that disassembling instructions after a given address (inclusive) can be achieved by something like:

x/5i address

which will print 5 instructions, but how do I disassemble the previous instruction?

I am debugging JIT code so things like disassembling a line doesn't work. I could disassemble a random range containing address like:

disas address-10 address+10

but this is very awkward and you'll see (bad) (hopefully not in the middle!) and start to worry that you are not getting something right. What I am looking for is something like:

x/-5i address

, but the above won't work.

Upvotes: 10

Views: 5837

Answers (3)

Gabriel F. T. Gomes
Gabriel F. T. Gomes

Reputation: 111

What I am looking for is something like:

x/-5i address

I'm not sure since when, but this does work with GBD 10. You have to compile with line number information, though, i.e.: compile with gcc -g.

Reference: https://sourceware.org/gdb/onlinedocs/gdb/Memory.html

More information at https://stackoverflow.com/a/77204059/619330

Upvotes: 0

Tomer
Tomer

Reputation: 3297

You can disassemble from the current instruction ($pc), and then just try to disassemble from a few bytes backwards until the second instruction you see is correct.

(lldb) x/3i $pc
->  0xeccac5d4: 0x6913 ldr    r3, [r2, #0x10]
    0xeccac5d6: 0xaa02 add    r2, sp, #0x8
    0xeccac5d8: 0x4798 blx    r3
(lldb) x/3i $pc-1
    0xeccac5d3: 0x1368 asrs   r0, r5, #0xd
    0xeccac5d5: 0x0269 lsls   r1, r5, #0x9
    0xeccac5d7: 0x98aa ldr    r0, [sp, #0x2a8]
(lldb) x/3i $pc-2
    0xeccac5d2: 0x6802 ldr    r2, [r0]
->  0xeccac5d4: 0x6913 ldr    r3, [r2, #0x10]   <------ Correct!
    0xeccac5d6: 0xaa02 add    r2, sp, #0x8

Upvotes: 0

Employed Russian
Employed Russian

Reputation: 213646

x/-5i address doesn't work

On x86, or any architecture with variable instruction size, you can't in general know the address of the start of previous instruction, and so you can't reliably disassemble previous instruction.

What I do (very similar to what you do): x/15i $pc-35. When you step back by sufficient number of bytes (35 here) the instruction stream disassembly usually re-synchronizes, you only see one or two (bad) instructions at the beginning, but instructions around $pc look correct.

Upvotes: 11

Related Questions