this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[xtrace] Update Methods To Implement Buffered String

Thomas A 5bc93a09 4ff97e09

+457 -400
+1
src/xtrace/base.h
··· 4 4 // common utilities for xtrace code 5 5 6 6 #define XTRACE_INLINE static __attribute__((always_inline)) 7 + #define XTRACE_HIDDEN __attribute__((visibility("hidden"))) 7 8 8 9 #ifdef __cplusplus 9 10 #define XTRACE_DECLARATIONS_C_BEGIN extern "C" {
+180 -170
src/xtrace/bsd_trace.cpp
··· 13 13 #include "bsd_trace.h" 14 14 #include "tls.h" 15 15 16 - static void print_errno(int nr, uintptr_t rv); 17 - static void print_errno_num(int nr, uintptr_t rv); 18 - static void print_errno_ptr(int nr, uintptr_t rv); 16 + static void print_errno(xtrace::String* log, int nr, uintptr_t rv); 17 + static void print_errno_num(xtrace::String* log, int nr, uintptr_t rv); 18 + static void print_errno_ptr(xtrace::String* log, int nr, uintptr_t rv); 19 19 20 - static void print_args(int nr, void* args[]); 20 + static void print_args(xtrace::String* log, int nr, void* args[]); 21 21 22 - static void print_kevent_return(int nr, uintptr_t rv); 23 - static void print_kevent_args(int nr, void* args[]); 24 - static void print_kevent64_return(int nr, uintptr_t rv); 25 - static void print_kevent64_args(int nr, void* args[]); 26 - static void print_kevent_qos_return(int nr, uintptr_t rv); 27 - static void print_kevent_qos_args(int nr, void* args[]); 22 + static void print_kevent_return(xtrace::String* log, int nr, uintptr_t rv); 23 + static void print_kevent_args(xtrace::String* log, int nr, void* args[]); 24 + static void print_kevent64_return(xtrace::String* log, int nr, uintptr_t rv); 25 + static void print_kevent64_args(xtrace::String* log, int nr, void* args[]); 26 + static void print_kevent_qos_return(xtrace::String* log, int nr, uintptr_t rv); 27 + static void print_kevent_qos_args(xtrace::String* log, int nr, void* args[]); 28 28 29 - static void print_select_return(int nr, uintptr_t rv); 30 - static void print_select_args(int nr, void* args[]); 29 + static void print_select_return(xtrace::String* log, int nr, uintptr_t rv); 30 + static void print_select_args(xtrace::String* log, int nr, void* args[]); 31 31 32 - static void print_timespec(const struct timespec* timespec); 32 + static void print_timespec(xtrace::String* log, const struct timespec* timespec); 33 33 34 34 // awk '/^[0-9]/ { if ($6 !~ "nosys") { split($6, a, "("); print "[" $1 "] = { \"" a[1] "\", print_args, print_errno }," } }' 35 35 ··· 445 445 [521] = { "abort_with_payload", print_args, print_errno_num }, 446 446 }; 447 447 448 - static void print_arg_int(void* arg) 448 + static void print_arg_int(xtrace::String* log, void* arg) 449 449 { 450 - xtrace_log("%d", (int) (long) arg); 450 + log->append_format("%d", (int) (long) arg); 451 451 } 452 452 453 - static void print_arg_ptr(void* arg) 453 + static void print_arg_ptr(xtrace::String* log, void* arg) 454 454 { 455 455 if (arg == NULL) 456 - xtrace_log("NULL"); 456 + log->append("NULL"); 457 457 else 458 - xtrace_log("%p", arg); 458 + log->append_format("%p", arg); 459 459 } 460 460 461 - extern "C" 462 - void xtrace_print_string_literal(const char* str) { 461 + void xtrace_print_string_literal(xtrace::String* log, const char* str) { 463 462 if (str == NULL) { 464 - xtrace_log("NULL"); 463 + log->append("NULL"); 465 464 return; 466 465 } 467 466 468 467 if (!xtrace_no_color) 469 - xtrace_log("\033[;1m"); // bold 468 + log->append("\033[;1m"); // bold 470 469 471 - xtrace_log("\""); 470 + log->append("\""); 472 471 473 472 for (; *str; str++) 474 473 { 475 474 switch (*str) 476 475 { 477 476 case '\\': 478 - xtrace_log("\\\\"); 477 + log->append("\\\\"); 479 478 break; 480 479 case '\n': 481 - xtrace_log("\\n"); 480 + log->append("\\n"); 482 481 break; 483 482 case '\t': 484 - xtrace_log("\\t"); 483 + log->append("\\t"); 485 484 break; 486 485 default: 487 - xtrace_log("%c", *str); 486 + log->append_format("%c", *str); 488 487 break; 489 488 } 490 489 } 491 490 492 - xtrace_log("\""); 491 + log->append("\""); 493 492 494 493 if (!xtrace_no_color) 495 - xtrace_log("\033[0m"); // reset 494 + log->append("\033[0m"); // reset 496 495 } 497 496 498 - static void print_arg_str(void* arg) 497 + static void print_arg_str(xtrace::String* log, void* arg) 499 498 { 500 499 const char* str = (const char*) arg; 501 - xtrace_print_string_literal(str); 500 + xtrace_print_string_literal(log, str); 502 501 } 503 502 504 - static void print_arg_prot(void* arg) 503 + static void print_arg_prot(xtrace::String* log, void* arg) 505 504 { 506 505 int cnt = 0; 507 506 int prot = (int)(long)arg; 508 507 509 508 if (prot & PROT_READ) 510 509 { 511 - xtrace_log("PROT_READ"); 510 + log->append("PROT_READ"); 512 511 cnt++; 513 512 } 514 513 if (prot & PROT_WRITE) 515 514 { 516 515 if (cnt > 0) 517 - xtrace_log("|"); 518 - xtrace_log("PROT_WRITE"); 516 + log->append("|"); 517 + log->append("PROT_WRITE"); 519 518 cnt++; 520 519 } 521 520 if (prot & PROT_EXEC) 522 521 { 523 522 if (cnt > 0) 524 - xtrace_log("|"); 525 - xtrace_log("PROT_EXEC"); 523 + log->append("|"); 524 + log->append("PROT_EXEC"); 526 525 cnt++; 527 526 } 528 527 if (cnt == 0) 529 528 { 530 - xtrace_log("PROT_NONE"); 529 + log->append("PROT_NONE"); 531 530 } 532 531 } 533 532 534 - static void print_mmap_flags(void* arg) 533 + static void print_mmap_flags(xtrace::String* log, void* arg) 535 534 { 536 535 int cnt = 0; 537 536 int flags = (int) (long) arg; ··· 554 553 if (flags & all_flags[i].flag) 555 554 { 556 555 if (cnt > 0) 557 - xtrace_log("|"); 558 - xtrace_log("%s", all_flags[i].name); 556 + log->append("|"); 557 + log->append_format("%s", all_flags[i].name); 559 558 cnt++; 560 559 } 561 560 } 562 561 563 562 if (cnt == 0) 564 563 { 565 - xtrace_log("MAP_FILE"); 564 + log->append("MAP_FILE"); 566 565 } 567 566 } 568 567 569 - extern "C" 570 - void print_open_flags(void* arg) 568 + void print_open_flags(xtrace::String* log, void* arg) 571 569 { 572 570 int cnt = 0; 573 571 int flags = (int) (long) arg; ··· 599 597 if (flags & all_flags[i].flag) 600 598 { 601 599 if (cnt > 0) 602 - xtrace_log("|"); 603 - xtrace_log("%s", all_flags[i].name); 600 + log->append("|"); 601 + log->append_format("%s", all_flags[i].name); 604 602 cnt++; 605 603 } 606 604 } 607 605 608 606 if (cnt == 0) 609 607 { 610 - xtrace_log("O_RDONLY"); 608 + log->append("O_RDONLY"); 611 609 } 612 610 } 613 611 614 - extern "C" void print_arg_posix_spawn_args(void* arg); 612 + extern void print_arg_posix_spawn_args(xtrace::String* log, void* arg); 615 613 616 - static void print_arg_string_array(void* arg) { 614 + static void print_arg_string_array(xtrace::String* log, void* arg) { 617 615 const char* const* array = (const char* const*)arg; 618 616 bool is_first = true; 619 617 620 - xtrace_log("{"); 618 + log->append("{"); 621 619 622 620 if (array) { 623 621 for (const char* const* ptr = array; *ptr != NULL; ++ptr) { 624 622 if (is_first) { 625 623 is_first = false; 626 624 } else { 627 - xtrace_log(", "); 625 + log->append(", "); 628 626 } 629 627 630 - xtrace_print_string_literal(*ptr); 628 + xtrace_print_string_literal(log, *ptr); 631 629 } 632 630 } 633 631 634 - xtrace_log("}"); 632 + log->append("}"); 635 633 }; 636 634 637 635 // TODO: output more specific information for more calls 638 636 639 637 static const struct { 640 638 int args_cnt; 641 - void (*print_arg[8])(void* arg); 639 + void (*print_arg[8])(xtrace::String* log, void* arg); 642 640 } args_info[] = { 643 641 [1] = { 1, { print_arg_int } }, // exit 644 642 [2] = { 0, { } }, // fork ··· 1042 1040 [521] = { 6, { print_arg_int, print_arg_int, print_arg_ptr, print_arg_int, print_arg_str, print_arg_int } }, // abort_with_payload 1043 1041 }; 1044 1042 1045 - static void print_args(int nr, void* args[]) 1043 + static void print_args(xtrace::String* log, int nr, void* args[]) 1046 1044 { 1047 1045 int cnt = args_info[nr].args_cnt; 1048 1046 for (int i = 0; i < cnt; i++) 1049 1047 { 1050 1048 if (i > 0) 1051 - xtrace_log(", "); 1052 - (*args_info[nr].print_arg[i])(args[i]); 1049 + log->append(", "); 1050 + (*args_info[nr].print_arg[i])(log, args[i]); 1053 1051 } 1054 1052 } 1055 1053 ··· 1057 1055 extern "C" 1058 1056 void darling_bsd_syscall_entry_print(int nr, void* args[]) 1059 1057 { 1058 + xtrace::String log; 1060 1059 #if __i386__ 1061 1060 // get rid of some info in the upper bytes that we don't need 1062 1061 nr = (int)((unsigned int)nr & 0xffff); 1063 1062 #endif 1064 1063 1065 - handle_generic_entry(bsd_defs, "bsd", nr, args); 1064 + handle_generic_entry(&log, bsd_defs, "bsd", nr, args); 1066 1065 1067 1066 if (nr == 1 || nr == 59) 1068 1067 { 1069 1068 // For exit() or execve(), print an extra newline, 1070 1069 // as we're likely not going to see the return. 1071 - xtrace_log("\n"); 1070 + log.append("\n"); 1071 + } 1072 + 1073 + if (log.size() > 0) { 1074 + xtrace_log("%s", log.c_str()); 1075 + log.clear(); 1072 1076 } 1073 1077 } 1074 1078 1075 1079 extern "C" 1076 1080 void darling_bsd_syscall_exit_print(uintptr_t retval) 1077 1081 { 1078 - handle_generic_exit(bsd_defs, "bsd", retval, 0); 1082 + xtrace::String log; 1083 + handle_generic_exit(&log, bsd_defs, "bsd", retval, 0); 1084 + 1085 + if (log.size() > 0) { 1086 + xtrace_log("%s", log.c_str()); 1087 + log.clear(); 1088 + } 1079 1089 } 1080 1090 1081 1091 const char* error_strings[128] = { ··· 1187 1197 [106] = "EQFULL", 1188 1198 }; 1189 1199 1190 - static void print_errno_num(int nr, uintptr_t rv) 1200 + static void print_errno_num(xtrace::String* log, int nr, uintptr_t rv) 1191 1201 { 1192 1202 intptr_t v = (intptr_t)rv; 1193 1203 if (v >= 0 || v < -4095) 1194 1204 { 1195 - xtrace_log("%ld", rv); 1205 + log->append_format("%ld", rv); 1196 1206 } 1197 1207 else 1198 - print_errno(nr, rv); 1208 + print_errno(log, nr, rv); 1199 1209 } 1200 1210 1201 - static void print_errno_ptr(int nr, uintptr_t rv) 1211 + static void print_errno_ptr(xtrace::String* log, int nr, uintptr_t rv) 1202 1212 { 1203 1213 intptr_t v = (intptr_t)rv; 1204 1214 if (v >= 0 || v < -4095) 1205 1215 { 1206 - xtrace_log("%p", (void*) rv); 1216 + log->append_format("%p", (void*) rv); 1207 1217 } 1208 1218 else 1209 - print_errno(nr, rv); 1219 + print_errno(log, nr, rv); 1210 1220 } 1211 1221 1212 - static void print_errno(int nr, uintptr_t rv) 1222 + static void print_errno(xtrace::String* log, int nr, uintptr_t rv) 1213 1223 { 1214 1224 const char* error = NULL; 1215 1225 intptr_t v = (intptr_t) rv; 1216 1226 if (-v < 128) 1217 1227 error = error_strings[-v]; 1218 1228 if (error != NULL) 1219 - xtrace_log("%s", error); 1229 + log->append_format("%s", error); 1220 1230 else 1221 - xtrace_log("%ld", v); 1231 + log->append_format("%ld", v); 1222 1232 } 1223 1233 1224 1234 static const char* const filter_names[] = { ··· 1364 1374 #undef FLAG 1365 1375 }; 1366 1376 1367 - static void print_kevent_common(int16_t filter, uintptr_t ident, uint16_t flags, uint32_t fflags, intptr_t data, void* udata) { 1377 + static void print_kevent_common(xtrace::String* log, int16_t filter, uintptr_t ident, uint16_t flags, uint32_t fflags, intptr_t data, void* udata) { 1368 1378 int filt_index = ~filter; 1369 1379 bool printed_something = false; 1370 1380 1371 - xtrace_log("%s { ident = ", (filt_index < 0 || filt_index >= sizeof(filter_names) / sizeof(*filter_names)) ? "EVFILT_UNKNOWN" : filter_names[filt_index]); 1381 + log->append_format("%s { ident = ", (filt_index < 0 || filt_index >= sizeof(filter_names) / sizeof(*filter_names)) ? "EVFILT_UNKNOWN" : filter_names[filt_index]); 1372 1382 1373 1383 switch (filter) { 1374 1384 case EVFILT_READ: ··· 1376 1386 case EVFILT_EXCEPT: 1377 1387 case EVFILT_VNODE: 1378 1388 case EVFILT_SOCK: 1379 - xtrace_log("fd %lu", ident); 1389 + log->append_format("fd %lu", ident); 1380 1390 break; 1381 1391 1382 1392 case EVFILT_PROC: 1383 - xtrace_log("pid %lu", ident); 1393 + log->append_format("pid %lu", ident); 1384 1394 break; 1385 1395 1386 1396 case EVFILT_SIGNAL: 1387 - xtrace_log("signal %s (%lu)", (ident < sizeof(signal_names) / sizeof(*signal_names)) ? signal_names[ident] : "SIGUNKNOWN", ident); 1397 + log->append_format("signal %s (%lu)", (ident < sizeof(signal_names) / sizeof(*signal_names)) ? signal_names[ident] : "SIGUNKNOWN", ident); 1388 1398 break; 1389 1399 1390 1400 case EVFILT_TIMER: 1391 - xtrace_log("timer %lu", ident); 1401 + log->append_format("timer %lu", ident); 1392 1402 break; 1393 1403 1394 1404 case EVFILT_MACHPORT: 1395 1405 // officially, only portsets can be used with EVFILT_MACHPORT. however, Apple introduced support for single ports in 10.13 or something around that time. 1396 - xtrace_log("port/portset %lu", ident); 1406 + log->append_format("port/portset %lu", ident); 1397 1407 break; 1398 1408 1399 1409 case EVFILT_FS: ··· 1404 1414 // notes: 1405 1415 // * EVFILT_VM is unsupported on macOS. 1406 1416 // * do EVFILT_FS, EVFILT_MEMORYSTATUS, and EVFILT_WORKLOOP even use `ident`? 1407 - xtrace_log("%lu", ident); 1417 + log->append_format("%lu", ident); 1408 1418 break; 1409 1419 1410 1420 default: 1411 - xtrace_log("%lu", ident); 1421 + log->append_format("%lu", ident); 1412 1422 break; 1413 1423 } 1414 1424 1415 - xtrace_log(", flags = "); 1425 + log->append(", flags = "); 1416 1426 1417 1427 for (size_t i = 0; i < sizeof(kevent_flag_names) / sizeof(*kevent_flag_names); ++i) { 1418 1428 if ((flags & kevent_flag_names[i].flag) == 0) { ··· 1422 1432 if (!printed_something) { 1423 1433 printed_something = true; 1424 1434 } else { 1425 - xtrace_log("|"); 1435 + log->append("|"); 1426 1436 } 1427 1437 1428 - xtrace_log("%s", kevent_flag_names[i].name); 1438 + log->append_format("%s", kevent_flag_names[i].name); 1429 1439 } 1430 1440 1431 - xtrace_log("%s(0x%x), fflags = ", printed_something ? " " : "", flags); 1441 + log->append_format("%s(0x%x), fflags = ", printed_something ? " " : "", flags); 1432 1442 1433 1443 printed_something = false; 1434 1444 ··· 1445 1455 if (!printed_something) { 1446 1456 printed_something = true; 1447 1457 } else { 1448 - xtrace_log("|"); 1458 + log->append("|"); 1449 1459 } 1450 1460 1451 - xtrace_log("%s", kevent_filter_flag_names[filt_index][i].name); 1461 + log->append_format("%s", kevent_filter_flag_names[filt_index][i].name); 1452 1462 } 1453 1463 } 1454 1464 1455 - xtrace_log("%s(0x%x), udata = %p, data = 0x%lx", printed_something ? " " : "", fflags, udata, data); 1465 + log->append_format("%s(0x%x), udata = %p, data = 0x%lx", printed_something ? " " : "", fflags, udata, data); 1456 1466 }; 1457 1467 1458 - static void print_kevent_structure(const struct kevent* event) { 1459 - print_kevent_common(event->filter, event->ident, event->flags, event->fflags, event->data, event->udata); 1460 - xtrace_log(" }"); 1468 + static void print_kevent_structure(xtrace::String* log, const struct kevent* event) { 1469 + print_kevent_common(log, event->filter, event->ident, event->flags, event->fflags, event->data, event->udata); 1470 + log->append(" }"); 1461 1471 }; 1462 1472 1463 - static void print_kevent64_structure(const struct kevent64_s* event) { 1464 - print_kevent_common(event->filter, event->ident, event->flags, event->fflags, event->data, (void*)(uintptr_t)event->udata); 1465 - xtrace_log(", ext[0] = 0x%llx, ext[1] = 0x%llx }", event->ext[0], event->ext[1]); 1473 + static void print_kevent64_structure(xtrace::String* log, const struct kevent64_s* event) { 1474 + print_kevent_common(log, event->filter, event->ident, event->flags, event->fflags, event->data, (void*)(uintptr_t)event->udata); 1475 + log->append_format(", ext[0] = 0x%llx, ext[1] = 0x%llx }", event->ext[0], event->ext[1]); 1466 1476 }; 1467 1477 1468 - static void print_kevent_qos_structure(const struct kevent_qos_s* event) { 1469 - print_kevent_common(event->filter, event->ident, event->flags, event->fflags, event->data, (void*)(uintptr_t)event->udata); 1470 - xtrace_log(", ext[0] = 0x%llx, ext[1] = 0x%llx, ext[2] = 0x%llx, ext[3] = 0x%llx, qos = %d, xflags = 0x%x }", event->ext[0], event->ext[1], event->ext[2], event->ext[3], event->qos, event->xflags); 1478 + static void print_kevent_qos_structure(xtrace::String* log, const struct kevent_qos_s* event) { 1479 + print_kevent_common(log, event->filter, event->ident, event->flags, event->fflags, event->data, (void*)(uintptr_t)event->udata); 1480 + log->append_format(", ext[0] = 0x%llx, ext[1] = 0x%llx, ext[2] = 0x%llx, ext[3] = 0x%llx, qos = %d, xflags = 0x%x }", event->ext[0], event->ext[1], event->ext[2], event->ext[3], event->qos, event->xflags); 1471 1481 }; 1472 1482 1473 1483 DEFINE_XTRACE_TLS_VAR(void*, kevent_stored_list, NULL, NULL); ··· 1480 1490 kevent_qos, 1481 1491 }; 1482 1492 1483 - static void print_kevent_return_common(int nr, uintptr_t rv, kevent_type type) { 1493 + static void print_kevent_return_common(xtrace::String* log, int nr, uintptr_t rv, kevent_type type) { 1484 1494 void* event_list; 1485 1495 int ret = (intptr_t)rv; 1486 1496 ··· 1500 1510 } 1501 1511 1502 1512 if (ret < 0) { 1503 - print_errno(nr, rv); 1513 + print_errno(log, nr, rv); 1504 1514 return; 1505 1515 } 1506 1516 1507 - xtrace_log("%d events {", ret); 1517 + log->append_format("%d events {", ret); 1508 1518 1509 1519 for (int i = 0; i < ret; ++i) { 1510 1520 if (i == 0) { 1511 - xtrace_log(" "); 1521 + log->append(" "); 1512 1522 } else { 1513 - xtrace_log(", "); 1523 + log->append(", "); 1514 1524 } 1515 1525 1516 1526 switch (type) { 1517 1527 case kevent_type::kevent: 1518 - print_kevent_structure(&((struct kevent*)event_list)[i]); 1528 + print_kevent_structure(log, &((struct kevent*)event_list)[i]); 1519 1529 break; 1520 1530 case kevent_type::kevent64: 1521 - print_kevent64_structure(&((struct kevent64_s*)event_list)[i]); 1531 + print_kevent64_structure(log, &((struct kevent64_s*)event_list)[i]); 1522 1532 break; 1523 1533 case kevent_type::kevent_qos: 1524 - print_kevent_qos_structure(&((struct kevent_qos_s*)event_list)[i]); 1534 + print_kevent_qos_structure(log, &((struct kevent_qos_s*)event_list)[i]); 1525 1535 break; 1526 1536 } 1527 1537 } 1528 1538 1529 - xtrace_log("%s}", ret > 0 ? " " : ""); 1539 + log->append_format("%s}", ret > 0 ? " " : ""); 1530 1540 }; 1531 1541 1532 - static void print_kevent_return(int nr, uintptr_t rv) { 1533 - print_kevent_return_common(nr, rv, kevent_type::kevent); 1542 + static void print_kevent_return(xtrace::String* log, int nr, uintptr_t rv) { 1543 + print_kevent_return_common(log, nr, rv, kevent_type::kevent); 1534 1544 }; 1535 1545 1536 - static void print_kevent_args(int nr, void* args[]) { 1546 + static void print_kevent_args(xtrace::String* log, int nr, void* args[]) { 1537 1547 int kq = (intptr_t)args[0]; 1538 1548 const struct kevent* change_list = (const struct kevent*)args[1]; 1539 1549 int nchanges = (intptr_t)args[2]; ··· 1543 1553 1544 1554 set_kevent_stored_list(event_list); 1545 1555 1546 - xtrace_log("%d, change_list = {", kq); 1556 + log->append_format("%d, change_list = {", kq); 1547 1557 1548 1558 for (int i = 0; i < nchanges; ++i) { 1549 1559 if (i == 0) { 1550 - xtrace_log(" "); 1560 + log->append(" "); 1551 1561 } else { 1552 - xtrace_log(", "); 1562 + log->append(", "); 1553 1563 } 1554 - print_kevent_structure(&change_list[i]); 1564 + print_kevent_structure(log, &change_list[i]); 1555 1565 } 1556 1566 1557 - xtrace_log("%s}, nchanges = %d, event_list = %p, nevents = %d, timeout = ", nchanges > 0 ? " " : "", nchanges, event_list, nevents); 1567 + log->append_format("%s}, nchanges = %d, event_list = %p, nevents = %d, timeout = ", nchanges > 0 ? " " : "", nchanges, event_list, nevents); 1558 1568 1559 - print_timespec(timeout); 1569 + print_timespec(log, timeout); 1560 1570 }; 1561 1571 1562 - static void print_kevent64_return(int nr, uintptr_t rv) { 1563 - print_kevent_return_common(nr, rv, kevent_type::kevent64); 1572 + static void print_kevent64_return(xtrace::String* log, int nr, uintptr_t rv) { 1573 + print_kevent_return_common(log, nr, rv, kevent_type::kevent64); 1564 1574 }; 1565 1575 1566 1576 static struct { ··· 1584 1594 #undef FLAG 1585 1595 }; 1586 1596 1587 - static void print_kevent64_args(int nr, void* args[]) { 1597 + static void print_kevent64_args(xtrace::String* log, int nr, void* args[]) { 1588 1598 int kq = (intptr_t)args[0]; 1589 1599 const struct kevent64_s* change_list = (const struct kevent64_s*)args[1]; 1590 1600 int nchanges = (intptr_t)args[2]; ··· 1596 1606 1597 1607 set_kevent64_stored_list(event_list); 1598 1608 1599 - xtrace_log("%d, change_list = {", kq); 1609 + log->append_format("%d, change_list = {", kq); 1600 1610 1601 1611 for (int i = 0; i < nchanges; ++i) { 1602 1612 if (i == 0) { 1603 - xtrace_log(" "); 1613 + log->append(" "); 1604 1614 } else { 1605 - xtrace_log(", "); 1615 + log->append(", "); 1606 1616 } 1607 - print_kevent64_structure(&change_list[i]); 1617 + print_kevent64_structure(log, &change_list[i]); 1608 1618 } 1609 1619 1610 - xtrace_log("%s}, nchanges = %d, event_list = %p, nevents = %d, flags = ", nchanges > 0 ? " " : "", nchanges, event_list, nevents); 1620 + log->append_format("%s}, nchanges = %d, event_list = %p, nevents = %d, flags = ", nchanges > 0 ? " " : "", nchanges, event_list, nevents); 1611 1621 1612 1622 for (size_t i = 0; i < sizeof(kevent_call_flags) / sizeof(*kevent_call_flags); ++i) { 1613 1623 if ((flags & kevent_call_flags[i].flag) == 0) { ··· 1617 1627 if (!printed_something) { 1618 1628 printed_something = true; 1619 1629 } else { 1620 - xtrace_log("|"); 1630 + log->append("|"); 1621 1631 } 1622 1632 1623 - xtrace_log("%s", kevent_call_flags[i].name); 1633 + log->append_format("%s", kevent_call_flags[i].name); 1624 1634 } 1625 1635 1626 1636 if (!printed_something) { 1627 - xtrace_log("0"); 1637 + log->append("0"); 1628 1638 } 1629 1639 1630 - xtrace_log(", timeout = "); 1640 + log->append(", timeout = "); 1631 1641 1632 - print_timespec(timeout); 1642 + print_timespec(log, timeout); 1633 1643 }; 1634 1644 1635 - static void print_kevent_qos_return(int nr, uintptr_t rv) { 1636 - print_kevent_return_common(nr, rv, kevent_type::kevent_qos); 1645 + static void print_kevent_qos_return(xtrace::String* log, int nr, uintptr_t rv) { 1646 + print_kevent_return_common(log, nr, rv, kevent_type::kevent_qos); 1637 1647 }; 1638 1648 1639 - static void print_kevent_qos_args(int nr, void* args[]) { 1649 + static void print_kevent_qos_args(xtrace::String* log, int nr, void* args[]) { 1640 1650 int kq = (intptr_t)args[0]; 1641 1651 const struct kevent_qos_s* change_list = (const struct kevent_qos_s*)args[1]; 1642 1652 int nchanges = (intptr_t)args[2]; ··· 1649 1659 1650 1660 set_kevent_qos_stored_list(event_list); 1651 1661 1652 - xtrace_log("%d, change_list = {", kq); 1662 + log->append_format("%d, change_list = {", kq); 1653 1663 1654 1664 for (int i = 0; i < nchanges; ++i) { 1655 1665 if (i == 0) { 1656 - xtrace_log(" "); 1666 + log->append(" "); 1657 1667 } else { 1658 - xtrace_log(", "); 1668 + log->append(", "); 1659 1669 } 1660 - print_kevent_qos_structure(&change_list[i]); 1670 + print_kevent_qos_structure(log, &change_list[i]); 1661 1671 } 1662 1672 1663 - xtrace_log("%s}, nchanges = %d, event_list = %p, nevents = %d, data_out = %p, data_available = %p (%ld), flags = ", nchanges > 0 ? " " : "", nchanges, event_list, nevents, data_out, data_available, data_available ? *data_available : 0); 1673 + log->append_format("%s}, nchanges = %d, event_list = %p, nevents = %d, data_out = %p, data_available = %p (%ld), flags = ", nchanges > 0 ? " " : "", nchanges, event_list, nevents, data_out, data_available, data_available ? *data_available : 0); 1664 1674 1665 1675 for (size_t i = 0; i < sizeof(kevent_call_flags) / sizeof(*kevent_call_flags); ++i) { 1666 1676 if ((flags & kevent_call_flags[i].flag) == 0) { ··· 1670 1680 if (!printed_something) { 1671 1681 printed_something = true; 1672 1682 } else { 1673 - xtrace_log("|"); 1683 + log->append("|"); 1674 1684 } 1675 1685 1676 - xtrace_log("%s", kevent_call_flags[i].name); 1686 + log->append_format("%s", kevent_call_flags[i].name); 1677 1687 } 1678 1688 1679 1689 if (!printed_something) { 1680 - xtrace_log("0"); 1690 + log->append("0"); 1681 1691 } 1682 1692 }; 1683 1693 1684 - static void print_timespec(const struct timespec* timespec) { 1694 + static void print_timespec(xtrace::String* log, const struct timespec* timespec) { 1685 1695 if (timespec) { 1686 - xtrace_log("(%ld s, %ld ns)", timespec->tv_sec, timespec->tv_nsec); 1696 + log->append_format("(%ld s, %ld ns)", timespec->tv_sec, timespec->tv_nsec); 1687 1697 } else { 1688 - xtrace_log("NULL"); 1698 + log->append("NULL"); 1689 1699 } 1690 1700 }; 1691 1701 1692 - static void print_timeval(const struct timeval* timeval) { 1702 + static void print_timeval(xtrace::String* log, struct timeval* timeval) { 1693 1703 if (timeval) { 1694 - xtrace_log("(%ld s, %d ns)", timeval->tv_sec, timeval->tv_usec); 1704 + log->append_format("(%ld s, %d ns)", timeval->tv_sec, timeval->tv_usec); 1695 1705 } else { 1696 - xtrace_log("NULL"); 1706 + log->append("NULL"); 1697 1707 } 1698 1708 }; 1699 1709 ··· 1706 1716 1707 1717 DEFINE_XTRACE_TLS_VAR(select_fdsets, stored_select_fdsets, ((struct select_fdsets){NULL, NULL, NULL, -1}), NULL); 1708 1718 1709 - static void print_fdset(const fd_set* set, int max_fd) { 1719 + static void print_fdset(xtrace::String* log, const fd_set* set, int max_fd) { 1710 1720 bool isFirst = true; 1711 - xtrace_log("{"); 1721 + log->append("{"); 1712 1722 if (set) { 1713 1723 for (size_t index = 0; index < sizeof(set->fds_bits) / sizeof(*set->fds_bits); ++index) { 1714 1724 bool shouldBreak = false; ··· 1721 1731 if ((set->fds_bits[index] & (1U << bit)) != 0) { 1722 1732 if (isFirst) { 1723 1733 isFirst = false; 1724 - xtrace_log(" "); 1734 + log->append(" "); 1725 1735 } else { 1726 - xtrace_log(", "); 1736 + log->append(", "); 1727 1737 } 1728 - xtrace_log("%d", fd); 1738 + log->append_format("%d", fd); 1729 1739 } 1730 1740 } 1731 1741 if (shouldBreak) { ··· 1734 1744 } 1735 1745 } 1736 1746 if (!isFirst) { 1737 - xtrace_log(" "); 1747 + log->append(" "); 1738 1748 } 1739 - xtrace_log("}"); 1749 + log->append("}"); 1740 1750 }; 1741 1751 1742 - static void print_select_return(int nr, uintptr_t rv) { 1752 + static void print_select_return(xtrace::String* log, int nr, uintptr_t rv) { 1743 1753 auto stored = get_ptr_stored_select_fdsets(); 1744 1754 int ret = (int)rv; 1745 1755 bool isFirst = true; 1746 1756 1747 1757 if (ret < 0) { 1748 - print_errno(nr, rv); 1758 + print_errno(log, nr, rv); 1749 1759 } else { 1750 - xtrace_log("%d descriptors: ", ret); 1760 + log->append_format("%d descriptors: ", ret); 1751 1761 1752 1762 if (stored->readfds) { 1753 1763 if (isFirst) { 1754 1764 isFirst = false; 1755 1765 } else { 1756 - xtrace_log(", "); 1766 + log->append(", "); 1757 1767 } 1758 - xtrace_log("read "); 1759 - print_fdset(stored->readfds, stored->max_fd); 1768 + log->append("read "); 1769 + print_fdset(log, stored->readfds, stored->max_fd); 1760 1770 } 1761 1771 1762 1772 if (stored->writefds) { 1763 1773 if (isFirst) { 1764 1774 isFirst = false; 1765 1775 } else { 1766 - xtrace_log(", "); 1776 + log->append(", "); 1767 1777 } 1768 - xtrace_log("write "); 1769 - print_fdset(stored->writefds, stored->max_fd); 1778 + log->append("write "); 1779 + print_fdset(log, stored->writefds, stored->max_fd); 1770 1780 } 1771 1781 1772 1782 if (stored->exceptfds) { 1773 1783 if (isFirst) { 1774 1784 isFirst = false; 1775 1785 } else { 1776 - xtrace_log(", "); 1786 + log->append(", "); 1777 1787 } 1778 - xtrace_log("except "); 1779 - print_fdset(stored->exceptfds, stored->max_fd); 1788 + log->append("except "); 1789 + print_fdset(log, stored->exceptfds, stored->max_fd); 1780 1790 } 1781 1791 } 1782 1792 ··· 1786 1796 stored->max_fd = -1; 1787 1797 }; 1788 1798 1789 - static void print_select_args(int nr, void* args[]) { 1799 + static void print_select_args(xtrace::String* log, int nr, void* args[]) { 1790 1800 auto stored = get_ptr_stored_select_fdsets(); 1791 1801 1792 1802 int nfds = (intptr_t)args[0]; ··· 1795 1805 fd_set* exceptfds = (fd_set*)args[3]; 1796 1806 struct timeval* timeout = (struct timeval*)args[4]; 1797 1807 1798 - xtrace_log("nfds = %d, readfds = ", nfds); 1799 - print_fdset(readfds, nfds); 1800 - xtrace_log(", writefds = "); 1801 - print_fdset(writefds, nfds); 1802 - xtrace_log(", exceptfds = "); 1803 - print_fdset(exceptfds, nfds); 1804 - xtrace_log(", timeout = "); 1805 - print_timeval(timeout); 1808 + log->append_format("nfds = %d, readfds = ", nfds); 1809 + print_fdset(log, readfds, nfds); 1810 + log->append(", writefds = "); 1811 + print_fdset(log, writefds, nfds); 1812 + log->append(", exceptfds = "); 1813 + print_fdset(log, exceptfds, nfds); 1814 + log->append(", timeout = "); 1815 + print_timeval(log, timeout); 1806 1816 1807 1817 stored->readfds = readfds; 1808 1818 stored->writefds = writefds;
+5 -5
src/xtrace/bsd_trace.h
··· 2 2 #define XTRACE_BSD_TRACE 3 3 4 4 #include "base.h" 5 - 6 - XTRACE_DECLARATIONS_C_BEGIN 7 - 8 - extern void xtrace_print_string_literal(const char* str); 5 + #include "string.h" 9 6 10 - XTRACE_DECLARATIONS_C_END 7 + #ifdef XTRACE_CPP 8 + extern void print_open_flags(xtrace::String* log, void* arg); 9 + extern void xtrace_print_string_literal(xtrace::String* log, const char* str); 10 + #endif 11 11 12 12 #endif // XTRACE_BSD_TRACE
+23 -14
src/xtrace/include/xtrace/xtrace-mig-types.h
··· 2 2 #define XTRACE_XTRACE_MIG_TYPES 3 3 4 4 #include <mach/message.h> 5 - 6 - #include "../base.h" 5 + #include "../../string.h" 6 + #include "../../base.h" 7 7 8 8 XTRACE_DECLARATIONS_C_BEGIN 9 9 10 10 struct xtrace_mig_callbacks { 11 - void (*add_raw_arg)(const char *format, ...) __attribute__((format(printf, 1, 2))); 12 - void (*add_num_arg)(unsigned long long n); 13 - void (*add_ptr_arg)(void *ptr); 14 - void (*add_string_arg)(const char *s); 15 - void (*add_bytes_arg)(const void *bytes, unsigned long cnt); 16 - void (*add_return_code_arg)(kern_return_t code); 17 - void (*add_port_arg)(mach_port_name_t port_name, mach_msg_type_name_t disposition); 18 - void (*add_ool_mem_arg)(const void *ptr, unsigned long size); 19 - void (*add_ool_ports_arg)(const void *ptr, unsigned long cnt, mach_msg_type_name_t disposition); 20 - void (*add_struct_arg)(const void *ptr, unsigned long cnt, unsigned long item_size); 21 - void (*add_array_arg)(const void *ptr, unsigned long cnt, unsigned long item_size); 11 + void (*add_raw_arg)(xtrace_string_t log, const char *format, ...) __attribute__((format(printf, 2, 3))); 12 + void (*add_num_arg)(xtrace_string_t log, unsigned long long n); 13 + void (*add_ptr_arg)(xtrace_string_t log, void *ptr); 14 + void (*add_string_arg)(xtrace_string_t log, const char *s); 15 + void (*add_bytes_arg)(xtrace_string_t log, const void *bytes, unsigned long cnt); 16 + void (*add_return_code_arg)(xtrace_string_t log, kern_return_t code); 17 + void (*add_port_arg)(xtrace_string_t log, mach_port_name_t port_name, mach_msg_type_name_t disposition); 18 + void (*add_ool_mem_arg)(xtrace_string_t log, const void *ptr, unsigned long size); 19 + void (*add_ool_ports_arg)(xtrace_string_t log, const void *ptr, unsigned long cnt, mach_msg_type_name_t disposition); 20 + void (*add_struct_arg)(xtrace_string_t log, const void *ptr, unsigned long cnt, unsigned long item_size); 21 + void (*add_array_arg)(xtrace_string_t log, const void *ptr, unsigned long cnt, unsigned long item_size); 22 + 23 + void (*set_return_code)(xtrace_string_t log, kern_return_t code); 24 + 25 + // String Functions 26 + xtrace_string_t (*xtrace_string_construct)(void); 27 + void (*xtrace_string_destruct)(xtrace_string_t obj); 28 + void (*xtrace_string_clear)(xtrace_string_t obj); 29 + const char* (*xtrace_string_c_str)(xtrace_string_t obj); 22 30 23 - void (*set_return_code)(kern_return_t code); 31 + // Logging Functions 32 + void (*xtrace_log)(const char* format, ...); 24 33 }; 25 34 26 35 typedef void xtrace_mig_routine(
+106 -89
src/xtrace/mach_trace.cpp
··· 12 12 #include "mach_trace.h" 13 13 #include "mig_trace.h" 14 14 #include "tls.h" 15 + #include "string.h" 15 16 16 17 DEFINE_XTRACE_TLS_VAR(int, mach_call_nr, -1, NULL); 17 18 DEFINE_XTRACE_TLS_VAR(void*, argument_ptr, NULL, NULL); 18 19 DEFINE_XTRACE_TLS_VAR(mach_port_name_t, request_port, MACH_PORT_NULL, NULL); 19 20 20 - static void print_kern_return(int nr, uintptr_t rv); 21 - static void print_port_return(int nr, uintptr_t rv); 22 - static void print_int_return(int nr, uintptr_t rv); 23 - static void print_empty(int nr, void* args[]); 24 - static void print_port_ptr_return(int nr, uintptr_t rv); 21 + static void print_kern_return(xtrace::String* log, int nr, uintptr_t rv); 22 + static void print_port_return(xtrace::String* log, int nr, uintptr_t rv); 23 + static void print_int_return(xtrace::String* log, int nr, uintptr_t rv); 24 + static void print_empty(xtrace::String* log, int nr, void* args[]); 25 + static void print_port_ptr_return(xtrace::String* log, int nr, uintptr_t rv); 25 26 26 - static void print_mach_msg_args(int nr, void* args[]); 27 - static void print_mach_port_insert_right_args(int nr, void* args[]); 27 + static void print_mach_msg_args(xtrace::String* log, int nr, void* args[]); 28 + static void print_mach_port_insert_right_args(xtrace::String* log, int nr, void* args[]); 28 29 29 - static void print_mach_port_member_args(int nr, void* args[]); 30 + static void print_mach_port_member_args(xtrace::String* log, int nr, void* args[]); 30 31 31 - static void print_mach_timebase_info_args(int nr, void* args[]); 32 - static void print_mach_timebase_info_res(int nr, uintptr_t rv); 32 + static void print_mach_timebase_info_args(xtrace::String* log, int nr, void* args[]); 33 + static void print_mach_timebase_info_res(xtrace::String* log, int nr, uintptr_t rv); 33 34 34 - static void print_mach_port_allocate_args(int nr, void* args[]); 35 - static void print_task_for_pid_args(int nr, void* args[]); 35 + static void print_mach_port_allocate_args(xtrace::String* log, int nr, void* args[]); 36 + static void print_task_for_pid_args(xtrace::String* log, int nr, void* args[]); 36 37 37 - static void print_pid_for_task_args(int nr, void* args[]); 38 - static void print_pid_for_task_res(int nr, uintptr_t rv); 38 + static void print_pid_for_task_args(xtrace::String* log, int nr, void* args[]); 39 + static void print_pid_for_task_res(xtrace::String* log, int nr, uintptr_t rv); 39 40 40 - static void print_mach_msg_entry(void* args[]); 41 - static void print_mach_msg_exit(void); 41 + static void print_mach_msg_entry(xtrace::String* log, void* args[]); 42 + static void print_mach_msg_exit(xtrace::String* log); 42 43 43 44 static const struct calldef mach_defs[128] = { 44 45 [10] = { "_kernelrpc_mach_vm_allocate_trap", NULL, print_kern_return }, ··· 47 48 [15] = { "_kernelrpc_mach_vm_map_trap", NULL, print_kern_return }, 48 49 [16] = { "_kernelrpc_mach_port_allocate_trap", print_mach_port_allocate_args, print_port_ptr_return }, 49 50 [17] = { "_kernelrpc_mach_port_destroy_trap", NULL, print_kern_return }, 50 - [18] = { "_kernelrpc_mach_port_deallocate_trap", [](int nr, void* args[]) { xtrace_log("task %u, port name %u", (unsigned int) (unsigned long) args[0], (unsigned int) (unsigned long) args[1]); }, print_kern_return }, 51 + [18] = { "_kernelrpc_mach_port_deallocate_trap", [](xtrace::String* log, int nr, void* args[]) { log->append_format("task %u, port name %u", (unsigned int) (unsigned long) args[0], (unsigned int) (unsigned long) args[1]); }, print_kern_return }, 51 52 [19] = { "_kernelrpc_mach_port_mod_refs_trap", NULL, print_kern_return }, 52 53 [20] = { "_kernelrpc_mach_port_move_member_trap", print_mach_port_member_args, print_kern_return }, 53 54 [21] = { "_kernelrpc_mach_port_insert_right_trap", print_mach_port_insert_right_args, print_kern_return }, ··· 209 210 extern "C" 210 211 void darling_mach_syscall_entry_print(int nr, void* args[]) 211 212 { 213 + xtrace::String log; 212 214 #if __i386__ 213 215 // get rid of some info in the upper bytes that we don't need 214 216 nr = (int)((unsigned int)nr & 0xffff); 215 217 #endif 216 218 217 219 set_mach_call_nr(nr); 218 - handle_generic_entry(mach_defs, "mach", nr, args); 220 + handle_generic_entry(&log, mach_defs, "mach", nr, args); 219 221 if (nr == 31 || nr == 32) 220 - print_mach_msg_entry(args); 222 + print_mach_msg_entry(&log, args); 223 + 224 + if (log.size() > 0) { 225 + xtrace_log("%s", log.c_str()); 226 + log.clear(); 227 + } 221 228 } 222 229 223 230 extern "C" 224 231 void darling_mach_syscall_exit_print(uintptr_t retval) 225 232 { 233 + xtrace::String log; 226 234 int nr = get_mach_call_nr(); 227 235 int is_msg = nr == 31 || nr == 32; 228 - handle_generic_exit(mach_defs, "mach", retval, is_msg); 236 + handle_generic_exit(&log, mach_defs, "mach", retval, is_msg); 229 237 if (retval == KERN_SUCCESS && is_msg) 230 - print_mach_msg_exit(); 238 + print_mach_msg_exit(&log); 231 239 set_mach_call_nr(-1); 240 + 241 + if (log.size() > 0) { 242 + xtrace_log("%s", log.c_str()); 243 + log.clear(); 244 + } 232 245 } 233 246 234 - void xtrace_print_kern_return(kern_return_t kr) 247 + void xtrace_print_kern_return(xtrace::String* log, kern_return_t kr) 235 248 { 236 249 if (kr >= MACH_RCV_IN_PROGRESS && kr <= MACH_RCV_INVALID_TRAILER) 237 - xtrace_log("%s", mach_rcv_errors[kr - MACH_RCV_IN_PROGRESS]); 250 + log->append_format("%s", mach_rcv_errors[kr - MACH_RCV_IN_PROGRESS]); 238 251 else if (kr >= MACH_SEND_IN_PROGRESS && kr <= MACH_SEND_INVALID_TRAILER) 239 - xtrace_log("%s", mach_send_errors[kr - MACH_SEND_IN_PROGRESS]); 252 + log->append_format("%s", mach_send_errors[kr - MACH_SEND_IN_PROGRESS]); 240 253 else if (kr >= KERN_SUCCESS && kr <= KERN_INSUFFICIENT_BUFFER_SIZE) 241 - xtrace_log("%s", kern_return_values[kr]); 254 + log->append_format("%s", kern_return_values[kr]); 242 255 else if (kr >= BOOTSTRAP_NOT_PRIVILEGED && kr <= BOOTSTRAP_NO_CHILDREN) 243 - xtrace_log("%s", bootstrap_errors[kr - BOOTSTRAP_NOT_PRIVILEGED]); 256 + log->append_format("%s", bootstrap_errors[kr - BOOTSTRAP_NOT_PRIVILEGED]); 244 257 else if (kr <= MIG_TYPE_ERROR && kr >= MIG_TRAILER_ERROR) 245 - xtrace_log("%s", mig_errors[MIG_TYPE_ERROR - kr]); 258 + log->append_format("%s", mig_errors[MIG_TYPE_ERROR - kr]); 246 259 else 247 - xtrace_log("(kern_return_t) %x", kr); 260 + log->append_format("(kern_return_t) %x", kr); 248 261 } 249 262 250 - static void print_kern_return(int nr, uintptr_t rv) 263 + static void print_kern_return(xtrace::String* log, int nr, uintptr_t rv) 251 264 { 252 - xtrace_print_kern_return((kern_return_t) rv); 265 + xtrace_print_kern_return(log, (kern_return_t) rv); 253 266 } 254 267 255 - static void print_port_return(int nr, uintptr_t rv) 268 + static void print_port_return(xtrace::String* log, int nr, uintptr_t rv) 256 269 { 257 - xtrace_log("port right %d", (unsigned int) (unsigned long) rv); 270 + log->append_format("port right %d", (unsigned int) (unsigned long) rv); 258 271 } 259 272 260 - static void print_int_return(char* buf, int nr, uintptr_t rv) 273 + static void print_int_return(xtrace::String* log, char* buf, int nr, uintptr_t rv) 261 274 { 262 - xtrace_log("%d", (int) (long) rv); 275 + log->append_format("%d", (int) (long) rv); 263 276 } 264 277 265 - static void print_empty(int nr, void* args[]) 278 + static void print_empty(xtrace::String* log, int nr, void* args[]) 266 279 { 267 280 268 281 } 269 282 270 - static void print_port_ptr_return(int nr, uintptr_t rv) 283 + static void print_port_ptr_return(xtrace::String* log, int nr, uintptr_t rv) 271 284 { 272 285 if (rv != KERN_SUCCESS) 273 286 { 274 - print_kern_return(nr, rv); 287 + print_kern_return(log, nr, rv); 275 288 set_argument_ptr(NULL); 276 289 return; 277 290 } ··· 279 292 { 280 293 return; 281 294 } 282 - xtrace_log("port right %d", *(mach_port_name_t*)get_argument_ptr()); 295 + log->append_format("port right %d", *(mach_port_name_t*)get_argument_ptr()); 283 296 set_argument_ptr(NULL); 284 297 } 285 298 ··· 293 306 "MACH_PORT_RIGHT_NUMBER" 294 307 }; 295 308 296 - static void print_mach_port_allocate_args(int nr, void* args[]) 309 + static void print_mach_port_allocate_args(xtrace::String* log, int nr, void* args[]) 297 310 { 298 311 mach_port_name_t target = (mach_port_name_t) (long) args[0]; 299 312 mach_port_right_t right = (mach_port_right_t) (long) args[1]; ··· 305 318 else 306 319 right_name = port_right_names[right]; 307 320 308 - xtrace_log("task %d, %s", target, right_name); 321 + log->append_format("task %d, %s", target, right_name); 309 322 } 310 323 311 324 static const char* const port_dispositions[] = { ··· 322 335 "MACH_MSG_TYPE_DISPOSE_SEND_ONCE" 323 336 }; 324 337 325 - static void print_mach_port_insert_right_args(int nr, void* args[]) 338 + static void print_mach_port_insert_right_args(xtrace::String* log, int nr, void* args[]) 326 339 { 327 340 mach_port_name_t target = (mach_port_name_t) (long) args[0]; 328 341 mach_port_name_t name = (mach_port_name_t) (long) args[1]; ··· 335 348 else 336 349 disp = port_dispositions[disposition - MACH_MSG_TYPE_PORT_NAME]; 337 350 338 - xtrace_log("task %d, new name %d, port right %d, %s", target, name, right, disp); 351 + log->append_format("task %d, new name %d, port right %d, %s", target, name, right, disp); 339 352 } 340 353 341 - static void print_mach_port_member_args(int nr, void* args[]) 354 + static void print_mach_port_member_args(xtrace::String* log, int nr, void* args[]) 342 355 { 343 356 mach_port_name_t target = (mach_port_name_t) (long) args[0]; 344 357 mach_port_name_t name = (mach_port_name_t) (long) args[1]; 345 358 mach_port_name_t pset = (mach_port_name_t) (long) args[2]; 346 359 347 - xtrace_log("task %d, port right %d, port set %d", target, name, pset); 360 + log->append_format("task %d, port right %d, port set %d", target, name, pset); 348 361 } 349 362 350 - static void print_mach_timebase_info_args(int nr, void* args[]) 363 + static void print_mach_timebase_info_args(xtrace::String* log, int nr, void* args[]) 351 364 { 352 365 set_argument_ptr(args[0]); 353 366 if (get_argument_ptr() == NULL) 354 - xtrace_log("NULL"); 367 + log->append("NULL"); 355 368 } 356 369 357 - static void print_mach_timebase_info_res(int nr, uintptr_t rv) 370 + static void print_mach_timebase_info_res(xtrace::String* log, int nr, uintptr_t rv) 358 371 { 359 372 if (rv != KERN_SUCCESS) 360 373 { 361 - print_kern_return(nr, rv); 374 + print_kern_return(log, nr, rv); 362 375 set_argument_ptr(NULL); 363 376 return; 364 377 } 365 378 if (get_argument_ptr() != NULL) 366 379 { 367 380 mach_timebase_info_t timebase = (mach_timebase_info_t)get_argument_ptr(); 368 - xtrace_log("numer = %d, denom = %d", timebase->numer, timebase->denom); 381 + log->append_format("numer = %d, denom = %d", timebase->numer, timebase->denom); 369 382 } 370 383 371 384 set_argument_ptr(NULL); 372 385 } 373 386 374 - static void print_task_for_pid_args(int nr, void* args[]) 387 + static void print_task_for_pid_args(xtrace::String* log, int nr, void* args[]) 375 388 { 376 389 mach_port_name_t target = (mach_port_name_t) (long) args[0]; 377 390 int pid = (int) (long) args[1]; 378 391 set_argument_ptr(args[2]); 379 392 380 - xtrace_log("task %d, pid %d", target, pid); 393 + log->append_format("task %d, pid %d", target, pid); 381 394 } 382 395 383 - static void print_pid_for_task_args(int nr, void* args[]) 396 + static void print_pid_for_task_args(xtrace::String* log, int nr, void* args[]) 384 397 { 385 398 mach_port_name_t task = (mach_port_name_t) (long) args[0]; 386 399 set_argument_ptr(args[1]); 387 400 388 - xtrace_log("task %d", task); 401 + log->append_format("task %d", task); 389 402 } 390 403 391 - static void print_pid_for_task_res(int nr, uintptr_t rv) 404 + static void print_pid_for_task_res(xtrace::String* log, int nr, uintptr_t rv) 392 405 { 393 406 if (rv != KERN_SUCCESS) 394 407 { 395 - print_kern_return(nr, rv); 408 + print_kern_return(log, nr, rv); 396 409 set_argument_ptr(NULL); 397 410 return; 398 411 } 399 412 if (get_argument_ptr() != NULL) 400 - xtrace_log("pid %d", * (int*)get_argument_ptr()); 413 + log->append_format("pid %d", * (int*)get_argument_ptr()); 401 414 402 415 set_argument_ptr(NULL); 403 416 } ··· 423 436 } 424 437 } 425 438 426 - static void print_mach_msg(const mach_msg_header_t* msg, mach_msg_size_t size) 439 + static void print_mach_msg(xtrace::String* log, const mach_msg_header_t* msg, mach_msg_size_t size) 427 440 { 428 - xtrace_log("{"); 441 + log->append("{"); 429 442 430 443 mach_msg_bits_t bits = msg->msgh_bits; 431 444 if (MACH_MSGH_BITS_HAS_REMOTE(bits)) 432 - xtrace_log("remote = %s %u, ", xtrace_msg_type_to_str(MACH_MSGH_BITS_REMOTE(bits), 0), msg->msgh_remote_port); 445 + log->append_format("remote = %s %u, ", xtrace_msg_type_to_str(MACH_MSGH_BITS_REMOTE(bits), 0), msg->msgh_remote_port); 433 446 if (MACH_MSGH_BITS_HAS_LOCAL(bits)) 434 - xtrace_log("local = %s %u, ", xtrace_msg_type_to_str(MACH_MSGH_BITS_LOCAL(bits), 0), msg->msgh_local_port); 447 + log->append_format("local = %s %u, ", xtrace_msg_type_to_str(MACH_MSGH_BITS_LOCAL(bits), 0), msg->msgh_local_port); 435 448 if (MACH_MSGH_BITS_HAS_VOUCHER(bits)) 436 - xtrace_log("voucher = %s %u, ", xtrace_msg_type_to_str(MACH_MSGH_BITS_VOUCHER(bits), 0), msg->msgh_voucher_port); 449 + log->append_format("voucher = %s %u, ", xtrace_msg_type_to_str(MACH_MSGH_BITS_VOUCHER(bits), 0), msg->msgh_voucher_port); 437 450 if (MACH_MSGH_BITS_IS_COMPLEX(bits)) 438 - xtrace_log("complex, "); 451 + log->append("complex, "); 439 452 440 - xtrace_log("id = %d}", msg->msgh_id); 453 + log->append_format("id = %d}", msg->msgh_id); 441 454 442 455 if (!MACH_MSGH_BITS_IS_COMPLEX(bits)) 443 456 { 444 - xtrace_log(", %lu bytes of inline data\n", size - sizeof(mach_msg_header_t)); 457 + log->append_format(", %lu bytes of inline data", size - sizeof(mach_msg_header_t)); 458 + xtrace_log("%s\n", log->c_str()); 459 + log->clear(); 445 460 return; 446 461 } 447 462 ··· 454 469 if (type == MACH_MSG_PORT_DESCRIPTOR) 455 470 { 456 471 mach_msg_port_descriptor_t* port = (mach_msg_port_descriptor_t*) ptr; 457 - xtrace_log(", %s %u", xtrace_msg_type_to_str(port->disposition, 0), port->name); 472 + log->append_format(", %s %u", xtrace_msg_type_to_str(port->disposition, 0), port->name); 458 473 ptr = (mach_msg_descriptor_t*) (port + 1); 459 474 } 460 475 else if (type == MACH_MSG_OOL_DESCRIPTOR || type == MACH_MSG_OOL_VOLATILE_DESCRIPTOR) 461 476 { 462 477 mach_msg_ool_descriptor_t* ool = (mach_msg_ool_descriptor_t*) ptr; 463 - xtrace_log(", ool [%p; %u]", ool->address, ool->size); 478 + log->append_format(", ool [%p; %u]", ool->address, ool->size); 464 479 ptr = (mach_msg_descriptor_t*) (ool + 1); 465 480 } 466 481 else if (type == MACH_MSG_OOL_PORTS_DESCRIPTOR) 467 482 { 468 483 mach_msg_ool_ports_descriptor_t* ool_ports = (mach_msg_ool_ports_descriptor_t*) ptr; 469 - xtrace_log(", ool ports %s [%p; x%u]", 484 + log->append_format(", ool ports %s [%p; x%u]", 470 485 xtrace_msg_type_to_str(ool_ports->disposition, 0), 471 486 ool_ports->address, ool_ports->count); 472 487 ptr = (mach_msg_descriptor_t*) (ool_ports + 1); 473 488 } 474 489 else 475 490 { 476 - xtrace_log(", ???"); 491 + log->append(", ???"); 477 492 ptr++; 478 493 } 479 494 } 480 495 481 - xtrace_log(", %lu bytes of inline data\n", size - ((const char*) ptr - (const char*) msg)); 496 + log->append_format(", %lu bytes of inline data", size - ((const char*) ptr - (const char*) msg)); 497 + xtrace_log("%s\n", log->c_str()); 498 + log->clear(); 482 499 } 483 500 484 - static void print_mach_msg_entry(void* args[]) 501 + static void print_mach_msg_entry(xtrace::String* log, void* args[]) 485 502 { 486 503 const mach_msg_header_t* message = (const mach_msg_header_t*) args[0]; 487 504 mach_msg_option_t options = (mach_msg_option_t) (long) args[1]; ··· 490 507 if (options & MACH_SEND_MSG) 491 508 { 492 509 set_request_port(message->msgh_remote_port); 493 - xtrace_log("\n"); 494 - xtrace_start_line(8); 495 - print_mach_msg(message, send_size); 496 - xtrace_start_line(8); 497 - xtrace_print_mig_message(message, get_request_port()); 498 - xtrace_log("\n"); 510 + xtrace_log("%s\n", log->c_str()); log->clear(); 511 + xtrace_start_line(log, 8); 512 + print_mach_msg(log, message, send_size); 513 + xtrace_start_line(log, 8); 514 + xtrace_print_mig_message(log, message, get_request_port()); 515 + xtrace_log("%s\n", log->c_str()); log->clear(); 499 516 } 500 517 501 518 if (options & MACH_RCV_MSG) ··· 513 530 set_argument_ptr(args[0]); 514 531 break; 515 532 default: 516 - xtrace_log("Unexpected mach_call_nr"); 533 + log->append("Unexpected mach_call_nr"); 517 534 return; 518 535 } 519 536 } 520 537 } 521 538 522 - static void print_mach_msg_exit() 539 + static void print_mach_msg_exit(xtrace::String* log) 523 540 { 524 541 if (get_argument_ptr() == NULL) 525 542 return; 526 543 527 544 const mach_msg_header_t* message = (const mach_msg_header_t*)get_argument_ptr(); 528 - xtrace_start_line(8); 529 - print_mach_msg(message, message->msgh_size); 530 - xtrace_start_line(8); 531 - xtrace_print_mig_message(message, get_request_port()); 532 - xtrace_log("\n"); 545 + xtrace_start_line(log, 8); 546 + print_mach_msg(log, message, message->msgh_size); 547 + xtrace_start_line(log, 8); 548 + xtrace_print_mig_message(log, message, get_request_port()); 549 + xtrace_log("%s\n", log->c_str()); log->clear(); 533 550 set_argument_ptr(NULL); 534 551 set_request_port(MACH_PORT_NULL); 535 552 } 536 553 537 - static void print_mach_msg_args(int nr, void* args[]) 554 + static void print_mach_msg_args(xtrace::String* log, int nr, void* args[]) 538 555 { 539 556 mach_msg_header_t* msg = (mach_msg_header_t*) args[0]; 540 557 mach_msg_option_t options = (mach_msg_option_t) (unsigned long) args[1]; ··· 544 561 mach_msg_timeout_t timeout = (mach_msg_timeout_t) (unsigned long) args[5]; 545 562 mach_port_name_t notify = (mach_port_name_t) (unsigned long) args[6]; 546 563 547 - xtrace_log("%p, ", msg); 564 + log->append_format("%p, ", msg); 548 565 549 566 int options_cnt = 0; 550 567 551 568 #define OPTION(OPT) if (options & OPT) \ 552 569 { \ 553 570 if (options_cnt > 0) \ 554 - xtrace_log("|"); \ 555 - xtrace_log(#OPT); \ 571 + log->append("|"); \ 572 + log->append(#OPT); \ 556 573 options_cnt++; \ 557 574 } 558 575 ··· 577 594 #undef OPTION 578 595 579 596 if (options_cnt == 0) 580 - xtrace_log("MACH_MSG_OPTION_NONE"); 597 + log->append("MACH_MSG_OPTION_NONE"); 581 598 582 - xtrace_log(", %d, %d, port %d, %d, port %d", send_size, rcv_size, rcv_name, timeout, notify); 599 + log->append_format(", %d, %d, port %d, %d, port %d", send_size, rcv_size, rcv_name, timeout, notify); 583 600 }
+4 -3
src/xtrace/mach_trace.h
··· 3 3 4 4 #include "base.h" 5 5 6 + #ifdef XTRACE_CPP 7 + void xtrace_print_kern_return(xtrace::String* log, kern_return_t kr); 8 + #endif 9 + 6 10 XTRACE_DECLARATIONS_C_BEGIN 7 - 8 11 const char* xtrace_msg_type_to_str(mach_msg_type_name_t type_name, int full); 9 - void xtrace_print_kern_return(kern_return_t kr); 10 - 11 12 XTRACE_DECLARATIONS_C_END 12 13 13 14 #endif // XTRACE_MACH_TRACE
+62 -43
src/xtrace/mig_trace.cpp
··· 14 14 #include "bsd_trace.h" 15 15 #include "xtrace/xtrace-mig-types.h" 16 16 #include "tls.h" 17 + #include "string.h" 17 18 18 19 #define XTRACE_MIG_DIR_PATH "/usr/lib/darling/xtrace-mig" 19 20 ··· 80 81 81 82 DEFINE_XTRACE_TLS_VAR(bool, is_first_arg, false, NULL); 82 83 83 - #define BEFORE if (!get_is_first_arg()) xtrace_log(", ") 84 + #define BEFORE if (!get_is_first_arg()) xtrace_string_append_c_string(log, ", ") 84 85 #define AFTER set_is_first_arg(false) 85 86 86 - static void add_raw_arg(const char* format, ...) 87 + XTRACE_HIDDEN extern "C" 88 + void add_raw_arg(xtrace_string_t log, const char* format, ...) 87 89 { 88 90 va_list vl; 89 91 va_start(vl, format); 90 92 91 93 BEFORE; 92 - char buf[100]; 93 - __simple_vsprintf(buf, format, vl); 94 + xtrace_string_append_format_valist(log, format, vl); 94 95 AFTER; 95 96 96 97 va_end(vl); 97 98 } 98 99 99 - static void add_num_arg(unsigned long long n) 100 + XTRACE_HIDDEN extern "C" 101 + void add_num_arg(xtrace_string_t log, unsigned long long n) 100 102 { 101 103 BEFORE; 102 - xtrace_log("%llu", n); 104 + xtrace_string_append_format(log, "%llu", n); 103 105 AFTER; 104 106 } 105 107 106 - static void add_ptr_arg(void* ptr) 108 + XTRACE_HIDDEN extern "C" 109 + void add_ptr_arg(xtrace_string_t log, void* ptr) 107 110 { 108 111 BEFORE; 109 - xtrace_log("%p", ptr); 112 + xtrace_string_append_format(log, "%p", ptr); 110 113 AFTER; 111 114 } 112 115 113 - static void add_string_arg(const char* s) 116 + XTRACE_HIDDEN extern "C" 117 + void add_string_arg(xtrace_string_t log, const char* s) 114 118 { 115 119 BEFORE; 116 - xtrace_print_string_literal(s); 120 + xtrace_print_string_literal(xtrace::String::to_cxx_ptr(log), s); 117 121 AFTER; 118 122 } 119 123 120 - static void add_bytes_arg(const void* bytes, unsigned long cnt) 124 + XTRACE_HIDDEN extern "C" 125 + void add_bytes_arg(xtrace_string_t log, const void* bytes, unsigned long cnt) 121 126 { 122 127 BEFORE; 123 128 const unsigned char* b = (const unsigned char*) bytes; 124 - xtrace_log("bytes "); 129 + xtrace_string_append_c_string(log, "bytes "); 125 130 for (int i = 0; i < cnt; i++) 126 - xtrace_log("%x", b[i]); 131 + xtrace_string_append_format(log, "%x", b[i]); 127 132 AFTER; 128 133 } 129 134 130 - static void add_return_code_arg(kern_return_t code) 135 + XTRACE_HIDDEN extern "C" 136 + void add_return_code_arg(xtrace_string_t log, kern_return_t code) 131 137 { 132 138 BEFORE; 133 - xtrace_print_kern_return(code); 139 + xtrace_print_kern_return(xtrace::String::to_cxx_ptr(log), code); 134 140 AFTER; 135 141 } 136 142 137 - static void add_port_arg(mach_port_name_t port_name, mach_msg_type_name_t disposition) 143 + XTRACE_HIDDEN extern "C" 144 + void add_port_arg(xtrace_string_t log, mach_port_name_t port_name, mach_msg_type_name_t disposition) 138 145 { 139 146 BEFORE; 140 - xtrace_log("%s %u", xtrace_msg_type_to_str(disposition, 0), port_name); 147 + xtrace_string_append_format(log, "%s %u", xtrace_msg_type_to_str(disposition, 0), port_name); 141 148 AFTER; 142 149 } 143 150 144 - static void add_ool_mem_arg(const void* ptr, unsigned long size) 151 + XTRACE_HIDDEN extern "C" 152 + void add_ool_mem_arg(xtrace_string_t log, const void* ptr, unsigned long size) 145 153 { 146 154 BEFORE; 147 - xtrace_log("mem [%p; %lu]", ptr, size); 155 + xtrace_string_append_format(log, "mem [%p; %lu]", ptr, size); 148 156 AFTER; 149 157 } 150 158 151 - static void add_ool_ports_arg(const void* ptr, unsigned long cnt, mach_msg_type_name_t disposition) 159 + XTRACE_HIDDEN extern "C" 160 + void add_ool_ports_arg(xtrace_string_t log, const void* ptr, unsigned long cnt, mach_msg_type_name_t disposition) 152 161 { 153 162 BEFORE; 154 - xtrace_log("%s [%p; x%lu]", xtrace_msg_type_to_str(disposition, 0), ptr, cnt); 163 + xtrace_string_append_format(log, "%s [%p; x%lu]", xtrace_msg_type_to_str(disposition, 0), ptr, cnt); 155 164 AFTER; 156 165 } 157 166 ··· 176 185 } 177 186 } 178 187 179 - static void add_struct_arg(const void* ptr, unsigned long cnt, unsigned long item_size) 188 + XTRACE_HIDDEN extern "C" 189 + void add_struct_arg(xtrace_string_t log, const void* ptr, unsigned long cnt, unsigned long item_size) 180 190 { 181 191 BEFORE; 182 192 unsigned char* p = (unsigned char*) ptr; 183 - xtrace_log("{"); 193 + xtrace_string_append_c_string(log, "{"); 184 194 for (unsigned long i = 0; i < cnt; i++) 185 195 { 186 196 if (i != 0) 187 - xtrace_log(", "); 188 - xtrace_log("%llu", read_integer((void*) p, item_size)); 197 + xtrace_string_append_c_string(log, ", "); 198 + xtrace_string_append_format(log, "%llu", read_integer((void*) p, item_size)); 189 199 p += item_size; 190 200 } 191 - xtrace_log("}"); 201 + xtrace_string_append_c_string(log, "}"); 192 202 AFTER; 193 203 } 194 204 195 - static void add_array_arg(const void* ptr, unsigned long cnt, unsigned long item_size) 205 + XTRACE_HIDDEN extern "C" 206 + void add_array_arg(xtrace_string_t log, const void* ptr, unsigned long cnt, unsigned long item_size) 196 207 { 197 208 BEFORE; 198 209 unsigned char* p = (unsigned char*) ptr; 199 - xtrace_log("["); 210 + xtrace_string_append_c_string(log, "["); 200 211 for (unsigned long i = 0; i < cnt; i++) 201 212 { 202 213 if (i != 0) 203 - xtrace_log(", "); 204 - xtrace_log("%llu", read_integer((void*) p, item_size)); 214 + xtrace_string_append_c_string(log, ", "); 215 + xtrace_string_append_format(log, "%llu", read_integer((void*) p, item_size)); 205 216 p += item_size; 206 217 } 207 - xtrace_log("]"); 218 + xtrace_string_append_c_string(log, "]"); 208 219 AFTER; 209 220 } 210 221 211 - static void set_return_code(kern_return_t code) 222 + XTRACE_HIDDEN extern "C" 223 + void set_return_code(xtrace_string_t log, kern_return_t code) 212 224 { 213 225 BEFORE; 214 - xtrace_print_kern_return(code); 226 + xtrace_print_kern_return(xtrace::String::to_cxx_ptr(log), code); 215 227 AFTER; 216 228 } 217 229 218 230 #undef BEFORE 219 231 #undef AFTER 220 232 221 - static const struct xtrace_mig_callbacks callbacks = { 233 + XTRACE_HIDDEN extern "C" 234 + const struct xtrace_mig_callbacks callbacks = { 222 235 .add_raw_arg = add_raw_arg, 223 236 .add_num_arg = add_num_arg, 224 237 .add_ptr_arg = add_ptr_arg, ··· 230 243 .add_ool_ports_arg = add_ool_ports_arg, 231 244 .add_struct_arg = add_struct_arg, 232 245 .add_array_arg = add_array_arg, 233 - .set_return_code = set_return_code 246 + .set_return_code = set_return_code, 247 + // String Functions 248 + .xtrace_string_construct = xtrace_string_construct, 249 + .xtrace_string_destruct = xtrace_string_destruct, 250 + .xtrace_string_clear = xtrace_string_clear, 251 + .xtrace_string_c_str = xtrace_string_c_str, 252 + // Logging Functions 253 + .xtrace_log = xtrace_log 234 254 }; 235 255 236 256 static const struct xtrace_mig_routine_desc* find_routine(mach_msg_id_t id, const struct xtrace_mig_subsystem* s, int* out_is_reply) ··· 323 343 return 0; 324 344 } 325 345 326 - extern "C" 327 - void xtrace_print_mig_message(const mach_msg_header_t* message, mach_port_name_t request_port) 346 + void xtrace_print_mig_message(xtrace::String* log, const mach_msg_header_t* message, mach_port_name_t request_port) 328 347 { 329 348 if (message == NULL) 330 349 return; ··· 340 359 return; 341 360 342 361 if (!is_reply) 343 - xtrace_log("%s::%s(", s->name, r->name); 362 + log->append_format("%s::%s(", s->name, r->name); 344 363 else 345 364 { 346 - xtrace_set_gray_color(); 347 - xtrace_log("%s::%s() -> ", s->name, r->name); 348 - xtrace_reset_color(); 365 + xtrace_set_gray_color(log); 366 + log->append_format("%s::%s() -> ", s->name, r->name); 367 + xtrace_reset_color(log); 349 368 } 350 369 351 370 set_is_first_arg(true); 352 371 r->routine(message, is_reply, &callbacks); 353 372 354 373 if (!is_reply) 355 - xtrace_log(")"); 374 + log->append(")"); 356 375 else 357 - xtrace_log(" "); 376 + log->append(" "); 358 377 }
+4 -3
src/xtrace/mig_trace.h
··· 4 4 #include <mach/message.h> 5 5 #include "base.h" 6 6 7 + #ifdef XTRACE_CPP 8 + void xtrace_print_mig_message(xtrace::String* log, const mach_msg_header_t* message, mach_port_name_t request_port); 9 + #endif 10 + 7 11 XTRACE_DECLARATIONS_C_BEGIN 8 - 9 12 void xtrace_setup_mig_tracing(void); 10 - void xtrace_print_mig_message(const mach_msg_header_t* message, mach_port_name_t request_port); 11 - 12 13 XTRACE_DECLARATIONS_C_END 13 14 14 15 #endif // XTRACE_MIG_TRACE
+22 -25
src/xtrace/posix_spawn_args.cpp
··· 12 12 13 13 #include "xtracelib.h" 14 14 15 - extern "C" void print_open_flags(void* arg); 16 - 17 15 static struct { 18 16 unsigned short flag; 19 17 const char* name; ··· 35 33 #undef POSIX_SPAWN_ATTR_ENTRY 36 34 }; 37 35 38 - extern "C" 39 - void print_arg_posix_spawn_args(void* arg) { 36 + void print_arg_posix_spawn_args(xtrace::String* log, void* arg) { 40 37 const struct _posix_spawn_args_desc* args = (const struct _posix_spawn_args_desc*)(arg); 41 38 bool is_first = true; 42 39 43 - xtrace_log("{ attributes = "); 40 + log->append("{ attributes = "); 44 41 45 42 if (args && args->attrp) { 46 43 for (size_t i = 0; all_posix_spawn_attrs[i].name != NULL; i++) { ··· 48 45 if (is_first) { 49 46 is_first = false; 50 47 } else { 51 - xtrace_log("|"); 48 + log->append("|"); 52 49 } 53 50 54 - xtrace_log("%s", all_posix_spawn_attrs[i].name); 51 + log->append_format("%s", all_posix_spawn_attrs[i].name); 55 52 } 56 53 } 57 54 } 58 55 59 56 if (is_first) { 60 - xtrace_log("0"); 57 + log->append("0"); 61 58 } 62 59 63 - xtrace_log(", file_actions = {"); 60 + log->append(", file_actions = {"); 64 61 65 62 if (args && args->file_actions) { 66 63 for (size_t i = 0; i < args->file_actions->psfa_act_count; ++i) { 67 64 const struct _psfa_action* action = &args->file_actions->psfa_act_acts[i]; 68 65 69 66 if (i != 0) { 70 - xtrace_log(", "); 67 + log->append(", "); 71 68 } 72 69 73 70 switch (action->psfaa_type) { 74 71 case PSFA_OPEN: 75 - xtrace_log("open("); 76 - xtrace_print_string_literal(action->psfaa_openargs.psfao_path); 77 - xtrace_log(", "); 78 - print_open_flags((void*)(intptr_t)(action->psfaa_openargs.psfao_oflag)); 79 - xtrace_log(", 0%o) to %d", action->psfaa_openargs.psfao_mode, action->psfaa_filedes); 72 + log->append("open("); 73 + xtrace_print_string_literal(log, action->psfaa_openargs.psfao_path); 74 + log->append(", "); 75 + print_open_flags(log, (void*)(intptr_t)(action->psfaa_openargs.psfao_oflag)); 76 + log->append_format(", 0%o) to %d", action->psfaa_openargs.psfao_mode, action->psfaa_filedes); 80 77 break; 81 78 82 79 case PSFA_CLOSE: 83 - xtrace_log("close(%d)", action->psfaa_filedes); 80 + log->append_format("close(%d)", action->psfaa_filedes); 84 81 break; 85 82 86 83 case PSFA_DUP2: 87 - xtrace_log("dup2(%d, %d)", action->psfaa_filedes, action->psfaa_dup2args.psfad_newfiledes); 84 + log->append_format("dup2(%d, %d)", action->psfaa_filedes, action->psfaa_dup2args.psfad_newfiledes); 88 85 break; 89 86 90 87 case PSFA_INHERIT: 91 - xtrace_log("inherit(%d)", action->psfaa_filedes); 88 + log->append_format("inherit(%d)", action->psfaa_filedes); 92 89 break; 93 90 94 91 case PSFA_FILEPORT_DUP2: 95 92 // NOTE: if we see this in the output, that's an issue; 96 93 // we don't have this implemented right now 97 - xtrace_log("dup2_fileport(port right %d, %d)", action->psfaa_fileport, action->psfaa_dup2args.psfad_newfiledes); 94 + log->append_format("dup2_fileport(port right %d, %d)", action->psfaa_fileport, action->psfaa_dup2args.psfad_newfiledes); 98 95 break; 99 96 100 97 case PSFA_CHDIR: 101 - xtrace_log("chdir("); 102 - xtrace_print_string_literal(action->psfaa_chdirargs.psfac_path); 103 - xtrace_log(")"); 98 + log->append("chdir("); 99 + xtrace_print_string_literal(log, action->psfaa_chdirargs.psfac_path); 100 + log->append(")"); 104 101 break; 105 102 106 103 case PSFA_FCHDIR: 107 - xtrace_log("fchdir(%d)", action->psfaa_filedes); 104 + log->append_format("fchdir(%d)", action->psfaa_filedes); 108 105 break; 109 106 110 107 default: 111 - xtrace_log("???"); 108 + log->append("???"); 112 109 break; 113 110 } 114 111 } 115 112 } 116 113 117 - xtrace_log("} }"); 114 + log->append("} }"); 118 115 };
+37 -39
src/xtrace/xtracelib.cpp
··· 236 236 setup_hook_with_perms((hook*)&_xtrace_postfork_child, (void*)xtrace_postfork_child_hook, true); 237 237 }; 238 238 239 - extern "C" 240 - void xtrace_set_gray_color(void) 239 + void xtrace_set_gray_color(xtrace::String* log) 241 240 { 242 241 if (xtrace_no_color) 243 242 return; 244 243 245 - xtrace_log("\033[37m"); 244 + log->append("\033[37m"); 246 245 } 247 246 248 - extern "C" 249 - void xtrace_reset_color(void) 247 + void xtrace_reset_color(xtrace::String* log) 250 248 { 251 249 if (xtrace_no_color) 252 250 return; 253 251 254 - xtrace_log("\033[0m"); 252 + log->append("\033[0m"); 255 253 } 256 254 257 - extern "C" 258 - void xtrace_start_line(int indent) 255 + void xtrace_start_line(xtrace::String* log, int indent) 259 256 { 260 - xtrace_set_gray_color(); 257 + xtrace_set_gray_color(log); 261 258 262 - xtrace_log("[%d]", sys_thread_selfid()); 259 + log->append_format("[%d]", sys_thread_selfid()); 263 260 for (int i = 0; i < indent + 1; i++) 264 - xtrace_log(" "); 261 + log->append(" "); 265 262 266 - xtrace_reset_color(); 263 + xtrace_reset_color(log); 267 264 } 268 265 269 - static void print_call(const struct calldef* defs, const char* type, int nr, int indent, int gray_name) 266 + static void print_call(xtrace::String* log, const struct calldef* defs, const char* type, int nr, int indent, int gray_name) 270 267 { 271 - xtrace_start_line(indent); 268 + xtrace_start_line(log, indent); 272 269 273 270 if (gray_name) 274 - xtrace_set_gray_color(); 271 + xtrace_set_gray_color(log); 275 272 276 273 if (defs[nr].name != NULL) 277 - xtrace_log("%s", defs[nr].name); 274 + log->append_format("%s", defs[nr].name); 278 275 else 279 - xtrace_log("%s %d", type, nr); 276 + log->append_format("%s %d", type, nr); 280 277 281 278 // Leaves gray color on! 282 279 } ··· 295 292 296 293 DEFINE_XTRACE_TLS_VAR(struct nested_call_struct, nested_call, (struct nested_call_struct) {0}, NULL); 297 294 298 - extern "C" 299 - void handle_generic_entry(const struct calldef* defs, const char* type, int nr, void* args[]) 295 + void handle_generic_entry(xtrace::String* log, const struct calldef* defs, const char* type, int nr, void* args[]) 300 296 { 301 297 if (xtrace_ignore) 302 298 return; ··· 304 300 if (get_ptr_nested_call()->previous_level < get_ptr_nested_call()->current_level && !xtrace_split_entry_and_exit) 305 301 { 306 302 // We are after an earlier entry without an exit. 307 - xtrace_log("\n"); 303 + xtrace_log("%s\n", log->c_str()); 304 + log->clear(); 308 305 } 309 306 310 307 int indent = 4 * get_ptr_nested_call()->current_level; 311 308 get_ptr_nested_call()->nrs[get_ptr_nested_call()->current_level] = nr; 312 309 313 - print_call(defs, type, nr, indent, 0); 310 + print_call(log, defs, type, nr, indent, 0); 314 311 315 312 if (defs[nr].name != NULL && defs[nr].print_args != NULL) 316 313 { 317 - xtrace_log("("); 318 - defs[nr].print_args(nr, args); 319 - xtrace_log(")"); 314 + log->append("("); 315 + defs[nr].print_args(log, nr, args); 316 + log->append(")"); 320 317 } 321 318 else 322 - xtrace_log("(...)"); 319 + log->append("(...)"); 323 320 324 - if (xtrace_split_entry_and_exit) 325 - xtrace_log("\n"); 321 + if (xtrace_split_entry_and_exit) { 322 + xtrace_log("%s\n", log->c_str()); 323 + log->clear(); 324 + } 326 325 327 326 get_ptr_nested_call()->previous_level = get_ptr_nested_call()->current_level++; 328 327 } 329 328 330 - extern "C" 331 - void handle_generic_exit(const struct calldef* defs, const char* type, uintptr_t retval, int force_split) 329 + void handle_generic_exit(xtrace::String* log, const struct calldef* defs, const char* type, uintptr_t retval, int force_split) 332 330 { 333 331 if (xtrace_ignore) 334 332 return; ··· 344 342 if (xtrace_split_entry_and_exit || force_split) 345 343 { 346 344 int indent = 4 * get_ptr_nested_call()->current_level; 347 - print_call(defs, type, nr, indent, 1); 348 - xtrace_log("()"); 345 + print_call(log, defs, type, nr, indent, 1); 346 + log->append("()"); 349 347 } 350 348 351 - xtrace_set_gray_color(); 352 - xtrace_log(" -> "); 353 - xtrace_reset_color(); 349 + xtrace_set_gray_color(log); 350 + log->append(" -> "); 351 + xtrace_reset_color(log); 354 352 355 353 if (defs[nr].name != NULL && defs[nr].print_retval != NULL) 356 - { 357 - defs[nr].print_retval(nr, retval); 358 - xtrace_log("\n"); 359 - } 354 + defs[nr].print_retval(log, nr, retval); 360 355 else 361 - xtrace_log("0x%lx\n", retval); 356 + log->append_format("0x%lx", retval); 357 + 358 + xtrace_log("%s\n", log->c_str()); 359 + log->clear(); 362 360 } 363 361 364 362 extern "C"
+13 -9
src/xtrace/xtracelib.h
··· 4 4 #include <darling/emulation/simple.h> 5 5 6 6 #include "base.h" 7 + #include "string.h" 7 8 9 + #ifdef XTRACE_CPP 8 10 struct calldef 9 11 { 10 12 const char* name; 11 - void (*print_args)(int nr, void* args[]); 12 - void (*print_retval)(int nr, uintptr_t rv); 13 + void (*print_args)(xtrace::String* log, int nr, void* args[]); 14 + void (*print_retval)(xtrace::String* log, int nr, uintptr_t rv); 13 15 }; 14 16 15 - XTRACE_DECLARATIONS_C_BEGIN 17 + void handle_generic_entry(xtrace::String* log, const struct calldef* defs, const char* type, int nr, void* args[]); 18 + void handle_generic_exit(xtrace::String* log, const struct calldef* defs, const char* type, uintptr_t retval, int force_split); 16 19 17 - void handle_generic_entry(const struct calldef* defs, const char* type, int nr, void* args[]); 18 - void handle_generic_exit(const struct calldef* defs, const char* type, uintptr_t retval, int force_split); 20 + void xtrace_set_gray_color(xtrace::String* log); 21 + void xtrace_reset_color(xtrace::String* log); 22 + 23 + void xtrace_start_line(xtrace::String* log, int indent); 24 + #endif 25 + 26 + XTRACE_DECLARATIONS_C_BEGIN 19 27 20 28 extern int xtrace_no_color; 21 - void xtrace_set_gray_color(void); 22 - void xtrace_reset_color(void); 23 - 24 - void xtrace_start_line(int indent); 25 29 26 30 void xtrace_log(const char* format, ...) __attribute__((format(printf, 1, 2))); 27 31 void xtrace_log_v(const char* format, va_list args) __attribute__((format(printf, 1, 0)));