Skip to content

fix(pack): emit portable PDBs so nuget.org accepts the .snupkg - #35

Merged
nullfx merged 3 commits into
mainfrom
fix/portable-pdbs
Oct 9, 2026
Merged

nullfx merged 3 commits into
mainfrom
fix/portable-pdbs

Conversation

@nullfx

@nullfx nullfx commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Fix: nuget.org rejected the 1.1.14 symbols package (non-portable PDBs)

This PR also changes the README # Benchmarks heading to ## Benchmarks and silences the SYSLIB0051 build warnings on net8.0/net10.0 (see the last two sections).

nuget.org rejected NullFX.CRC.1.1.14.snupkg with "contains one or more pdbs that are not portable". All 11 PDBs in it were Windows-format (Microsoft C/C++ MSF 7.00) PDBs. The main .nupkg was published normally.

Cause

Since 2021, NullFX.CRC.csproj's Release property group has set <DebugType> to an empty value. With DebugSymbols=true and no DebugType, the compiler falls back to full debug info, which on Windows (the release runner) writes Windows PDBs. On Linux the compiler can't write Windows PDBs and produces portable ones, so local Linux pack checks didn't show the problem.

Fix

  • NullFX.CRC.csproj: <DebugType>portable</DebugType>. The compiler now gets /debug:portable for all 11 target frameworks.

  • verify-package.ps1: now also checks the .snupkg:

    • It must exist.
    • It must contain lib/<tfm>/NullFX.CRC.pdb for every target framework.
    • Every PDB must start with the portable BSJB signature.

    CI packs on Windows for every PR, so a regression would fail the PR build instead of reaching nuget.org.

Validation

Check Result
DebugType (Release; net10.0, net48) '' before → portable after
Compiler debug switch /debug:portable for all TFMs (22 compiler invocations)
verify-package.ps1 on the published 1.1.14 .nupkg + .snupkg ❌ fails: 11/11 PDBs flagged as not portable
Fixed build, pack, verify-package.ps1 ✅ passes: 11 portable PDBs, 0 problems

About 1.1.14

Its symbols can't be fixed after the fact. nuget.org only accepts a .snupkg whose PDBs match the DLLs already published, and a rebuild produces different PDB IDs. The next release (1.1.15) will publish symbols normally.

README: ## Benchmarks heading

  • README.md: # Benchmarks → ## Benchmarks, matching the other sections.
  • update-readme-benchmarks.ps1: its default heading changes to ## Benchmarks in the same commit. It matches the heading exactly, so without this the next release wouldn't find the section and would append a duplicate. Tested against main's README: one ## Benchmarks section, results replaced, everything above it unchanged.

SYSLIB0051 warnings on net8.0 / net10.0

The net8.0 and net10.0 builds warned that UnknownAlgorithmException's protected serialization constructor calls the obsolete Exception(SerializationInfo, StreamingContext) constructor.

  • UnknownAlgorithmException.cs: the protected (SerializationInfo, StreamingContext) constructor is now [Obsolete(DiagnosticId = "SYSLIB0051")], inside #if NET8_0_OR_GREATER. That matches how the base Exception constructor is marked.
  • NullFX.CRC.csproj: SYSLIB0051 added to NoWarn.
  • Public API: the constructor stays and nothing is removed. On net8.0+, code that derives from UnknownAlgorithmException and calls this constructor now gets the same SYSLIB0051 warning it would get for System.Exception. Older targets are unchanged.
Check Result
Build, all 11 TFMs 0 warnings (previously 2× SYSLIB0051)
Attribute in the compiled DLLs Present for net8.0 and net10.0 only
Unit tests (net10.0) 36/36 passed

🤖 Generated with Claude Code

https://claude.ai/code/session_012C6aJYkYBV2GSnSZwsd9GU

claude added 2 commits October 9, 2026 16:47
nuget.org rejected the NullFX.CRC 1.1.14 symbols package: "contains one
or more pdbs that are not portable". All 11 PDBs were Windows (MSF 7.00)
PDBs.

Cause: the Release property group set <DebugType> to an empty value (it
has done since 2021). With DebugSymbols=true and no DebugType, csc falls
back to 'full', which on Windows writes Windows PDBs. On Linux the
compiler can only write portable PDBs, which is why local Linux pack
checks passed and only the Windows release build was affected.

- Set <DebugType>portable</DebugType> explicitly (csc now receives
  /debug:portable for every target framework).
- verify-package.ps1 now also opens the .snupkg: it requires a PDB for
  every target framework and fails if any PDB lacks the portable "BSJB"
  signature. CI packs on Windows for every PR, so this is caught before
  a release. Verified it rejects the published 1.1.14 .snupkg (11 of 11
  PDBs flagged) and accepts the fixed build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012C6aJYkYBV2GSnSZwsd9GU
'# Benchmarks' -> '## Benchmarks' in README.md so it matches the other
sections. update-readme-benchmarks.ps1 looks for that exact heading, so
its default changes with it (otherwise the next release would not find
the section and would append a duplicate).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012C6aJYkYBV2GSnSZwsd9GU
@nullfx nullfx self-assigned this Oct 9, 2026
net8.0 and net10.0 builds warned:
  UnknownAlgorithmException.cs(48,98): warning SYSLIB0051:
  'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete

- Mark the protected (SerializationInfo, StreamingContext) constructor
  [Obsolete(DiagnosticId = "SYSLIB0051")] under #if NET8_0_OR_GREATER,
  matching how the base Exception constructor is marked. Calling an
  obsolete member from an obsolete member does not warn, and derived
  types on net8.0+ now see the same SYSLIB0051 guidance as for
  System.Exception. Older targets are unchanged.
- Add SYSLIB0051 to NoWarn for the library project.

The constructor is kept (no API removal). Verified: all 11 TFMs build
with 0 warnings, the attribute is emitted only for net8.0/net10.0, and
the 36 unit tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012C6aJYkYBV2GSnSZwsd9GU
@nullfx
nullfx merged commit 77f948e into main Oct 9, 2026
5 checks passed
@nullfx
nullfx deleted the fix/portable-pdbs branch October 9, 2026 23:06
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.

2 participants