| 57 | DbgCtl dbg_ctl_backtrace{"backtrace"}; |
| 58 | |
| 59 | static threadlist |
| 60 | threads_for_process(pid_t proc) |
| 61 | { |
| 62 | DIR *dir = nullptr; |
| 63 | struct dirent *entry = nullptr; |
| 64 | |
| 65 | char path[64]; |
| 66 | threadlist threads; |
| 67 | |
| 68 | if (snprintf(path, sizeof(path), "/proc/%ld/task", static_cast<long>(proc)) >= static_cast<int>(sizeof(path))) { |
| 69 | goto done; |
| 70 | } |
| 71 | |
| 72 | dir = opendir(path); |
| 73 | if (dir == nullptr) { |
| 74 | goto done; |
| 75 | } |
| 76 | |
| 77 | while ((entry = readdir(dir))) { |
| 78 | pid_t threadid; |
| 79 | |
| 80 | if (isdot(entry->d_name) || isdotdot(entry->d_name)) { |
| 81 | continue; |
| 82 | } |
| 83 | |
| 84 | threadid = strtol(entry->d_name, nullptr, 10); |
| 85 | if (threadid > 0) { |
| 86 | threads.push_back(threadid); |
| 87 | Dbg(dbg_ctl_backtrace, "found thread %ld\n", (long)threadid); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | done: |
| 92 | if (dir) { |
| 93 | closedir(dir); |
| 94 | } |
| 95 | |
| 96 | return threads; |
| 97 | } |
| 98 | |
| 99 | static void |
| 100 | backtrace_for_thread(pid_t threadid, TextBuffer &text) |
no test coverage detected