Comment by Joker_vD

2 days ago

...there is no bloody way debuggers don't just subtract 1 from the EIP on INT 3. Like... there is no way. Right?

If every single SIGTRAP was caused by an INT3 instruction, then this would work, but SIGTRAP can also be generated by single stepping where subtracting 1 would be incorrect.

GDB already compensates for breakpoints it inserts itself because it knows their locations, so it subtracts 1 as you suggest. It could also recognize embedded INT3 instructions but that requires distinguishing their traps from other causes of SIGTRAP which is much more complicated. So instead GDB generally leaves the instruction pointer unchanged for embedded INT3 instructions.

Here's a discussion of precisely this issue from the GDB developers:

https://sourceware.org/pipermail/gdb/2009-February/034621.ht...

  • An INT 3 isn't even always one byte; there's a one byte encoding, but I believe it's also legal to issue a two byte encoded INT N, where N is 3.

  • I’m pretty sure that even kernels from the date of that message report the trap/fault vector.

    But let’s be clear. ptrace() is unbelievably crappy, and gdb is approximately as crappy.

I've been working in C++ using VS for about 15 years and for as long as I've remembered my heuristic has been that if I get a breakpoint the offending instruction is on the line above what was reported.

  • That's just an eternally confusing bug of VS/cdb. On other IDEs such as QtCreator with clang or gdb it shows the break red dot exactly where the issue is.