Subversion Repositories HelenOS

Rev

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

Rev 2935 Rev 2936
Line 42... Line 42...
42
#include <udebug.h>
42
#include <udebug.h>
43
#include <async.h>
43
#include <async.h>
44
#include <string.h>
44
#include <string.h>
45
 
45
 
46
#include "cmd.h"
46
#include "cmd.h"
-
 
47
#include "cons.h"
47
#include "include/arch.h"
48
#include "include/arch.h"
48
#include "fib_synch.h"
49
#include "fib_synch.h"
49
#include "main.h"
50
#include "main.h"
50
 
51
 
51
void thread_debug_start(unsigned thread_hash);
52
void thread_debug_start(unsigned thread_hash);
52
 
53
 
53
#define INBUF_SIZE 64
54
#define IN_BUF_SIZE 64
54
char in_buf[INBUF_SIZE];
55
static char in_buf[IN_BUF_SIZE];
55
 
56
 
56
#define MAX_ARGC 10
57
#define MAX_ARGC 10
57
int cmd_argc;
58
int cmd_argc;
58
char *cmd_argv[MAX_ARGC + 1];   /* need one spare field for cmd_split() */
59
char *cmd_argv[MAX_ARGC + 1];   /* need one spare field for cmd_split() */
59
 
60
 
Line 72... Line 73...
72
breakpoint_t brk_list[MAX_BRKPTS];
73
breakpoint_t brk_list[MAX_BRKPTS];
73
int lifted_brkpt;
74
int lifted_brkpt;
74
 
75
 
75
fcv_t go_cv;
76
fcv_t go_cv;
76
 
77
 
77
void read_line(char *buffer, int n)
-
 
78
{
-
 
79
    char c;
-
 
80
    int i;
-
 
81
 
-
 
82
    i = 0;
-
 
83
    while (i < n - 1) {
-
 
84
        c = getchar();
-
 
85
        if (c == '\n') break;
-
 
86
        if (c == '\b') {
-
 
87
            if (i > 0) {
-
 
88
                putchar('\b');
-
 
89
                --i;
-
 
90
            }
-
 
91
            continue;
-
 
92
        }
-
 
93
       
-
 
94
        putchar(c);
-
 
95
        buffer[i++] = c;
-
 
96
    }
-
 
97
 
-
 
98
    putchar('\n');
-
 
99
    buffer[i] = '\0';
-
 
100
}
-
 
101
 
-
 
102
void command_split(char *cmd_str)
78
void command_split(char *cmd_str)
103
{
79
{
104
    char *p = cmd_str;
80
    char *p = cmd_str;
105
 
81
 
106
    if (*p == '\0') {
82
    if (*p == '\0') {
Line 148... Line 124...
148
 
124
 
149
        --cmp_len;
125
        --cmp_len;
150
    }
126
    }
151
 
127
 
152
    if (num_found == 0) {
128
    if (num_found == 0) {
153
        printf("Unknown command. Try one of:\n");
129
        cons_printf("Unknown command. Try one of:\n");
154
        cmd_help(0, NULL);
130
        cmd_help(0, NULL);
155
        return;
131
        return;
156
    }
132
    }
157
 
133
 
158
    if (cmd_argc - 1 != cmd_table[idx_found].argc) {
134
    if (cmd_argc - 1 != cmd_table[idx_found].argc) {
159
        printf("Command '%s' expects %d arguments\n",
135
        cons_printf("Command '%s' expects %d arguments\n",
160
        cmd_table[idx_found].name, cmd_table[idx_found].argc);
136
        cmd_table[idx_found].name, cmd_table[idx_found].argc);
161
        return;
137
        return;
162
    }
138
    }
163
 
139
 
164
    (*cmd_table[idx_found].proc)(cmd_argc, cmd_argv);
140
    (*cmd_table[idx_found].proc)(cmd_argc, cmd_argv);
165
}
141
}
166
 
142
 
-
 
143
void thread_stop(void)
-
 
144
{
-
 
145
    cons_printf("[t] stopped\n");
-
 
146
    fcv_wait(&go_cv);
-
 
147
    cons_printf("[t] go\n");
-
 
148
}
-
 
