C 变量的地址在gdb中不匹配
我正在为NetBSD系统使用英特尔的ICC编译器。 我一直在与一个bug作斗争,当我观察到来自gdb中两个不同机制的符号的核心转储地址不一样时,我更感到惊讶 当使用“信息符号连接输出”和p&connection输出进行检查时,变量连接输出似乎有不同的地址 这看起来像是一个编译器问题,其中优化到CPU寄存器中的badf_errcnt被分配了一个内存位置,然后编译器将这两个位置混淆了吗 EDIT1:变量connection\u out是一个静态int全局变量C 变量的地址在gdb中不匹配,c,gdb,intel,netbsd,C,Gdb,Intel,Netbsd,我正在为NetBSD系统使用英特尔的ICC编译器。 我一直在与一个bug作斗争,当我观察到来自gdb中两个不同机制的符号的核心转储地址不一样时,我更感到惊讶 当使用“信息符号连接输出”和p&connection输出进行检查时,变量连接输出似乎有不同的地址 这看起来像是一个编译器问题,其中优化到CPU寄存器中的badf_errcnt被分配了一个内存位置,然后编译器将这两个位置混淆了吗 EDIT1:变量connection\u out是一个静态int全局变量 gdb$ disassemble sig
gdb$ disassemble sigusr1_rt
Dump of assembler code for function sigusr1_rt:
0x01845000 <+0>: push %ebp
0x01845001 <+1>: mov %esp,%ebp
0x01845003 <+3>: sub $0x8,%esp
0x01845006 <+6>: movl $0x16c156a,0x188f05c
0x01845010 <+16>: mov %ebp,%esp
0x01845012 <+18>: pop %ebp
0x01845013 <+19>: ret
0x01845014 <+20>: lea 0x0(%esi),%esi
0x0184501a <+26>: lea 0x0(%edi),%edi
End of assembler dump.
gdb$ info symbol 0x188f05c
connection_out in section .bss of /sites/eqx/work/swcores/tripunjay/F10ACOREDIR/f10cp_sshd.login-eqx-06.6402/sshd
gdb$ p &connection_out
$10 = (int *) 0x188f048
gdb$ p/d 0x188f05c - 0x188f048
$11 = 20
gdb$ p/x 0x188f05c - 0x188f048
$12 = 0x14
gdb$ info symbol 0x188f048
badf_errcnt.5450.0.13 in section .bss of /sites/eqx/work/swcores/tripunjay/F10ACOREDIR/f10cp_sshd.login-eqx-06.6402/sshd
gdb$ p &badf_errcnt
No symbol "badf_errcnt" in current context.
gdb$ select-frame 5
gdb$ frame
Stack level 5, frame at 0xbb4aca20:
eip = 0x1846007 in wait_until_can_do_something (serverloop.c:404); saved eip 0x1846698
called by frame at 0xbb4b0af0, caller of frame at 0xbb4ac9d0
source language c.
Arglist at 0xbb4aca18, args: readsetp=0xbb4b0ab4, writesetp=0xbb4b0ab8, maxfdp=0x4, nallocp=0xbb4b0abc, max_time_milliseconds=0x0
Locals at 0xbb4aca18, Previous frame's sp is 0xbb4aca20
Saved registers:
ebx at 0xbb4aca00, ebp at 0xbb4aca18, esi at 0xbb4ac9fc, edi at 0xbb4aca04, eip at 0xbb4aca1c
readsetp = 0xbb4b0ab4
writesetp = 0xbb4b0ab8
maxfdp = 0x4
nallocp = 0xbb4b0abc
max_time_milliseconds = 0x0
badf_errcnt = <optimized out>
tv = <optimized out>
tvp = <optimized out>
client_alive_scheduled = 0x0
gdb$ p &badf_errcnt
Can't take address of "badf_errcnt" which isn't an lvalue.
gdb$discomble sigusr1\u rt
函数sigusr1\u rt的汇编程序代码转储:
0x01845000:推送%ebp
0x01845001:mov%esp,%ebp
0x01845003:子$0x8,%esp
0x01845006:movl$0x16c156a、0x188f05c
0x01845010:mov%ebp,%esp
0x01845012:弹出%ebp
0x01845013:ret
0x01845014:lea 0x0(%esi),%esi
0x0184501a:lea 0x0(%edi),%edi
汇编程序转储结束。
gdb$info符号0x188f05c
连接在/sites/eqx/work/swcores/tripunjay/F10ACOREDIR/f10cp\u sshd.login-eqx-06.6402/sshd的bss部分中
gdb$p&U输出连接
$10=(整数*)0x188f048
gdb$p/d 0x188f05c-0x188f048
$11 = 20
gdb$p/x 0x188f05c-0x188f048
$12=0x14
gdb$info符号0x188f048
第.bss/sites/eqx/work/swcores/Tripuncay/F10ACORDIR/f10cp/sshd.login-eqx-06.6402/sshd节中的badf_errcnt.5450.0.13
gdb$p&badf\u错误
当前上下文中没有符号“badf_errcnt”。
gdb$选择帧5
gdb$帧
堆栈级别5,0xbb4aca20处的帧:
eip=0x1846007处于等待状态,直到您可以执行某项操作(serverloop.c:404);已保存的eip 0x1846698
由0xbb4b0af0处的帧调用,0xbb4ac9d0处的帧调用方
源语言c。
0xBB4B018处的Arglist,args:readsetp=0xbb4b0ab4,writesetp=0xbb4b0ab8,maxfdp=0x4,nallocp=0xbb4b0abc,最大时间毫秒=0x0
局部变量位于0xbb4aca18,上一帧的sp为0xbb4aca20
保存的寄存器:
0xbb4aca00处的ebx、0xbb4aca18处的ebp、0xbb4ac9fc处的esi、0xbb4aca04处的edi、0xbb4aca1c处的eip
readsetp=0xbb4b0ab4
writesetp=0xbb4b0ab8
maxfdp=0x4
nallocp=0xbb4b0abc
最大\u时间\u毫秒=0x0
错误=
电视=
tvp=
客户端\u活动\u计划=0x0
gdb$p&badf\u错误
无法获取不是左值的“badf_errcnt”地址。
我不认为编译器被搞糊涂了,但是gdb
很可能会被搞糊涂,或者至少在信息太少的情况下工作
ICC似乎没有为gdb
提供足够的符号调试器信息,因此您没有看到任何非常有用的信息。代码是否使用正确的选项编译以在生成的二进制文件中记录调试信息?(即-g
,也可能-O0
)
您是否尝试过使用
idbc
(英特尔调试器)?映射文件说明了什么?如何检查映射文件?感谢您的新知识。它来自生产机器中的一个过程,因此两者都不能使用。虽然当我将变量设置为全局变量并删除静态范围时,我没有发现问题所在。在生产环境中不使用“-g”几乎没有任何有效的借口!您甚至可以将调试信息保存在一个单独的文件中,以便仅在开发机器上使用,即使用生产机器的核心文件副本。事实上,这正是NetBSD工具链(在最新版本中)对标准系统二进制文件的工作方式。然而,即使这对ICC不起作用,保留调试信息的唯一开销就是所需的磁盘空间,这通常是微不足道的。是的,因此我在我的专用开发机器上有完整的符号表信息。然而,正如我从前辈那里学到的,使用-g选项编译有时会导致某些可能的优化无效,因此会产生一些性能损失。首先,不要担心小优化,尤其是在没有首先分析和衡量它们是否重要的情况下。其次,阅读编译器手册,了解它使用各种命令行选项的功能。就我个人而言,我从来没有听说过任何C编译器将-g
置于任何优化选项之上,我使用过许多编译器,尽管我没有使用过最新的英特尔编译器,所以我会查看手册。问题通常是相反的,因为优化器通常会使调试器变得非常困难,即使有所有可用的调试符号。此外,如果您只能在生产环境中复制正在查找的bug,那么我认为这是安装程序调试版本的一个很好的理由,完全禁用优化,直到您可以收集一些真正有用的调试信息。