首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在调用堆栈中,当类型指针的参数持有模式0x8080808080808080或0xf8f8f8f8f8f8f8f8f8f8f8f8f8f8?

在调用堆栈中,当类型指针的参数持有模式0x8080808080808080或0xf8f8f8f8f8f8f8f8f8f8f8f8f8f8?
EN

Stack Overflow用户
提问于 2018-09-11 16:13:04
回答 1查看 127关注 0票数 2

当我使用GDB调试一个问题时,我遇到了这种奇怪的行为。我无法用任何合乎逻辑的答案说服自己。

下面是由于函数开始时的断点而获得的调用堆栈的快照(为了简单起见,我将堆栈帧限制在3级)。

代码语言:javascript
复制
(gdb) 
#0  hashset_get (hashset=<value optimized out>, item_key=0x7fffd7e4f5b8)
    at /xxx/yyy/zzz/hashset.c:123
#1  0x00007fffed855d00 in hashmap_get (hashmap=<value optimized out>, key=0x7fffd7e4f648)
    at /xxx/yyy/zzz/hashmap.c:789
#2  0x00007ffa589d8eeb in hashmap_get_value (hashmap=0x7ff9d82d1b78, key=0x7fffd7e4f648)
    at /xxx/yyy/zzz/hashmap.c:456

在此之后,只有一步执行。稍后,堆栈帧如下所示-

代码语言:javascript
复制
    (gdb) bt
#0  hashset_get (hashset=0xf8f8f8f8f8f8f8f8, item_key=0x7fffd7e4f5b8)
    at /xxx/yyy/zzz/hashset.c:125
#1  0x00007fffed855d00 in hashmap_get (hashmap=<value optimized out>, key=0x7fffd7e4f648)
    at /xxx/yyy/zzz/hashmap.c:789
#2  0x00007ffa589d8eeb in hashmap_get_value (hashmap=0x7ff9d82d1b78, key=0x7fffd7e4f648)
    at /xxx/yyy/zzz/hashmap.c:456

我知道,当GDB将任何变量显示为“值优化出”时,它表明它的值存储在寄存器中,而不是存储在堆栈帧上。

然而,在本例中,arg hashset 0xf8f8f8f8f8f8f8f8**. (最初显示为“值优化出的”)被更改为地址位置- 0xf8f8f8f8f8f8f8f8**.。那么,这是否意味着它最初将** hashset 存储在寄存器中,然后在堆栈帧上创建了一个空间?

这个地址看起来不像任何其他的内存位置地址。您可以在地址中看到一些模式(比如f8f8.)

为了使事实更加混乱,如果我试图打印该位置的数据,GDB输出如下-

代码语言:javascript
复制
(gdb) p *hashset
Cannot access memory at address 0xf8f8f8f8f8f8f8f8

我尝试了更多的东西,希望它能帮助我理解这种行为。

0x7fffd7e4f5b8 item_key**,为** hashset分配了一个有效地址,该地址由arg 持有。

代码语言:javascript
复制
(gdb) s hashset=0x7fffd7e4f5b8
(gdb) p *hashset
Cannot access memory at address 0xb8b8b8b8b8b8b8b8
(gdb) p hashset
$6 = (hashset) 0xb8b8b8b8b8b8b8b8

但令我惊讶的是,当我打印hashset**,的值时,它显示的地址是** 0xb8b8b8b8b8b8b8b8 而不是 0x7fffd7e4f5b8**!!**

有人能解释一下这里发生了什么吗?

编辑:没有崩溃/挂起。系统正常运行

EN

回答 1

Stack Overflow用户

发布于 2018-09-13 02:20:44

我知道,当GDB将任何变量显示为“值优化出”时,它表明它的值存储在寄存器中,而不是存储在堆栈帧上。

这不是“优化价值”的意思。

这意味着:编译器没有在当前程序计数器上为这个变量提供位置信息。

理论上,DWARF标准足够丰富,它可以描述“可以通过向register的值添加constant来定位这个变量”,或者“通过添加register Aregister B,以及用contents of location pointed by register C添加结果”。实际上,很少有编译器使用如此长的长度,而只是简单地忽略了信息。

但是,在本例中,arg hashset最初显示为“值优化出”,后来被更改为某个地址位置。

当您高级程序计数器时,GDB在新PC上找到了位置信息。但是,解释这些位置信息会导致值0xf8f8f8f8f8f8f8f8,这不可能是x86_64上指针的真值。

由此可以得出这样的结论:位置信息不正确(很可能是编译器错误),或者GDB没有正确解释DWARF描述(并非闻所未闻)。

不幸的是,这种调试工件是调试优化代码时的一个事实。他们也依赖GCC和GDB的精确版本--更新的版本通常都是(但并不总是如此!)好多了。Clang/LLVM目前相当差,产生“优化的值”的频率比它应该的要高得多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52280153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档