From 43368e1d9ab8437079001f7a5f6ae2241acaece3 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 23 Dec 2015 13:53:53 +0100 Subject: [PATCH] btrace: do not return out of TRY/CATCH In btrace_pt_readmem_callback, we read memory inside TRY/CATCH and return in case of an error return value. This corrupts the cleanup chain, which eventually results in a SEGV when doing or discarding cleanups later on. gdb/ * btrace.c (btrace_pt_readmem_callback): Do not return in TRY/CATCH. testsuite/ * gdb.btrace/dlopen.exp: New. * gdb.btrace/dlopen.c: New. * gdb.btrace/dlopen-dso.c: New. --- gdb/ChangeLog | 4 +++ gdb/btrace.c | 9 ++--- gdb/testsuite/ChangeLog | 6 ++++ gdb/testsuite/gdb.btrace/dlopen-dso.c | 22 ++++++++++++ gdb/testsuite/gdb.btrace/dlopen.c | 50 ++++++++++++++++++++++++++ gdb/testsuite/gdb.btrace/dlopen.exp | 52 +++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 gdb/testsuite/gdb.btrace/dlopen-dso.c create mode 100644 gdb/testsuite/gdb.btrace/dlopen.c create mode 100644 gdb/testsuite/gdb.btrace/dlopen.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 46d7fd79e3f..3d8923bc457 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2016-01-04 Markus Metzger + + * btrace.c (btrace_pt_readmem_callback): Do not return in TRY/CATCH. + 2016-01-02 Mike Frysinger * configure.tgt (powerpc*-*-*): Delete test call and diff --git a/gdb/btrace.c b/gdb/btrace.c index b7f8106c356..4c88ddd6e51 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -842,21 +842,22 @@ btrace_pt_readmem_callback (gdb_byte *buffer, size_t size, const struct pt_asid *asid, uint64_t pc, void *context) { - int errcode; + int result, errcode; + result = (int) size; TRY { errcode = target_read_code ((CORE_ADDR) pc, buffer, size); if (errcode != 0) - return -pte_nomap; + result = -pte_nomap; } CATCH (error, RETURN_MASK_ERROR) { - return -pte_nomap; + result = -pte_nomap; } END_CATCH - return size; + return result; } /* Translate the vendor from one enum to another. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ae3861f4b3f..45a6c6a5793 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-01-04 Markus Metzger + + * gdb.btrace/dlopen.exp: New. + * gdb.btrace/dlopen.c: New. + * gdb.btrace/dlopen-dso.c: New. + 2015-12-25 Sandra Loosemore * lib/gdb.exp (gdb_test): Update comments to clarify that the diff --git a/gdb/testsuite/gdb.btrace/dlopen-dso.c b/gdb/testsuite/gdb.btrace/dlopen-dso.c new file mode 100644 index 00000000000..3a1733efcf5 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/dlopen-dso.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015-2016 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 . */ + +int +answer (void) +{ + return 42; +} diff --git a/gdb/testsuite/gdb.btrace/dlopen.c b/gdb/testsuite/gdb.btrace/dlopen.c new file mode 100644 index 00000000000..7e01f79d5cb --- /dev/null +++ b/gdb/testsuite/gdb.btrace/dlopen.c @@ -0,0 +1,50 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015-2016 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 . */ + +#include +#include +#include + +static int +test (void) +{ + void *dso; + int (*fun) (void); + int answer; + + dso = dlopen (DSO_NAME, RTLD_NOW | RTLD_GLOBAL); + assert (dso != NULL); + + fun = (int (*) (void)) dlsym (dso, "answer"); + assert (fun != NULL); + + answer = fun (); + + dlclose (dso); + + return answer; +} + +int +main (void) +{ + int answer; + + answer = test (); + + return answer; +} diff --git a/gdb/testsuite/gdb.btrace/dlopen.exp b/gdb/testsuite/gdb.btrace/dlopen.exp new file mode 100644 index 00000000000..2afb42bc347 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/dlopen.exp @@ -0,0 +1,52 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2015-2016 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 . + +if { [skip_btrace_tests] } { return -1 } +if { [skip_shlib_tests] } { return -1 } + +standard_testfile + +set basename_lib dlopen-dso +set srcfile_lib $srcdir/$subdir/$basename_lib.c +set binfile_lib [standard_output_file $basename_lib.so] + +if { [gdb_compile_shlib $srcfile_lib $binfile_lib \ + [list additional_flags=-fPIC]] != "" } { + untested "Could not compile $binfile_lib." + return -1 +} + +if { [prepare_for_testing $testfile.exp $testfile $srcfile \ + [list additional_flags=-DDSO_NAME=\"$binfile_lib\" libs=-ldl]] } { + return -1 +} + +if ![runto_main] { + return 0 +} + +# Trace the test function +# +gdb_test_no_output "record btrace" +gdb_test "next" + +# The memory containing the library call we traced is already gone. +# Trace decode used to run into a SEGV after corrupting the cleanup chain. +# +# The test passes if we don't crash GDB. +# +gdb_test "info record" -- 2.30.2