+static int fr_debugger_attached(void)
+{
+ int pid;
+
+ int from_child[2] = {-1, -1};
+
+ if (pipe(from_child) < 0) {
+ fr_strerror_printf("Debugger check failed: Error opening internal pipe: %s", fr_syserror(errno));
+ return -1;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ fr_strerror_printf("Debugger check failed: Error forking: %s", fr_syserror(errno));
+ return -1;
+ }
+
+ /* Child */
+ if (pid == 0) {
+ int8_t ret = 0;
+ int ppid = getppid();
+
+ /* Close parent's side */
+ close(from_child[0]);
+
+ if (_PTRACE(PTRACE_ATTACH, ppid) == 0) {
+ /* If we attached then we're not running under a debugger */
+ write(from_child[1], &ret, sizeof(ret));
+
+ /* Wait for the parent to stop and continue it */
+ waitpid(ppid, NULL, 0);
+ _PTRACE(PTRACE_CONT, ppid);
+
+ /* Detach */
+ _PTRACE(PTRACE_DETACH, ppid);
+ exit(0);
+ }
+
+ ret = 1;
+ /* Something is already attached */
+ write(from_child[1], &ret, 1);
+
+ exit(0);
+ /* Parent */
+ } else {
+ int8_t ret = -1;
+
+ /*
+ * The child writes a 1 if pattach failed else 0.
+ *
+ * This read may be interrupted by pattach,
+ * which is why we need the loop.
+ */
+ while ((read(from_child[0], &ret, 1) < 0) && (errno == EINTR));
+
+ /* Ret not updated */
+ if (ret < 0) {
+ fr_strerror_printf("Debugger check failed: Error getting status from child: %s",
+ fr_syserror(errno));
+ }
+
+ /* Close the pipes here (if we did it above, it might race with pattach) */
+ close(from_child[1]);
+ close(from_child[0]);
+
+ /* Collect the status of the child */
+ waitpid(pid, NULL, 0);
+
+ return ret;
+ }
+}
+#else
+static int fr_debugger_attached(void)