149
 
167
/*
150
/*
168
 * Called by a fibril (from arch code) when a breakpoint is hit.
151
 * Called by a fibril (from arch code) when a breakpoint is hit.
169
 */
152
 */
170
void breakpoint_hit(void)
153
void breakpoint_hit(void)
171
{
154
{
-
 
155
    cons_printf("breakpoint hit\n");
172
    fcv_wait(&go_cv);
156
    thread_stop();
173
}
157
}
174
 
158
 
175
int task_connect(int taskid)
159
int task_connect(int taskid)
176
{
160
{
177
    int rc;
161
    int rc;
178
    unsigned evmask;
162
    unsigned evmask;
179
 
163
 
180
    printf("ipc_connect_kbox(%d)... ", taskid);
164
    cons_printf("ipc_connect_kbox(%d)... ", taskid);
181
    rc = ipc_connect_kbox(taskid);
165
    rc = ipc_connect_kbox(taskid);
182
    printf("-> %d\n", rc);
166
    cons_printf("-> %d\n", rc);
183
    app_phone = rc;
167
    app_phone = rc;
184
    if (rc < 0) return rc;
168
    if (rc < 0) return rc;
185
 
169
 
186
    printf("udebug_begin()... ");
170
    cons_printf("udebug_begin()... ");
187
    rc = udebug_begin(app_phone);
171
    rc = udebug_begin(app_phone);
188
    printf("-> %d\n", rc);
172
    cons_printf("-> %d\n", rc);
189
    if (rc < 0) return rc;
173
    if (rc < 0) return rc;
190
 
174
 
191
    evmask = UDEBUG_EM_ALL & ~(UDEBUG_EM_SYSCALL_B | UDEBUG_EM_SYSCALL_E);
175
    evmask = UDEBUG_EM_ALL & ~(UDEBUG_EM_SYSCALL_B | UDEBUG_EM_SYSCALL_E);
192
    printf("udebug_set_evmask(0x%x)... ", evmask);
176
    cons_printf("udebug_set_evmask(0x%x)... ", evmask);
193
    rc = udebug_set_evmask(app_phone, evmask);
177
    rc = udebug_set_evmask(app_phone, evmask);
194
    printf("-> %d\n", rc);
178
    cons_printf("-> %d\n", rc);
195
    if (rc < 0) return rc;
179
    if (rc < 0) return rc;
196
 
180
 
197
    return 0;
181
    return 0;
198
}
182
}
199
 
183
 
Line 202... Line 186...
202
    int rc;
186
    int rc;
203
    int tb_copied;
187
    int tb_copied;
204
    int tb_needed;
188
    int tb_needed;
205
    int i;
189
    int i;
206
 
190
 
207
    printf("send IPC_M_DEBUG_THREAD_READ message\n");
191
    cons_printf("send IPC_M_DEBUG_THREAD_READ message\n");
208
    rc = udebug_thread_read(app_phone, (unsigned)thread_hash_buf,
192
    rc = udebug_thread_read(app_phone, (unsigned)thread_hash_buf,
209
        THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
193
        THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
210
    printf("-> %d\n", rc);
194
    cons_printf("-> %d\n", rc);
211
    if (rc < 0) return rc;
195
    if (rc < 0) return rc;
212
 
196
 
213
    n_threads = tb_copied / sizeof(unsigned);
197
    n_threads = tb_copied / sizeof(unsigned);
214
 
198
 
215
    printf("thread IDs:");
199
    cons_printf("thread IDs:");
216
    for (i=0; i<n_threads; i++) {
200
    for (i=0; i<n_threads; i++) {
217
        printf(" %u", thread_hash_buf[i]);
201
        cons_printf(" %u", thread_hash_buf[i]);
218
    }
202
    }
219
    printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
203
    cons_printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
220
 
204
 
221
    return 0;
205
    return 0;
222
}
206
}
223
 
207
 
