Subversion Repositories HelenOS

Rev

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

Rev 3448 Rev 3474
Line 31... Line 31...
31
 */
31
 */
32
 
32
 
33
/**
33
/**
34
 * @file
34
 * @file
35
 * @brief   Udebug operations.
35
 * @brief   Udebug operations.
-
 
36
 *
-
 
37
 * Udebug operations on tasks and threads are implemented here. The
-
 
38
 * functions defined here are called from the udebug_ipc module
-
 
39
 * when servicing udebug IPC messages.
36
 */
40
 */
37
 
41
 
38
#include <debug.h>
42
#include <debug.h>
39
#include <proc/task.h>
43
#include <proc/task.h>
40
#include <proc/thread.h>
44
#include <proc/thread.h>
Line 63... Line 67...
63
 *
67
 *
64
 * In this function, holding the TASK->udebug.lock mutex prevents the
68
 * In this function, holding the TASK->udebug.lock mutex prevents the
65
 * thread from leaving the debugging session, while relaxing from
69
 * thread from leaving the debugging session, while relaxing from
66
 * the t->lock spinlock to the t->udebug.lock mutex.
70
 * the t->lock spinlock to the t->udebug.lock mutex.
67
 *
71
 *
-
 
72
 * @param t     Pointer, need not at all be valid.
-
 
73
 * @param having_go Required thread state.
-
 
74
 *
68
 * Returns EOK if all went well, or an error code otherwise.
75
 * Returns EOK if all went well, or an error code otherwise.
69
 */
76
 */
70
static int _thread_op_begin(thread_t *t, bool having_go)
77
static int _thread_op_begin(thread_t *t, bool having_go)
71
{
78
{
72
    task_id_t taskid;
79
    task_id_t taskid;
Line 144... Line 151...
144
    /* Only t->udebug.lock left */
151
    /* Only t->udebug.lock left */
145
 
152
 
146
    return EOK; /* All went well */
153
    return EOK; /* All went well */
147
}
154
}
148
 
155
 
149
 
-
 
-
 
156
/** End debugging operation on a thread. */
150
static void _thread_op_end(thread_t *t)
157
static void _thread_op_end(thread_t *t)
151
{
158
{
152
    mutex_unlock(&t->udebug.lock);
159
    mutex_unlock(&t->udebug.lock);
153
}
160
}
154
 
161
 
-
 
162
/** Begin debugging the current task.
155
/**
163
 *
-
 
164
 * Initiates a debugging session for the current task (and its threads).
-
 
165
 * When the debugging session has started a reply will be sent to the
-
 
166
 * UDEBUG_BEGIN call. This may happen immediately in this function if
-
 
167
 * all the threads in this task are stoppable at the moment and in this
-
 
168
 * case the function returns 1.
-
 
169
 *
-
 
170
 * Otherwise the function returns 0 and the reply will be sent as soon as
-
 
171
 * all the threads become stoppable (i.e. they can be considered stopped).
-
 
172
 *
-
 
173
 * @param call  The BEGIN call we are servicing.
156
 * \return 0 (ok, but not done yet), 1 (done) or negative error code.
174
 * @return  0 (OK, but not done yet), 1 (done) or negative error code.
157
 */
175
 */
158
int udebug_begin(call_t *call)
176
int udebug_begin(call_t *call)
159
{
177
{
160
    int reply;
178
    int reply;
161
 
179
 
Line 203... Line 221...
203
        reply ? "reply" : "stoppability wait");
221
        reply ? "reply" : "stoppability wait");
204
 
222
 
205
    return reply;
223
    return reply;
206
}
224
}
207
 
225
 
-
 
226
/** Finish debugging the current task.
-
 
227
 *
-
 
228
 * Closes the debugging session for the current task.
-
 
229
 * @return Zero on success or negative error code.
-
 
230
 */
208
int udebug_end(void)
231
int udebug_end(void)
209
{
232
{
210
    int rc;
233
    int rc;
211
 
234
 
212
    LOG("udebug_end()\n");
235
    LOG("udebug_end()\n");
Line 219... Line 242...
219
    mutex_unlock(&TASK->udebug.lock);
242
    mutex_unlock(&TASK->udebug.lock);
220
 
243
 
221
    return rc;
244
    return rc;
222
}
245
}
223
 
246
 
-
 
247
/** Set the event mask.
-
 
248
 *
-
 
249
 * Sets the event mask that determines which events are enabled.
-
 
250
 *
-
 
251
 * @param mask  Or combination of events that should be enabled.
-
 
252
 * @return  Zero on success or negative error code.
-
 
253
 */
224
int udebug_set_evmask(udebug_evmask_t mask)
254
int udebug_set_evmask(udebug_evmask_t mask)
225
{
255
{
226
    LOG("udebug_set_mask()\n");
256
    LOG("udebug_set_mask()\n");
227
 
257
 
228
    mutex_lock(&TASK->udebug.lock);
258
    mutex_lock(&TASK->udebug.lock);
Line 239... Line 269...
239
    mutex_unlock(&TASK->udebug.lock);
269
    mutex_unlock(&TASK->udebug.lock);
240
 
270
 
241
    return 0;
271
    return 0;
242
}
272
}
243
 
273
 
-
 
