.so文件会改变类型吗?动态链接pmemobj_create报错Invalid argument求解
解决动态库链接PMDK函数后执行报错的问题
这个问题的核心原因是编译动态库libfoo.so时没有显式链接PMDK的libpmemobj库,导致运行时无法正确解析pmemobj_create函数的实现,进而引发参数传递异常或者符号解析错误,最终出现"Invalid argument"的报错。
修复步骤
1. 重新编译动态库,显式链接libpmemobj
编译动态库时,必须将PMDK的库链接进去,确保动态库能正确找到pmemobj_create的实现:
# 编译foo.c为位置无关目标文件(如果PMDK头文件不在系统默认路径,需添加-I指定路径) gcc -c -fPIC foo.c -o foo.o -I/path/to/pmdk/include # 编译动态库并链接libpmemobj(如果PMDK库不在系统默认路径,需添加-L指定路径) gcc -shared -o libfoo.so foo.o -lpmemobj -L/path/to/pmdk/lib
2. 链接test程序时确保依赖库可被找到
链接test程序时,需要指定自己的动态库和PMDK库的路径:
gcc test.o -o test -L./ -lfoo -lpmemobj
3. 运行时配置库路径(如果需要)
如果PMDK库或者你的libfoo.so不在系统默认的库搜索路径中,运行前需要设置LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=./:/path/to/pmdk/lib ./test
为什么静态链接正常,动态库会出问题?
当你直接编译foo.o和test.o链接成可执行文件时,链接器会在链接阶段直接将pmemobj_create的实现(从libpmemobj中)绑定到可执行文件中,所有符号都能正确解析,参数传递也不会有问题。
但编译动态库时,如果不显式链接libpmemobj,动态库中pmemobj_create会被标记为未定义符号。虽然最终链接test程序时链接器可能能找到系统中的libpmemobj,但运行时的延迟绑定机制可能导致函数地址解析异常,进而破坏参数栈,触发"Invalid argument"的错误。
你也可以通过nm libfoo.so | grep pmemobj_create检查动态库中的符号状态:如果输出是U pmemobj_create,说明该符号未定义,这就是问题所在;修复后应该能看到符号的正常绑定信息。
内容的提问来源于stack exchange,提问作者AetX
相关产品推荐
相关产品推荐