224
void event_thread_b(unsigned hash)
208
void event_thread_b(unsigned hash)
225
{
209
{
226
    async_serialize_start();
210
    async_serialize_start();
227
    printf("new thread, hash 0x%x\n", hash);
211
    cons_printf("new thread, hash 0x%x\n", hash);
228
    async_serialize_end();
212
    async_serialize_end();
229
 
213
 
230
    thread_debug_start(hash);
214
    thread_debug_start(hash);
231
}
215
}
232
 
216
 
Line 234... Line 218...
234
 
218
 
235
static void debug_event(thash_t thash, udebug_event_t ev_type, sysarg_t val0)
219
static void debug_event(thash_t thash, udebug_event_t ev_type, sysarg_t val0)
236
{
220
{
237
    switch (ev_type) {
221
    switch (ev_type) {
238
    case UDEBUG_EVENT_STOP:
222
    case UDEBUG_EVENT_STOP:
239
        printf("stop event\n");
223
        cons_printf("stop event\n");
240
        printf("waiting for resume\n");
224
        cons_printf("waiting for resume\n");
241
        while (paused) {
225
        while (paused) {
242
            usleep(1000000);
226
            usleep(1000000);
243
            fibril_yield();
227
            fibril_yield();
244
            printf(".");
228
            cons_printf(".");
245
        }
229
        }
246
        printf("resumed\n");
230
        cons_printf("resumed\n");
247
        break;
231
        break;
248
    case UDEBUG_EVENT_THREAD_B:
232
    case UDEBUG_EVENT_THREAD_B:
249
        event_thread_b(val0);
233
        event_thread_b(val0);
250
        break;
234
        break;
251
    case UDEBUG_EVENT_THREAD_E:
235
    case UDEBUG_EVENT_THREAD_E:
252
        printf("thread 0x%x exited\n", val0);
236
        cons_printf("thread 0x%x exited\n", val0);
253
        abort_debug = true;
237
        abort_debug = true;
254
        break;
238
        break;
255
    case UDEBUG_EVENT_BREAKPOINT:
239
    case UDEBUG_EVENT_BREAKPOINT:
256
        arch_event_breakpoint(thash);
240
        arch_event_breakpoint(thash);
257
        break;
241
        break;
258
    case UDEBUG_EVENT_TRAP:
242
    case UDEBUG_EVENT_TRAP:
259
        arch_event_trap(thash);
243
        arch_event_trap(thash);
260
        break;
244
        break;
261
    default:
245
    default:
262
        printf("unknown event type %d\n", ev_type);
246
        cons_printf("unknown event type %d\n", ev_type);
263
        break;
247
        break;
264
    }
248
    }
265
}
249
}
266
 
250
 
267
void debug_loop(void *thread_hash_arg)
251
void debug_loop(void *thread_hash_arg)
Line 273... Line 257...
273
    unsigned val0, val1;
257
    unsigned val0, val1;
274
 
258
 
275
    thread_hash = (unsigned)thread_hash_arg;
259
    thread_hash = (unsigned)thread_hash_arg;
276
    thread_id = next_thread_id++;
260
    thread_id = next_thread_id++;
277
 
261
 
278
    printf("debug_loop(%d)\n", thread_id); 
262
    cons_printf("debug_loop(%d)\n", thread_id);
279
 
263
 
280
    while (!abort_debug) {
264
    while (!abort_debug) {
281
 
265
 
282
        printf("[t%d] go...\n", thread_id);
-
 
283
        /* Run thread until an event occurs */
266
        /* Run thread until an event occurs */
284
        rc = udebug_go(app_phone, thread_hash,
267
        rc = udebug_go(app_phone, thread_hash,
285
            &ev_type, &val0, &val1);
268
            &ev_type, &val0, &val1);
286
        printf("[t%d] stopped\n", thread_id);
-
 
287
 
269
 
288
        if (ev_type == UDEBUG_EVENT_FINISHED) {
270
        if (ev_type == UDEBUG_EVENT_FINISHED) {
289
            printf("thread %u debugging finished\n", thread_id);
271
            cons_printf("thread %u debugging finished\n", thread_id);
290
            break;
272
            break;
291
        }
273
        }
292
        if (rc >= 0) debug_event(thread_hash, ev_type, val0);
274
        if (rc >= 0) debug_event(thread_hash, ev_type, val0);
293
    }
275
    }
