[Bug gdb/22645] New: gdb hangs on 32-bit ARM armv7l at SIGTRAP from "bkpt" instruction 0xe1200070

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/22645] New: gdb hangs on 32-bit ARM armv7l at SIGTRAP from "bkpt" instruction 0xe1200070

macro@linux-mips.org
https://sourceware.org/bugzilla/show_bug.cgi?id=22645

            Bug ID: 22645
           Summary: gdb hangs on 32-bit ARM armv7l at SIGTRAP from "bkpt"
                    instruction 0xe1200070
           Product: gdb
           Version: HEAD
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: jreiser at BitWagon dot com
  Target Milestone: ---

gdb hangs in an infinite loop instead of stopping upon SIGTRAP when an inferior
on 32-bit ARM architecture 'armv7l' (such as RaspberryPi-3B in 32-bit mode)
executes the instruction "bkpt", which is 0xe1200070.  The Linux kernel sends
SIGTRAP, but gdb processing tries PTRACE_CONT, which re-triggers the SIGTRAP.
Interrupting the gdb hang with SIGINT (ctrl-C) revives gdb, and the output for
SIGINT looks like the way gdb should have responded in the first place to the
SIGTRAP.

Here is an annotated transcript of a console terminal session which contains a
4-line reproducible test case plus recipe, as well as some 'strace' debugging
of the ptrace() calls used by gdb.
=====
$ uname -a   ## the hardware and operating system environment
Linux host 4.14.7-300.fc27.armv7hl #1 SMP Mon Dec 18 17:10:15 UTC 2017 armv7l
armv7l armv7l GNU/Linux

$ cat bkpt.S   ## the test case
        .globl _start
_start:
        bkpt
        nop

$ gcc -o bkpt -nostartfiles -nostdlib bkpt.S   ## the build recipe

$ ./bkpt   ## bare execution gets SIGTRAP
Trace/breakpoint trap (core dumped)
$ echo $?   ## shell exit code of previous process in this shell
133   ## 133 = 128 + 5;  5 ==> SIGTRAP
$ strace ./bkpt
execve("./bkpt", ["./bkpt"], 0xbeebe4c0 /* 28 vars */) = 0
--- SIGTRAP {si_signo=SIGTRAP, si_code=TRAP_HWBKPT, si_pid=65688, si_uid=0} ---
+++ killed by SIGTRAP (core dumped) +++
Trace/breakpoint trap (core dumped)

$ gdb --version
GNU gdb (GDB) 8.0.50.20171216-git
$ gdb bkpt   ## gdb hangs
(gdb) x/12i _start   ## verify correct assembly
   0x10098 <_start>:    bkpt    0x0000
   0x1009c <_start+4>:  nop     {0}
   0x100a0:     Cannot access memory at address 0x100a0
(gdb) x/12x _start
0x10098 <_start>:       0xe1200070      0xe320f000      Cannot access memory at
address 0x100a0
(gdb) run
Starting program: /path/to/bkpt
^C   ## session appears to be hung (gdb "unhealthy"), so send SIGINT from
console
Program received signal SIGINT, Interrupt.
0x00010098 in _start ()   ## gdb acts healthy for SIGINT; why not for SIGTRAP?
(gdb) x/i $pc
=> 0x10098 <_start>:    bkpt    0x0000   ## the correct place
(gdb)
   0x1009c <_start+4>:  nop     {0}
(gdb) q

$ dmesg | tail   ## what happened while SIGTRAP under gdb
[  483.287100] Unhandled prefetch abort: breakpoint debug exception (0x002) at
0x00010098
[  483.295547] Unhandled prefetch abort: breakpoint debug exception (0x002) at
0x00010098
[  483.303960] Unhandled prefetch abort: breakpoint debug exception (0x002) at
0x00010098

