编辑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 内在支持中存在错误。SIGILL 被提出 b/c 它不理解 _mm_mullo_epi32 指令。更新到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 funcs。
调试跟踪
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结构中的三个函数用于:
- sp_env_list_free_children() 将所有 e->_data 从 e = self->_garbage->head 释放到 e = self->_garbage->tail。
- sp_env_list_del ()删除从self->_garbage->head到self->_garbage->tail的指针
- sp_env_free() 释放 self->_garbage 指针
如果不清楚,我可以提供任何其他信息。我希望有人至少可以确认我对非顺序行为的观察是准确的。非常感谢!