Skip to content

Ship a Release PDB for HSMCppWrapper.dll (symbols for the aggregator)#1216

Merged
lotgon merged 1 commit into
masterfrom
fix/wrapper-release-pdb
Jul 1, 2026
Merged

Ship a Release PDB for HSMCppWrapper.dll (symbols for the aggregator)#1216
lotgon merged 1 commit into
masterfrom
fix/wrapper-release-pdb

Conversation

@lotgon

@lotgon lotgon commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

The VS Release config omits debug info by default, so the handoff bundle shipped Release without a .pdb (pack.ps1 warned) — no symbols for crash analysis at tt-aggregator2. This adds /Zi (compile) + /DEBUG /OPT:REF /OPT:ICF (link) for the Release config only of the HSMCppWrapper target: Release stays optimized but produces a PDB.

Exports/ABI are unchanged, so the aggregator relink stays byte-for-byte identical (545 exports).

Verified end-to-end: a workflow_dispatch build off this branch produced a bundle whose dll/HSMCppWrapper/x64/Release/ now contains HSMCppWrapper.pdb alongside the dll + libcurl/z runtime.

🤖 Generated with Claude Code

…handoff)

The VS Release config omits debug info by default, so the handoff bundle shipped
Release without a .pdb (pack.ps1 warned) — no symbols for crash analysis downstream.
Add /Zi (compile) + /DEBUG /OPT:REF /OPT:ICF (link) for the Release config only, so
Release stays optimized but produces a PDB. Exports/ABI are unchanged, so the relink
stays byte-for-byte identical (545 exports).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review — PR #1216 fix/wrapper-release-pdb

Small, well-scoped change: emit a PDB for the Release HSMCppWrapper.dll so the handoff bundle ships symbols for crash analysis at tt-aggregator2.

The change is coherent with the rest of the pipeline and the core reasoning is sound:

  • ✅ It closes a real gap — src/wrapper/packaging/pack.ps1 already looks for HSMCppWrapper.pdb in the Release output (and Write-Warnings when it's missing), and MANIFEST.md advertises the PDB. Before this PR the Release lane produced no PDB, so that warning always fired for Release.
  • ✅ The /OPT:REF /OPT:ICF reasoning is correct: passing /DEBUG flips the linker's Release default to /OPT:NOREF,NOICF, so re-adding them preserves the size/speed folding — Release stays optimized and symbolizable.
  • ✅ Correctly scoped to Release via $<$<CONFIG:Release>:...>. That per-config genex is required here because the project configures once and builds both configs (multi-config VS generator, confirmed in .github/workflows/hsm-wrapper-release.yml). Debug already emits a PDB by default, so leaving it untouched is right.

A few points worth addressing, none blocking:

1. "byte-for-byte identical" comment overstates what happens (maintainability)

src/wrapper/CMakeLists.txt:53

// Exports/ABI are unaffected, so the relink stays byte-for-byte identical.

/DEBUG embeds a CodeView (RSDS) debug-directory entry into the PE containing the PDB path and a freshly generated GUID + age signature per link, and updates the PE checksum. So the Release DLL is not byte-for-byte identical to the pre-change build, and it is non-reproducible across rebuilds (each link gets a new signature).

What actually stays stable is the thing that matters for the consumer: the exported ABI / import library is unchanged, so tt-aggregator2 relinks with no source or link changes. Suggest rewording to that effect (e.g. "the exported ABI and import lib are unchanged, so the consumer relinks unaffected") rather than claiming the binary bytes are identical — otherwise someone diffing two Release DLLs will be surprised.

2. /Zi uses a shared compiler PDB — consider /Z7 for build robustness (low)

src/wrapper/CMakeLists.txt:54

/Zi routes per-TU debug info through a single shared compiler PDB (via mspdbsrv). Under parallel compilation this occasionally surfaces as fatal error C1041: cannot open program database due to lock contention. /Z7 embeds the debug info directly in each .obj, avoids the shared-PDB serialization entirely, and still lets /DEBUG produce the linker PDB the bundle needs.

Risk here is low (only 9 translation units), so this is a suggestion, not a requirement. Modern CMake also exposes set_target_properties(... MSVC_DEBUG_INFORMATION_FORMAT ...) if you'd rather express it declaratively.

3. Multi-flag genex with spaces — fine on your generator, but fragile if the generator ever changes (low)

src/wrapper/CMakeLists.txt:55

target_link_options(HSMCppWrapper PRIVATE $<$<CONFIG:Release>:/DEBUG /OPT:REF /OPT:ICF>)

This one genex expands to a single list element containing three space-separated flags. On the VS multi-config generator you use, link options are emitted verbatim into <AdditionalOptions>, so this works. But on a single-config Ninja/Makefiles generator CMake can treat a space-containing element as one quoted argument, which the linker would reject. Splitting into separate flags is more portable and costs nothing:

target_link_options(HSMCppWrapper PRIVATE
    $<$<CONFIG:Release>:/DEBUG>
    $<$<CONFIG:Release>:/OPT:REF>
    $<$<CONFIG:Release>:/OPT:ICF>)

(or the semicolon form $<$<CONFIG:Release>:/DEBUG;/OPT:REF;/OPT:ICF>).

Minor

  • The embedded RSDS record will bake the build-machine PDB path (e.g. the GitHub runner's D:\a\... working dir) into the shipped Release DLL. That's expected for any symbol-shipping binary and not sensitive here — noting only for completeness.

Overall: correct, minimal, and it fixes a genuine gap in the release bundle. Recommend tightening the comment (#1) and, optionally, adopting /Z7 (#2) before merge.

@lotgon
lotgon merged commit 4c591e9 into master Jul 1, 2026
22 checks passed
@lotgon
lotgon deleted the fix/wrapper-release-pdb branch July 1, 2026 23:45
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.

1 participant