2012-05-04 98 views
3

我在共享庫內得到SEGSEGV後,試圖獲取並將堆棧追蹤保存到文件中。共享庫是一個封閉源代碼產品的插件。所有這些都適用於生產,我無法直接訪問它。共享庫內的追蹤功能

我的代碼捕獲SIGSEGV信號,打印堆棧跟蹤並退出。我有這樣的事情:

/opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] 的/ opt/ecelerity/libexec目錄/site/ec_attachextensions.so [0x2aecc2019fee] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc201a587]

/選擇/ ecelerity/sbin目錄/ ecelerity [0x5]

/選擇/ ecelerity/sbin目錄/ ecelerity(sieve_seng_execute + 0x82)[0x506d32] /opt/ecelerity/libexec/validate/sieve.so [ 0x2aecc2862c9e] /選擇/ ecelerity/sbin目錄/ ecelerity(VALIDATE_DATA + 0xA5的)[0x4a90d5] /選擇/ ecelerity/sbin目錄/ ecelerity(esmtp_message_factory + 0x154e)[0x46eace] /選擇/ ecelerity/sbin目錄/ ecelerity(schedule_event_and_dispatch +的0x6A) [0x49c59a]

問題是我不能擁有共享 庫中的函數和偏移量的名稱。據我所知,我可以在 addr2line實用程序的幫助下找到給定地址的函數名稱/文件名,我將在/proc/$PID/maps中找到庫偏移量。

在那之後,我執行類似的東西:

addr2line -e /opt/ecelerity/libexec/site/ec_attachextensions.so (LIBRARY_OFFSET_FROM_MAPS_FILE - 0x2aecc2019f11) 

哪裏0x2aecc2019f11是從上面的堆棧跟蹤的地址。我想知道是否有任何方法可以在不觸及地圖文件的情況下獲取堆棧跟蹤中的函數名稱?換句話說,我該如何編程呢?請問dladdr在這裏有幫助(dladdr無法從我提供的backtrace函數提供的地址獲取函數名稱)?

回答

1

回溯代碼使用與dladdr大致相同的機制來確定函數名稱。

,如果你的庫使用一個鏈接器映射文件(定義什麼是被出口,可以用來限制所有其他項目的可見性),或-fvisibility=hidden有明確可見的符號構建,則掩蓋了符號以便它們不會出現在回溯輸出中。

解決方法是在不使用限制庫中所有符號可見性的地圖文件的情況下進行編譯,或者使用-fvisibility=default進行編譯。這將無需代表您的努力就能回溯工作。

爲了在沒有這樣做的情況下正常工作,您需要從.so加載本地符號表並使用類似於addr2line的機制來確定符號位置。這樣做的機制是利用libelf1。讀取本地符號表。

...這當然要求表格沒有從文件中剝離。如果是這樣的話,那麼這些技巧都不重要,因爲.so根本沒有提供這些信息。

1

您可以讓信號處理程序爲您讀取/ proc/self/maps。

或者您可以輸出某些函數的絕對地址,然後您可以將其用作比較點以查找庫偏移量。

但是,如果有一個動態鏈接器函數會給你基地址,我不會感到驚訝 - 你可以檢查文檔。