ARM-Linux GDB调试Core文件动态库不能加载
一 本次试验环境gcc:arm-linux-gcc 4.5.1gdb:arm-linux-gdb 4.5.1 根据你编译时交叉编译工具链的版本编译相对应的gdb和gdbservergcc:arm-linux-gdbserver 4.5.1Qt:4.7.0Qt Creator: 2.8.0二 生成Core文件参考:三 拷贝目标机Core文件和可执行程序到开发主机上如本次试验的例子,我将core文件和
一 本次试验环境
gcc:arm-linux-gcc 4.5.1
gdb:arm-linux-gdb 4.5.1 根据你编译时交叉编译工具链的版本编译相对应的gdb和gdbserver
gcc:arm-linux-gdbserver 4.5.1
Qt:4.7.0
Qt Creator: 2.8.0
二 生成Core文件
三 拷贝目标机Core文件和可执行程序到开发主机上
如本次试验的例子,我将core文件和可执行程序拷贝到我的虚拟机目录为/home/yangtq/CBsic/testcoredump
四 使用arm-linux-gdb调试出现不能加载动态库
1)调试命令
arm-linux-gdb
2)载入可执行文件和core文件,在gdb环境中敲下列命令
file vlClient
core-file core
图片显示不能加载动态链接库12个,我们可以使用下列命令查看详细信息
info sharedlibrary
对于上图显示的动态链接库装载路径,表明在我们开发机上相应的目录中没有找到,我们可以通过设置sysroot,solib-absolute-prefix,solib-search-path参数来解决此问题。
五 GDB sysroot solib-absolute-prefix solib-search-path了解
5.1 sysroot,solib-absolute-prefix,solib-search-path定义
1)
set sysroot 与 set solib-absolute-prefix 是同一条命令,实际上,set sysroot是set solib-absolute-prefix 的别名
2)
set sysroot 或 set solib-absolute-prefix
set solib-absolute-prefix path
1)如果这一变量被设置,path将被作为任何绝对路径共享库的前缀
2)许多运行时载入到目标程序内存中的共享库,生成Core文件时的路径就是载入的绝对路径。
3)如果你使用“solib-absolute-prefix”查找共享库,设置的path应该和Core文件中显示的目标上有一样的路径
结构,比如第四步最后一张图中info sharedlibrary显示的/yctek/qt/lib/libQt*等。
那么你设置的path目录下也必须有yctek/qt/lib等目录结构,它只是用path替换了/yctek的根前缀(/)
show solib-absolute-prefix
1)显示当前共享库前缀的配置。
3)
set solib-search-path
set solib-search-path path
1)如果这一变量被设置,其中path是冒号分割的用来搜索共享库的目录的列表。
“solib-search-path”在“solib-absolute-prefix”定位库失败后使用,
或者库的路径是相对的,而不是绝对的。
如果你想使用“solib-search-path”代替“solib-absolute-prefix”,
确定“solib-absolute-prefix”设置的是不存在的目录,以阻止GDB查找宿主机上的库。
show solib-search-path
1)显示当前共享库查找路径的配置。
4)
set solib-search-path设置动态库的搜索路径,该命令可设置多个搜索路径,路径之间使用“:”隔开(在linux中为冒号,DOS和Win32中为分号)
5)
set solib-absolute-prefix 与 set solib-search-path 的区别:
总体上来说solib-absolute-prefix设置库的绝对路径前缀,只对绝对路径有效;而solib-search-path设置库的搜索路径,对绝对路径和相对路径均起作用。(编译器自动链接的so库多采用绝对路径)。
6)
set solib-absolute-prefix由于是路径前缀,所以只能设置一个路径,而solib-search-path可以设置多个搜索路径。在载入动态库信息时CoreDump会碰到两种路径:绝对路径和相对路径。
编译时链接的库通常是绝对路径,例如"/yctek/qt/lib/libQtCore.so.4"、"/yctek/qt/lib/libQtGui.so.4"等,此时在Core文件中也同样保存为绝对路径;
而程序用dlopen函数载入的so库可能使用相对路径,例如"./libddd.so",此时Core文件原封不动地保存相同的路径。
5.2 sysroot,solib-absolute-prefix,solib-search-path作用规则
A | /home/yangtq/CBsic/testcoredump/vllib | Rt(A) | home/yangtq/CBsic/testcoredump/vllib | ||||
Bn | /home/yangtq/vllib |
| |||||
C | /yctek/qt/lib/libQtCore.so.4 | Fn(C) | libQtCore.so.4 | ||||
绝对路径 | |||||||
A/C | /home/yangtq/CBsic/testcoredump/vllib/yctek/qt/lib/libQtCore.so.4 | ||||||
Rt(A)/C | home/yangtq/CBsic/testcoredump/vllib/yctek/qt/lib/libQtCore.so.4 | ||||||
Bn/Rt(A)/C | /home/yangtq/vllib/home/yangtq/CBsic/testcoredump/vllib/yctek/qt/lib/libQtCore.so.4 | ||||||
Bn/Fn(C) | /home/yangtq/vllib/libQtCore.so.4 |
为便于表述,
- 用A表示set solib-absolute-prefix设置的路径;Rt(A)表示A去掉根前缀后的路径(即去掉前缀“/”符号)
- 用Bn表示set solib-search-path设置的每一条路径
- 用C表示Core文件中保存的库路径,即待搜索的库文件路径;Fn(C)表示C中去掉目录后的文件名(路径最后“/”符号后的字符串)。
1. 对绝对路径,搜索顺序是:(/yctek/qt/lib/libQtCore.so.4)
1) A/C // 先添加solib-absolute-prefix前缀进行搜索,成功则不再继续,否则继续2)
2) Rt(A)/C // 再把1)的根前缀去掉后进行搜索,成功则不再继续,否则继续3)
3) Bn/Rt(A)/C // 再在2)的基础上逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续4)
4) Bn/Fn(C) // 再使用Fn(C)中的文件名(去掉目录段),并逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续5)
5) $PATH/Rt(A)/C // 在2)的基础上使用环境变量$PATH中的每条路径进行搜索,成功则不再继续,否则继续6)
6) $LD_LIBRARY_PATH/Rt(A)/C // 在2)的基础上使用环境变量$LD_LIBRARY_PATH中的每条路径进行搜索,成功则不再继续,否则继续7)
7) 返回失败
2.对相对路径,搜索顺序是:(./libddd.so)
1) C // 直接使用原始路径进行搜索,成功则不再继续,否则继续2)
2) Bn/C // 再逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续3)
3) Bn/Fn(C) // 再使用Fn(C)中的文件名(去掉目录段),并逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续4)
4) $PATH / C // 再使用环境变量$PATH中的每条路径进行搜索,成功则不再继续,否则继续5)
5) $LD_LIBRARY_PATH / C // 再使用环境变量$LD_LIBRARY_PATH中的每条路径进行搜索,成功则不再继续,否则继续6)
6) 返回失败
3.总结
从上面看到,对绝对路径和相对路径都有一步是采用文件名和solib-search-path拼接来查找(绝对路径的第4步和相对路径的第3步),所以只要用set solib-search-path设置了每一个库文件所在的直接目录,那么就能保证每一个库都能被找到。
5.3 sysroot,solib-absolute-prefix,solib-search-path用法
set solib-absolute-prefix /home/yangtq/CBsic/testcoredump/vllib
set solib-search-path /home/yangtq/vllib:/home/yangtq/vllib1
5.4 sysroot,solib-absolute-prefix,solib-search-path实操
5.4.1 如果目标机的root文件系统是在开发机上构建的
1)示例开发机上构建的根文件系统目录为:
/home/yangtq/ArmPlatform/ycArm/ycfilesystemmake/yc335x-system
2)
1.arm-linux-gdb
2.file vlClient //载入可执行文件
3.core-file core //载入core文件
4.core-file //可以先清除载入的core文件,避免弄错的话
5.core-file core //载入core文件
6.info sharedlibrary //查看原始动态链接库绝对路径
7.set sysroot /home/yangtq/ArmPlatform/ycArm/ycfilesystemmake/yc335x-system //设置绝对路径前缀
8.info sharedlibrary //查看是否成功
5.4.2 如果开发机上没有目标机上的库函数
1)在目标机上把info sharedlibrary中显示的库文件拷贝到一个文件夹如示例的vllib
2)然后压缩 vllib.tar
tar -cvf vllib.tar vllib
3.u盘或其它工具拷贝到开发机上
4.解压到测试目录如示例的/home/yangtq/CBsic/testcoredump
tar -xvf /u盘/vllib.tar -C /home/yangtq/CBsic/testcoredump
5.设置solib-search-path
1.arm-linux-gdb
2.file vlClient //载入可执行文件
3.core-file core //载入core文件
6.info sharedlibrary //查看原始动态链接库绝对路径
7.set solib-search-path /home/yangtq/CBsic/testcoredump/vllib //设置绝对路径前缀
8.info sharedlibrary //查看是否成功
六 使用GDB命令 bt定位段错误发生位置
1)第五步设置成功之后我就可以使用bt或where命令查看发生段错误的堆栈调用了,然后以此来判断我们的程序死在哪里
更多推荐
所有评论(0)