| 125 | |
| 126 | #ifndef _WIN32 |
| 127 | bool IsDebuggerPresent() |
| 128 | { |
| 129 | #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) |
| 130 | int mib[] = { |
| 131 | CTL_KERN, |
| 132 | KERN_PROC, |
| 133 | KERN_PROC_PID, |
| 134 | getpid(), |
| 135 | # if defined(__NetBSD__) || defined(__OpenBSD__) |
| 136 | sizeof(struct kinfo_proc), |
| 137 | 1, |
| 138 | # endif |
| 139 | }; |
| 140 | u_int miblen = std::size(mib); |
| 141 | struct kinfo_proc info; |
| 142 | usz size = sizeof(info); |
| 143 | |
| 144 | if (sysctl(mib, miblen, &info, &size, NULL, 0)) |
| 145 | { |
| 146 | return false; |
| 147 | } |
| 148 | |
| 149 | return info.KP_FLAGS & P_TRACED; |
| 150 | #else |
| 151 | char buf[4096]; |
| 152 | fs::file status_fd("/proc/self/status"); |
| 153 | if (!status_fd) |
| 154 | { |
| 155 | std::fprintf(stderr, "Failed to open /proc/self/status\n"); |
| 156 | return false; |
| 157 | } |
| 158 | |
| 159 | const auto num_read = status_fd.read(buf, sizeof(buf) - 1); |
| 160 | if (num_read == 0 || num_read == umax) |
| 161 | { |
| 162 | std::fprintf(stderr, "Failed to read /proc/self/status (%d)\n", errno); |
| 163 | return false; |
| 164 | } |
| 165 | |
| 166 | buf[num_read] = '\0'; |
| 167 | std::string_view status = buf; |
| 168 | |
| 169 | const auto found = status.find("TracerPid:"); |
| 170 | if (found == umax) |
| 171 | { |
| 172 | std::fprintf(stderr, "Failed to find 'TracerPid:' in /proc/self/status\n"); |
| 173 | return false; |
| 174 | } |
| 175 | |
| 176 | for (const char* cp = status.data() + found + 10; cp <= status.data() + num_read; ++cp) |
| 177 | { |
| 178 | if (!std::isspace(*cp)) |
| 179 | { |
| 180 | return std::isdigit(*cp) != 0 && *cp != '0'; |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | return false; |
no test coverage detected