Example from BZ 130995 Description of problem: The ptrace(PT_STEP,SIGALARM) system call instead implements ptrace(PT_CONTINUE,SIGALARM). Version-Release number of selected component (if applicable): Roland says this is present in all i386 kernels. How reproducible: Always. Steps to Reproduce: In the below, target_resume(...) corresponds directly to a ptrace call. cagney@tomago$ gdb ./a.out [...] (gdb) b handler Breakpoint 1 at 0x80483bb: file sigstep.c, line 31. (gdb) list main 39 itimer_real = ITIMER_REAL, 40 itimer_virtual = ITIMER_VIRTUAL 41 } itimer = ITIMER_REAL; /* ITIMER_VIRTUAL; */ 42 43 main () 44 { 45 46 /* Set up the signal handler. */ 47 memset (&action, 0, sizeof (action)); 48 action.sa_handler = handler; (gdb) 49 sigaction (SIGVTALRM, &action, NULL); 50 sigaction (SIGALRM, &action, NULL); 51 52 /* The values needed for the itimer. This needs to be at least long 53 enough for the setitimer() call to return. */ 54 memset (&itime, 0, sizeof (itime)); 55 itime.it_value.tv_usec = 250 * 1000; 56 57 /* Loop for ever, constantly taking an interrupt. */ 58 while (1) (gdb) 59 { 60 /* Set up a one-off timer. A timer, rather than SIGSEGV, is 61 used as after a timer handler finishes the interrupted code 62 can safely resume. */ 63 setitimer (itimer, &itime, NULL); 64 /* Wait. */ 65 while (!done); 66 done = 0; 67 } 68 } (gdb) break 65 Breakpoint 2 at 0x8048456: file sigstep.c, line 65. (gdb) set debug target 1 (gdb) run Starting program: /home/cagney/tmp/sigstep/a.out [...] Breakpoint 2, main () at sigstep.c:65 65 while (!done); (gdb) step target_terminal_inferior () target_xfer_memory (0x8048456, xxx, 2, read, xxx) = 2, bytes = a1 64 Try to step off breakpoint, get back SIGALRM (ok), EIP doesn't change (ok). target_resume (27256, step, 0) target_wait (-1, status) = 27256, status->kind = stopped, signal = SIGALRM target_fetch_registers (eip) = 56840408 0x8048456 134513750 target_terminal_inferior () target_xfer_memory (0x8048456, xxx, 2, read, xxx) = 2, bytes = a1 64 Try to deliver SIGALRM, get back SIGTRAP (ok), EIP didn't change (not ok, should have been handler or signal trampoline). target_resume (27256, step, SIGALRM) target_wait (-1, status) = 27256, status->kind = stopped, signal = SIGTRAP target_fetch_registers (eip) = 56840408 0x8048456 134513750 target_xfer_memory (0x80483bb, xxx, 1, read, xxx) = 1, bytes = c7 target_xfer_memory (0x80483bb, xxx, 1, write, xxx) = 1, bytes = cc target_insert_breakpoint (0x80483bb, xxx) = 0 target_xfer_memory (0x8048456, xxx, 1, read, xxx) = 1, bytes = a1 target_xfer_memory (0x8048456, xxx, 1, write, xxx) = 1, bytes = cc target_insert_breakpoint (0x8048456, xxx) = 0 target_xfer_memory (0x4e02b0, xxx, 1, read, xxx) = 1, bytes = 55 target_xfer_memory (0x4e02b0, xxx, 1, write, xxx) = 1, bytes = cc target_insert_breakpoint (0x4e02b0, xxx) = 0 target_xfer_memory (0x4e3310, xxx, 1, read, xxx) = 1, bytes = 55 target_xfer_memory (0x4e3310, xxx, 1, write, xxx) = 1, bytes = cc target_insert_breakpoint (0x4e3310, xxx) = 0 target_xfer_memory (0x320820, xxx, 1, read, xxx) = 1, bytes = 55 target_xfer_memory (0x320820, xxx, 1, write, xxx) = 1, bytes = cc target_insert_breakpoint (0x320820, xxx) = 0 target_terminal_inferior () target_xfer_memory (0x8048457, xxx, 1, read, xxx) = 1, bytes = 64 GDB thinks it's still single stepping in main() so tries to do another single-step but with breakpoints inserted (it assumed the above managed to step off the breakpoint at 65). Since the PC didn't change, it re-hits the breakpoint at 65 causing a SIGTRAP and an off-by-one PC - decremented so that it matches the breakpoint. target_resume (-1, step, 0) target_wait (-1, status) = 27256, status->kind = stopped, signal = SIGTRAP target_fetch_registers (eip) = 57840408 0x8048457 134513751 target_prepare_to_store () target_store_registers (eip) = 56840408 0x8048456 134513750 target_xfer_memory (0x80483bb, xxx, 1, write, xxx) = 1, bytes = c7 target_remove_breakpoint (0x80483bb, xxx) = 0 target_xfer_memory (0x8048456, xxx, 1, write, xxx) = 1, bytes = a1 target_remove_breakpoint (0x8048456, xxx) = 0 target_xfer_memory (0x4e02b0, xxx, 1, write, xxx) = 1, bytes = 55 target_remove_breakpoint (0x4e02b0, xxx) = 0 target_xfer_memory (0x4e3310, xxx, 1, write, xxx) = 1, bytes = 55 target_remove_breakpoint (0x4e3310, xxx) = 0 target_xfer_memory (0x320820, xxx, 1, write, xxx) = 1, bytes = 55 target_remove_breakpoint (0x320820, xxx) = 0 target_terminal_ours () Breakpoint 2, main () at sigstep.c:65 65 while (!done); (gdb) The ptrace(PT_STEP,SIGNAL) should setup the signal and then execute no instructions.
Thanks, David. Andrew, could you please verify that this bug has been fixed by testing on p630.lab.boston.redhat.com (or installing a kernel from porkchop as described in comment #6)?
In 32-bit mode, the PT_STEP, it's issuing one instruction after constructing the signal frame. It should just construct the signal frame, adjust the PC to signal-handler address and then fake a sigtrap. See the corresponding i386 PR for the background. (gdb) b 65 Breakpoint 1 at 0x10000550: file sigstep.c, line 65. (gdb) run Starting program: /tmp/cagney/sigstep Breakpoint 1, main () at sigstep.c:65 65 while (!done); (gdb) break *handler Breakpoint 2 at 0x10000480: file sigstep.c, line 30. (gdb) stepi 0x10000554 65 while (!done); in detail: (gdb) stepi target_xfer_memory (0x100004ac, xxx, 4, read, xxx) = 4, bytes = 94 21 ff e0 target_xfer_memory (0x100004b0, xxx, 4, read, xxx) = 4, bytes = 7c 08 02 a6 target_xfer_memory (0x100004b4, xxx, 4, read, xxx) = 4, bytes = 93 e1 00 1c target_xfer_memory (0x100004b8, xxx, 4, read, xxx) = 4, bytes = 90 01 00 24 target_xfer_memory (0x100004bc, xxx, 4, read, xxx) = 4, bytes = 7c 3f 0b 78 target_xfer_memory (0x100004c0, xxx, 4, read, xxx) = 4, bytes = 3d 20 10 01 target_fetch_registers (r1) = ffffdbe0 0xffffdbe0 4294958048 target_xfer_memory (0xffffdbe0, xxx, 4, read, xxx) = 4, bytes = ff ff dc 00 target_fetch_registers (r31) = ffffdbe0 0xffffdbe0 4294958048 target_terminal_inferior () target_resume (10456, step, 0) target_wait (-1, status) = 10456, status->kind = stopped, signal = SIGALRM target_fetch_registers (pc) = 10000550 0x10000550 268436816 target_xfer_memory (0x10000550, xxx, 4, read, xxx) = 4, bytes = 3d 20 10 01 target_xfer_memory (0x1000054c, xxx, 4, read, xxx) = 4, bytes = 48 01 05 55 target_xfer_memory (0x10000550, xxx, 4, read, xxx) = 4, bytes = 3d 20 10 01 target_xfer_memory (0x1000054c, xxx, 4, read, xxx) = 4, bytes = 48 01 05 55 target_xfer_memory (0x100004ac, xxx, 4, read, xxx) = 4, bytes = 94 21 ff e0 target_xfer_memory (0x100004b0, xxx, 4, read, xxx) = 4, bytes = 7c 08 02 a6 target_xfer_memory (0x100004b4, xxx, 4, read, xxx) = 4, bytes = 93 e1 00 1c target_xfer_memory (0x100004b8, xxx, 4, read, xxx) = 4, bytes = 90 01 00 24 target_xfer_memory (0x100004bc, xxx, 4, read, xxx) = 4, bytes = 7c 3f 0b 78 target_xfer_memory (0x100004c0, xxx, 4, read, xxx) = 4, bytes = 3d 20 10 01 target_fetch_registers (r1) = ffffdbe0 0xffffdbe0 4294958048 target_xfer_memory (0xffffdbe0, xxx, 4, read, xxx) = 4, bytes = ff ff dc 00 target_fetch_registers (r31) = ffffdbe0 0xffffdbe0 4294958048 target_terminal_inferior () target_resume (10456, step, SIGALRM) target_wait (-1, status) = 10456, status->kind = stopped, signal = SIGTRAP target_fetch_registers (pc) = 10000484 0x10000484 268436612 Notice how the resume/step/sigalarm stopped at 0x10000484 and not 0x10000480. I think 64-bit PPC has the same problem.
The patch in comment #12 has just been committed to the RHEL3 U4 patch pool this evening (in kernel version 2.4.21-23.EL). The additional siginfo problem will be fixed in U5.
ernie: it sounds as if there are 2 issues gathered in this one bug. Would it make sense to move the siginfo problem into a seperate bug targetted for a RHEL3-U5 Blocker list?
James, that's probably a good idea.
James/Andrew/David, is there a new bugzilla for the ppc64 siginfo problems?
Not AFAIK; Paulus fixed them before Andrew had a chance to track them down and make a properly coherent report.
The original bug is fixed; The second bug isn't but that should really be filed separately.
This bug report is considered fully resolved in U4 and will be closed when the U4 advisory is pushed on RHN. I'm removing it from the U5 blocker list. The ppc64 siginfo rework was committed to 2.4.21-24.EL.
An errata has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on the solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2004-550.html