Rev 2867 | Rev 2871 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2867 | Rev 2868 | ||
---|---|---|---|
Line 15... | Line 15... | ||
15 | 15 | ||
16 | #include "syscalls.h" |
16 | #include "syscalls.h" |
17 | #include "errors.h" |
17 | #include "errors.h" |
18 | #include "debug_api.h" |
18 | #include "debug_api.h" |
19 | 19 | ||
20 | #define TIDBUF_SIZE 64 |
20 | #define THBUF_SIZE 64 |
21 | unsigned threadid_buf[TIDBUF_SIZE]; |
21 | unsigned thread_hash_buf[THBUF_SIZE]; |
22 | unsigned n_threads; |
22 | unsigned n_threads; |
23 | 23 | ||
- | 24 | int next_thread_id; |
|
- | 25 | ||
24 | int phoneid; |
26 | int phoneid; |
25 | int abort_trace; |
27 | int abort_trace; |
26 | 28 | ||
- | 29 | void thread_trace_start(unsigned thread_hash); |
|
- | 30 | ||
- | 31 | ||
27 | int task_connect(int taskid) |
32 | int task_connect(int taskid) |
28 | { |
33 | { |
29 | int rc; |
34 | int rc; |
30 | 35 | ||
31 | printf("ipc_connect_task(%d)...\n", taskid); |
36 | printf("ipc_connect_task(%d)...\n", taskid); |
Line 49... | Line 54... | ||
49 | int tb_needed; |
54 | int tb_needed; |
50 | int i; |
55 | int i; |
51 | 56 | ||
52 | 57 | ||
53 | printf("send IPC_M_DEBUG_THREAD_READ message\n"); |
58 | printf("send IPC_M_DEBUG_THREAD_READ message\n"); |
54 | rc = debug_thread_read(phoneid, (unsigned)threadid_buf, |
59 | rc = debug_thread_read(phoneid, (unsigned)thread_hash_buf, |
55 | TIDBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed); |
60 | THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed); |
56 | printf("-> %d\n", rc); |
61 | printf("-> %d\n", rc); |
57 | if (rc < 0) return rc; |
62 | if (rc < 0) return rc; |
58 | 63 | ||
59 | n_threads = tb_copied / sizeof(unsigned); |
64 | n_threads = tb_copied / sizeof(unsigned); |
60 | 65 | ||
61 | printf("thread IDs:"); |
66 | printf("thread IDs:"); |
62 | for (i=0; i<n_threads; i++) { |
67 | for (i=0; i<n_threads; i++) { |
63 | printf(" %u", threadid_buf[i]); |
68 | printf(" %u", thread_hash_buf[i]); |
64 | } |
69 | } |
65 | printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
70 | printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
66 | 71 | ||
67 | return 0; |
72 | return 0; |
68 | } |
73 | } |
Line 119... | Line 124... | ||
119 | ipc_args[0], ipc_args[1], ipc_args[2], |
124 | ipc_args[0], ipc_args[1], ipc_args[2], |
120 | ipc_args[3], ipc_args[4], ipc_args[5]); |
125 | ipc_args[3], ipc_args[4], ipc_args[5]); |
121 | } |
126 | } |
122 | } |
127 | } |
123 | 128 | ||
124 | void event_syscall(unsigned thread_idx, unsigned sc_id, int sc_rc) |
129 | void event_syscall(unsigned thread_id, unsigned thread_hash, unsigned sc_id, int sc_rc) |
125 | { |
130 | { |
126 | unsigned sc_args[6]; |
131 | unsigned sc_args[6]; |
127 | int rv_type; |
132 | int rv_type; |
128 | int rc; |
133 | int rc; |
129 | 134 | ||
130 | /* Read syscall arguments */ |
135 | /* Read syscall arguments */ |
131 | rc = debug_args_read(phoneid, threadid_buf[thread_idx], sc_args); |
136 | rc = debug_args_read(phoneid, thread_hash, sc_args); |
132 | 137 | ||
133 | async_serialize_start(); |
138 | async_serialize_start(); |
134 | 139 | ||
135 | printf("[%d] ", thread_idx); |
140 | printf("[%d] ", thread_id); |
136 | 141 | ||
137 | if (rc < 0) { |
142 | if (rc < 0) { |
138 | printf("error\n"); |
143 | printf("error\n"); |
139 | async_serialize_end(); |
144 | async_serialize_end(); |
140 | return; |
145 | return; |
Line 160... | Line 165... | ||
160 | void event_new_thread(unsigned hash) |
165 | void event_new_thread(unsigned hash) |
161 | { |
166 | { |
162 | async_serialize_start(); |
167 | async_serialize_start(); |
163 | printf("new thread, hash 0x%x\n", hash); |
168 | printf("new thread, hash 0x%x\n", hash); |
164 | async_serialize_end(); |
169 | async_serialize_end(); |
- | 170 | ||
- | 171 | thread_trace_start(hash); |
|
165 | } |
172 | } |
166 | 173 | ||
167 | void trace_loop(void *thread_idx_arg) |
174 | void trace_loop(void *thread_hash_arg) |
168 | { |
175 | { |
169 | int rc; |
176 | int rc; |
170 | unsigned ev_type; |
177 | unsigned ev_type; |
- | 178 | unsigned thread_hash; |
|
171 | unsigned thread_idx; |
179 | unsigned thread_id; |
172 | unsigned val0, val1; |
180 | unsigned val0, val1; |
173 | 181 | ||
174 | thread_idx = (unsigned)thread_idx_arg; |
182 | thread_hash = (unsigned)thread_hash_arg; |
- | 183 | thread_id = next_thread_id++; |
|
- | 184 | ||
175 | printf("trace_loop(%d)\n", thread_idx); |
185 | printf("trace_loop(%d)\n", thread_id); |
176 | 186 | ||
177 | while (!abort_trace) { |
187 | while (!abort_trace) { |
178 | 188 | ||
179 | /* Run thread until an event occurs */ |
189 | /* Run thread until an event occurs */ |
180 | rc = debug_go(phoneid, threadid_buf[thread_idx], |
190 | rc = debug_go(phoneid, thread_hash, |
181 | &ev_type, &val0, &val1); |
191 | &ev_type, &val0, &val1); |
182 | 192 | ||
183 | printf("rc = %d, ev_type=%d\n", rc, ev_type); |
193 | printf("rc = %d, ev_type=%d\n", rc, ev_type); |
184 | if (ev_type == UDEBUG_EVENT_FINISHED) { |
194 | if (ev_type == UDEBUG_EVENT_FINISHED) { |
185 | printf("thread %u debugging finished\n", threadid_buf[thread_idx]); |
195 | printf("thread %u debugging finished\n", thread_id); |
186 | break; |
196 | break; |
187 | } |
197 | } |
188 | 198 | ||
189 | if (rc >= 0) { |
199 | if (rc >= 0) { |
190 | switch (ev_type) { |
200 | switch (ev_type) { |
191 | case UDEBUG_EVENT_SYSCALL: |
201 | case UDEBUG_EVENT_SYSCALL: |
192 | event_syscall(thread_idx, val0, (int)val1); |
202 | event_syscall(thread_id, thread_hash, val0, (int)val1); |
193 | break; |
203 | break; |
194 | case UDEBUG_EVENT_NEW_THREAD: |
204 | case UDEBUG_EVENT_NEW_THREAD: |
195 | event_new_thread(val0); |
205 | event_new_thread(val0); |
196 | break; |
206 | break; |
197 | default: |
207 | default: |
Line 200... | Line 210... | ||
200 | } |
210 | } |
201 | } |
211 | } |
202 | 212 | ||
203 | } |
213 | } |
204 | 214 | ||
205 | printf("trace_loop(%d) exiting\n", thread_idx); |
215 | printf("trace_loop(%d) exiting\n", thread_id); |
206 | } |
216 | } |
207 | 217 | ||
- | 218 | void thread_trace_start(unsigned thread_hash) |
|
- | 219 | { |
|
- | 220 | fid_t fid; |
|
- | 221 | ||
- | 222 | fid = fibril_create(trace_loop, (void *)thread_hash); |
|
- | 223 | if (fid == 0) { |
|
- | 224 | printf("Warning: Failed creating fibril\n"); |
|
- | 225 | } |
|
- | 226 | fibril_add_ready(fid); |
|
- | 227 | } |
|
208 | 228 | ||
209 | void trace_active_task(void) |
229 | void trace_active_task(void) |
210 | { |
230 | { |
211 | int taskid; |
231 | int taskid; |
212 | int i; |
232 | int i; |
213 | int rc; |
233 | int rc; |
214 | fid_t fid; |
- | |
215 | 234 | ||
216 | printf("Syscall Tracer\n"); |
235 | printf("Syscall Tracer\n"); |
217 | printf("Press 'c' to connect\n"); |
236 | printf("Press 'c' to connect\n"); |
218 | while ((i = getchar()) != 'c') |
237 | while ((i = getchar()) != 'c') |
219 | putchar(i); |
238 | putchar(i); |
Line 234... | Line 253... | ||
234 | } |
253 | } |
235 | 254 | ||
236 | abort_trace = 0; |
255 | abort_trace = 0; |
237 | 256 | ||
238 | for (i = 0; i < n_threads; i++) { |
257 | for (i = 0; i < n_threads; i++) { |
239 | fid = fibril_create(trace_loop, (void *)i); |
258 | thread_trace_start(thread_hash_buf[i]); |
240 | if (fid == 0) { |
- | |
241 | printf("Warning: Failed creating fibril\n"); |
- | |
242 | } |
- | |
243 | fibril_add_ready(fid); |
- | |
244 | } |
259 | } |
245 | 260 | ||
246 | getchar(); |
261 | getchar(); |
247 | 262 | ||
248 | printf("terminate debugging session...\n"); |
263 | printf("terminate debugging session...\n"); |
Line 254... | Line 269... | ||
254 | return; |
269 | return; |
255 | } |
270 | } |
256 | 271 | ||
257 | int main(void) |
272 | int main(void) |
258 | { |
273 | { |
- | 274 | next_thread_id = 1; |
|
- | 275 | ||
259 | while (1) { |
276 | while (1) { |
260 | trace_active_task(); |
277 | trace_active_task(); |
261 | } |
278 | } |
262 | } |
279 | } |
263 | 280 |