2010-02-21 57 views
4

我在Linux上遇到一些與我的C程序有關的問題。它在Windows上編譯和運行得很好。 Linux終端返回以下信息:堆棧粉碎後如何處理錯誤信息

*** stack smashing detected ***: ./student terminated  
======= Backtrace: =========         
/lib/libc.so.6(__fortify_fail+0x4b)[0xb7e908ab]    
/lib/libc.so.6(__fortify_fail+0x0)[0xb7e90860]    
./student[0x8048c09]           
./student[0x80486dd]           
/lib/libc.so.6(__libc_start_main+0xe5)[0xb7dc0775] 
./student[0x80485e1] 
======= Memory map: ======== 
08048000-0804a000 r-xp 00000000 00:11 11222  /mnt/win/POT03/Eclipse/student 
0804a000-0804b000 r--p 00001000 00:11 11222  /mnt/win/POT03/Eclipse/student 
0804b000-0804c000 rw-p 00002000 00:11 11222  /mnt/win/POT03/Eclipse/student 
0804c000-0821a000 rw-p 0804c000 00:00 0   [heap] 
b7da9000-b7daa000 rw-p b7da9000 00:00 0 
b7daa000-b7eeb000 r-xp 00000000 75:00 116292  /lib/libc-2.9.so 
b7eeb000-b7eed000 r--p 00141000 75:00 116292  /lib/libc-2.9.so 
b7eed000-b7eee000 rw-p 00143000 75:00 116292  /lib/libc-2.9.so 
b7eee000-b7ef1000 rw-p b7eee000 00:00 0 
b7ef4000-b7f01000 r-xp 00000000 75:00 116275  /lib/libgcc_s.so.1 
b7f01000-b7f02000 r--p 0000c000 75:00 116275  /lib/libgcc_s.so.1 
b7f02000-b7f03000 rw-p 0000d000 75:00 116275  /lib/libgcc_s.so.1 
b7f03000-b7f06000 rw-p b7f03000 00:00 0 
b7f06000-b7f22000 r-xp 00000000 75:00 116288  /lib/ld-2.9.so 
b7f22000-b7f23000 r--p 0001b000 75:00 116288  /lib/ld-2.9.so 
b7f23000-b7f24000 rw-p 0001c000 75:00 116288  /lib/ld-2.9.so 
bf8eb000-bf900000 rw-p bf8eb000 00:00 0   [stack] 
ffffe000-fffff000 r-xp 00000000 00:00 0   [vdso] 
Aborted 

如何使用此信息來跟蹤問題?

回答

7

用調試信息編譯你的程序,然後用valgrind運行。

gcc -g student.cpp -o student 
valgrind ./student 

嘗試一個調試器:

gcc -g student.cpp -o student 
gdb ./student 
run 
    // wait for it to crash 
backtrace 
help // to figure out what else you can do 
+4

valgrind的+1 - 它可能比gdb更有用。 – 2010-02-21 20:09:14

+1

使用GDB'bt'的主要問題(我認爲)是,只有在返回時(塊/函數的結尾)纔會注意到被搗毀的堆棧。因此,您在回溯輸出中看到的行將是右大括號,在你的某個地方寫一個堆棧分配的緩衝區/數組。 – eckes 2013-04-25 22:26:02

+0

在這種情況下,這裏的建議不太可能對其他人有所幫助。首先,Valgrind不太可能幫助你發現問題,因爲問題是堆棧粉碎溢出 - Valgrind在處理堆棧分配緩衝區方面效率不高。其次,調試器會在您從緩衝區被分配的函數返回的位置爲您提供堆棧跟蹤,而不是您在緩衝區末尾寫入的位置處的堆棧跟蹤。關閉堆疊保護器是一個可怕的想法;如果您收到此消息,則說明您存在嚴重的安全漏洞。 – 2014-02-09 02:20:02

1

首先你需要一個地圖文件。從映射文件中,您可以查找內存地址(0x8048c09)。該函數實際上將從堆棧中的地址之前的地址開始。從這裏你可以知道你在哪個函數中崩潰,並且對彙編程序生成的知識有一點了解,你可以計算出它墜毀的函數有多遠。然後,你看看代碼,並試圖找出你做錯了什麼。

失敗......使用調試器。然後你就可以看到墜毀的位置。從那裏你甚至可以(如果你正在運行一個優化版本,你將能夠)看到你究竟是什麼呼叫以及參數是什麼。然後您可以查看是什麼導致了問題,並且可以阻止它發生。

+0

呸,彙編...程序的規模相對較小,不值得這一努力。我會試着找出程序使用調試器崩潰的地方。 – Pieter 2010-02-21 20:07:31