[gdb/breakpoints] Fix sigsegv in info prog at exec catchpoint
authorTom de Vries <tdevries@suse.de>
Tue, 3 Jul 2018 15:08:42 +0000 (17:08 +0200)
committerTom de Vries <tdevries@suse.de>
Wed, 25 Jul 2018 22:56:41 +0000 (00:56 +0200)
With the test-case contained in this patch and compiled for debug we run into
a segfault with trunk gdb:
...
$ gdb catch-follow-exec -batch -ex "catch exec" \
  -ex "set follow-exec-mode new" -ex "run" -ex "info prog"
Catchpoint 1 (exec)
process xxx is executing new program: /usr/bin/ls
[New inferior 2 (process 0)]
[New process xxx]

Thread 2.1 "ls" hit Catchpoint 1 (exec'd /usr/bin/ls), in _start () from
  /lib64/ld-linux-x86-64.so.2
Segmentation fault (core dumped)
...

The patch fixes the segfault by returning an error in info_program_command
if get_last_target_status returns minus_one_ptid.

The test-case is non-standard, because the standard approach runs into
PR23368, a problem with gdb going to the background.

Build and reg-tested on x86_64-linux.

2018-07-26  Tom de Vries  <tdevries@suse.de>

PR breakpoints/23366
* infcmd.c (info_program_command): Handle ptid == minus_one_ptid.

* gdb.base/catch-follow-exec.c: New test.
* gdb.base/catch-follow-exec.exp: New file.

gdb/ChangeLog
gdb/infcmd.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/catch-follow-exec.c [new file with mode: 0644]
gdb/testsuite/gdb.base/catch-follow-exec.exp [new file with mode: 0644]

index ee5c9ea478e2bdb122261ea65620be3bd7d2caf0..605aeef603b4f9d1ee864592b063e6fd90e23881 100644 (file)
@@ -1,3 +1,8 @@
+2018-07-26  Tom de Vries  <tdevries@suse.de>
+
+       PR breakpoints/23366
+       * infcmd.c (info_program_command): Handle ptid == minus_one_ptid.
+
 2018-07-26  Tom de Vries  <tdevries@suse.de>
 
        * dwarf2read.c (read_subrange_type): Warn if DW_AT_upper_bound or
index 821bcc6544c2e5c9e3ef4a0a94466ba834495e72..74d5956765f1cf5acedc0e7d1407f7398ffdabbe 100644 (file)
@@ -2091,7 +2091,7 @@ info_program_command (const char *args, int from_tty)
       get_last_target_status (&ptid, &ws);
     }
 
-  if (ptid == null_ptid)
+  if (ptid == null_ptid || ptid == minus_one_ptid)
     error (_("No selected thread."));
 
   thread_info *tp = find_thread_ptid (ptid);
index ab50f70e28c09762aaf632880b4688d16c122fd6..aa8b06a07239219a4a5a0fbcb01f8486ecbf44bb 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-26  Tom de Vries  <tdevries@suse.de>
+
+       PR breakpoints/23366
+       * gdb.base/catch-follow-exec.c: New test.
+       * gdb.base/catch-follow-exec.exp: New file.
+
 2018-07-25  Tom de Vries  <tdevries@suse.de>
 
        * gdb.base/vla-optimized-out-o3.exp: New file.  Reuse
diff --git a/gdb/testsuite/gdb.base/catch-follow-exec.c b/gdb/testsuite/gdb.base/catch-follow-exec.c
new file mode 100644 (file)
index 0000000..fa68a2a
--- /dev/null
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+main (void)
+{
+  char *exec_args[] = { "/bin/ls", "ppp", NULL };
+  execve (exec_args[0], exec_args, NULL);
+}
diff --git a/gdb/testsuite/gdb.base/catch-follow-exec.exp b/gdb/testsuite/gdb.base/catch-follow-exec.exp
new file mode 100644 (file)
index 0000000..0e32ed4
--- /dev/null
@@ -0,0 +1,58 @@
+# Copyright 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Check whether finish respects the print pretty user setting when printing the
+# function result.
+
+standard_testfile
+
+if {[build_executable "failed to prepare" $testfile $srcfile debug] == -1} {
+    return -1
+}
+
+if { ![remote_file target exists /bin/bash] } {
+    unsupported "no bash"
+    return
+}
+
+if { ![remote_file target exists /bin/ls] } {
+    unsupported "no ls"
+    return
+}
+
+proc catch_follow_exec { } {
+    global binfile
+    global GDB
+
+    set test "catch-follow-exec"
+
+    append FLAGS " \"$binfile\""
+    append FLAGS " -batch"
+    append FLAGS " -ex \"catch exec\""
+    append FLAGS " -ex \"set follow-exec-mode new\""
+    append FLAGS " -ex \"run\""
+    append FLAGS " -ex \"info prog\""
+
+    catch {exec /bin/bash -c "$GDB $FLAGS"} catchlog
+    send_log "$catchlog\n"
+
+    if { [regexp {No selected thread} $catchlog] } {
+       pass $test
+    } else {
+       fail $test
+    }
+}
+
+catch_follow_exec