程序集 – 寄存器在gdb分析的核心转储中具有“错误”值
我正在使用gdb分析SIGSEV创建的核心转储文件.我得到了C源代码,但是当我评估表达式时,我得到了正确的值(表达式为
local_var = ((array[index])->field[index2]).field2 其中array是一个全局变量). index和index2的值被优化了(当然:-(),但我计算了几次,每次我得到相同的有效值.绝望之后我检查了反汇编的代码和寄存器并得到了这个: 0x00002b083e06d84c <+142>: mov %r13d,%edx # index (234) to edx 0x00002b083e06d84f <+145>: mov 0x2039fa(%rip),%rax # 0x2b083e271250 (address of array) 0x00002b083e06d856 <+152>: mov (%rax,%rdx,8),%rdx # array[index] (0x2b083e271250+8*234) to rdx 0x00002b083e06d85a <+156>: movslq %ecx,%rax # index2 to rax => 0x00002b083e06d85d <+159>: mov 0x28(%rdx),%rdx # array[index]->field to rdx 评论是我对代码的理解.在最后一条指令处收到SIGSEV.寄存器的内容: rax 0x5 5 rbx 0x2aaad4096a9c 46913190193820 rcx 0x5 5 rdx 0x0 0 rsi 0xea 234 rdi 0xc75000a9 3343909033 rbp 0x41f898c0 0x41f898c0 rsp 0x41f898a0 0x41f898a0 r8 0x2aaacb411c60 46913042848864 r9 0x2020202020207475 2314885530818475125 r10 0x52203c3c20202020 5917796139299512352 r11 0x2b083bb29070 47314361290864 r12 0xc75000a9 3343909033 r13 0xea 234 r14 0x0 0 r15 0x2aaad40966a4 46913190192804 rip 0x2b083e06d85d 0x2b083e06d85d 因为rdx是0,所以我理解最后一段中的分段错误,因为代码试图从0x28读取,这是无法访问的.我不明白为什么rdx为0?在第一行中,edx获得234值(自该指令起r13寄存器未被修改,这是我计算的索引的有效值).在第三行中,0x2b083e5b6f20(8 * 234)= 0x2b083e5b7670处的8个字节被分配给rdx,但这些字节不是0: (gdb) x/2 0x2b083e5b7670 0x2b083e5b7670: 0x3e578900 0x00002b08 rdx如何以0值结束? 我在x86_64 Linux上这样做,这是一个多线程程序.这可能是硬件错误吗? SIGSEV并不总是发生. 解决方法
听起来你可能有一个数据竞争:在当前线程加载数组[index]) – >字段(当时为0)之后,其他一些线程进来并在那里写了一个不同的值(你现在观察到的新值)核心).
一切皆有可能,但数据竞争的可能性要高出99.99%. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |