How breakpoints work

preview_player
Показать описание
This time we will try to understand the trick debuggers do to set up breakpoints. It is not only about the debugger, but the operating system's kernel (linux) should know what sequence of bytes is used by gdb as a breakpoint.

#c #cpp #cpu #linux #kernel #debugging #arm #gdb #breakpoint
Рекомендации по теме
Комментарии
Автор

On x86 there is INT3 which is a valid CPU instruction meant for generating a debugger interrupt/trap

siniarskimar
Автор

Some architectures (like x86) have special hardware debug registers that can do even fancier things like break on memory read/write/execute so you can place breakpoints on data as well as on code without having to replace anything making the resume process braindead easy and fast. Thr only downside is that you have a limited about of those and they dont exist on every platform.

nezu_cc
Автор

This channel is a treasure! And how come this video has the least views while it's literally the most interesting one?

Anyway, I knew some platforms had explicit debugging support. But this method is just ingenious! And if the CPU doesn't even have traps and kernel-mode code, you could achieve a similar effect with just calls + stack analysis. (Or noting down which breakpoint was hit and jumping away to the handler.)

mskiptr
Автор

On x86 i remember there's a special hardware trace flag that will generate a debugger interrupt for every single instruction executed, without the need to explicitly insert/replace any instructions. That's basically how single stepping works on x86. For resume i assume we can replace the original instruction back, set trace flag, resume & let cpu execute the replaced instruction, hit trace flag interrupt, then re-replace the instruction with a trap and clear the trace flag in the interrupt handler.

not sure how other architecture does it tho. but i would imagine it would be quite tricky to do without any hardware support.

miigon
Автор

Copy the the source, minus the illegal instruction and restart the process? seems like a hell of a lot of work though. *scratches head*

alastairtheduke
Автор

I'm not sure if this would fit but how about using the original instruction as the "arguments" to the breakpoint

nanamacapagal
Автор

How does the kernel handler know which process is the gdb?

twometerpeterr
Автор

im not sure if this is rude of me to point to other videos but, fasterthanlime made a video that explored this topic a little bit using actual code. i recommend checking it out. didn't have these pretty animations though.

aemogie
Автор

could create a new instruction that's a copy of the old one, and then put a jump after it going back to the original location?
though this feels like it could cause a few problems. you'd need to allocate memory somewhere. what happens if you hit an interrupt before you get back to the original code, and then the memory gets lost? or could this cause other problems?
i think it would probably be fine as long as the kernel allocated a permanent space for a "return from trap" instruction for each process. maybe this would be useful for other exceptions, too?
the other idea would be to replace the breakpoint with the original instruction, but this'd cause issues if you were in a loop and returned to it. you could try setting a temporary second breakpoint that you'd hit again at which point the original could be restored, but this could cause performance issues, and more crucially if your instruction is a jump you may not be able to guarantee the second breakpoint could be hit.

electra_
Автор

could you jump back into the execution after the breakpoint? and make sure the trap is only prepended?

spookyconnolly