Rev 2921 | Rev 3015 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2921 | Rev 3014 | ||
|---|---|---|---|
| Line 39... | Line 39... | ||
| 39 | #include <console/klog.h> |
39 | #include <console/klog.h> |
| 40 | #include <udebug/udebug.h> |
40 | #include <udebug/udebug.h> |
| 41 | #include <errno.h> |
41 | #include <errno.h> |
| 42 | #include <arch.h> |
42 | #include <arch.h> |
| 43 | 43 | ||
| - | 44 | void udebug_task_init(udebug_task_t *ut) |
|
| - | 45 | { |
|
| - | 46 | ut->dt_state = UDEBUG_TS_INACTIVE; |
|
| - | 47 | ut->begin_call = NULL; |
|
| - | 48 | ut->not_stoppable_count = 0; |
|
| - | 49 | ut->evmask = 0; |
|
| - | 50 | } |
|
| - | 51 | ||
| 44 | static void udebug_wait_for_go(waitq_t *wq) |
52 | static void udebug_wait_for_go(waitq_t *wq) |
| 45 | { |
53 | { |
| 46 | int rc; |
54 | int rc; |
| 47 | ipl_t ipl; |
55 | ipl_t ipl; |
| 48 | 56 | ||
| Line 64... | Line 72... | ||
| 64 | ASSERT(TASK); |
72 | ASSERT(TASK); |
| 65 | 73 | ||
| 66 | ipl = interrupts_disable(); |
74 | ipl = interrupts_disable(); |
| 67 | spinlock_lock(&TASK->lock); |
75 | spinlock_lock(&TASK->lock); |
| 68 | 76 | ||
| 69 | nsc = --TASK->not_stoppable_count; |
77 | nsc = --TASK->udebug.not_stoppable_count; |
| 70 | 78 | ||
| 71 | if (TASK->dt_state == UDEBUG_TS_BEGINNING) { |
79 | if (TASK->udebug.dt_state == UDEBUG_TS_BEGINNING) { |
| 72 | klog_printf("udebug_stoppable_begin"); |
80 | klog_printf("udebug_stoppable_begin"); |
| 73 | klog_printf(" - nsc := %d", nsc); |
81 | klog_printf(" - nsc := %d", nsc); |
| 74 | } |
82 | } |
| 75 | 83 | ||
| 76 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
84 | if (TASK->udebug.dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
| 77 | /* |
85 | /* |
| 78 | * This was the last non-stoppable thread. Reply to |
86 | * This was the last non-stoppable thread. Reply to |
| 79 | * DEBUG_BEGIN call. |
87 | * DEBUG_BEGIN call. |
| 80 | */ |
88 | */ |
| 81 | 89 | ||
| 82 | db_call = TASK->debug_begin_call; |
90 | db_call = TASK->udebug.begin_call; |
| 83 | ASSERT(db_call); |
91 | ASSERT(db_call); |
| 84 | 92 | ||
| 85 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
93 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
| 86 | spinlock_lock(&THREAD->debug_lock); |
94 | spinlock_lock(&THREAD->debug_lock); |
| 87 | THREAD->debug_stoppable = true; |
95 | THREAD->debug_stoppable = true; |
| 88 | spinlock_unlock(&THREAD->debug_lock); |
96 | spinlock_unlock(&THREAD->debug_lock); |
| 89 | 97 | ||
| 90 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
98 | TASK->udebug.dt_state = UDEBUG_TS_ACTIVE; |
| 91 | TASK->debug_begin_call = NULL; |
99 | TASK->udebug.begin_call = NULL; |
| 92 | spinlock_unlock(&TASK->lock); |
100 | spinlock_unlock(&TASK->lock); |
| 93 | interrupts_restore(ipl); |
101 | interrupts_restore(ipl); |
| 94 | 102 | ||
| 95 | IPC_SET_RETVAL(db_call->data, 0); |
103 | IPC_SET_RETVAL(db_call->data, 0); |
| 96 | //klog_printf("udebug_stoppable_begin/ipc_answer"); |
104 | //klog_printf("udebug_stoppable_begin/ipc_answer"); |
| 97 | ipc_answer(&TASK->answerbox, db_call); |
105 | ipc_answer(&TASK->answerbox, db_call); |
| 98 | 106 | ||
| 99 | } else if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
107 | } else if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) { |
| 100 | /* |
108 | /* |
| 101 | * Active debugging session |
109 | * Active debugging session |
| 102 | */ |
110 | */ |
| 103 | 111 | ||
| 104 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
112 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
| Line 157... | Line 165... | ||
| 157 | spinlock_lock(&TASK->lock); |
165 | spinlock_lock(&TASK->lock); |
| 158 | 166 | ||
| 159 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
167 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
| 160 | spinlock_lock(&THREAD->debug_lock); |
168 | spinlock_lock(&THREAD->debug_lock); |
| 161 | 169 | ||
| 162 | if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
170 | if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) { |
| 163 | //klog_printf("udebug_stoppable_end"); |
171 | //klog_printf("udebug_stoppable_end"); |
| 164 | //klog_printf("debug_stop=%d", THREAD->debug_stop); |
172 | //klog_printf("debug_stop=%d", THREAD->debug_stop); |
| 165 | } |
173 | } |
| 166 | 174 | ||
| 167 | if (THREAD->debug_active && |
175 | if (THREAD->debug_active && |
| 168 | THREAD->debug_stop == true) { |
176 | THREAD->debug_stop == true) { |
| 169 | TASK->debug_begin_call = NULL; |
177 | TASK->udebug.begin_call = NULL; |
| 170 | spinlock_unlock(&THREAD->debug_lock); |
178 | spinlock_unlock(&THREAD->debug_lock); |
| 171 | spinlock_unlock(&TASK->lock); |
179 | spinlock_unlock(&TASK->lock); |
| 172 | interrupts_restore(ipl); |
180 | interrupts_restore(ipl); |
| 173 | 181 | ||
| 174 | udebug_wait_for_go(&THREAD->go_wq); |
182 | udebug_wait_for_go(&THREAD->go_wq); |
| 175 | 183 | ||
| 176 | goto restart; |
184 | goto restart; |
| 177 | /* must try again - have to lose stoppability atomically */ |
185 | /* must try again - have to lose stoppability atomically */ |
| 178 | } else { |
186 | } else { |
| 179 | ++TASK->not_stoppable_count; |
187 | ++TASK->udebug.not_stoppable_count; |
| 180 | THREAD->debug_stoppable = false; |
188 | THREAD->debug_stoppable = false; |
| 181 | 189 | ||
| 182 | spinlock_unlock(&THREAD->debug_lock); |
190 | spinlock_unlock(&THREAD->debug_lock); |
| 183 | spinlock_unlock(&TASK->lock); |
191 | spinlock_unlock(&TASK->lock); |
| 184 | interrupts_restore(ipl); |
192 | interrupts_restore(ipl); |
| Line 199... | Line 207... | ||
| 199 | spinlock_lock(&THREAD->debug_lock); |
207 | spinlock_lock(&THREAD->debug_lock); |
| 200 | 208 | ||
| 201 | /* Must only generate events when in debugging session and have go */ |
209 | /* Must only generate events when in debugging session and have go */ |
| 202 | if (THREAD->debug_active != true || |
210 | if (THREAD->debug_active != true || |
| 203 | THREAD->debug_stop == true || |
211 | THREAD->debug_stop == true || |
| 204 | (TASK->debug_evmask & UDEBUG_EVMASK(etype)) == 0) { |
212 | (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
| 205 | spinlock_unlock(&THREAD->debug_lock); |
213 | spinlock_unlock(&THREAD->debug_lock); |
| 206 | interrupts_restore(ipl); |
214 | interrupts_restore(ipl); |
| 207 | return; |
215 | return; |
| 208 | } |
216 | } |
| 209 | 217 | ||
| Line 338... | Line 346... | ||
| 338 | spinlock_lock(&THREAD->debug_lock); |
346 | spinlock_lock(&THREAD->debug_lock); |
| 339 | 347 | ||
| 340 | /* Must only generate events when in debugging session and have go */ |
348 | /* Must only generate events when in debugging session and have go */ |
| 341 | if (THREAD->debug_active != true || |
349 | if (THREAD->debug_active != true || |
| 342 | THREAD->debug_stop == true || |
350 | THREAD->debug_stop == true || |
| 343 | (TASK->debug_evmask & UDEBUG_EVMASK(etype)) == 0) { |
351 | (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
| 344 | spinlock_unlock(&THREAD->debug_lock); |
352 | spinlock_unlock(&THREAD->debug_lock); |
| 345 | interrupts_restore(ipl); |
353 | interrupts_restore(ipl); |
| 346 | return; |
354 | return; |
| 347 | } |
355 | } |
| 348 | 356 | ||
| Line 394... | Line 402... | ||
| 394 | int flags; |
402 | int flags; |
| 395 | 403 | ||
| 396 | klog_printf("udebug_task_cleanup()"); |
404 | klog_printf("udebug_task_cleanup()"); |
| 397 | klog_printf("task %llu", ta->taskid); |
405 | klog_printf("task %llu", ta->taskid); |
| 398 | 406 | ||
| 399 | if (ta->dt_state == UDEBUG_TS_BEGINNING && |
407 | if (ta->udebug.dt_state == UDEBUG_TS_BEGINNING && |
| 400 | ta->dt_state != UDEBUG_TS_ACTIVE) { |
408 | ta->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
| 401 | klog_printf("udebug_task_cleanup(): task not being debugged"); |
409 | klog_printf("udebug_task_cleanup(): task not being debugged"); |
| 402 | return EINVAL; |
410 | return EINVAL; |
| 403 | } |
411 | } |
| 404 | 412 | ||
| 405 | /* Finish debugging of all userspace threads */ |
413 | /* Finish debugging of all userspace threads */ |
| Line 446... | Line 454... | ||
| 446 | } |
454 | } |
| 447 | } |
455 | } |
| 448 | spinlock_unlock(&t->debug_lock); |
456 | spinlock_unlock(&t->debug_lock); |
| 449 | } |
457 | } |
| 450 | 458 | ||
| 451 | ta->dt_state = UDEBUG_TS_INACTIVE; |
459 | ta->udebug.dt_state = UDEBUG_TS_INACTIVE; |
| 452 | ta->debugger = NULL; |
460 | ta->udebug.debugger = NULL; |
| 453 | 461 | ||
| 454 | return 0; |
462 | return 0; |
| 455 | } |
463 | } |
| 456 | 464 | ||
| 457 | 465 | ||