stdc ++中的非法指令

时间:2013-07-16 03:53:49

标签: linux gcc

程序:

#include <stdio.h>
#include <sstream>
int main()
{
    std::stringstream ss;
    ss << "hello world " << 1234 << "\n";
    std::string str = ss.str();
    printf(str.c_str());
    return 0;
}

生成文件:

CC=/usr/local/gcc-4.6.2/bin/g++
CFLAGS=-g -c -W -m32 -Wa,-mtune=pentiumiii
LINKFLAGS=-m32 -static-libgcc -static-libstdc++ -Wl,-rpath,./runtime,--dynamic-linker,./runtime/ld-linux.so.2
all:test
test: list_test.o
    $(CC) $(LINKFLAGS) list_test.o -o test 

list_test.o: list_test.cpp
    $(CC) $(CFLAGS) list_test.cpp

clean:
     rm *.o ./test -f

我在64位linux中构建它。当它在具有pentinum(R)III cpu的32位linux中运行时,存在非法指令。

非法指令如下:

(gdb) disas 0x0804f77a 0x0804f77b
Dump of assembler code from 0x804f77a to 0x804f77b:
0x0804f77a <std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::_M_sync(std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::char_type*, std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::__size_type, std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::__size_type)+138>:     movq   %xmm0,0xc(%esp)

汇编程序转储结束。

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

指令movq %xmm0,0xc(%esp)Streaming SIMD Extensions (SSE)指令集的一部分。理论上Pentium III支持SSE,但是你试图运行它的处理器显然不支持SSE。您可以使用-mno-sse编译器选项禁用GCC上的SSE指令生成。您还可以尝试-march=pentium3生成与Pentium III及更高版本兼容的代码。

此外,您的printf调用有一个错误 - 您应该(几乎)从不传递非常量字符串作为格式参数(第一个参数)。如果该字符串恰好包含任何%符号,则会导致未定义的行为。充其量,这将崩溃,最糟糕的是,您可能会有一个无声的安全漏洞。解决方法是这样做:

printf("%s", str.c_str());

或者更好的是,完全避免使用printf函数族的潜在问题,因为您使用的是C ++:

std::cout << str;  // Optionally also do `<< std::flush'

答案 1 :(得分:1)

它看起来像SSE指令,显然处理器不支持。 (奔腾3应该支持SSE)。

您可以尝试使用-mno-sse编译代码,看看它是否有帮助。