{"id":163,"date":"2015-01-05T10:54:00","date_gmt":"2015-01-05T10:54:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2015\/01\/05\/understanding-symbol-files-and-visual-studios-symbol-settings\/"},"modified":"2022-05-26T01:19:37","modified_gmt":"2022-05-26T09:19:37","slug":"understanding-symbol-files-and-visual-studios-symbol-settings","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/understanding-symbol-files-and-visual-studios-symbol-settings\/","title":{"rendered":"Understanding symbol files and Visual Studio\u2019s symbol settings"},"content":{"rendered":"<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ee416588(v=vs.85).aspx\">Symbols<\/a> are a fundamental requirement for debugging and other diagnostic tools. Fortunately in most cases when you are building and launching your application in Visual Studio you don\u2019t have to think about symbols for your code. However the odds are that at some point in time you\u2019ll need to change how symbols load, where the debugger looks for them, or will need to load symbols for a 3<sup>rd<\/sup> party component (e.g. Windows or .NET libraries). Additionally because symbols are so <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms241613.aspx\">fundamental to debugging<\/a>, we continue to make tweaks to the experience so understanding the ins and outs of how Visual Studio behaves can save you hours of frustration.<\/p>\n<p>In this blog post I\u2019ll walk you through what symbols are and how to configure Visual Studio\u2019s symbol settings (which are used by other diagnostic tools beyond the debugger such as the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms182372.aspx\">performance tools<\/a> and <a href=\"http:\/\/blogs.msdn.com\/b\/zainnab\/archive\/2013\/02\/12\/understanding-intellitrace-part-i-what-the-is-intellitrace.aspx?wa=wsignin1.0\">IntelliTrace<\/a>), the various knobs available when debugging, and how to trouble shoot issues when Visual Studio isn\u2019t able to find the symbol files that you need.<\/p>\n<h2>Symbol basics<\/h2>\n<p>Before we delve into the details of symbol files it\u2019s important to briefly review what symbols are and why they are important:<\/p>\n<ul>\n<li>**What is a symbol file? **For the Microsoft compilers, these are the .pdb files that are produced as part of your build.<\/li>\n<li>**What is in a symbol (.pdb) file? **The exact contents of symbol files will vary from language to language and based on your compiler settings, but at a very high level they are the record of how the compiler turned your source code into machine code that the processor executes.<\/li>\n<li>\n<p>**Why do I need symbols? **Without symbols, tools are unable to correlate the instructions executing in the application to the original source code.<\/p>\n<\/li>\n<li>\n<p>When debugging, without a symbol file you are unable to set breakpoints on a specific line of code. If symbols are not loaded you will see a hollow circle with a warning symbol while in debug mode, and if you hover the mouse over it a tooltip will tell you that the breakpoint will not be hit because no symbols have been loaded.<\/p>\n<\/li>\n<li>Depending on what you are debugging, symbols may be required to show you a complete call stack and to inspect objects using the Watch windows, or DataTips (e.g. this is true for C++).<\/li>\n<li>*Note: If you are debugging a dump file that does not contain the heap, the debugger will need access to the original binary file so it can determine the correct symbol file to load. Said another way, if you are debugging a dump with no heap information, you need both the corresponding binary and symbol file on the symbol path. *<\/li>\n<\/ul>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image001\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/8055.clip_image001_thumb_23A206A8.png\" alt=\"clip_image001\" width=\"512\" height=\"193\" border=\"0\" \/><\/p>\n<h3>Visual Studio\u2019s default behavior<\/h3>\n<p>Before we look at any of Visual Studio\u2019s advanced settings it\u2019s important that I stop and review the default behavior (meaning if you never touch a setting how will it behave):<\/p>\n<ul>\n<li>\n<p>Visual Studio will try to load symbols for all binaries (referred to as \u201cmodules\u201d) in the process when the module is loaded (and for all modules already loaded when attaching to a process).<\/p>\n<\/li>\n<li>\n<p>The exception to this is when you are debugging managed (.NET) applications, the debugger will not load symbols for any binaries considered \u201cnot your code\u201d when <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dn457346.aspx#BKMK__NET_Framework_Just_My_Code\">\u201cJust My Code\u201d is enabled<\/a>.<\/p>\n<\/li>\n<li>\n<p>No symbol locations are set, so it will not find symbols for any Microsoft runtime binaries<\/p>\n<\/li>\n<li>\n<p><em>If you right click on a module in the Call Stack or Modules windows and choose to load symbols it will automatically try to get them from the Microsoft public symbol servers assuming it can\u2019t be found on your local machine.<\/em><\/p>\n<\/li>\n<li>\n<p>Visual Studio will always find symbols when:<\/p>\n<\/li>\n<li>The symbol file is located in the same folder as its corresponding module. <em>The default build output settings for Visual Studio projects will output the symbols next to the binaries. This means that Visual Studio will always be able to find the symbols for your projects.<\/em><\/li>\n<li>The symbol file is located in the same directory is was placed during compilation. <em>The full path of the .pdb is placed into the binary at build time.<\/em><\/li>\n<\/ul>\n<h3><a id=\"troubleshooting\">How can I tell if a symbol is loaded and if not why?<\/a><\/h3>\n<p>The screenshot above (with the hollow breakpoint) shows a situation where symbols didn\u2019t load for a source file you are trying to set a breakpoint in. The other ways to determine if symbols are loaded:<\/p>\n<ul>\n<li>A message will appear in the call stack window saying that symbols are not loaded\u00a0<\/li>\n<\/ul>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image003\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/1682.clip_image003_thumb_1C82CA30.jpg\" alt=\"clip_image003\" width=\"487\" height=\"167\" border=\"0\" \/><\/p>\n<ul>\n<li>\n<p>The Modules window will tell you (Debug -> Windows -> Modules):<\/p>\n<\/li>\n<li>\n<p>The status of the symbol file (loaded, skipped, or couldn\u2019t be opened or found)<\/p>\n<\/li>\n<li>Path the binary is loaded from<\/li>\n<li>[if loaded] where the symbol file was loaded from<\/li>\n<li>The module version<\/li>\n<li>The module\u2019s time stamp<\/li>\n<\/ul>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image005\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/2275.clip_image005_thumb_2335D3B3.jpg\" alt=\"clip_image005\" width=\"628\" height=\"172\" border=\"0\" \/><\/p>\n<p>Additionally the debugger can tell you why it didn&#8217;t load symbols and where it searched for them. To see this information, open the Modules window, right click on a module and choose \u201cSymbol Load Information\u2026\u201d<\/p>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image007\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/5822.clip_image007_thumb_77F13CAB.jpg\" alt=\"clip_image007\" width=\"430\" height=\"200\" border=\"0\" \/><\/p>\n<p>This will display a box that shows you all the paths the debugger searched for the symbol file.<\/p>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image009\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/0624.clip_image009_thumb_4CACA5A4.jpg\" alt=\"clip_image009\" width=\"544\" height=\"301\" border=\"0\" \/><\/p>\n<p>Some common reasons symbols aren&#8217;t loaded include:<\/p>\n<ul>\n<li>Symbol paths don\u2019t point to the correct location<\/li>\n<li>\n<p>The symbol file is from a different version of the module than the one loaded in the process<\/p>\n<\/li>\n<li>\n<p>Visual Studio requires that the symbol file come from the exact same build as the module. It cannot load symbols that come from a different build even if the source code was identical<\/p>\n<\/li>\n<li>\n<p>[Managed only] Just My Code settings prevent the debugger from loading the symbol file<\/p>\n<\/li>\n<\/ul>\n<h2>Configuring Visual Studio\u2019s settings<\/h2>\n<p>Now that you understand what symbols are, and how to determine if they are loaded let\u2019s look at how you configure Visual Studio\u2019s symbol settings. To access symbols settings, go to the \u201cDebug\u201d menu and choose \u201cOptions\u2026\u201d (\u201cOptions and Settings\u2026\u201d in previous versions of Visual Studio), and then select the \u201cSymbols\u201d sub page<\/p>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image011\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/4265.clip_image011_thumb_778509B6.jpg\" alt=\"clip_image011\" width=\"628\" height=\"368\" border=\"0\" \/><\/p>\n<p>You\u2019ll notice the following settings on the page:<\/p>\n<ol>\n<li>Symbol file (.pdb) locations<\/li>\n<li>Symbol cache settings<\/li>\n<li>\u201cLoad all symbols\u201d button Autom <\/li>\n<li>Automatic symbol loading settings<\/li>\n<\/ol>\n<h3>Symbol file locations<\/h3>\n<p>If you are building and debugging your application from Visual Studio this option likely won\u2019t apply to the symbols for your modules, but remote symbol locations (or symbol servers) are used to load symbols in situations where you need a 3<sup>rd<\/sup> party symbol file (e.g. one from Microsoft), or you are working in an environment where you may not have the symbols on your local machine (e.g. your application is built using a build server.\u00a0 <a href=\"http:\/\/bit.ly\/SymbolServerTFS\">If you are using TFS read about how to add symbol and source archiving support<\/a>).<\/p>\n<p>The symbol file location box tells the debugger where to look for symbol files, these can be http symbol servers (e.g. the prepopulated \u201cMicrosoft Symbol Severs\u201d entry), network shares, or folders on your local machine<\/p>\n<ul>\n<li>You can add as many paths as you need.<\/li>\n<li>There is a pre-populated entry for Microsoft\u2019s public symbol servers. If you want to load symbols for modules from Microsoft (e.g. for the runtime or operating system) check this box.<\/li>\n<li>Visual Studio will search local paths before querying network paths regardless of the order provided.<\/li>\n<li>For performance reasons, <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2012\/11\/30\/debugger-source-symbol-improvements-to-visual-studio-2012.aspx\">beginning in Visual Studio 2012 Update 1<\/a>, Visual Studio will only search each symbol server once for a symbol file in a given Visual Studio session (until you restart Visual Studio) when automatic symbol loading is enabled. This means you don\u2019t pay the cost of a network call every time you start debugging when the server doesn\u2019t contain the file.<\/li>\n<li><em>Environment Variable: &#95;NT&#95;SYMBOL_PATH<\/em>: If you see this in your symbol file locations it means that the environment variable &#95;NT&#95;SYMBOL_PATH is set. Visual Studio uses a library from Windows to load symbols, and the library will always search any locations in this environment variable for symbols; which is why you cannot uncheck the option in Visual Studio. You will need to unset the environment variable if you want Visual Studio to ignore the variable.<br \/>\nIf you need the environment variable for other purposes, the easy way to unset the variable locally is to open a command prompt, enter \u201cset &#95;NT&#95;SYMBOL_PATH=\u201d and then launch Visual Studio from the command prompt. You system\u2019s environment settings will remain unaffected.<\/li>\n<\/ul>\n<h3>Symbol cache<\/h3>\n<p>The symbol cache is the location on your local machine that Visual Studio places a copy of the symbols it finds on remote locations for future use. Assuming you provide a path for the symbol cache, Visual Studio will search the cache before trying to find symbols in any symbol file locations you specified above. For performance reasons we recommend specifying a symbol cache if you need symbols stored in a remote location.<\/p>\n<h3>Load All Symbols<\/h3>\n<p>This button is only enabled while Visual Studio is in debug mode, and clicking it will tell the debugger to try to load symbols for all modules in the process.<\/p>\n<h3><a id=\"manual\">Automatic Symbol Loading<\/a><\/h3>\n<p>Visual Studio offers two modes of automatic symbol loading:<\/p>\n<ul>\n<li>**Automatically load symbols for all modules unless excluded: **As the title indicates, unless you add a module to the exclude list by clicking \u201cSpecify excluded modules\u201d, Visual Studio will try to load symbols for all modules in the process. You will typically want this setting if you want symbols loaded for almost everything in the process, or if there are only a handful of very large ones you don\u2019t want loaded for memory or debug startup performance reasons.<\/li>\n<li>\n<p>**Only specified modules: **This setting by default will load symbols that are next to the binary on the disk, but will not try to load symbols for any other modules unless you add them to the include list by clicking \u201cSpecify modules\u201d.<\/p>\n<\/li>\n<li>\n<p><em>beginning with Visual Studio 2013 Update 2, the \u201cSpecify modules\u201d dialogs accept * for module names. So if for example you wanted to use manual loading but always load symbols for anything with \u201cMicrosoft\u201d in the name, you could enter \u201c&#42;Microsoft&#42;\u201d<\/em><\/p>\n<\/li>\n<\/ul>\n<p>****<img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image013\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/1134.clip_image013_thumb_45213637.jpg\" alt=\"clip_image013\" width=\"478\" height=\"387\" border=\"0\" \/>**<\/p>\n<ul>\n<li>Symbols can be manually loaded from the Call Stack window as needed. To do this, you can select an individual frame (or select all with ctrl+a), right click and choose \u201cLoad symbols\u201d. This will load symbols for all of the modules that were in the call stack window at that time. If loading symbols improves the call stack and additional modules are found you will need to repeat this as it won\u2019t automatically try to load symbols for modules that appear due to the previous load.<\/li>\n<\/ul>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image015\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/0552.clip_image015_thumb_19DC9F30.jpg\" alt=\"clip_image015\" width=\"628\" height=\"513\" border=\"0\" \/><\/p>\n<ul>\n<li>The other option to load symbols manually when you are debugging is to locate the module in the Modules window (Debug -> Windows -> Modules), right click and choose \u201cLoad Symbols\u201d.<\/li>\n<\/ul>\n<p><img decoding=\"async\" style=\"float: none;padding-top: 0px;padding-left: 0px;margin-left: auto;padding-right: 0px;margin-right: auto;border: 0px\" title=\"clip_image016\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/01\/3288.clip_image016_thumb_6E980828.png\" alt=\"clip_image016\" width=\"390\" height=\"266\" border=\"0\" \/><\/p>\n<h3>Deep dive on manual symbol loading<\/h3>\n<p>It is worth calling out that \u201cOnly specified modules\u201d is my and many of the Visual Studio team\u2019s preferred setting when debugging. The reason for this is:<\/p>\n<ul>\n<li>\n<p>When debugging very large applications you can load symbols on demand as you need them. This helps with:<\/p>\n<\/li>\n<li>\n<p>The performance of your debug session\u2014you don\u2019t have to wait for symbols to load for everything in the process you are debugging.<\/p>\n<\/li>\n<li>\n<p>Visual Studio\u2019s memory\u2014if you are debugging a very large application you may need to selectively load symbols for only the modules you are interested in. Since Visual Studio is a 32bit process, it can at most grow to 4 GB in Virtual Memory. For very large applications you can have more in symbol files than this.<\/p>\n<\/li>\n<li>\n<p>You can leave your symbol servers enabled without encountering unexpected performance hits when debugging new applications or during your first debug session in a new Visual Studio instance.\nIf you have a very large solution that you build entirely on your machine you will need to uncheck the \u201cAlways load symbols located next to modules\u201d checkbox to see the benefits I mentioned above. Then you will either need load the symbols on demand while debugging, or set the ones you need to automatically load.<\/p>\n<\/li>\n<li>\n<p>If you need to hit breakpoints in those modules you will want to set them to load automatically.<\/p>\n<\/li>\n<li>If you aren\u2019t sure you will need the symbols ahead of time you will want to wait and load them only if you need them to inspect an object or complete the call stack.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>Keeping track of symbols and configuring your settings correctly and for optimal performance can be quite complicated. Hopefully the above content helps you understand the settings available to you. However if you run into issues I did not cover, or have any other feedback you\u2019d like to share, please let me know below, through <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/zzszcehe.aspx\">Visual Studio\u2019s Send a Smile feature<\/a>, or in our <a href=\"http:\/\/social.msdn.microsoft.com\/Forums\/en-US\/vsdebug\/threads\">MSDN forum<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Symbols are a fundamental requirement for debugging and other diagnostic tools. Fortunately in most cases when you are building and launching your application in Visual Studio you don\u2019t have to think about symbols for your code. However the odds are that at some point in time you\u2019ll need to change how symbols load, where the [&hellip;]<\/p>\n","protected":false},"author":77,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,225],"tags":[],"class_list":["post-163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-git"],"acf":[],"blog_post_summary":"<p>Symbols are a fundamental requirement for debugging and other diagnostic tools. Fortunately in most cases when you are building and launching your application in Visual Studio you don\u2019t have to think about symbols for your code. However the odds are that at some point in time you\u2019ll need to change how symbols load, where the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/77"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=163"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}