Subversion Repositories HelenOS

Rev

Rev 3016 | Rev 3026 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3016 Rev 3018
Line 48... Line 48...
48
    ut->begin_call = NULL;
48
    ut->begin_call = NULL;
49
    ut->not_stoppable_count = 0;
49
    ut->not_stoppable_count = 0;
50
    ut->evmask = 0;
50
    ut->evmask = 0;
51
}
51
}
52
 
52
 
-
 
53
void udebug_thread_initialize(udebug_thread_t *ut)
-
 
54
{
-
 
55
    waitq_initialize(&ut->go_wq);
-
 
56
    ut->go_call = NULL;
-
 
57
    ut->uspace_state = NULL;
-
 
58
    ut->stop = true;
-
 
59
    ut->stoppable = true;
-
 
60
    ut->debug_active = false;
-
 
61
    ut->cur_event = 0; /* none */
-
 
62
}
-
 
63
 
53
static void udebug_wait_for_go(waitq_t *wq)
64
static void udebug_wait_for_go(waitq_t *wq)
54
{
65
{
55
    int rc;
66
    int rc;
56
    ipl_t ipl;
67
    ipl_t ipl;
57
 
68
 
Line 88... Line 99...
88
         */
99
         */
89
 
100
 
90
        db_call = TASK->udebug.begin_call;
101
        db_call = TASK->udebug.begin_call;
91
        ASSERT(db_call);
102
        ASSERT(db_call);
92
 
103
 
93
        /* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */
104
        /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */
94
        ipl = interrupts_disable();
105
        ipl = interrupts_disable();
95
        spinlock_lock(&THREAD->debug_lock);
106
        spinlock_lock(&THREAD->udebug.lock);
96
        THREAD->debug_stoppable = true;
107
        THREAD->udebug.stoppable = true;
97
        spinlock_unlock(&THREAD->debug_lock);
108
        spinlock_unlock(&THREAD->udebug.lock);
98
        interrupts_restore(ipl);
109
        interrupts_restore(ipl);
99
 
110
 
100
        TASK->udebug.dt_state = UDEBUG_TS_ACTIVE;
111
        TASK->udebug.dt_state = UDEBUG_TS_ACTIVE;
101
        TASK->udebug.begin_call = NULL;
112
        TASK->udebug.begin_call = NULL;
102
        mutex_unlock(&TASK->udebug.lock);
113
        mutex_unlock(&TASK->udebug.lock);
Line 108... Line 119...
108
    } else if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) {
119
    } else if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) {
109
        /*
120
        /*
110
         * Active debugging session
121
         * Active debugging session
111
         */
122
         */
112
 
123
 
113
        /* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */
124
        /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */
114
        ipl = interrupts_disable();
125
        ipl = interrupts_disable();
115
        spinlock_lock(&THREAD->debug_lock);
126
        spinlock_lock(&THREAD->udebug.lock);
116
        THREAD->debug_stoppable = true;
127
        THREAD->udebug.stoppable = true;
117
 
128
 
118
        if (THREAD->debug_active && THREAD->debug_stop) {
129
        if (THREAD->udebug.debug_active && THREAD->udebug.stop) {
119
            /*
130
            /*
120
             * Thread was requested to stop - answer go call
131
             * Thread was requested to stop - answer go call
121
             */
132
             */
122
 
133
 
123
            /* Make sure nobody takes this call away from us */
134
            /* Make sure nobody takes this call away from us */
124
            go_call = THREAD->debug_go_call;
135
            go_call = THREAD->udebug.go_call;
125
            THREAD->debug_go_call = NULL;
136
            THREAD->udebug.go_call = NULL;
126
            ASSERT(go_call);
137
            ASSERT(go_call);
127
 
138
 
128
            IPC_SET_RETVAL(go_call->data, 0);
139
            IPC_SET_RETVAL(go_call->data, 0);
129
            IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP);
140
            IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP);
130
 
141
 
131
            THREAD->cur_event = UDEBUG_EVENT_STOP;
142
            THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
132
            spinlock_unlock(&THREAD->debug_lock);
143
            spinlock_unlock(&THREAD->udebug.lock);
133
            interrupts_restore(ipl);
144
            interrupts_restore(ipl);
134
 
145
 
135
                ipc_answer(&TASK->answerbox, go_call);
146
                ipc_answer(&TASK->answerbox, go_call);
136
 
147
 
137
                mutex_unlock(&TASK->udebug.lock);
148
                mutex_unlock(&TASK->udebug.lock);
138
        } else {
149
        } else {
139
            /*
150
            /*
140
             * No stop request - nothing happens.
151
             * No stop request - nothing happens.
141
             */
152
             */
142
            spinlock_unlock(&THREAD->debug_lock);
153
            spinlock_unlock(&THREAD->udebug.lock);
143
            interrupts_restore(ipl);
154
            interrupts_restore(ipl);
144
                mutex_unlock(&TASK->udebug.lock);
155
                mutex_unlock(&TASK->udebug.lock);
145
        }
156
        }
146
    } else {
157
    } else {
147
        /*
158
        /*
148
         * All other cases - nothing special happens.
159
         * All other cases - nothing special happens.
149
         */
160
         */
150
 
161
 
151
        /* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */
162
        /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */
152
        ipl = interrupts_disable();
163
        ipl = interrupts_disable();
153
        spinlock_lock(&THREAD->debug_lock);
164
        spinlock_lock(&THREAD->udebug.lock);
154
        THREAD->debug_stoppable = true;
165
        THREAD->udebug.stoppable = true;
155
        spinlock_unlock(&THREAD->debug_lock);
166
        spinlock_unlock(&THREAD->udebug.lock);
156
        interrupts_restore(ipl);
167
        interrupts_restore(ipl);
157
 
168
 
158
            mutex_unlock(&TASK->udebug.lock);
169
            mutex_unlock(&TASK->udebug.lock);
159
    }
170
    }
160
}
171
}
Line 164... Line 175...
164
    ipl_t ipl;
175
    ipl_t ipl;
165
 
176
 
166
restart:
177
restart:
167
    mutex_lock(&TASK->udebug.lock);
178
    mutex_lock(&TASK->udebug.lock);
168
 
179
 
169
    /* Lock order OK, THREAD->debug_lock is after TASK->udebug.lock */
180
    /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */
170
    ipl = interrupts_disable();
181
    ipl = interrupts_disable();
171
    spinlock_lock(&THREAD->debug_lock);
182
    spinlock_lock(&THREAD->udebug.lock);
172
 
183
 
173
    if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) {
184
    if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) {
174
        //klog_printf("udebug_stoppable_end");
185
        //klog_printf("udebug_stoppable_end");
175
        //klog_printf("debug_stop=%d", THREAD->debug_stop);
186
        //klog_printf("udebug.stop=%d", THREAD->udebug.stop);
176
    }
187
    }
177
 
188
 
178
    if (THREAD->debug_active &&
189
    if (THREAD->udebug.debug_active &&
179
        THREAD->debug_stop == true) {
190
        THREAD->udebug.stop == true) {
180
        TASK->udebug.begin_call = NULL;
191
        TASK->udebug.begin_call = NULL;
181
        spinlock_unlock(&THREAD->debug_lock);
192
        spinlock_unlock(&THREAD->udebug.lock);
182
        interrupts_restore(ipl);
193
        interrupts_restore(ipl);
183
        mutex_unlock(&TASK->udebug.lock);
194
        mutex_unlock(&TASK->udebug.lock);
184
 
195
 
185
        udebug_wait_for_go(&THREAD->go_wq);
196
        udebug_wait_for_go(&THREAD->udebug.go_wq);
186
 
197
 
187
        goto restart;
198
        goto restart;
188
        /* must try again - have to lose stoppability atomically */
199
        /* must try again - have to lose stoppability atomically */
189
    } else {
200
    } else {
190
        ++TASK->udebug.not_stoppable_count;
201
        ++TASK->udebug.not_stoppable_count;
191
        THREAD->debug_stoppable = false;
202
        THREAD->udebug.stoppable = false;
192
 
203
 
193
        spinlock_unlock(&THREAD->debug_lock);
204
        spinlock_unlock(&THREAD->udebug.lock);
194
        interrupts_restore(ipl);
205
        interrupts_restore(ipl);
195
        mutex_unlock(&TASK->udebug.lock);
206
        mutex_unlock(&TASK->udebug.lock);
196
    }
207
    }
