当GDB无法显示so动态库的信息或者显示信息有误时,通常是由于库搜索路径错误导致的,可使用set sysroot、set solib-absolute-prefix、set solib-search-path来指定库搜索路径。

1. set sysroot 与 set solib-absolute-prefix 是同一条命令,实际上,set sysroot是set solib-absolute-prefix 的别名。

2. set solib-search-path设置动态库的搜索路径,该命令可设置多个搜索路径,路径之间使用“:”隔开(在linux中为冒号,DOS和Win32中为分号)。

3. set solib-absolute-prefix 与 set solib-search-path 的区别:

总体上来说solib-absolute-prefix设置库的绝对路径前缀,只对绝对路径有效;而solib-search-path设置库的搜索路径,对绝对路径和相对路径均起作用。(编译器自动链接的so库多采用绝对路径)。

详细规则有:

set solib-search-path由于是路径前缀,所以只能设置一个路径,而solib-search-path可以设置多个搜索路径。

在载入动态库信息时Coredump会碰到两种路径:绝对路径和相对路径。编译时链接的库通常是绝对路径,例如"/lib/libc.so.6"、"/lib/libdl.so.2"等,此时在Coredump文件中也同样保存为绝对路径;而程序用dlopen函数载入的so库可能使用相对路径,例如"./libddd.so",此时Coredump文件原封不动地保存相同的路径。

为便于表述,用A表示set solib-absolute-prefix设置的路径,R(A)表示A去掉根前缀后的路径(即去掉前缀“/”符号),用Bn表示set solib-search-path设置的每一条路径,用X表示Coredump中保存的库路径,即待搜索的库文件路径,F(X)表示X中去掉目录后的文件名(路径最后“/”符号后的字符串)。

对绝对路径,搜索顺序是:

1) A / X                       // 先添加solib-absolute-prefix前缀进行搜索,成功则不再继续,否则继续2)

2) R(A) / X                 // 再把1)的根前缀去掉后进行搜索,成功则不再继续,否则继续3)

3) Bn / R(A) / X         // 再在2)的基础上逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续4)

4) Bn / F(X)               // 再只使用2)中的文件名(去掉目录段),并逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续5)

5) $PATH / R(A) / X                                    // 在2)的基础上使用环境变量$PATH中的每条路径进行搜索,成功则不再继续,否则继续6)

6) $LD_LIBRARY_PATH / R(A) / X         // 在2)的基础上使用环境变量$LD_LIBRARY_PATH中的每条路径进行搜索,成功则不再继续,否则继续7)

7) 返回失败

对相对路径,搜索顺序是:

1) X                            // 直接使用原始路径进行搜索,成功则不再继续,否则继续2)

2) Bn / X                    // 再逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续3)

3) Bn / F(X)               // 再只使用文件名(去掉目录段),并逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续4)

4) $PATH / X                                    // 再使用环境变量$PATH中的每条路径进行搜索,成功则不再继续,否则继续5)

5) $LD_LIBRARY_PATH / X         // 再使用环境变量$LD_LIBRARY_PATH中的每条路径进行搜索,成功则不再继续,否则继续6)

6) 返回失败

===================================

举例说明:

set solib-absolute-prefix /root/temp

set solib-search-path /home/evan:/home/peter

$PATH is /usr/sbin:/usr/bin

$LD_LIBRARY_PATH is /opt:/usr/games

那么对绝对路径"/lib/libc.so.6"的搜索顺序是:

1) A / X

/root/temp/lib/libc.so.6

2) R(A) / X

root/temp/lib/libc.so.6

3) Bn / R(A) / X

/home/evan/root/temp/lib/libc.so.6

/home/peter/root/temp/lib/lic.so.6

4) Bn / F(X)

/home/evan/libc.so.6

/home/peter/libc.so.6

5) $PATH / R(A) / X

/usr/sbin/root/temp/lib/libc.so.6

/usr/bin/roo/temp/lib/lic.so.6

6) $LD_LIBRARY_PATH / R(A) / X

/opt/root/temp/lib/libc.so.6

/usr/games/root/temp/lib/libc.so.6

对相对路径"./libddd.so"的搜索顺序是

1) X

./libddd.so

2) Bn / X

/home/evan/./libddd.so

/home/peter/./libddd.so

3) Bn / F(X)

/home/evan/libddd.so

/home/peter/libddd.so

4) $PATH / X

/usr/sbin/./libddd.so

/usr/bin/./libddd.so

5) $LD_LIBRARY_PATH / X

/opt/./libddd.so

/usr/games/./libddd.so

从上面看到,对绝对路径和相对路径都有一步是采用文件名和solib-search-path拼接来查找(绝对路径的第4步和相对路径的第3步),所以只要用set solib-search-path设置了每一个库文件所在的直接目录,那么就能保证每一个库都能被找到。

