G-WAN是否應該與valgrind一起工作?
我們測試了Valgrind,雖然它做了很多事情,但它並不適用於高併發作業(即使低併發性是Valgrind的問題)。
可行的選項來檢測在G-WAN下運行的C代碼中的內存錯誤?
使用malloc()
包裝,預分配池,或者甚至更好,使用alloca()
避免在首位內存問題。
需要注意的是G-WAN處理C腳本錯誤指針沒有崩潰的服務器,請參閱:http://gwan.ch/developers#crash
此bug的代碼:
int main(int argc, char *argv[])
{
strcpy(0xBADC0DE, 0xBADC0DE);
return 200;
}
...會產生類似下面的 '優雅'崩潰報告:
Script: crash_libc.c
Client: 127.0.0.1
Query : ?crash_libc
Signal : 11:Address not mapped to object
Signal src : 1:SEGV_MAPERR
errno : 0
Thread : 0
Code Pointer: 0000f5200b33 (module:/lib/libc.so.6, function:strcpy, line:0)
Access Address: 00000badc0de
Registers : EAX=00000badc0de CS=00000033 EIP=0000f5200b33 EFLGS=000000010202
EBX=000000000001 SS=ec2d8ed4 ESP=0000f5ded828 EBP=0000f5dee020
ECX=000033323130 DS=ec2d8ed4 ESI=0000ec2d8f86 FS=00000033
EDX=000003b03c00 ES=ec2d8ed4 EDI=00000badc0de CS=00000033
Module :Function :Line # PgrmCntr(EIP) RetAddress FramePtr(EBP)
libc.so.6: strcpy: - 0000f5200b33 0000ec2d8f00 0000f5dee020
servlet: main: 37 0000ec2d8f00 00000042e10c 0000f5dee020
和G-WAN竟把告訴你在哪裏錯誤在源代碼中發生(見G-WAN crash_xxx.c例子)instea d殺死服務器進程。
如果您不想調試C代碼,然後使用Java或Scala(均由G-WAN支持) - 您將需要更多內存,因爲您的數據將保持加載狀態,直到GC將所有內容放慢它認爲可以釋放 - 但至少你會享受更少的內存相關的錯誤,如果有的話。
根據提問人的要求,這裏有更多的細節。
2012年底,我們測試了十幾種免費和商業工具,像Valgrind一樣,應該幫助調試併發性。我們還使用靜態工具來學習源代碼,而不僅僅是運行(編譯)程序的動態工具。
可悲的事實是,他們都從常見問題的困擾,他們:
- 一般都支持併發(核問題)
- 瑣碎警報的產生gazillions(甚至更多的假警報太慢)
- 是非常昂貴的(這是或商業的當然),並不能總是在購買前測試(!)
所以,周檢查和過濾所有這些結果後,我們花了很多時間「糾正」的G-WAN的代碼庫,以消除因無法區分工具的瑣碎和假警報(警報從錯誤的代碼中得到有效的代碼)......但是,當時我們感到沮喪,我們還沒有在G-WAN中發現任何真正的錯誤(明確表明這幾周浪費了時間)。
因此,上面的結論是:儘可能簡化代碼,並在需要更復雜的策略時嘗試預先分配塊。
當然,Linux LIBC堅持用(不可捕捉的)abort
信號殺死應用程序並不能幫助(這可以防止程序從恢復或轉儲相關跟蹤),尤其是對於馬虎的雙免費Linux LIBC檢測(錯誤地認爲當程序使用malloc()一次時,所有代碼都使用它的malloc() - 這通常由LIBC調用完成!)。我甚至沒有談論mmap()失敗,也沒有談到OOM kill-switch。
到目前爲止,我們發現的唯一解決方案是避免使用Linux LIBC,並用我們自己的C運行時編譯我們需要的所有東西。對於所有用戶,這是一個難以推薦的「要做的事情」,但它對我們有效。
我們很高興看到Linux使用我們的部分代碼(或者至少一些在G-WAN中實現的概念),因爲這會使我們的生活(以及許多其他開發人員)變得非常容易,但過去我們與「負責人」進行的接觸並不令人鼓舞。總而言之,從操作系統,像我們這樣的獨立軟件開發商和開發者那裏有改進的餘地 - 畢竟,自2004年以來,併發只是「主流」......差不多十年前。
來源
2013-07-16 12:34:29
Gil
Valgrind在signle核心上運行,但它調試高併發作業NP。當你有一個錯誤時,你總是可以將一部分流量重定向到一個valgrind-ed服務器。像DUMA和ElectricFence這樣的LD_PRELOAD malloc包裝器也不能與G-WAN一起工作(DUMA立即崩潰,EF在'stream3.c'中崩潰)。當處理異步代碼時,內存處理並不像alloca那麼簡單,即使使用alloca,如果可能的話,每個大型程序都會有錯誤和內存損壞。感謝您的回答。然而問題在於:什麼是G-WAN的工作valgrind選擇? – ArtemGr
我會在上面的回覆中添加更多細節,但簡而言之(真正有能力的)併發調試工具目前還沒有商業可用。 – Gil
再次感謝Gil的回答。不過,你對這個場景的失望並不是解決調試代碼問題的一個解決方案。在新的編譯器中,「-fsanitize = address」如何?您是否計劃在G-WAN中支持? – ArtemGr