Rev 3452 | Rev 3455 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3452 | Rev 3454 | ||
|---|---|---|---|
| Line 53... | Line 53... | ||
| 53 | #include "ipcp.h" |
53 | #include "ipcp.h" |
| 54 | #include "errors.h" |
54 | #include "errors.h" |
| 55 | #include "trace.h" |
55 | #include "trace.h" |
| 56 | 56 | ||
| 57 | #define THBUF_SIZE 64 |
57 | #define THBUF_SIZE 64 |
| 58 | unsigned thread_hash_buf[THBUF_SIZE]; |
58 | uintptr_t thread_hash_buf[THBUF_SIZE]; |
| 59 | unsigned n_threads; |
59 | int n_threads; |
| 60 | 60 | ||
| 61 | int next_thread_id; |
61 | int next_thread_id; |
| 62 | 62 | ||
| 63 | int phoneid; |
63 | int phoneid; |
| 64 | int abort_trace; |
64 | int abort_trace; |
| 65 | 65 | ||
| 66 | unsigned thash; |
66 | uintptr_t thash; |
| 67 | volatile int paused; |
67 | volatile int paused; |
| 68 | 68 | ||
| 69 | void thread_trace_start(unsigned thread_hash); |
69 | void thread_trace_start(uintptr_t thread_hash); |
| 70 | 70 | ||
| 71 | static proto_t *proto_console; |
71 | static proto_t *proto_console; |
| 72 | static task_id_t task_id; |
72 | static task_id_t task_id; |
| 73 | 73 | ||
| 74 | /** Combination of events/data to print. */ |
74 | /** Combination of events/data to print. */ |
| Line 123... | Line 123... | ||
| 123 | if (rc < 0) { |
123 | if (rc < 0) { |
| 124 | printf("udebug_thread_read() -> %d\n", rc); |
124 | printf("udebug_thread_read() -> %d\n", rc); |
| 125 | return rc; |
125 | return rc; |
| 126 | } |
126 | } |
| 127 | 127 | ||
| 128 | n_threads = tb_copied / sizeof(unsigned); |
128 | n_threads = tb_copied / sizeof(uintptr_t); |
| 129 | 129 | ||
| 130 | printf("Threads:"); |
130 | printf("Threads:"); |
| 131 | for (i = 0; i < n_threads; i++) { |
131 | for (i = 0; i < n_threads; i++) { |
| 132 | printf(" [%d] (hash 0x%x)", 1+i, thread_hash_buf[i]); |
132 | printf(" [%d] (hash 0x%lx)", 1+i, thread_hash_buf[i]); |
| 133 | } |
133 | } |
| 134 | printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
134 | printf("\ntotal of %u threads\n", tb_needed / sizeof(uintptr_t)); |
| 135 | 135 | ||
| 136 | return 0; |
136 | return 0; |
| 137 | } |
137 | } |
| 138 | 138 | ||
| 139 | void val_print(int val, val_type_t v_type) |
139 | void val_print(int val, val_type_t v_type) |
| Line 194... | Line 194... | ||
| 194 | printf(" -> "); |
194 | printf(" -> "); |
| 195 | val_print(retval, val_type); |
195 | val_print(retval, val_type); |
| 196 | putchar('\n'); |
196 | putchar('\n'); |
| 197 | } |
197 | } |
| 198 | 198 | ||
| 199 | static void print_sc_args(unsigned *sc_args, int n) |
199 | static void print_sc_args(sysarg_t *sc_args, int n) |
| 200 | { |
200 | { |
| 201 | int i; |
201 | int i; |
| 202 | 202 | ||
| 203 | putchar('('); |
203 | putchar('('); |
| 204 | if (n > 0) printf("%d", sc_args[0]); |
204 | if (n > 0) printf("%ld", sc_args[0]); |
| 205 | for (i = 1; i < n; i++) { |
205 | for (i = 1; i < n; i++) { |
| 206 | printf(", %d", sc_args[i]); |
206 | printf(", %ld", sc_args[i]); |
| 207 | } |
207 | } |
| 208 | putchar(')'); |
208 | putchar(')'); |
| 209 | } |
209 | } |
| 210 | 210 | ||
| 211 | static void sc_ipc_call_async_fast(unsigned *sc_args, int sc_rc) |
211 | static void sc_ipc_call_async_fast(sysarg_t *sc_args, sysarg_t sc_rc) |
| 212 | { |
212 | { |
| 213 | ipc_call_t call; |
213 | ipc_call_t call; |
| 214 | int phoneid; |
214 | ipcarg_t phoneid; |
| 215 | 215 | ||
| 216 | if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
216 | if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
| 217 | return; |
217 | return; |
| 218 | 218 | ||
| 219 | phoneid = sc_args[0]; |
219 | phoneid = sc_args[0]; |
| Line 226... | Line 226... | ||
| 226 | IPC_SET_ARG5(call, 0); |
226 | IPC_SET_ARG5(call, 0); |
| 227 | 227 | ||
| 228 | ipcp_call_out(phoneid, &call, sc_rc); |
228 | ipcp_call_out(phoneid, &call, sc_rc); |
| 229 | } |
229 | } |
| 230 | 230 | ||
| 231 | static void sc_ipc_call_async_slow(unsigned *sc_args, int sc_rc) |
231 | static void sc_ipc_call_async_slow(sysarg_t *sc_args, sysarg_t sc_rc) |
| 232 | { |
232 | { |
| 233 | ipc_call_t call; |
233 | ipc_call_t call; |
| 234 | int rc; |
234 | int rc; |
| 235 | 235 | ||
| 236 | if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
236 | if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
| Line 242... | Line 242... | ||
| 242 | if (rc >= 0) { |
242 | if (rc >= 0) { |
| 243 | ipcp_call_out(sc_args[0], &call, sc_rc); |
243 | ipcp_call_out(sc_args[0], &call, sc_rc); |
| 244 | } |
244 | } |
| 245 | } |
245 | } |
| 246 | 246 | ||
| 247 | static void sc_ipc_call_sync_fast(unsigned *sc_args) |
247 | static void sc_ipc_call_sync_fast(sysarg_t *sc_args) |
| 248 | { |
248 | { |
| 249 | ipc_call_t question, reply; |
249 | ipc_call_t question, reply; |
| 250 | int rc; |
250 | int rc; |
| 251 | int phoneidx; |
251 | int phoneidx; |
| 252 | 252 | ||
| Line 270... | Line 270... | ||
| 270 | 270 | ||
| 271 | // printf("call ipc_call_sync\n"); |
271 | // printf("call ipc_call_sync\n"); |
| 272 | ipcp_call_sync(phoneidx, &question, &reply); |
272 | ipcp_call_sync(phoneidx, &question, &reply); |
| 273 | } |
273 | } |
| 274 | 274 | ||
| 275 | static void sc_ipc_call_sync_slow(unsigned *sc_args) |
275 | static void sc_ipc_call_sync_slow(sysarg_t *sc_args) |
| 276 | { |
276 | { |
| 277 | ipc_call_t question, reply; |
277 | ipc_call_t question, reply; |
| 278 | int rc; |
278 | int rc; |
| 279 | 279 | ||
| 280 | memset(&question, 0, sizeof(question)); |
280 | memset(&question, 0, sizeof(question)); |
| Line 288... | Line 288... | ||
| 288 | if (rc < 0) return; |
288 | if (rc < 0) return; |
| 289 | 289 | ||
| 290 | ipcp_call_sync(sc_args[0], &question, &reply); |
290 | ipcp_call_sync(sc_args[0], &question, &reply); |
| 291 | } |
291 | } |
| 292 | 292 | ||
| 293 | static void sc_ipc_wait(unsigned *sc_args, int sc_rc) |
293 | static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc) |
| 294 | { |
294 | { |
| 295 | ipc_call_t call; |
295 | ipc_call_t call; |
| 296 | int rc; |
296 | int rc; |
| 297 | 297 | ||
| 298 | if (sc_rc == 0) return; |
298 | if (sc_rc == 0) return; |
| Line 305... | Line 305... | ||
| 305 | if (rc >= 0) { |
305 | if (rc >= 0) { |
| 306 | ipcp_call_in(&call, sc_rc); |
306 | ipcp_call_in(&call, sc_rc); |
| 307 | } |
307 | } |
| 308 | } |
308 | } |
| 309 | 309 | ||
| 310 | static void event_syscall_b(unsigned thread_id, unsigned thread_hash, unsigned sc_id, int sc_rc) |
310 | static void event_syscall_b(unsigned thread_id, uintptr_t thread_hash, |
| - | 311 | unsigned sc_id, sysarg_t sc_rc) |
|
| 311 | { |
312 | { |
| 312 | unsigned sc_args[6]; |
313 | sysarg_t sc_args[6]; |
| 313 | int rc; |
314 | int rc; |
| 314 | 315 | ||
| 315 | /* Read syscall arguments */ |
316 | /* Read syscall arguments */ |
| 316 | rc = udebug_args_read(phoneid, thread_hash, sc_args); |
317 | rc = udebug_args_read(phoneid, thread_hash, sc_args); |
| 317 | 318 | ||
| Line 332... | Line 333... | ||
| 332 | } |
333 | } |
| 333 | 334 | ||
| 334 | async_serialize_end(); |
335 | async_serialize_end(); |
| 335 | } |
336 | } |
| 336 | 337 | ||
| 337 | static void event_syscall_e(unsigned thread_id, unsigned thread_hash, unsigned sc_id, int sc_rc) |
338 | static void event_syscall_e(unsigned thread_id, uintptr_t thread_hash, |
| - | 339 | unsigned sc_id, sysarg_t sc_rc) |
|
| 338 | { |
340 | { |
| 339 | unsigned sc_args[6]; |
341 | sysarg_t sc_args[6]; |
| 340 | int rv_type; |
342 | int rv_type; |
| 341 | int rc; |
343 | int rc; |
| 342 | 344 | ||
| 343 | /* Read syscall arguments */ |
345 | /* Read syscall arguments */ |
| 344 | rc = udebug_args_read(phoneid, thread_hash, sc_args); |
346 | rc = udebug_args_read(phoneid, thread_hash, sc_args); |
| Line 380... | Line 382... | ||
| 380 | } |
382 | } |
| 381 | 383 | ||
| 382 | async_serialize_end(); |
384 | async_serialize_end(); |
| 383 | } |
385 | } |
| 384 | 386 | ||
| 385 | static void event_thread_b(unsigned hash) |
387 | static void event_thread_b(uintptr_t hash) |
| 386 | { |
388 | { |
| 387 | async_serialize_start(); |
389 | async_serialize_start(); |
| 388 | printf("New thread, hash 0x%x\n", hash); |
390 | printf("New thread, hash 0x%lx\n", hash); |
| 389 | async_serialize_end(); |
391 | async_serialize_end(); |
| 390 | 392 | ||
| 391 | thread_trace_start(hash); |
393 | thread_trace_start(hash); |
| 392 | } |
394 | } |
| 393 | 395 | ||
| 394 | static int trace_loop(void *thread_hash_arg) |
396 | static int trace_loop(void *thread_hash_arg) |
| 395 | { |
397 | { |
| 396 | int rc; |
398 | int rc; |
| 397 | unsigned ev_type; |
399 | unsigned ev_type; |
| 398 | unsigned thread_hash; |
400 | uintptr_t thread_hash; |
| 399 | unsigned thread_id; |
401 | unsigned thread_id; |
| 400 | unsigned val0, val1; |
402 | sysarg_t val0, val1; |
| 401 | 403 | ||
| 402 | thread_hash = (unsigned)thread_hash_arg; |
404 | thread_hash = (uintptr_t)thread_hash_arg; |
| 403 | thread_id = next_thread_id++; |
405 | thread_id = next_thread_id++; |
| 404 | 406 | ||
| 405 | printf("Start tracing thread [%d] (hash 0x%x)\n", thread_id, thread_hash); |
407 | printf("Start tracing thread [%d] (hash 0x%lx)\n", thread_id, thread_hash); |
| 406 | 408 | ||
| 407 | while (!abort_trace) { |
409 | while (!abort_trace) { |
| 408 | 410 | ||
| 409 | /* Run thread until an event occurs */ |
411 | /* Run thread until an event occurs */ |
| 410 | rc = udebug_go(phoneid, thread_hash, |
412 | rc = udebug_go(phoneid, thread_hash, |
| Line 436... | Line 438... | ||
| 436 | break; |
438 | break; |
| 437 | case UDEBUG_EVENT_THREAD_B: |
439 | case UDEBUG_EVENT_THREAD_B: |
| 438 | event_thread_b(val0); |
440 | event_thread_b(val0); |
| 439 | break; |
441 | break; |
| 440 | case UDEBUG_EVENT_THREAD_E: |
442 | case UDEBUG_EVENT_THREAD_E: |
| 441 | printf("Thread 0x%x exited\n", val0); |
443 | printf("Thread 0x%lx exited\n", val0); |
| 442 | abort_trace = 1; |
444 | abort_trace = 1; |
| 443 | break; |
445 | break; |
| 444 | default: |
446 | default: |
| 445 | printf("Unknown event type %d\n", ev_type); |
447 | printf("Unknown event type %d\n", ev_type); |
| 446 | break; |
448 | break; |
| Line 451... | Line 453... | ||
| 451 | 453 | ||
| 452 | printf("Finished tracing thread [%d]\n", thread_id); |
454 | printf("Finished tracing thread [%d]\n", thread_id); |
| 453 | return 0; |
455 | return 0; |
| 454 | } |
456 | } |
| 455 | 457 | ||
| 456 | void thread_trace_start(unsigned thread_hash) |
458 | void thread_trace_start(uintptr_t thread_hash) |
| 457 | { |
459 | { |
| 458 | fid_t fid; |
460 | fid_t fid; |
| 459 | 461 | ||
| 460 | thash = thread_hash; |
462 | thash = thread_hash; |
| 461 | 463 | ||
| Line 670... | Line 672... | ||
| 670 | 672 | ||
| 671 | --argc; ++argv; |
673 | --argc; ++argv; |
| 672 | } |
674 | } |
| 673 | 675 | ||
| 674 | if (task_id != 0) { |
676 | if (task_id != 0) { |
| 675 | if (argc == 0) return; |
677 | if (argc == 0) return 0; |
| 676 | printf("Extra arguments\n"); |
678 | printf("Extra arguments\n"); |
| 677 | print_syntax(); |
679 | print_syntax(); |
| 678 | return -1; |
680 | return -1; |
| 679 | } |
681 | } |
| 680 | 682 | ||