# Frame symbolication LLDB performs symbolication on program crash logs to convert them into the file and symbol names used in the program’s source code. ## Manual symbolication with LLDB Use LLDB to symbolicate your crash logs; it can often provide more information than other symbolication programs: - Inlined functions - Variables that are in scope for an address, along with their locations. The simplest form of symbolication is to load an executable: (lldb) target create --no-dependents --arch x86_64 /tmp/a.out Copy to clipboard The –no-dependents option is used with the target create command, so you do not load all the dependent shared libraries from the current system. When you symbolicate, you are often symbolicating a binary that was running on another system, and even though the main executable might reference shared libraries in /usr/lib, you often do not want to load the versions on the current computer. The image list command displays a list of all shared libraries associated with the current target. As expected, there is only a single binary: (lldb) image list [ 0] 73431214-6B76-3489-9557-5075F03E36B4 0x0000000100000000 /tmp/a.out /tmp/a.out.dSYM/Contents/Resources/DWARF/a.out Copy to clipboard Now you can look up an address: (lldb) image lookup --address 0x100000aa3 Address: a.out[0x0000000100000aa3] (a.out. TEXT. text + 131) Summary: a.out`main + 67 at main.c:13 Copy to clipboard Because no slide or load addresses were specified for individual sections in the binary ([Define load addresses for sections](dframe-symbol-define-load-addresses-for-sections)), the address used here is a *file address*. A file address refers to a virtual address as defined by each object file. If you do not use –no-dependents with the target create command, LLDB loads all the dependent shared libraries: (lldb) image list [ 0] 73431214-6B76-3489-9557-5075F03E36B4 0x0000000100000000 /tmp/a.out/ tmp/a.out.dSYM/Contents/Resources/DWARF/a.out [ 1] 8CBCF9B9-EBB7-365E-A3FF-2F3850763C6B 0x0000000000000000/usr/lib/ system/libsystem_c.dylib [ 2] 62AA0B84-188A-348B-8F9E-3E2DB08DB93C 0x0000000000000000/usr/lib/ system/libsystem_dnssd.dylib [ 3] C0535565-35D1-31A7-A744-63D9F10F12A4 0x0000000000000000/usr/lib/ system/libsystem_kernel.dylib ... Copy to clipboard Performing a lookup using a file address can result in multiple matches because most shared libraries have a virtual address space that starts at zero: (lldb) image lookup -a 0x1000 Address: a.out[0x0000000000001000] (a.out. PAGEZERO + 4096) Address: libsystem_c.dylib[0x0000000000001000](libsystem_c.dylib.TEXT.text + 928) Summary: libsystem_c.dylib`mcount + 9 Address: libsystem_dnssd.dylib[0x0000000000001000](libsystem_dnssd.dylib. TEXT. text + 456) Summary: libsystem_dnssd.dylib`ConvertHeaderBytes + 38 Address: libsystem_kernel.dylib[0x0000000000001000](libsystem_kernel.dylib. TEXT. text + 1116) Summary: libsystem_kernel.dylib`clock_get_time + 102 ... Copy to clipboard To avoid getting multiple file address matches, specify the name of the shared library to limit the search: (lldb) image lookup -a 0x1000 a.out Address: a.out[0x0000000000001000] (a.out. PAGEZERO + 4096) Copy to clipboard ## Define load addresses for sections When symbolicating your crash logs, it can be tedious if you must always adjust your crash log addresses into file addresses. To avoid performing any conversion, you can set the load address for the sections of the modules in your target. Once you set any section load address, lookups will switch to using load addresses. You can also slide all sections in the executable by the same amount, or set the load address for individual sections. Use the target modules load –slide command to set the load address for all sections. The following example slides all sections in file a.out by adding 0x123000 to each section’s file address: (lldb) target create --no-dependents --arch x86_64 /tmp/a.out (lldb) target modules load --file a.out --slide 0x123000 Copy to clipboard It is often easier to specify the actual load location of each section by name. ## Load multiple executables Often you have more than one executable involved when you need to symbolicate a crash log. When this happens, create a target for the main executable or one of the shared libraries, and then add more modules to the target using the target modules add command. For example, consider a crash log which contains the following images: Binary Images: 0x100000000 - 0x100000ff7 /tmp/a.out 0x7fff83f32000 - 0x7fff83ffefe7 <8CBCF9B9-EBB7-365E-A3FF-2F3850763C6B>/usr/lib/system/libsystem_c.dylib 0x7fff883db000 - 0x7fff883e3ff7 <62AA0B84-188A-348B-8F9E-3E2DB08DB93C>/usr/lib/system/libsystem_dnssd.dylib 0x7fff8c0dc000 - 0x7fff8c0f7ff7 /usr/lib/system/libsystem_kernel.dylib Copy to clipboard To symbolicate this log, first create the target using the main executable, and then add any extra shared libraries: (lldb) target create --no-dependents --arch x86_64 /tmp/a.out (lldb) target modules add /usr/lib/system/libsystem_c.dylib (lldb) target modules add /usr/lib/system/libsystem_dnssd.dylib (lldb) target modules add /usr/lib/system/libsystem_kernel.dylib Copy to clipboard If you have debug symbols in standalone files, you can specify their paths using the – symfile option for the target create and target modules add commands: (lldb) target create --no-dependents --arch x86_64 /tmp/a.out --symfile /tmp/a.out.dSYM (lldb) target modules add /usr/lib/system/libsystem_c.dylib --symfile /build/server/a/libsystem_c.dylib.dSYM (lldb) target modules add /usr/lib/system/libsystem_dnssd.dylib --symfile /build/server/b/libsystem_dnssd.dylib.dSYM (lldb) target modules add /usr/lib/system/libsystem_kernel.dylib --symfile /build/server/c/libsystem_kernel.dylib.dSYM Copy to clipboard Next, set the load addresses for each TEXT section (note the colors of the load addresses above and below) using the first address from the Binary Images section for each image: (lldb) target modules load --file a.out 0x100000000 (lldb) target modules load --file libsystem_c.dylib0x7fff83f32000 (lldb) target modules load --file libsystem_dnssd.dylib 0x7fff883db000 (lldb) target modules load --file libsystem_kernel.dylib 0x7fff8c0dc000 Copy to clipboard Any stack backtraces that have not yet been symbolicated can now be symbolicated using the image lookup command with the raw backtrace addresses. Given the following raw backtrace: Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x00007fff8a1e6d46 kill + 10 1 libsystem_c.dylib 0x00007fff84597df0 abort + 177 2 libsystem_c.dylib 0x00007fff84598e2a assert_rtn + 146 3 a.out 0x0000000100000f46 main + 70 4 libdyld.dylib 0x00007fff8c4197e1 start + 1 Copy to clipboard The following load addresses can now be symbolicated: (lldb) image lookup -a 0x00007fff8a1e6d46 (lldb) image lookup -a 0x00007fff84597df0 (lldb) image lookup -a 0x00007fff84598e2a (lldb) image lookup -a 0x0000000100000f46 Copy to clipboard ## Get variable information If you use the –verbose option with the image lookup –address command, you can get verbose information which often includes the locations of some of your local variables: (lldb) image lookup --address 0x100123aa3 --verbose Address: a.out[0x0000000100000aa3] (a.out. TEXT. text + 110) Summary: a.out`main + 50 at main.c:13 Module: file = "/tmp/a.out", arch = "x86_64" CompileUnit: id = {0x00000000}, file = "/tmp/main.c", language = "ISOC:1999" Function: id = {0x0000004f}, name = "main", range = [0x0000000100000bc0-0x0000000100000dc9) FuncType: id = {0x0000004f}, decl = main.c:9, clang_type = "int (int, const char **, const char **, const char **)" Blocks: id = {0x0000004f}, range = [0x100000bc0-0x100000dc9) id = {0x000000ae}, range = [0x100000bf2-0x100000dc4) LineEntry: [0x0000000100000bf2-0x0000000100000bfa): /tmp/main.c:13:23 Symbol: id = {0x00000004}, range = [0x0000000100000bc0-0x0000000100000dc9), name="main" Variable: id = {0x000000bf}, name = "path", type= "char [1024]", location = DW_OP_fbreg(-1072), decl = main.c:28 Variable: id = {0x00000072}, name = "argc", type= "int", *location = r13*, decl = main.c:8 Variable: id = {0x00000081}, name = "argv", type= "const char **", *location = r12*, decl = main.c:8 Variable: id = {0x00000090}, name = "envp", type= "const char **", *location = r15*, decl = main.c:8 Variable: id = {0x0000009f}, name = "aapl", type= "const char **", *location = rbx*, decl = main.c:8 Copy to clipboard The interesting part of this listing is the variables: they are the parameters and local variables that are in scope for the address that was specified. Crash logs often include register information for the first frame in each stack. Being able to reconstruct one or more local variables can help you decipher more information from a crash log than you typically would be able to. In reality, this is only useful for the first frame, and only if your crash logs have register information for your threads. ## Use Python API to symbolicate You can perform all the commands demonstrated in the previous sections using the Python script bridge. The following code recreates the target and adds the three shared libraries that were added in the crash log example in get variable information <frame-symbol-get-variable-information>: triple = "x86_64-apple-macosx" platform_name = None add_dependents = False target = lldb.debugger.CreateTarget("/tmp/a.out", triple, platform_name, add_dependents, lldb.SBError()) if target: # Get the executable module module = target.GetModuleAtIndex(0) target.SetSectionLoadAddress(module.FindSection(" TEXT"), 0x100000000) module = target.AddModule("/usr/lib/system/libsystem_c.dylib", triple, None,"/build/server/a/libsystem_c.dylib.dSYM") target.SetSectionLoadAddress(module.FindSection(" TEXT"), 0x7fff83f32000) module = target.AddModule ("/usr/lib/system/libsystem_dnssd.dylib",triple, None, "/build/server/b/libsystem_dnssd.dylib.dSYM") target.SetSectionLoadAddress(module.FindSection(" TEXT"), 0x7fff883db000) module = target.AddModule ("/usr/lib/system/libsystem_kernel.dylib", triple, None, "/build/server/c/libsystem_kernel.dylib.dSYM") target.SetSectionLoadAddress(module.FindSection(" TEXT"), 0x7fff8c0dc000) load_addr = 0x00007fff8a1e6d46 # so_addr is a section offset address, or a lldb.SBAddress object so_addr = target.ResolveLoadAddress (load_addr) # Get a symbol context for the section offset address which # includes a module, compile unit, function, block, line entry, and # symbol sym_ctx = so_addr.GetSymbolContext(lldb.eSymbolContextEverything) print sym_ctx Copy to clipboard ## Use built-in Python module to symbolicate LLDB includes a module in the lldb package named `lldb.utils.symbolication`. This module contains numerous symbolication functions that simplify symbolication by allowing you to create objects to represent symbolication class objects such as: lldb.utils.symbolication.Address lldb.utils.symbolication.Section lldb.utils.symbolication.Image lldb.utils.symbolication.Symbolicator lldb.utils.symbolication.Address Copy to clipboard This class represents an address that will be symbolicated. It will cache any information that has been looked up: module, compile unit, function, block, line entry, symbol. It does this by having a `lldb.SBSymbolContext` as a member variable. ### lldb.utils.symbolication.Section This class represents a section that might get loaded in lldb.utils.symbolication.Image. It includes helper functions which enable you to set it from text that may have been extracted from a crash log file. ### lldb.utils.symbolication.Image This class represents a module that might get loaded into the target used for symbolication. This class contains the executable path, the optional symbol file path, the triple, and the list of sections that must be loaded if you choose to ask the target to load this image. Many of these objects will never be loaded on the target unless they are required by symbolication. You often have a crash log that has 100 to 200 different shared libraries loaded, but your crash log stack backtraces only use a few of these shared libraries. Only the images that contain stack backtrace addresses are to be loaded in the target for symbolication. Subclasses of this class are to override the locate\_module\_and\_debug\_symbols method: class CustomImage(lldb.utils.symbolication.Image): def locate_module_and_debug_symbols (self): # Locate the module and symbol given the info found in # the crash log Copy to clipboard Overriding this function allows clients to find the correct executable module and symbol files because they might reside on a build server. ### lldb.utils.symbolication.Symbolicator This class coordinates the symbolication process by loading only the `lldb.utils.symbolication.Image` instances that are to be loaded to symbolicate a supplied address. Last Published: Oct 06, 2026 [Previous Topic User-defined formats](https://docs.qualcomm.com/bundle/publicresource/80-N2040-31/topics/frame-and-thread-formatting.md) [Next Topic Variable formatting](https://docs.qualcomm.com/bundle/publicresource/80-N2040-31/topics/variable-formatting.md)