From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id V6inCBq0vmqEISUAWB0awg (envelope-from ) for ; Thu, 01 Oct 2026 15:27:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=simark.ca; s=mail; t=1790882842; bh=S6A45fbjadQHk1aYZ18TKlM+V+Yb5IoYz0TOXhpTBqI=; h=Date:Subject:To:Cc:References:From:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=TWiUDUWn4xH3UqCro6o4wVbXwDmvOS/LWthRMRIw9O/G+U9GTUrz5s9dd5sslIDzk 9FxsM4gcfbnNPrgrF4aHci8cB3m8ViuGGrAdzrkW2uUE0+NiZ98jWkdSA05OC82R6M btM8b8+f5P9NMW82p/FBhz/TThMEqK0O25qEY6t4= Received: by simark.ca (Postfix, from userid 112) id 08E9E1E047; Thu, 01 Oct 2026 15:27: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=-2.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,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=simark.ca header.i=@simark.ca header.a=rsa-sha256 header.s=mail header.b=X9brn6Ln; dkim-atps=neutral Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 085561E047 for ; Thu, 01 Oct 2026 15:27:20 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8A0D64BB3BA3 for ; Thu, 1 Oct 2026 19:27:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8A0D64BB3BA3 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=simark.ca header.i=@simark.ca header.a=rsa-sha256 header.s=mail header.b=X9brn6Ln Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id C73074BB1C04 for ; Thu, 1 Oct 2026 19:26:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C73074BB1C04 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=simark.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=simark.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C73074BB1C04 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1790882812; cv=none; b=wxgYQQWUwkBt2umDur9ficU04CMPB3WZXlY5hTow5Jrh9OW3rbnnt2jrPYkH68ECQw9UqB4QIUA3OYcoW+GkeyAF0PbFV3KdVvAGgN3l3DJThpoHZrRrUzY2mOoAk9CR2Xy1M8Xjj99Pmt4WUZq85GlURasMvL8yhamCH+GRZ6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1790882812; c=relaxed/simple; bh=S6A45fbjadQHk1aYZ18TKlM+V+Yb5IoYz0TOXhpTBqI=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=TAiARXwCikb46iVCle5PZIxx/ymIS08WDYq0tv9pqHMY5n50rYCprqpoNFvjandf/kj5iMF0FEzznZO9OTozPtidOJ2Plun0XfrWLRvM3BIgC19Tmw7hB6Ty6aerHmjKDHPYRCVxkDgZHTBe6jwGk9s0Snohrdg9FhlqWqBH3xA= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=simark.ca header.i=@simark.ca header.a=rsa-sha256 header.s=mail header.b=X9brn6Ln DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C73074BB1C04 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=simark.ca; s=mail; t=1790882810; bh=S6A45fbjadQHk1aYZ18TKlM+V+Yb5IoYz0TOXhpTBqI=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=X9brn6LnklOjbUAYHceWiCGnDrQUbo187XHPaYg/twayftVcZv1GXGzJOoI/AJzqG TGIw0OZC5sIkAbWJE3gxAkMZUGPYRAX7WQ4yhX1QdfsBDLKI1HcY8AWVx96YhshW0S BLIrfMjoGGmyIP1beG5x3y/G4gsaF1O9xCGOwgLI= Received: by simark.ca (Postfix) id 8B0C71E047; Thu, 01 Oct 2026 15:26:49 -0400 (EDT) Message-ID: <0b9890d4-3a61-476a-bd8d-50d2b189f16d@simark.ca> Date: Thu, 1 Oct 2026 15:26:49 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] gdb: Implement stop-on-solib-events for GPU code objects To: Bratislav Filipovic , gdb-patches@sourceware.org Cc: Lancelot.Six@amd.com, TankutBaris.Aktemur@amd.com, luis.machado.foss@gmail.com, pedro@palves.net References: <20261001104000.7968-1-bfilipov@amd.com> Content-Language: fr From: Simon Marchi In-Reply-To: <20261001104000.7968-1-bfilipov@amd.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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 Hi Bratislav, Some advice for future submissions: - Since this is v2, pass `-v2` to git-format-patch or git-send-email so that it inserts "v2" in the subject. - Set `format.useAutoBase` in your git config to make git record the base commit on which your patch is based. This makes it easier to apply the patch. Ref: https://git-scm.com/docs/git-config#Documentation/git-config.txt-formatuseAutoBase On 10/1/26 6:35 AM, Bratislav Filipovic wrote: > GDB's "set stop-on-solib-events 1" setting allows users to stop execution > when shared libraries are loaded or unloaded, enabling inspection and > breakpoint placement before library code executes. This feature works for > CPU shared libraries but is not working for GPU code objects loaded by the > AMD ROCm runtime. > > This commit implements stop-on-solib-events support for GPU code objects, > making GPU code object load/unload events behave consistently with CPU > shared library events. > > The root cause is in amd_dbgapi_target_breakpoint::check_status(), which > unconditionally sets bs->stop = 0 and bs->print_it = print_it_noop, > regardless of the stop_on_solib_events setting. This is in contrast to > internal_breakpoint::check_status() for CPU shared libraries, which > respects the setting. > > The fix includes: > > 1. Generalize print_solib_event() function to eliminate code duplication > between CPU and GPU event printing. The function now accepts parameters > for event description, field names, and plural forms. This reduces > ~50 lines of duplicated code. > > 2. Add code_object_list_updated flag to amd_dbgapi_inferior_info to track > when AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED events occur during > process_event_queue(). Point #2, not true anymore. > diff --git a/gdb/NEWS b/gdb/NEWS > index 77ad2d3fc22..957ba2e8563 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -3,6 +3,12 @@ > > *** Changes since GDB 18 > > +* The 'set stop-on-solib-events' setting now applies to GPU code objects > + loaded by the AMD ROCm runtime, in addition to CPU shared libraries. > + When enabled (non-zero value), GDB will stop execution whenever GPU code Remove `(non-zero value)`, since stop-on-solib-events is now a bool. The MI changes should be documented in NEWS, in an "MI changes" section (see past releases for an example). > @@ -665,6 +682,29 @@ amd_dbgapi_target_breakpoint::check_status (struct bpstat *bs) > pulongest (resume_breakpoint_id.handle)); > > amd_dbgapi_event_processed (resume_event_id); > + > + /* If a CODE_OBJECT_LIST_UPDATED event was seen during event processing, > + check if the user requested to stop on solib events. This implements > + stop-on-solib-events for GPU code objects. */ > + if (code_object_list_updated && stop_on_solib_events != 0) Remove the `!= 0`, as stop_on_solib_events is now a bool. > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c > index 988737b6f96..05f55db6a7e 100644 > --- a/gdb/breakpoint.c > +++ b/gdb/breakpoint.c > @@ -5113,7 +5113,9 @@ print_bp_stop_message (bpstat *bs) > /* See breakpoint.h. */ > > void > -print_solib_event (bool is_catchpoint) > +print_solib_event (bool is_catchpoint, const char *event_description, > + const char *plural_description, const char *item_field_name, > + const char *object_kind) Instead of passing all these `const char *`, I think it would be better to centralize all the messages here. One reason is that when we'll have a second GPU target, we won't want to have it repeat the same GPU code object strings. Also, the strings for shared library are "hidden" as default parameters to this function, in the header, which makes it hard to follow. Finally, having "decomposed" messages like this is not good for translation, it's better to have full sentences. I would suggest something like this. In the header file: --- /* Strings used by print_solib_event to describe a kind of loadable object. */ struct print_solib_event_strings { /* Message printed when objects were added or removed. */ const char *stopped_msg; /* Message printed when no objects were added or removed. */ const char *stopped_no_change_msg; /* MI field name for each item of the "added" and "removed" lists. */ const char *item_field_name; /* Value of the MI "object-kind" field. */ const char *object_kind; }; /* Strings for shared libraries. */ extern const print_solib_event_strings print_solib_event_strings_shared_library; /* Strings for GPU code objects. */ extern const print_solib_event_strings print_solib_event_strings_gpu_code_object; /* A helper function that prints a shared library stopped event. IS_CATCHPOINT is true if the event is due to a "catch load" catchpoint, false otherwise. */ extern void print_solib_event (bool is_catchpoint, const print_solib_event_strings &strings); --- In the source file: --- /* See breakpoint.h. */ const print_solib_event_strings print_solib_event_strings_shared_library = { N_("Stopped due to shared library event:\n"), N_("Stopped due to shared library event (no libraries added or " "removed)\n"), "library", "shared-library" }; /* See breakpoint.h. */ const print_solib_event_strings print_solib_event_strings_gpu_code_object = { N_("Stopped due to GPU code object event:\n"), N_("Stopped due to GPU code object event (no GPU code objects added or " "removed)\n"), "code-object", "gpu-code-object" }; /* See breakpoint.h. */ void print_solib_event (bool is_catchpoint, const print_solib_event_strings &strings) --- And then in print_solib_event_strings you get the strings from the `strings` parameter. For the translated strings (those marked with N_), pass them through the _ macro: if (!is_catchpoint) current_uiout->text (any_added || any_deleted ? _(strings.stopped_msg) : _(strings.stopped_no_change_msg)); And then in amd-dbgapi-target.c, the print_solib_event call would look like: print_solib_event (false, print_solib_event_strings_gpu_code_object); Same for the other calls, but they would pass the other object. Just a note regarding the MI output, I think it's fine to add the "object-kind" value so that a frontend could adjust its display if it wants to say "GPU code objects" instead of "shared libraries". However, I would leave the existing "library" entry as-is. The reason being that frontends that do not know about this new GPU code object thing would expect to see a "library" entry, so it would be a backwards incompatible change. Also, if you leave it as "library", existing frontends can work just fine with GPU code objects (they'll present them as libraries), since there's nothing fundamentally different between shared libraries and GPU code objects in GDB, other than the name. So I'd remove the "item_field_name" from the struct above. Also, I would always emit the object-kind key, not just for GPU objects, it's clearer that way. It's not a breaking change to add an entry to a dict (or whatever MI calls them). Some tests will need to be updated though, so adding this entry could perhaps be done as a preparatory patch. > diff --git a/gdb/testsuite/gdb.rocm/solib-event.exp b/gdb/testsuite/gdb.rocm/solib-event.exp > new file mode 100644 > index 00000000000..f91b8d41995 > --- /dev/null > +++ b/gdb/testsuite/gdb.rocm/solib-event.exp > @@ -0,0 +1,112 @@ > +# Copyright 2026 Free Software Foundation, Inc. > +# Copyright 2026 Advanced Micro Devices, Inc. Remove AMD copyright. > + > +# 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 "set stop-on-solib-events 1" works for GPU code objects. > +# Tests both file:// events (hipModuleLoad) and memory:// events > +# (hipModuleLoadData), as well as unload events (hipModuleUnload). > +# Also tests that the default setting (0) does not stop execution. > + > +load_lib rocm.exp > + > +require allow_hip_tests > + > +standard_testfile .cpp > + > +# Build device module (.co file). > +set kernel_srcfile ${testfile}-kernel.cpp > +set hipmodule_path [standard_output_file ${testfile}.co] > + > +if {[gdb_compile $srcdir/$subdir/$kernel_srcfile \ > + $hipmodule_path object \ > + {debug hip additional_flags=--cuda-device-only}] != ""} { > + return > +} Since you have a "Build host executable" comment below, I would add a "Build GPU code object" above this. > +proc test_enabled {} { > + with_rocm_gpu_lock { > + clean_restart $::testfile > + > + if {![runto_main -inferior-args $::hipmodule_path]} { > + return > + } > + > + gdb_breakpoint [gdb_get_line_number "Enable SOLIB events here"] -temporary > + gdb_continue_to_breakpoint "at enable solib-event" > + > + gdb_test_no_output "set stop-on-solib-events 1" Since stop-on-solib-events is now a bool, I would suggest using on/off instead of 1/0 throughout. It would be nice to have a test for the MI change. > + > + with_test_prefix "file://" { > + gdb_breakpoint "test_file_load" -temporary > + gdb_continue_to_breakpoint "at test_file_load" > + > + # Test 1: file:// load event (hipModuleLoad). > + gdb_test "continue" \ > + "Stopped due to GPU code object event.*Inferior loaded file://\[^\r\n\]+" \ > + "load" > + > + # Test 2: file:// unload event (hipModuleUnload). > + gdb_test "continue" \ > + "Stopped due to GPU code object event.*Inferior unloaded file://\[^\r\n\]+" \ > + "unload" > + } > + > + with_test_prefix "memory://" { > + gdb_breakpoint "test_memory_load" -temporary > + gdb_continue_to_breakpoint "at test_memory_load" > + > + # Test 3: memory:// load event (hipModuleLoadData). > + gdb_test "continue" \ > + "Stopped due to GPU code object event.*Inferior loaded memory://\[^\r\n\]+" \ > + "load" > + > + # Test 4: memory:// unload event (hipModuleUnload). > + gdb_test "continue" \ > + "Stopped due to GPU code object event.*Inferior unloaded memory://\[^\r\n\]+" \ > + "unload" > + } > + } I don't know if we need a test for that, but how does it behave if we have some code objects loaded and we let the host program terminate? Does it fire some code object updated events? Simon