最近发现一个程序执行中报错,报错内容如下,这里对排查和修复方法做一个记录。

XXXX:symbol lookup error:/home/…/libpdfium.so:undefined
symbol:CRYPT_MD5Generate

先说结论,undefined symbol 是因为你的程序中使用了未实现的函数。

比方说你编译时只加入了头文件*.h,而函数实现部分.c,文件未编译进去,这时候就会出现undefined symbol。

还有一种情况是,在C++代码调用C语言代码也会导致出现undefined symbol,原因是C++支持函数重载,编译器在编译函数时会将函数类型也加到编译后的代码中,而C语言并不支持函数重载,编译后的代码不包含函数类型,一般只包含函数名,这就会导致*.h文件中定义的函数,找不到对应.c文件中的实现。

解决办法是在*.h文件中添加extern "C" {}将C语言的函数声明括起来即可。 更多信息参考:C++ extern “C”的作用详解

此外附上几个排查undefined symbol问题比较有用的命令。

编译生成动态链接库后,调用时出现:

# lichunhong @ lichunhong-ThinkPad-T470p in ~/Documents/src/effective_robotics_programming_with_ros-master/catkin_ws on git:lichunhong/dev x [18:54:05] C:127
$ rosrun path_plan PathPlanSimulation
/home/lichunhong/Documents/src/effective_robotics_programming_with_ros-master/catkin_ws/devel/lib/path_plan/PathPlanSimulation:
 symbol lookup error: /home/lichunhong/Documents/src/effective_robotics_programming_with_ros-master/catkin_ws/src/pathPlan/lib/libpathplan.so: 
 undefined symbol: _ZN12ninebot_algo10AprAlgoLog9instance_E

即 symbol lookup error: libpathplan.so: undefined symbol: _ZN12ninebot_algo10AprAlgoLog9instance_E

出现这种问题时,往往是链接时出现了问题,下面分3步解决

(1)使用file 命令查看 so库的架构,看看是否与平台一致

可以看到,当前so库架构为x86-64,可以在GNU/Linux平台下使用。平台与架构一致

# lichunhong @ lichunhong-ThinkPad-T470p in ~/Documents/src/motion_planner/bin on git:dev x [18:47:54] 
$ file libpathplan.so 
libpathplan.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, 
BuildID[sha1]=32ae641e73c547376df20ca94746fbf5507de415, not stripped

接下来,需要定位一下 undefined symbol的具体信息

(2)通过 ldd -r xxx.so 命令查看so库链接状态和错误信息

ldd命令,可以查看对应的可执行文件或库文件依赖哪些库,但可执行文件或库文件要求与操作系统的编译器类型相同,即电脑是X86的GCC编译器,那么无法通过ldd命令查看ARM交叉编译器编译出来的可执行文件或库文件。

如果想在Ubuntu等Linux宿主机上查看ARM交叉编译好的可执行程序和库文件的相关依赖关系,可以通过以下命令:
readelf -d xxx.so | grep NEEDED

# lichunhong @ lichunhong-ThinkPad-T470p in ~/Documents/src/effective_robotics_programming_with_ros-master/catkin_ws/src/pathPlan/lib on git:lichunhong/dev x [18:57:19] 
$ ldd -r libpathplan.so
	linux-vdso.so.1 =>  (0x00007ffec1bd8000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f186cc0a000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f186c901000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f186c6eb000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f186c321000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f186d27a000)
undefined symbol: pthread_create	(./libpathplan.so)
undefined symbol: _ZN12ninebot_algo10AprAlgoLog9instance_E	(./libpathplan.so)
undefined symbol: _ZN2cv3maxERKNS_3MatES2_	(./libpathplan.so)
undefined symbol: _ZN12ninebot_algo10AprAlgoLog8WriteLogE10LEVEL_TYPEPKcS3_z	(./libpathplan.so)
undefined symbol: _ZN2cv6dilateERKNS_11_InputArrayERKNS_12_OutputArrayES2_NS_6Point_IiEEiiRKNS_7Scalar_IdEE	(./libpathplan.so)
undefined symbol: _ZN2cvgtERKNS_3MatEd	(./libpathplan.so)
undefined symbol: _ZN2cv8fastFreeEPv	(./libpathplan.so)
undefined symbol: _ZN2cv3Mat5setToERKNS_11_InputArrayES3_	(./libpathplan.so)
undefined symbol: _ZN12ninebot_algo10AprAlgoLog9instance_E	(./libpathplan.so)

可以看到有好多 undefined symbol ,其中就有提到的 _ZN12ninebot_algo10AprAlgoLog9instance_E 错误

(3) 使用 c++filt symbol 定位错误在那个C++文件中

从上面的undefined symbol中,通过c++filt ,可以定位到大多是opencv的问题

# lichunhong @ lichunhong-ThinkPad-T470p in ~/Documents/src/effective_robotics_programming_with_ros-master/catkin_ws/src/pathPlan/lib on git:lichunhong/dev x [19:04:26] C:1
$ c++filt _ZN2cv7waitKeyEi
cv::waitKey(int)
 
# lichunhong @ lichunhong-ThinkPad-T470p in ~/Documents/src/effective_robotics_programming_with_ros-master/catkin_ws/src/pathPlan/lib on git:lichunhong/dev x [19:04:31] 
$ c++filt _ZN2cv3maxERKNS_3MatES2_
cv::max(cv::Mat const&, cv::Mat const&)
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