搜索

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

download PDF

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

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

GDBserver 现在使用 shell 启动 inferior

为了在 underferior 命令行参数中启用扩展和变量替换,GDBserver 现在在 shell 中启动与 GDB 相同的扩展和变量替换。

使用 shell 禁用:

  • 使用 目标 extend-remote GDB 命令时,通过 set start-with-shell off 命令禁用 shell。
  • 当使用 目标远程 GDB 命令时,请使用 gdbserver 的 --no-startup-with-shell 选项禁用 shell。

例 3.1. 远程 GDB 底层中 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 支持已删除

删除了对调试使用 GNU Compiler for Java(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 形式显示,如 2.1。因此,$ _thread convenience 变量和 InferiorThread.num Python 属性中的线程数字在 inferiors 之间不再是唯一的。

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

为了向后兼容,Machine Interface(MI)线程 ID 始终包含全局 ID。

例 3.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 版本

对 Sun 版本的 stabs 调试文件格式的支持已删除。GDB 仍然支持 GCC 在 RHEL 中通过 gcc -gstabs 选项生成的 stabs 格式

sysroot 处理更改

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

当 GDB 远程启动进程时,或者当它连接到已经运行的进程(本地和远程)时,会预先指定系统 root 的文件名。这意味着,对于远程进程,默认值为 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:显示所有 29863 可能性?(y 或 n)
  • 在 RHEL 8 中:显示所有 200 个可能?(y 或 n)

删除了 HP-UX XDB 兼容性模式

HP-UX XDB 兼容模式的 -xdb 选项已从 GDB 中删除。

处理线程信号

在以前的版本中,GDB 可以向当前线程发送信号,而不是实际发送信号的线程。这个程序错误已被解决,GDB 现在总是在恢复执行时将信号传递给正确的线程。

此外,sign 命令现在始终正确地将请求的信号传送到当前线程。如果程序因信号和用户切换线程而停止,GDB 将请求确认。

断点模式始终插入并自动合并

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

remotebaud 命令不再被支持

set remotebaudshow remotebaud 命令不再被支持。使用 设置的 serial baud 并改为 显示 serial baud 命令。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.