Subversion Repositories HelenOS

Rev

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

Rev 2897 Rev 2898
Line 50... Line 50...
50
 *
50
 *
51
 * Simply put, return thread t with t->debug_lock held,
51
 * Simply put, return thread t with t->debug_lock held,
52
 * but only if it verifies all conditions.
52
 * but only if it verifies all conditions.
53
 *
53
 *
54
 * Specifically, verifies that thread t exists, is a userspace thread,
54
 * Specifically, verifies that thread t exists, is a userspace thread,
55
 * and belongs to the current task (TASK). It also locks t->debug_lock,
55
 * and belongs to the current task (TASK). Verifies, that the thread
-
 
56
 * has (or hasn't) go according to having_go (typically false).
56
 * making sure that t->debug_active is true - that the thread is
57
 * It also locks t->debug_lock, making sure that t->debug_active is true
57
 * in a valid debugging session.
58
 * - that the thread is in a valid debugging session.
58
 *
59
 *
59
 * Returns EOK if all went well, or an error code otherwise.
60
 * Returns EOK if all went well, or an error code otherwise.
60
 * Interrupts must be already disabled when calling this function.
61
 * Interrupts must be already disabled when calling this function.
61
 *
62
 *
62
 * Note: This function sports complicated locking.
63
 * Note: This function sports complicated locking.
63
 */
64
 */
64
static int _thread_op_begin(thread_t *t)
65
static int _thread_op_begin(thread_t *t, bool having_go)
65
{
66
{
66
    int rc;
67
    int rc;
67
    task_id_t taskid;
68
    task_id_t taskid;
68
 
69
 
69
    taskid = TASK->taskid;
70
    taskid = TASK->taskid;
Line 91... Line 92...
91
        /* It's not, deny its existence */
92
        /* It's not, deny its existence */
92
        rc = ENOENT;
93
        rc = ENOENT;
93
        goto error_exit;
94
        goto error_exit;
94
    }
95
    }
95
 
96
 
96
    if ((t->debug_active != true) || (t->debug_stop != true)) {
97
    if ((t->debug_active != true) || (!t->debug_stop != having_go)) {
97
        /* Not in debugging session or already has GO */
98
        /* Not in debugging session or undesired GO state */
98
        rc = ENOENT;
99
        rc = EINVAL;
99
        goto error_exit;
100
        goto error_exit;
100
    }
101
    }
101
 
102
 
102
    spinlock_unlock(&threads_lock);
103
    spinlock_unlock(&threads_lock);
103
    spinlock_unlock(&t->lock);
104
    spinlock_unlock(&t->lock);
Line 211... Line 212...
211
    klog_printf("udebug_go()");
212
    klog_printf("udebug_go()");
212
 
213
 
213
    ipl = interrupts_disable();
214
    ipl = interrupts_disable();
214
 
215
 
215
    /* On success, this will lock t->debug_lock */
216
    /* On success, this will lock t->debug_lock */
216
    rc = _thread_op_begin(t);
217
    rc = _thread_op_begin(t, false);
217
    if (rc != EOK) {
218
    if (rc != EOK) {
218
        interrupts_restore(ipl);
219
        interrupts_restore(ipl);
219
        return rc;
220
        return rc;
220
    }
221
    }
221
 
222
 
Line 232... Line 233...
232
    interrupts_restore(ipl);
233
    interrupts_restore(ipl);
233
 
234
 
234
    return 0;
235
    return 0;
235
}
236
}
236
 
237
 
-
 
238
int udebug_stop(thread_t *t, call_t *call)
-
 
