Is it expected that changes made to a program's address space would not be reverted during reverse debugging?
I have been debugging a program which segfaults when a pointer to strlen
in the GOT becomes corrupted during the course of execution. Thanks to advice stemming from comments to this question, I made the GOT of this program read-only by linking with the -z relro
option; however, this does not prevent the pointer in question from being overwritten. Namely, I can start
the program in gdb, step to the first occurrence of strlen
, verify that the pointer is valid (for example: x/g 0x5555555d10a8 ==> 0x5555555d10a8 <strlen@got.plt>: 0x00007ffff7e8d1e0
), continue
running, and wait for the pointer to become invalid (pointing to a nonsensical address outside the address space of the program; for example: x/g 0x5555555d10a8 ==>
0x5555555d10a8 <strlen@got.plt>: 0x0000000000002156
), prompting a segv
.
However, if I record full
the entire execution (from the first line until the program segfaults), and then awatch
the address with the pointer to strlen
during reverse-continue
, the watchpoint never triggers. And when the program has finally gotten back to instruction #0, the pointer is still pointing to the invalid address that it had when it segfaulted.
This leads to two questions. First, why is the GOT mutable despite the -z relro
linker option? Second, is it expected for a location in memory (the pointer to strlen
) that is altered during program execution to not be restored to its original value during reverse execution?