编辑2:我仍然停留在这里,但问题很可能是在自动矢量化重写系统中,这与这个问题无关。我在下面的评论中提到的valgrind的SIGILL输出上再次更新此问题
==10478== Process terminating with default action of signal 4 (SIGILL)
==10478== Illegal opcode at address 0x423F4C ==10478== at 0x423F4C: sp_private_9_compute (smmintrin.h:209)
==10478== by 0x4247F4: sp_private_9__timeCompute
在调试SSE代码时,首先要检查是否看到valgrind引发了SIGILL,是您的VALGRIND是最新的。在我的情况下,我使用的是V3.6,该版本在SSE4内在支持中存在错误。由于不了解_mm_mullo_epi32指令,SIGILL被b / c提出。将其更新到V3.9之后,valgrind可以更好地定位SSE程序的实际问题。
如果我找到更多相关的调试提示,我将再次更新此问题。
编辑1:我希望有人可以确认我对调试跟踪中非顺序行为的观察是准确的。
首先,这是一个有关C调试的非常具体的问题。如果您通读并提供任何反馈意见,我将不胜感激。
背景:我正在使用代码生成系统,最近我不断从glibc获得“双重释放或破坏”。因此,我使用额外的调试信息重新编译了自动生成的代码,并使用gdb运行了它。而且或者我现在脑筋急转弯,或者实际上我在顺序代码执行中观察到了非顺序行为。
代码:
LINE:6851 if(self->_garbage != 0) {
LINE:6852 sp_env_list_free_children(self->_garbage);
LINE:6853 sp_env_list___del__(self->_garbage);
LINE:6854 sp_env_free(self->_garbage, sizeof(sp_env_list_t));
LINE:6855 }//End of if
LINE:6856 }//End of an outer if structure
LINE:6857 }//End of the function call containing the if structure
在调试跟踪之后,我将解释free和del函数。
调试跟踪
6851 if (((self->_garbage != 0))) {
(gdb) step
6852 sp_env_list_free_children(self->_garbage);
(gdb) print self->_garbage
$1 = (sp_env_list_t *) 0x649080
(gdb) step
6853 sp_env_list___del__(self->_garbage);
(gdb) print self->_garbage
$2 = (sp_env_list_t *) 0x649080
(gdb) step
6854 sp_env_free(self->_garbage, sizeof(sp_env_list_t ));
(gdb) print self->_garbage
$3 = (sp_env_list_t *) 0x649080
(gdb) step
6857 }
(gdb) print self->_garbage
$4 = (sp_env_list_t *) 0x649080
(gdb) step
sp_private_11___del__ (self=<value optimized out>) at sp_moddft_int32.c:6854
6854 sp_env_free(self->_garbage, sizeof(sp_env_list_t ));
(gdb) print self->_garbage
Cannot access memory at address 0x18
(gdb) step
Single stepping until exit from function sp_env_free,
which has no line number information.
*__GI___libc_free (mem=0x649080) at malloc.c:3692
3692 malloc.c: No such file or directory.
in malloc.c
在调试跟踪中可以看到,它在6854行之后到达6857行,然后再次回到6854行。由于self-> _ garbage已被完全释放,因此应该在其中发生“双重释放或损坏”。但是,整个功能是连续的,没有循环。我不明白为什么它会跳回来。
为完整起见,if结构中的三个函数用于:
如果不清楚,我可以提供任何其他信息。我希望有人至少可以确认我对非顺序行为的观察是准确的。非常感谢!
当您单步执行优化的代码时,它似乎常常随机出现。只要保持定义的顺序关系,优化器就可以自由地重组代码流。
在这种情况下,我怀疑您正在看到尾部调用优化(TCO)的结果。您的最终调用sp_env_free
是一个尾部调用,假设它所在的函数已经void
返回。因此,该函数可以还原其被调用方保存的寄存器(即,执行结尾),然后跳转到sp_env_free
,而不是先调用sp_env_free
然后执行结尾。这样可以节省堆栈框架和一些设置堆栈框架的说明。
由于结尾处在函数的末尾,因此名义上它的行号为6857,即使该行上可见的所有内容都是紧括号。因此,TCO与您看到的行号顺序完全一致。我敢肯定这不是唯一的可能性。通常,要想出一个好的优化器并不容易。如果您真的想知道,可以尝试使用查看生成的汇编代码-S
,但是鉴于您的文件至少有6857行,也可能不容易解密。
如果要明智地调试程序,请关闭优化。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句