239
{
-
 
240
    ipl_t ipl;
-
 
241
    int rc;
-
 
242
 
-
 
243
    klog_printf("udebug_stop()");
-
 
244
 
-
 
245
    ipl = interrupts_disable();
-
 
246
 
-
 
247
    /*
-
 
248
     * On success, this will lock t->debug_lock. Note that this makes sure
-
 
249
     * the thread is not stopped.
-
 
250
     */
-
 
251
    rc = _thread_op_begin(t, true);
-
 
252
    if (rc != EOK) {
-
 
253
        interrupts_restore(ipl);
-
 
254
        return rc;
-
 
255
    }
-
 
256
 
-
 
257
    /* Take GO away from the thread */
-
 
258
    t->debug_stop = true;
-
 
259
 
-
 
260
    if (!t->debug_stoppable) {
-
 
261
        /* Answer will be sent when the thread becomes stoppable */
-
 
262
        _thread_op_end(t);
-
 
263
        interrupts_restore(ipl);
-
 
264
        return 0;
-
 
265
    }
-
 
266
 
-
 
267
    /*
-
 
268
     * Answer GO call
-
 
269
     */
-
 
270
    klog_printf("udebug_stop - answering go call");
-
 
271
 
-
 
272
    /* Make sure nobody takes this call away from us */
-
 
273
    call = t->debug_go_call;
-
 
274
    t->debug_go_call = NULL;
-
 
275
 
-
 
276
    IPC_SET_RETVAL(call->data, 0);
-
 
277
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
-
 
278
    klog_printf("udebug_stop/ipc_answer");
-
 
279
 
-
 
280
    THREAD->cur_event = UDEBUG_EVENT_STOP;
-
 
281
    _thread_op_end(t);
-
 
282
 
-
 
283
    spinlock_lock(&TASK->lock);
-
 
284
    ipc_answer(&TASK->answerbox, call);
-
 
285
    spinlock_unlock(&TASK->lock);
-
 
286
 
-
 
287
    interrupts_restore(ipl);
-
 
288
    klog_printf("udebog_stop/done");
-
 
289
    return 0;
-
 
290
}
237
 
291
 
238
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
292
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
239
{
293
{
240
    thread_t *t;
294
    thread_t *t;
241
    link_t *cur;
295
    link_t *cur;
Line 308... Line 362...
308
    if (!arg_buffer) return ENOMEM;
362
    if (!arg_buffer) return ENOMEM;
309
 
363
 
310
    ipl = interrupts_disable();
364
    ipl = interrupts_disable();
311
 
365
 
312
    /* On success, this will lock t->debug_lock */
366
    /* On success, this will lock t->debug_lock */
313
    rc = _thread_op_begin(t);
367
    rc = _thread_op_begin(t, false);
314
    if (rc != EOK) {
368
    if (rc != EOK) {
315
        interrupts_restore(ipl);
369
        interrupts_restore(ipl);
316
        return rc;
370
        return rc;
317
    }
371
    }
318
 
372
 
Line 348... Line 402...
348
    if (!regs_buffer) return ENOMEM;
402
    if (!regs_buffer) return ENOMEM;
349
 
403
 
350
    ipl = interrupts_disable();
404
    ipl = interrupts_disable();
351
 
405
 
352
    /* On success, this will lock t->debug_lock */
406
    /* On success, this will lock t->debug_lock */
353
    rc = _thread_op_begin(t);
407
    rc = _thread_op_begin(t, false);
354
    if (rc != EOK) {
408
    if (rc != EOK) {
355
        interrupts_restore(ipl);
409
        interrupts_restore(ipl);
356
        return rc;
410
        return rc;
357
    }
411
    }
358
 
412
 
Line 387... Line 441...
387
    /* Try to change the thread's uspace_state */
441
    /* Try to change the thread's uspace_state */
388
 
442
 
389
    ipl = interrupts_disable();
443
    ipl = interrupts_disable();
390
 
444
 
391
    /* On success, this will lock t->debug_lock */
445
    /* On success, this will lock t->debug_lock */
392
    rc = _thread_op_begin(t);
446
    rc = _thread_op_begin(t, false);
393
    if (rc != EOK) {
447
    if (rc != EOK) {
394
        interrupts_restore(ipl);
448
        interrupts_restore(ipl);
395
        return rc;
449
        return rc;
396
    }
450
    }
397
 
451