I code a debugger using python's ptrace
module. After a debugged program stops on a breakpoint, I do:
On my system, if the step 2 (singleStep
) immediately follows by the step 3 (createBreakpoint
), then something wrong happens with the error message:
ptrace.error.PtraceError: ptrace(cmd=4, ...) error #3: No such process
But if I insert a delay (in the code below using sys.readline
), then all the steps and the debugged program are executed successfully.
Quite possible, the error is not specific to ptrace
module, maybe I just don't know the correct approach. Any help is welcome.
Python code:
import sys
import ptrace.debugger.child
import ptrace.debugger.debugger
pid = ptrace.debugger.child.createChild(['./sleeper'], 0)
dbg = ptrace.debugger.debugger.PtraceDebugger()
process = dbg.addProcess(pid, is_attached=1)
# use gdb "disassemble main" to find the address of
# the "movel"-instruction between the two "call"s
bp = process.createBreakpoint(0x08048432)
process.cont()
event = process.waitEvent()
print("New process event: %s" % event)
bp.desinstall(set_ip=1)
# Try to reinstall the breakpoint
process.singleStep()
if 1: # otherwise crash?
print 'Press any key to continue...'
sys.stdin.readline()
bp = process.createBreakpoint(bp.address)
print("Continue process execution")
process.cont()
C code:
#include <stdio.h>
int main() {
printf( "~~~~~~~~~~~~> Before breakpoint\n" );
// The breakpoint
printf( "~~~~~~~~~~~~> After breakpoint\n" );
return 0;
}
The man-page for ptrace says:
PTRACE_SYSCALL, PTRACE_SINGLESTEP
Restart the stopped tracee as for PTRACE_CONT, but arrange for the tracee to be stopped at the next entry to or exit from a system call, or after execution of a single instruction, respectively. (The tracee will also, as usual, be stopped upon receipt of a signal.) From the tracer's perspective, the tracee will appear to have been stopped by receipt of a SIGTRAP. So, for PTRACE_SYSCALL, for example, the idea is to inspect the arguments to the system call at the first stop, then do another PTRACE_SYSCALL and inspect the return value of the system call at the second stop. The data argument is treated as for PTRACE_CONT. (addr is ignored.)
I tried to handle the signal by doing nothing, and it helped.
process.singleStep()
event = process.waitEvent() # Repair-line
bp = process.createBreakpoint(bp.address)