diff options
author | Mike Gulick <mike.gulick@mathworks.com> | 2017-10-30 18:13:44 -0400 |
---|---|---|
committer | Simon Marchi <simon.marchi@ericsson.com> | 2018-01-17 12:54:59 -0500 |
commit | 416675305692976aca45860e24b963982a2e682a (patch) | |
tree | 5999c0ba0fccc5fdffa709272d61b791747b3abd /gdb/testsuite/gdb.base/solib-vanish.exp | |
parent | 4d9b86e17505063c96a01d40cdf5b4fc2080a798 (diff) | |
download | gdb-416675305692976aca45860e24b963982a2e682a.zip gdb-416675305692976aca45860e24b963982a2e682a.tar.gz gdb-416675305692976aca45860e24b963982a2e682a.tar.bz2 |
Fix gdb segv when objfile can't be opened
This fixes PR 16577.
This patch changes gdb_bfd_map_section to issue a warning rather than an error
if it is unable to read the object file, and sets the size of the section/frame
that it attempted to read to 0 on error.
The description of gdb_bfd_map_section states that it will try to read or map
the contents of the section SECT, and if successful, the section data is
returned and *SIZE is set to the size of the section data. This function was
throwing an error and leaving *SIZE as-is. Setting the section size to 0
indicates to dwarf2_build_frame_info that there is no data to read, otherwise
it will try to read from an invalid frame pointer.
Changing the error to a warning allows this to be handled gracefully.
Additionally, the error was clobbering the breakpoint output indicating the
current frame (function name, arguments, source file, and line number). E.g.
Thread 3 "foo" hit Breakpoint 1, BFD: reopening /tmp/jna-1013829440/jna2973250704389291330.tmp: No such file or directory
BFD: reopening /tmp/jna-1013829440/jna2973250704389291330.tmp: No such file or directory
(gdb)
While the "BFD: reopening ..." messages will still appear interspersed in the
breakpoint output, the current frame info is now displayed:
Thread 3 "foo" hit Breakpoint 1, BFD: reopening /tmp/jna-1013829440/jna1875755897659885075.tmp: No such file or directory
BFD: reopening /tmp/jna-1013829440/jna1875755897659885075.tmp: No such file or directory
warning: Can't read data for section '.eh_frame' in file '/tmp/jna-1013829440/jna1875755897659885075.tmp'
do_something () at file.cpp:80
80 {
(gdb)
Diffstat (limited to 'gdb/testsuite/gdb.base/solib-vanish.exp')
-rw-r--r-- | gdb/testsuite/gdb.base/solib-vanish.exp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/solib-vanish.exp b/gdb/testsuite/gdb.base/solib-vanish.exp new file mode 100644 index 0000000..928ca4e --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-vanish.exp @@ -0,0 +1,107 @@ +# Copyright 2017-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/>. +# + +# This test case verifies that GDB gracefully handles a shared library file +# vanishing after being dlopen'ed. This consists of three nested function calls: +# +# main() -> foo() -> bar() +# +# where: +# - foo exists in solib-vanish-lib1.so, which is dlopen'ed by main() +# - bar exists in solib-vanish-lib2.so, which is dynamically linked into +# solib-vanish-lib1.so +# +# Immediately after dlopen'ing solib-vanish-lib1.so, the so file is moved aside +# by renaming. The main executable and solib-vanish-lib2.so are still +# accessible. +# +# If a breakpoint is set on bar(), gdb throws an error when this breakpoint is +# hit: +# +# (gdb) r +# Starting program: /local/gdb/git/pr_16577_repro/simple/solib-vanish-main +# +# Breakpoint 1, BFD: reopening ./solib-vanish-lib1.so: No such file or directory +# +# BFD: reopening ./solib-vanish-lib1.so: No such file or directory +# +# (gdb) +# +# Notice that this does not print the current frame, i.e.: +# bar (y=1) at solib-vanish-lib2.c:19 +# 19 return y + 1; /* break here */ +# (gdb) +# +# The current gdb git tip segfaults if we then try to step: +# (gdb) n +# Segmentation fault + +# This test verifies that: +# 1) GDB does not segfault when stepping +# 2) The stack frame is printed + +if { [skip_shlib_tests] } { + return 0 +} + +# Library 2 +set lib2name "solib-vanish-lib2" +set srcfile_lib2 ${srcdir}/${subdir}/${lib2name}.c +set binfile_lib2 [standard_output_file ${lib2name}.so] +set lib2_flags {debug} + +# Library 1 +set lib1name "solib-vanish-lib1" +set srcfile_lib1 ${srcdir}/${subdir}/${lib1name}.c +set binfile_lib1 [standard_output_file ${lib1name}.so] +set lib1_flags [list debug shlib=${binfile_lib2}] + +# Main program +set testfile "solib-vanish-main" +set srcfile ${srcdir}/${subdir}/${testfile}.c +set executable ${testfile} +set binfile [standard_output_file ${executable}] +set bin_flags [list debug shlib_load additional_flags=-DVANISH_LIB=\"${binfile_lib1}\"] + +if { [gdb_compile_shlib ${srcfile_lib2} ${binfile_lib2} $lib2_flags] != "" + || [gdb_compile_shlib ${srcfile_lib1} ${binfile_lib1} $lib1_flags] != "" + || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { + untested "failed to compile" + return -1 +} + +clean_restart $testfile + +if { ![runto_main] } { + fail "can't run to main" + return +} + +delete_breakpoints + +set lib2_lineno [gdb_get_line_number "break here" ${srcfile_lib2}] + +gdb_breakpoint "${lib2name}.c:${lib2_lineno}" {allow-pending} + +# Verify that both the location and source code are displayed +gdb_continue_to_breakpoint "bar" \ + ".*/${lib2name}.c:${lib2_lineno}.*break here.*" + +# This should not segfault +gdb_test "next" \ + "" \ + "next succeeds" + |