LLDB:添加符号文件?
Posted
技术标签:
【中文标题】LLDB:添加符号文件?【英文标题】:LLDB: add symbols file? 【发布时间】:2015-12-06 23:45:33 【问题描述】:我正在尝试使用 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 add
和target symbols add
,但没有成功。
【问题讨论】:
您是否使用 Gradle 构建应用程序?如果是这样,你能分享你的构建文件吗?也请分享您的 Android.mk 文件 我确实使用 gradle 构建它。构建文件与 Teapot 示例 (developer.android.com/ndk/samples/sample_teapot.html) 中的构建文件相同.用于构建 .so 的 Android.mk 也是在 Android Studio 支持之前用于与 ndk 一起构建的标准文件。它使用 clang 和 c++_static(太大,无法在此处添加)。我正在使用最新的 NDK 你是在windows上调试吗?我假设您提供的路径来自Android。 NDK 中还有一些已知的 bug;当使用 LLDB 断点进行调试时,在 Windows 上并不总是有效;如果遇到这种情况,您可以切换到 GDB 调试作为临时解决方法。 尝试使用 isDebuggable 和 isJniDebuggable 配置调试构建类型设置为 true tools.android.com/tech-docs/new-build-system/… 从OSX调试,我试过isDebuggable和isJniDebuggable,都没有效果。 【参考方案1】:此线程中的答案似乎是针对 MacOSX 的。我正在使用 Linux,所以这些答案不是很有帮助。一段时间后,我想通了,这是一个非常简单的解决方案。在执行“进程附加”之前,您应该执行以下命令:
settings set target.exec-search-paths /path/to/directory/with/unstripped/library/on/host
使用此设置,lldb 可以毫无问题地找到库的正确版本。
顺便说一句,最新版本的 Android Studio 对外部库没有任何问题(事实上,相同的技术用于设置所有库的正确路径,包括“内部”和“外部”,至少如果你是使用 Gradle 构建)。但是如果你使用独立的 lldb,这会非常方便。
为避免在每个调试会话开始后键入它,您可以将此命令保存到文件(例如lldb.cmd
),然后像这样启动 lldb:
./lldb -S lldb.cmd
【讨论】:
这似乎不适用于 AS 2.2.2(也在 Linux 下运行)。lldb
正在使用存储在.lldb/module_cache/...
(我可以在image list
中看到)中不包含调试符号的库。我已将 exec-search-path 放在 LLDB Startup Commands
下的 Run/Debug Configuration
中。路径本身指向abs_path_to_project/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a
,因为该目录包含带有调试符号的共享库。关于我在这里做错了什么有什么想法吗?
不知道LLDB startup commands
,没用过。你可以手动输入它,它有效吗?您的image list
上是否显示库?
抱歉,我的库没有正确构建以进行调试,您的答案在修复构建过程后对我有用。谢谢。【参考方案2】:
使用“target.source-map”设置
(lldb) 设置列表 target.source-map source-map -- 源路径 用于跟踪源文件之间位置变化的重新映射 何时构建,以及它在当前系统上的位置。 它由一个 duple 数组组成,每个 duple 的第一个元素是路径的某个部分(从根开始) 文件时 已构建,第二个是原始构建层次结构的其余部分植根于本地系统。每个 的元素 数组按顺序检查,第一个匹配的获胜。
即
settings set target.source-map /build_src /source
建筑环境在/build_src
下,.dSYM文件(符号)复制到/source
下
编辑:
二进制文件通常在构建并打包到发行版后被剥离。如果您的构建系统保存了一个未剥离的可执行文件,则可以使用键 DBGSymbolRichExecutable
提供该可执行文件的路径您可以编写一个 shell 命令,该命令将被赋予一个 UUID 值并且是 期望返回一个带有某些键的 plist,这些键指定二进制文件的位置 是。
您可以使用以下命令启用 shell 脚本:
% defaults write com.apple.DebugSymbols DBGShellCommands /path/to/shellscript
您的 shell 脚本将使用 UUID 字符串值调用,例如 “23516BE4-29BE-350C-91C9-F36E7999F0F1”。 shell 脚本可以响应 plist 格式如下:
<?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/lldb-dev@cs.uiuc.edu/msg01142.html
编辑 2:
用于打印可执行文件的构建 UUID 的终端命令
$ xcrun dwarfdump --uuid <PATH_TO_APP_EXECUTABLE>
source
【讨论】:
这很好!,我如何设置/获取我的 .so apriori 的 UUID?【参考方案3】:为了完整起见,我最终做的是
- 将-Wl,--build-id=sha1
添加到libmain.so 的Android.mk 中的LOCAL_LDFLAGS
- 将/Users/username/Projects/gow/android/AppName/app/build/intermediates/binaries/debug/arm7/obj/armeabi-v7a/
的符号链接添加到未剥离的共享对象。
这允许 Android-Studio 的 LLDB 找到未剥离的 .so,正确显示其符号,并允许我在 libmain.so 代码中添加断点。
【讨论】:
【参考方案4】:我发现当共享库不包含.note.gnu.build-id
部分时会出现此问题。此部分包含文件的唯一 ID。要创建此部分,需要将 --build-id
开关传递给 LD 链接器。
将 build-id 添加到我的共享库后,LLDB 开始使用未剥离版本的库并成功加载其调试信息。
【讨论】:
以上是关于LLDB:添加符号文件?的主要内容,如果未能解决你的问题,请参考以下文章