197
}
208
}
198
 
209
 
Line 206... Line 217...
206
void udebug_before_thread_runs(void)
217
void udebug_before_thread_runs(void)
207
{
218
{
208
    ipl_t ipl;
219
    ipl_t ipl;
209
 
220
 
210
    /* This will happen if we get preempted inside this function. */
221
    /* This will happen if we get preempted inside this function. */
211
    if (THREAD->debug_in_before_thread_runs)
222
    if (THREAD->udebug.in_before_thread_runs)
212
        return;
223
        return;
213
 
224
 
214
    THREAD->debug_in_before_thread_runs = true;
225
    THREAD->udebug.in_before_thread_runs = true;
215
    ipl = interrupts_enable();
226
    ipl = interrupts_enable();
216
 
227
 
217
    /* Now we're free to do whatever we need (lock mutexes, sleep, etc.) */
228
    /* Now we're free to do whatever we need (lock mutexes, sleep, etc.) */
218
 
229
 
219
    /* Check if we're supposed to stop */
230
    /* Check if we're supposed to stop */
220
    udebug_stoppable_begin();
231
    udebug_stoppable_begin();
221
    udebug_stoppable_end();
232
    udebug_stoppable_end();
222
 
233
 
223
    interrupts_restore(ipl);
234
    interrupts_restore(ipl);
224
    THREAD->debug_in_before_thread_runs = false;
235
    THREAD->udebug.in_before_thread_runs = false;
225
}
236
}
226
 
237
 
227
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3,
238
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3,
228
    unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc,
239
    unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc,
229
    bool end_variant)
240
    bool end_variant)
Line 235... Line 246...
235
    etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B;
246
    etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B;
236
 
247
 
237
    mutex_lock(&TASK->udebug.lock);
248
    mutex_lock(&TASK->udebug.lock);
238
 
249
 
239
    ipl = interrupts_disable();
250
    ipl = interrupts_disable();
240
    spinlock_lock(&THREAD->debug_lock);
251
    spinlock_lock(&THREAD->udebug.lock);
241
 
252
 
242
    /* Must only generate events when in debugging session and have go */
253
    /* Must only generate events when in debugging session and have go */
