This is the mail archive of the gdb-prs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug breakpoints/22921] New: breakpoint in PLT corrupts function argument in $rcx


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

            Bug ID: 22921
           Summary: breakpoint in PLT corrupts function argument in $rcx
           Product: gdb
           Version: 8.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: breakpoints
          Assignee: unassigned at sourceware dot org
          Reporter: stsp at users dot sourceforge.net
  Target Milestone: ---

Created attachment 10865
  --> https://sourceware.org/bugzilla/attachment.cgi?id=10865&action=edit
test-case

Hello.

This bug is very illusive, so I spent quite some
time creating this fully automated test case.

Unpack tst.tar.gz.
There is a Makefile with testing targets.
"make pure" will compile and run the test-case w/o gdb.
You should see the following:
---
./tst
TEST PASSED! size=512
---

Now run "make gdb_good":
---
Function "DynAlloc" not defined.
Breakpoint 1 (DynAlloc) pending.
warning: Corrupted shared library list: 0x613e90 != 0x7ffff7ffd990

Breakpoint 1, 0x00007ffff6caaff0 in DynAlloc(char const*, unsigned int,
unsigned int)@plt () from ./libfdpp.so

Breakpoint 1, DynAlloc (what=0x7ffff6cf6a9f "dosobj", num=1, size=512) at
dyninit.cc:59
59        if (size != 512)
TEST PASSED! size=512
[Inferior 1 (process 31269) exited normally]
---

It will use the .gdbinit script that does not trigger
the bug. It is needed to show what arguments the function
"DynAlloc" is called with. "size=512" is a correct value.

Now run "make gdb_bad":
---
Function "DynAlloc" not defined.
Breakpoint 1 (DynAlloc) pending.
warning: Corrupted shared library list: 0x613e90 != 0x7ffff7ffd990

Breakpoint 1, 0x00007ffff6caaff0 in DynAlloc(char const*, unsigned int,
unsigned int)@plt () from ./libfdpp.so
#1  0x00007ffff6cf4560 in dosobj_init () at dosobj.cc:16
16          __FAR(void)fa = DynAlloc("dosobj", 1, size);
$1 = 512
0x00007ffff6caaff6 in DynAlloc(char const*, unsigned int, unsigned int)@plt ()
from ./libfdpp.so

Breakpoint 1, DynAlloc (what=0x7ffff6cf6a9f "dosobj", num=1, size=4140478454)
at dyninit.cc:59
59        if (size != 512)
TEST FAILED! size=-154488842
[Inferior 1 (process 31420) exited normally]
---

This shows that the size argument is corrupted.
There is a custom .gdbinit script here that is triggering
the race condition in gdb. What it does is sets the
breakpoint to DynAlloc, triggers this breakpoint, waits
one second, then does "c".
The argument that resides in $rcx, gets corrupted during
this "wait one second" thing. The "good" gdbinit script
just doesn't wait one second, so corruption does not happen.
The test-case arms the SIGALRM handler which should come
while gdb is waiting. Then the $rcx corruption happens.
Note that the signal handler is empty, so by itself it
can't corrupt $rcx. Also the corruption does not happen
if the PLT for DynAlloc is disabled via visibility=hidden.
So really it is something very tricky: PLT+signal+breakpoint -
all come into the game.

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]