From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id GZDlMNLGTmpG0iwAWB0awg (envelope-from ) for ; Wed, 08 Jul 2026 17:53:22 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=oct2025 header.b=t3igKhMd; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id BCED21E098; Wed, 08 Jul 2026 17:53:22 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 143F91E04F for ; Wed, 08 Jul 2026 17:53:22 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6F3D14BA2E24 for ; Wed, 8 Jul 2026 21:53:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F3D14BA2E24 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=oct2025 header.b=t3igKhMd Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 90D614BA2E10 for ; Wed, 8 Jul 2026 21:51:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 90D614BA2E10 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 90D614BA2E10 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783547518; cv=none; b=ru4p0c1jxCdR2SURIsaj/PB37fRCawT9J4C5h3J8XHf2Xm38j2DYGeonBOW2ol6ZsxXMSPdRBoMRYHXNUjJP17oylnTGNkHC9GCjlPtqyzR0WYc4gZndj390TxU5A2KNwDm5u3HLztkku8CfLZ27NCLxpZN64X6zPd0vpTZGslg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783547518; c=relaxed/simple; bh=nnX+ovE6BobSEdeFJHO+9TujxTZzGWjQW2fNKCPf8KA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=O+HxpSYLCRbxWF9Nn61v2o6MneqULN2ubDjl5mlfm7DWzWbsgAqJ6tZLJbbEh+1Ird78Pvw++kqW4kNIOGN98hwAeyy+BwrG+wq3Bbj9G77aG59vaEWJfwbJP/Phz7CGuqQfxEDDHiE7qbCRuPufoNJIJlOJ0O8pZXgIMhI9KeY= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=oct2025 header.b=t3igKhMd DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 90D614BA2E10 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 668Lpoqj117319 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Jul 2026 17:51:55 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 668Lpoqj117319 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=oct2025; t=1783547515; bh=FM2OW4/MmcWBiTR2/btsALGnDkYUq1ssn5yaVVFMzwE=; h=From:To:Cc:Subject:Date:In-Reply-To:From; b=t3igKhMdzKHr2VF5kyo7ous2KkMi9y2M14pYvn85fRMKsfl2uRm3l7JcdaE+MwRDJ O4Bytf2e9rmAvkeyS+hD0zx4+CfIK4p9tZIkzW0HaJnDBmc7YBqvaVeoro+YWHISsB dc3Eyv2EP6jNZIjJIPwT1VNy6nAhD490qMFTSjLJ8AjAiLss9UZ4UJSQZdHaYhwqGO nka2EZeiURW0NPsWzw6xEWNaeOtmslEqPtbJrlk6HtifmHNeObuMTBAk95MIfcy+od wiN2S79He8O8TzvrPaUeOjdkvVZvFg0eWh0Cxtv+s1RY+Z5J7VyNt1bo4+j3h8MMR2 Zx+QiQanPBwQA== Received: by simark.ca (Postfix) id 2FC0A1E090; Wed, 08 Jul 2026 17:51:49 -0400 (EDT) From: simon.marchi@polymtl.ca To: gdb-patches@sourceware.org Cc: Tom Tromey , Lancelot SIX , Simon Marchi , Lancelot Six Subject: [PATCH v3 01/10] gdb/solib-rocm: assert that host ops isn't rocm_solib_ops Date: Wed, 8 Jul 2026 17:51:33 -0400 Message-ID: <20260708215145.93134-2-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260708215145.93134-1-simon.marchi@polymtl.ca> References: <20260708215145.93134-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Jul 2026 21:51:50 +0000 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: Simon Marchi In some fork cases, the rocm_solib_target_inferior_created observer gets called while the child inferior (passed as a parameter) already has a rocm_solib_ops installed. Since we unconditionally wrap the existing solib_ops with a new rocm_solib_ops, we can end up with a chain of multiple rocm_solib_ops, like: rocm_solib_ops -> rocm_solib_ops -> svr4_solib_ops I don't think it is technically harmful as of now (unless the process does a ton of forks and the rocm_solib_ops accumulate), but it is for sure useless. Add an assert for this in the rocm_solib_ops constructor, which reveals the cases where this happens. When a fork happens with follow-fork-mode == child and detach-on-fork on, infrun's follow_fork_inferior function directly moves the program space from the parent the child inferior, as an optimization. Coming into rocm_solib_target_inferior_created, the inferior's pspace unexpectedly already has a rocm_solib_ops pushed. Fix this locally by using an inferior_forked observer. In the scenario described above, remove the rocm_solib_ops and restore the host solib_ops as the program space's solib_ops, to make it look as if infrun didn't do this trick. This requires adding two parameters to the inferior_forked observer (detach_on_fork and follow_child). This should probably be done by infrun directly at some point. The logic being that it's fine to do an optimization, but it should look as if it didn't occur. If infrun created a brand new pspace for the child, there wouldn't be a rocm_solib_ops there already. But I prefer a local fix for now. Finally, there are also the vfork cases, where the child inferior shares the program space with its parent, and therefore the child's program space already has a rocm_solib_ops installed. Address this case by returning early (the `inf->vfork_parent != nullptr` check), because there is nothing we want to do for a vfork child anyway. Change-Id: I2e76d111e96f1e01b6799b04da9cdd6f6e2984c9 Approved-by: Lancelot Six (amdgpu) --- gdb/amd-dbgapi-target.c | 3 ++- gdb/infrun.c | 3 ++- gdb/observable.h | 8 ++++++-- gdb/solib-rocm.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c index b4ca15069063..607fa39497dd 100644 --- a/gdb/amd-dbgapi-target.c +++ b/gdb/amd-dbgapi-target.c @@ -2392,7 +2392,8 @@ amd_dbgapi_inferior_execd (inferior *exec_inf, inferior *follow_inf) static void amd_dbgapi_inferior_forked (inferior *parent_inf, inferior *child_inf, - target_waitkind fork_kind) + target_waitkind fork_kind, bool detach_on_fork, + bool follow_child) { if (child_inf != nullptr) { diff --git a/gdb/infrun.c b/gdb/infrun.c index f51d301cf39a..ab3fde11cf94 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -699,7 +699,8 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"), target_follow_fork (child_inf, child_ptid, fork_kind, follow_child, detach_fork); - gdb::observers::inferior_forked.notify (parent_inf, child_inf, fork_kind); + gdb::observers::inferior_forked.notify (parent_inf, child_inf, fork_kind, + detach_fork, follow_child); /* target_follow_fork must leave the parent as the current inferior. If we want to follow the child, we make it the current one below. */ diff --git a/gdb/observable.h b/gdb/observable.h index 9f1c33ba7100..979e9d1c3ace 100644 --- a/gdb/observable.h +++ b/gdb/observable.h @@ -92,9 +92,13 @@ extern observable the child (because we follow only the child or we follow both), CHILD_INF is the child inferior. Otherwise, CHILD_INF is nullptr. - FORK_KIND is TARGET_WAITKIND_FORKED or TARGET_WAITKIND_VFORKED. */ + FORK_KIND is TARGET_WAITKIND_FORKED or TARGET_WAITKIND_VFORKED. + + DETACH_ON_FORK and FOLLOW_CHILD represent the "detach-on-fork" and + "follow-fork-mode" settings. */ extern observable inferior_forked; + target_waitkind /* fork_kind */, bool /* detach_on_fork */, + bool /* follow_child */> inferior_forked; /* The shared library specified by SOLIB has been loaded. Note that when gdb calls this observer, the library's symbols probably diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c index 73797801d6cd..48040111b196 100644 --- a/gdb/solib-rocm.c +++ b/gdb/solib-rocm.c @@ -165,8 +165,14 @@ struct rocm_solib_ops : public solib_ops explicit rocm_solib_ops (program_space *pspace, solib_ops_up host_ops) : solib_ops (pspace), m_host_ops (std::move (host_ops)) { + gdb_assert (m_host_ops != nullptr); + gdb_assert (dynamic_cast (m_host_ops.get ()) == nullptr); } + /* Release the host solib_ops. */ + solib_ops_up release_host_ops () + { return std::move (m_host_ops); } + /* The methods implemented by rocm_solib_ops. */ owning_intrusive_list current_sos () const override; void create_inferior_hook (int from_tty) const override; @@ -820,6 +826,10 @@ rocm_update_solib_list () static void rocm_solib_target_inferior_created (inferior *inf) { + /* A vfork child shares its pspace with its parent, do not touch anything. */ + if (inf->vfork_parent != nullptr) + return; + get_solib_info (inf)->solib_list.clear (); auto prev_ops = inf->pspace->release_solib_ops (); @@ -851,6 +861,24 @@ rocm_solib_target_inferior_execd (inferior *exec_inf, inferior *follow_inf) get_solib_info (exec_inf)->solib_list.clear (); } +static void +rocm_solib_target_inferior_forked (inferior *parent_inf, inferior *child_inf, + target_waitkind fork_kind, + bool detach_on_fork, bool follow_child) +{ + if (detach_on_fork && follow_child && fork_kind == TARGET_WAITKIND_FORKED) + { + /* In this particular configuration, infrun's follow_fork_inferior + function moves the parent pspace to the child directly. Remove the + existing rocm_solib_ops from the child and restore the host solib_ops, + to make it look like a brand new pspace. */ + auto rocm_ops_holder = child_inf->pspace->release_solib_ops (); + auto rocm_ops + = gdb::checked_static_cast (rocm_ops_holder.get ()); + child_inf->pspace->set_solib_ops (rocm_ops->release_host_ops ()); + } +} + INIT_GDB_FILE (rocm_solib) { /* The dependency on the amd-dbgapi exists because solib-rocm's @@ -864,4 +892,7 @@ INIT_GDB_FILE (rocm_solib) gdb::observers::inferior_execd.attach (rocm_solib_target_inferior_execd, "solib-rocm", { &get_amd_dbgapi_target_inferior_execd_observer_token () }); + + gdb::observers::inferior_forked.attach + (rocm_solib_target_inferior_forked, "solib-rocm"); } -- 2.55.0