LLVM编译器2.0的bug



使用LLVM编译器编译以下代码时,无法正常运行。(它不会增加。)当使用GCC 4.2编译时,它可以正确运行。这是一个错误的LLVM编译器?

#include <stdio.h>
#include <string.h>
void BytesFromHexString(unsigned char *data, const char *string) {
    printf("bytes:%s:", string);
    int len = (int)strlen(string);
    for (int i=0; i<len; i+=2) {
        unsigned char x;
        sscanf((char *)(string + i), "%02x", &x);
        printf("%02x", x);
        data[i] = x;
    }
    printf("n");
}
int main (int argc, const char * argv[])
{
    // insert code here...
    unsigned char data[64];
    BytesFromHexString(data, "4d4f5cb093fc2d3d6b4120658c2d08b51b3846a39b51b663e7284478570bcef9");
    return 0;
}

对于sscanf,您将使用%2x而不是%02x。此外,%2x表示将传递一个额外的int*参数。但是你要通过unsigned char*考试。最后,sscanf接受const char*作为第一个实参,因此不需要进行强制转换。

试试吧:

int x;
sscanf((string + i), "%2x", &x);

EDIT:澄清为什么这个变化解决了这个问题:在你的代码中,sscanf试图在只能容纳sizeof(unsigned char)字节的内存位置(&x)中写入sizeof(int)字节。1字节)。所以,你覆盖了一定数量的内存。这个被覆盖的内存很可能是i变量的一部分。

从编译器的角度来看,这段代码表现不同的原因是gcc和llvm(或任何其他编译器)可能以不同的方式布局堆栈。在此之前,您可能只是在堆栈上添加了本示例中不需要的其他东西,但是对于llvm编译器的不同布局,您正在添加一些更有用的东西。

这是在调试问题时使用堆栈保护的另一个很好的理由(-fstack- protection -all/-fstack-protector)。它可以帮助解决这些问题。

最新更新