2020-12-14 14:07:53
最近又碰到一个问题,明明在cmake中添加了依赖的库,但库中某些函数能链接上,某些找不到符号,后面才发现是因为 cmake中没写库路径的情况下,链接了/usr/lib中的同名的依赖库,而/usr/lib中的库是早期版本,所有有些函数没有,自然找不到符号定义。两种解决方法:
1 删除/usr/lib中的老版本,避免混淆,同时cmake中加上 动态库路径
2 直接用新版本的依赖库替换/usr/lib中的库
2018年6月20日15:42:38
记录下 最近发现的一个问题
说有两个函数的定义找不到,初步用 nm 看了下, 导出了这两个函数的,
用 nm -D xxx.so 看了下, 发现函数签名中 参数 的类型不太一样, 一个是 c++0x ::basic_string之类的,
但找不到那个错误 报出的 是 std::string
原来 使用 xxx.so 的代码是用 C++11 编译的, 但 导出函数的xxx.so库是 C++0x编译的, 两个不统一,
导致 string 被修饰得不一样,所以发生 未定义错误!
使用 C++11 编译后就好了!
比如 boost库
./bootstrap.sh --with-toolset=gcc --prefix=/usr/local
./b2 -j12 toolset=gcc variant=release link=shared threading=multi address-model=64 cxxflags=-std=c++11 install
首先这篇文章总结得不错
https://blog.csdn.net/stpeace/article/details/73302833
然后依然会碰到问题,这时候就要看具体的函数签名了
Name Mangling in C++
参考
以下内容来自:
http://blog.51cto.com/hipercomer/855223
nm工具的 --demangle 选项 可以让函数名可读
name demangling
C++的name mangling技术一般使得函数变得面目全非,而很多情况下我们在查看这些符号的时候并不需要看到这些函数name mangling之后的效果,而是想看看是否定义了某个函数,或者是否引用了某个函数,这对于我们调试程序是非常有帮助的。
所以需要一种方法从name mangling之后的符号变换为name mangling之前的符号,这个过程称之为name demangling.事实上有很多工具提供这些功能,最常用的就是c++filt命令,c++filt命令接受一个name mangling之后的符号作为输入并输出demangling之后的符号。例如:
[lichao@sg01 name_mangling]$ c++filt _Z9test_funcRiPKcdSsf
test_func(int&, char const*, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)
一般更常用的方法为:
[lichao@sg01 name_mangling]$ nm func.o | c++filt
0000000000000060 t global constructors keyed to _Z9test_funcRiPKcdSsf
U _Unwind_Resume
0000000000000022 t __static_initialization_and_destruction_0(int, int)
0000000000000000 T test_func(int&, char const*, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)
U std::allocator<char>::allocator()
U std::allocator<char>::~allocator()
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
0000000000000000 b std::__ioinit
U __cxa_atexit
U __dso_handle
U __gxx_personality_v0
0000000000000076 t __tcf_0
000000000000008e T main
另外使用nm命令也可以demangle符号,使用选项-C即可,例如:
[lichao@sg01 name_mangling]$ nm -C func.o
0000000000000060 t global constructors keyed to _Z9test_funcRiPKcdSsf
U _Unwind_Resume
0000000000000022 t __static_initialization_and_destruction_0(int, int)
0000000000000000 T test_func(int&, char const*, double, std::string, float)
U std::allocator<char>::allocator()
U std::allocator<char>::~allocator()
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
0000000000000000 b std::__ioinit
U __cxa_atexit
U __dso_handle
U __gxx_personality_v0
0000000000000076 t __tcf_0
000000000000008e T main
又到了Last but not least important的时候了,还有一个特别重要的接口函数就是__cxa_demangle(),此函数的原型为:
namespace abi {
extern "C" char* __cxa_demangle (const char* mangled_name,
char* buf,
size_t* n,
int* status);
}
用于将mangled_name所指向的mangled进行demangle并将结果存放在buf中,n为buf的大小。status存放函数执行的结果,返回值为0表示执行成功。
下面是使用这个接口函数进行demangle的例子:
/*
* Author: Chaos Lee
* Description: Employ __cxa_demangle to demangle a mangling function name.
* Date:2012/05/06
*
*/
#include<iostream>
#include<cxxabi.h>
using namespace std;
using namespace abi;
int main(int argc,char *argv[])
{
const char * mangled_string = "_Z9test_funcRiPKcdSsf";
char buffer[100];
int status;
size_t n=100;
__cxa_demangle(mangled_string,buffer,&n,&status);
cout<<buffer<<endl;
cout<<status<<endl;
return 0;
}
测试结果:
[lichao@sg01 name_mangling]$ g++ cxa_demangle.cpp -o cxa_demangle
[lichao@sg01 name_mangling]$ ./cxa_demangle
test_func(int&, char const*, double, std::string, float)
0