]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
util: Ensure debugger can be attached to process
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 29 Mar 2021 02:04:53 +0000 (15:04 +1300)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 20 Apr 2021 11:42:37 +0000 (11:42 +0000)
samba_start_debugger() attempts to start a debugger attached to the
calling process by calling system() to start a background process.
However, if the spawned shell exits before the debugger has had a chance
to attach, the debugger process will no longer be a child of the parent
process (as it will have been reparented).

If the system does not allow tracing by non-child processes, attachment
may fail as a result.

This commit replaces the system() call and the implicit shell around
xterm with an explicit fork()/exec() so that the debugger remains a
child of the calling process, ensuring the attachment succeeds unless
tracing is disabled completely.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlet <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
lib/util/util.c

index 7d7fb91e875637e6a6800d1c6f5270209babbb43..b175b22cf13d664ed081d9d06704109470d00d37 100644 (file)
@@ -1166,21 +1166,27 @@ void anonymous_shared_free(void *ptr)
 */
 void samba_start_debugger(void)
 {
-       char *cmd = NULL;
+       pid_t pid = fork();
+       if (pid == -1) {
+               return;
+       } else if (pid) {
 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
-       /*
-        * Make sure all children can attach a debugger.
-        */
-       prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
+               /*
+                * Make sure the child process can attach a debugger.
+                */
+               prctl(PR_SET_PTRACER, pid, 0, 0, 0);
 #endif
-       if (asprintf(&cmd, "xterm -e \"gdb --pid %u\"&", getpid()) == -1) {
-               return;
-       }
-       if (system(cmd) == -1) {
+               sleep(2);
+       } else {
+               char *cmd = NULL;
+
+               if (asprintf(&cmd, "gdb --pid %u", getppid()) == -1) {
+                       _exit(EXIT_FAILURE);
+               }
+
+               execlp("xterm", "xterm", "-e", cmd, (char *) NULL);
                free(cmd);
-               return;
+               _exit(errno);
        }
-       free(cmd);
-       sleep(2);
 }
 #endif