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 addtarget 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:添加符号文件?的主要内容,如果未能解决你的问题,请参考以下文章

xcode调试

在lldb调试中调用c++函数

如何撤消strip - 即将符号添加回剥离的二进制文件

libstdc++.so:添加符号时出错:文件格式错误

删除/重新添加文件,现在我得到架构 arm64 的未定义符号:

在C盘Fonts文件夹里放置了一个符号文件。但是我在使用Arcgis时,给地类图斑添加地类符号时却找不到那个符