Skip to content

Full debug: describe ordinary Rust device globals (AS1) #1120

Closed

Description

@nihalpasham

What problem does this solve?

Ordinary Rust device statics are materialized as generated AS1 LLVM globals,
but cuda-oxide emits no DIGlobalVariable / DIGlobalVariableExpression, no
global !dbg attachment, and no compile-unit globals list. cuda-gdb therefore
cannot resolve source globals such as GLOBAL_COUNTER.

This is a child of #226 and should establish reusable global-debug plumbing for
the separate AS3 shared-memory task.

Proposed behavior

  • Preserve the source leaf name, structured Rust scope path, definition span,
    visibility/locality, generated linkage name, and semantic Rust type while
    stable MIR still exposes them. Join/debug-deduplicate through the opaque
    mangled static identity, never the non-injective display path.
  • Carry that record through mir.global_alloc and LLVM lowering.
  • Emit a DIGlobalVariableExpression, attach it to the generated AS1 global,
    and retain it in the compile unit's globals list.
  • Describe the semantic source type even when initialized physical storage is
    represented as [N x i8].

Expected debugger behavior

  • A global such as debuginfo::GLOBAL_COUNTER is readable/writable by its
    canonical qualified Rust name and has the correct Rust type.
  • Same-leaf statics in different modules remain distinct and resolve by their
    qualified Rust names.
  • Debugger lookup never silently hides one same-leaf static behind another.

Acceptance criteria

  • Exact LLVM metadata includes source name, qualified scope, physical
    linkageName, declaration file/line, semantic type, alignment, correct
    locality, global attachment, and CU retention.
  • Duplicate references to one static deduplicate to one global/debug entry.
  • Two same-leaf statics in distinct module/function/block scopes retain
    distinct physical storage, relocation targets, DIEs, values, and addresses;
    repeated references to one definition deduplicate.
  • Tests cover initialized byte-array storage and aggregate semantic types.
  • Full debug emits variable metadata; line tables/debug off do not.
  • AS3 shared and AS4 constant memory remain explicitly out of scope.
  • LLVM verifier, llc/ptxas, and live cuda-gdb checks pass.

Out of scope / follow-up

Unqualified print GLOBAL_COUNTER is contextual in cuda-gdb: it only resolved
in controls where the stopped DISubprogram carried the exact same namespace,
and it did not resolve from a child namespace to an ancestor. Until function
scopes use the same structured namespace graph (or an imported-entity/alias
mechanism is validated), the canonical T28 acceptance command is
print debuginfo::GLOBAL_COUNTER.

StaticDef::name() is not injective: two opposite-block static X
declarations in one function can have the same display path. The AS1 physical
storage key, initializer relocation targets, and debug side table must all use
the same exact mangled identity; merely rejecting the debug collision still
leaves physical storage coalesced.

Current evidence

On baseline 6c5458fe, the AS1 allocation exists as @__device_global_N, and
its semantic MIR type survives long enough to preserve, but no global DWARF is
emitted. The cuda-devtools T28 assessment reports no source symbol.

Environment

  • Baseline: 6c5458fe991bbde32c5bee74d87822aef1b5a691
  • CUDA/cuda-gdb: 13.3
  • GPU: RTX 5090 (sm_120)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    IR-loweringLowering between dialects (dialect-mir to LLVM dialect)codegenDevice code-generation pipeline (Rust MIR to IR to PTX)debug infoDebug information in generated PTX/IR (line/source maps)enhancementNew feature or requestllvm-exportTextual LLVM/NVVM IR exporter (llvm-export crate)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions