Skip to content

Fix __builtin_verbose_trap support for GPU and CPU - #199

Open
amd-bfilipov wants to merge 3 commits into
amd-stagingfrom
users/bfilipov/fix-s_trap-2-pc-adjustment
Open

Fix __builtin_verbose_trap support for GPU and CPU#199
amd-bfilipov wants to merge 3 commits into
amd-stagingfrom
users/bfilipov/fix-s_trap-2-pc-adjustment

Conversation

@amd-bfilipov

@amd-bfilipov amd-bfilipov commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Ticket: AIROCGDB-558

Summary

Implements complete support for __builtin_verbose_trap on both AMD GPU and CPU (x86_64), making verbose trap diagnostic messages visible in backtraces.

Problem

When __builtin_verbose_trap fired, the diagnostic inline frames were not visible in backtraces, making it impossible to see the trap category and message. Two issues prevented this:

  1. PC pointing past trap instruction: After s_trap 2 on GPU, PC was not rewound to point at the trap instruction, causing GDB to miss the inlined DWARF frame containing the diagnostic info
  2. Inline frames hidden by default: GDB's skip_inline_frames() intentionally hides inline frames to improve stepping experience, but this also hid the verbose trap frames

Solution

This PR provides a two-part fix:

1. PC Adjustment for s_trap 2 (GPU)

Rewind PC by 4 bytes when a wave stops with s_trap 2, similar to breakpoint handling. This ensures the PC remains in the inlined DWARF frame containing __builtin_verbose_trap debug info.

Files changed:

  • gdb/amd-dbgapi-target.c - PC adjustment logic
  • gdb/testsuite/gdb.rocm/builtin_verbose_trap.{cpp,exp} - Test coverage

2. gdbarch Hook for Inline Frame Control (GPU + CPU)

Adds architecture-specific control over inline frame visibility using GDB's gdbarch pattern. Architectures can now prevent skipping of compiler-generated inline frames containing diagnostic information.

Changes:

  • gdb/gdbarch_components.py - Define show_verbose_trap_inline_frame method
  • gdb/arch-utils.{c,h} - Default implementation (preserves current behavior)
  • gdb/amdgpu-tdep.c - AMD GPU implementation (checks SIGABRT + name pattern)
  • gdb/amd64-linux-tdep.c - CPU x86_64 implementation (checks SIGILL + name pattern)
  • gdb/inline-frame.c - Call gdbarch hook in skip loop
  • gdb/gdbarch-gen.{c,h} - Auto-generated

Detection logic:

  • Only shows frame when both conditions met:
    1. Stop signal matches trap type (SIGABRT for GPU s_trap 2, SIGILL for CPU ud2)
    2. Symbol name starts with __clang_trap_msg$<category>$<message>
  • Preserves normal stepping behavior (frames hidden when user steps into them)

Results

Before:

Thread 6 received signal SIGABRT, Aborted.
#0  test_trap_kernel () at test.cpp:24

After (GPU):

Thread 6 received signal SIGABRT, Aborted.
#0  __clang_trap_msg$check verbose$This is verbose trap! ()
    at test.cpp:23
#1  test_trap_kernel () at test.cpp:24

After (CPU):

Program received signal SIGILL, Illegal instruction.
#0  __clang_trap_msg$check negative$Value must be non-negative! ()
    at test.cpp:4
#1  check_value (value=-1) at test.cpp:5
#2  main () at test.cpp:12

@amd-bfilipov
amd-bfilipov requested a review from a team as a code owner July 10, 2026 13:23
Comment thread gdb/amd-dbgapi-target.c Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.exp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.exp Outdated
Comment thread gdb/amd-dbgapi-target.c
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.cpp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.cpp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.cpp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.exp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_trap.exp Outdated
@amd-bfilipov
amd-bfilipov force-pushed the users/bfilipov/fix-s_trap-2-pc-adjustment branch 2 times, most recently from 998fd18 to f65ff67 Compare July 13, 2026 13:36

@aktemur aktemur left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash the second patch to the second, so that the test accompanies the fix.

Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.cpp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.cpp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.exp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.exp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.exp Outdated
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.exp Outdated
@aktemur aktemur assigned amd-bfilipov and unassigned aktemur Jul 15, 2026
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# Test that __builtin_trap PC is correctly adjusted

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is now using __builtin_verbose_trap, this test is about that.

# If PC adjustment is working, PC should be at the s_trap instruction.
gdb_test "x/i \$pc" \
".*s_trap.*" \
"PC points to trap instruction"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main thing we'd want to test here is wether the current frame gives us the trap, i.e. does your message show un bt or similar message.

The expectation is to see that in the message with the SIGABRT signal, saying where we stopped.

@amd-bfilipov
amd-bfilipov force-pushed the users/bfilipov/fix-s_trap-2-pc-adjustment branch from f65ff67 to 994a6fa Compare July 30, 2026 09:49
Comment thread gdb/amd64-linux-tdep.c
Comment thread gdb/amdgpu-tdep.c
Comment thread gdb/arch-utils.c Outdated
Comment thread gdb/inline-frame.c
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.cpp
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.exp
Comment thread gdb/testsuite/gdb.rocm/builtin_verbose_trap.exp Outdated
@amd-bfilipov amd-bfilipov changed the title Adjust PC for abort trap (s_trap 2) to improve __builtin_verbose_trap support Fix __builtin_verbose_trap support for GPU and CPU Jul 30, 2026
@amd-bfilipov
amd-bfilipov force-pushed the users/bfilipov/fix-s_trap-2-pc-adjustment branch 2 times, most recently from c9f8030 to 60cbb93 Compare August 3, 2026 13:19

@lancesix lancesix left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test should exercise the stepping as well. And since you add host support, I suppose this should have a test as well.

@amd-bfilipov
amd-bfilipov force-pushed the users/bfilipov/fix-s_trap-2-pc-adjustment branch 4 times, most recently from 87123a0 to 7e59e5d Compare August 3, 2026 15:18
When a wave stops with s_trap 2,
rewind the PC by 4 bytes to point at the trap instruction, similar
to breakpoint handling.

This ensures the PC remains in the inlined DWARF frame containing
debug info for __builtin_verbose_trap messages.

Fixes: ROCM-22957

Add test for s_trap 2 PC adjustment

Test that __builtin_verbose_trap() correctly stops with PC pointing
at the trap instruction.

Related: ROCM-22957
@amd-bfilipov
amd-bfilipov force-pushed the users/bfilipov/fix-s_trap-2-pc-adjustment branch from 7e59e5d to a36876d Compare August 3, 2026 16:00
Implement architecture-specific control over inline frame visibility
for verbose trap scenarios using the gdbarch pattern.

Add new gdbarch method `show_verbose_trap_inline_frame` that allows
architectures to prevent skipping of compiler-generated inline frames
containing diagnostic information (e.g., __builtin_verbose_trap).

Changes:
- gdbarch_components.py: Define new Method `show_verbose_trap_inline_frame`
- arch-utils.{c,h}: Provide default implementation (returns false)
- amdgpu-tdep.c: Implement AMD GPU-specific version that detects
  __clang_trap_msg$... frames by name pattern
- inline-frame.c: Call gdbarch hook in skip_inline_frames() loop
- gdbarch-gen.{c,h}: Regenerated from gdbarch_components.py

This approach keeps architecture-specific logic (GPU vs CPU) in
architecture-specific files, following GDB's design patterns.

Ticket: ROCM-22957 / AIROCGDB-558
@amd-bfilipov
amd-bfilipov force-pushed the users/bfilipov/fix-s_trap-2-pc-adjustment branch from a36876d to 1b9efda Compare August 4, 2026 12:16
__builtin_verbose_trap is a Clang builtin that allows embedding custom
trap messages in the binary for better crash diagnostics.

Add test for CPU (x86_64) __builtin_verbose_trap inline frame display.
This complements the GPU test in gdb.rocm/builtin_verbose_trap.exp.

The test verifies that:
- Normal inline frames (add_numbers) are hidden during stepping
- Verbose trap inline frame IS shown when trap fires with SIGILL
- CPU uses ud2 instruction which generates SIGILL (unlike GPU s_trap
  which generates SIGABRT)

Both GPU and CPU share the same DWARF pattern for verbose trap:
__clang_trap_msg$<category>$<message>
@amd-bfilipov

Copy link
Copy Markdown
Contributor Author

The test should exercise the stepping as well. And since you add host support, I suppose this should have a test as well.

Ok. Added another inline function to the test, so the test steps over it and checks whether regular inline frames stay hidden.
Added a cpu version of the test. It's in a separate commit but we can rearrange that if needed.

@jhuber6

jhuber6 commented Aug 5, 2026

Copy link
Copy Markdown

I'm not intimately familiar with gdb, but the lldb output seems much more descriptive here. Any chance we can do something similar? From the example with -fsanitize-runtime=trap -fsanitize=undefined in Clang.

(lldb) run
Process 302532 launched: 'llvm-project/build/a.out' (x86_64)
Process 302532 stopped
* thread #1, name = 'a.out', stop reason = Undefined Behavior Sanitizer: signed integer addition overflow in 'x + 1'
       frame #1: 0x0000555555555750 a.out`signed_overflow(x=2147483647) at ubsan_test.c:4:39
   1     #include <limits.h>
   2     #include <stdio.h>
   3     
-> 4     int signed_overflow(int x) { return x + 1; }
   5     
   6     int shift_oob(int x, int amount) { return x << amount; }
   7     

Comment thread gdb/amd-dbgapi-target.c

When dealing with a corefile, it is expected that the PC has
been adjusted before generating the corefile, so no need to
re-do it now. */
if ((stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0
if (((stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0
|| (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_ASSERT_TRAP) != 0)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I am not sure this should be the way to go.

I have ROCm/rocm-systems#9776 to change the trap handler behaviour so this is not necessary. Such change would fix other issues reported independent to this PR.

@palves palves left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re. the "gdb: Add gdbarch hook to show verbose trap inline frames" patch:

The commit log needs to be turned upside down.

This adds the gdbarch hook, yes, but it needs to begin by stating what the problem is, talk about __builtin_verbose_trap, show what goes wrong today without the fix.

I.e., establish rationale for why a change is needed.

Explain that this affects both CPU and GPU.

Then state how we're fixing this. The new gdbarch hook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants