关于android:LLDB:添加符号文件?

LLDB: add symbols file?

我正在尝试使用lldb从Android Studio的本机调试中调试android本机应用程序。
我的本机应用程序包含一个由Android Studio编译和运行的libmain.so和由我编译的另一个外部libother.so。 调试时,我可以在libmain.so中设置断点,但不能在libother.so中设置断点。
两个共享对象都被剥离,但是Android Studio以某种方式使lldb知道libmain.so的未剥离版本。 我想对libother.so做同样的事情。

我需要给lldb什么命令,以便它可以从本地计算机上未解压缩的文件中加载符号?
当我执行image list时,我看到带有路径的主.so指向其本地未压缩版本:

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

第二个.so的路径类似于
/var/folders/3w/5nr95lxx3qvdm2ylb8c8b7500000gn/T/./lldb/module_cache/remote-android/.cache/B5F32653-0000-0000-0000-000000000000/libother.so

如何使lldb查找libother.so的解压缩版本?
我尝试了image addtarget symbols add,但是没有用。


该线程中的答案似乎特定于MacOSX。我正在使用Linux,所以这些答案不是很有帮助。一段时间后,我弄清楚了,这是一个非常简单的解决方案。在执行"过程附加"之前,应执行以下命令:

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

使用此设置,lldb可以正确查找库的正确版本。

顺便说一句,最新版本的Android Studio外部库没有任何问题(实际上,至少在使用Gradle构建时,使用相同的技术来设置所有库("内部"和"外部")的正确路径)。但是,如果您使用独立的lldb,这将非常方便。

为了避免在每次调试会话开始后都键入它,您可以将此命令保存到文件(例如lldb.cmd),然后像这样启动lldb:

1
./lldb -S lldb.cmd


为了完整起见,我最终要做的是
-在libmain.so的Android.mk中的LOCAL_LDFLAGS中添加-Wl,--build-id=sha1
-将符号链接从/Users/username/Projects/gow/android/AppName/app/build/intermediates/binaries/debug/arm7/obj/armeabi-v7a/添加到未剥离的共享库。

这样一来,Android Studio的LLDB就可以找到解开的.so,正确显示其符号,并允许我在libmain.so代码中添加断点。


使用" target.source-map"设置

(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.

1
settings set target.source-map /build_src /source

建筑环境位于/build_src下,.dSYM文件(符号)被复制到/source

编辑:

二进制文件通常在构建并打包到发行版中后被剥离。如果您的构建系统保存了未压缩的可执行文件,则可以使用键DBGSymbolRichExecutable提供此可执行文件的路径。

您可以编写一个shell命令,该命令将被赋予一个UUID值,并且
期望返回带有某些键的plist,这些键指定二进制文件的位置
是。

您可以使用以下命令启用外壳脚本:

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

您的shell脚本将使用UUID字符串值调用,例如
" 23516BE4-29BE-350C-91C9-F36E7999F0F1"。 Shell脚本可以使用
plist的格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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>

有关更多详细信息,请参见:

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

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

编辑2:

终端命令打印可执行文件的构建UUID

1
$ xcrun dwarfdump --uuid <PATH_TO_APP_EXECUTABLE>

资源


我发现共享库不包含.note.gnu.build-id部分时,会发生此问题。此部分包含文件的唯一ID。要创建此部分,需要将--build-id开关传递给LD链接器。

将build-id添加到我的共享库后,LLDB开始使用该库的未压缩版本并成功加载了其调试信息。