infinite loop stopping at "pop" insn on x64-windows
We noticed the following hang trying to run a program where one of the subroutines we built without debugging info (opaque_routine): $ gdb my_program (gdb) break opaque_routine (gdb) run [...hangs...] The problem comes from the fact that, at the breakpoint's address, we have the following code: => 0x0000000000401994 <+4>: pop %rbp At some point after hitting the breakpoint and stopping, GDB calls amd64_windows_frame_decode_epilogue, which then gets stuck in the following infinite loop: | /* We don't care about the instruction deallocating the frame: | if it hasn't been executed, the pc is still in the body, | if it has been executed, the following epilog decoding will work. */ | | /* First decode: | - pop reg [41 58-5f] or [58-5f]. */ | | while (1) | { | /* Read opcode. */ | if (target_read_memory (pc, &op, 1) != 0) | return -1; | | if (op >= 0x40 && op <= 0x4f) | { | /* REX prefix. */ | rex = op; | | /* Read opcode. */ | if (target_read_memory (pc + 1, &op, 1) != 0) | return -1; | } | else | rex = 0; | | if (op >= 0x58 && op <= 0x5f) | { | /* pop reg */ | gdb_byte reg = (op & 0x0f) | ((rex & 1) << 3); | | cache->prev_reg_addr[amd64_windows_w2gdb_regnum[reg]] = cur_sp; | cur_sp += 8; | } | else | break; | | /* Allow the user to break this loop. This shouldn't happen as the | number of consecutive pop should be small. */ | QUIT; | } Nothing in that loop updates PC, and therefore, because the instruction we stopped at is a "pop", we keep looping forever doing the same thing over and over! This patch fixes the issue by advancing PC to the beginning of the next instruction if the current one is a "pop reg" instruction. gdb/ChangeLog: * amd64-windows-tdep.c (amd64_windows_frame_decode_epilogue): Increment PC in while loop skipping "pop reg" instructions.
This commit is contained in:
parent
416dc9c6e9
commit
a6a20ad7a1
|
@ -1,3 +1,8 @@
|
|||
2015-11-23 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* amd64-windows-tdep.c (amd64_windows_frame_decode_epilogue):
|
||||
Increment PC in while loop skipping "pop reg" instructions.
|
||||
|
||||
2015-11-23 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* arm-tdep.c (arm_exidx_unwind_sniffer): Do not check for a frame
|
||||
|
|
|
@ -488,6 +488,7 @@ amd64_windows_frame_decode_epilogue (struct frame_info *this_frame,
|
|||
|
||||
cache->prev_reg_addr[amd64_windows_w2gdb_regnum[reg]] = cur_sp;
|
||||
cur_sp += 8;
|
||||
pc += rex ? 2 : 1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue