Subversion Repositories HelenOS

Rev

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