Subversion Repositories HelenOS

Rev

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