Repository navigation
[FEA]: Debugger pretty-printers: cuda::annotated_ptr #10100 #10232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Jacobfaib
merged 10 commits into
NVIDIA:main
from
iakshayubale:add-annotated-ptr-pretty-printers
Oct 16, 2026
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
869b837
feat: Add debugger pretty-printers for cuda::annotated_ptr
iakshayubale 341af83
[pre-commit.ci] auto code formatting
pre-commit-ci[bot] 7c28a75
refactor: enhance annotated_ptr pretty printers with cccl_common helpers
iakshayubale a0848e7
fix: address review comments on type name handling and fixture values
iakshayubale f7292b4
[pre-commit.ci] auto code formatting
pre-commit-ci[bot] c65a3cb
fix: correct test case argument format in annotated_ptr CMakeLists
iakshayubale 914054d
Fix imports
iakshayubale 8831a5c
fix: use correct parameter in test cases
iakshayubale 89393d2
fix: update LLDB expected output to include type information
iakshayubale e8f3948
Address review feedback on annotated_ptr pretty-printers
iakshayubale File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| """GDB pretty printer for cuda::annotated_ptr.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from types import ModuleType | ||
|
|
||
| import cccl_common | ||
|
|
||
| import gdb | ||
| import gdb.printing | ||
|
|
||
|
|
||
| def _is_annotated_ptr(value_type: gdb.Type) -> bool: | ||
| """Check if a GDB type represents cuda::annotated_ptr.""" | ||
| value_type = cccl_common.canonical_type(value_type) | ||
| type_name = cccl_common.public_type_name(value_type) | ||
| template_name = cccl_common.template_name(value_type) | ||
| return ( | ||
| type_name.startswith("cuda::") | ||
| and template_name.rsplit("::", 1)[-1] == "annotated_ptr" | ||
| ) | ||
|
|
||
|
|
||
| class AnnotatedPtrPrinter: | ||
| """Expose cuda::annotated_ptr type and pointer value to GDB.""" | ||
|
|
||
| def __init__(self, value: gdb.Value) -> None: | ||
| # Strip reference to access members | ||
| self.value = cccl_common.strip_reference_value(value) | ||
| # Store canonical type for type name display | ||
| self.canonical_type_obj = cccl_common.canonical_type(self.value.type) | ||
| # Extract base type name without template arguments to avoid duplication | ||
| self.type_name = cccl_common.template_name( | ||
| cccl_common.public_type_name(self.canonical_type_obj) | ||
| ) | ||
|
|
||
| def _template_arguments(self) -> tuple[str, str]: | ||
| """Return the pointee and property type names.""" | ||
| pointee_type = self.canonical_type_obj.template_argument(0) | ||
| property_type = self.canonical_type_obj.template_argument(1) | ||
| return ( | ||
| cccl_common.public_type_name(pointee_type), | ||
| cccl_common.public_type_name(property_type), | ||
| ) | ||
|
|
||
| def _pointer_display(self) -> str: | ||
| """Return the stored pointer, spelling a null pointer as nullptr.""" | ||
| ptr_value = int(self.value["__repr"]) | ||
| return "nullptr" if ptr_value == 0 else f"{ptr_value:#x}" | ||
|
|
||
| def to_string(self) -> str: | ||
| """Combine type info and pointer value into annotated_ptr display.""" | ||
| pointee_type_name, property_type_name = self._template_arguments() | ||
| full_type = f"{self.type_name}<{pointee_type_name}, {property_type_name}>" | ||
| return f"{full_type} -> {self._pointer_display()}" | ||
|
|
||
|
|
||
| class AnnotatedPtrPrinterLookup(gdb.printing.PrettyPrinter): | ||
| """Select the cuda::annotated_ptr printer by its public class name.""" | ||
|
|
||
| def __init__(self) -> None: | ||
| super().__init__("cuda::annotated_ptr") | ||
|
|
||
| def __call__(self, value: gdb.Value) -> AnnotatedPtrPrinter | None: | ||
| if _is_annotated_ptr(value.type): | ||
| return AnnotatedPtrPrinter(value) | ||
| return None | ||
|
|
||
|
|
||
| def register(objfile: ModuleType) -> None: | ||
| """Register the cuda::annotated_ptr printer with GDB.""" | ||
| gdb.printing.register_pretty_printer( | ||
| objfile, AnnotatedPtrPrinterLookup(), replace=True | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| """LLDB pretty printer for cuda::annotated_ptr.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import re | ||
|
|
||
| import cccl_common | ||
|
|
||
| import lldb | ||
|
|
||
| _ANNOTATED_PTR_PATTERN = re.compile(r"^cuda::annotated_ptr<.+,.+>$") | ||
| InternalDict = dict[str, object] | ||
|
|
||
|
|
||
| def is_annotated_ptr(value_type: lldb.SBType, _internal_dict: InternalDict) -> bool: | ||
| type_name = cccl_common.canonical_type_name(value_type) | ||
| return _ANNOTATED_PTR_PATTERN.fullmatch(type_name) is not None | ||
|
|
||
|
|
||
| def annotated_ptr_summary(value: lldb.SBValue, _internal_dict: InternalDict) -> str: | ||
| # LLDB already renders the declared type, so the summary only adds the pointer. | ||
| repr_ptr = cccl_common.strip_reference_value(value).GetChildMemberWithName("__repr") | ||
| if not repr_ptr.IsValid(): | ||
| return "-> unavailable" | ||
|
|
||
| error = lldb.SBError() | ||
| ptr_addr = repr_ptr.GetValueAsUnsigned(error) | ||
| if error.Fail(): | ||
| return "-> unavailable" | ||
| return "-> nullptr" if ptr_addr == 0 else f"-> {ptr_addr:#x}" | ||
|
|
||
|
|
||
| def register(debugger: lldb.SBDebugger, category: str, module: str) -> None: | ||
| """Register CUDA annotated_ptr formatters with LLDB.""" | ||
| debugger.HandleCommand( | ||
| f"type summary add --category {category} --python-function " | ||
| f"{module}.annotated_ptr_summary --recognizer-function " | ||
| f"{module}.is_annotated_ptr" | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| libcudacxx_add_pretty_printer_test( | ||
| NAME annotated_ptr | ||
| SOURCES source.cu | ||
| CASES | ||
| # gersemi: off | ||
| --case inspect_streaming annotated_ptr.streaming ptr | ||
| --case inspect_persisting annotated_ptr.persisting ptr | ||
| --case inspect_global annotated_ptr.global ptr | ||
| --case inspect_null annotated_ptr.null ptr | ||
| --case inspect_before_update annotated_ptr.update.before ptr | ||
| --case inspect_after_update annotated_ptr.update.after ptr | ||
| # gersemi: on | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| =============== annotated_ptr.streaming begin =============== | ||
| cuda::annotated_ptr<int, cuda::access_property::streaming> -> <address> | ||
| =============== annotated_ptr.streaming end =============== | ||
| =============== annotated_ptr.persisting begin =============== | ||
| cuda::annotated_ptr<int, cuda::access_property::persisting> -> <address> | ||
| =============== annotated_ptr.persisting end =============== | ||
| =============== annotated_ptr.global begin =============== | ||
| cuda::annotated_ptr<float, cuda::access_property::global> -> <address> | ||
| =============== annotated_ptr.global end =============== | ||
| =============== annotated_ptr.null begin =============== | ||
| cuda::annotated_ptr<int, cuda::access_property::streaming> -> nullptr | ||
| =============== annotated_ptr.null end =============== | ||
| =============== annotated_ptr.update.before begin =============== | ||
| cuda::annotated_ptr<int, cuda::access_property::streaming> -> <address> | ||
| =============== annotated_ptr.update.before end =============== | ||
| =============== annotated_ptr.update.after begin =============== | ||
| cuda::annotated_ptr<int, cuda::access_property::streaming> -> nullptr | ||
| =============== annotated_ptr.update.after end =============== |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| =============== annotated_ptr.streaming begin =============== | ||
| (const cuda::annotated_ptr<int, cuda::access_property::streaming> &) <address> -> <address> | ||
| =============== annotated_ptr.streaming end =============== | ||
| =============== annotated_ptr.persisting begin =============== | ||
| (const cuda::annotated_ptr<int, cuda::access_property::persisting> &) <address> -> <address> | ||
| =============== annotated_ptr.persisting end =============== | ||
| =============== annotated_ptr.global begin =============== | ||
| (const cuda::annotated_ptr<float, cuda::access_property::global> &) <address> -> <address> | ||
| =============== annotated_ptr.global end =============== | ||
| =============== annotated_ptr.null begin =============== | ||
| (const cuda::annotated_ptr<int, cuda::access_property::streaming> &) <address> -> nullptr | ||
| =============== annotated_ptr.null end =============== | ||
| =============== annotated_ptr.update.before begin =============== | ||
| (const cuda::annotated_ptr<int, cuda::access_property::streaming> &) <address> -> <address> | ||
| =============== annotated_ptr.update.before end =============== | ||
| =============== annotated_ptr.update.after begin =============== | ||
| (const cuda::annotated_ptr<int, cuda::access_property::streaming> &) <address> -> nullptr | ||
| =============== annotated_ptr.update.after end =============== |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| #include <cuda/annotated_ptr> | ||
|
|
||
| // Give the inspected parameter a stack location that survives optimization, so the | ||
| // debugger can read it in this frame. Without this the parameter stays in a | ||
| // caller-clobbered register and reads as unavailable at -O3. | ||
| #define KEEP_FOR_DEBUGGER(values) asm volatile("" : : "g"(&(values)) : "memory") | ||
|
|
||
| [[gnu::noinline]] void inspect_streaming(const cuda::annotated_ptr<int, cuda::access_property::streaming>& ptr) | ||
| { | ||
| KEEP_FOR_DEBUGGER(ptr); | ||
| } | ||
|
Jacobfaib marked this conversation as resolved.
Resolved
|
||
|
|
||
| [[gnu::noinline]] void inspect_persisting(const cuda::annotated_ptr<int, cuda::access_property::persisting>& ptr) | ||
| { | ||
| KEEP_FOR_DEBUGGER(ptr); | ||
| } | ||
|
|
||
| [[gnu::noinline]] void inspect_global(const cuda::annotated_ptr<float, cuda::access_property::global>& ptr) | ||
| { | ||
| KEEP_FOR_DEBUGGER(ptr); | ||
| } | ||
|
|
||
| [[gnu::noinline]] void inspect_null(const cuda::annotated_ptr<int, cuda::access_property::streaming>& ptr) | ||
| { | ||
| KEEP_FOR_DEBUGGER(ptr); | ||
| } | ||
|
|
||
| [[gnu::noinline]] void inspect_before_update(const cuda::annotated_ptr<int, cuda::access_property::streaming>& ptr) | ||
| { | ||
| KEEP_FOR_DEBUGGER(ptr); | ||
| } | ||
|
|
||
| [[gnu::noinline]] void inspect_after_update(const cuda::annotated_ptr<int, cuda::access_property::streaming>& ptr) | ||
| { | ||
| KEEP_FOR_DEBUGGER(ptr); | ||
| } | ||
|
|
||
| int main() | ||
| { | ||
| // Allocate test data with mutable backing (required by annotated_ptr) | ||
| int streaming_data = 42; | ||
| int persisting_data = 100; | ||
| float global_data = 3.14f; | ||
| int updated_data = 7; | ||
|
|
||
| const cuda::annotated_ptr<int, cuda::access_property::streaming> streaming_ptr(&streaming_data); | ||
| inspect_streaming(streaming_ptr); | ||
|
|
||
| const cuda::annotated_ptr<int, cuda::access_property::persisting> persisting_ptr(&persisting_data); | ||
| inspect_persisting(persisting_ptr); | ||
|
|
||
| const cuda::annotated_ptr<float, cuda::access_property::global> global_ptr(&global_data); | ||
| inspect_global(global_ptr); | ||
|
Jacobfaib marked this conversation as resolved.
Resolved
|
||
|
|
||
| const cuda::annotated_ptr<int, cuda::access_property::streaming> null_ptr{}; | ||
| inspect_null(null_ptr); | ||
|
|
||
| // The pointer is non-null before the update and null after it, so the two stops print | ||
| // different values even though the runner masks non-zero addresses. | ||
| cuda::annotated_ptr<int, cuda::access_property::streaming> updated_ptr(&updated_data); | ||
| inspect_before_update(updated_ptr); | ||
| updated_ptr = cuda::annotated_ptr<int, cuda::access_property::streaming>{}; | ||
| inspect_after_update(updated_ptr); | ||
|
|
||
| return 0; | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.