This is the mail archive of the gdb@sources.redhat.com 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]

Re: internal-error: insert_step_resume_breakpoint_at_sal


[chug chug chug]

This is what I've noticed ...

(gdb) n
infrun: proceed (addr=0xffffffff, signal=144, step=1)

GDB tries to single step off the breakpoint @0x80a05f6, (when doing this all breakpoints are removed). GDB is expecting to get a SIGTRAP back ...

infrun: resume (step=1, signal=0)
target_terminal_inferior ()
child:target_xfer_partial (2, (null), 0xbffff18a, 0x0, 0x80a05f6, 2) = 2, bytes = 8b 45
target_resume (2896, step, 0)
infrun: wait_for_inferior


... but instead the inferior executes _no_ instructions and instead returns a [pending] SIGIO (still @0x80a05f6) ...

target_wait (-1, status) = 2896,   status->kind = stopped, signal = SIGIO
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
target_fetch_registers (eip) = f6050a08 0x80a05f6 134874614
infrun: stop_pc = 0x80a05f6
infrun: random signal 23

... so GDB again tries to step the inferior, this time passing in the SIGNAL, and expecting back a SIGTRAP when the inferior reaches the signal handlers first instruction ...

[wonder if, for this case GDB can insert all breakpoints and do a continue]

infrun: resume (step=1, signal=23)
target_terminal_inferior ()
child:target_xfer_partial (2, (null), 0xbfffeffa, 0x0, 0x80a05f6, 2) = 2, bytes = 8b 45
target_resume (2896, step, SIGIO)
infrun: prepare_to_wait


... but instead GDB gets back another pending SIGIO with the PC still back at the original BP instruction!

=> that's a known kernel bug. Instead of single-stepping into the signal handler, the kernel runs the signal handler to completion. Fixed in very recent 2.6 kernels.

... so gdb tries again to step into the signal handler again (remember, GDB's expecting the inferior to return a sigtrap from the process reaching the signal handler's first instruction) ...

target_wait (-1, status) = 2896, status->kind = stopped, signal = SIGIO
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
target_fetch_registers (eip) = f6050a08 0x80a05f6 134874614
infrun: stop_pc = 0x80a05f6
infrun: random signal 23
infrun: resume (step=1, signal=23)
target_terminal_inferior ()
child:target_xfer_partial (2, (null), 0xbfffeffa, 0x0, 0x80a05f6, 2) = 2, bytes = 8b 45
target_resume (2896, step, SIGIO)
infrun: prepare_to_wait


... but instead the signal handler runs, returns, and then executes _one_ instruction before trapping!

=> that's part of the same kernel bug

target_wait (-1, status) = 2896,   status->kind = stopped, signal = SIGTRAP
target_fetch_registers (eip) = f9050a08 0x80a05f9 134874617
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x80a05f9
infrun: trap expected
infrun: step-resume breakpoint

... so I think we've now got gdb thinking that the inferior got a sigtrap [tick] indicating that the process reached the handler [cross] and hence the the inferior should continue until the signal handler returns ...

child:target_xfer_partial (2, (null), 0x84ff020, 0x0, 0x810bdc0, 1) = 1, bytes =
83
child:target_xfer_partial (2, (null), 0x0, 0x8271b10, 0x810bdc0, 1) = 1, bytes =
cc
target_insert_breakpoint (0x810bdc0, xxx) = 0
child:target_xfer_partial (2, (null), 0x85004c8, 0x0, 0x80e74c1, 1) = 1, bytes = 68
child:target_xfer_partial (2, (null), 0x0, 0x8271b10, 0x80e74c1, 1) = 1, bytes =
cc
target_insert_breakpoint (0x80e74c1, xxx) = 0
child:target_xfer_partial (2, (null), 0x874d058, 0x0, 0x80a05f6, 1) = 1, bytes = 8b
child:target_xfer_partial (2, (null), 0x0, 0x8271b10, 0x80a05f6, 1) = 1, bytes =
cc
target_insert_breakpoint (0x80a05f6, xxx) = 0
child:target_xfer_partial (2, (null), 0x874d348, 0x0, 0x40009bd0, 1) = 1, bytes = c3
child:target_xfer_partial (2, (null), 0x0, 0x8271b10, 0x40009bd0, 1) = 1, bytes =
cc
target_insert_breakpoint (0x40009bd0, xxx) = 0
child:target_xfer_partial (2, (null), 0x8aacb20, 0x0, 0x4000c2e0, 1) = 1, bytes =
55
child:target_xfer_partial (2, (null), 0x0, 0x8271b10, 0x4000c2e0, 1) = 1, bytes =
cc
target_insert_breakpoint (0x4000c2e0, xxx) = 0
child:target_xfer_partial (2, (null), 0x87f2118, 0x0, 0x4032e860, 1) = 1, bytes = 55
child:target_xfer_partial (2, (null), 0x0, 0x8271b10, 0x4032e860, 1) = 1, bytes =
cc
target_insert_breakpoint (0x4032e860, xxx) = 0
infrun: resume (step=0, signal=0)


... consequently GDB inserts breakpoints, including the step-resume breakpoint at expected signal return address, and continues the target. The inferior is ment to next run the handler, return, and hit the step-resume breakpoint. Funny enough this doesn't work (it's well past that step resume breakpoint).

First thing I'd do is run the sig*.exp tests to see which are failing - if the kernel's working correctly they all pass.

The next thing we can consider is, for the case of GDB wanting to "next" over a signal optimizing things so that instead it does a "continue/signal". That might help a little, but then it might not.

Andrew


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