// doTrap handles SIGTRAP debug events with a cause of 0. These can // be caused either by an installed breakpoint, a breakpoint in the // program text, or by single stepping. // // TODO(austin) I think we also get this on an execve syscall. func (ev *debugEvent) doTrap() (threadState, os.Error) { t := ev.t if t.state == singleStepping { return stopped, nil } // Hit a breakpoint. Linux leaves the program counter after // the breakpoint. If this is an installed breakpoint, we // need to back the PC up to the breakpoint PC. var regs syscall.PtraceRegs err := t.ptraceGetRegs(®s) if err != nil { return stopped, err } b, ok := t.proc.breakpoints[uintptr(regs.PC())-uintptr(len(bpinst386))] if !ok { // We must have hit a breakpoint that was actually in // the program. Leave the IP where it is so we don't // re-execute the breakpoint instruction. Expose the // fact that we stopped with a SIGTRAP. return stoppedSignal, nil } t.breakpoint = b t.logTrace("at breakpoint %v, backing up PC from %#x", b, regs.PC()) regs.SetPC(uint64(b.pc)) err = t.ptraceSetRegs(®s) if err != nil { return stopped, err } return stoppedBreakpoint, nil }