免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1149 | 回复: 0
打印 上一主题 下一主题

ldd_truss_nm [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-05 10:05 |只看该作者 |倒序浏览


HOW-TO: using truss, ldd and nm to observe binary files


有时候我们在运行某个程式的时候,总是会报FILE A no such file or directory之类的错误。但是我们又不知道这个程式是以怎么个形式在找A文件,有时候在某个目录明明有A文件,程式还是会报错,那我们就得知道这个程式在找这个文件的时候,是去哪个目录下找的。ldd truss nm命令就是实现这个功能的利器。
I've decided to write down a few useful tips on observing binary files in Solaris. The commands used are available since Solaris 8, so hopefully you'll find these tricks useful.
Quite often it happens that the programs we run don't work as they should, showing us errors like "referenced symbol not found" or this:
ld.so.1: ./thunderbird-bin: fatal: libmozjs.so: open failed: No such file or directory
So in order for us to find out what exact librabries are being used by a given binary, or where it expects these libraries to be found, and what libraries are not found at all, we have to take the following steps:
1) First we have to see what libraries the ld linker is going to use for our file. For instance, this is how you would find our what libraries are used by the main executable of the Thunderbird mail client:
bash-3.00$ ldd thunderbird-bin
libmozjs.so => (file not found)
libgtk-x11-2.0.so.0 => /usr/lib/libgtk-x11-2.0.so.0
libgdk-x11-2.0.so.0 => /usr/lib/libgdk-x11-2.0.so.0
libatk-1.0.so.0 => /usr/lib/libatk-1.0.so.0
libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0
libm.so.2 => /lib/libm.so.2
...
As always in my examples, the command output is abridged, but you get the idea. It's clearly seen that one of the files - the libmozjs.so library - isn't found. This means, there is no such file in either of the standard library paths or in the current working directory.
2) Now it's about time we find our where the linker expects this libmozjs.so to be found. To do this, we're going to use the truss command. All we're interested in at this stage are the stat and open system calls: stat is used to verify whether some file exists, and open is used to open this file for the later access.
bash-3.00$ truss -f -t stat,open ./thunderbird-bin
13070: stat("/export/soft/thunderbird/thunderbird-bin", 0xFFBFFAD0) = 0
13070: open("/var/ld/ld.config", O_RDONLY) Err#2 ENOENT
13070: stat("/export/soft/thunderbird/libc.so.1", 0xFFBFF600) Err#2 ENOENT
13070: stat("/export/soft/thunderbird/../libc.so.1", 0xFFBFF600) Err#2 ENOENT
13070: stat("/usr/sfw/lib/libc.so.1", 0xFFBFF600) Err#2 ENOENT
13070: stat("/opt/sfw/lib/libc.so.1", 0xFFBFF600) Err#2 ENOENT
13070: stat("/usr/local/lib/libc.so.1", 0xFFBFF600) Err#2 ENOENT
13070: stat("/usr/openwin/lib/libc.so.1", 0xFFBFF600) Err#2 ENOENT
13070: stat("/lib/libc.so.1", 0xFFBFF600) = 0
13070: open("/lib/libc.so.1", O_RDONLY) = 3
13070: stat("/export/soft/thunderbird/libxpcom.so", 0xFFBFF418) = 0
13070: open("/export/soft/thunderbird/libxpcom.so", O_RDONLY) = 3
13070: stat("/export/soft/thunderbird/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/export/soft/thunderbird/../libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/usr/sfw/lib/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/opt/sfw/lib/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/usr/local/lib/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/usr/openwin/lib/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/lib/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
13070: stat("/usr/lib/libmozjs.so", 0xFFBFF398) Err#2 ENOENT
ld.so.1: ./thunderbird-bin: fatal: libmozjs.so: open failed: No such file or directory
13070: stat("/export/soft/thunderbird/libgtk-x11-2.0.so.0", 0xFFBFF398) Err#2 ENOENT
...
From this output you can see very well how linker goes through one standard libraries directory to another in a cyclic search for ever library our binary needs. And for our libmozjs.so we can see that logically this library would be found in the current directory where I'm running the thunderbird-bin from, /export/soft/thunderbird. There is no such file there, simply because I've renamed it for this demo.
And this is how the same ldd command would look when all the files are in place:
bash-3.00$ ldd thunderbird-bin
libmozjs.so => /export/soft/thunderbird/libmozjs.so
libgtk-x11-2.0.so.0 => /usr/lib/libgtk-x11-2.0.so.0
libgdk-x11-2.0.so.0 => /usr/lib/libgdk-x11-2.0.so.0
libatk-1.0.so.0 => /usr/lib/libatk-1.0.so.0
libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0
libm.so.2 => /lib/libm.so.2
...
So you can be assured now that our library is found and loaded from the /export/soft/thunderbird/libmozjs.so location.
Thus, by using this simple yet very powerful combination of ldd and truss commands, you can stop guessing and find out exactly which libraries are loaded in a particular order and where they are loaded from.
3) For the "referenced symbol not found" errors, we have to take one more step. These errors happen mostly because the linker finds the library our binary needs, but this library somehow doesn't have the functions we're interested in. So, once we know the exact library file after following the steps 1 and 2 of this manual, it's time for us to look at this particular file and see what functions are available. Many libraries have thousands of functions accessible, so it would make sense to use grep if you know the function you're looking for.
For instance, the following command shows all the functions of the libgdk-x11-2.0 library, which have gdk_threads in their names:
bash-3.00$ nm /usr/lib/libgdk-x11-2.0.so.0 | grep gdk_threads
[3632] | 86512| 68|FUNC |GLOB |0 |11 |gdk_threads_enter
[219] | 86648| 104|FUNC |LOCL |0 |11 |gdk_threads_impl_lock
[220] | 86752| 104|FUNC |LOCL |0 |11 |gdk_threads_impl_unlock
[4329] | 86856| 212|FUNC |GLOB |0 |11 |gdk_threads_init
[3507] | 86580| 68|FUNC |GLOB |0 |11 |gdk_threads_leave
[4095] | 532720| 4|OBJT |GLOB |0 |17 |gdk_threads_lock
[3579] | 532716| 4|OBJT |GLOB |0 |17 |gdk_threads_mutex
[4391] | 87068| 144|FUNC |GLOB |0 |11 |gdk_threads_set_lock_functions
[4443] | 532724| 4|OBJT |GLOB |0 |17 |gdk_threads_unlock
As you understand, if you get a "referenced symbol not found" error, this is quite often because an incorrect (incompatible) version of some library is used - it could be very old or just too new a version of the library, so the functions your binary is looking for are simply not there anymore or called differently.
Well, that's all for today. If you have any additional info to add to this short manual, you're very welcome to leave comments. I'll be happy to hear your opinion.
Defined tags for this entry:
how-to
,
howto
,
ldd
,
nm
,
solaris
,
sysadmin
,
troubleshooting
,
truss



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/46451/showart_1680435.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP