|
29 | 29 | #include "interface.h" |
30 | 30 | #include "common.h" |
31 | 31 |
|
| 32 | +// Check if a specific signal is blocked for a given thread. |
| 33 | +// Returns: 1 if signal is blocked, 0 if not blocked, -1 on error. |
| 34 | +static int swipr_is_signal_blocked(swipr_os_dep_thread_id tid, int signum) { |
| 35 | + if (signum < 1 || signum > 64) { |
| 36 | + return -1; |
| 37 | + } |
| 38 | + |
| 39 | + char path[64]; |
| 40 | + snprintf(path, sizeof(path), "/proc/self/task/%d/status", tid); |
| 41 | + |
| 42 | + int fd = open(path, O_RDONLY); |
| 43 | + if (fd < 0) { |
| 44 | + return -1; |
| 45 | + } |
| 46 | + |
| 47 | + char buffer[4096]; |
| 48 | + ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1); |
| 49 | + int close_result = close(fd); |
| 50 | + if (bytes_read <= 0 || (close_result != 0 && !(close_result == -1 && errno == EINTR))) { |
| 51 | + return -1; |
| 52 | + } |
| 53 | + buffer[bytes_read] = '\0'; |
| 54 | + |
| 55 | + // Find the SigBlk line |
| 56 | + const char *sigblk_line = strstr(buffer, "\nSigBlk:"); |
| 57 | + if (!sigblk_line) { |
| 58 | + sigblk_line = strstr(buffer, "SigBlk:"); |
| 59 | + if (!sigblk_line) { |
| 60 | + return -1; |
| 61 | + } |
| 62 | + } else { |
| 63 | + sigblk_line++; // Skip the newline |
| 64 | + } |
| 65 | + |
| 66 | + // Skip "SigBlk:" and whitespace |
| 67 | + sigblk_line += 7; |
| 68 | + while (*sigblk_line == ' ' || *sigblk_line == '\t') { |
| 69 | + sigblk_line++; |
| 70 | + } |
| 71 | + |
| 72 | + // Parse the hexadecimal mask |
| 73 | + unsigned long long mask = strtoull(sigblk_line, NULL, 16); |
| 74 | + |
| 75 | + // Check if the signal bit is set (signals are 1-indexed) |
| 76 | + int bit_position = signum - 1; |
| 77 | + return (mask & (1ULL << bit_position)) ? 1 : 0; |
| 78 | +} |
| 79 | + |
32 | 80 | struct thread_info *swipr_os_dep_create_thread_list(size_t *all_threads_count) { |
33 | 81 | struct thread_info *all_threads = calloc(sizeof(struct thread_info), SWIPR_MAX_MUTATOR_THREADS); |
34 | 82 | if (!all_threads) { |
@@ -61,6 +109,13 @@ struct thread_info *swipr_os_dep_create_thread_list(size_t *all_threads_count) { |
61 | 109 |
|
62 | 110 | pid_t tid = atol(ent->d_name); |
63 | 111 | if (tid != 0 && tid != my_tid) { |
| 112 | + // Check if SIGPROF is blocked for this thread |
| 113 | + int sigprof_blocked = swipr_is_signal_blocked(tid, SIGPROF); |
| 114 | + if (sigprof_blocked > 0) { |
| 115 | + // Skip threads that have SIGPROF blocked |
| 116 | + continue; |
| 117 | + } |
| 118 | + |
64 | 119 | int idx = next_index++; |
65 | 120 | all_threads[idx].ti_id = tid; |
66 | 121 | char file_path[128] = {0}; |
|
0 commit comments