16.4. GDB 中兼容性破坏的变化
Red Hat Enterprise Linux 8 中提供的 GDB 版本包含许多破坏兼容性的变化,特别是在直接从终端读取 GDB 输出的情况下。以下部分详细介绍了这些变化。
不建议解析 GDB 的输出。首选使用 Python GDB API 或 GDB 机器接口(MI)的脚本。
GDBserver 现在使用 shell 启动 inferior
要在 inferior 命令行参数中启用扩展和变量替换,GDBserver 现在会在 shell 中启动 inferior,与 GDB 一样。
要禁止使用 shell :
-
使用
target extended-remote
GDB 命令时,请使用set startup-with-shell off
命令禁用 shell。 -
当使用
目标远程
GDB 命令时,请使用 gdbserver 的--no-startup-with-shell
选项禁用 shell。
例 16.1. 远程 GDB inferiors 中的 shell 扩展的示例
这个示例演示了在 Red Hat Enterprise Linux 版本 7 和 8 中通过 GDBserver 运行 /bin/echo /*
命令的不同:
对于 RHEL 7:
$ gdbserver --multi :1234 $ gdb -batch -ex 'target extended-remote :1234' -ex 'set remote exec-file /bin/echo' -ex 'file /bin/echo' -ex 'run /*' /*
对于 RHEL 8:
$ gdbserver --multi :1234 $ gdb -batch -ex 'target extended-remote :1234' -ex 'set remote exec-file /bin/echo' -ex 'file /bin/echo' -ex 'run /*' /bin /boot (...) /tmp /usr /var
gcj
支持已删除
删除了对使用 Java 的 GNU 编译器(gcj)
调试 Java 程序的支持。
符号转储维护命令的新语法
符号转储维护命令语法现在在文件名之前包括一些选项。因此,在 RHEL 7 中可以与 GDB 一起工作的命令在 RHEL 8 中无法工作。
例如,以下命令不再在文件中存储符号,而是生成一个错误消息:
(gdb) maintenance print symbols /tmp/out main.c
符号转储维护命令的新语法为:
maint print symbols [-pc address] [--] [filename] maint print symbols [-objfile objfile] [-source source] [--] [filename] maint print psymbols [-objfile objfile] [-pc address] [--] [filename] maint print psymbols [-objfile objfile] [-source source] [--] [filename] maint print msymbols [-objfile objfile] [--] [filename]
线程数不再是全局的
在以前的版本中,GDB 只使用全局线程编号。编号已扩展为以 inferior_num.thread_num
形式按 inferior 显示,如 2.1
。因此,$_thread
方便变量和 InferiorThread.num
Python 属性中的线程号在 inferior 间不再是唯一的。
GDB 现在按线程存储第二个线程 ID,称为全局线程 ID,这是之前版本中线程号的新等价物。要访问全局线程号,请使用 $_gthread
方便变量以及 InferiorThread.global_num
Python 属性。
为了向后兼容,机器接口(MI)线程 ID 始终包含全局 ID。
例 16.2. GDB 线程数更改示例
在 Red Hat Enterprise Linux 7 上:
# debuginfo-install coreutils $ gdb -batch -ex 'file echo' -ex start -ex 'add-inferior' -ex 'inferior 2' -ex 'file echo' -ex start -ex 'info threads' -ex 'pring $_thread' -ex 'inferior 1' -ex 'pring $_thread' (...) Id Target Id Frame * 2 process 203923 "echo" main (argc=1, argv=0x7fffffffdb88) at src/echo.c:109 1 process 203914 "echo" main (argc=1, argv=0x7fffffffdb88) at src/echo.c:109 $1 = 2 (...) $2 = 1
在 Red Hat Enterprise Linux 8 中:
# dnf debuginfo-install coreutils $ gdb -batch -ex 'file echo' -ex start -ex 'add-inferior' -ex 'inferior 2' -ex 'file echo' -ex start -ex 'info threads' -ex 'pring $_thread' -ex 'inferior 1' -ex 'pring $_thread' (...) Id Target Id Frame 1.1 process 4106488 "echo" main (argc=1, argv=0x7fffffffce58) at ../src/echo.c:109 * 2.1 process 4106494 "echo" main (argc=1, argv=0x7fffffffce58) at ../src/echo.c:109 $1 = 1 (...) $2 = 1
值内容的内存可能会受限制
在以前的版本中,GDB 不会限制为值内容分配的内存量。因此,调试不正确的程序可能会导致 GDB 分配过多的内存。已添加 max-value-size
设置来限制分配的内存量。这个限制的默认值为 64 KiB。因此,Red Hat Enterprise Linux 8 中的 GDB 不会显示太大的值,而是会报告这个值太大。
例如,打印一个定义为 char s[128*1024];
的值会生成不同的结果:
-
Red Hat Enterprise Linux 7,
$1 = 'A' <repeats 131072 times>
-
On Red Hat Enterprise Linux 8,
value requires 131072 bytes, which is more than max-value-size
stabs 格式的Sun 版本不再支持
对 stabs
调试文件格式的 Sun 版本的支持已删除。GDB 仍然支持在 RHEL 中使用 GCC 的 gcc -gstabs
选项生成的 stabs
格式。
Sysroot 处理的变化
当搜索调试所需文件时,使用 set sysroot path
命令指定系统根。现在,为这个命令提供的目录名可能会有字符串 target:
前缀,它使 GDB 从目标系统中(本地和远程)对共享的库。以前可用的 remote:
前缀现在被视为 target:
另外,为了向后兼容,默认的系统根值已从空字符串变为 target:
。
当 GDB 远程启动进程时,或者当它连接到已运行的进程(本地和远程)时,指定的系统根将附加到主可执行文件的文件名前面。这意味着,对于远程进程,默认值 target:
使 GDB 始终尝试从远程系统加载调试信息。为防止这种情况,请在 target remote
命令之前运行 set sysroot
命令,以便在远程符号文件之前可以找到本地符号文件。
HISTSIZE 不再控制 GDB 命令历史记录大小
在以前的版本中,GDB 使用 HISTSIZE
环境变量来确定命令历史记录应保留多长。GDB 已改为使用 GDBHISTSIZE
环境变量。该变量只适用于 GDB。可能的值及其作用:
- 正数 - 使用这个大小的命令历史记录,
-
-1
或空字符串 - 保留所有命令的历史记录, - 非数字值 - 忽略。
添加了完成限制
在完成过程中考虑的最大候选数量现在可以使用 set max-completions
命令来限制。要显示当前的限制,请运行 show max-completions
命令。默认值为 200。这个限制防止 GDB 产生大量的完成列表并变得无响应。
例如,输入 p <tab><tab>
之后的输出是:
-
在 RHEL 7 上:
Display all 29863 possibilities? (y or n)
-
在 RHEL 8 上:
Display all 200 possibilities? (y or n)
删除了 HP-UX XDB 兼容性模式
HP-UX XDB 兼容模式的 -xdb
选项已从 GDB 中删除。
处理线程的信号
在以前的版本中,GDB 可向当前线程发送信号,而不是实际发送信号的线程。这个 bug 已被解决,GDB 现在在恢复执行时始终将信号传递给正确的线程。
此外,signal
命令现在总是能够将请求的信号正确地传送给当前线程。如果程序针对信号停止了,且用户切换了线程,则 GDB 将要求确认。
断点模式总是插入断开和自动合并
breakpoint always-inserted
设置已被更改。已删除 auto
值和对应行为。默认值现在为 off
。另外,off
值不会导致 GDB 不从目标中删除断点,直到所有进程都停止了。
不再支持 remotebaud 命令
set remotebaud
和 show remotebaud
命令不再被支持。改为使用 set serial baud
和 show serial baud
命令。