SPDK/DPDK静态链接库踩坑

372 篇文章 4 订阅
345 篇文章 27 订阅

最近几天,尝试集成 SPDK 到我们的分布式系统里。为了避免对 SPDK 进行较大的改动,决定使用静态链接库,然后利用 SPDK 的 API 写 target。

编译 SPDK ,写一个简单的 target 例子都很顺利。但是当运行的时候,reactor 初始化分配mempool 一直错误。这个错误非常奇怪。第一时间怀疑 hugepage 空间不足,但是仔细看了一下,肯定是够的。

与此同时,发现同样的 DPDK 配置,SPDK 自带的 app 都可以初始化成功。从日志看一模一样,除了最后,自己写的初始化 mempool 失败,自带的可以成功。百思不得其解。

终于在 SPDK 的 issue 里看到了一个同样的错误

lib/event/reactor.c: 685:spdk_reactors_init: ERROR: spdk_event_mempool creation failed

根据反馈看,应该是 __attribute__ ((constructor)) 的问题。

经过在初始化路径上加上日志,发现就是这个问题。但是,为什么会这样呢?

这个扩展属性,不就是 gcc 默认就打开了么?

经过试验发现,原来,问题出在静态库上。

 $ cat foo.c 
#include <stdio.h>

__attribute__((constructor)) void foo()
{
    printf("foo called\n");
}

#include<stdio.h>
__attribute__((constructor)) void before_main() {
   printf("Before main\n");
}
__attribute__((destructor)) void after_main() {
   printf("After main\n");
}
int main(int argc, char **argv) {
   printf("In main\n");
   return 0;
}
 $ gcc -c foo.c
 $ ar rcs foo.a foo.o 
 $ gcc test.c foo.a
 $ ./a.out 
Before main
In main
After main

看一下动态库:

$ g++ -c foo.c -o foo.o -fPIC
$ g++ -shared -fPIC -o libfoo.so foo.o                                                                                                                                                                         1 ↵
$ g++ test.c -L. -lfoo                
$ export LD_LIBRARY_PATH=`pwd`                                                                                                                                                                               127 ↵
$ ./a.out                     
foo called
Before main
In main
After main

发现问题了,静态链接的 foo.c 里面的 __attribute__((constructor)) 并没有执行。动态链接后是正确的。

原因是linker在静态链接的时候,默认只链接用到的符号,没有用到的就不会拿过来了。对于上面的这种情况,__attribute__((constructor)) 属性的模块构造器就被 strip 了。

解决办法是使用-Wl,--whole-archive 和 --no-whole-archive 标签,显式的标识链接所有的符号。

 $ g++ test.c -Wl,--whole-archive foo.a -Wl,--no-whole-archive
root@31-216:~/smartx/spdk 
 $ ./a.out 
Before main
foo called
In main
After main
注意,-Wl,--whole-archive 中间不能有空格。

Done。

这个坑容易踩到,在此记录一下。

原文链接:https://zhuanlan.zhihu.com/p/42814326   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值