243
    if (THREAD->debug_active != true ||
254
    if (THREAD->udebug.debug_active != true ||
244
        THREAD->debug_stop == true ||
255
        THREAD->udebug.stop == true ||
245
        (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
256
        (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
246
        spinlock_unlock(&THREAD->debug_lock);
257
        spinlock_unlock(&THREAD->udebug.lock);
247
        interrupts_restore(ipl);
258
        interrupts_restore(ipl);
248
        mutex_unlock(&TASK->udebug.lock);
259
        mutex_unlock(&TASK->udebug.lock);
249
        return;
260
        return;
250
    }
261
    }
251
 
262
 
252
    //klog_printf("udebug_syscall_event");
263
    //klog_printf("udebug_syscall_event");
253
    call = THREAD->debug_go_call;
264
    call = THREAD->udebug.go_call;
254
    THREAD->debug_go_call = NULL;
265
    THREAD->udebug.go_call = NULL;
255
 
266
 
256
    IPC_SET_RETVAL(call->data, 0);
267
    IPC_SET_RETVAL(call->data, 0);
257
    IPC_SET_ARG1(call->data, etype);
268
    IPC_SET_ARG1(call->data, etype);
258
    IPC_SET_ARG2(call->data, id);
269
    IPC_SET_ARG2(call->data, id);
259
    IPC_SET_ARG3(call->data, rc);
270
    IPC_SET_ARG3(call->data, rc);
260
    //klog_printf("udebug_syscall_event/ipc_answer");
271
    //klog_printf("udebug_syscall_event/ipc_answer");
261
 
272
 
262
    THREAD->syscall_args[0] = a1;
273
    THREAD->udebug.syscall_args[0] = a1;
263
    THREAD->syscall_args[1] = a2;
274
    THREAD->udebug.syscall_args[1] = a2;
264
    THREAD->syscall_args[2] = a3;
275
    THREAD->udebug.syscall_args[2] = a3;
265
    THREAD->syscall_args[3] = a4;
276
    THREAD->udebug.syscall_args[3] = a4;
266
    THREAD->syscall_args[4] = a5;
277
    THREAD->udebug.syscall_args[4] = a5;
267
    THREAD->syscall_args[5] = a6;
278
    THREAD->udebug.syscall_args[5] = a6;
268
 
279
 
269
    /*
280
    /*
270
     * Make sure debug_stop is true when going to sleep
281
     * Make sure udebug.stop is true when going to sleep
271
     * in case we get woken up by DEBUG_END. (At which
282
     * in case we get woken up by DEBUG_END. (At which
272
     * point it must be back to the initial true value).
283
     * point it must be back to the initial true value).
273
     */
284
     */
274
    THREAD->debug_stop = true;
285
    THREAD->udebug.stop = true;
275
 
286
 
276
    THREAD->cur_event = etype;
287
    THREAD->udebug.cur_event = etype;
277
    spinlock_unlock(&THREAD->debug_lock);
288
    spinlock_unlock(&THREAD->udebug.lock);
278
    interrupts_restore(ipl);
289
    interrupts_restore(ipl);
279
 
290
 
280
    ipc_answer(&TASK->answerbox, call);
291
    ipc_answer(&TASK->answerbox, call);
281
 
292
 
282
    mutex_unlock(&TASK->udebug.lock);
293
    mutex_unlock(&TASK->udebug.lock);
283
 
294
 
284
    udebug_wait_for_go(&THREAD->go_wq);
295
    udebug_wait_for_go(&THREAD->udebug.go_wq);
285
}
296
}
286
 
297
 
287
void udebug_thread_b_event(struct thread *t)
298
void udebug_thread_b_event(struct thread *t)
288
{
299
{
289
    call_t *call;
300
    call_t *call;
290
    ipl_t ipl;
301
    ipl_t ipl;
291
 
302
 
292
    mutex_lock(&TASK->udebug.lock);
303
    mutex_lock(&TASK->udebug.lock);
293
 
304
 
294
    ipl = interrupts_disable();
305
    ipl = interrupts_disable();
295
    spinlock_lock(&THREAD->debug_lock);
306
    spinlock_lock(&THREAD->udebug.lock);
296
 
307
 
297
    klog_printf("udebug_thread_b_event");
308
    klog_printf("udebug_thread_b_event");
298
    klog_printf("- check state");
309
    klog_printf("- check state");
299
 
310
 
300
    /* Must only generate events when in debugging session */
311
    /* Must only generate events when in debugging session */
301
    if (THREAD->debug_active != true) {
312
    if (THREAD->udebug.debug_active != true) {
302
        klog_printf("- debug_active: %s, debug_stop: %s",
313
        klog_printf("- debug_active: %s, udebug.stop: %s",
303
            THREAD->debug_active ? "yes(+)" : "no(-)",
314
            THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
304
            THREAD->debug_stop ? "yes(-)" : "no(+)");
315
            THREAD->udebug.stop ? "yes(-)" : "no(+)");
305
        spinlock_unlock(&THREAD->debug_lock);
316
        spinlock_unlock(&THREAD->udebug.lock);
306
        interrupts_restore(ipl);
317
        interrupts_restore(ipl);
307
        mutex_unlock(&TASK->udebug.lock);
318
        mutex_unlock(&TASK->udebug.lock);
308
        return;
319
        return;
309
    }
320
    }
310
 
321
 
311
    klog_printf("- trigger event");
322
    klog_printf("- trigger event");
312
 
323
 
313
    call = THREAD->debug_go_call;
324
    call = THREAD->udebug.go_call;
314
    THREAD->debug_go_call = NULL;
325
    THREAD->udebug.go_call = NULL;
315
    IPC_SET_RETVAL(call->data, 0);
326
    IPC_SET_RETVAL(call->data, 0);
316
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_B);
327
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_B);
317
    IPC_SET_ARG2(call->data, (unative_t)t);
