簡體   English   中英

調用@plt函數時,在dlopen / static init上共享庫SIGSEGV

[英]Shared library SIGSEGV on dlopen / static init when calling @plt function

我的應用程序使用靜態初始化代碼調整庫。 所有其他庫都做同樣的事情並且之前加載得很好,但是當從另一個庫調用函數時,這個庫就會死掉。 這類似於:

0x12311 <-- bad address
_static_initialization_0 <-- function call
....
dlopen

現在,反匯編中的函數調用看起來像

call _Z6MyFuncRA37_Kc@plt

但是,此調用最終調用無效地址0x12311,即PLT條目獲取錯誤的地址。

問題很可能是所討論的庫是第三方庫,即使它依賴於其他庫,它以二進制預構建形式出現。 上周我們做了一個很大的優化,並改變了很多標題,等等。 PLT錯誤的函數MyFunc位於我們的(另一個)庫中,它進行了大量的優化更改。

這怎么可能? 確切的問題是:

  1. 什么是導致PLT不匹配的機制
  2. 有沒有辦法解決它而不觸及預編譯庫 - 可選,因為我可以獲得重建版本,但我仍然好奇為什么它崩潰

此外,使用-O2優化編譯時,相同的應用程序工作正常,這就是我所說的奇怪(二進制庫在兩種情況下都相同)。

PS ubuntu 12.04 x86_64但應用程序是i386。

更新:注釋中的建議(由於某種原因刪除)檢查LD_DEBUG是好的,在LD_DEBUG =綁定中我在app的“崩潰”版本中看到了這一點:

 10272:  /media/EXT/work/build32/bin/libMyLib.so: error: 
    symbol lookup error: undefined symbol: omp_set_num_threads (fatal)

然后它會停止綁定libMyLib.so符號,而在非失敗版本中它會保持綁定其他符號。 但我不明白為什么它繼續執行並嘗試加載父庫。 實際上該計划如下:

libA -> libB -> libMyLib

libMyLib失敗(如上面的LD_DEBUG輸出所示),因此它會跳過它並完全跳過libB(!)並繼續綁定libA符號。 非失敗版本完全加載libMyLib符號,然后繼續使用libB符號,然后使用libA符號。

坦率地說,它看起來像ld bug。

至於為什么優化版本工作,我想omp_方法並不是真正需要的,並且被鏈接器優化拋出,因此它在運行時找不到它。

這是我在LD_DEBUG中看到的=在找不到libC的omp_符號后的所有日志:

19225: symbol=omp_set_num_threads; lookup in file=/usr/lib/i386-linux-gnu/libXdmcp.so.6 [0]
19225: /media/EXT/Work/libC.so: error: symbol lookup error: undefined symbol: omp_set_num_threads (fatal)
19225:
19225: file=/media/EXT/libA.so [0]; destroying link map
19225:
19225: file=/media/EXT/libA.so [0]; dynamically loaded by /media/EXT/libX.so [0]
19225: file=/media/EXT/libA.so [0]; generating link map
19225: dynamic: 0xf2fdb764 base: 0xf2f81000 size: 0x00064a28
19225: entry: 0xf2f8ffd0 phdr: 0xf2f81034 phnum: 7
19225:
19225: checking for version `GCC_3.0' in file /lib/i386-linux-gnu/libgcc_s.so.1 [0] required by file /media/EXT/libA.so [0]
... few more checking
19225: object=/media/EXT/libA.so [0]
19225: scope 0: bin/mainapp /lib/i386-linux-gnu/libpthread.so.0 /media/EXT/libX.so ...
19225: scope 1:...
19225:
19225:
19225: relocation processing: /media/EXT/libA.so
19225: symbol=_ZTVN10__cxxabiv117__class_type_infoE; lookup in file=bin/mainapp [0]
19225: symbol=_ZTVN10__cxxabiv117__class_type_infoE; lookup in file=/lib/i386-linux-gnu/libpthread.so.0 [0]
19225: symbol=_ZTVN10__cxxabiv117__class_type_infoE; lookup in file=/media/EXT/libX.so [0]
19225: binding file /media/EXT/libA.so [0] to /media/EXT/libX.so [0]: normal symbol `_ZTVN10__cxxabiv117__class_type_infoE'

... here it continues to bind libA symbols, and after finishing that

19225:
19225:
19225: calling init: /media/EXT/libC.so
19225:

它為非初始化的libC.so模塊調用init。

(只是提到libX.so是調用dlopen的基本模塊,還包含所有其他庫使用的基本方法。)

在銷毀了libA的鏈接映射后,日志顯示它再次生成,我只是不明白加載器是否繼續加載libA或者這次從頭開始而不打擾libB / libC。 好吧,它在任何情況下都會忽略libB / libC,直到為libC調用init。

omp_set_num_threads與GCC內部的OpenMP支持有關。

你或許應該通過-fopenmp標志在編譯和鏈接時間與gcc(即使你只是dlopen -ing使用OpenMP庫)。

也許原來的圖書館提供商忘記了。

(OpenMP正在改變編譯過程的整個行為)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM