/branches/tracing/kernel/generic/include/udebug/udebug.h |
---|
120,7 → 120,8 |
typedef enum { |
UDEBUG_EVENT_FINISHED = 1, /**< Debuging session has finished */ |
UDEBUG_EVENT_SYSCALL /**< A syscall has been executed */ |
UDEBUG_EVENT_SYSCALL, /**< A syscall has been executed */ |
UDEBUG_EVENT_NEW_THREAD /**< The task created a new thread */ |
} udebug_event_t; |
#ifdef KERNEL |
138,6 → 139,8 |
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_new_thread_event(struct thread *t); |
void udebug_stoppable_begin(void); |
void udebug_stoppable_end(void); |
/branches/tracing/kernel/generic/src/proc/thread.c |
---|
840,6 → 840,8 |
thread_attach(t, TASK); |
thread_ready(t); |
udebug_new_thread_event(t); |
return 0; |
} else |
free(kernel_uarg); |
/branches/tracing/kernel/generic/src/udebug/udebug.c |
---|
80,8 → 80,13 |
spinlock_lock(&THREAD->debug_lock); |
/* Must only generate events when in debugging session and have go */ |
if (THREAD->debug_active == true && |
THREAD->debug_stop == false) { |
if (THREAD->debug_active != true || |
THREAD->debug_stop == true) { |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
return; |
} |
klog_printf("udebug_syscall_event"); |
call = THREAD->debug_go_call; |
IPC_SET_RETVAL(call->data, 0); |
114,11 → 119,56 |
interrupts_restore(ipl); |
waitq_sleep(&THREAD->go_wq); |
} else { |
} |
void udebug_new_thread_event(struct thread *t) |
{ |
call_t *call; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
klog_printf("udebug_new_thread_event"); |
klog_printf("- check state"); |
/* Must only generate events when in debugging session */ |
if (THREAD->debug_active != true) { |
klog_printf("- debug_active: %s, debug_stop: %s", |
THREAD->debug_active ? "yes(+)" : "no(-)", |
THREAD->debug_stop ? "yes(-)" : "no(+)"); |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
return; |
} |
klog_printf("- trigger event"); |
call = THREAD->debug_go_call; |
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, UDEBUG_EVENT_NEW_THREAD); |
IPC_SET_ARG2(call->data, (unative_t)t); |
/* |
* Make sure debug_stop is true when going to sleep |
* in case we get woken up by DEBUG_END. (At which |
* point it must be back to the initial true value). |
*/ |
THREAD->debug_stop = true; |
THREAD->cur_event = UDEBUG_EVENT_NEW_THREAD; |
spinlock_unlock(&THREAD->debug_lock); |
spinlock_lock(&TASK->lock); |
ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
klog_printf("- sleep"); |
waitq_sleep(&THREAD->go_wq); |
} |
/** @} |
*/ |
/branches/tracing/uspace/app/sctrace/sctrace.c |
---|
121,16 → 121,55 |
} |
} |
void event_syscall(unsigned thread_idx, unsigned sc_id, int sc_rc) |
{ |
unsigned sc_args[6]; |
int rv_type; |
int rc; |
/* Read syscall arguments */ |
rc = debug_args_read(phoneid, threadid_buf[thread_idx], sc_args); |
async_serialize_start(); |
printf("[%d] ", thread_idx); |
if (rc < 0) { |
printf("error\n"); |
async_serialize_end(); |
return; |
} |
/* Print syscall name, id and arguments */ |
printf("%s", syscall_desc[sc_id].name); |
print_sc_args(sc_args, syscall_desc[sc_id].n_args); |
rv_type = syscall_desc[sc_id].rv_type; |
print_sc_retval(sc_rc, rv_type); |
switch (sc_id) { |
case SYS_IPC_CALL_ASYNC_SLOW: |
sc_ipc_call_async_slow(sc_args); |
break; |
default: |
break; |
} |
async_serialize_end(); |
} |
void event_new_thread(unsigned hash) |
{ |
async_serialize_start(); |
printf("new thread, hash 0x%x\n", hash); |
async_serialize_end(); |
} |
void trace_loop(void *thread_idx_arg) |
{ |
int rc; |
unsigned sc_args[6]; |
unsigned copied; |
unsigned ev_type; |
unsigned sc_id; |
int sc_rc; |
int rv_type; |
unsigned thread_idx; |
unsigned val0, val1; |
thread_idx = (unsigned)thread_idx_arg; |
printf("trace_loop(%d)\n", thread_idx); |
137,9 → 176,9 |
while (!abort_trace) { |
/* Run thread until a syscall is executed */ |
/* Run thread until an event occurs */ |
rc = debug_go(phoneid, threadid_buf[thread_idx], |
&ev_type, &sc_id, &sc_rc); |
&ev_type, &val0, &val1); |
printf("rc = %d, ev_type=%d\n", rc, ev_type); |
if (ev_type == UDEBUG_EVENT_FINISHED) { |
147,35 → 186,22 |
break; |
} |
/* Read syscall arguments */ |
if (rc >= 0) { |
rc = debug_args_read(phoneid, threadid_buf[thread_idx], |
sc_args); |
} |
async_serialize_start(); |
printf("[%d] ", thread_idx); |
/* Print syscall name, id and arguments */ |
if (rc >= 0) { |
printf("%s", syscall_desc[sc_id].name); |
print_sc_args(sc_args, syscall_desc[sc_id].n_args); |
rv_type = syscall_desc[sc_id].rv_type; |
print_sc_retval(sc_rc, rv_type); |
} |
async_serialize_end(); |
switch (sc_id) { |
case SYS_IPC_CALL_ASYNC_SLOW: |
sc_ipc_call_async_slow(sc_args); |
switch (ev_type) { |
case UDEBUG_EVENT_SYSCALL: |
event_syscall(thread_idx, val0, (int)val1); |
break; |
case UDEBUG_EVENT_NEW_THREAD: |
event_new_thread(val0); |
break; |
default: |
printf("unknown event type %d\n", ev_type); |
break; |
} |
} |
} |
printf("trace_loop(%d) exiting\n", thread_idx); |
} |
/branches/tracing/uspace/app/tester/debug/debug1.c |
---|
24,7 → 24,7 |
//printf("(active) wait for thread 'test'\n"); |
while (!done) { |
usleep(5000000); |
usleep(20000000); |
printf("."); |
} |