diff options
author | Tom Tromey <tom@tromey.com> | 2023-08-01 15:09:49 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2023-08-26 10:10:59 -0600 |
commit | 9030a82d6f700e03ab143f0d002e9f21ae2fd52f (patch) | |
tree | 6c8cb41f79076800fa6473f430d719d38192c386 /gdb | |
parent | d2ac569f7b443aef7b2be2f0c80d8ab0d67b4292 (diff) | |
download | gdb-9030a82d6f700e03ab143f0d002e9f21ae2fd52f.zip gdb-9030a82d6f700e03ab143f0d002e9f21ae2fd52f.tar.gz gdb-9030a82d6f700e03ab143f0d002e9f21ae2fd52f.tar.bz2 |
Use get_frame_address_in_block in print_frame
The author of 'mold' pointed out that with a certain shared library,
gdb would fail to find the shared library's name in 'bt'.
The function in question appeared at the end of the .so's .text
segment and ended with a call to 'abort'.
This turned out to be a classic case of calling get_frame_pc when
get_frame_address_in_block is needed -- the former will be off-by-one
for purposes of finding the enclosing function or shared library.
The included test fails without the patch on my system. However, I
imagine it can't be assumed to reliably fail. Nevertheless it seemed
worth doing.
Regression tested on x86-64 Fedora 38.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29074
Reviewed-by: Kevin Buettner <kevinb@redhat.com>
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/stack.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/solib-abort-lib.c | 23 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/solib-abort.c | 25 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/solib-abort.exp | 56 |
4 files changed, 105 insertions, 1 deletions
diff --git a/gdb/stack.c b/gdb/stack.c index 002bf58..0b35d62 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1420,7 +1420,7 @@ print_frame (const frame_print_options &fp_opts, { const char *lib = solib_name_from_address (get_frame_program_space (frame), - get_frame_pc (frame)); + get_frame_address_in_block (frame)); if (lib) { diff --git a/gdb/testsuite/gdb.base/solib-abort-lib.c b/gdb/testsuite/gdb.base/solib-abort-lib.c new file mode 100644 index 0000000..2254323 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-abort-lib.c @@ -0,0 +1,23 @@ +/* Copyright 2023 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/>. +*/ + +#include <stdlib.h> + +void +callee (void) +{ + abort (); +} diff --git a/gdb/testsuite/gdb.base/solib-abort.c b/gdb/testsuite/gdb.base/solib-abort.c new file mode 100644 index 0000000..42f4dc5 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-abort.c @@ -0,0 +1,25 @@ +/* Copyright 2023 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/>. +*/ + +extern void callee (void); + +int +main () +{ + callee (); + return 0; +} + diff --git a/gdb/testsuite/gdb.base/solib-abort.exp b/gdb/testsuite/gdb.base/solib-abort.exp new file mode 100644 index 0000000..fcc2296 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-abort.exp @@ -0,0 +1,56 @@ +# Copyright 2023 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/>. + +# Test corner case of printing solib name when unwinding. +# https://sourceware.org/bugzilla/show_bug.cgi?id=29074 + +require allow_shlib_tests + +# Library file. +set libname "solib-abort-lib" +set srcfile_lib ${srcdir}/${subdir}/${libname}.c +set binfile_lib [standard_output_file ${libname}.so] +# Note: no debugging info here, since this will assure that the solib +# name is printed in the stack trace. +set lib_flags {} + +# Binary file. +set testfile "solib-abort" +set srcfile ${srcdir}/${subdir}/${testfile}.c +set binfile [standard_output_file ${testfile}] +set bin_flags [list debug shlib=${binfile_lib}] + +if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" + || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { + untested "failed to compile" + return -1 +} + +clean_restart $binfile + +if {![runto_main]} { + return 0 +} + +# Run until the program dies. +gdb_test "cont" "Program received signal SIGABRT,.*" + +# The solib name should show up in the stack trace. The bug here was +# that if the function calling abort appeared last in the text +# section, and if GCC didn't emit an epilogue after the call, then gdb +# would use the wrong PC to find the solib name. This test doesn't +# exactly test this in all situations, but with the correct +# environment it is sufficient. +gdb_test "bt" "#$decimal .* in callee .* from .*${libname}\\.so.*" |