Is XCode or lldb able to download source files when debugging core dumps?

I wonder when people debugging core dumps with XCode, is XCode able to display the source files on the crash stack? If the source files are not available, is XCode or lldb downloading them?

I asked this because WinDbg is able to download source files when debugging minidump file, so I image that XCode/lldb has similar functionality.

If not, is python scripting via SBAPI the right way to achieve the goal of downloading source files for those stack frames?

lldb doesn’t currently have facilities to download source files for you. It does know how to map the build-time location of source files to their debug-time location. That’s what the target.source-map setting is for.

But at present, you would have to get the source files onto your local machine and write the source-map setting appropriately. There’s no way to tell lldb “go here to get this source file”.

On MacOS, lldb uses a “DebugSymbols” framework to find the debug info for a given binary image (by UUID):

[

Symbols on macOS — The LLDB Debugger
lldb.llvm.org

](Symbols on macOS — The LLDB Debugger)

We could certainly extend that basic idea to other hosts and add support for download source files as well. That’s probably the cleanest way to do this. It’s just as interface so it is easy to get it to accommodate many debug symbol repositories.

But nothing of that sort exists today.

Jim

Thanks.

Symbols on macOS — The LLDB Debugger

My understanding of this docs is that is about using the defaults command in MacOS to locate/download symbols files from com.apple.DebugSymbols.

We could certainly extend that basic idea to other hosts and add support for download source files as well. That’s probably the cleanest way to do this. It’s just as interface so it is easy to get it to accommodate many debug symbol repositories.

Creating a similar tool as defaults in other platform (like linux) seems a lot work to do. I feel like adding this functionality using customized python scripting is easier way to do it.

Defaults are just the way to set options for the symbol lookup & caching, like what the callout tool should be and where the cache directory should be. I wouldn’t focus on that; the interesting bit was how we specified the lookup, and caching strategy. Presumably you could do the same thing on Linux with environment variables, or some init file or whatever. The main idea is that since there’s no way to know what the policy for storing & looking up old debug info will be in any given setup, we made a way to invoke a simple “UUID → cached debug symbols” tool which happens automatically and on demand. Then if you have an extant symbols repository or library for managing same, you can easily adapt it to this callout.

You wouldn’t even need to do this by adding a separate library. You could do all this in your Host plugin, presumably adding some lldb settings to specify the cache location and the callout tool, and then running the callout by hand in your Host plugin. We used a separate library because “please find me the symbols for this UUID” is something many analysis tools on the system want to do, not just lldb. By adding this system library, all the analysis tools can share the facility.

Of course, there’s no problem with adding some Python command that does “please get the debug info & sources for this Module”. But that’s going to be pretty “by hand”. If you want this to be transparent in lldb, you need to use the same hook point in lldb’s symbol search that the DebugSymbols callout hooks into.

The simplest approach for getting sources would be to use the extant hook point, and add fetching sources & fixing up the source-map to the work that gets done in the DebugSymbols equivalent callout. That’s half done in the macOS DebugSymbols code, since the return info from DebugSymbols on macOS can optionally include source-map {original, current} pairs, and lldb will fix up the Module’s source paths using this info. That part works already on macOS and it wouldn’t be all that hard to adapt it to other systems. The module-specific source maps are already present. The only reason we didn’t also copy the sources in the DebugSymbols callout tool it that we tend to use mounts rather than copying for that purpose.

If you wanted to be more efficient (many projects have lots of source code that doesn’t get seen in a typical debug session) you could add another callout point in the SourceManager. But that would be a bit more work.

Jim

Thanks for the detailed writing-up.

If we want to do caching for sources, we don’t want to copy the entire source repo since we only care about the sources that show up in the crash stack. And the only way to get source files showing up in the crash stack is to do a backtrace on that crash dump. So, an extended python command seems to do this job after we have a backtrace. Or we could use mounts, similar to DebugSymbols, which seems more ideal. I’ll explore the latter option first.