From patchwork Fri Jul 7 16:24:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magne Hov X-Patchwork-Id: 72309 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E81C2384C693 for ; Fri, 7 Jul 2023 16:25:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E81C2384C693 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688747119; bh=ZrCwduGDTcHdq153P++bbIFTDgPaDT4VVUyr0RLp2Mo=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Xva5DRs8Q0cbUdTsaH8fvh1KolxByckhhzGAYmmrHn43GJ8fovexb5Ek3FaBJaJOU hczEW73k+R46Womu9EHKKWwZZoxgtEAmYiLcC+2W5vkAm5dRTzwy+s3/3q+Rqrm5pe XPfgour4nHYnmCekkeZaDqNKJCTGGIdcHqjfJjXs= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by sourceware.org (Postfix) with ESMTPS id E4575385E005 for ; Fri, 7 Jul 2023 16:24:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E4575385E005 Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-3fbc5d5746cso23233295e9.2 for ; Fri, 07 Jul 2023 09:24:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688747093; x=1691339093; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZrCwduGDTcHdq153P++bbIFTDgPaDT4VVUyr0RLp2Mo=; b=AN95SkVsgSt9Up8nd/xldaMlLLg0bzDdjxA3CUxbQnbM9j1KUpzL/uUndF+u4TCfe8 CUcsxwWoidz+B2arjNQ3O1cvNwBo849tfJ4ekibNf9/UjkD1nsaLCtS1lvgN7N4Te4FX ipL7ou6GOhTDsnG8C3iHWCeFu/xuFsxY7y36Ow8TX9qlJQK//GjIiyg6J0bOHm9dLgtS w0Xo6qSWSlqiPFvXcF6UgEnro1bXhb1Ktv3JCg92COHEGZWSj2IRFDmX1mRRzyQp3+7l oMOYenTJ+W6dB+BteSNXeEsj6h77HxThN2C0kC2pcmV3WA+pb7DoUzIUtU8XFFDLzFhP BssA== X-Gm-Message-State: ABy/qLYmnfP4K7dEtRbdDL6OofbfYii50fV2epjzKtTVWki9cdj/pKVJ qsKNjAzs6+g4s0C27A3tAUwuegtkMyrSYvs2IaJ3s6Fo7lT8PgBMNDuCJvoKk5SRE88TUpJPPzu R6SXIJnBs9cUCsgE3u58EU0ZBo8B2AzDBJQbk3EL27oCbSm1mUUcW6j1PsaS5MWwqTFhjDYc= X-Google-Smtp-Source: APBJJlE+G3LVG0h4KLjqslwWEHF7AX2R/p6rHNKM3/3oxDmryItIV4tHEDJXH2ov8p/O8QsxLLM1Sw== X-Received: by 2002:a1c:4b17:0:b0:3fb:b008:2003 with SMTP id y23-20020a1c4b17000000b003fbb0082003mr4739758wma.38.1688747093590; Fri, 07 Jul 2023 09:24:53 -0700 (PDT) Received: from sbrinz-thinkpad.undoers.io (nrwh-14-b2-v4wan-164652-cust345.vm23.cable.virginm.net. [81.96.125.90]) by smtp.gmail.com with ESMTPSA id f11-20020a7bc8cb000000b003fa98908014sm2931834wml.8.2023.07.07.09.24.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jul 2023 09:24:53 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Magne Hov Subject: [PATCH v2 1/2] gdb: keep record of thread numbers for reverse execution targets Date: Fri, 7 Jul 2023 17:24:50 +0100 Message-Id: <20230707162451.3605544-2-mhov@undo.io> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230707162451.3605544-1-mhov@undo.io> References: <20230629083651.3145268-1-mhov@undo.io> <20230707162451.3605544-1-mhov@undo.io> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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-Patchwork-Original-From: Magne Hov via Gdb-patches From: Magne Hov Reply-To: Magne Hov Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Targets that support reverse execution may report threads that have previously been seen to exit. Currently, GDB assigns a new thread number every time it sees the same thread (re)appearing, but this is problematic because it makes the output of `info threads` inconsistent, and because thread-specific breakpoints depend on stable thread-numbers in order to stop on the right thread. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23454 Reviewed-By: Bruno Larsen --- gdb/inferior.c | 1 + gdb/inferior.h | 7 +++++++ gdb/thread.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/gdb/inferior.c b/gdb/inferior.c index eee4785fbf7..b6323110e69 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -258,6 +258,7 @@ inferior::clear_thread_list (bool silent) delete thr; }); ptid_thread_map.clear (); + ptid_thread_num_map.clear (); } /* Notify interpreters and observers that inferior INF was removed. */ diff --git a/gdb/inferior.h b/gdb/inferior.h index caa8e4d494a..33eb857645e 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -569,6 +569,13 @@ class inferior : public refcounted_object, /* The highest thread number this inferior ever had. */ int highest_thread_num = 0; + /* A map of ptid_t to global thread number and per-inferior thread + number, used for targets that support reverse execution. These + mappings are maintained for the lifetime of the inferior so that + thread numbers can be reused for threads that reappear after + having exited. */ + std::unordered_map, hash_ptid> ptid_thread_num_map; + /* State of GDB control of inferior process execution. See `struct inferior_control_state'. */ inferior_control_state control; diff --git a/gdb/thread.c b/gdb/thread.c index 7f7f035b5ab..ef3da68fc30 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -290,6 +290,15 @@ add_thread_silent (process_stratum_target *targ, ptid_t ptid) inf->num, ptid.to_string ().c_str (), targ->shortname ()); + /* Targets that support reverse execution can see the same thread + being added multiple times. If the state for an exited thread is + still present in the inferior's thread list it must be cleaned up + now before we add a new non-exited entry for the same thread. + Targets without reverse execution are not affected by this because + they do not reuse thread numbers. */ + if (target_can_execute_reverse ()) + delete_exited_threads (); + /* We may have an old thread with the same id in the thread list. If we do, it must be dead, otherwise we wouldn't be adding a new thread with the same id. The OS is reusing this id --- delete @@ -332,8 +341,33 @@ thread_info::thread_info (struct inferior *inf_, ptid_t ptid_) { gdb_assert (inf_ != NULL); - this->global_num = ++highest_thread_num; - this->per_inf_num = ++inf_->highest_thread_num; + /* Targets that support reverse execution may see the same thread be + created multiple times so a historical record must be maintained + and queried. For targets without reverse execution we don't look + up historical thread numbers because it leaves us vulnerable to + collisions between thread identifiers that have been recycled by + the target operating system. */ + if (target_can_execute_reverse ()) + { + auto pair = inf_->ptid_thread_num_map.find (ptid_); + if (pair != inf_->ptid_thread_num_map.end ()) + { + this->global_num = pair->second.first; + this->per_inf_num = pair->second.second; + } + else + { + this->global_num = ++highest_thread_num; + this->per_inf_num = ++inf_->highest_thread_num; + inf_->ptid_thread_num_map[ptid_] = std::make_pair (this->global_num, + this->per_inf_num); + } + } + else + { + this->global_num = ++highest_thread_num; + this->per_inf_num = ++inf_->highest_thread_num; + } /* Nothing to follow yet. */ this->pending_follow.set_spurious ();