294
 
276
 
295
    printf("debug_loop(%d) exiting\n", thread_id);
277
    cons_printf("debug_loop(%d) exiting\n", thread_id);
296
}
278
}
297
 
279
 
298
void thread_debug_start(unsigned thread_hash)
280
void thread_debug_start(unsigned thread_hash)
299
{
281
{
300
    fid_t fid;
282
    fid_t fid;
301
 
283
 
302
    thash = thread_hash;
284
    thash = thread_hash;
303
 
285
 
304
    fid = fibril_create(debug_loop, (void *)thread_hash);
286
    fid = fibril_create(debug_loop, (void *)thread_hash);
305
    if (fid == 0) {
287
    if (fid == 0) {
306
        printf("Warning: Failed creating fibril\n");
288
        cons_printf("Warning: Failed creating fibril\n");
307
    }
289
    }
308
    fibril_add_ready(fid);
290
    fibril_add_ready(fid);
309
}
291
}
310
 
292
 
311
void debug_active_task(void)
293
void debug_active_task(void)
Line 313... Line 295...
313
    int taskid;
295
    int taskid;
314
    int i;
296
    int i;
315
    int rc;
297
    int rc;
316
    int c;
298
    int c;
317
 
299
 
318
    printf("Breakpoint Debugger\n");
300
    cons_printf("Breakpoint Debugger\n");
319
    printf("Press 'c' to connect\n");
301
    cons_printf("Press 'c' to connect\n");
320
    while ((i = getchar()) != 'c')
302
    while ((i = getchar()) != 'c')
321
        putchar(i);
303
        putchar(i);
322
 
304
 
323
    taskid = 14;
305
    taskid = 14;
324
    rc = task_connect(taskid);
306
    rc = task_connect(taskid);
325
    if (rc < 0) {
307
    if (rc < 0) {
326
        printf("Failed to connect to task %d\n", taskid);
308
        cons_printf("Failed to connect to task %d\n", taskid);
327
        return;
309
        return;
328
    }
310
    }
329
 
311
 
330
    printf("Connected to task %d\n", taskid);
312
    cons_printf("Connected to task %d\n", taskid);
331
 
313
 
332
    rc = get_thread_list();
314
    rc = get_thread_list();
333
    if (rc < 0) {
315
    if (rc < 0) {
334
        printf("Failed to get thread list (error %d)\n", rc);
316
        cons_printf("Failed to get thread list (error %d)\n", rc);
335
        return;
317
        return;
336
    }
318
    }
337
 
319
 
338
    abort_debug = false;
320
    abort_debug = false;
339
 
321
 
340
    for (i = 0; i < n_threads; i++) {
322
    for (i = 0; i < n_threads; i++) {
341
        thread_debug_start(thread_hash_buf[i]);
323
        thread_debug_start(thread_hash_buf[i]);
342
    }
324
    }
343
 
325
 
344
    while (!quit) {
326
    while (!quit) {
345
        printf("> ");
-
 
346
        read_line(in_buf, INBUF_SIZE);
327
        cons_read_line(in_buf, IN_BUF_SIZE);
347
        command_split(in_buf);
328
        command_split(in_buf);
348
        if (cmd_argc == 0) continue;
329
        if (cmd_argc == 0) continue;
349
 
330
 
350
        command_run();
331
        command_run();
351
    }
332
    }
352
 
333
 
353
    printf("terminate debugging session...\n");
334
    cons_printf("terminate debugging session...\n");
354
    abort_debug = true;
335
    abort_debug = true;
355
    udebug_end(app_phone);
336
    udebug_end(app_phone);
356
    ipc_hangup(app_phone);
337
    ipc_hangup(app_phone);
357
 
338
 
358
    printf("done\n");
339
    cons_printf("done\n");
359
    return;
340
    return;
360
}
341
}
361
 
342
 
362
static void main_init(void)
343
static void main_init(void)
363
{
344
{