274
/** Give thread GO.
-
 
275
 *
-
 
276
 * Upon recieving a go message, the thread is given GO. Having GO
-
 
277
 * means the thread is allowed to execute userspace code (until
-
 
278
 * a debugging event or STOP occurs, at which point the thread loses GO.
244
 
279
 *
-
 
280
 * @param t The thread to operate on (unlocked and need not be valid).
-
 
281
 * @param call  The GO call that we are servicing.
-
 
282
 */
245
int udebug_go(thread_t *t, call_t *call)
283
int udebug_go(thread_t *t, call_t *call)
246
{
284
{
247
    int rc;
285
    int rc;
248
 
286
 
249
    /* On success, this will lock t->udebug.lock */
287
    /* On success, this will lock t->udebug.lock */
Line 264... Line 302...
264
    _thread_op_end(t);
302
    _thread_op_end(t);
265
 
303
 
266
    return 0;
304
    return 0;
267
}
305
}
268
 
306
 
-
 
307
/** Stop a thread (i.e. take its GO away)
-
 
308
 *
-
 
309
 * Generates a STOP event as soon as the thread becomes stoppable (i.e.
-
 
310
 * can be considered stopped).
-
 
311
 *
-
 
312
 * @param t The thread to operate on (unlocked and need not be valid).
-
 
313
 * @param call  The GO call that we are servicing.
-
 
314
 */
269
int udebug_stop(thread_t *t, call_t *call)
315
int udebug_stop(thread_t *t, call_t *call)
270
{
316
{
271
    int rc;
317
    int rc;
272
 
318
 
273
    LOG("udebug_stop()\n");
319
    LOG("udebug_stop()\n");
Line 313... Line 359...
313
 
359
 
314
    LOG("udebog_stop/done\n");
360
    LOG("udebog_stop/done\n");
315
    return 0;
361
    return 0;
316
}
362
}
317
 
363
 
-
 
364
/** Read the list of userspace threads in the current task.
-
 
365
 *
-
 
366
 * The list takes the form of a sequence of thread hashes (i.e. the pointers
-
 
367
 * to thread structures). A buffer of size @a buf_size is allocated and
-
 
368
 * a pointer to it written to @a buffer. The sequence of hashes is written
-
 
369
 * into this buffer.
-
 
370
 *
-
 
371
 * If the sequence is longer than @a buf_size bytes, only as much hashes
-
 
372
 * as can fit are copied. The number of thread hashes copied is stored
-
 
373
 * in @a n.
-
 
374
 *
-
 
375
 * The rationale for having @a buf_size is that this function is only
-
 
376
 * used for servicing the THREAD_READ message, which always specifies
-
 
377
 * a maximum size for the userspace buffer.
-
 
378
 *
-
 
379
 * @param buffer    The buffer for storing thread hashes.
-
 
380
 * @param buf_size  Buffer size in bytes.
-
 
381
 * @param n     The actual number of hashes copied will be stored here.
-
 
382
 */
318
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
383
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
319
{
384
{
320
    thread_t *t;
385
    thread_t *t;
321
    link_t *cur;
386
    link_t *cur;
322
    unative_t tid;
387
    unative_t tid;
Line 374... Line 439...
374
    *n = copied_ids * sizeof(unative_t);
439
    *n = copied_ids * sizeof(unative_t);
375
 
440
 
376
    return 0;
441
    return 0;
377
}
442
}
378
 
443
 
-
 
444
/** Read the arguments of a system call.
-
 
445
 *
-
 
446
 * The arguments of the system call being being executed are copied
-
 
447
 * to an allocated buffer and a pointer to it is written to @a buffer.
-
 
448
 * The size of the buffer is exactly such that it can hold the maximum number
-
 
449
 * of system-call arguments.
-
 
450
 *
-
 
451
 * Unless the thread is currently blocked in a SYSCALL_B or SYSCALL_E event,
-
 
452
 * this function will fail with an EINVAL error code.
-
 
453
 *
-
 
454
 * @param buffer    The buffer for storing thread hashes.
-
 
455
 */
379
int udebug_args_read(thread_t *t, void **buffer)
456
int udebug_args_read(thread_t *t, void **buffer)
380
{
457
{
381
    int rc;
458
    int rc;
382
    unative_t *arg_buffer;
459
    unative_t *arg_buffer;
383
 
460
 
Line 404... Line 481...
404
 
481
 
405
    *buffer = arg_buffer;
482
    *buffer = arg_buffer;
406
    return 0;
483
    return 0;
407
}
484
}
408
 
485
 
-
 
486
/** Read the memory of the debugged task.
-
 
487
 *
-
 
488
 * Reads @a n bytes from the address space of the debugged task, starting
-
 
489
 * from @a uspace_addr. The bytes are copied into an allocated buffer
-
 
490
 * and a pointer to it is written into @a buffer.
-
 
491
 *
-
 
492
 * @param uspace_addr   Address from where to start reading.
-
 
493
 * @param n     Number of bytes to read.
-
 
494
 * @param buffer    For storing a pointer to the allocated buffer.
-
 
495
 */
409
int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer)
496
int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer)
410
{
497
{
411
    void *data_buffer;
498
    void *data_buffer;
412
    int rc;
499
    int rc;
413
 
500