1On Demand Symbols 2================= 3 4On demand symbols can be enabled in LLDB for projects that generate debug info 5for more than what is required by a normal debug session. Some build systems 6enable debug information for all binaries and can end up producing many 7gigabytes of debug information. This amount of debug information can greatly 8increase debug session load times and can slow developer productivity when the 9debug information isn't indexed. It can also cause expression evaluation to 10be slow when types from all of the binaries have full debug info as each module 11is queried for very common types, or global name lookups fail due to a mistyped 12expression. 13 14.. contents:: 15 :local: 16 17When should I consider enabling this feature? 18--------------------------------------------- 19 20Anyone that has a build system that produces debug information for many 21binaries that are not all required when you want to focus on debugging a few of 22the produced binaries. Some build systems enable debug info as a project wide 23switch and the build system files that control how things are built are not 24easy to modify to produce debug info for only a small subset of the files being 25linked. If your debug session startup times are slow because of too much debug 26info, this feature might help you be more productive during daily use. 27 28How do I enable on demand symbols? 29---------------------------------- 30 31This feature is enabled using a LLDB setting: 32 33 34:: 35 36 (lldb) settings set symbols.load-on-demand true 37 38Users can also put this command into their ~/.lldbinit file so it is always 39enabled. 40 41How does this feature work? 42--------------------------- 43 44This feature works by selectively enabling debug information for modules that 45the user focuses on. It is designed to be enabled and work without the user 46having to set any other settings and will try and determine when to enable 47debug info access from the modules automatically. All modules with debug info 48start off with their debug information turned off for expensive name and type 49lookups. The debug information for line tables are always left enabled to allow 50users to reliably set breakpoints by file and line. As the user debugs their 51target, some simple things can cause module to get its debug information 52enabled (called hydration): 53- Setting a file and line breakpoint 54- Any PC from any stack frame that maps to a module 55- Setting a breakpoint by function name 56- Finding a global variable by name 57 58Since most users set breakpoints by file and line, this is an easy way for 59people to inform the debugger that they want focus on this module. Breakpoints 60by file and line are always enabled when on demand symbols is being used. Line 61tables in debug information are cheap to parse and breakpoints will be able to 62be set in any module that has debug info. Setting breakpoints by file and line 63acts as one of the primary ways to enable debug info for a module as it is 64the most common way to stop your program at interesting areas of your code. 65 66Once the user hits a breakpoint, or stops the program for any other reason, 67like a crash, assertion or signal, the debugger will calculate the stack frames 68for one or more threads. Any stack frames whose PC value is contained within 69one of a module's sections will have its debug information enabled. This allows 70us to enable debug information for the areas of code that the user is stopped 71in and will allow only the important subset of modules to have their debug 72information enabled. 73 74On demand symbol loading tries to avoid indexing the names within the debug 75information and makes a few tradeoffs to allow name matching of functions and 76globals without having to always index all of the debug information. 77Setting breakpoints by function name can work, but we try to avoid using 78debug information by relying on the symbol tables from a module. Debug 79information name indexing is one of the most expensive operations that we are 80trying to avoid with the on demand symbol loading so this is one of the main 81tradeoffs of this feature. When setting a breakpoint by function name, if the 82symbol table contains a match, the debug inforamation will be enabled for that 83module and the query will be completed using the debug information. This does 84mean that setting breakpoints on inline function names can fail for modules 85that have debug info, but no matches in the symbol table since inlined 86functions don't exist in symbol tables. When using on demand symbol loading it 87is encouraged to not strip the symbol tables of local symbols as this will 88allow users to set breakpoints on all concrete functions reliably. Stripped 89symbol tables have their local symbols removed from the symbol table which 90means that static functions and non exported function will not appear in the 91symbol tables. This can cause breakpoint setting by function name to fail when 92previously it wouldn't fail. 93 94Global variable lookups rely on the same methodology as breakpoint setting by 95function name: we use the symbol tables to find a match first if debug 96information isn't enabled for a module. If we find a match in the symbol table 97for a global variable lookup, we will enable debug inforamation and complete 98the query using the debug information. It is encouraged to not strip your 99symbol tables with this features as static variables and other non exported 100globals will not appear in the symbol table and can lead to matches not being 101found. 102 103What other things might fail? 104----------------------------- 105 106The on demand symbol loading feature tries to limit expensive name lookups 107within debug inforamtion. As such, some lookups by name might fail when they 108wouldn't when this feature is not eabled: 109- Setting breakpoints by function name for inlined functions 110- Type lookups when the expression parser requests types by name 111- Global variable lookups by name when the name of the variable is stripped 112 113Setting breakpoints by function name can fail for inline function because this 114information is only contained in the debug information. No symbols are created 115for inlined functions unless there is a concrete copy of the inlined function 116in that same module. As a result, we might not end up stopping at all inlined 117functions when requested with this feature enabled. Setting file and line 118breakpoints are a good way still use on demand symbol loading effectively 119and still being able to stop at inline function invocations. 120 121The expression parser often tries to lookup types by name when the user types 122an expression. These are some of the most costly parts of expression evaluation 123as the user can type something like "iterator" as part of their expression and 124this can result in matches from all STL types in all modules. These kinds of 125global type lookup queries can cause thousands of results to be found if debug 126information is enabled. The way that most debug information is created these 127days has the type information inlined into each module. Typically each module 128will contain full type definitions in the debug info for any types that are 129used in code. This means that when you type an expression when stopped, you 130have debug information for all of the variables, arguments and global variables 131in your current stack frame and we should be able to find type that are 132important by using only the modules that have their debug information enabled. 133 134The expression parser can also be asked to display global variables and they 135can be looked up by name. For this feature to work reliably with on demand 136symbol loading enabled, just don't strip your symbol tables and the expression 137parser should have no problem finding your variables. Most global variables 138that are exported will still be in your symbol table if it is stripped, but 139static variables and non exported globals will not be. 140 141Can I troubleshoot issues when I believe this feature is impeding my debugging? 142------------------------------------------------------------------------------- 143 144Logging has been added that can be enabled to help notify our engineers when 145something is not producing results when this feature is enabled. This logging 146can be enabled during a debug session and can be sent to the LLDB engineers 147to help troubleshoot these situation. To enable logging, type the following 148command: 149 150:: 151 152 (lldb) log enable -f /tmp/ondemand.txt lldb on-demand 153 154When the logging is enabled, we get full visibility into each query that would 155have produced results if this feature were not enabled and will allow us to 156troublshoot issues. Enabling this logging before an expression, setting a 157breakpoint by name, or doing a type lookup can help us see the patterns that 158cause failures and will help us improve this feature. 159