首页 > 其他分享 >gdb 加载动态库方法

gdb 加载动态库方法

时间:2023-04-21 10:58:55浏览次数:40  
标签:lib gdbso 路径 solib gdb evan mips 动态 加载

当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) 返回失败
 

博主注:在gdb中设置环境变量,如LD_LIBRARY_PATH可以通过以下gdb命令实现:

(gdb) set env LD_LIBRARY_PATH /tmp

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

 
  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也被正确地载入。

标签:lib,gdbso,路径,solib,gdb,evan,mips,动态,加载
From: https://www.cnblogs.com/lidabo/p/17339541.html

相关文章

  • 7.数组动态创建和函数
    动态创建函数动态函数一维数组动态赋值int*data=newint[3];//动态分配地址for(inti=0;i<3;i++){data[i]=1;cout<<data[i]<<"";}delete[]data;//释放分配的·地址 二维数组动态分配地址int**d......
  • Cesium加载广告牌(一)
    Cesium加载广告牌(一)在Cesium开发中需要加载图标等操作,这时候就需要使用Cesium中添加广告牌的功能,这里需要用到一个很重要的属性方法Entity()。在官方文档中,Entity的解释为:将多种形式的可视化实体聚合到单个高级对象中。它们可以手动创建并添加到Viewer实体中,也可以由数据源(如Czm......
  • 微信小程序加载第三方字体
    一、加载本地字体做小程序项目时,有时为了提升页面展示效果,会引入一些第三方字体,引入方式如下代码片段/*直接在app.css引入*/@font-face{font-family:"alifont";//是你封装的名字src:url('./static/css/subset-AlibabaPuHuiTiR.ttf')format('truetype');//你......
  • 动态研发的技术原理与2种模式
    最近在看一些移动开发的文章,很多都在反复讲动态更新这个概念,其实换种讲法就是热更新,既然很多地方都在讲,作为一名“躺平”的开发者,必须再深入了解下具体的原理和模式。动态机制及技术原理动态研发模式就是一种基于云端的移动应用开发方法,主要能让开发者快速构建和发布多端的移动应用......
  • m厌氧间歇发酵动态控制系统matlab仿真,对比PID控制和MPC控制
    1.算法描述        生物发酵过程,其中稀释速率和供料基质浓度可作为操作变量。出口的细胞浓度或生物浓度、基质浓度以及产品浓度是过程的状态变量。例如在生产酒精的发酵过程中,是酵母浓度,是葡萄糖浓度,而是乙醇浓度。假设发酵培养基是单一均相生长的有机体,则广泛采用的非构......
  • pyinstaller 打包时第三方模块与图片资源加载
    打包命令pyinstaller--onefile--windowed**.py 修改**.spec文件pathex=['/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/ddddocr'],datas=[('./images','images'),('/Library/Frameworks/Python.fram......
  • ONVIF网络摄像头(IPC)客户端开发—RTSP RTCP RTP加载H264视频流
    前言:RTSP,RTCP,RTP一般是一起使用,在FFmpeg和live555这些库中,它们为了更好的适用性,所以实现起来非常复杂,直接查看FFmpeg和Live555源代码来熟悉这些协议非常吃力,这里将它们独立出来实现,以便更好的理解协议。本文主要介绍RTSP,RTCP,RTP加载H264数据流。说明:(1)大华IPC摄像头作为服......
  • ONVIF网络摄像头(IPC)客户端开发—RTSP RTCP RTP加载AAC音频流
    前言:RTSP,RTCP,RTP一般是一起使用,在FFmpeg和live555这些库中,它们为了更好的适用性,所以实现起来非常复杂,直接查看FFmpeg和Live555源代码来熟悉这些协议非常吃力,这里将它们独立出来实现,以便更好的理解协议。本文主要介绍RTSP,RTCP,RTP加载AAC音频流。说明:(1)大华IPC摄像头作为服......
  • tomcat启动时,加载类
    有时候在开发Web应用的时候,需要tomcat启动后自动加载一个用户的类,执行一些初始化方法,如从数据库中加载业务字典到内存中,因此需要在tomcat启动时就自动加载一个类,或运行一个类的方法。可以采用在WEB-INF/web.xml中添加一个监听程序(ServletContextListener配置......
  • DyLoRA:使用动态无搜索低秩适应的预训练模型的参数有效微调
    又一个针对LoRA的改进方法:DyLoRA:Parameter-EfficientTuningofPretrainedModelsusingDynamicSearch-FreeLowRankAdaptationhttps://arxiv.org/pdf/2210.07558v2.pdfhttps://github.com/huawei-noah/KD-NLP/tree/main/DyLoRAPart1前言LoRA存在的问题:rank的值是固......