Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2866 → Rev 2867

/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,45 → 80,95
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) {
klog_printf("udebug_syscall_event");
call = THREAD->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");
if (THREAD->debug_active != true ||
THREAD->debug_stop == true) {
spinlock_unlock(&THREAD->debug_lock);
interrupts_restore(ipl);
return;
}
 
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;
klog_printf("udebug_syscall_event");
call = THREAD->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");
 
/*
* 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->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;
 
THREAD->cur_event = UDEBUG_EVENT_SYSCALL;
spinlock_unlock(&THREAD->debug_lock);
/*
* 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;
 
spinlock_lock(&TASK->lock);
ipc_answer(&TASK->answerbox, THREAD->debug_go_call);
spinlock_unlock(&TASK->lock);
THREAD->cur_event = UDEBUG_EVENT_SYSCALL;
spinlock_unlock(&THREAD->debug_lock);
 
interrupts_restore(ipl);
spinlock_lock(&TASK->lock);
ipc_answer(&TASK->answerbox, THREAD->debug_go_call);
spinlock_unlock(&TASK->lock);
 
waitq_sleep(&THREAD->go_wq);
} else {
interrupts_restore(ipl);
 
waitq_sleep(&THREAD->go_wq);
}
 
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,33 → 186,20
break;
}
 
/* Read syscall arguments */
if (rc >= 0) {
rc = debug_args_read(phoneid, threadid_buf[thread_idx],
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;
}
}
 
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);
break;
default:
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(".");
}