Subversion Repositories HelenOS

Rev

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