4. 查看so库的加载路径是否正确可使用info sharedlibrary命令,如果已找到对应的文件则其From和To的加载地址会有值,并且右边路径显示的就是加载文件所在的地址,这个时候,如果so库文件含符号信息,则syms Read的值为Yes,否则为No,如果未找到对应的文件则From和To的地址为空,syms Read的值为No,此时右边路径显示的是Coredump文件中库文件路径。

5. 如果在Coredump文件载入过程中,或者info sharedlibrary命令时,出现" Cannot access memory at address 0x87000069 "这样的错误,这通常是由于所使用的主执行文件("file"命令或"exec-file"命令)与Coredump文件("core"命令或"core-file"命令)两者不匹配导致的。这个时候应检查主执行文件是否是生成Coredump时所用的主执行文件,只要差一点,就可能导致动态库信息读取错误。

6. 如果载入过程中有" warning: .dynamic section for "/lib/librt.so.1" is not at the expected address (wrong library or version mismatch?) "这样的提示,这通常是库搜索路径设置错误,GDB载入了错误的库文件导致的。这时,应使用info sharedlibrary命令查看相应库的载入路径,并使用set sysroot或set solib-search-path修改搜索路径来将错误的库修正到正确的路径上。

7. 在设置了搜索路路径后,最好先用file命令载入主执行文件,再用core命令载入Coredump文件,这样才能保证正确载入库的符号表。否则,如果先用core命令载入Coredump文件,再用file命令载入主执行文件,那么会造成库只是被搜索但并不载入符号(使用info sharedlibrary命令可以看到),这时再重新执行一次core命令就可以了。

8. 一个实际的搜索例子:

当前目录为/home

主执行文件在/home/evan/gdbso/mips/gdbso

Core文件在/home/evan/gdbso/mips/Coredump

所用动态库与拷贝到主执行文件同一目录下

编译主执行文件所用的标准库被拷贝到主执行文件的lib目录下/home/evan/gdbso/mips/lib/libxxx.so

进入GDB,用file命令载入主执行文件:

evan@ubunu:/home$ mips-linux-gnu-gdb
...
(gdb) file evan/gdbso/mips/gdbso
Reading symbols from /home/evan/gdbso/mips/gdbso...done.
(gdb) info sharedlibrary 
No shared libraries loaded at this time.

可以看到只载入了主执行文件时,是无法得到动态库信息的。

再用core命令载入Coredump文件:

(gdb) core evan/gdbso/mips/Coredump
...
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address (wrong library or version mismatch?)
...
(gdb) info sharedlibrary 
From        To          Syms Read   Shared Object Library
0x2aad98c0  0x2aadd6d8  Yes         /lib/librt.so.1
0x2aaf3460  0x2ab0db98  Yes         /lib/libm.so.6
0x2ab7e2e0  0x2ab89b28  Yes         /lib/libpthread.so.0
0x2abba9a0  0x2acb2bd8  Yes         /lib/libc.so.6
0x2ad06a40  0x2ad07988  Yes         /lib/libdl.so.2
                        No          /lib/ld.so.1
                        No          ./libddd.so
(gdb) 

在同时有了主执行文件和Coredump文件后,用info sharedlibrary就可以看到动态库信息了。但在载入过程中有库版本不匹配的提示。通过info sharedlibrary也看到GDB错误地载入了系统中自带的标准库。

我们将绝对路径设置到一个不存在的目录来看看Coredump中保存的原始路径名:

(gdb) set sysroot /noexist
...
(gdb) info sharedlibrary 
From        To          Syms Read   Shared Object Library
                        No          /lib/librt.so.1
                        No          /lib/libm.so.6
                        No          /lib/libpthread.so.0
                        No          /lib/libc.so.6
                        No          /lib/libdl.so.2
                        No          /lib/ld.so.1
                        No          ./libddd.so
(gdb) 

Coredump中保存的原始路径名为/lib/librt.so.1,为了让GDB使用正确的库/home/evan/gdbso/mips/lib/librt.so.1,只需要将绝对路径前缀设置为/home/evan/gdbso/mips即可,这里设置为evan/gdbso/mips来演示效果:

(gdb) set sysroot evan/gdbso/mips
...
(gdb) info sharedlibrary 
From        To          Syms Read   Shared Object Library
0x2aad98c0  0x2aade270  Yes         evan/gdbso/mips/lib/librt.so.1
0x2aaf3110  0x2ab31b70  Yes         evan/gdbso/mips/lib/libm.so.6
0x2ab7e320  0x2ab8e620  Yes         evan/gdbso/mips/lib/libpthread.so.0
0x2abba6a0  0x2accc3f0  Yes         evan/gdbso/mips/lib/libc.so.6
0x2ad06b50  0x2ad07c70  Yes         evan/gdbso/mips/lib/libdl.so.2
0x2aaa8810  0x2aac2e40  Yes         evan/gdbso/mips/lib/ld.so.1
                        No          ./libddd.so
(gdb) 

