目的
デバッグ時に今の実行環境で特定シンボルが使用されているかを判別したい時があります。
(LD_PRELOADで特定関数をフックしたい時など => 参考: LD_PRELOADでprintfを後から差し替える - Qiita )
その場合の調査方法をまとめました。
実行ソース
基本的に ldd
と readelf
を使うだけですが、せっかくなのでツール化しました。
elf_symbol_searcher.sh
#!/bin/bash
APP=$1
SYMBOL=$2
LIST=$(echo $APP; ldd $APP \
| grep -v -E 'ld-linux*.so' \
| grep -v 'linux-vdso.so' \
| grep -v 'linux-gate.so' \
| awk '{print $3}')
for f in $LIST
do
echo $f
readelf -s -W $f | grep $SYMBOL
done
ldd
で依存ライブラリを取得していますが、ld-linux*.so
と Linux Virtual Dynamic Shared Objects
(参考)は除外しています。
nm
でもシンボルは取得できますが strip
されているとシンボルが見えなくなるため、今回は readelf
を使用しています。
実行例としては以下のようになります。
今回の対象は /usr/bin/weston
で、検索対象は eglSwapBuffers
になります。
実行結果
$ ./elf_symbol_searcher.sh /usr/bin/weston eglSwapBuffers
/usr/bin/weston
166: 0000000000000000 0 FUNC GLOBAL DEFAULT UND eglSwapBuffers
/usr/lib/x86_64-linux-gnu/libwayland-server.so.0
/usr/lib/x86_64-linux-gnu/libpixman-1.so.0
/usr/lib/x86_64-linux-gnu/mesa-egl/libEGL.so.1
180: 0000000000006fb0 380 FUNC GLOBAL DEFAULT 11 eglSwapBuffersRegionNOK
187: 0000000000009850 339 FUNC GLOBAL DEFAULT 11 eglSwapBuffers
235: 00000000000079e0 427 FUNC GLOBAL DEFAULT 11 eglSwapBuffersWithDamageEXT
/usr/lib/x86_64-linux-gnu/mesa-egl/libGLESv2.so.2
/usr/lib/x86_64-linux-gnu/libxkbcommon.so.0
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libffi.so.6
/lib/x86_64-linux-gnu/librt.so.1
/lib/x86_64-linux-gnu/libpthread.so.0
/usr/lib/x86_64-linux-gnu/libX11-xcb.so.1
/usr/lib/x86_64-linux-gnu/libX11.so.6
/usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0
/usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0
/usr/lib/x86_64-linux-gnu/libxcb.so.1
/usr/lib/x86_64-linux-gnu/libwayland-client.so.0
/usr/lib/x86_64-linux-gnu/libgbm.so.1
/usr/lib/x86_64-linux-gnu/libdrm.so.2
/usr/lib/x86_64-linux-gnu/libglapi.so.0
/usr/lib/x86_64-linux-gnu/libXau.so.6
/usr/lib/x86_64-linux-gnu/libXdmcp.so.6
とても簡易的ですが、本体の weston
と eglSwapBuffers
を実装している libEGL
にシンボルがあることが調査できました。
スクリプトは以下にも公開しています。(pythonとかで書いてもう少し使いやすくする予定)
https://github.com/koara-local/elf_symbol_searcher
TODO
以上でもデバッグ用途には使用できますが、もうちょっと詳しく検索できると良さそうです。
- シンボルの複数指定 + 正規表現での検索
- 除外ライブラリの指定
- C++の場合のデマングル前後での検索
など