public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug breakpoints/14901] New: Breakpoints can end up in the middle of an instruction, causing corruption
@ 2012-11-30 21:24 gdb at dima dot secretsauce.net
  2024-01-22 17:17 ` [Bug breakpoints/14901] " ssbssa at sourceware dot org
  0 siblings, 1 reply; 2+ messages in thread
From: gdb at dima dot secretsauce.net @ 2012-11-30 21:24 UTC (permalink / raw)
  To: gdb-prs

http://sourceware.org/bugzilla/show_bug.cgi?id=14901

             Bug #: 14901
           Summary: Breakpoints can end up in the middle of an
                    instruction, causing corruption
           Product: gdb
           Version: 7.5
            Status: NEW
          Severity: normal
          Priority: P2
         Component: breakpoints
        AssignedTo: unassigned@sourceware.org
        ReportedBy: gdb@dima.secretsauce.net
    Classification: Unclassified


I'm using gdb 7.5.1, on a more-or-less vanilla amd64 box. I'm seeing that it is
possible to

1. set a breakpoint somewhere
2. load a new version of the executable being debugged
3. observe the breakpoint 0xCC byte end up in the middle of an instruction,
   causing havoc

The 0xCC byte corrupts the instruction it ends up in. Furthermore, unless one
knows that a breakpoint is involved, the observed behavior is extremely
mysterious. The output of "disass /r" doesn't display the 0xCC, so the user
thinks they're stepping through one instruction, while gdb is executing a
completely different one.

To reproduce, I have the following source I named tst.c:

==============================
#include <stdio.h>
#include <stdlib.h>

static void f(void)
{
#ifdef PAD
  char c = 3;
#endif
  int  a = 5;

  printf("0x%x\n", a);
}

int main(void)
{
  f();
  return 0;
}
==============================

I compile this with and without defining PAD:

gcc-4.7 -DPAD -g -o tst_pad tst.c; gcc-4.7 -g -o tst tst.c

I then load "tst_pad", set the breakpoint on the "a=5" line, then load "tst".
The old breakpoint stays at the same exact address, corrupting the a=5
statement.

This can be shown by running "gdb -x gdb.cmd" with gdb.cmd as

==============================
file /tmp/tst_pad
b main
r
s
n
b
info b
c
file /tmp/tst
r
info b
disass /r f
c
q
==============================

The output I see from this is

==============================
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Breakpoint 1 at 0x400539: file tst.c, line 16.

Breakpoint 1, main () at tst.c:16
16      f();
f () at tst.c:7
7      char c = 3;
9      int  a = 5;
Breakpoint 2 at 0x400518: file tst.c, line 9.
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400539 in main at tst.c:16
    breakpoint already hit 1 time
2       breakpoint     keep y   0x0000000000400518 in f at tst.c:9
0x5
[Inferior 1 (process 17031) exited normally]

Breakpoint 1, main () at tst.c:16
16      f();
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400535 in main at tst.c:16
    breakpoint already hit 1 time
2       breakpoint     keep y   0x0000000000400518 in f at tst.c:9
Dump of assembler code for function f:
   0x000000000040050c <+0>:    55    push   rbp
   0x000000000040050d <+1>:    48 89 e5    mov    rbp,rsp
   0x0000000000400510 <+4>:    48 83 ec 10    sub    rsp,0x10
   0x0000000000400514 <+8>:    c7 45 fc 05 00 00 00    mov    DWORD PTR
[rbp-0x4],0x5
   0x000000000040051b <+15>:    8b 45 fc    mov    eax,DWORD PTR [rbp-0x4]
   0x000000000040051e <+18>:    89 c6    mov    esi,eax
   0x0000000000400520 <+20>:    bf fc 05 40 00    mov    edi,0x4005fc
   0x0000000000400525 <+25>:    b8 00 00 00 00    mov    eax,0x0
   0x000000000040052a <+30>:    e8 b1 fe ff ff    call   0x4003e0 <printf@plt>
   0x000000000040052f <+35>:    c9    leave  
   0x0000000000400530 <+36>:    c3    ret    
End of assembler dump.
0xcc05
[Inferior 1 (process 17039) exited normally]
==============================

Note that the breakpoint is at 0x400518 in BOTH executables, and the "a"
variable ends up being 0xCC05 instead of 5. This is extremely perplexing to the
unsuspecting user, since the output of "disass /r" doesn't show the 0xCC. So
the
user steps through the instruction "mov DWORD PTR [rbp-0x4],0x5", but observes
something completely different happening!

gdb appears to have some safeguards against this. In the above script the
breakpoint was set with a simple "b" command when gdb was stopped at the
particular location. If it was set with "b 9" instead (breaking on line 9,
which
should be the same) then when loading the new executable, the breakpoint is
moved to 0x400514, which is at the start of an instruction, and produces more
predictable behavior.

I think it would be great if the breakpoint reinterpretation was either fixed,
or documented more clearly to indicate when the breakpoint should be moved and
when not. "help b" doesn't make clear that "b" and "b 9" produce very different
behaviors. Also, it would be great if "disass /r" had some sort of indication
that a particular instruction has been overwritten by a breakpoint; this would
make the observed failure much less baffling.

Thanks

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug breakpoints/14901] Breakpoints can end up in the middle of an instruction, causing corruption
  2012-11-30 21:24 [Bug breakpoints/14901] New: Breakpoints can end up in the middle of an instruction, causing corruption gdb at dima dot secretsauce.net
@ 2024-01-22 17:17 ` ssbssa at sourceware dot org
  0 siblings, 0 replies; 2+ messages in thread
From: ssbssa at sourceware dot org @ 2024-01-22 17:17 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=14901

Hannes Domani <ssbssa at sourceware dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ssbssa at sourceware dot org

--- Comment #1 from Hannes Domani <ssbssa at sourceware dot org> ---
This is a similar issue to PR11273, since 'b' without arguments is used here,
which sets the breakpoint on the current address, no matter what.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-01-22 17:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-30 21:24 [Bug breakpoints/14901] New: Breakpoints can end up in the middle of an instruction, causing corruption gdb at dima dot secretsauce.net
2024-01-22 17:17 ` [Bug breakpoints/14901] " ssbssa at sourceware dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).