ChatGPT解决这个技术问题 Extra ChatGPT

如何在 gdb 中打印长字符串的完整值?

我想在 GDB 中打印 C 字符串的全长。默认情况下它是缩写的,我如何强制 GDB 打印整个字符串?


J
John Carter
set print elements 0

From the GDB manual

设置打印元素元素数

设置一个数组 GDB 将打印多少元素的限制。如果 GDB 正在打印一个大数组,它会在打印完 set print elements 命令设置的元素数量后停止打印。此限制也适用于字符串的显示。当 GDB 启动时,此限制设置为 200。将元素数量设置为零意味着打印不受限制。


现在您可能还需要“设置打印重复 0”,否则 GDB 将省略字符串/数组的重复元素。
这也适用于数组类型
您可能还需要“设置 max-value-size 无限制”。
佚名

只要您的程序处于正常状态,您还可以 call (void)puts(your_string) 将其打印到标准输出。实际上,同样的原则适用于调试器可用的所有功能。


这个答案甚至比“设置打印元素 0”(出于我的目的)更好,因为它尊重换行符/回车符而不是转义它们。
很好的解决方案,但在尝试分析核心转储文件时不起作用
注意:此选项仅在您正在调试实时程序时有效。调试核心文件时不能使用 GDB 的“调用”命令。
还要求 gdb 保持理智,但情况似乎越来越不是这样(在我的 Mac OS X 机器上,我得到“在当前上下文中没有符号“放置”。”)
我只是在 xcode 的输出窗口中写了“puts(your_string)”
A
Azeem

printf 命令将打印完整的字符串:

(gdb) printf "%s\n", string

对不起,但这不是真的
这似乎尊重 set print elements nnn 限制,除非您执行 set print elements 0,否则不会打印完整的字符串。
当我尝试这个时,我只得到:“值不能转换为整数。”
对于 std::string 您需要 string.c_str() 以避免“值无法转换为整数”错误
W
Wichert Akkerman

还有第三个选项:x 命令,它允许您为特定命令设置不同的限制,而不是更改全局设置。要打印字符串的前 300 个字符,您可以使用 x/300s your_string。输出可能有点难以阅读。例如打印 SQL 查询会导致:

(gdb) x/300sb stmt.c_str()
0x9cd948:    "SELECT article.r"...
0x9cd958:    "owid FROM articl"...
..

我想知道“x/300sb”是什么意思。在此 cheat sheet (pdf) 的帮助下,我将“x/300sb cstr”翻译为“检查地址 cstr 处的 300 个内存单位(字节),解释为以 NULL 结尾的字符串 (S)。”。如果你的字符串长度为 100,那么你会看到很多垃圾,因为所有 300 个字节都被打印出来了,不管它们是否有意义。不过,+1 将我介绍给x
a
abstraktor

只是为了完成它:

(gdb) p (char[10]) *($ebx)
$87 =   "asdfasdfe\n"

您必须给出一个长度,但可能会更改该字符串的表示:

(gdb) p/x (char[10]) *($ebx)
$90 =   {0x61,
  0x73,
  0x64,
  0x66,
  0x61,
  0x73,
  0x64,
  0x66,
  0x65,
  0xa}

如果您想通过它们的值进行调试,这可能很有用


m
mrtimdog

使用 set elements ... 并不总是最好的方法。如果有一个不同的 set string-elements ...,那将很有用。

所以,我在我的 .gdbinit 中使用了这些函数:

define pstr
  ptype $arg0._M_dataplus._M_p
  printf "[%d] = %s\n", $arg0._M_string_length, $arg0._M_dataplus._M_p
end

define pcstr
  ptype $arg0
  printf "[%d] = %s\n", strlen($arg0), $arg0
end

注意事项:

第一个依赖于 c++ lib,因为它访问 std::string 的成员,但很容易调整。

第二个只能用于正在运行的程序,因为它调用 strlen。