Created attachment 6942 [details] assembly When debugging, it writes wrong bytes. See my assemby. It runs fine without gdb
It works but you probably mean you have put "break *_start" breakpoint there, it crashes then. Use "hbreak *_start" and it will work. GDB could verify the breakpoint byte has not changed when removing the breakpoint.
Created attachment 6943 [details] GDB log It still crash with hbreak *_start
Created attachment 6944 [details] Various recent GDBs I can't speak for gdb-7.2, that is really too old release. Moreover it is SuSE variant which is heavily patched and such bugreport belongs more to the SuSE bugtracker. With trunk FSF GDB I have found hbreak no longer can be placed. It works with hbreak with Fedora GDB as it has it patched but that is irrelevant here. With trunk FSF GDB it is most easier to just remove the breakpoint. See the attached example runs.
Why hbreak feathure was removed in newest version? It will be returned?
hbreak is dependent on target arch. And target arch is known only after the target is running. If you do "start" then "hbreak" works in FSF GDB. Yes, sometimes it should be fixed in FSF GDB, you can submit an appropriate patch to gdb-patches, the Fedora one is: http://pkgs.fedoraproject.org/cgit/gdb.git/tree/gdb-bz541866-rwatch-before-run.patch
There are very similar bug about software break point http://sourceware.org/bugzilla/show_bug.cgi?id=14959 I found this: http://www.sourceware.org/gdb/onlinedocs/gdbint.html#Algorithms It says: >Software breakpoints require gdb to do somewhat more work. The basic theory is that gdb will replace a program instruction with a trap, illegal divide, or some other instruction that will cause an exception, and then when it's encountered, gdb will take the exception and stop the program. When the user says to continue, gdb will restore the original instruction, single-step, re-insert the trap, and continue on. >Since it literally overwrites the program being tested, the program area must be writable, so this technique won't work on programs in ROM. It can also distort the behavior of programs that examine themselves, although such a situation would be highly unusual. So, there are bug with restoring the original instruction
Hmm... Maybe I can write a GDB plugin that doing many "stepi" and checks each instruction working with RAM on the subject of whether it is trying to read or write from/to position of software breakpoints. And if it do so, plugin interrupts this "stepi-check_opcode" loop. It is possible? Where can I read about GDB plugin api? And another question. Why does my program in assembler does not overwrite the bytes of software breakpoint?
(In reply to comment #7) > Hmm... Maybe I can write a GDB plugin that doing many "stepi" and checks each > instruction working with RAM on the subject of whether it is trying to read or > write from/to position of software breakpoints. And if it do so, plugin > interrupts this "stepi-check_opcode" loop. I see it overcomplicated. Just patch default_memory_remove_breakpoint in gdb/mem-break.c so that it: * Temporarily sets show_memory_breakpoints. * Uses target_read_memory to fetch the data from inferior. * Compares the read in bytes with what gdbarch_breakpoint_from_pc returns and if it does not match it prints some warning and prevents the current call of target_write_raw_memory with shadow_contents. * Restores show_memory_breakpoints (see make_show_memory_breakpoints_cleanup). And it should be configurable as it will be a performance hit primarily with remote targets. See also several *-tdep.c files using set_gdbarch_memory_remove_breakpoint as they have something more specific than default_memory_remove_breakpoint. > Why does my program in assembler > does not overwrite the bytes of software breakpoint? * GDB inserts breakpoint: * GDB saves original (old) instruction. * GDB writes there breakpoint * Your code overwrites the breakpoint by new instruction. * GDB removes breakpoint: * GDB writes there the original (old) instruction. - Your new instruction is lost.
Created attachment 6948 [details] testing GDB (In reply to comment #8) > (In reply to comment #7) > > Hmm... Maybe I can write a GDB plugin that doing many "stepi" and checks each > > instruction working with RAM on the subject of whether it is trying to read or > > write from/to position of software breakpoints. And if it do so, plugin > > interrupts this "stepi-check_opcode" loop. > > I see it overcomplicated. Just patch default_memory_remove_breakpoint in > gdb/mem-break.c so that it: > * Temporarily sets show_memory_breakpoints. > * Uses target_read_memory to fetch the data from inferior. > * Compares the read in bytes with what gdbarch_breakpoint_from_pc returns > and if it does not match it prints some warning and prevents the current > call of target_write_raw_memory with shadow_contents. > * Restores show_memory_breakpoints (see make_show_memory_breakpoints_cleanup). > > And it should be configurable as it will be a performance hit primarily with > remote targets. > > See also several *-tdep.c files using set_gdbarch_memory_remove_breakpoint as > they have something more specific than default_memory_remove_breakpoint. > Yes, this is good idea if memory write check is enough, but how can it help if the program read from software breakpoint address (integrity check)? What happens if instruction under breakpoint "wants" read or overwrite himself? I'll check it. I'm going to read the GDB Internals Manual and try to do something > > > Why does my program in assembler > > does not overwrite the bytes of software breakpoint? > > * GDB inserts breakpoint: > * GDB saves original (old) instruction. > * GDB writes there breakpoint > * Your code overwrites the breakpoint by new instruction. > * GDB removes breakpoint: > * GDB writes there the original (old) instruction. > - Your new instruction is lost. It behaves differently. If GDB step into another breakpoint, then it rewrite breakpoints. See attached. Why?
(In reply to comment #9) > Yes, this is good idea if memory write check is enough, but how can it help if > the program read from software breakpoint address (integrity check)? It is never perfect but it should at least improve the situation. > It behaves differently. If GDB step into another breakpoint, then it rewrite > breakpoints. See attached. Why? I do not see exactly what do you want to know. For example if you have a breakpoint at address X and GDB is currently stopped at that address X during "continue" the breakpoint at address X is removed, single-stepped, breakpoint is put back to address X and only then the inferior is continued. You can see it if you use "set debug infrun 1".