可以看到,GDB已经正确地载入了绝对路径。但相对路径"./libddd.so"还没有找到,为了使用/home/evan/gdbso/mips/libddd.so,设置库搜索路径包含/home/evan/gdbso/mips即可。为了查看效果,这里还添加了一个不存在的搜索路径:

(gdb) set solib-search-path /noexist:/home/evan/gdbso/mips
...
(gdb) info sharedlibrary 
From        To          Syms Read   Shared Object Library
0x2aad98c0  0x2aade270  Yes         evan/gdbso/mips/lib/librt.so.1
0x2aaf3110  0x2ab31b70  Yes         evan/gdbso/mips/lib/libm.so.6
0x2ab7e320  0x2ab8e620  Yes         evan/gdbso/mips/lib/libpthread.so.0
0x2abba6a0  0x2accc3f0  Yes         evan/gdbso/mips/lib/libc.so.6
0x2ad06b50  0x2ad07c70  Yes         evan/gdbso/mips/lib/libdl.so.2
0x2aaa8810  0x2aac2e40  Yes         evan/gdbso/mips/lib/ld.so.1
0x2ad1a590  0x2ad1a770  Yes         /home/evan/gdbso/mips/libddd.so
(gdb) 

可以看到,所有的库都找到正确的路径了,Syms也被正确地载入。

来源:http://blog.csdn.net/_xiao/article/details/23289971

GDB动态库搜索路径的更多相关文章

  1. 【转载】Linux动态库搜索路径的技巧

    转自:http://soft.chinabyte.com/os/232/11488732_2.shtml 众所周知,Linux动 态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都 ...

  2. Linux动态库搜索路径的技巧

    众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径 ...

  3. Linux 静态库与动态库搜索路径设置详解【转】

    原文地址:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅 ...

  4. Linux 静态库与动态库搜索路径设置详解

    转载:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅限于 ...

  5. Windows平台LoadLibrary加载动态库搜索路径的问题

    一.背景 在给Adobe Premiere/After Effects等后期制作软件开发第三方插件的时候,我们总希望插件依赖的动态库能够脱离插件的位置,单独存储到另外一个地方.这样一方面可以与其他程序 ...

  6. linux添加动态库搜索路径

    在有时运行程序出现动态库找不着的问题,而明明装了的.这时候可能是没有将相应的路径添加到系统中去. 具体说:cd /etc/ld.so.conf.d/ 可以发现里面有一堆*.conf的文件 我们要做的就 ...

  7. 环境变量,include搜索路径,lib库搜索路径

    环境变量 系统环境变量 我们知道,我们经常要设置一些环境变量,系统环境变量我们非常容易理解.其实我们在windows中经常容易接触.其实环境变量是一个非常广泛的一个概念,它与web应用程序中的web. ...

  8. Linux下动态库查找路径的问题

    说到和动态库查找路径相关的问题,总体上可以分为两类:    第一类: 通过源代码编译程序时出现的找不到某个依赖包的问题,而如果此时你恰好已经按照它的要求确确实实.千真万确.天地良心地把依赖库给装好了, ...

  9. 谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH

    谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH  PKG_CONFIG_PATH 转载自:http://blog.chinaunix.net/xmlrpc.ph ...

随机推荐

  1. python——周边

    Pythonic的禅意 import this python是用c语言写的.传说python不止有C语言实现,还有java实现,还有python实现的python,甚至还有js实现的python. p ...

  2. Titanium vs PhoneGap

    http://mobile.51cto.com/Titanium-318049.htm http://www.ibm.com/developerworks/cn/opensource/os-titan ...

  3. tip use view.isineditmode() in your custom views to skip code when shown in eclipse

    tip use view.isineditmode() in your custom views to skip code when shown in eclipse

  4. HttpClient -- 血的教训

    HttpClient -- 血的教训 千万别用httpClient 不支持httpVersion2.0 因为这个导致项目重做

  5. powerdesigner的学习

    1  powerdesigner的层次 使用过eclipse作为java开发的都知道,workspace是顶级目录,一次只能打开一个,project是项目,位于workspace中,一个workspa ...

  6. java语法学习问题总结

    No.1:EnumTest No.2:Addition 在此程序中,学习了将文本框调用出来,文本框输入的数据都是String类型,所以用于计算时需要先进行转型,然后计算. No.3:TestDoubl ...

  7. flex css 布局

    http://www.w3cplus.com/css3/flexbox-basics.html

  8. Android开发指南-框架主题-安全和许可

    概述:Android操作系统是一个安全便捷的Linux系统,遵循Linux系统机制,允许多进程.为了进程间的数据共享和交互共用,设计"权限"这个名词,声明权限代表可使用此权限,未声 ...

  9. 转:SSL协议详解

    http://kb.cnblogs.com/page/162080/ 背景介绍    最近在看<密码学与网络安全>相关的书籍,这篇文章主要详细介绍一下著名的网络安全协议SSL. 在开始SS ...

  10. 4 Values whose Sum is 0

      Time Limit:15000MS     Memory Limit:228000KB     64bit IO Format:%I64d & %I64u Submit Status D ...