Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LLDB: add symbols file?

I'm trying to debug an android native app from Android Studio's native debugging using lldb.
My native app contains one libmain.so that is compiled and run by Android Studio and another external libother.so compiled by me. when debugging, I am able to set breakpoints in libmain.so but not libother.so.
Both shared objects are stripped but somehow Android Studio makes lldb know about the unstripped version of libmain.so. I want to do the same for libother.so.

What command do I need to give lldb so that it would load the symbols from an unstripped file on my local machine?
When I do image list I see the main .so with a path the points to its local unstripped version:

/Users/username/Projects/gow/android/AppName/app/build/intermediates/binaries/debug/arm7/obj/armeabi-v7a/libmain.so

and the second .so with a path like /var/folders/3w/5nr95lxx3qvdm2ylb8c8b7500000gn/T/./lldb/module_cache/remote-android/.cache/B5F32653-0000-0000-0000-000000000000/libother.so

How do I make lldb find the unstripped version of libother.so ?
I tried image add and target symbols add but it didn't work.

like image 925
shoosh Avatar asked Sep 10 '15 15:09

shoosh


People also ask

Is GDB better than LLDB?

Both GDB and LLDB are of course excellent debuggers without doubt. GDB is debugger part of the GNU project created to work along the GNU compiler. LLDB is debugger part of the LLVM project created to work along LLVM compiler. The majority of the commands are the same.

Is LLDB the same as GDB?

In brief, LLDB and GDB are two debuggers. The main difference between LLDB and GDB is that in LLDB, the programmer can debug programs written in C, Objective C and C++ while, in GDB, the programmer can debug programs written in Ada, C, C++, Objective C, Pascal, FORTRAN and Go.

What is LLDB C++?

LLDB is the default debugger in Xcode on macOS and supports debugging C, Objective-C and C++ on the desktop and iOS devices and simulator.

How do you set a breakpoint in LLDB?

In lldb you can set breakpoints by typing either break or b followed by information on where you want the program to pause. After the b command, you can put either: a function name (e.g., b my_subroutine ) a line number (e.g., b 12 )


2 Answers

The answers in this thread seem to be specific for MacOSX. I am using Linux, so these answers weren't very helpful. After some time I've figured it out, and here is a very simple solution. Before you do "process attach" you should execute the following command:

settings set target.exec-search-paths /path/to/directory/with/unstripped/library/on/host

With this setting lldb has no problems finding the correct version of the library.

BTW, latest versions of Android Studio don't have any problems with external libraries (in fact, the same technique is used to set correct paths all libraries, both "internal" and "external", at least if you're building with Gradle). But if you use standalone lldb, this can be very handy.

To avoid typing it after start of each debugging session you can save this command to file (e.g. lldb.cmd) and then start lldb like this:

./lldb -S lldb.cmd
like image 77
Aleksei Petrenko Avatar answered Oct 09 '22 21:10

Aleksei Petrenko


use the "target.source-map" setting

(lldb) settings list target.source-map
source-map -- Source path remappings used to track the change of location between a source file when built, and where it exists on the current system. It consists of an array of duples, the first element of each duple is some part (starting at the root) of the path to the file when it was built, and the second is where the remainder of the original build hierarchy is rooted on the local system. Each element of the array is checked in order and the first one that results in a match wins.

i.e.

settings set target.source-map /build_src /source

where the building environment is under /build_src and the.dSYM files (symbols) are copied under /source

EDIT:

Binaries are often stripped after being built and packaged into a release. If your build systems saves an unstripped executable a path to this executable can be provided using the key DBGSymbolRichExecutable

You can write a shell command that will be given a UUID value and is expected to return a plist with certain keys that specify where the binary is.

You can enable the shell script using:

% defaults write com.apple.DebugSymbols DBGShellCommands /path/to/shellscript

Your shell script will be invoked with a UUID string value like "23516BE4-29BE-350C-91C9-F36E7999F0F1". The shell script can respond with a plist in the following format:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
<plist version="1.0">
<dict>
        <key>23516BE4-29BE-350C-91C9-F36E7999F0F1</key>
        <dict>
                <key>DBGArchitecture</key>
                <string>i386</string>
                <key>DBGBuildSourcePath</key>
                <string>/path/to/build/sources</string>
                <key>DBGSourcePath</key>
                <string>/path/to/actual/sources</string>
                <key>DBGDSYMPath</key>
                <string>/path/to/foo.dSYM/Contents/Resources/DWARF/foo</string>
                <key>DBGSymbolRichExecutable</key>
                <string>/path/to/unstripped/exectuable</string>
        </dict>
        <key>A40597AA-5529-3337-8C09-D8A014EB1578</key>
        <dict>
                <key>DBGArchitecture</key>
                <string>x86_64</string>
                .....
        </dict>
</dict>
</plist>

for more details please see:

http://lldb.llvm.org/symbols.html

https://www.mail-archive.com/[email protected]/msg01142.html

EDIT 2:

Terminal command to print an executable's build UUID

$ xcrun dwarfdump --uuid <PATH_TO_APP_EXECUTABLE>

source

like image 40
Pat Avatar answered Oct 09 '22 20:10

Pat