变量值不可用
通常,该得分与该计划的优化级别有关:
“优化出”表示程序符号声明了具有给定名称的变量,但该变量没有值或位置。这意味着编译器已完全优化了变量,调试程序无法显示它。如果需要,请使用优化程度较低的构建设置。
不可用表示变量在当前地址无效,但其值在其他地址已知。在优化代码中,编译器通常会重复使用寄存器,破坏之前变得不可用的值。
您可以使用“sym-info”命令查看变量的有效范围:
[zxdb] sym-info my_variable
Variable: my_variable
Type: int
DWARF tag: 0x05
DWARF location (address range + DWARF expression bytes):
[0x3e0d0a3e05b, 0x3e0d0a3e0b2): 0x70 0x88 0x78
[0x3e0d0a3e0b2, 0x3e0d0a3eb11): 0x76 0x48 0x10 0xf8 0x07 0x1c 0x06
在“DWARF 位置”下,它将给出变量值已知的地址范围列表(包括范围的起始位置,不包括结束位置)。运行到其中一个地址以查看变量的值(使用“di”可查看当前地址)。
您可以忽略“DWARF 表达式字节”,它们是用于查找变量的内部指令。
找不到符号
sym-stat
命令将告知您符号的状态。如果没有正在运行的进程,它将提供有关您指定的不同符号位置的信息。如果未找到您的符号,请确保与您的预期相符:
[zxdb] sym-stat
Symbol index status
Indexed Source path
(folder) /home/me/.build-id
(folder) /home/me/build/out/x64
0 my_dir/my_file
如果您在“符号索引状态”的“已编入索引”列中看到“0”,则表示调试程序无法找到您的符号所在的位置。请参阅下文,了解如何指定这些内容的位置。
使用“.build-id”层次结构的符号源会针对已编入索引的符号列出“(folder)”,因为这类源不需要编入索引。如需检查层次结构是否包含给定的 build ID,请前往其中的“.build-id”,然后找到该 build ID 中最前面的 - 多个字符所在的文件夹,查看是否有匹配的文件。
如果您有一个正在运行的程序,sym-stat
还会针对加载到进程的每个二进制文件输出符号信息。如果没有找到符号,请在此列表中找到二进制文件或共享库的条目。如果系统显示:
Symbols loaded: No
则表示它在本地计算机上“符号索引状态”中列出的任何位置都找不到与给定 build ID 对应的符号化二进制文件。您可能需要使用 -s
添加新位置。
如果显示如下内容:
Symbols loaded: Yes
Symbol file: /home/foo/bar/...
Source files indexed: 1
Symbols indexed: 0
其中,“已编入索引的源文件”和“已编入索引的符号”为 0 或一个非常小的整数,表示调试程序找到了符号化文件,但其中只有很少的符号或根本没有符号。通常,这意味着二进制文件未在启用符号的情况下构建,或者符号已剥离。请检查您的 build,您应该将路径传递给未剥离的二进制文件,并且原始编译行应包含用于获取符号的 -g
。
了解 Zxdb 如何加载符号
符号设置通常应由您的环境自动设置(请参阅下文中的关于符号设置),让大多数用户不必进行任何配置。本部分提供了一些实现详情,以帮助您诊断问题。
关于 build ID
Zxdb 使用二进制文件的“build ID”找到目标设备上二进制文件的符号。如果 build ID 不匹配,Zxdb 将不会加载这些符号,即使文件名相同也是如此。如需在 Linux 上查看二进制文件的 build ID(Mac 用户需要单独安装 readelf),请转储 ELF 二进制文件的“备注”:
$ readelf -n my_binary
... (some other notes omitted) ...
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: 18cec080fc47cdc07ec554f946f2e73d38541869
sym-stat
Zxdb 命令将显示当前附加进程中加载的每个二进制文件和库的 build ID,以及对应的符号文件(如果找到)。
符号服务器
Zxdb 可以从 Google 服务器或上游 debuginfod 服务器加载预构建库的符号。如此一来,对于非本地构建的任何内容,SDK 用户都会收到符号。如需了解详情,请参阅下载符号。
对于大型二进制文件,符号可能是几 GB,因此下载过程可能需要几分钟时间。
在此期间,sym-stat
命令会显示“正在下载...”。
下载的符号存储在符号缓存中。symbol-cache
设置包含此目录的名称:
[zxdb] get symbol-cache
symbol-cache = /home/me/.fuchsia/debug/symbol-cache
从从上游软件包提取的预构建二进制文件中下载符号时,debuginfo 可能没有相应的 ELF 二进制文件(具体取决于服务器和软件包)。您可能会在 zxdb 中看到如下错误:
...
binary for build_id 26820458adaf5d95718fb502d170fe374ae3ee70 not found on 5 servers
binary for build_id 53eaa845e9ca621f159b0622daae7387cdea1e97 not found on 5 servers
binary for build_id f3fd699712aae08bbaae3191eedba514c766f9d2 not found on 5 servers
binary for build_id 4286bd11475e673b194ee969f5f9e9759695e644 not found on 5 servers
binary for build_id 2d28b51427b49abcd41dcf611f8f3aa6a2811734 not found on 5 servers
binary for build_id 0401bd8da6edab3e45399d62571357ab12545133 not found on 5 servers
...
表示在 debuginfod 服务器上未找到 ELF 二进制文件。这意味着 ELF 符号将不适用于此特定二进制文件,这通常适用于大多数调试场景。在这种情况下,最常用的 ELF 特定符号是 PLT 符号。
使用 sym-stat
验证 DWARF 信息是否已加载(与 ELF 符号分开下载):
libc.so.6
Base: 0x1c85fdc2000
Build ID: 0401bd8da6edab3e45399d62571357ab12545133
Symbols loaded: Yes
Symbol file: /home/me/.fuchsia/debug/symbol-cache/04/01bd8da6edab3e45399d62571357ab12545133.debug
Source files indexed: 1745
Symbols indexed: 10130
“.build-id”目录符号数据库
许多构建环境(包括主“fuchsia.git”代码库)都会在名为“.build-id”的标准目录结构中添加符号化二进制文件。此目录中包含根据二进制文件 build ID 的前两个字符命名的子目录,这些子目录中将包含根据 build ID 的其余字符命名的符号文件。
您可以在命令行中设置一个或多个 build ID 目录(无需将其命名为“.build-id”),也可以使用 build-id-dirs
设置(目录路径列表)以交互方式设置这些目录:
[zxdb] set build-id-dirs += "/home/me/project/out/x64/.build-id"
这些目录将显示在 sym-stat
命令的输出中,但会带有“(folder)”(而不是其中发现的二进制文件数量)注释,并且二进制文件不会显示在 sym-stat --dump-index
输出中。这是因为 Zxdb 会在搜索符号时按需搜索这些目录,而不是提前枚举它们。
单个文件和目录
如果您有一个二进制文件,但不包含其他符号数据库格式,则可以单独告知 Zxdb 该文件。您可以使用命令行标志,也可以使用 symbol-paths
设置(文件或目录列表)以交互方式设置该标志:
[zxdb] set symbol-paths += /home/me/project/a.out
此设置还接受目录名称。在这种情况下,Zxdb 会以非递归方式枚举该目录中的所有文件,并查找具有 build ID 的二进制文件:
[zxdb] set symbol-paths += /home/me/project/build/
如需查看您提供的营业地点的状态,请执行以下操作:
[zxdb] sym-stat
Symbol index status
This command just refreshed the index.
Use "sym-stat --dump-index" to see the individual mappings.
Indexed Source path
1 /home/me/a.out
2 /home/me/project/build/
您还可以使用 sym-stat --dump-index
命令查看以这种方式添加的二进制文件的 build ID 和文件名。
“ids.txt”符号索引
某些较旧的内部 Google 项目会生成名为“ids.txt”的文件。这样可以提供从二进制文件的 build ID 到本地系统上的符号路径的映射。如果您的 build 会生成此类文件,并且该文件不会自动加载,您可以通过命令行标志将其提供给 Zxdb,也可以使用 ids-txts
设置(文件名列表)以交互方式提供该文件:
[zxdb] set ids-txts += "/home/me/project/build/ids.txt"
ids.txt 文件中的符号文件也会反映在上一部分中介绍的 sym-stat
和 sym-stat --dump-index
命令中。
符号设置简介
您的环境应该会自动应用上述了解 Zxdb 如何加载符号部分中所述的设置。本部分介绍如何设置这些符号,以帮助调试符号加载问题。
symbol-index-files
设置包含一个或多个应由开发环境设置的 JSON 格式文件:
[zxdb] get symbol-index-files
symbol-index-files =
• /home/me/.fuchsia/debug/symbol-index.json
此文件可以包含一些全局设置,还可以引用其他符号索引文件。通常,您正在使用的每个构建环境都有一个类似文件,该文件以引用方式包含在该全局文件中。如果您要在构建环境之间切换,并发现符号无法加载,请检查 ffx debug symbol-index list
命令以确保您的环境已注册。通常,当您运行任何 ffx debug ...
子工具时,它们会自动插入到包含的列表中。
源代码行不匹配
有时,源文件列表与代码不匹配。最常见的原因是 build 已过时,不再与源代码匹配。调试程序将检查符号文件的修改时间是否晚于源文件,但它仅在第一次显示文件时输出警告。如果您怀疑有问题,请查看此警告。
有些用户会多次结账。如果在错误的文件中找到了文件,请替换 build-dirs
选项,如上文设置指南中所述。
如需显示从 list
中找到的文件的文件名,请使用 -f
选项:
[zxdb] list -f
/home/me/fuchsia/out/x64/../../src/foo/bar.cc
... <source code> ...
您还可以设置 show-file-paths
选项。这会增加文件路径信息:
- 它会在源代码列表中显示完整的解析路径,如
list -f
中所示。 - 它会显示完整路径,而不只是文件名,而在其他位置(例如回溯)。
[zxdb] set show-file-paths true
在特定行上设置断点时,如果显示的断点位置与您输入的行号不匹配,您可能会注意到不匹配。在大多数情况下,这是因为此符号无法识别指定行中的任何代码,因此调试程序使用了下一行。即使是在未优化的 build 中也是如此,并且在变量声明中最常见。
[zxdb] b file.cc:138
Breakpoint 1 (Software) @ file.cc:138
138 int my_value = 0; <- Breakpoint was requested here.
◉ 139 DoSomething(&my_value); <- But ended up here.
140 if (my_value > 0) {