由gdb打印ptr与打印"%s"混淆

时间:2020-03-05 18:52:23  来源:igfitidea点击:
1167      ptr = (void*)getcwd(cwd, MAX_PATH_LENGTH-1);
(gdb) n
1168      if (!ptr) {
(gdb) print ptr
 = 0xbff2d96c "/media/MMC-SD/partition1/aaaaaaaaaaa"
(gdb) print &cwd
 = (char (*)[3500]) 0xbff2d96c
(gdb) print strlen(cwd)
 = 36
(gdb) print "%s",cwd
 = "/media/MMC-SD/partition1/aaaaaaaaaaa", '
(gdb) print cwd
 = "/media", '##代码##' <repeats 782 times>, "6???" ...
(gdb) print (char*) cwd
 = 0xbfc8eb84 "/media"
' <repeats 912 times>, "??O?001##代码##0##代码##0##代码##0##代码##0??027##代码##0##代码##0##代码##0?3????EL鷠3?000??027##代码##0##代码##0##代码##0##代码##0##代码##0##代码##0##代码##07##代码##0##代码##0##代码##0##代码##0??/?027##代码##0##代码##0##代码##0?3????N????0???鷠3?000??027##代码##0##代码##0##代码##0##代码##0##代码##0##代码##0##代码##0??000##代码##0##代码##0##代码##0##代码##1##代码##0##代码##0##代码##0??M鷠3????##代码##0##代码##0##代码##0##代码##0.1?027??w##代码##5\b##代码##1##代码##0"... (gdb) print "%s", ptr = 0xbff2d96c "/media/MMC-SD/partition1/aaaaaaaaaaa" (gdb) Quit

为什么ptr可以正确打印字符串,而cwd却不能;这也会影响程序,如果我尝试使用cwd,它会崩溃...

[编辑:原来,崩溃是由该变量上的一个愚蠢的缓冲区溢出引起的... grr ...不是gdb,但打印问题仍然有效]

解决方案

回答

该" ptr"显示为格式正确的字符串,而" cwd"显示为"字节缓冲区",可能特定于gdb。无论如何,它都不会影响应用程序;根据man 3 getcwdptr应该指向cwd(或者如果发生错误应该为NULL)。
我们可以在不使程序崩溃的情况下使用ptr吗?

回答

cwd是什么类型?上面的代码片段没有告诉我们。 gdb可能会以不同的方式对待ptr为void *。

回答

在gdb中以不同的方式打印cwd的原因是,因为gdb知道ptr是char *(我猜),而cwd是长度为3500的数组(如图所示)。输出)。因此,在打印ptr时,它会打印指针值(作为服务,它还会指向它的字符串),而在打印`cwd'时,它会打印整个数组。

我看不出有任何原因为什么使用cwd而不是ptr会导致问题,但是我需要查看一些代码来确保。

回答

我同意mweerden。尝试一些我认为与代码相似的事情,我得到:

##代码##

从gdb中获取,因此似乎由于cwd被定义为char cwd [3500],因此gdb将打印整个数组,而如果我们告诉gdb将其解释为char *,它将按预期工作。如果应用程序崩溃,我认为这是由于其他原因。