| 54 | } |
| 55 | |
| 56 | static int demangler_main() |
| 57 | { |
| 58 | FILE *fp = fdopen(symbol_fds[0], "r"); |
| 59 | if (fp == NULL) |
| 60 | return EXIT_FAILURE; |
| 61 | |
| 62 | while (true) { |
| 63 | fd_set fdset; |
| 64 | |
| 65 | FD_ZERO(&fdset); |
| 66 | FD_SET(symbol_fds[0], &fdset); |
| 67 | FD_SET(exit_fds[0], &fdset); |
| 68 | int maxfd = max(symbol_fds[0], exit_fds[0]); |
| 69 | |
| 70 | if (select(maxfd + 1, &fdset, NULL, NULL, NULL) <= 0) |
| 71 | continue; |
| 72 | |
| 73 | if (FD_ISSET(exit_fds[0], &fdset)) { |
| 74 | break; |
| 75 | } else if (FD_ISSET(symbol_fds[0], &fdset)) { |
| 76 | char msg[512]; |
| 77 | char buf[512]; |
| 78 | |
| 79 | while (fgets(msg, sizeof(msg), fp) != NULL) { |
| 80 | u32 len = strlen32(msg); |
| 81 | if (len <= 1) |
| 82 | break; |
| 83 | msg[len - 1] = '\0'; |
| 84 | |
| 85 | char *mangled_name = strchr(msg, '('); |
| 86 | char *offset_begin = strchr(msg, '+'); |
| 87 | char *offset_end = strchr(msg, ')'); |
| 88 | char *addr_begin = strchr(msg, '['); |
| 89 | char *addr_end = strchr(msg, ']'); |
| 90 | |
| 91 | // Attempt to demangle the symbol. |
| 92 | if (mangled_name && offset_begin && offset_end && mangled_name < offset_begin) { |
| 93 | *mangled_name++ = '\0'; |
| 94 | *offset_begin++ = '\0'; |
| 95 | *offset_end++ = '\0'; |
| 96 | *addr_begin++ = '\0'; |
| 97 | *addr_end++ = '\0'; |
| 98 | |
| 99 | int demangle_ok; |
| 100 | char *real_name = abi::__cxa_demangle(mangled_name, 0, 0, &demangle_ok); |
| 101 | char line[256]; |
| 102 | memset(line, 0, sizeof(line)); |
| 103 | |
| 104 | stbsp_snprintf(buf |
| 105 | , sizeof(buf) |
| 106 | , "%s(%s+%s) in %s" |
| 107 | , msg |
| 108 | , (demangle_ok == 0 ? real_name : mangled_name) |
| 109 | , offset_begin |
| 110 | , addr2line(line, sizeof(line), addr_begin) |
| 111 | ); |
| 112 | |
| 113 | free(real_name); |