Subversion Repositories HelenOS

Rev

Rev 2837 | Rev 2850 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2832 svoboda 1
/** @addtogroup sctrace
2
 * @{
3
 */
4
/** @file
5
 */
6
 
7
#include <stdio.h>
8
#include <unistd.h>
9
#include <syscall.h>
10
#include <ipc/ipc.h>
2835 svoboda 11
#include <fibril.h>
12
#include <errno.h>
2838 svoboda 13
#include <udebug.h>
2832 svoboda 14
 
15
#include "syscalls.h"
16
#include "errors.h"
17
#include "debug_api.h"
18
 
19
#define TIDBUF_SIZE 64
20
unsigned threadid_buf[TIDBUF_SIZE];
21
 
22
int phoneid;
2835 svoboda 23
int abort_trace;
2832 svoboda 24
 
25
int task_connect(int taskid)
26
{
27
    int rc;
28
 
29
    printf("ipc_connect_task(%d)...\n", taskid);
30
    rc = ipc_connect_kbox(taskid);
31
    printf("-> %d\n", rc);
32
    phoneid = rc;
33
    if (rc < 0) return rc;
34
 
35
    printf("debug_begin()\n");
36
    rc = debug_begin(phoneid);
37
    printf("-> %d\n", rc);
38
    if (rc < 0) return rc;
39
 
40
    return 0;
41
}
42
 
43
int get_thread_list(void)
44
{
45
    int rc;
46
    int tb_copied;
47
    int tb_needed;
48
    int i;
49
 
50
 
51
    printf("send IPC_M_DEBUG_THREAD_READ message\n");
52
    rc = debug_thread_read(phoneid, (unsigned)threadid_buf,
53
        TIDBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
54
    printf("-> %d\n", rc);
55
    if (rc < 0) return rc;
56
 
57
    printf("thread IDs:");
58
    for (i=0; i<tb_copied / sizeof(unsigned); i++) {
59
        printf(" %u", threadid_buf[i]);
60
    }
61
    printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
62
 
63
    return 0;
64
}
65
 
66
void print_sc_retval(int retval, rv_type_t rv_type)
67
{
68
    printf (" -> ");
69
    if (rv_type == RV_INTEGER) {
70
        printf("%d", retval);
71
    } else if (rv_type == RV_HASH) {
72
        printf("0x%08x", retval);
73
    } else if (rv_type == RV_ERRNO) {
74
        if (retval >= -15 && retval <= 0) {
75
            printf("%d %s (%s)", retval,
76
                err_desc[retval].name,
77
                err_desc[retval].desc);
78
        } else {
79
            printf("%d", retval);
80
        }
81
    } else if (rv_type == RV_INT_ERRNO) {
82
        if (retval >= -15 && retval < 0) {
83
            printf("%d %s (%s)", retval,
84
                err_desc[retval].name,
85
                err_desc[retval].desc);
86
        } else {
87
            printf("%d", retval);
88
        }
89
    }
90
    putchar('\n');
91
}
92
 
93
void print_sc_args(unsigned *sc_args, int n)
94
{
95
    int i;
96
 
97
    putchar('(');
98
    if (n > 0) printf("%d", sc_args[0]);
99
    for (i=1; i<n; i++) {
100
        printf(", %d", sc_args[i]);
101
    }
102
    putchar(')');
103
}
104
 
105
void sc_ipc_call_async_slow(unsigned *sc_args)
106
{
107
    unsigned ipc_args[6];
108
    int rc;
109
 
110
    memset(ipc_args, 0, sizeof(ipc_args));
111
    rc = debug_mem_read(phoneid, ipc_args, sc_args[1], sizeof(ipc_args));
112
 
113
    if (rc >= 0) {
114
        printf("args: (%u, %u, %u, %u, %u, %u)\n",
115
            ipc_args[0], ipc_args[1], ipc_args[2],
116
            ipc_args[3], ipc_args[4], ipc_args[5]);
117
    }
118
}
119
 
2835 svoboda 120
int keyboard_fibril(void *arg)
121
{
122
    (void)arg;
123
 
124
    printf("keyboard fibril started\n");
125
 
126
    getchar();
127
    printf("keyboard fibril setting abort_trace\n");
128
    abort_trace = 1;
129
    printf("keyboard fibril sending debug_end()\n");
130
    debug_end(phoneid);
2837 svoboda 131
    printf("keyboard fibril hanging up phone\n");
132
    ipc_hangup(phoneid);
2835 svoboda 133
    printf("keyboard fibril exitting\n");
134
 
135
    return EOK;
136
}
137
 
2832 svoboda 138
void trace_loop(void)
139
{
140
    int rc;
141
    unsigned sc_args[6];
142
    unsigned copied;
143
    unsigned ev_type;
144
    unsigned sc_id;
145
    int sc_rc;
146
    int rv_type;
2835 svoboda 147
    fid_t kb_fid;
2832 svoboda 148
 
2835 svoboda 149
    abort_trace = 0;
150
    kb_fid = fibril_create(keyboard_fibril, NULL);
151
    if (kb_fid == 0) {
152
        printf("Failed creating keyboard fibril\n");
153
        return;
154
    }
155
    fibril_add_ready(kb_fid);
156
 
157
    while (!abort_trace) {
158
 
2832 svoboda 159
        /* Run thread until a syscall is executed */
160
        rc = debug_go(phoneid, threadid_buf[0],
161
            &ev_type, &sc_id, &sc_rc);
162
 
2838 svoboda 163
        printf("rc = %d, ev_type=%d\n", rc, ev_type);
164
        if (ev_type == UDEBUG_EVENT_FINISHED) {
165
            printf("thread %u debugging finished\n", threadid_buf[0]);
166
            break;
167
        }
168
 
2832 svoboda 169
        /* Read syscall arguments */
170
        if (rc >= 0) {
171
            rc = debug_args_read(phoneid, threadid_buf[0],
172
                sc_args);
173
        }
174
 
175
        /* Print syscall name, id and arguments */
176
        if (rc >= 0) {
177
            printf("%s", syscall_desc[sc_id].name);
178
            print_sc_args(sc_args, syscall_desc[sc_id].n_args);
179
            rv_type = syscall_desc[sc_id].rv_type;
180
            print_sc_retval(sc_rc, rv_type);
181
        }
182
 
183
        switch (sc_id) {
184
        case SYS_IPC_CALL_ASYNC_SLOW:
185
            sc_ipc_call_async_slow(sc_args);
186
            break;
187
        default:
188
            break;
189
        }
190
    }
2835 svoboda 191
 
192
    printf("trace_loop() exiting\n");
2832 svoboda 193
}
194
 
195
 
196
void trace_active_task(void)
197
{
198
    int taskid;
199
    int i;
200
    int rc;
201
 
202
    printf("Syscall Tracer\n");
203
    printf("Press 'c' to connect\n");
204
    while ((i = getchar()) != 'c')
205
        putchar(i);
206
 
207
    taskid = 13;
208
    rc = task_connect(taskid);
209
    if (rc < 0) {
210
        printf("Failed to connect to task %d\n", taskid);
211
        return;
212
    }
213
 
214
    printf("Connected to task %d\n", taskid);
215
 
216
    rc = get_thread_list();
217
    if (rc < 0) {
218
        printf("Failed to get thread list (error %d)\n", rc);
219
        return;
220
    }
221
 
222
    trace_loop();
2835 svoboda 223
/*
224
    printf("press 'd' to disconnect\n");
225
    while ((i = getchar()) != 'd')
226
        putchar(i);
2832 svoboda 227
 
2835 svoboda 228
    printf("call debug_end()\n");
229
    debug_end(phoneid);
230
*/
2832 svoboda 231
    printf("done\n");
232
    return;
233
}
234
 
235
int main(void)
236
{
2835 svoboda 237
    while (1) {
238
        trace_active_task();
239
    }
2832 svoboda 240
}
241
 
242
/** @}
243
 */