From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id ODSFIhjkwmLx+gsAWB0awg (envelope-from ) for ; Mon, 04 Jul 2022 08:59:04 -0400 Received: by simark.ca (Postfix, from userid 112) id 87D0A1E22B; Mon, 4 Jul 2022 08:59:04 -0400 (EDT) Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=NwNJwP8o; dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id B4D1C1E222 for ; Mon, 4 Jul 2022 08:59:03 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 639B3385C331 for ; Mon, 4 Jul 2022 12:59:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 639B3385C331 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1656939543; bh=+LKjZwHv8tLrIMHammQzlDrK53N6UyyqXA8Bpjl8iE0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=NwNJwP8oHndn6Z60K84sNFl7jgYAUmFhBB3ERFM/tQThzcaXY2sZDyge1io35UPwr s8KRkgKt04Df53CB1CGdXtg9mjPdcsKwrvUteg72uobBWh6FoWnuIFfevSQXmk+qtz exgOl0B6idGuf1x2yYpfcAkOHuzICAMrSd3BlJt4= Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by sourceware.org (Postfix) with ESMTPS id BB2FE385C321 for ; Mon, 4 Jul 2022 12:58:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BB2FE385C321 X-IronPort-AV: E=McAfee;i="6400,9594,10397"; a="266148557" X-IronPort-AV: E=Sophos;i="5.92,243,1650956400"; d="scan'208";a="266148557" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 05:58:07 -0700 X-IronPort-AV: E=Sophos;i="5.92,243,1650956400"; d="scan'208";a="769251699" Received: from labpc2407.iul.intel.com (HELO localhost) ([172.28.48.175]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 05:58:06 -0700 To: gdb-patches@sourceware.org Subject: [PATCH v3 2/4] gdb, infrun, record: fix hang when step-over fails with no-history Date: Mon, 4 Jul 2022 13:54:05 +0200 Message-Id: <20220704115407.1239498-3-markus.t.metzger@intel.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220704115407.1239498-1-markus.t.metzger@intel.com> References: <20220704115407.1239498-1-markus.t.metzger@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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: , From: Markus Metzger via Gdb-patches Reply-To: Markus Metzger Cc: pedro@palves.net Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" 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/infrun.c | 14 +++ .../gdb.btrace/multi-thread-break-hang.exp | 88 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 gdb/testsuite/gdb.btrace/multi-thread-break-hang.exp diff --git a/gdb/infrun.c b/gdb/infrun.c index a821ba06b22..3fa262efb01 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -74,6 +74,8 @@ #include "gdbsupport/common-debug.h" #include "gdbsupport/buildargv.h" +struct execution_control_state; + /* Prototypes for local functions */ static void sig_print_info (enum gdb_signal); @@ -103,6 +105,8 @@ static bool start_step_over (void); static bool step_over_info_valid_p (void); +static int finish_step_over (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; @@ -5872,6 +5876,16 @@ 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 may call restart_threads, which may change the + current thread. make sure we leave the event thread as the + current thread. */ + scoped_restore_current_thread restore_thread; + 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..df0c984cee0 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/multi-thread-break-hang.exp @@ -0,0 +1,88 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2021-2022 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 pthreads}] { + 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.*" + +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 [get_integer_valueof "\$_thread" bad] + +# Determine the other thread. +set other "bad" +if { $thread == 1 } { + set other 2 +} elseif { $thread == 2 } { + set other 1 +} + +# This test requires scheduler-locking 'on' or 'step'; 'replay' would +# implicitly stop replaying, avoiding the problem; 'off' would step one +# and resume the other. +# +# With the current record-btrace implementation that steps all resumed +# threads in lock-step, 'off' might actually pass but we don't want to +# bake that behavior into tests. +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.35.3 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