17,17 → 17,50 |
#include <udebug/udebug.h> |
#include <udebug/udebug_ipc.h> |
|
/** |
* Get and lock a phone's callee task. |
* |
* This will return a pointer to the task to which the phone |
* is connected. It will lock the task, making sure it exists. |
* (TODO: make sure the udebug-cleanup of the task hasn't |
* started yet) |
*/ |
static task_t *get_lock_callee_task(phone_t *phone) |
{ |
answerbox_t *answerbox; |
answerbox_t *box; |
task_t *ta; |
task_id_t taskid; |
ipl_t ipl; |
|
// FIXME: locking!!! |
ipl = interrupts_disable(); |
spinlock_lock(&phone->lock); |
if (phone->state != IPC_PHONE_CONNECTED) { |
spinlock_unlock(&phone->lock); |
interrupts_restore(ipl); |
return NULL; |
} |
|
answerbox = phone->callee; |
ta = answerbox->task; |
box = phone->callee; |
|
spinlock_lock(&box->lock); |
ta = box->task; |
taskid = ta->taskid; |
spinlock_unlock(&box->lock); |
spinlock_unlock(&phone->lock); |
|
/* Locking decoupled using taskid */ |
|
spinlock_lock(&tasks_lock); |
ta = task_find_by_id(taskid); |
if (ta == NULL) { |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
return NULL; |
} |
|
spinlock_lock(&ta->lock); |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
|
return ta; |
} |
35,14 → 68,17 |
static int udebug_rp_begin(call_t *call, phone_t *phone) |
{ |
task_t *ta; |
ipl_t ipl; |
|
klog_printf("debug_begin()"); |
|
ipl = interrupts_disable(); |
ta = get_lock_callee_task(phone); |
klog_printf("debugging task %llu", ta->taskid); |
|
if (ta->being_debugged != false) { |
spinlock_unlock(&ta->lock); |
interrupts_restore(ipl); |
klog_printf("debug_begin(): busy error"); |
return EBUSY; |
} |
55,11 → 91,13 |
ta->debug_begin_call = NULL; |
ta->stop_request = false; |
spinlock_unlock(&ta->lock); |
interrupts_restore(ipl); |
klog_printf("debug_begin(): immediate backsend"); |
return 1; /* actually we need backsend with 0 retval */ |
} |
|
spinlock_unlock(&ta->lock); |
interrupts_restore(ipl); |
|
klog_printf("debug_begin() done (wait for stoppability)"); |
return 0; |
69,6 → 107,7 |
{ |
thread_t *t; |
task_t *ta; |
ipl_t ipl; |
|
klog_printf("debug_go()"); |
ta = get_lock_callee_task(phone); |
75,17 → 114,22 |
|
// FIXME: must save this in thread struct, not task struct!!! |
ta->debug_go_call = call; |
spinlock_unlock(&ta->lock); |
|
t = (thread_t *) IPC_GET_ARG2(call->data); |
|
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
if (!thread_exists(t)) { |
spinlock_unlock(&ta->lock); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
|
klog_printf("debug_go(): waitq_wakeup"); |
waitq_wakeup(&t->go_wq, WAKEUP_FIRST); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
|
spinlock_unlock(&ta->lock); |
|
return 0; /* no backsend */ |
} |
|
96,6 → 140,7 |
void *uspace_buffer; |
unative_t to_copy; |
int rc; |
ipl_t ipl; |
|
klog_printf("debug_args_read()"); |
// FIXME: verify task/thread state |
102,12 → 147,23 |
|
ta = get_lock_callee_task(phone); |
klog_printf("task %llu", ta->taskid); |
spinlock_unlock(&ta->lock); |
|
t = (thread_t *) IPC_GET_ARG2(call->data); |
|
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
|
if (!thread_exists(t)) { |
spinlock_unlock(&ta->lock); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
|
// FIXME: copy to a local buffer before releasing the lock |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
|
uspace_buffer = (void *)IPC_GET_ARG3(call->data); |
to_copy = IPC_GET_ARG4(call->data); |
if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t); |
119,8 → 175,6 |
return rc; |
} |
|
spinlock_unlock(&ta->lock); |
|
IPC_SET_ARG1(call->data, to_copy); |
|
klog_printf("debug_args_read() done"); |