$ strace -e trace=ptrace -o strace-gdb.out gdb ./bkpt   ## note strange
PTRACE_CONT after SIGTRAP (33 lines below; "what is this?")
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1307, si_uid=1000,
si_status=0, si_utime=0, si_stime=0} ---
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_GETREGS, 1308, NULL, 0xbe84ec60) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=SI_USER,
si_pid=1308, si_uid=1000}) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_GETREGS, 1308, NULL, 0xbe84ec60) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=SI_USER,
si_pid=1308, si_uid=1000}) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1309, si_uid=1000,
si_status=SIGSTOP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_SETOPTIONS, 1309, NULL, PTRACE_O_TRACESYSGOOD) = 0
ptrace(PTRACE_SETOPTIONS, 1309, NULL, PTRACE_O_TRACEFORK) = 0
ptrace(PTRACE_SETOPTIONS, 1309, NULL,
PTRACE_O_TRACEFORK|PTRACE_O_TRACEVFORKDONE) = 0
ptrace(PTRACE_CONT, 1309, NULL, SIG_0)  = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1309, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_GETEVENTMSG, 1309, NULL, [1310]) = 0
ptrace(PTRACE_KILL, 1310)               = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=1310, si_uid=1000,
si_status=SIGKILL, si_utime=0, si_stime=0} ---
ptrace(PTRACE_SETOPTIONS, 1309, NULL, PTRACE_O_EXITKILL) = 0
ptrace(PTRACE_KILL, 1309)               = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1309, si_uid=1000,
si_status=SIGCHLD, si_utime=0, si_stime=0} ---
ptrace(PTRACE_KILL, 1309)               = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=1309, si_uid=1000,
si_status=SIGKILL, si_utime=0, si_stime=0} ---
ptrace(PTRACE_SETOPTIONS, 1308, NULL,
PTRACE_O_TRACESYSGOOD|PTRACE_O_TRACEFORK|PTRACE_O_TRACEVFORK|PTRACE_O_TRACECLONE|PTRACE_O_TRACEEXEC|PTRACE_O_TRACEVFORKDONE|PTRACE_O_EXITKILL)
= 0
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84efa8,
iov_len=72}]) = 0
ptrace(PTRACE_GETVFPREGS, 1308, NULL, 0xbe84ee88) = 0
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ef70,
iov_len=72}]) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ede8,
iov_len=72}]) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0, si_value={int=1308, ptr=0x51c}}) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0}) = 0
ptrace(PTRACE_GETHBPREGS, 1308, NULL, 0xbe84edec) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0   ## what is this?
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ede8,
iov_len=72}]) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0, si_value={int=1308, ptr=0x51c}}) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0}) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=0} ---
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ede8,
iov_len=72}]) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0, si_value={int=1308, ptr=0x51c}}) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0}) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=1} ---
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ede8,
iov_len=72}]) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0, si_value={int=1308, ptr=0x51c}}) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0}) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0

   <<snip>>

--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGTRAP, si_utime=0, si_stime=20} ---
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ede8,
iov_len=72}]) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0, si_value={int=1308, ptr=0x51c}}) = 0
ptrace(PTRACE_GETSIGINFO, 1308, NULL, {si_signo=SIGTRAP, si_code=TRAP_HWBKPT,
si_pid=65688, si_uid=0}) = 0
ptrace(PTRACE_CONT, 1308, 0x1, SIG_0)   = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=1308, si_uid=1000,
si_status=SIGINT, si_utime=0, si_stime=20} ---
ptrace(PTRACE_GETREGSET, 1308, NT_PRSTATUS, [{iov_base=0xbe84ef68,
iov_len=72}]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10094, [0xbd7e609d]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_PEEKTEXT, 1308, 0x10098, [0xe1200070]) = 0
ptrace(PTRACE_KILL, 1308)               = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=1308, si_uid=1000,
si_status=SIGKILL, si_utime=0, si_stime=20} ---
ptrace(PTRACE_KILL, 1308)               = -1 ESRCH (No such process)
+++ exited with 0 +++

=====

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/22645] gdb hangs on 32-bit ARM armv7l at SIGTRAP from "bkpt" instruction 0xe1200070

macro@linux-mips.org
https://sourceware.org/bugzilla/show_bug.cgi?id=22645

--- Comment #1 from John Reiser <jreiser at BitWagon dot com> ---
The same bad behavior also occurs when the bkpt is not the first instruction:
=====
        .globl _start
_start:
        nop
        bkpt
        nop
=====

In the past gdb has had trouble when the very first instruction after execve
generated a trap:
   https://bugzilla.redhat.com/show_bug.cgi?id=162775
   "gdb ignores SIGTRAP at entry address"
   2008-03-10  [almost ten years ago]

but the revised test case above, where the SIGTRAP is at the second
instruction, still hangs under gdb.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug gdb/22645] gdb hangs on 32-bit ARM armv7l at SIGTRAP from "bkpt" instruction 0xe1200070

macro@linux-mips.org
In reply to this post by macro@linux-mips.org
https://sourceware.org/bugzilla/show_bug.cgi?id=22645

--- Comment #2 from John Reiser <jreiser at BitWagon dot com> ---
Contrasting with the similar "brk #0" (.word 0xd4200000) on 64-bit ARM aarch64:
gdb stops and reports SIGTRAP the first time (does not silently loop using
PTRACE_CONT) and strace shows
=====
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=9705, si_uid=1000,
si_status=SIGTRAP, si_utime=1, si_stime=0} ---
ptrace(PTRACE_GETREGSET, 9705, NT_PRSTATUS, [{iov_base=0xffffe5b28e88,
iov_len=272}]) = 0
ptrace(PTRACE_GETSIGINFO, 9705, NULL, {si_signo=SIGTRAP, si_code=TRAP_BRKPT,
si_pid=4194520, si_uid=0, si_value={int=-441282160, ptr=0xffffe5b29190}}) = 0
ptrace(PTRACE_PEEKTEXT, 9705, 0x4000d8, [0xd503201fd4200000]) = 0
ptrace(PTRACE_PEEKTEXT, 9705, 0x4000d8, [0xd503201fd4200000]) = 0
ptrace(PTRACE_PEEKTEXT, 9705, 0x4000d0, [0xd503201f155c8bda]) = 0
ptrace(PTRACE_PEEKTEXT, 9705, 0x4000d8, [0xd503201fd4200000]) = 0
=====
One notable difference is:
   si_code=TRAP_BRKPT   on 64-bit ARM
   si_code=TRAP_HWBKPT  on 32-bit ARM

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