/branches/tracing/kernel/generic/include/proc/thread.h |
---|
206,6 → 206,7 |
/** Debugging stuff */ |
waitq_t go_wq; |
unative_t syscall_args[6]; |
} thread_t; |
/** Thread list lock. |
/branches/tracing/kernel/generic/include/udebug.h |
---|
7,7 → 7,12 |
#ifndef KERN_UDEBUG_H_ |
#define KERN_UDEBUG_H_ |
void udebug_syscall_event(void); |
typedef enum { |
UDEBUG_EVENT_SYSCALL |
} udebug_event_t; |
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc); |
void udebug_stoppable_begin(void); |
void udebug_stoppable_end(void); |
/branches/tracing/kernel/generic/include/ipc/ipc.h |
---|
224,6 → 224,18 |
*/ |
#define IPC_M_DEBUG_STOP 12 |
/** Read arguments of a syscall. |
* |
* - ARG1 - thread identification |
* - ARG2 - destination address in the caller's address space |
* - ARG3 - size of receiving buffer in bytes |
* |
* on answer, the kernel will set: |
* |
* - ARG1 - actual size in bytes of data read |
*/ |
#define IPC_M_DEBUG_ARGS_READ 12 |
/* Well-known methods */ |
#define IPC_M_LAST_SYSTEM 511 |
#define IPC_M_PING 512 |
/branches/tracing/kernel/generic/src/syscall/syscall.c |
---|
111,7 → 111,7 |
if (THREAD->interrupted) |
thread_exit(); |
udebug_syscall_event(); |
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc); |
udebug_stoppable_end(); |
return rc; |
/branches/tracing/kernel/generic/src/ipc/sysipc.c |
---|
361,7 → 361,43 |
spinlock_unlock(&ta->lock); |
} |
static int debug_args_read(call_t *call, phone_t *phone) |
{ |
thread_t *t; |
link_t *l; |
task_t *ta; |
void *uspace_buffer; |
unative_t to_copy; |
int rc; |
klog_printf("debug_args_read()"); |
// FIXME: verify task/thread state |
ta = get_lock_callee_task(phone); |
klog_printf("task %llu", ta->taskid); |
l = ta->th_head.next; |
if (l != &TASK->th_head) { |
t = list_get_instance(l, thread_t, th_link); |
/* t = requested thread */ |
uspace_buffer = (void *)IPC_GET_ARG2(call->data); |
to_copy = IPC_GET_ARG3(call->data); |
rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy); |
if (rc != 0) { |
spinlock_unlock(&ta->lock); |
klog_printf("debug_args_read() - copy failed"); |
return rc; |
} |
IPC_SET_ARG1(call->data, to_copy); |
} |
spinlock_unlock(&ta->lock); |
klog_printf("debug_args_read() done"); |
return 1; /* actually need becksend with retval 0 */ |
} |
/** Called before the request is sent. |
* |
* @param call Call structure with the request. |
414,11 → 450,13 |
case IPC_M_DEBUG_BEGIN: |
/* actually need possibility of backsend with 0 result code */ |
rc = debug_begin(call, phone); |
if (rc != 0) return rc; |
break; |
return rc; |
case IPC_M_DEBUG_GO: |
debug_go(call, phone); |
break; |
case IPC_M_DEBUG_ARGS_READ: |
rc = debug_args_read(call, phone); |
return rc; |
default: |
break; |
} |
/branches/tracing/kernel/generic/src/udebug/udebug.c |
---|
58,15 → 58,29 |
} |
} |
void udebug_syscall_event(void) |
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc) |
{ |
call_t *call; |
spinlock_lock(&TASK->lock); |
/* being debugged + have go */ |
if (TASK->being_debugged && !TASK->stop_request) { /* locking! */ |
klog_printf("udebug_syscall_event"); |
IPC_SET_RETVAL(TASK->debug_go_call->data, 0); |
call = TASK->debug_go_call; |
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, UDEBUG_EVENT_SYSCALL); |
IPC_SET_ARG2(call->data, id); |
IPC_SET_ARG3(call->data, rc); |
klog_printf("udebug_syscall_event/ipc_answer"); |
THREAD->syscall_args[0] = a1; |
THREAD->syscall_args[1] = a2; |
THREAD->syscall_args[2] = a3; |
THREAD->syscall_args[3] = a4; |
THREAD->syscall_args[4] = a5; |
THREAD->syscall_args[5] = a6; |
ipc_answer(&TASK->answerbox, TASK->debug_go_call); |
spinlock_unlock(&TASK->lock); |
waitq_sleep(&THREAD->go_wq); |
/branches/tracing/uspace/app/tester/debug/debug1.c |
---|
10,6 → 10,11 |
int rc; |
int phoneid; |
int i; |
unsigned sc_args[6]; |
unsigned copied; |
unsigned ev_type; |
unsigned sc_id; |
int sc_rc; |
printf("running debug1 test\n"); |
taskid = 12; |
23,9 → 28,17 |
printf("-> %d\n", rc); |
while (1) { |
printf("send IPC_M_DEBUG_GO message\n"); |
rc = ipc_call_sync_0_0(phoneid, IPC_M_DEBUG_GO); |
printf("-> %d\n", rc); |
rc = ipc_call_sync_0_3(phoneid, IPC_M_DEBUG_GO, &ev_type, |
&sc_id, &sc_rc); |
rc = ipc_call_sync_3_1(phoneid, IPC_M_DEBUG_ARGS_READ, NULL, |
sc_args, 6 * sizeof(unsigned), &copied); |
if (rc >= 0) { |
printf("id %u(%u, %u, %u, %u, %u, %u) -> %d\n", |
sc_id, |
sc_args[0], sc_args[1], sc_args[2], |
sc_args[3], sc_args[4], sc_args[5], |
sc_rc); |
} |
} |
printf("done\n"); |