mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
af48d08f97
The gdb.arch/i386-bp_permanent.exp test is currently failing an assertion recently added: (gdb) stepi ../../src/gdb/infrun.c:2237: internal-error: resume: Assertion `sig != GDB_SIGNAL_0' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) FAIL: gdb.arch/i386-bp_permanent.exp: Single stepping past permanent breakpoint. (GDB internal error) The assertion expects that the only reason we currently need to step a breakpoint instruction is when we have a signal to deliver. But when stepping a permanent breakpoint (with or without a signal) we also reach this code. The assertion is correct and the permanent breakpoints skipping code is wrong. Consider the case of the user doing "step/stepi" when stopped at a permanent breakpoint. GDB's `resume' calls the gdbarch_skip_permanent_breakpoint hook and then happily continues stepping: /* Normally, by the time we reach `resume', the breakpoints are either removed or inserted, as appropriate. The exception is if we're sitting at a permanent breakpoint; we need to step over it, but permanent breakpoints can't be removed. So we have to test for it here. */ if (breakpoint_here_p (aspace, pc) == permanent_breakpoint_here) { gdbarch_skip_permanent_breakpoint (gdbarch, regcache); } But since gdbarch_skip_permanent_breakpoint already advanced the PC manually, this ends up executing the instruction that is _after_ the breakpoint instruction. The user-visible result is that a single-step steps two instructions. The gdb.arch/i386-bp_permanent.exp test is actually ensuring that that's indeed how things work. It runs to an int3 instruction, does "stepi", and checks that "leave" was executed with that "stepi". Like this: (gdb) b *0x0804848c Breakpoint 2 at 0x804848c (gdb) c Continuing. Breakpoint 2, 0x0804848c in standard () (gdb) disassemble Dump of assembler code for function standard: 0x08048488 <+0>: push %ebp 0x08048489 <+1>: mov %esp,%ebp 0x0804848b <+3>: push %edi => 0x0804848c <+4>: int3 0x0804848d <+5>: leave 0x0804848e <+6>: ret 0x0804848f <+7>: nop (gdb) si 0x0804848e in standard () (gdb) disassemble Dump of assembler code for function standard: 0x08048488 <+0>: push %ebp 0x08048489 <+1>: mov %esp,%ebp 0x0804848b <+3>: push %edi 0x0804848c <+4>: int3 0x0804848d <+5>: leave => 0x0804848e <+6>: ret 0x0804848f <+7>: nop End of assembler dump. (gdb) One would instead expect that a stepi at 0x0804848c stops at 0x0804848d, _before_ the "leave" is executed. This commit changes GDB this way. Care is taken to make stepping into a signal handler when the step starts at a permanent breakpoint instruction work correctly. The patch adjusts gdb.arch/i386-bp_permanent.exp in this direction, and also makes it work on x86_64 (currently it only works on i*86). The patch also adds a new gdb.base/bp-permanent.exp test that exercises many different code paths related to stepping permanent breakpoints, including the stepping with signals cases. The test uses "hack/trick" to make it work on all (or most) platforms -- it doesn't really hard code a breakpoint instruction. Tested on x86_64 Fedora 20, native and gdbserver. gdb/ 2014-11-12 Pedro Alves <palves@redhat.com> * infrun.c (resume): Clear the thread's 'stepped_breakpoint' flag. Rewrite stepping over a permanent breakpoint. (thread_still_needs_step_over, proceed): Don't set stepping_over_breakpoint for permanent breakpoints. (handle_signal_stop): Don't clear stepped_breakpoint. Also pull single-step breakpoints out of the target on hardware step targets. (process_event_stop_test): If stepping a permanent breakpoint doesn't hit the step-resume breakpoint, delete the step-resume breakpoint. (switch_back_to_stepped_thread): Also check if the stepped thread has advanced already on hardware step targets. (currently_stepping): Return true if the thread stepped a breakpoint. gdb/testsuite/ 2014-11-12 Pedro Alves <palves@redhat.com> * gdb.arch/i386-bp_permanent.c: New file. * gdb.arch/i386-bp_permanent.exp: Don't skip on x86_64. (srcfile): Set to i386-bp_permanent.c. (top level): Adjust to work in both 32-bit and 64-bit modes. Test that stepi does not execute the 'leave' instruction, instead of testing it does execute. * gdb.base/bp-permanent.c: New file. * gdb.base/bp-permanent.exp: New file. |
||
---|---|---|
.. | ||
aarch64-atomic-inst.c | ||
aarch64-atomic-inst.exp | ||
alpha-step.c | ||
alpha-step.exp | ||
altivec-abi.c | ||
altivec-abi.exp | ||
altivec-regs.c | ||
altivec-regs.exp | ||
amd64-byte.exp | ||
amd64-disp-step.exp | ||
amd64-disp-step.S | ||
amd64-dword.exp | ||
amd64-entry-value-inline.c | ||
amd64-entry-value-inline.exp | ||
amd64-entry-value-inline.S | ||
amd64-entry-value-param.c | ||
amd64-entry-value-param.exp | ||
amd64-entry-value-param.S | ||
amd64-entry-value-paramref.cc | ||
amd64-entry-value-paramref.exp | ||
amd64-entry-value-paramref.S | ||
amd64-entry-value.cc | ||
amd64-entry-value.exp | ||
amd64-entry-value.s | ||
amd64-i386-address.exp | ||
amd64-i386-address.S | ||
amd64-invalid-stack-middle.c | ||
amd64-invalid-stack-middle.exp | ||
amd64-invalid-stack-middle.S | ||
amd64-invalid-stack-top.c | ||
amd64-invalid-stack-top.exp | ||
amd64-optimout-repeat.c | ||
amd64-optimout-repeat.exp | ||
amd64-optimout-repeat.S | ||
amd64-prologue-xmm.c | ||
amd64-prologue-xmm.exp | ||
amd64-prologue-xmm.s | ||
amd64-pseudo.c | ||
amd64-stap-optional-prefix.exp | ||
amd64-stap-optional-prefix.S | ||
amd64-stap-special-operands.exp | ||
amd64-stap-three-arg-disp.c | ||
amd64-stap-three-arg-disp.S | ||
amd64-stap-triplet.c | ||
amd64-stap-triplet.S | ||
amd64-stap-wrong-subexp.exp | ||
amd64-stap-wrong-subexp.S | ||
amd64-tailcall-cxx1.cc | ||
amd64-tailcall-cxx1.S | ||
amd64-tailcall-cxx2.cc | ||
amd64-tailcall-cxx2.S | ||
amd64-tailcall-cxx.exp | ||
amd64-tailcall-noret.c | ||
amd64-tailcall-noret.exp | ||
amd64-tailcall-noret.S | ||
amd64-tailcall-ret.c | ||
amd64-tailcall-ret.exp | ||
amd64-tailcall-ret.S | ||
amd64-word.exp | ||
arm-bl-branch-dest.c | ||
arm-bl-branch-dest.exp | ||
arm-disp-step.exp | ||
arm-disp-step.S | ||
avr-flash-qualifier.c | ||
avr-flash-qualifier.exp | ||
e500-abi.c | ||
e500-abi.exp | ||
e500-prologue.c | ||
e500-prologue.exp | ||
e500-regs.c | ||
e500-regs.exp | ||
gdb1291.exp | ||
gdb1291.s | ||
gdb1431.exp | ||
gdb1431.s | ||
gdb1558.c | ||
gdb1558.exp | ||
i386-avx512.c | ||
i386-avx512.exp | ||
i386-avx.c | ||
i386-avx.exp | ||
i386-bp_permanent.c | ||
i386-bp_permanent.exp | ||
i386-byte.exp | ||
i386-cfi-notcurrent.exp | ||
i386-cfi-notcurrent.S | ||
i386-disp-step.exp | ||
i386-disp-step.S | ||
i386-dr3-watch.c | ||
i386-dr3-watch.exp | ||
i386-float.exp | ||
i386-float.S | ||
i386-gnu-cfi-asm.S | ||
i386-gnu-cfi.c | ||
i386-gnu-cfi.exp | ||
i386-mpx.c | ||
i386-mpx.exp | ||
i386-permbkpt.exp | ||
i386-permbkpt.S | ||
i386-prologue.c | ||
i386-prologue.exp | ||
i386-pseudo.c | ||
i386-signal.c | ||
i386-signal.exp | ||
i386-size-overlap.c | ||
i386-size-overlap.exp | ||
i386-size.c | ||
i386-size.exp | ||
i386-sse-stack-align.c | ||
i386-sse-stack-align.exp | ||
i386-sse-stack-align.S | ||
i386-sse.c | ||
i386-sse.exp | ||
i386-stap-eval-lang-ada.c | ||
i386-stap-eval-lang-ada.exp | ||
i386-stap-eval-lang-ada.S | ||
i386-unwind.c | ||
i386-unwind.exp | ||
i386-word.exp | ||
ia64-breakpoint-shadow.exp | ||
ia64-breakpoint-shadow.S | ||
iwmmxt-regs.c | ||
iwmmxt-regs.exp | ||
Makefile.in | ||
mips16-thunks-inmain.c | ||
mips16-thunks-main.c | ||
mips16-thunks-sin.c | ||
mips16-thunks-sinfrob16.c | ||
mips16-thunks-sinfrob.c | ||
mips16-thunks-sinmain.c | ||
mips16-thunks-sinmips16.c | ||
mips16-thunks.exp | ||
mips-octeon-bbit.c | ||
mips-octeon-bbit.exp | ||
pa64-nullify.s | ||
pa-nullify.exp | ||
pa-nullify.s | ||
powerpc-aix-prologue.c | ||
powerpc-aix-prologue.exp | ||
powerpc-d128-regs.c | ||
powerpc-d128-regs.exp | ||
powerpc-power.exp | ||
powerpc-power.s | ||
powerpc-prologue.c | ||
powerpc-prologue.exp | ||
powerpc-stackless.exp | ||
powerpc-stackless.S | ||
ppc64-atomic-inst.exp | ||
ppc64-atomic-inst.S | ||
ppc-dfp.c | ||
ppc-dfp.exp | ||
ppc-fp.c | ||
ppc-fp.exp | ||
s390-multiarch.c | ||
s390-multiarch.exp | ||
s390-tdbregs.c | ||
s390-tdbregs.exp | ||
sparc-sysstep.c | ||
sparc-sysstep.exp | ||
spu-info.c | ||
spu-info.exp | ||
spu-ls.c | ||
spu-ls.exp | ||
thumb2-it.exp | ||
thumb2-it.S | ||
thumb-bx-pc.exp | ||
thumb-bx-pc.S | ||
thumb-prologue.c | ||
thumb-prologue.exp | ||
thumb-singlestep.exp | ||
thumb-singlestep.S | ||
vsx-regs.c | ||
vsx-regs.exp |