ptrace: PTRACE_SINGLESTEP
This commit is contained in:
parent
9e19ebb93a
commit
41ba264cdc
20
apps/dbg.c
20
apps/dbg.c
@ -403,6 +403,11 @@ static void show_commandline(pid_t pid, int status, struct regs * regs) {
|
||||
if (signum == SIGINT) signum = 0;
|
||||
ptrace(PTRACE_CONT, pid, NULL, (void*)(uintptr_t)signum);
|
||||
return;
|
||||
} else if (!strcmp(buf, "step") || !strcmp(buf,"s")) {
|
||||
int signum = WSTOPSIG(status);
|
||||
if (signum == SIGINT) signum = 0;
|
||||
ptrace(PTRACE_SINGLESTEP, pid, NULL, (void*)(uintptr_t)signum);
|
||||
return;
|
||||
} else if (!strcmp(buf, "poke")) {
|
||||
char * addr = arg;
|
||||
char * data = strstr(addr, " ");
|
||||
@ -599,8 +604,19 @@ int main(int argc, char * argv[]) {
|
||||
if (WIFSTOPPED(status)) {
|
||||
if (WSTOPSIG(status) == SIGTRAP) {
|
||||
/* Don't care about TRAP right now */
|
||||
//ptrace(PTRACE_SIGNALS_ONLY_PLZ, p, NULL, NULL);
|
||||
ptrace(PTRACE_CONT, p, NULL, NULL);
|
||||
int event = (status >> 16) & 0xFF;
|
||||
switch (event) {
|
||||
case PTRACE_EVENT_SINGLESTEP: {
|
||||
struct regs regs;
|
||||
ptrace(PTRACE_GETREGS, res, NULL, ®s);
|
||||
show_commandline(res, status, ®s);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//ptrace(PTRACE_SIGNALS_ONLY_PLZ, p, NULL, NULL);
|
||||
ptrace(PTRACE_CONT, p, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("Program received signal %s.\n", sig_to_str(WSTOPSIG(status)));
|
||||
|
||||
|
@ -13,12 +13,14 @@ enum __ptrace_request {
|
||||
PTRACE_GETREGS,
|
||||
PTRACE_PEEKDATA,
|
||||
PTRACE_SIGNALS_ONLY_PLZ,
|
||||
PTRACE_POKEDATA
|
||||
PTRACE_POKEDATA,
|
||||
PTRACE_SINGLESTEP
|
||||
};
|
||||
|
||||
enum __ptrace_event {
|
||||
PTRACE_EVENT_SYSCALL_ENTER,
|
||||
PTRACE_EVENT_SYSCALL_EXIT,
|
||||
PTRACE_EVENT_SINGLESTEP,
|
||||
};
|
||||
|
||||
#ifndef __kernel__
|
||||
|
@ -7,9 +7,12 @@
|
||||
#include <kernel/signal.h>
|
||||
#include <kernel/misc.h>
|
||||
#include <kernel/time.h>
|
||||
#include <kernel/ptrace.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
#include <kernel/arch/x86_64/mmu.h>
|
||||
#include <kernel/arch/x86_64/ports.h>
|
||||
#include <kernel/arch/x86_64/pml.h>
|
||||
@ -229,11 +232,21 @@ struct regs * isr_handler(struct regs * r) {
|
||||
/* Spurious interrupt */
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
/* Debug interrupt */
|
||||
r->rflags &= ~(1 << 8);
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACE_SIGNALS) {
|
||||
ptrace_signal(SIGTRAP, PTRACE_EVENT_SINGLESTEP);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
default: {
|
||||
if (r->int_no < 32) {
|
||||
if (!this_core->current_process || r->cs == 0x08) {
|
||||
arch_fatal();
|
||||
}
|
||||
printf("int_no %ld in process %d\n",
|
||||
r->int_no, this_core->current_process->id);
|
||||
send_signal(this_core->current_process->id, SIGILL, 1);
|
||||
} else {
|
||||
for (size_t i = 0; i < IRQ_CHAIN_DEPTH; i++) {
|
||||
|
@ -127,6 +127,22 @@ long ptrace_signals_only(pid_t pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long ptrace_singlestep(pid_t pid, int sig) {
|
||||
process_t * tracee = process_from_pid(pid);
|
||||
if (!tracee || (tracee->tracer != this_core->current_process->id) || !(tracee->flags & PROC_FLAG_SUSPENDED)) return -ESRCH;
|
||||
|
||||
struct regs * target = tracee->interrupt_registers ? tracee->interrupt_registers : tracee->syscall_registers;
|
||||
|
||||
/* arch_set_singlestep? */
|
||||
target->rflags |= (1 << 8);
|
||||
|
||||
__sync_and_and_fetch(&tracee->flags, ~(PROC_FLAG_SUSPENDED));
|
||||
tracee->status = (sig << 8);
|
||||
make_process_ready(tracee);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long ptrace_handle(long request, pid_t pid, void * addr, void * data) {
|
||||
switch (request) {
|
||||
case PTRACE_ATTACH:
|
||||
@ -143,6 +159,8 @@ long ptrace_handle(long request, pid_t pid, void * addr, void * data) {
|
||||
return ptrace_poke(pid,addr,data);
|
||||
case PTRACE_SIGNALS_ONLY_PLZ:
|
||||
return ptrace_signals_only(pid);
|
||||
case PTRACE_SINGLESTEP:
|
||||
return ptrace_singlestep(pid,(uintptr_t)data);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user