Red Hat Training

A Red Hat training course is available for RHEL 8

16.4. GDB 中的兼容性破坏更改

Red Hat Enterprise Linux 8 中提供的 GDB 版本包含大量破坏兼容性的更改,特别是在直接从终端读取 GDB 输出的情况下。以下部分详细介绍了这些更改。

不建议分析 GDB 的输出。首选使用 Python GDB API 或 GDB 机器接口(MI)的脚本。

GDBserver 现在使用 shell 启动不仲裁

要启用不小命令行参数的扩展和变量替换,GDBserver 现在会在 shell 中启动低端的 shell,与 GDB 相同。

使用 shell 禁用:

  • 使用 target extended-remote GDB 命令时,请使用 set startup-with-shell off 命令禁用 shell。
  • 使用 target remote GDB 命令时,使用 GDBserver 的 --no-startup-with-shell 选项禁用 shell。

例 16.1. 远程 GDB Inferiors 中的 shell 扩展示例

这个示例演示了通过 GDBserver 运行 /bin/echo /* 命令在 Red Hat Enterprise Linux 版本 7 和 8 中的不同:

  • 对于 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 删除支持

删除了对使用 GNU Compiler 编译的 Java 程序进行调试的支持(gcj)。

符号转储维护命令的新语法

符号转储维护命令语法现在包括在文件名之前的选项。因此,在 RHEL 8 中使用 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 格式显示,如 2.1。因此,$_thread 方便变量中的线程号和 InferiorThread.num Python 属性中的线程数不再唯一。

GDB 现在存储每个线程的第二个线程 ID,称为全局线程 ID,这是之前版本中与线程编号对应的新线程 ID。要访问全局线程编号,请使用 $_gthread convenience 变量和 InferiorThread.global_num Python 属性。

为了向后兼容,Machine Interface(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]; 的值会生成不同的结果:

  • 红帽企业 Linux 7, $1 = 'A' <repeats 131072 times>
  • 在 Red Hat Enterprise Linux 8 中, value requires 131072 bytes, which is more than max-value-size

Sun 版本的 stabs 格式不再被支持

对 Sun 版本的 stabs debug 文件格式的支持已被删除。GDB 仍支持使用 gcc -gstabs 选项在 RHEL 中生成的 stabs 格式。

Sysroot 处理更改

set sysroot path 命令在搜索调试所需的文件时指定系统 root。现在,为这个命令提供的目录名称可能会带有字符串 target: 前缀,使 GDB 从目标系统(本地和远程)读取共享库。以前可用的 remote: 前缀现在被视为 target:。另外,为了向后兼容,默认系统 root 值已从空字符串改为 target:

指定的系统 root 在主可执行文件的文件名前面、当 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 可向当前线程发送信号,而不是实际发送信号的线程。这个程序错误已被解决,GDB 现在在恢复执行时始终将信号传递给正确的线程。

另外,signal 命令现在总是可以正确地向当前线程提供请求的信号。如果针对信号而停止程序并且用户切换的线程,GDB 将要求确认。

断点模式总是关闭和自动合并

breakpoint always-inserted 设置已更改。已删除 auto 值和对应行为。默认值为 off。另外,在所有线程都停止前,off 值现在会导致 GDB 不会从目标中删除断点。

不再支持 remotebaud 命令

不再支持 set remotebaudshow remotebaud 命令。使用 set serial baudshow serial baud 命令。