LLVM 编译器 2.0 错误?
当使用 LLVM 编译器编译以下代码时,它无法正确运行。 (i 没有增加。) 使用 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;
}
When the following code is compiled with LLVM Compiler, it doesn't operate correctly.
(i doesn't increase.)
It operates correctly when compiling with GCC 4.2.
Is this a bug of LLVM Compiler?
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于
sscanf
,您可以使用%2x
而不是%02x
。此外,%2x
表示将传递额外的int*
参数。但是您传递的是一个unsigned char*
。最后,sscanf 将 const char* 作为第一个参数,因此不需要进行强制转换。因此,请尝试一下:
编辑:澄清为什么此更改可以解决问题:在您的代码中,
sscanf
尝试编写sizeof(int)
内存位置 (&x
) 中只能容纳sizeof(unsigned char)
字节(即 1 个字节)的字节。因此,您覆盖了一定量的内存。这个被覆盖的内存很可能是 i 变量(的一部分)。For
sscanf
you'd use%2x
instead of%02x
. Furthermore,%2x
indicates that an extraint*
argument will be passed. But you're passing anunsigned char*
. And finally,sscanf
takes aconst char*
as first argument, so there's no need for that cast.So give this a try :
EDIT : to clarify why this change resolves the issue : in your code,
sscanf
tried to writesizeof(int)
bytes in a memory location (&x
) that could only holdsizeof(unsigned char)
bytes (ie. 1 byte). So, you were overwriting a certain amount of memory. This overwritten memory could very well have been (part of) thei
variable.从编译器方面来看,此代码表现不同的原因是 gcc 和 llvm(或任何其他编译器)可能以不同的方式布置堆栈。在此之前,您可能只是破坏了堆栈上不需要的其他内容,但由于 llvm 编译器的不同布局,您正在破坏一些更有用的东西。
这是在调试问题时使用堆栈保护器的另一个好理由(-fstack-protector-all/-fstack-protector)。它可以帮助解决这些问题。
From the compiler side of things the reason for this code behaving differently is that gcc and llvm (or any other compiler) may lay out the stack differently. You were likely just clobbering something else on the stack before that you didn't need for this example, but with the different layout for the llvm compiler you were clobbering something more useful.
This is another good reason to use stack protectors when debugging a problem (-fstack-protector-all/-fstack-protector). It can help flush out these issues.