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;
|
if (signum == SIGINT) signum = 0;
|
||||||
ptrace(PTRACE_CONT, pid, NULL, (void*)(uintptr_t)signum);
|
ptrace(PTRACE_CONT, pid, NULL, (void*)(uintptr_t)signum);
|
||||||
return;
|
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")) {
|
} else if (!strcmp(buf, "poke")) {
|
||||||
char * addr = arg;
|
char * addr = arg;
|
||||||
char * data = strstr(addr, " ");
|
char * data = strstr(addr, " ");
|
||||||
@ -599,8 +604,19 @@ int main(int argc, char * argv[]) {
|
|||||||
if (WIFSTOPPED(status)) {
|
if (WIFSTOPPED(status)) {
|
||||||
if (WSTOPSIG(status) == SIGTRAP) {
|
if (WSTOPSIG(status) == SIGTRAP) {
|
||||||
/* Don't care about TRAP right now */
|
/* Don't care about TRAP right now */
|
||||||
//ptrace(PTRACE_SIGNALS_ONLY_PLZ, p, NULL, NULL);
|
int event = (status >> 16) & 0xFF;
|
||||||
ptrace(PTRACE_CONT, p, NULL, NULL);
|
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 {
|
} else {
|
||||||
printf("Program received signal %s.\n", sig_to_str(WSTOPSIG(status)));
|
printf("Program received signal %s.\n", sig_to_str(WSTOPSIG(status)));
|
||||||
|
|
||||||
|
@ -13,12 +13,14 @@ enum __ptrace_request {
|
|||||||
PTRACE_GETREGS,
|
PTRACE_GETREGS,
|
||||||
PTRACE_PEEKDATA,
|
PTRACE_PEEKDATA,
|
||||||
PTRACE_SIGNALS_ONLY_PLZ,
|
PTRACE_SIGNALS_ONLY_PLZ,
|
||||||
PTRACE_POKEDATA
|
PTRACE_POKEDATA,
|
||||||
|
PTRACE_SINGLESTEP
|
||||||
};
|
};
|
||||||
|
|
||||||
enum __ptrace_event {
|
enum __ptrace_event {
|
||||||
PTRACE_EVENT_SYSCALL_ENTER,
|
PTRACE_EVENT_SYSCALL_ENTER,
|
||||||
PTRACE_EVENT_SYSCALL_EXIT,
|
PTRACE_EVENT_SYSCALL_EXIT,
|
||||||
|
PTRACE_EVENT_SINGLESTEP,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef __kernel__
|
#ifndef __kernel__
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
#include <kernel/signal.h>
|
#include <kernel/signal.h>
|
||||||
#include <kernel/misc.h>
|
#include <kernel/misc.h>
|
||||||
#include <kernel/time.h>
|
#include <kernel/time.h>
|
||||||
|
#include <kernel/ptrace.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
|
||||||
#include <kernel/arch/x86_64/mmu.h>
|
#include <kernel/arch/x86_64/mmu.h>
|
||||||
#include <kernel/arch/x86_64/ports.h>
|
#include <kernel/arch/x86_64/ports.h>
|
||||||
#include <kernel/arch/x86_64/pml.h>
|
#include <kernel/arch/x86_64/pml.h>
|
||||||
@ -229,11 +232,21 @@ struct regs * isr_handler(struct regs * r) {
|
|||||||
/* Spurious interrupt */
|
/* Spurious interrupt */
|
||||||
break;
|
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: {
|
default: {
|
||||||
if (r->int_no < 32) {
|
if (r->int_no < 32) {
|
||||||
if (!this_core->current_process || r->cs == 0x08) {
|
if (!this_core->current_process || r->cs == 0x08) {
|
||||||
arch_fatal();
|
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);
|
send_signal(this_core->current_process->id, SIGILL, 1);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < IRQ_CHAIN_DEPTH; i++) {
|
for (size_t i = 0; i < IRQ_CHAIN_DEPTH; i++) {
|
||||||
|
@ -127,6 +127,22 @@ long ptrace_signals_only(pid_t pid) {
|
|||||||
return 0;
|
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) {
|
long ptrace_handle(long request, pid_t pid, void * addr, void * data) {
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case PTRACE_ATTACH:
|
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);
|
return ptrace_poke(pid,addr,data);
|
||||||
case PTRACE_SIGNALS_ONLY_PLZ:
|
case PTRACE_SIGNALS_ONLY_PLZ:
|
||||||
return ptrace_signals_only(pid);
|
return ptrace_signals_only(pid);
|
||||||
|
case PTRACE_SINGLESTEP:
|
||||||
|
return ptrace_singlestep(pid,(uintptr_t)data);
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user