Symbol Resolution - microsoft/MSO-Scripts GitHub Wiki
Many tools can reveal the resource usage of an app.
But why is that app so resource hungry?
What code / component / feature is responsible?
Windows Event Tracing is able to capture call stacks / stack walks: the code execution trail at each resource-consuming event.
"Symbol Resolution" is the mechanism for giving human readable (!) names to each bit of code along those execution paths. This is how you can attribute system resource usage, as well as time lapses, to specific code. (Time is also a resource!)
The symbol resolution mechanisms differ, depending on the type of code that executes.
- Symbolic and debugging information for Native Code is stored in PDB files (Program DataBase) generated by the compiler/linker.
- Public versions of these PDB files for Microsoft Windows and Office are available from a public symbol server.
- WPA acquires the PDB files and translates them to a smaller, more efficient SymCache format.
- Two environment variables configure how the PDB and SymCache files are acquired and cached: _NT_SYMBOL_PATH and _NT_SYMCACHE_PATH
PDB Symbol Files:
- A PDB symbol file is created when enabled by the compiler (/Zi switch, MS Visual C++) and the linker (/DEBUG or /PROFILE switch).
- A PDB is paired with its executable module via a unique, embedded signature: the original file name + a GUID + an "age" value
- For each executable module of interest, WPA searches for the corresponding PDB in the folder where it was built, or on a network share/server that you specify.
- Microsoft's public symbol server provides PDB files with limited symbolic information for Windows modules: srv*https://msdl.microsoft.com/download/symbols
- Microsoft's symbol server also provides limited PDB files for Office applications, as of August 2022.
- Google also provides a public symbol server: srv*https://chromium-browser-symsrv.commondatastorage.googleapis.com
-
WPA uses the environment variable _NT_SYMBOL_PATH to help configure its PDB search and cache strategy.
A basic symbol path:_NT_SYMBOL_PATH = cache*c:\symbols;srv*https://msdl.microsoft.com/download/symbols;<alternate_path>
SymCache Files:
- WPA optimizes symbol resolution by translating PDB symbol files to the smaller, more efficient SymCache format.
-
WPA uses the environment variable _NT_SYMCACHE_PATH to help configure its SymCache search and cache strategy.
A basic SymCache path:_NT_SYMCACHE_PATH = c:\symcache*<alternate_path>
In MSO-Scripts, symbol resolution for Native Code is enabled automatically. If either of the two environment variables _NT_SYMBOL_PATH
or _NT_SYMCACHE_PATH
is not defined, the scripts will provide a basic, default setting which references the Microsoft Public Symbol Server.
PDB and SymCache files can be further configured within WPA under: Trace > Configure Symbol Paths
Note
By convention, MSO-Scripts will create separate root folders for PDB symbol files and for SymCache files, usually: c:\Symbols
and c:\SymCache
However, .PDB and .SymCache files can coexist within the same root folder if the environment variables are explicitly set in that way.
Important
The downloaded PDB symbol files are no longer needed by WPA, as they are immediately converted to SymCache format. (PDB symbol files may be useful to other tools, such debuggers.) As the accumulated .PDB file storage can become very large, you may want to delete it from time to time.
Since finding, loading, and resolving native symbols can be slow at times, see the hints for optimizing symbol resolution.
In MSO-Scripts, the -CLR switch, used with the Start command, does all of the work to enable symbol resolution for Managed Code.
Three steps produce symbolic call stacks for Managed Code:
- ETW providers within the Common Language Runtime (CLR) produce the tables required to map code addresses to symbolic names. (In MSO-Scripts, see: WPRP\CLR.wprp)
- WPR generates symbol files corresponding to .NET (CLR/C#) modules. Since this process can be slow, MSO-Scripts disables it when possible via -SkipPDBGen. (The cache for these generated files is: %ProgramData%\WindowsPerformanceRecorder\NGenPdbs_Cache )
- WPA gathers the raw execution stacks and CLR symbolic data tables from the trace file to produce symbolic call stacks.
With the -CLR switch, MSO-Scripts enables these mechanisms to facilitate analyzing Managed Code. (Otherwise they are disabled, as they can be rather resource-intensive.)
In MSO-Scripts, the -JS switch, used with the Start command, does most of the work to enable symbol resolution for JavaScript.
You may also need to pass certain command-line switches to the app itself.
Three steps produce symbolic call stacks for JavaScript:
- ETW providers within the Chromium/V8 and Chakra JavaScript engines produce the tables required to map code address to symbolic names and script files. (In MSO-Scripts, see: WPRP\JS.wprp)
- For apps based on Chromium (Chrome, Edge, WebView2), certain command-line switches may need to be provided to the app itself to enable or enhance symbol resolution. Older apps based on Chakra (IE, WebView) do not need such switches.
- WPA gathers the raw execution stacks and JavaScript symbolic data tables from the trace file to produce symbolic call stacks.
In some (older?) versions of Edge/Chrome, enabling symbolic stacks also requires a command-line switch:
--js-flags=--enable-etw-stack-walking
Other switches make some of the symbols more readable, but may reduce runtime performance:
--no-short-builtin-calls --interpreted-frames-native-stack
To enable or possibly enhance ETW tracing in MSEdge or Chrome:
- Make sure that there are no running instances:
TaskKill /f /im MSEdge.exe
orTaskKill /f /im Chrome.exe
- Then Start MSEdge or Chrome with these added command-line switches:
--js-flags="--enable-etw-stack-walking --no-short-builtin-calls --interpreted-frames-native-stack"
To enable ETW tracing in WebView2, set an environment variable:
- Run: sysdm.cpl
- Advanced Tab > Environment Variables > System Variables > New...
- Enter:
Variable Name = WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS
Variable Value = --js-flags="--enable-etw-stack-walking --no-short-builtin-calls --interpreted-frames-native-stack"
Or from a CMD prompt:
setx WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS "--js-flags=\"--enable-etw-stack-walking --no-short-builtin-calls --interpreted-frames-native-stack\""