/branches/tracing/kernel/generic/include/udebug/udebug.h |
---|
207,14 → 207,7 |
/** Debugging part of thread_t structure. |
*/ |
typedef struct { |
/** |
* Prevent deadlock with udebug_before_thread_runs() in interrupt |
* handler, without actually disabling interrupts. |
* ==0 means "unlocked", >0 means "locked" |
*/ |
atomic_t int_lock; |
/** Synchronize debug ops on this thread / access to this structure */ |
/** Synchronize debug ops on this thread / access to this structure. */ |
mutex_t lock; |
waitq_t go_wq; |
222,11 → 215,11 |
unative_t syscall_args[6]; |
istate_t *uspace_state; |
/** What type of event are we stopped in or 0 if none */ |
udebug_event_t cur_event; |
bool stop; |
bool stoppable; |
bool debug_active; /**< In a debugging session */ |
/** What type of event are we stopped in or 0 if none. */ |
udebug_event_t cur_event; |
bool go; /**< thread is GO */ |
bool stoppable; /**< thread is stoppable */ |
bool debug_active; /**< thread is in a debugging session */ |
} udebug_thread_t; |
struct task; |
/branches/tracing/kernel/generic/src/synch/futex.c |
---|
115,6 → 115,7 |
uintptr_t paddr; |
pte_t *t; |
ipl_t ipl; |
int rc; |
ipl = interrupts_disable(); |
134,9 → 135,17 |
interrupts_restore(ipl); |
futex = futex_find(paddr); |
return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags | |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = waitq_sleep_timeout(&futex->wq, usec, flags | |
SYNCH_FLAGS_INTERRUPTIBLE); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
return (unative_t) rc; |
} |
/** Wakeup one thread waiting in futex wait queue. |
/branches/tracing/kernel/generic/src/syscall/syscall.c |
---|
108,11 → 108,7 |
THREAD->udebug.uspace_state = &fake_state; |
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false); |
#endif |
if (id < SYSCALL_END) { |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = syscall_table[id](a1, a2, a3, a4, a5, a6); |
} else { |
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id); |
125,10 → 121,9 |
#ifdef CONFIG_UDEBUG |
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true); |
udebug_stoppable_end(); |
THREAD->udebug.uspace_state = NULL; |
#endif |
return rc; |
} |
/branches/tracing/kernel/generic/src/ipc/sysipc.c |
---|
455,10 → 455,17 |
IPC_SET_ARG5(call.data, 0); |
if (!(res = request_preprocess(&call, phone))) { |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = ipc_call_sync(phone, &call); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
if (rc != EOK) |
return rc; |
process_answer(&call); |
} else { |
IPC_SET_RETVAL(call.data, res); |
} |
495,7 → 502,13 |
GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
if (!(res = request_preprocess(&call, phone))) { |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = ipc_call_sync(phone, &call); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
if (rc != EOK) |
return rc; |
process_answer(&call); |
798,9 → 811,17 |
{ |
call_t *call; |
restart: |
restart: |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
call = ipc_wait_for_call(&TASK->answerbox, usec, |
flags | SYNCH_FLAGS_INTERRUPTIBLE); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
if (!call) |
return 0; |
/branches/tracing/kernel/generic/src/udebug/udebug.c |
---|
35,18 → 35,6 |
* @brief Udebug hooks and data structure management. |
* |
* Udebug is an interface that makes userspace debuggers possible. |
* |
* Functions in this file are executed directly in each thread, which |
* may or may not be the subject of debugging. The udebug_stoppable_begin/end() |
* functions are also executed in the clock interrupt handler. To avoid |
* deadlock, functions in this file are protected from the interrupt |
* by locking the recursive lock THREAD->udebug.int_lock (just an atomic |
* variable). This prevents udebug_stoppable_begin/end() from being |
* executed in the interrupt handler (they are skipped). |
* |
* Functions in udebug_ops.c and udebug_ipc.c execute in different threads, |
* so they needn't be protected from the (preemptible) interrupt-initiated |
* code. |
*/ |
#include <synch/waitq.h> |
55,16 → 43,7 |
#include <errno.h> |
#include <arch.h> |
static inline void udebug_int_lock(void) |
{ |
atomic_inc(&THREAD->udebug.int_lock); |
} |
static inline void udebug_int_unlock(void) |
{ |
atomic_dec(&THREAD->udebug.int_lock); |
} |
/** Initialize udebug part of task structure. |
* |
* Called as part of task structure initialization. |
89,14 → 68,9 |
mutex_initialize(&ut->lock, MUTEX_PASSIVE); |
waitq_initialize(&ut->go_wq); |
/* |
* At the beginning the thread is stoppable, so int_lock be set, too. |
*/ |
atomic_set(&ut->int_lock, 1); |
ut->go_call = NULL; |
ut->uspace_state = NULL; |
ut->stop = true; |
ut->go = false; |
ut->stoppable = true; |
ut->debug_active = false; |
ut->cur_event = 0; /* none */ |
162,11 → 136,8 |
ASSERT(THREAD); |
ASSERT(TASK); |
udebug_int_lock(); |
/* Early check for undebugged tasks */ |
if (!udebug_thread_precheck()) { |
udebug_int_unlock(); |
return; |
} |
199,7 → 170,8 |
* Active debugging session |
*/ |
if (THREAD->udebug.debug_active && THREAD->udebug.stop) { |
if (THREAD->udebug.debug_active == true && |
THREAD->udebug.go == false) { |
/* |
* Thread was requested to stop - answer go call |
*/ |
231,7 → 203,6 |
{ |
/* Early check for undebugged tasks */ |
if (!udebug_thread_precheck()) { |
udebug_int_unlock(); |
return; |
} |
240,7 → 211,7 |
mutex_lock(&THREAD->udebug.lock); |
if (THREAD->udebug.debug_active && |
THREAD->udebug.stop == true) { |
THREAD->udebug.go == false) { |
TASK->udebug.begin_call = NULL; |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
248,7 → 219,7 |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
goto restart; |
/* must try again - have to lose stoppability atomically */ |
/* Must try again - have to lose stoppability atomically. */ |
} else { |
++TASK->udebug.not_stoppable_count; |
ASSERT(THREAD->udebug.stoppable == true); |
257,8 → 228,6 |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
} |
udebug_int_unlock(); |
} |
/** Upon being scheduled to run, check if the current thread should stop. |
273,17 → 242,7 |
ipl_t ipl; |
return; |
ASSERT(!PREEMPTION_DISABLED); |
/* |
* Prevent agains re-entering, such as when preempted inside this |
* function. |
*/ |
if (atomic_get(&THREAD->udebug.int_lock) != 0) |
return; |
udebug_int_lock(); |
ipl = interrupts_enable(); |
/* Now we're free to do whatever we need (lock mutexes, sleep, etc.) */ |
293,8 → 252,6 |
udebug_stoppable_end(); |
interrupts_restore(ipl); |
udebug_int_unlock(); |
} |
/** Syscall event hook. |
311,11 → 268,8 |
etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B; |
udebug_int_lock(); |
/* Early check for undebugged tasks */ |
if (!udebug_thread_precheck()) { |
udebug_int_unlock(); |
return; |
} |
322,9 → 276,9 |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
/* Must only generate events when in debugging session and have go */ |
/* Must only generate events when in debugging session and is go. */ |
if (THREAD->udebug.debug_active != true || |
THREAD->udebug.stop == true || |
THREAD->udebug.go == false || |
(TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
349,11 → 303,11 |
THREAD->udebug.syscall_args[5] = a6; |
/* |
* Make sure udebug.stop is true when going to sleep |
* Make sure udebug.go is false 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->udebug.stop = true; |
THREAD->udebug.go = false; |
THREAD->udebug.cur_event = etype; |
ipc_answer(&TASK->answerbox, call); |
362,8 → 316,6 |
mutex_unlock(&TASK->udebug.lock); |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
udebug_int_unlock(); |
} |
/** Thread-creation event hook. |
378,8 → 330,6 |
{ |
call_t *call; |
udebug_int_lock(); |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
388,9 → 338,9 |
/* Must only generate events when in debugging session */ |
if (THREAD->udebug.debug_active != true) { |
LOG("- debug_active: %s, udebug.stop: %s\n", |
LOG("- debug_active: %s, udebug.go: %s\n", |
THREAD->udebug.debug_active ? "yes(+)" : "no(-)", |
THREAD->udebug.stop ? "yes(-)" : "no(+)"); |
THREAD->udebug.go ? "yes(-)" : "no(+)"); |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
return; |
405,11 → 355,11 |
IPC_SET_ARG2(call->data, (unative_t)t); |
/* |
* Make sure udebug.stop is true when going to sleep |
* Make sure udebug.go is false 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->udebug.stop = true; |
THREAD->udebug.go = false; |
THREAD->udebug.cur_event = UDEBUG_EVENT_THREAD_B; |
ipc_answer(&TASK->answerbox, call); |
419,8 → 369,6 |
LOG("- sleep\n"); |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
udebug_int_unlock(); |
} |
/** Thread-termination event hook. |
432,8 → 380,6 |
{ |
call_t *call; |
udebug_int_lock(); |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
440,11 → 386,11 |
LOG("udebug_thread_e_event\n"); |
LOG("- check state\n"); |
/* Must only generate events when in debugging session */ |
/* Must only generate events when in debugging session. */ |
if (THREAD->udebug.debug_active != true) { |
/* printf("- debug_active: %s, udebug.stop: %s\n", |
/* printf("- debug_active: %s, udebug.go: %s\n", |
THREAD->udebug.debug_active ? "yes(+)" : "no(-)", |
THREAD->udebug.stop ? "yes(-)" : "no(+)");*/ |
THREAD->udebug.go ? "yes(-)" : "no(+)");*/ |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
return; |
457,10 → 403,10 |
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E); |
/* Prevent any further debug activity in thread */ |
/* Prevent any further debug activity in thread. */ |
THREAD->udebug.debug_active = false; |
THREAD->udebug.cur_event = 0; /* none */ |
THREAD->udebug.stop = true; /* set to initial value */ |
THREAD->udebug.go = false; /* set to initial value */ |
ipc_answer(&TASK->answerbox, call); |
467,8 → 413,10 |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
/* Leave int_lock enabled */ |
/* This event does not sleep - debugging has finished in this thread */ |
/* |
* This event does not sleep - debugging has finished |
* in this thread. |
*/ |
} |
static void breakpoint_trap_event(uintptr_t addr, udebug_event_t etype) |
475,17 → 423,14 |
{ |
call_t *call; |
udebug_int_lock(); |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
/* Must only generate events when in debugging session and have go */ |
/* Must only generate events when in debugging session and have go. */ |
if (THREAD->udebug.debug_active != true || |
THREAD->udebug.stop == true) { |
THREAD->udebug.go == false) { |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
udebug_int_unlock(); |
return; |
} |
493,7 → 438,6 |
if ((TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
udebug_int_unlock(); |
return; |
} |
506,11 → 450,11 |
IPC_SET_ARG2(call->data, addr); |
/* |
* Make sure udebug.stop is true when going to sleep |
* Make sure udebug.go is false 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->udebug.stop = true; |
THREAD->udebug.go = false; |
THREAD->udebug.cur_event = etype; |
printf("- send answer\n"); |
520,8 → 464,6 |
mutex_unlock(&TASK->udebug.lock); |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
udebug_int_unlock(); |
} |
void udebug_breakpoint_event(uintptr_t addr) |
554,8 → 496,6 |
LOG("udebug_task_cleanup()\n"); |
LOG("task %" PRIu64 "\n", ta->taskid); |
udebug_int_lock(); |
if (ta->udebug.dt_state != UDEBUG_TS_BEGINNING && |
ta->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
LOG("udebug_task_cleanup(): task not being debugged\n"); |
576,19 → 516,19 |
spinlock_unlock(&t->lock); |
interrupts_restore(ipl); |
/* Only process userspace threads */ |
/* Only process userspace threads. */ |
if ((flags & THREAD_FLAG_USPACE) != 0) { |
/* Prevent any further debug activity in thread */ |
/* Prevent any further debug activity in thread. */ |
t->udebug.debug_active = false; |
t->udebug.cur_event = 0; /* none */ |
/* Still has go? */ |
if (t->udebug.stop == false) { |
/* Is the thread still go? */ |
if (t->udebug.go == true) { |
/* |
* Yes, so clear go. As debug_active == false, |
* this doesn't affect anything. |
*/ |
t->udebug.stop = true; |
t->udebug.go = false; |
/* Answer GO call */ |
LOG("answer GO call with EVENT_FINISHED\n"); |
617,8 → 557,6 |
ta->udebug.dt_state = UDEBUG_TS_INACTIVE; |
ta->udebug.debugger = NULL; |
udebug_int_unlock(); |
return 0; |
} |
/branches/tracing/kernel/generic/src/udebug/udebug_ops.c |
---|
57,7 → 57,7 |
* |
* Specifically, verifies that thread t exists, is a userspace thread, |
* and belongs to the current task (TASK). Verifies, that the thread |
* has (or hasn't) go according to having_go (typically false). |
* is (or is not) go according to being_go (typically false). |
* It also locks t->udebug.lock, making sure that t->udebug.debug_active |
* is true - that the thread is in a valid debugging session. |
* |
70,11 → 70,11 |
* the t->lock spinlock to the t->udebug.lock mutex. |
* |
* @param t Pointer, need not at all be valid. |
* @param having_go Required thread state. |
* @param being_go Required thread state. |
* |
* Returns EOK if all went well, or an error code otherwise. |
*/ |
static int _thread_op_begin(thread_t *t, bool having_go) |
static int _thread_op_begin(thread_t *t, bool being_go) |
{ |
task_id_t taskid; |
ipl_t ipl; |
98,7 → 98,7 |
spinlock_lock(&t->lock); |
spinlock_unlock(&threads_lock); |
/* Verify that 't' is a userspace thread */ |
/* Verify that 't' is a userspace thread. */ |
if ((t->flags & THREAD_FLAG_USPACE) == 0) { |
/* It's not, deny its existence */ |
spinlock_unlock(&t->lock); |
107,7 → 107,7 |
return ENOENT; |
} |
/* Verify debugging state */ |
/* Verify debugging state. */ |
if (t->udebug.debug_active != true) { |
/* Not in debugging session or undesired GO state */ |
spinlock_unlock(&t->lock); |
124,9 → 124,9 |
spinlock_unlock(&t->lock); |
interrupts_restore(ipl); |
/* Only mutex TASK->udebug.lock left */ |
/* Only mutex TASK->udebug.lock left. */ |
/* Now verify that the thread belongs to the current task */ |
/* Now verify that the thread belongs to the current task. */ |
if (t->task != TASK) { |
/* No such thread belonging this task*/ |
mutex_unlock(&TASK->udebug.lock); |
139,18 → 139,18 |
*/ |
mutex_lock(&t->udebug.lock); |
/* The big task mutex is no longer needed */ |
/* The big task mutex is no longer needed. */ |
mutex_unlock(&TASK->udebug.lock); |
if (!t->udebug.stop != having_go) { |
/* Not in debugging session or undesired GO state */ |
if (t->udebug.go != being_go) { |
/* Not in debugging session or undesired GO state. */ |
mutex_unlock(&t->udebug.lock); |
return EINVAL; |
} |
/* Only t->udebug.lock left */ |
/* Only t->udebug.lock left. */ |
return EOK; /* All went well */ |
return EOK; /* All went well. */ |
} |
/** End debugging operation on a thread. */ |
204,7 → 204,7 |
reply = 0; /* no reply */ |
} |
/* Set udebug.debug_active on all of the task's userspace threads */ |
/* Set udebug.debug_active on all of the task's userspace threads. */ |
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
t = list_get_instance(cur, thread_t, th_link); |
273,7 → 273,7 |
/** Give thread GO. |
* |
* Upon recieving a go message, the thread is given GO. Having GO |
* Upon recieving a go message, the thread is given GO. Being GO |
* means the thread is allowed to execute userspace code (until |
* a debugging event or STOP occurs, at which point the thread loses GO. |
* |
284,7 → 284,7 |
{ |
int rc; |
/* On success, this will lock t->udebug.lock */ |
/* On success, this will lock t->udebug.lock. */ |
rc = _thread_op_begin(t, false); |
if (rc != EOK) { |
return rc; |
291,11 → 291,11 |
} |
t->udebug.go_call = call; |
t->udebug.stop = false; |
t->udebug.go = true; |
t->udebug.cur_event = 0; /* none */ |
/* |
* Neither t's lock nor threads_lock may be held during wakeup |
* Neither t's lock nor threads_lock may be held during wakeup. |
*/ |
waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST); |
317,7 → 317,6 |
int rc; |
LOG("udebug_stop()\n"); |
mutex_lock(&TASK->udebug.lock); |
/* |
* On success, this will lock t->udebug.lock. Note that this makes sure |
328,21 → 327,21 |
return rc; |
} |
/* Take GO away from the thread */ |
t->udebug.stop = true; |
/* Take GO away from the thread. */ |
t->udebug.go = false; |
if (!t->udebug.stoppable) { |
/* Answer will be sent when the thread becomes stoppable */ |
if (t->udebug.stoppable != true) { |
/* Answer will be sent when the thread becomes stoppable. */ |
_thread_op_end(t); |
return 0; |
} |
/* |
* Answer GO call |
* Answer GO call. |
*/ |
LOG("udebug_stop - answering go call\n"); |
/* Make sure nobody takes this call away from us */ |
/* Make sure nobody takes this call away from us. */ |
call = t->udebug.go_call; |
t->udebug.go_call = NULL; |
354,6 → 353,7 |
_thread_op_end(t); |
mutex_lock(&TASK->udebug.lock); |
ipc_answer(&TASK->answerbox, call); |
mutex_unlock(&TASK->udebug.lock); |
422,7 → 422,7 |
flags = t->flags; |
spinlock_unlock(&t->lock); |
/* Not interested in kernel threads */ |
/* Not interested in kernel threads. */ |
if ((flags & THREAD_FLAG_USPACE) != 0) { |
/* Using thread struct pointer as identification hash */ |
tid = (unative_t) t; |
458,16 → 458,16 |
int rc; |
unative_t *arg_buffer; |
/* Prepare a buffer to hold the arguments */ |
/* Prepare a buffer to hold the arguments. */ |
arg_buffer = malloc(6 * sizeof(unative_t), 0); |
/* On success, this will lock t->udebug.lock */ |
/* On success, this will lock t->udebug.lock. */ |
rc = _thread_op_begin(t, false); |
if (rc != EOK) { |
return rc; |
} |
/* Additionally we need to verify that we are inside a syscall */ |
/* Additionally we need to verify that we are inside a syscall. */ |
if (t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_B && |
t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_E) { |
_thread_op_end(t); |
474,7 → 474,7 |
return EINVAL; |
} |
/* Copy to a local buffer before releasing the lock */ |
/* Copy to a local buffer before releasing the lock. */ |
memcpy(arg_buffer, t->udebug.syscall_args, 6 * sizeof(unative_t)); |
_thread_op_end(t); |
/branches/tracing/uspace/app/trace/trace.c |
---|
445,10 → 445,20 |
thread_hash = (uintptr_t)thread_hash_arg; |
thread_id = next_thread_id++; |
printf("Start tracing thread [%d] (hash 0x%lx)\n", thread_id, thread_hash); |
printf("Start tracing thread [%d] (hash 0x%lx).\n", thread_id, thread_hash); |
while (!abort_trace) { |
if (paused) { |
printf("Press R to resume (and be patient).\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("Resumed\n"); |
} |
/* Run thread until an event occurs */ |
rc = udebug_go(phoneid, thread_hash, |
&ev_type, &val0, &val1); |
469,23 → 479,16 |
break; |
case UDEBUG_EVENT_STOP: |
printf("Stop event\n"); |
printf("Waiting for resume\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("Resumed\n"); |
break; |
case UDEBUG_EVENT_THREAD_B: |
event_thread_b(val0); |
break; |
case UDEBUG_EVENT_THREAD_E: |
printf("Thread 0x%lx exited\n", val0); |
printf("Thread 0x%lx exited.\n", val0); |
abort_trace = 1; |
break; |
default: |
printf("Unknown event type %d\n", ev_type); |
printf("Unknown event type %d.\n", ev_type); |
break; |
} |
} |
492,7 → 495,7 |
} |
printf("Finished tracing thread [%d]\n", thread_id); |
printf("Finished tracing thread [%d].\n", thread_id); |
return 0; |
} |
580,6 → 583,7 |
c = getchar(); |
if (c == 'q') break; |
if (c == 'p') { |
printf("Pause...\n"); |
paused = 1; |
rc = udebug_stop(phoneid, thash); |
printf("stop -> %d\n", rc); |
586,6 → 590,7 |
} |
if (c == 'r') { |
paused = 0; |
printf("Resume...\n"); |
} |
} |
702,7 → 707,7 |
case 'i': dm = dm | DM_IPC; break; |
case 'p': dm = dm | DM_SYSTEM | DM_USER; break; |
default: |
printf("Unexpected event type '%c'\n", *c); |
printf("Unexpected event type '%c'.\n", *c); |
exit(1); |
} |
777,6 → 782,7 |
int rc; |
printf("System Call / IPC Tracer\n"); |
printf("Controls: Q - Quit, P - Pause, R - Resume\n"); |
display_mask = DM_THREAD | DM_SYSTEM | DM_USER; |
787,11 → 793,11 |
rc = connect_task(task_id); |
if (rc < 0) { |
printf("Failed connecting to task %lld\n", task_id); |
printf("Failed connecting to task %lld.\n", task_id); |
return 1; |
} |
printf("Connected to task %lld\n", task_id); |
printf("Connected to task %lld.\n", task_id); |
if (task_ldr != NULL) { |
program_run(); |
/branches/tracing/uspace/srv/console/console.c |
---|
466,7 → 466,9 |
} |
continue; |
} |
keybuffer_pop(&conn->keybuffer, (int *) &arg1); |
int ch; |
keybuffer_pop(&conn->keybuffer, &ch); |
arg1 = ch; |
break; |
} |
ipc_answer_2(callid, EOK, arg1, arg2); |