如何从lib .so文件中查找函数?

时间:2016-08-24 08:02:04

标签: linux grep shared-libraries nm

我可以打印一个* .so文件的导出功能列表,如

nm -C lib/libopencv_ml.so

然后找到我的功能

nm -C lib/libopencv_ml.so | grep myfunction

但是当我想从所有.so文件中找到函数时如何确定哪个.so包含我的函数?

这只是打印函数的所有条目,但我需要知道它出现在哪个.so文件中。

nm -C lib/*.so | grep cvSetZero

似乎-H选项也没有帮助。 -H, --with-filename print the file name for each match

nm -C lib/*.so | grep -Hn cvSetZero

生成输出,如:

(standard input):98:                 U cvSetZero
(standard input):796:                 U cvSetZero
(standard input):2564:00000000000b2540 T cvSetZero
(standard input):8673:                 U cvSetZero
(standard input):12233:                 U cvSetZero
(standard input):15503:                 U cvSetZero
(standard input):17460:                 U cvSetZero
(standard input):18727:                 U cvSetZero
(standard input):20865:                 U cvSetZero

2 个答案:

答案 0 :(得分:3)

我找到了解决方案

nm -C -A lib/*.so | grep cvSetZero

它产生了这种输出:

lib/libopencv_calib3d.so:                 U cvSetZero
lib/libopencv_contrib.so:                 U cvSetZero
lib/libopencv_core.so:00000000000b2540 T cvSetZero
lib/libopencv_highgui.so:                 U cvSetZero
lib/libopencv_imgproc.so:                 U cvSetZero
lib/libopencv_legacy.so:                 U cvSetZero
lib/libopencv_ml.so:                 U cvSetZero
lib/libopencv_objdetect.so:                 U cvSetZero
lib/libopencv_video.so:                 U cvSetZero

答案 1 :(得分:0)

你最后可以追加一个:
    | c++filt

为了解码符号。另外,作为一般说明,gcc-nm应该在用LTO编译的系统中使用。

编辑:使用nm的另一种方法是使用-D--defined-only,然后将可能的错误重定向到/dev/null,{{1带有grep完全符号。

'\bsymbol_name\b'

这样可以搜索定义symbol_name的库,而不仅仅是使用它。 $ nm -Dn -o --defined-only /lib/* /usr/lib64/* 2> /dev/null | grep '\bprintf\b' /lib/libc-2.26.so:0000000000058ee0 T printf /lib/libc.so.6:0000000000058ee0 T printf 允许仅在动态库(.so)中搜索。

但似乎扫描定义(+)或不定义( - )符号的库的最终方式是scanelf

-D

使用$ scanelf -qRys +printf /lib64/ printf /lib64/lib/clang/3.7.0/lib/linux/libclang_rt.asan-i386.so printf /lib64/lib/clang/3.7.0/lib/linux/libclang_rt.asan-x86_64.so printf /lib64/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2.0.0 printf /lib64/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libtsan.so.0.0.0 printf /lib64/lib/gcc/x86_64-pc-linux-gnu/5.4.0/32/libasan.so.2.0.0 printf /lib64/libc-2.26.so $ scanelf -qRys -printf /lib64/ printf /lib64/lib/ConsoleKit/ck-collect-session-info printf /lib64/libnsl-2.26.so 选项运行scanelf /以搜索整个系统,而不会越过挂载点。