從 glib 和 gobject 內部獲取分段錯誤 - 我想我想針對 glib2 的獨立版本建構/靜態連結
我還沒有完全理解段錯誤和回溯是如何工作的,但我的印像是,如果列表頂部的函式引用“glib”或“gobject”,那麼通常應該使用庫的 Bad Issues(TM)不會出錯。
好吧,這就是我從兩個完全不同的程序中得到的。
第一個是 irssi 的最新版本,直接從 github.com 編譯(乾淨,沒有任何故障或錯誤)。
Program received signal SIGSEGV, Segmentation fault. 0xb7cf77ea in g_ascii_strcasecmp () from /usr/lib/libglib-2.0.so.0 (gdb) bt #0 0xb7cf77ea in g_ascii_strcasecmp () from /usr/lib/libglib-2.0.so.0 #1 0x08103455 in config_node_section_index () #2 0x081036b0 in config_node_traverse () #3 0x080fb674 in settings_get_bool () #4 0x08090bce in command_history_init () #5 0x08093d81 in fe_common_core_init () #6 0x0805a60d in main ()
我遇到的第二個程序是針對 GTK 建構的 NetSurf Web 瀏覽器(它也可以 100% 乾淨地編譯)(當不是使用 GTK 建構時它執行良好):
Program received signal SIGSEGV, Segmentation fault. 0xb7c1bace in g_type_check_instance_cast () from /usr/lib/libgobject-2.0.so.0 (gdb) bt #0 0xb7c1bace in g_type_check_instance_cast () from /usr/lib/libgobject-2.0.so.0 #1 0x080cd31c in nsgtk_scaffolding_set_websearch () #2 0x080d05da in nsgtk_new_scaffolding () #3 0x080dafd8 in gui_create_browser_window () #4 0x0809e806 in browser_window_create () #5 0x080c2fa9 in ?? () #6 0x0807c09d in main ()
我有 99.99% 的信心,我正在研究的問題是 glib2 的某種故障。我係統的其餘部分工作 100% 正常,只是這兩個程序在做奇怪的事情。
我同樣有信心,如果我嘗試建構使用這些庫的其他程序,它們也很可能會失敗。
顯然,戳 glib 和朋友 - 甚至犯一個微小的小錯誤 - 是一個即時配方,幾乎使系統中的每個程序都發生災難性的可怕破壞(我從很久以前使用另一個系統的經驗說起:P)。
鑑於我完全不知道我在用這種東西做什麼,而且我知道,我不願意去那裡;我想保持我目前的系統配置正常執行:)
我正在考慮編譯一個新版本的 glib2(和 co.),然後將這些程序靜態連結到它。我只是不知道該怎麼做 - 我需要執行哪些步驟?
我的另一個想法是
./configure --prefix=/usr; make; make install
使用與我現在“回到”我的系統中的完全相同版本的 glib,重新安裝它。我看到相關的核心庫都以“ 0.3200.4 ”結尾:-rwxr-xr-x 1 root root 1.4M Aug 9 2012 /usr/lib/libgio-2.0.so.0.3200.4 -rwxr-xr-x 1 root root 1.2M Aug 9 2012 /usr/lib/libglib-2.0.so.0.3200.4 -rwxr-xr-x 1 root root 11K Aug 9 2012 /usr/lib/libgmodule-2.0.so.0.3200.4 -rwxr-xr-x 1 root root 308K Aug 9 2012 /usr/lib/libgobject-2.0.so.0.3200.4 -rwxr-xr-x 1 root root 3.7K Aug 9 2012 /usr/lib/libgthread-2.0.so.0.3200.4
這可能會起作用,還是會嚴重破壞事情?:S
如果可行,“0.3200.4”翻譯成什麼版本?
我還可以嘗試哪些其他想法?
我不一定要尋找 glib 本身的修復程序來糾正正在發生的任何基本錯誤——它對我的影響並沒有那麼嚴重。我只想讓 irssi 和 NetSurf 正常執行。
我的印像是,如果列表頂部的函式引用“glib”或“gobject”,那麼通常不應該出錯的庫就會出現 Bad Issues(TM)。
你會得到錯誤的印象,如果你的意思是這表明缺陷可能在那些庫中。這並不意味著;這更有可能意味著這就是早期錯誤最終爆發的地方。從本質上講,C 沒有很多執行時保護措施,因此您可以輕鬆傳遞將編譯但不會進一步驗證的參數(除非您自己做)。簡單的例子:
int main (void) { char whoops[3] = { 'a', 'b', 'c' }; if (strcmp(whoops, "abcdef")) puts(whoops);
將未終止的字元串傳遞給幾個不同的字元串函式。這將編譯沒有問題,並且很可能執行正常,因為記憶體違規將非常輕微,但它可能會
strcmp()
在or中出現段錯誤puts()
。這並不意味著strcmp()
實現是錯誤的。錯誤顯然就在那裡main()
。像這樣的函式無法從邏輯上確定傳遞的參數是否被正確終止(這就是我的意思是 WRT 執行時檢查,而 C“本質上”缺少它們)。規定編譯器應該檢查沒有什麼意義,因為大多數時候數據不會像那樣被硬編碼。
回溯中間的東西也不一定發揮作用,儘管它可以。通常開始尋找的地方是最後一個條目;這就是問題的根源。
但是錯誤可能總是在任何地方。通常將回溯與記憶體檢查器報告的錯誤進行比較
valgrind
可以幫助縮小範圍。WRT 你的例子可能有很多東西需要篩選;最後我檢查了 valgrind 和 gtk 不是快樂的玩伴。我正在考慮編譯一個新版本的 glib2(和 co.),然後將這些程序靜態連結到它。
你可以,儘管我看不出有任何理由相信任何事情都會因此而變得更好。它正在抓住稻草。您實際上無法自己調試問題,這是可以理解的,因此您考慮一下可以嘗試的方法。
您很可能只是在浪費大量時間並讓自己感到沮喪。
我有 99.99% 的信心,我正在研究的問題是 glib2 的某種故障。
我有 99% 的信心,你在那裡過於自信。
雖然錯誤可能出現在任何地方,但根據經驗,將最廣泛測試的部分視為最不可能的罪魁禍首。在這種情況下,glib 非常普遍,而 irssi 和 NetSurf 則相對晦澀難懂。
您最好的辦法可能是送出錯誤報告。回溯通常在那裡非常受歡迎。從 irssi 和 NetSurf 開始;如果你直接說油嘴滑舌,他們會合理地說,除非你能證明,否則他們沒有理由相信這是他們的問題(這一切都沒有)。另一方面,如果 irssi 人確定它是油嘴滑舌的,他們可能會想自己去追求。