328
    IPC_SET_ARG2(call->data, (unative_t)t);
318
 
329
 
319
    /*
330
    /*
320
     * Make sure debug_stop is true when going to sleep
331
     * Make sure udebug.stop is true when going to sleep
321
     * in case we get woken up by DEBUG_END. (At which
332
     * in case we get woken up by DEBUG_END. (At which
322
     * point it must be back to the initial true value).
333
     * point it must be back to the initial true value).
323
     */
334
     */
324
    THREAD->debug_stop = true;
335
    THREAD->udebug.stop = true;
325
 
336
 
326
    THREAD->cur_event = UDEBUG_EVENT_THREAD_B;
337
    THREAD->udebug.cur_event = UDEBUG_EVENT_THREAD_B;
327
    spinlock_unlock(&THREAD->debug_lock);
338
    spinlock_unlock(&THREAD->udebug.lock);
328
    interrupts_restore(ipl);
339
    interrupts_restore(ipl);
329
 
340
 
330
    ipc_answer(&TASK->answerbox, call);
341
    ipc_answer(&TASK->answerbox, call);
331
 
342
 
332
    mutex_unlock(&TASK->udebug.lock);
343
    mutex_unlock(&TASK->udebug.lock);
333
 
344
 
334
    klog_printf("- sleep");
345
    klog_printf("- sleep");
335
    udebug_wait_for_go(&THREAD->go_wq);
346
    udebug_wait_for_go(&THREAD->udebug.go_wq);
336
}
347
}
337
 
348
 
