Skip to content

Switch to v0 mangling for symbols exceeding 64KB characters on targets generated PDB debug info #934

@Fulgen301

Description

@Fulgen301

Proposal

The PDB debug information format, used for various Windows targets, has a symbol length limit of 64 K(i)B. With certain projects, rustc generates symbol names exceeding that length due to name mangling, leading to linker crashes and / or linker errors. This MCP proposes to switch to v0 name mangling instead of legacy name mangling for too long symbols to ensure proper linkage and PDB generation.

Before VS 17.14, and link.exe version 19.44, link.exe handled symbol names exceeding that length incorrectly, presumably writing truncated symbol names. Microsoft updated the limit handling in Version 19.44, which introduced crashing on too long symbol names, which originally surfaced as a Rust bug report, with multiple users being affected. The issue was subsequently reported to MS. While the crash was fixed, the overall limitation, being a limitation of the debug info format itself, was not lifted, and projects generating symbol names that are too long fail with the following linker error:

  = note: LINK : fatal error LNK1318: Unerwarteter PDB-Fehler: LIMIT (12) "".

Not only is this error message less than ideal, giving users no information as to what actually is the problem, but the overall problem remains - valid Rust code can exceed the PDB symbol limit due to the verbosity of legacy name mangling.

While Rust cannot fix that limitation, it can reduce the verbosity of its symbols by mangling them with v0 instead of legacy mangling. This MCP is intentionally only proposing using that mangling for symbols that are too long for the following reasons:

  • There is precedent for the use of multiple name mangling formats, as rustc-internal symbols are always mangled with v0. Due to this, the overall code complexity is quite low, amounting to "mangle with legacy, if pdb debuginfo and symbol length > cutoff then mangle with v0".
  • The issue that third-party tooling may not be able to demangle the symbols as opposed to the legacy mangling format used by C++ is not considered to be relevant enough for symbol names of such length - the mangled symbol is already at 65 thousand characters or more. Even if tooling has to display the mangled symbol name as opposed to the unmangled one, a possibility it has to consider anyway due to unmangled symbols, neither the mangled nor the unmangled symbol name is readable at such lengths.
  • It only affects symbols that currently cause linker errors, crashes, or debug information that does not accurately represent the symbols anyway.
  • While v0 mangling does not remove the limitation in any way, it seems to be compact enough to reduce the likeliness of hitting the limitation quite effectively.

Empirical testing has determined the maximum symbol length to be exactly 65521 bytes, with leaves 14 bytes for whatever other bookkeeping PDB does for a symbol before it hits the maximum value of a 16-bit unsigned integer. While that value can serve as a cutoff, a slightly lower value should probably be used to guard against potential corner cases; 65000 seems reasonable at first glance.

Mentors or Reviewers

If you have a reviewer or mentor in mind for this work, mention them here. You can put your own name here if you are planning to mentor the work.

Process

The main points of the Major Change Process are as follows:

  • File an issue describing the proposal.
  • A compiler team member who is knowledgeable in the area can second by writing @rustbot second or kickoff a team FCP with @rfcbot fcp $RESOLUTION.
  • Once an MCP is seconded, the Final Comment Period begins.
    • Final Comment Period lasts for 10 days after all outstanding concerns are solved.
    • Outstanding concerns will block the Final Comment Period from finishing. Once all concerns are resolved, the 10 day countdown is restarted.
    • If no concerns are raised after 10 days since the resolution of the last outstanding concern, the MCP is considered approved.

You can read more about Major Change Proposals on forge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-compilerAdd this label so rfcbot knows to poll the compiler teamfinal-comment-periodThe FCP has started, most (if not all) team members are in agreementmajor-changeA proposal to make a major change to rustcto-announceAnnounce this issue on triage meeting

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions