43,6 → 43,7 |
|
void udebug_task_init(udebug_task_t *ut) |
{ |
mutex_initialize(&ut->lock); |
ut->dt_state = UDEBUG_TS_INACTIVE; |
ut->begin_call = NULL; |
ut->not_stoppable_count = 0; |
71,8 → 72,7 |
ASSERT(THREAD); |
ASSERT(TASK); |
|
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
mutex_lock(&TASK->udebug.lock); |
|
nsc = --TASK->udebug.not_stoppable_count; |
|
90,15 → 90,16 |
db_call = TASK->udebug.begin_call; |
ASSERT(db_call); |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
/* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */ |
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
THREAD->debug_stoppable = true; |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
|
TASK->udebug.dt_state = UDEBUG_TS_ACTIVE; |
TASK->udebug.begin_call = NULL; |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
|
IPC_SET_RETVAL(db_call->data, 0); |
//klog_printf("udebug_stoppable_begin/ipc_answer"); |
109,7 → 110,8 |
* Active debugging session |
*/ |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
/* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */ |
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
THREAD->debug_stoppable = true; |
|
128,18 → 130,18 |
|
THREAD->cur_event = UDEBUG_EVENT_STOP; |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
|
ipc_answer(&TASK->answerbox, go_call); |
|
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
} else { |
/* |
* No stop request - nothing happens. |
*/ |
spinlock_unlock(&THREAD->debug_lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
} |
} else { |
/* |
146,13 → 148,14 |
* All other cases - nothing special happens. |
*/ |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
/* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */ |
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
THREAD->debug_stoppable = true; |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
|
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
} |
} |
|
161,10 → 164,10 |
ipl_t ipl; |
|
restart: |
mutex_lock(&TASK->udebug.lock); |
|
/* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */ |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
spinlock_lock(&THREAD->debug_lock); |
|
if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) { |
176,8 → 179,8 |
THREAD->debug_stop == true) { |
TASK->udebug.begin_call = NULL; |
spinlock_unlock(&THREAD->debug_lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
|
udebug_wait_for_go(&THREAD->go_wq); |
|
188,8 → 191,8 |
THREAD->debug_stoppable = false; |
|
spinlock_unlock(&THREAD->debug_lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
} |
} |
|
211,7 → 214,7 |
THREAD->debug_in_before_thread_runs = true; |
ipl = interrupts_enable(); |
|
/* Now we're free to do whatever we need (lock mutexes, etc.) */ |
/* Now we're free to do whatever we need (lock mutexes, sleep, etc.) */ |
|
/* Check if we're supposed to stop */ |
udebug_stoppable_begin(); |
231,6 → 234,8 |
|
etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B; |
|
mutex_lock(&TASK->udebug.lock); |
|
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
|
240,11 → 245,14 |
(TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return; |
} |
|
//klog_printf("udebug_syscall_event"); |
call = THREAD->debug_go_call; |
THREAD->debug_go_call = NULL; |
|
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, etype); |
IPC_SET_ARG2(call->data, id); |
267,12 → 275,12 |
|
THREAD->cur_event = etype; |
spinlock_unlock(&THREAD->debug_lock); |
|
spinlock_lock(&TASK->lock); |
ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
|
ipc_answer(&TASK->answerbox, call); |
|
mutex_unlock(&TASK->udebug.lock); |
|
udebug_wait_for_go(&THREAD->go_wq); |
} |
|
281,6 → 289,8 |
call_t *call; |
ipl_t ipl; |
|
mutex_lock(&TASK->udebug.lock); |
|
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
|
294,6 → 304,7 |
THREAD->debug_stop ? "yes(-)" : "no(+)"); |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return; |
} |
|
300,6 → 311,7 |
klog_printf("- trigger event"); |
|
call = THREAD->debug_go_call; |
THREAD->debug_go_call = NULL; |
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_B); |
IPC_SET_ARG2(call->data, (unative_t)t); |
313,12 → 325,12 |
|
THREAD->cur_event = UDEBUG_EVENT_THREAD_B; |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
|
spinlock_lock(&TASK->lock); |
ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
spinlock_unlock(&TASK->lock); |
ipc_answer(&TASK->answerbox, call); |
|
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
|
klog_printf("- sleep"); |
udebug_wait_for_go(&THREAD->go_wq); |
} |
328,6 → 340,8 |
call_t *call; |
ipl_t ipl; |
|
mutex_lock(&TASK->udebug.lock); |
|
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
|
341,6 → 355,7 |
THREAD->debug_stop ? "yes(-)" : "no(+)"); |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return; |
} |
|
347,6 → 362,7 |
klog_printf("- trigger event"); |
|
call = THREAD->debug_go_call; |
THREAD->debug_go_call = NULL; |
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E); |
|
354,13 → 370,13 |
THREAD->debug_active = false; |
THREAD->cur_event = 0; /* none */ |
THREAD->debug_stop = true; /* set to initial value */ |
|
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
|
spinlock_lock(&TASK->lock); |
ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
spinlock_unlock(&TASK->lock); |
ipc_answer(&TASK->answerbox, call); |
|
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
|
/* This event does not sleep - debugging has finished in this thread */ |
} |
370,6 → 386,8 |
call_t *call; |
ipl_t ipl; |
|
mutex_lock(&TASK->udebug.lock); |
|
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->debug_lock); |
|
379,11 → 397,14 |
(TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return; |
} |
|
klog_printf("udebug_breakpoint/trap_event"); |
call = THREAD->debug_go_call; |
THREAD->debug_go_call = NULL; |
|
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, etype); |
IPC_SET_ARG2(call->data, addr); |
397,12 → 418,11 |
|
THREAD->cur_event = etype; |
spinlock_unlock(&THREAD->debug_lock); |
interrupts_restore(ipl); |
klog_printf("- send answer"); |
|
spinlock_lock(&TASK->lock); |
ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
ipc_answer(&TASK->answerbox, call); |
mutex_unlock(&TASK->udebug.lock); |
|
udebug_wait_for_go(&THREAD->go_wq); |
} |
420,7 → 440,7 |
/** |
* Terminate task debugging session. |
* |
* \param ta Must be already locked and interrupts must be disabled. |
* \param ta->udebug.lock must be already locked. |
* \return Zero on success or negative error code. |
*/ |
int udebug_task_cleanup(struct task *ta) |
428,6 → 448,7 |
thread_t *t; |
link_t *cur; |
int flags; |
ipl_t ipl; |
|
klog_printf("udebug_task_cleanup()"); |
klog_printf("task %llu", ta->taskid); |
442,6 → 463,7 |
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
t = list_get_instance(cur, thread_t, th_link); |
|
ipl = interrupts_disable(); |
spinlock_lock(&t->debug_lock); |
spinlock_lock(&t->lock); |
|
467,7 → 489,9 |
klog_printf("answer GO call with EVENT_FINISHED"); |
IPC_SET_RETVAL(t->debug_go_call->data, 0); |
IPC_SET_ARG1(t->debug_go_call->data, UDEBUG_EVENT_FINISHED); |
/* FIXME: must not call with interrupts disabled!!*/ |
ipc_answer(&ta->answerbox, t->debug_go_call); |
t->debug_go_call = NULL; |
} else { |
/* |
* Debug_stop is already at initial value. |
482,6 → 506,7 |
} |
} |
spinlock_unlock(&t->debug_lock); |
interrupts_restore(ipl); |
} |
|
ta->udebug.dt_state = UDEBUG_TS_INACTIVE; |