Skip to content

NATVIS errors/warnings are not reported in cppvsdbg debugger output #10343

Description

@jeremyong

Environment

  • OS and version: Windows 10 Pro 22H2
  • VS Code: 1.74.2
  • C/C++ extension: 1.13.8

Bug Summary and Steps to Reproduce

Bug Summary:

Visual Studio provides a set of options to change NATVIS logging output, shown below:

image

These messages are important to identify errors in either parsing the NATVIS XML file itself, or parsing individual expressions within a given object reflected by the visualizer.

Steps to reproduce:

  1. Create either a malformed NATVIS file, or annotate a type with a malformed expression
  2. Observe that the entire NATVIS file is silently dropped by the debugger without any error or indications

Debugger Configurations

This occurs with the default launch configuration and a specified `visualizerFile` configuration key set.

Debugger Logs

No relevant logs were produced with the engine and trace logging enabled.

Other Extensions

No response

Additional Information

No response

Activity

  1. guusw commented on Jun 20, 2023

    @guusw

    Is there any way to see the errors somewhere else even if they're not in the debugger output?

  2. akkiss commented on Jul 2, 2023

    @akkiss

    I'm struggling with this as well. Trying to use a natvis file but nothing happens, don't know why, it would be nice to see some feedback on loading the natvis file.

  3. Nerixyz commented on Jan 31, 2025

    @Nerixyz

    Since Microsoft doesn't seem to care about this, we have to resort to binary patching1. Make sure to create a backup before (or use my script which does that automatically).

    In the extension directory, ($Env:USERPROFILE\extensions\ms-vscode.cpptools-1.23.5-win32-x64), navigate to debugAdapters\vsdbg\bin, open CppDebug.dll, and set the byte at position 0x39FD9 to one of the following values:

    • Off: 5 (default)
    • Error: 3
    • Warning: 2
    • Verbose: 1

    For convenience, I made a PowerShell script that does just that (and verifies the edits). You don't need to restart VS Code.

    Script

    Usage:

    > .\SetNatvisLogLevel.ps1 Warning
    Set level to Warning
    param (
        [Parameter(Position = 0, Mandatory)]
        [ValidateSet('Off', 'Error', 'Warning', 'Verbose')]
        [string] $Level,
    
        [string] $VsCodeDir = "$Env:USERPROFILE\.vscode" 
    )
    
    $ErrorActionPreference = 'Stop';
    
    function FindCppToolsExtension {
        param (
            [string] $ExtensionsDir
        )
        
        $dirs = Get-ChildItem $ExtensionsDir -Filter "ms-vscode.cpptools*" -Directory;
    
        if ($dirs.Length -ne 1) {
            throw "No 'ms-vscode.cpptools*' directory found in '$ExtensionsDir'";
        }
    
        return $dirs[0].FullName;
    }
    
    function BackupOriginalFile {
        param (
            [string] $Path,
            [string] $DesiredHash
        )
        
        $curHash = (Get-FileHash $Path).Hash;
        $bkpPath = $Path + ".bak";
        $bkpHash = $null;
        if (Test-Path -PathType Leaf $bkpPath) {
            $bkpHash = (Get-FileHash $bkpPath).Hash;
        }
    
        if ($bkpHash -eq $DesiredHash) {
            return # already backed up
        }
    
        if ($curHash -ne $DesiredHash) {
            throw "$Path does not have the expected hash:`nExpected: $DesiredHash`nGot: $curHash`nWas the binary updated?";
        }
    
        Copy-Item $Path $bkpPath;
    }
    
    function PatchBinary {
        param (
            [string] $Path,
            [int] $Index,
            [byte] $Value
        )
        $data = [System.IO.File]::ReadAllBytes($Path)
        $data[$Index] = $Value;
        [System.IO.File]::WriteAllBytes($Path, $data)
    }
    
    $DLL_HASHES = @{
        "Off"     = "1370EE82E37F0E1AD71298E2B26A2E68183B61EC835F7936BBB5FC27397768C5"
        "Error"   = "907812BA7A9C9104C60851781BA2B68B65D3F476C63B0E6D75BC7A4F1B1E2455"
        "Warning" = "397FFCAF71EA1550D6E97ECCAF59C3368423BBDBAFA777BF25BF5EBA51512573"
        "Verbose" = "8040D68B22A95726FB0AD75BAC86BBBB74BCE45FDCA2902A7402E1DF6AB82E51"
    };
    $VALUES = @{
        "Off"     = [byte] 5
        "Error"   = [byte] 3
        "Warning" = [byte] 2
        "Verbose" = [byte] 1
    };
    $INDEX = 0x39FD9;
    
    $DLL_PATH = "debugAdapters\vsdbg\bin";
    $DLL_NAME = "CppDebug.dll";
    
    if (-not $VALUES.ContainsKey($Level)) {
        throw "Invalid level specified: $Level";
    }
    
    $extensionsDir = Join-Path $VsCodeDir "extensions";
    $debuggerBinDir = Join-Path $(FindCppToolsExtension -ExtensionsDir $extensionsDir) $DLL_PATH;
    $binaryPath = Join-Path $debuggerBinDir $DLL_NAME;
    
    BackupOriginalFile -Path $binaryPath -DesiredHash $DLL_HASHES["Off"];
    PatchBinary -Path $binaryPath -Index $INDEX -Value $VALUES[$Level];
    
    $newHash = (Get-FileHash $binaryPath).Hash;
    $expectedHash = $DLL_HASHES[$Level];
    if ($newHash -ne $expectedHash) {
        throw "Patched binary does not have expected hash`nExpected: $expectedHash`nGot: $newHash";
    }
    
    Write-Host -ForegroundColor Green "Set level to $Level";

    Footnotes

    1. There seems to be some mechanism to pass this value through environment variables as well, but it's disabled (I think). For this setting, you'd define Debugger_Level. However, in the function that loads this, the string gets unconditionally overwritten by an empty string, so it's never returned. ↩

  4. rlabrecque commented on Jul 3, 2025

    @rlabrecque

    Great script Nerixyz (@Nerixyz) ; hopefully easy enough for anyone else that needs to use this script to figure out, but I had to make a minor change to it:

    Before:

    $dirs = Get-ChildItem $ExtensionsDir -Filter "ms-vscode.cpptools*" -Directory;
    

    After:

    $dirs = Get-ChildItem $ExtensionsDir -Filter "ms-vscode.cpptools-1*" -Directory;
    

    Because it was also finding ms-vscode.cpptools-themes-2.0.0\

    Close VSCode before running it; then once you set it, the log messages were showing up in the Debug Console while running my application. Copy all that output over to a new vscode editor window or such then just search for your .natvis file.

  5. sean-mcmanus commented on Jul 3, 2025

    @sean-mcmanus
    Contributor

    I think vsdbg is still being maintained but the VS debug team maintainers might not be aware of this bug. It's possible if someone reported the bug against VS on the Developer Community site then we could ship a fixed binary.

  6. romasandu-gaijin commented on Dec 16, 2025

    @romasandu-gaijin

    Astounding that such a basic debugger usability feature is still missing in 2025. And the fix seems to be quite trivial too! Come on, Microsoft, if AI agents are so good, why don't you let one fix this bug?

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions