我有一小段代码(这是我遇到的问题的一个最小工作示例):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void xorBuffer(unsigned char* dst, unsigned char* src, int len)
{
while (len != 0)
{
*dst ^= *src;
dst++;
src++;
len--;
}
}
int main()
{
unsigned char* a = malloc(32);
unsigned char* b = malloc(32);
int t;
memset(a, 0xAA, 32);
memset(b, 0xBB, 32);
xorBuffer(a, b, 32);
printf("result = ");
for (t = 0; t < 32; t++) printf("%.2x", a[t]);
printf("\n");
return 0;
}
这段代码应该执行两个 32 字节内存缓冲区的异或(从概念上讲,应该这样做a = a ^ b
)。由于 0xAA ^ 0xBB = 0x11,它应该打印“11”三十二次。
我的问题是,当我在 MinGW-GCC (Windows) 下编译它时,它在调试模式下完美运行(无优化),但是当启用从 -O3 开始的优化时,在 xorBuffer 循环中途出现 SIGILL 崩溃。此外,如果我将 printf 放入有问题的循环中,它会再次完美运行。我怀疑堆栈损坏,但我只是看不到我在这里做错了什么。
尝试在启用优化的情况下使用 GDB 进行调试是一个失败的原因,因为所有 GDB 都向我展示了针对每个变量的“变量优化”(当然,如果我尝试将变量打印出来,它会突然起作用)。
有人知道这里到底发生了什么吗?我在这个问题上花费了太长时间,我真的需要正确解决它才能继续前进。我的猜测是我缺少一些基本的 C 指针知识,但对我来说,代码看起来是正确的。它可能来自缓冲区增量,但据我所知,sizeof(unsigned char) == 1
它应该一个一个地遍历每个字节。
值得一提的是,即使在我的 Linux 机器上对 GCC 进行了优化,该代码也能正常工作。
那么......这里有什么交易?谢谢!
根据要求,整个程序的汇编输出:
使用-O2:点击
使用-O3:点击
我在 GCC 4.6.2 上观察到这种行为(与 MinGW 一起运行)