Subversion Repositories HelenOS

Rev

Rev 2835 | Rev 2838 | 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);
2837 svoboda 130
    printf("keyboard fibril hanging up phone\n");
131
    ipc_hangup(phoneid);
2835 svoboda 132
    printf("keyboard fibril exitting\n");
133
 
134
    return EOK;
135
}
136
 
2832 svoboda 137
void trace_loop(void)
138
{
139
    int rc;
140
    unsigned sc_args[6];
141
    unsigned copied;
142
    unsigned ev_type;
143
    unsigned sc_id;
144
    int sc_rc;
145
    int rv_type;
2835 svoboda 146
    fid_t kb_fid;
2832 svoboda 147
 
2835 svoboda 148
    abort_trace = 0;
149
    kb_fid = fibril_create(keyboard_fibril, NULL);
150
    if (kb_fid == 0) {
151
        printf("Failed creating keyboard fibril\n");
152
        return;
153
    }
154
    fibril_add_ready(kb_fid);
155
 
156
    while (!abort_trace) {
157
 
2832 svoboda 158
        /* Run thread until a syscall is executed */
159
        rc = debug_go(phoneid, threadid_buf[0],
160
            &ev_type, &sc_id, &sc_rc);
161
 
162
        /* Read syscall arguments */
163
        if (rc >= 0) {
164
            rc = debug_args_read(phoneid, threadid_buf[0],
165
                sc_args);
166
        }
167
 
168
        /* Print syscall name, id and arguments */
169
        if (rc >= 0) {
170
            printf("%s", syscall_desc[sc_id].name);
171
            print_sc_args(sc_args, syscall_desc[sc_id].n_args);
172
            rv_type = syscall_desc[sc_id].rv_type;
173
            print_sc_retval(sc_rc, rv_type);
174
        }
175
 
176
        switch (sc_id) {
177
        case SYS_IPC_CALL_ASYNC_SLOW:
178
            sc_ipc_call_async_slow(sc_args);
179
            break;
180
        default:
181
            break;
182
        }
183
    }
2835 svoboda 184
 
185
    printf("trace_loop() exiting\n");
2832 svoboda 186
}
187
 
188
 
189
void trace_active_task(void)
190
{
191
    int taskid;
192
    int i;
193
    int rc;
194
 
195
    printf("Syscall Tracer\n");
196
    printf("Press 'c' to connect\n");
197
    while ((i = getchar()) != 'c')
198
        putchar(i);
199
 
200
    taskid = 13;
201
    rc = task_connect(taskid);
202
    if (rc < 0) {
203
        printf("Failed to connect to task %d\n", taskid);
204
        return;
205
    }
206
 
207
    printf("Connected to task %d\n", taskid);
208
 
209
    rc = get_thread_list();
210
    if (rc < 0) {
211
        printf("Failed to get thread list (error %d)\n", rc);
212
        return;
213
    }
214
 
215
    trace_loop();
2835 svoboda 216
/*
217
    printf("press 'd' to disconnect\n");
218
    while ((i = getchar()) != 'd')
219
        putchar(i);
2832 svoboda 220
 
2835 svoboda 221
    printf("call debug_end()\n");
222
    debug_end(phoneid);
223
*/
2832 svoboda 224
    printf("done\n");
225
    return;
226
}
227
 
228
int main(void)
229
{
2835 svoboda 230
    while (1) {
231
        trace_active_task();
232
    }
2832 svoboda 233
}
234
 
235
/** @}
236
 */