set solib-search-path用于gdb中指定动态库搜索路径,仅影响相对路径及剥离根目录后的绝对路径查找(如/lib/libc.so.6转为lib/libc.so.6再搜索),需用冒号分隔多路径、在加载core后执行bt前设置,并配合info sharedlibrary验证实际加载的so文件。

gdb里怎么用set solib-search-path加载动态库
core文件分析失败,常见原因是GDB找不到对应的.so文件——尤其是程序用dlopen加载的相对路径库(如"./libnet.so")或交叉编译环境下的系统库。此时必须手动告诉GDB去哪找,set solib-search-path就是干这个的。
它只影响「相对路径」和「从绝对路径中剥离根目录后」的库查找(比如/lib/libc.so.6会被转成lib/libc.so.6再搜索),不覆盖set sysroot对绝对路径的前缀作用。
实操要点:
-
set solib-search-path接受多个路径,用冒号:分隔(Linux/macOS),不能有空格 - 路径末尾不加
/,GDB会自动拼接 - 必须在
core加载后、执行bt前设置,否则栈帧里函数名仍显示为?? - 如果路径下有同名so但版本不对,GDB可能静默加载错的,建议用
info sharedlibrary确认实际加载的是哪个文件
示例:
gdb ./myapp ./core.1234 (gdb) set solib-search-path /opt/staging/lib:/home/dev/sysroot/lib (gdb) bt #0 0x0000ffff8a21234c in ?? () #1 0x0000ffff8a215678 in my_handler () at handler.c:42
为什么set solib-search-path不生效
最常踩的坑是:你以为它能“补全”任意路径,但它其实只参与特定阶段的搜索链。GDB查一个库X时,按顺序尝试:
-
solib-absolute-prefix+X(仅当X是绝对路径) - 去掉
X开头/后的路径(即R(A))+X - 每个
solib-search-path路径 +R(A)+X - 每个
solib-search-path路径 +F(X)(只取文件名)
也就是说,如果你的core里记录的是/usr/local/lib/libxxx.so,而你只设了solib-search-path /opt/lib,那GDB根本不会去/opt/lib/libxxx.so找——它先尝试/opt/lib/usr/local/lib/libxxx.so,显然不存在。
解决办法:
- 用
readelf -d ./myapp | grep NEEDED和eu-readelf -n ./core.1234 | grep -A2 "NT_FILE"确认core里实际记录的库路径格式 - 若全是绝对路径,优先用
set sysroot /path/to/sysroot(等价于set solib-absolute-prefix) - 若含
./或../,才真正需要solib-search-path,且路径要对应到这些相对路径的“基准目录”
嵌入式交叉调试时solib-search-path怎么配
arm/aarch64等交叉场景下,solib-search-path几乎必设,因为目标机的/lib在主机上并不存在。典型组合是:
-
set sysroot /path/to/arm-sysroot—— 覆盖/lib/ld-linux.so.3这类绝对路径系统库 -
set solib-search-path /path/to/project/libs:/path/to/sdk/lib—— 覆盖dlopen("libcustom.so")这种无路径名或相对路径的库
注意:sysroot路径必须真实存在且结构完整(含lib/、usr/lib/等子目录),否则sysroot本身就会失效;而solib-search-path里的路径只要包含目标so文件即可,不要求目录结构一致。
验证是否生效:
(gdb) info sharedlibrary From To Syms Read Shared Object Library 0x0000ffff8a1f0000 0x0000ffff8a22a000 Yes /path/to/arm-sysroot/lib/libc.so.6 0x0000ffff8a230000 0x0000ffff8a245000 Yes /path/to/project/libs/libcustom.so
和LD_LIBRARY_PATH、PATH有什么区别
solib-search-path是GDB内部机制,只影响GDB自己解析core时的库定位,完全不依赖宿主机环境变量。即使你在shell里unset LD_LIBRARY_PATH,只要GDB里设了solib-search-path,照样能加载。
反过来说,如果只改了LD_LIBRARY_PATH却没在GDB里设solib-search-path,GDB也看不到——它根本不读这个变量。
真正容易混淆的是set environment LD_LIBRARY_PATH,这个命令是让GDB在run可执行文件时透传给子进程用的,对core分析毫无作用。
所以结论很直接:分析core时,忘掉LD_LIBRARY_PATH和PATH,只管set sysroot和set solib-search-path。
最麻烦的情况是core里混用了绝对路径、相对路径、以及不同构建阶段的安装路径——这时候得靠info proc mappings和cat /proc/$(pidof myapp)/maps(如果还能跑)交叉比对内存地址段,再反推该用哪个路径前缀。这种细节往往被忽略,但恰恰是定位不到符号的根本原因。











