2013-07-16 50 views
0

程序:在STDC非法指令++

#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) 

彙編轉儲結束。

如何解決此問題?

+0

我相信'-Wa, ''在'CFLAGS'中沒用,應該是'CFLAGS = -g -Wall -m32 -mtune = pentiumiii' –

+0

/usr/local/gcc-4.6.2/bin/g++ -g -c -W -m32 -mno -sse -mtune = pentiumiii list_test.cpp list_test.cpp:1:0:錯誤:壞值(pentiumiii)-mtune =開關 –

回答

2

指令movq %xmm0,0xc(%esp)Streaming SIMD Extensions (SSE)指令集的一部分。 Pentium III理論上支持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' 
+0

我嘗試使用-mno-sse編譯器選項,但它不起作用! 無法使用-mcpu = pentium3進行編譯,錯誤如下: g ++:warning:'-mcpu ='已棄用;使用'-mtune ='或'-march ='代替 list_test.cpp:1:0:error:bad value(pentinumiii)for -mtune = switch –

+1

@JianZhang:嘗試'-march ='而不是'-mcpu = '。 –

+0

請注意,該特定指令實際上可能位於鏈接的某個庫中,而不是源文件生成的代碼中。如果是這種情況,則需要使用適當的選項重新構建整個庫以避免不受支持的說明。更好的是,只要在你的目標系統上進行構建,並且它已經具有正常運行的庫... – twalberg

1

它看起來像一個SSE指令,顯然不被處理器支持。 (奔騰3應該支持SSE)。

你可以嘗試編譯你的代碼-mno-sse,看看它是否有幫助。