由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 getcwd
,ptr
应该指向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 *,它将按预期工作。如果应用程序崩溃,我认为这是由于其他原因。