被gdb print ptr和print“%s”混淆

时间:2008-09-12 16:46:41

标签: c gdb buffer-overflow buffer-overrun

1167      ptr = (void*)getcwd(cwd, MAX_PATH_LENGTH-1);
(gdb) n
1168      if (!ptr) {
(gdb) print ptr
$1 = 0xbff2d96c "/media/MMC-SD/partition1/aaaaaaaaaaa"
(gdb) print &cwd
$2 = (char (*)[3500]) 0xbff2d96c
(gdb) print strlen(cwd)
$3 = 36
(gdb) print "%s",cwd
$4 = "/media/MMC-SD/partition1/aaaaaaaaaaa", '\0' <repeats 912 times>, "��O�001\000\000\000\000��027\000\000\000�3����EL鷠3�000��027\000\000\000\000\000\000\000\027\000\000\000\000��/�027\000\000\000�3����N����\230���鷠3�000��027\000\000\000\000\000\000\000��000\000\000\000\001\000\000\000��M鷠3����\000\000\000\000.\231�027��w\005\b\001\000"...
(gdb) print "%s", ptr
$5 = 0xbff2d96c "/media/MMC-SD/partition1/aaaaaaaaaaa"
(gdb) Quit

为什么ptr正确打印字符串但不是cwd;如果我尝试使用cwd ...

,这也会影响程序并崩溃

[编辑:事实证明崩溃是由于这个var ... grr上的一个愚蠢的缓冲区溢出...而不是gdb,但打印问题仍然有效]

4 个答案:

答案 0 :(得分:5)

我同意mweerden。尝试我认为类似于你的代码的东西,我得到:

(gdb) print cwd
$1 = "/media", '\0' <repeats 782 times>, "\016���" ...
(gdb) print (char*) cwd
$2 = 0xbfc8eb84 "/media"

来自gdb,所以似乎自cwd被定义为char cwd[3500]以来,gdb打印整个数组,而如果你告诉gdb将其解释为char*,它将起作用如你所料。如果您的应用程序崩溃,我会认为这是因为其他原因。

答案 1 :(得分:2)

cwdgdb打印方式不同的原因是gdb知道ptrchar *(我猜)和{{1} }是一个长度为cwd的数组(如输出中所示)。因此,当打印3500时,它会打印指针值(作为服务也指向它指向的字符串),打印时ptr打印整个数组。

我认为使用cwd代替cwd导致问题没有任何理由,但我需要看一些代码才能确定。

答案 2 :(得分:1)

ptr显示为格式良好的字符串,cwd显示为“字节缓冲区”可能特定于gdb。在任何情况下,它都不应影响您的申请;根据{{​​1}},man 3 getcwd应指向ptr(如果发生错误,则应为NULL)。 你可以使用cwd而不会破坏程序吗?

答案 3 :(得分:0)

cwd是什么类型的?上面的代码片段没有告诉我们。 pdb可能是一个空格*被gdb区别对待。