Discussion:
[Bug breakpoints/23763] New: gdb places function breakpoint after segment override prefix, crashing inferior
tstarling at wikimedia dot org
2018-10-12 00:51:14 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23763

Bug ID: 23763
Summary: gdb places function breakpoint after segment override
prefix, crashing inferior
Product: gdb
Version: 8.1
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: breakpoints
Assignee: unassigned at sourceware dot org
Reporter: tstarling at wikimedia dot org
Target Milestone: ---

I have a function that starts by reading from a thread local storage variable:

(gdb) x/5i excimer_timer_thread_shutdown
0x5555558ee535 <excimer_timer_thread_shutdown>: push %rbp
0x5555558ee536 <excimer_timer_thread_shutdown+1>: mov %rsp,%rbp
0x5555558ee539 <excimer_timer_thread_shutdown+4>: sub $0x30,%rsp
0x5555558ee53d <excimer_timer_thread_shutdown+8>: mov %fs:0x0,%rax
0x5555558ee546 <excimer_timer_thread_shutdown+17>: lea -0xf0(%rax),%rax

When I put a breakpoint on this function, gdb uses an address which is in the
middle of the fourth instruction, after the fs: segment override prefix:

(gdb) break excimer_timer_thread_shutdown
Breakpoint 1 at 0x5555558ee53e: file /srv/php/git/ext/excimer/excimer_timer.c,
line 110.

The program is interrupted at this location, and then segfaults when it tries
to resume after the segment override, presumably attempting to read from
address zero without a segment override:

Thread 1 "php" hit Breakpoint 1, excimer_timer_thread_shutdown () at
/srv/php/git/ext/excimer/excimer_timer.c:110
110 ZEND_HASH_FOREACH_VAL(excimer_timer_tls.timers_by_id,
zp_thread) {
(gdb) print $pc
$1 = (void (*)()) 0x5555558ee53e <excimer_timer_thread_shutdown+9>
(gdb) cont

Thread 1 "php" received signal SIGSEGV, Segmentation fault.
excimer_timer_thread_shutdown () at
/srv/php/git/ext/excimer/excimer_timer.c:110
110 ZEND_HASH_FOREACH_VAL(excimer_timer_tls.timers_by_id,
zp_thread) {

I gather gdb is trying to put the breakpoint after the stack setup, but it
misinterprets the 0x64 segment override opcode, and so the breakpoint ends up
at +9 instead of +8.

objdump confirms that the line number information provided by gcc is correct:

000000000000033d <excimer_timer_thread_shutdown>:
excimer_timer_thread_shutdown():
/srv/php/git/ext/excimer/excimer_timer.c:106
33d: 55 push %rbp
33e: 48 89 e5 mov %rsp,%rbp
341: 48 83 ec 30 sub $0x30,%rsp
/srv/php/git/ext/excimer/excimer_timer.c:110
345: 64 48 8b 04 25 00 00 mov %fs:0x0,%rax

Here are the relevant two lines from objdump -g, proving that the line numbers
are exactly as shown in the disassembly:

[0x0000061b] Special opcode 50: advance Address by 3 to 0x33d and Line by 3
to 106
[0x0000061c] Special opcode 121: advance Address by 8 to 0x345 and Line by 4
to 110
--
You are receiving this mail because:
You are on the CC list for the bug.
Loading...