{"id":3793,"date":"2018-03-19T10:56:18","date_gmt":"2018-03-19T17:56:18","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=3793"},"modified":"2018-03-19T10:56:18","modified_gmt":"2018-03-19T17:56:18","slug":"diagnosing-debugging-symbol-load-errors-for-linux-applications","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/linux\/symbols\/","title":{"rendered":"Diagnosing Debugging Symbol Load Errors for Linux Applications"},"content":{"rendered":"<p>This tutorial shows how to diagnose common problems with debugging symbols\u00a0for Linux C\/C++ applications. We will create a basic application with VisualGDB, break the debug symbol generation to illustrate common project setup problems and will then show how to\u00a0check the ELF files for debug symbols and restore the settings required for\u00a0generating the debug information.<\/p>\n<p>Before you begin, install Visual Studio and VisualGDB.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Linux Project wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3794\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/01-newprj.png\" alt=\"01-newprj\" width=\"941\" height=\"653\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/01-newprj.png 941w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/01-newprj-300x208.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/01-newprj-392x272.png 392w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/01-newprj-130x90.png 130w\" sizes=\"(max-width: 941px) 100vw, 941px\" \/><\/a><\/li>\n<li>Proceed with creating an MSBuild-based application:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/02-msb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3795\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/02-msb.png\" alt=\"02-msb\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/02-msb.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/02-msb-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Select the Linux machine you would like to use for building the\u00a0code:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/03-target1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3796\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/03-target1.png\" alt=\"03-target\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/03-target1.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/03-target1-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Proceed with the default source code access settings:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/04-store.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3797\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/04-store.png\" alt=\"04-store\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/04-store.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/04-store-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a>Then press &#8220;Finish&#8221; to create the project.<\/li>\n<li>In order to successfully debug\u00a0your project, the final ELF file needs to have debug symbols &#8211; information relating addresses in your program to specific source lines and variable names. This information is generated when you pass &#8220;-ggdb&#8221; to the gcc arguments when compiling each source file and and might be removed\u00a0from the final executable by either specifying &#8220;-s&#8221; in the linker flags or using the &#8220;strip&#8221; tool after the linking:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/scheme.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3810\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/scheme.png\" alt=\"scheme\" width=\"680\" height=\"648\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/scheme.png 680w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/scheme-300x286.png 300w\" sizes=\"(max-width: 680px) 100vw, 680px\" \/><\/a><\/li>\n<li>We will now\u00a0show what happens if the debug information is removed\u00a0from the executable and how to\u00a0track back the\u00a0option responsible for removing it. Open\u00a0VS Project Properties and clear the &#8220;Debug Information Format&#8221; setting under C\/C++-&gt;General:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/05-nodebug1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3798\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/05-nodebug1.png\" alt=\"05-nodebug1\" width=\"822\" height=\"558\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/05-nodebug1.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/05-nodebug1-300x204.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Go to the Linker Settings and add &#8220;-s&#8221; to linker command line:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/06-strip.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3799\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/06-strip.png\" alt=\"06-strip\" width=\"822\" height=\"558\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/06-strip.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/06-strip-300x204.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Set a breakpoint in main() and try debugging the program. VisualGDB will\u00a0warn that the program exits without triggering a single breakpoint. The GDB Session log will contain the following line:\n<pre class=\"\">No symbol table is loaded. Use the \"file\" command.<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3800\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable.png\" alt=\"07-symtable\" width=\"1055\" height=\"733\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable.png 1055w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable-300x208.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable-1024x711.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable-392x272.png 392w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/07-symtable-130x90.png 130w\" sizes=\"(max-width: 1055px) 100vw, 1055px\" \/><\/a><\/li>\n<li>This message means that\u00a0the program debugged by gdb is missing the debug symbols. The first step of diagnosing it would be to locate the binary on the build machine and run the following command on it:\n<pre class=\"\">objdump -h &lt;ELF file&gt; | grep debug<\/pre>\n<\/li>\n<li>If the output is empty, locate some of the .o files corresponding to your source files and run the same command on them:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/08-nodebug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3801\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/08-nodebug.png\" alt=\"08-nodebug\" width=\"1083\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/08-nodebug.png 1083w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/08-nodebug-300x126.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/08-nodebug-1024x431.png 1024w\" sizes=\"(max-width: 1083px) 100vw, 1083px\" \/><\/a>In this example the output is empty for both the final ELF file and the .o file (since we have disabled\u00a0debug information generation\u00a0via C\/C++ compiler settings).<\/li>\n<li>You can also open the file in gdb and run the &#8220;info sources&#8221; command (same will work for the .o file) to double-check this.\u00a0GDB will respond that no symbols are present:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/09-sources.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3802\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/09-sources.png\" alt=\"09-sources\" width=\"1083\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/09-sources.png 1083w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/09-sources-300x126.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/09-sources-1024x431.png 1024w\" sizes=\"(max-width: 1083px) 100vw, 1083px\" \/><\/a><\/li>\n<li>Since the .o files don&#8217;t have the symbols either,\u00a0we narrowed down the problem to the missing -ggdb flag. For MSBuild projects the flags are stored in the .gcc.rsp files,\u00a0however if your project is built via custom Makefiles,\u00a0you might need to enable verbose build mode (e.g. V=1, _V=1 or VERBOSE=1) to see the full command line:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/10-rsp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3803\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/10-rsp.png\" alt=\"10-rsp\" width=\"1083\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/10-rsp.png 1083w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/10-rsp-300x126.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/10-rsp-1024x431.png 1024w\" sizes=\"(max-width: 1083px) 100vw, 1083px\" \/><\/a><\/li>\n<li>Go to VS Project Properties and restore the Debug Information Format setting:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/11-optigdb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3804\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/11-optigdb.png\" alt=\"11-optigdb\" width=\"822\" height=\"558\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/11-optigdb.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/11-optigdb-300x204.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Build the project and re-run the objdump commands. See how the .o file now contains .debug_xxx sections storing the debug symbols:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/12-symbols.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3805\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/12-symbols.png\" alt=\"12-symbols\" width=\"1083\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/12-symbols.png 1083w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/12-symbols-300x126.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/12-symbols-1024x431.png 1024w\" sizes=\"(max-width: 1083px) 100vw, 1083px\" \/><\/a><\/li>\n<li>The final ELF file is still not debuggable as we did not remove the &#8220;-s&#8221; option from the\u00a0linker settings. Running objdump on it will confirm this:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/13-nofinal.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3806\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/13-nofinal.png\" alt=\"13-nofinal\" width=\"1083\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/13-nofinal.png 1083w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/13-nofinal-300x126.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/13-nofinal-1024x431.png 1024w\" sizes=\"(max-width: 1083px) 100vw, 1083px\" \/><\/a><\/li>\n<li>If you\u00a0observe this with your projects (debug\u00a0information in the .o files, but not in the final ELF file), check that the linker command line doesn&#8217;t contain the &#8220;-s&#8221; switch. Once you remove it from the project properties, the debug information will get propagated to the final ELF file:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/14-final.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3807\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/14-final.png\" alt=\"14-final\" width=\"1083\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/14-final.png 1083w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/14-final-300x126.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/14-final-1024x431.png 1024w\" sizes=\"(max-width: 1083px) 100vw, 1083px\" \/><\/a>If the command lines look correct, but the symbols are still not propagated (or generated), try copying the command line from the logs, removing the .o (or ELF) file, running gcc manually and recheck the generated file.\u00a0 You may find out that the custom Makefiles you are using are not displaying all build\u00a0flags correctly or they do a some custom\u00a0post-build step that removes the debug information.<\/li>\n<li>You can also explore the debug information by running &#8220;objdump -g &lt;ELF file&gt; | less&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/15-unit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3808\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/15-unit.png\" alt=\"15-unit\" width=\"1579\" height=\"456\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/15-unit.png 1579w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/15-unit-300x87.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/15-unit-1024x296.png 1024w\" sizes=\"(max-width: 1579px) 100vw, 1579px\" \/><\/a>Scroll to the contents of the <strong>.debug_info<\/strong> section and check for\u00a0the\u00a0&#8220;Compilation Unit&#8221; records.\u00a0Each source file compiled with debug\u00a0symbols will have a corresponding record listed in the final ELF file.<\/li>\n<li>Another reason why the debug information could be missing is the &#8216;strip&#8217; tool. It dramatically reduces the size of the ELF binaries by removing debug information from them (also breaking source-level debugging). You can try running it on your executable and compare the sizes before and after it (also confirming that the <strong>.debug_xxx<\/strong> sections disappear):<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/16-strip.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3809\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/16-strip.png\" alt=\"16-strip\" width=\"1074\" height=\"475\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/16-strip.png 1074w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/16-strip-300x133.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/03\/16-strip-1024x453.png 1024w\" sizes=\"(max-width: 1074px) 100vw, 1074px\" \/><\/a>If running the link command line manually produces an executable with valid symbols, but the final executable built by your Make scripts doesn&#8217;t have them, most likely\u00a0the Make scripts run the &#8216;strip&#8217; tool to reduce the binary size. In this case disabling this command for debug builds should get debugging\u00a0to work.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to diagnose common problems with debugging symbols\u00a0for Linux C\/C++ applications. We will create a basic application<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[75,33],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/3793"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=3793"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/3793\/revisions"}],"predecessor-version":[{"id":3811,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/3793\/revisions\/3811"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=3793"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=3793"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=3793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}