How to Set a Breakpoint on 'Memory Access' in Gdb

Can I set a breakpoint on 'memory access' in GDB?

watch only breaks on write, rwatch let you break on read, and awatch let you break on read/write.

You can set read watchpoints on memory locations:

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface

but one limitation applies to the rwatch and awatch commands; you can't use gdb variables
in expressions:

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.

So you have to expand them yourself:

gdb$ print $ebx 
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f

Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()

Edit: Oh, and by the way. You need either hardware or software support. Software is obviously much slower. To find out if your OS supports hardware watchpoints you can see the can-use-hw-watchpoints environment setting.

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.

Can I have gdb break on read/write from an address?

Yes.

Using Watchpoints:

watch - only breaks on write (and only if the value changes)

rwatch - breaks on read, and

awatch - breaks on read/write.

A more detailed brief from some internet sources:

watch

watch is gdb’s way of setting data breakpoints which will halt the execution of a program if memory changes at the specified location.

watch breakpoints can either be set on the variable name or any address location.

watch my_variable
watch *0x12345678
where 0x12345678 is a valid address.

rwatch

rwatch (read-watch) breakpoints break the execution of code when the program tries to read from a variable or memory location.

rwatch iWasAccessed
rwatch *0x12345678
where 0x12345678 is a valid address.

awatch

awatch or access watches break execution of the program if a variable or memory location is written to or read from. In summary, awatches are watches and rwatches all in one. It is a handy way of creating one breakpoint than two separate ones.

awatch *0x12345678
where 0x12345678 is a valid address.

GDB set breakpoint in function offset

(gdb) p &foo
$1 = (<text variable, no debug info> *) 0x555555555129 <foo>
(gdb) b *foo+0x10
Breakpoint 2 at 0x555555555139

QED.

GDB Cannot insert breakpoint, Cannot access memory at address XXX?

Debugging stripped code is probably very much useless (except for reverse engineering), but you can cause gdb to stop at the very first instruction, and you are already doing this accidentally. If the address of a breakpoint cannot be mapped, gdb stops and tells you the error. As a side effect, your program is stopped at its first instruction. An address that's guaranteed to be unmappable is 0, so just do the following:

(gdb) b *0
Breakpoint 1 at 0x0
(gdb) r
Starting program: [...]
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x0

(gdb) disas
Dump of assembler code for function _start:
=> 0x00007ffff7ddd190 <+0>: mov %rsp,%rdi
0x00007ffff7ddd193 <+3>: callq 0x7ffff7de0750 <_dl_start>

Here you see the PC sits at 0x00007ffff7ddd190. So this is your entry point at runtime.

In order to be able to continue (or: single-step for example), you have to delete the offending breakpoint:

(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) c
Continuing.

Credits for this answer go to this answer on reverse engineering

GDB breakpoint in main() cannot access memory

(gdb) x/24s $esp
0xffffffffffffe550: <error: Cannot access memory at address 0xffffffffffffe550>

On an x86-64 target, $rsp should be used. Using $esp will lead to incorrect results.

$esp is taken from the bottom 32 bits of the 64-bit $rsp register, and gdb treats it as type int32_t. $rsp in your example was probably 0x7fffffffe550. Gdb's x command, which wants to use a 64-bit address, will take the bottom 32 bits of $rsp, 0xffffe550, and sign-extend that to 0xffffffffffffe550. That's almost certainly an invalid address; typical user-space addresses on Linux don't go above 0x7ffffffff000 or so.

Try x/24s $rsp. If you're trying to follow exercises out of an old book, you may be able to duplicate their 32-bit examples by giving gcc the -m32 option, if it supports it. Then you can use $esp.



Related Topics



Leave a reply



Submit