(windows) GDB/MI crash when using "-list-thread-groups --available"
authorJoel Brobecker <brobecker@adacore.com>
Mon, 4 Jun 2018 20:03:32 +0000 (15:03 -0500)
committerJoel Brobecker <brobecker@adacore.com>
Mon, 4 Jun 2018 20:07:33 +0000 (16:07 -0400)
On Windows, using the "-list-thread-groups --available" GDB/MI command
before an inferior is being debugged:

    % gdb -q -i=mi
    =thread-group-added,id="i1"
    =cmd-param-changed,param="auto-load safe-path",value="/"
    (gdb)
    -list-thread-groups --available
    Segmentation fault

Ooops!

The SEGV happens because the -list-thread-groups --available command
triggers a windows_nat_target::xfer_partial call for a TARGET_OBJECT_OSDATA
object.  Until a program is being debugged, the target_ops layer that
gets the call is the Windows "native" layer. Except for a couple of
specific objects (TARGET_OBJECT_MEMORY and TARGET_OBJECT_LIBRARIES),
this layer's xfer_partial method delegates the xfer of other objects
to the target beneath:

    default:
      return beneath->xfer_partial (object, annex,
                                    readbuf, writebuf, offset, len,
                                    xfered_len);

Unfortunately, there is no "beneath layer" in this case, so
beneath is NULL and dereferencing it leads to the SEGV.

This patch fixes the issue by checking beneath before trying
to delegate the request.

gdb/ChangeLog:

        * windows-nat.c (windows_nat_target::xfer_partial): Return
        TARGET_XFER_E_IO if we need to delegate to the target beneath
        but BENEATH is NULL.

gdb/testsuite/ChangeLog:

        * gdb.mi/list-thread-groups-no-inferior.exp: New testcase.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/list-thread-groups-no-inferior.exp [new file with mode: 0644]
gdb/windows-nat.c

index d0c43027d6e45278723cfdad1c0ef67a56e39bf0..b5580c429ad2ec293aa29111a68839d30312437c 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-04  Joel Brobecker  <brobecker@adacore.com>
+
+       * windows-nat.c (windows_nat_target::xfer_partial): Return
+       TARGET_XFER_E_IO if we need to delegate to the target beneath
+       but BENEATH is NULL.
+
 2018-06-04  Simon Marchi  <simon.marchi@ericsson.com>
 
        * Makefile.in (config.status): Add configure.nat as a
index 8cef172a26d92a44add8324aad31808a70b5c842..0e98d7e115a654c2e5f6da341c963c50b389811e 100644 (file)
@@ -1,3 +1,7 @@
+2018-06-04  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.mi/list-thread-groups-no-inferior.exp: New testcase.
+
 2018-06-01  Joel Brobecker  <brobecker@adacore.com>
 
        * gdb.ada/bp_fun_addr: New testcase.
diff --git a/gdb/testsuite/gdb.mi/list-thread-groups-no-inferior.exp b/gdb/testsuite/gdb.mi/list-thread-groups-no-inferior.exp
new file mode 100644 (file)
index 0000000..9ab3838
--- /dev/null
@@ -0,0 +1,47 @@
+# 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/>.
+
+# The purpose of this test is to verify that GDB is able to handle
+# the "-list-thread-groups --available" command, even when there is
+# no inferior. In particular, we want to verify that GDB does not
+# crash.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+# Try the "-list-thread-groups --available".  This command can generate
+# a very large amount of output, potentially exceeding expect's buffer
+# size.  So we consume the output in chunks.
+
+set test "-list-thread-groups --available"
+gdb_test_multiple $test $test {
+    -re "\}" {
+        exp_continue
+    }
+    -re "\r\n$gdb_prompt " {
+        pass $test
+    }
+}
+
+# Verify that GDB is still alive.
+
+mi_gdb_test "-data-evaluate-expression 1" \
+            ".*\\^done,value=\"1\"" \
+            "GDB is still alive"
index 0f242579359ca12205e992cd0c4ff505798a0605..e3e36cdc3e549900842e80364ecbe1f2f87f3ebb 100644 (file)
@@ -2966,6 +2966,13 @@ windows_nat_target::xfer_partial (enum target_object object,
                                            writebuf, offset, len, xfered_len);
 
     default:
+      if (beneath == NULL)
+       {
+         /* This can happen when requesting the transfer of unsupported
+            objects before a program has been started (and therefore
+            with the current_target having no target beneath).  */
+         return TARGET_XFER_E_IO;
+       }
       return beneath->xfer_partial (object, annex,
                                    readbuf, writebuf, offset, len,
                                    xfered_len);