From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by sourceware.org (Postfix) with ESMTPS id 2315E3851C27 for ; Tue, 16 Mar 2021 09:35:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2315E3851C27 IronPort-SDR: iFNtpQGY1N2qy0tbPm34VNh+VPmkiuuaMBYR+2UVlKIub7X0TY/+tjNUkaj1Q6M2xDNefZnuhc zvbUSZmnUT8g== X-IronPort-AV: E=McAfee;i="6000,8403,9924"; a="176826009" X-IronPort-AV: E=Sophos;i="5.81,251,1610438400"; d="scan'208";a="176826009" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Mar 2021 02:35:07 -0700 IronPort-SDR: No27qu4VBdU8/m64O+TNTvu1NfJFnXLKqYjAhcBneWYpWkFgF1lFf1Yg5IDLle79a0zysCL6Jq MR+0Q0gC9DpA== X-IronPort-AV: E=Sophos;i="5.81,251,1610438400"; d="scan'208";a="605193563" Received: from labpc2407.iul.intel.com (HELO localhost) ([172.28.50.61]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Mar 2021 02:35:06 -0700 From: Markus Metzger To: gdb-patches@sourceware.org Subject: [PATCH 2/4] gdb, infrun, record: fix hang when step-over fails with no-history Date: Tue, 16 Mar 2021 10:34:59 +0100 Message-Id: <20210316093501.936148-3-markus.t.metzger@intel.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210316093501.936148-1-markus.t.metzger@intel.com> References: <20210316093501.936148-1-markus.t.metzger@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Mar 2021 09:35:12 -0000 When trying to step over a breakpoint at the end of the trace while another thread is replaying, the step-over will fail with no-history. This does not clear step_over_info so a subsequent resume will cause GDB to not resume the thread and expect a SIGTRAP to complete the step-over. This will never come causing GDB to hang in the wait-for-event poll. This is a variant of the issue fixed in the parent commit. That commit addressed the issue for a single-threaded process and fixed an issue with reverse/replay stepping in general. This commit addresses the issue for a multi-threaded process. In this case, the single-step does not complete. Finish an in-flight step-over when a thread stopped with NO_HISTORY. Since we did not move, we will simply start the step-over again. gdb/ChangeLog: 2021-03-02 Markus Metzger * infrun.c (finish_step_over): New declaration. (handle_inferior_event): Call finish_step_over. gdb/testsuite/ChangeLog: 2021-03-02 Markus Metzger * gdb.btrace/multi-thread-break-hang.exp: New file. --- gdb/infrun.c | 6 ++ .../gdb.btrace/multi-thread-break-hang.exp | 92 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 gdb/testsuite/gdb.btrace/multi-thread-break-hang.exp diff --git a/gdb/infrun.c b/gdb/infrun.c index 591fda93d21..e79094ad2b2 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -95,6 +95,8 @@ static void resume (gdb_signal sig); static void wait_for_inferior (inferior *inf); +static int finish_step_over (struct execution_control_state *ecs); + /* Asynchronous signal handler registered as event loop source for when we have pending events ready to be passed to the core. */ static struct async_event_handler *infrun_async_inferior_event_token; @@ -5543,6 +5545,10 @@ handle_inferior_event (struct execution_control_state *ecs) return; gdb::observers::no_history.notify (); + + /* Cancel an in-flight step-over. It will not succeed since we + won't be able to step at the end of the execution history. */ + finish_step_over (ecs); stop_waiting (ecs); return; } diff --git a/gdb/testsuite/gdb.btrace/multi-thread-break-hang.exp b/gdb/testsuite/gdb.btrace/multi-thread-break-hang.exp new file mode 100644 index 00000000000..8496de5b36c --- /dev/null +++ b/gdb/testsuite/gdb.btrace/multi-thread-break-hang.exp @@ -0,0 +1,92 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2021 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 . + +# Test that we cancel an in-flight step-over at the end of the execution +# history as long as some other thread is still replaying. +# +# This used to cause GDB to hang in poll (). + +if { [skip_btrace_tests] } { + unsupported "target does not support record-btrace" + return -1 +} + +standard_testfile multi-thread-step.c +if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug libs=-lpthread}] { + return -1 +} + +if ![runto_main] { + untested "failed to run to main" + return -1 +} + +# Set up breakpoints. +set bp_1 [gdb_get_line_number "bp.1" $srcfile] +set bp_2 [gdb_get_line_number "bp.2" $srcfile] + +# Trace the code between the two breakpoints. +gdb_breakpoint $srcfile:$bp_1 +gdb_continue_to_breakpoint "continue to bp.1" ".*$srcfile:$bp_1\r\n.*" + +# Make sure GDB knows about the new thread. +gdb_test "info threads" ".*" +gdb_test_no_output "record btrace" + +# We have two threads at or close to bp.1 but handled only one stop event. +# Remove the breakpoint so we do not need to deal with the 2nd event. +delete_breakpoints +gdb_breakpoint $srcfile:$bp_2 +gdb_continue_to_breakpoint "continue to bp.2" ".*$srcfile:$bp_2\r\n.*" + +# Determine the thread that reported the breakpoint. +set thread "bad" +gdb_test_multiple "thread" "thread" { + -re "Current thread is \($decimal\).*\r\n$gdb_prompt $" { + set thread $expect_out(1,string) + } +} + +# Determine the other thread. +set other "bad" +if { $thread == 1 } { + set other 2 +} elseif { $thread == 2 } { + set other 1 +} + +# This test works for scheduler-locking 'on' or 'step'; 'replay' would +# implicitly stop replaying, avoiding the problem; 'off' would step one +# and resume the other. The test would work for the current lock-step +# implementation. +gdb_test_no_output "set scheduler-locking step" + +# Start replaying the other thread. This will prevent stepping the thread +# that reported the event. +gdb_test "thread apply $other record goto begin" ".*" +gdb_test "thread apply $other info record" "Replay in progress.*" + +# We're at a breakpoint so this triggers step-over. Since we're at the +# end of the trace, the step will fail. +gdb_test "stepi" "No more reverse-execution history.*" "stepi.1" + +# We used to hang at the second step since step-over insisted on polling +# the next event. +gdb_test "stepi" "No more reverse-execution history.*" "stepi.2" + +# Do one more just in case. +gdb_test "stepi" "No more reverse-execution history.*" "stepi.3" -- 2.29.2 Intel Deutschland GmbH Registered Address: Am Campeon 10, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928