338
void udebug_thread_e_event(void)
349
void udebug_thread_e_event(void)
339
{
350
{
340
    call_t *call;
351
    call_t *call;
341
    ipl_t ipl;
352
    ipl_t ipl;
342
 
353
 
343
    mutex_lock(&TASK->udebug.lock);
354
    mutex_lock(&TASK->udebug.lock);
344
 
355
 
345
    ipl = interrupts_disable();
356
    ipl = interrupts_disable();
346
    spinlock_lock(&THREAD->debug_lock);
357
    spinlock_lock(&THREAD->udebug.lock);
347
 
358
 
348
    klog_printf("udebug_thread_e_event");
359
    klog_printf("udebug_thread_e_event");
349
    klog_printf("- check state");
360
    klog_printf("- check state");
350
 
361
 
351
    /* Must only generate events when in debugging session */
362
    /* Must only generate events when in debugging session */
352
    if (THREAD->debug_active != true) {
363
    if (THREAD->udebug.debug_active != true) {
353
        klog_printf("- debug_active: %s, debug_stop: %s",
364
        klog_printf("- debug_active: %s, udebug.stop: %s",
354
            THREAD->debug_active ? "yes(+)" : "no(-)",
365
            THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
355
            THREAD->debug_stop ? "yes(-)" : "no(+)");
366
            THREAD->udebug.stop ? "yes(-)" : "no(+)");
356
        spinlock_unlock(&THREAD->debug_lock);
367
        spinlock_unlock(&THREAD->udebug.lock);
357
        interrupts_restore(ipl);
368
        interrupts_restore(ipl);
358
        mutex_unlock(&TASK->udebug.lock);
369
        mutex_unlock(&TASK->udebug.lock);
359
        return;
370
        return;
360
    }
371
    }
361
 
372
 
362
    klog_printf("- trigger event");
373
    klog_printf("- trigger event");
363
 
374
 
364
    call = THREAD->debug_go_call;
375
    call = THREAD->udebug.go_call;
365
    THREAD->debug_go_call = NULL;
376
    THREAD->udebug.go_call = NULL;
366
    IPC_SET_RETVAL(call->data, 0);
377
    IPC_SET_RETVAL(call->data, 0);
367
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
378
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
368
 
379
 
369
    /* Prevent any further debug activity in thread */
380
    /* Prevent any further debug activity in thread */
370
    THREAD->debug_active = false;
381
    THREAD->udebug.debug_active = false;
371
    THREAD->cur_event = 0;      /* none */
382
    THREAD->udebug.cur_event = 0;       /* none */
372
    THREAD->debug_stop = true;  /* set to initial value */
383
    THREAD->udebug.stop = true; /* set to initial value */
373
 
384
 
374
    spinlock_unlock(&THREAD->debug_lock);
385
    spinlock_unlock(&THREAD->udebug.lock);
375
    interrupts_restore(ipl);
386
    interrupts_restore(ipl);
376
 
387
 
377
    ipc_answer(&TASK->answerbox, call);
388
    ipc_answer(&TASK->answerbox, call);
378
 
389
 
379
    mutex_unlock(&TASK->udebug.lock);
390
    mutex_unlock(&TASK->udebug.lock);
Line 387... Line 398...
387
    ipl_t ipl;
398
    ipl_t ipl;
388
 
399
 
389
    mutex_lock(&TASK->udebug.lock);
400
    mutex_lock(&TASK->udebug.lock);
390
 
401
 
391
    ipl = interrupts_disable();
402
    ipl = interrupts_disable();
392
    spinlock_lock(&THREAD->debug_lock);
403
    spinlock_lock(&THREAD->udebug.lock);
393
 
404
 
394
    /* Must only generate events when in debugging session and have go */
405
    /* Must only generate events when in debugging session and have go */
395
    if (THREAD->debug_active != true ||
406
    if (THREAD->udebug.debug_active != true ||
396
        THREAD->debug_stop == true ||
407
        THREAD->udebug.stop == true ||
397
        (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
408
        (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
398
        spinlock_unlock(&THREAD->debug_lock);
409
        spinlock_unlock(&THREAD->udebug.lock);
399
        interrupts_restore(ipl);
410
        interrupts_restore(ipl);
400
        mutex_unlock(&TASK->udebug.lock);
411
        mutex_unlock(&TASK->udebug.lock);
401
        return;
412
        return;
402
    }
413
    }
403
 
414
 
404
    klog_printf("udebug_breakpoint/trap_event");
415
    klog_printf("udebug_breakpoint/trap_event");
405
    call = THREAD->debug_go_call;
416
    call = THREAD->udebug.go_call;
406
    THREAD->debug_go_call = NULL;
417
    THREAD->udebug.go_call = NULL;
407
 
418
 
408
    IPC_SET_RETVAL(call->data, 0);
419
    IPC_SET_RETVAL(call->data, 0);
409
    IPC_SET_ARG1(call->data, etype);
420
    IPC_SET_ARG1(call->data, etype);
410
    IPC_SET_ARG2(call->data, addr);
421
    IPC_SET_ARG2(call->data, addr);
411
 
422
 
412
    /*
423
    /*
413
     * Make sure debug_stop is true when going to sleep
424
     * Make sure udebug.stop is true when going to sleep
414
     * in case we get woken up by DEBUG_END. (At which
425
     * in case we get woken up by DEBUG_END. (At which
415
     * point it must be back to the initial true value).
426
     * point it must be back to the initial true value).
416
     */
427
     */
417
    THREAD->debug_stop = true;
428
    THREAD->udebug.stop = true;
418
 
429
 
419
    THREAD->cur_event = etype;
430
    THREAD->udebug.cur_event = etype;
420
    spinlock_unlock(&THREAD->debug_lock);
431
    spinlock_unlock(&THREAD->udebug.lock);
421
    interrupts_restore(ipl);
432
    interrupts_restore(ipl);
422
    klog_printf("- send answer");
433
    klog_printf("- send answer");
423
 
434
 
424
    ipc_answer(&TASK->answerbox, call);
435
    ipc_answer(&TASK->answerbox, call);
425
    mutex_unlock(&TASK->udebug.lock);
436
    mutex_unlock(&TASK->udebug.lock);
426
 
437
 
427
    udebug_wait_for_go(&THREAD->go_wq);
438
    udebug_wait_for_go(&THREAD->udebug.go_wq);
428
}
439
}
429
 
440
 
430
void udebug_breakpoint_event(uintptr_t addr)
441
void udebug_breakpoint_event(uintptr_t addr)
431
{
442
{
432
    breakpoint_trap_event(addr, UDEBUG_EVENT_BREAKPOINT);
443
    breakpoint_trap_event(addr, UDEBUG_EVENT_BREAKPOINT);
Line 462... Line 473...
462
    /* Finish debugging of all userspace threads */
473
    /* Finish debugging of all userspace threads */
463
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
474
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
464
        t = list_get_instance(cur, thread_t, th_link);
475
        t = list_get_instance(cur, thread_t, th_link);
465
 
476
 
466
        ipl = interrupts_disable();
477
        ipl = interrupts_disable();
467
        spinlock_lock(&t->debug_lock);
478
        spinlock_lock(&t->udebug.lock);
468
        spinlock_lock(&t->lock);
479
        spinlock_lock(&t->lock);
469
 
480
 
470
        flags = t->flags;
481
        flags = t->flags;
471
 
482
 
472
        spinlock_unlock(&t->lock);
483
        spinlock_unlock(&t->lock);
473
 
484
 
474
        /* Only process userspace threads */
485
        /* Only process userspace threads */
475
        if ((flags & THREAD_FLAG_USPACE) != 0) {
486
        if ((flags & THREAD_FLAG_USPACE) != 0) {
476
            /* Prevent any further debug activity in thread */
487
            /* Prevent any further debug activity in thread */
477
            t->debug_active = false;
488
            t->udebug.debug_active = false;
478
            t->cur_event = 0;   /* none */
489
            t->udebug.cur_event = 0;    /* none */
479
 
490
 
480
            /* Still has go? */
491
            /* Still has go? */
481
            if (t->debug_stop == false) {
492
            if (t->udebug.stop == false) {
482
                /*
493
                /*
483
                * Yes, so clear go. As debug_active == false,
494
                * Yes, so clear go. As debug_active == false,
484
                 * this doesn't affect anything.
495
                 * this doesn't affect anything.
485
                 */
496
                 */
486
                t->debug_stop = true;  
497
                t->udebug.stop = true; 
487
 
498
 
488
                /* Answer GO call */
499
                /* Answer GO call */
489
                klog_printf("answer GO call with EVENT_FINISHED");
500
                klog_printf("answer GO call with EVENT_FINISHED");
490
                IPC_SET_RETVAL(t->debug_go_call->data, 0);
501
                IPC_SET_RETVAL(t->udebug.go_call->data, 0);
491
                IPC_SET_ARG1(t->debug_go_call->data, UDEBUG_EVENT_FINISHED);
502
                IPC_SET_ARG1(t->udebug.go_call->data, UDEBUG_EVENT_FINISHED);
492
                /* FIXME: must not call with interrupts disabled!!*/
503
                /* FIXME: must not call with interrupts disabled!!*/
493
                ipc_answer(&ta->answerbox, t->debug_go_call);
504
                ipc_answer(&ta->answerbox, t->udebug.go_call);
494
                t->debug_go_call = NULL;
505
                t->udebug.go_call = NULL;
495
            } else {
506
            } else {
496
                /*
507
                /*
497
                 * Debug_stop is already at initial value.
508
                 * Debug_stop is already at initial value.
498
                 * Yet this means the thread needs waking up.
509
                 * Yet this means the thread needs waking up.
499
                 */
510
                 */
500
 
511
 
501
                /*
512
                /*
502
                 * t's lock must not be held when calling
513
                 * t's lock must not be held when calling
503
                 * waitq_wakeup.
514
                 * waitq_wakeup.
504
                 */
515
                 */
505
                waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
516
                waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
506
            }
517
            }
507
        }
518
        }
508
        spinlock_unlock(&t->debug_lock);
519
        spinlock_unlock(&t->udebug.lock);
509
        interrupts_restore(ipl);
520
        interrupts_restore(ipl);
510
    }
521
    }
511
 
522
 
512
    ta->udebug.dt_state = UDEBUG_TS_INACTIVE;
523
    ta->udebug.dt_state = UDEBUG_TS_INACTIVE;
513
    ta->udebug.debugger = NULL;
524
    ta->udebug.debugger = NULL;