2011-08-11 3 views
0

다음 코드를 LLVM 컴파일러와 함께 컴파일하면 올바르게 작동하지 않습니다. (i는 증가하지 않습니다.) GCC 4.2로 컴파일 할 때 올바르게 작동합니다. 이것은 LLVM 컴파일러의 버그입니까?LLVM 컴파일러 2.0 버그?

#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; 
} 
+0

[clang] (http://clang.llvm.org/) 프론트 엔드 또는 GCC를 사용하고 있습니까? –

답변

6

sscanf 위해 당신은 %2x 대신 %02x 사용하십시오. 또한 %2x은 추가 int* 인수가 전달됨을 나타냅니다. 하지만 unsigned char*을 전달 중입니다. 마지막으로 sscanfconst char*을 첫 번째 인수로 사용하므로 해당 캐스트가 필요하지 않습니다.

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

편집 :이 변경 문제가 해결 이유를 명확히하기 :

그래서 시도해 코드에서, sscanf는 만 수있는 메모리 위치에 sizeof(int) 바이트 (&x)를 작성하는 시도 sizeof(unsigned char) 바이트 (예 : 1 바이트)를 보유하십시오. 그래서, 당신은 일정량의 메모리를 덮어 썼습니다. 이렇게 덮어 쓴 메모리는 i 변수의 일부일 수 있습니다.

+0

고맙습니다. 그것은 당신의 대답으로 해결했습니다. –

+1

@ Takayoshi Sato : 답변으로 문제가 해결되면 [답변 수락] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)을 클릭하십시오. 감사. – DarkDust

0

컴파일러 측면에서 보면이 코드의 동작 방식이 다르기 때문에 gcc 및 llvm (또는 다른 컴파일러)이 스택을 다르게 배치 할 수 있습니다. 당신은이 예제에서 필요하지 않았던 스택에 다른 것을 clobbering 할 가능성이 높았지만, llvm 컴파일러의 다른 레이아웃을 사용하면 더 유용한 것을 clobbering했다.

문제를 디버깅 할 때 스택 보호기를 사용하는 또 다른 이유가 있습니다 (-fstack-protector-all/-fstack-protector). 이 문제를 해결하는 데 도움이 될 수 있습니다.