Subversion Repositories HelenOS

Rev

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