Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2826 → Rev 2827

/branches/tracing/kernel/generic/include/proc/thread.h
210,6 → 210,7
unative_t syscall_args[6];
istate_t *uspace_state;
bool debug_stop;
bool debug_active; /**< In a debugging session */
} thread_t;
 
/** Thread list lock.
/branches/tracing/kernel/generic/src/proc/thread.c
347,6 → 347,7
t->debug_go_call = NULL;
t->uspace_state = NULL;
t->debug_stop = true;
t->debug_active = false;
 
/* might depend on previous initialization */
thread_create_arch(t);
/branches/tracing/kernel/generic/src/udebug/udebug_ipc.c
69,7 → 69,11
{
task_t *ta;
ipl_t ipl;
int rc;
 
thread_t *t;
link_t *cur;
 
klog_printf("debug_begin()");
 
ipl = interrupts_disable();
89,17 → 93,29
if (ta->not_stoppable_count == 0) {
ta->dt_state = UDEBUG_TS_ACTIVE;
ta->debug_begin_call = NULL;
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
klog_printf("debug_begin(): immediate backsend");
return 1; /* actually we need backsend with 0 retval */
rc = 1; /* actually we need backsend with 0 retval */
} else {
rc = 0; /* no backsend */
}
/* Set debug_active on all of the task's userspace threads */
 
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
 
spinlock_lock(&t->lock);
if ((t->flags & THREAD_FLAG_USPACE) != 0)
t->debug_active = true;
spinlock_unlock(&t->lock);
}
 
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
 
klog_printf("debug_begin() done (wait for stoppability)");
return 0;
klog_printf("debug_begin() done (%s)",
rc ? "backsend" : "stoppability wait");
 
return rc;
}
 
static int udebug_rp_go(call_t *call, phone_t *phone)
125,6 → 141,13
return ENOENT;
}
 
if ((t->debug_active != true) || (t->debug_stop != true)) {
/* Not in debugging session or already has GO */
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return EBUSY;
}
 
t->debug_go_call = call;
t->debug_stop = false;
waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
143,9 → 166,9
unative_t to_copy;
int rc;
ipl_t ipl;
unative_t buffer[6];
 
klog_printf("debug_args_read()");
// FIXME: verify task/thread state
 
ta = get_lock_callee_task(phone);
klog_printf("task %llu", ta->taskid);
156,21 → 179,34
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
if (!thread_exists(t)) {
/* Verify that 't' exists and belongs to task 'ta' */
if (!thread_exists(t) || (t->task != ta)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
// FIXME: copy to a local buffer before releasing the lock
//FIXME: additionally we need to verify that we are inside a syscall
if ((t->debug_active != true) || (t->debug_stop != true)) {
/* Not in debugging session or has GO */
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return EBUSY;
}
 
/* Copy to a local buffer before releasing the lock */
memcpy(buffer, t->syscall_args, 6 * sizeof(unative_t));
 
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
 
/* Now copy to userspace */
 
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);
 
rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy);
rc = copy_to_uspace(uspace_buffer, buffer, to_copy);
if (rc != 0) {
spinlock_unlock(&ta->lock);
klog_printf("debug_args_read() - copy failed");
195,19 → 231,30
ipl_t ipl;
 
klog_printf("debug_regs_read()");
// FIXME: verify task/thread state
 
ta = get_lock_callee_task(phone);
spinlock_unlock(&ta->lock);
//FIXME: don't lock ta
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
t = (thread_t *) IPC_GET_ARG2(call->data);
if (!thread_exists(t)) {
 
/* Verify that 't' exists and belongs to task 'ta' */
if (!thread_exists(t) || (t->task != ta)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
if ((t->debug_active != true) || (t->debug_stop != true)) {
/* Not in debugging session or has GO */
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return EBUSY;
}
 
state = t->uspace_state;
if (state == NULL) {
spinlock_unlock(&threads_lock);
264,10 → 311,9
return rc;
}
 
// FIXME: verify task/thread state
 
ta = get_lock_callee_task(phone);
spinlock_unlock(&ta->lock);
//FIXME: don't lock ta
 
/* Now try to change the thread's uspace_state */
 
275,12 → 321,21
spinlock_lock(&threads_lock);
 
t = (thread_t *) IPC_GET_ARG2(call->data);
if (!thread_exists(t)) {
 
/* Verify that 't' exists and belongs to task 'ta' */
if (!thread_exists(t) || (t->task != ta)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
if ((t->debug_active != true) || (t->debug_stop != true)) {
/* Not in debugging session or has GO */
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return EBUSY;
}
 
state = t->uspace_state;
if (state == NULL) {
spinlock_unlock(&threads_lock);
320,11 → 375,17
int flags;
 
klog_printf("debug_thread_read()");
// FIXME: verify task/thread state
 
ipl = interrupts_disable();
ta = get_lock_callee_task(phone);
 
/* Verify task state */
if (ta->dt_state != UDEBUG_TS_ACTIVE) {
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
return EBUSY;
}
 
/* Count the threads first */
 
num_threads = 0;
390,7 → 451,6
void *buffer;
 
klog_printf("udebug_rp_mem_write()");
// FIXME: verify task/thread state
 
uspace_data = (void *)IPC_GET_ARG2(call->data);
to_copy = IPC_GET_ARG4(call->data);
486,8 → 546,21
unsigned size;
void *buffer;
int rc;
udebug_task_state_t dts;
 
klog_printf("udebug_receive_mem_write()");
 
/* Verify task state */
spinlock_lock(&TASK->lock);
dts = TASK->dt_state;
spinlock_unlock(&TASK->lock);
 
if (dts != UDEBUG_TS_ACTIVE) {
IPC_SET_RETVAL(call->data, EBUSY);
ipc_answer(&TASK->kernel_box, call);
return;
}
uspace_dst = (void *)IPC_GET_ARG3(call->data);
size = IPC_GET_ARG4(call->data);
 
499,6 → 572,7
rc = copy_to_uspace(uspace_dst, buffer, size);
if (rc) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
return;
}