diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2020-03-18 10:53:41 +0100 |
---|---|---|
committer | Markus Metzger <markus.t.metzger@intel.com> | 2020-04-21 15:51:06 +0200 |
commit | 1a476b6d68f338e6daa0345501c0cf0fe97dd8f3 (patch) | |
tree | f9e909c6d92dfbd11943892ccb24458b680251ad | |
parent | 4778a5f87d253399083565b4919816f541ebe414 (diff) | |
download | binutils-1a476b6d68f338e6daa0345501c0cf0fe97dd8f3.zip binutils-1a476b6d68f338e6daa0345501c0cf0fe97dd8f3.tar.gz binutils-1a476b6d68f338e6daa0345501c0cf0fe97dd8f3.tar.bz2 |
gdb, btrace: forward fetch_registers for unknown threads
In the record-btrace target, while replaying, we can only provide the PC
register. The btrace state is stored in the thread_info. So, when trying
to determine whether we are currently replaying, GDB calls
find_thread_ptid() to obtain the thread_info. It also asserts that we do
have a thread_info.
For new threads, libthread-db may fetch registers before the thread is
known to GDB. In this case, find_thread_ptid() returns nullptr and the
assertion fails.
Forward the fetch_registers request to the target beneath in that case.
gdb/ChangeLog:
2020-03-19 Markus Metzger <markus.t.metzger@intel.com>
* record-btrace.c (record_btrace_target::fetch_registers): Forward
request if we do not have a thread_info.
gdb/testsuite/ChangeLog:
2020-03-19 Markus Metzger <markus.t.metzger@intel.com>
* gdb.btrace/enable-new-thread.c: New test.
* gdb.btrace/enable-new-thread.exp: New file.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/record-btrace.c | 11 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/enable-new-thread.c | 36 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/enable-new-thread.exp | 57 |
5 files changed, 111 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0e80cdb..c761d49 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2020-04-21 Markus Metzger <markus.t.metzger@intel.com> + + * record-btrace.c (record_btrace_target::fetch_registers): Forward + request if we do not have a thread_info. + 2020-04-21 Tom de Vries <tdevries@suse.de> PR gdb/25471 diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index fe2ab8a..9b04d06 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -1532,11 +1532,16 @@ record_btrace_target::remove_breakpoint (struct gdbarch *gdbarch, void record_btrace_target::fetch_registers (struct regcache *regcache, int regno) { + btrace_insn_iterator *replay = nullptr; + + /* Thread-db may ask for a thread's registers before GDB knows about the + thread. We forward the request to the target beneath in this + case. */ thread_info *tp = find_thread_ptid (regcache->target (), regcache->ptid ()); - gdb_assert (tp != NULL); + if (tp != nullptr) + replay = tp->btrace.replay; - btrace_insn_iterator *replay = tp->btrace.replay; - if (replay != NULL && !record_btrace_generating_corefile) + if (replay != nullptr && !record_btrace_generating_corefile) { const struct btrace_insn *insn; struct gdbarch *gdbarch; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f722567..09ad4cd 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-04-21 Markus Metzger <markus.t.metzger@intel.com> + + * gdb.btrace/enable-new-thread.c: New test. + * gdb.btrace/enable-new-thread.exp: New file. + 2020-04-21 Tom de Vries <tdevries@suse.de> PR gdb/25471 diff --git a/gdb/testsuite/gdb.btrace/enable-new-thread.c b/gdb/testsuite/gdb.btrace/enable-new-thread.c new file mode 100644 index 0000000..d4dc240 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/enable-new-thread.c @@ -0,0 +1,36 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 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 <pthread.h> +#include <unistd.h> + +static void * +test (void *arg) +{ + return arg; /* bp.1 */ +} + +int +main (void) +{ + pthread_t th; + + pthread_create (&th, NULL, test, NULL); + pthread_join (th, NULL); + + return 0; +} diff --git a/gdb/testsuite/gdb.btrace/enable-new-thread.exp b/gdb/testsuite/gdb.btrace/enable-new-thread.exp new file mode 100644 index 0000000..e8b17ad --- /dev/null +++ b/gdb/testsuite/gdb.btrace/enable-new-thread.exp @@ -0,0 +1,57 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2020 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 that new threads of recorded inferiors also get recorded. + +if { [skip_btrace_tests] } { + unsupported "target does not support record-btrace" + return -1 +} + +standard_testfile +if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { + return -1 +} + +if ![runto_main] { + untested "failed to run to main" + return -1 +} + +# Record the main thread. Recording will automatically be enabled for the +# other thread. +gdb_test "record btrace" + +gdb_breakpoint [gdb_get_line_number "bp.1" $srcfile] +gdb_continue_to_breakpoint "cont to bp.1" ".*/\\* bp\.1 \\*/.*" + +proc check_thread_recorded { num } { + global decimal + + with_test_prefix "thread $num" { + gdb_test "thread $num" "Switching to thread $num.*" + + gdb_test "info record" [multi_line \ + "Active record target: record-btrace" \ + ".*" \ + "Recorded $decimal instructions in $decimal functions \[^\\\r\\\n\]*" \ + ] + } +} + +check_thread_recorded 1 +check_thread_recorded 2 |