2012-09-05 137 views
1

我的程序隨機調用回調函數時崩潰了Segmentation錯誤。當我分析核心時,回調函數地址是0x20202020。 程序以信號11結束,分段故障。程序崩潰時調用回調函數時出現段錯誤

#0 0x20202020 in ??() 

(gdb) bt 

#0 0x20202020 in ??() 
#1 0xf775a8cf in my_function (parm_p=0x9b88020) at ../src/mewz.c:1395 

(mqheader_p->mqh_callback)(mqheader_p->mqh_cbarg); 

mqh_callback = 0x20202020, 
mqh_cbarg = 0x20202020, 

這是隨機發生的。 我知道0x20202020不是回調函數的有效地址,但爲什麼這個回調函數地址是隨機指向一個無效地址的。任何線索?

+0

您需要使用您正在編寫程序的語言來標記此問題。 – chucksmash

+0

mqheader_p變量未初始化或已被覆蓋,可能是由一些stringpointer值所覆蓋。 – wildplasser

+0

代碼以「C」語言編寫。 (mqheader_p-> mqh_callback)是回調函數指針。 –

回答

2

回調函數指針可能已被覆蓋,或正在從內存中使用,甚至沒有正確分配和初始化。

有點有趣,0x20是空格字符的ASCII碼。

可以做的事:

  1. mqheader_p點,檢查各地的數據分配的代碼。
  2. 在調試器中運行該程序,並在函數指針上設置一個觀察點。
2

我的猜測是緩衝區溢出。由於0x20恰好是ASCII空間,我認爲這是覆蓋地址的字符串的一部分。特別注意你對sprintf等的使用。

你可以記錄內存之前和之後可能會給你更多的線索可能會覆蓋的線索。

注意:0x20202020是四個字節0​​x20 0x20 0x20 0x20或一行中的4個空格字符。

+0

它並不完全是0x20,它是0x20202020 –

+0

在上一個核心文件中,該值爲0x57 –

+0

您正在用指針一次查看4個字節,以便連續4個空格。 0x57是'W'字符,請看[ASCII表格](http://www.asciitable.com/)。 – weston

0

爲了解決這類問題,我認爲您可以在第一次啓動mqh_callback後打印出mqh_callback值,另一個打印輸出應該在您調用回調之前。 Aonther將在mqh_callback的地址上使用寫入斷點。

這樣的錯誤可能來自某些指針技巧操作,比如缺少初始化,緩衝區溢出等等。

+0

嗨wbao,謝謝你的回覆。 我試着打印這些值,同時分配和調用回調之前。對於時間的呃,兩個值都是一樣的。但在調用回調函數之前的某個時間點,該值變爲0x20202020。這是一個線程啓動功能。 –

+0

我不確定你的env是否支持。 GDB擁有awatch命令,讓您可以在特定虛擬地址上觀看寫入內存訪問。如何用這個來追蹤「邪惡」?這可能是一個簡單的方法來找到誰更改你的函數指針 – wbao

+0

嗨Wbao,問題是這在客戶端環境中發生。還有一件更有趣的事情是,它有數量龐大的客戶端安裝,它不會崩潰。只有一個客戶隨機崩潰。 –