1. 今天在linux使用dlopen打开我编译的一个动态库时发现总是提示失败。
这时可以调用ldd命令查看编译部署的那个动态库依赖库有哪些,是否能找到。
我通过调用ldd ./libSyslogAticGatherTask.so (./libSyslogAticGatherTask.so是我编译好的一个动态库名)
发现提示linuxACE.so.6.0.3 => not found,如下图所示。
这里libACE.so.6.0.3应该是一个链接文件,但执行目录中没有这个链接文件,使用ln -s 命令创建一个软链接指向本地libACE-6.0.3.so即可:ln -s ./libACE.so.6.0.3 ./libACE-6.0.3.so
之后调用该动态链接库发现成功。
2. 今天编译另一个动态库,发现总是提示 undefined reference to `ACE_Service_Config::open(int, char**, char const*, bool, bool, bool)。这个函数是ACE的一个函数,但是这个动态库我已经放到指定目录下了,头文件也包含了。也是我进入ACE库目录,然后执行nm ./libACE.so.6.0.3查看它导出的函数,由于它导出的函数很多,我需要查看ACE_Service_Config::open函数的导出情况,于是执行nm ./libACE.so.6.0.3 | grep ACE_Service_Config | grep open,发现结果为:
000000000014d1a0 T _ZN18ACE_Service_Config6open_iEPKcS1_bbb
通过查ACE_Service_Config的源代码,发现这个函数是ACE_Service_Config::open_i函数,而open并没有导出,可是我纳闷了,这个代码是很老的代码,为什么之前的代码没有出现这个问题呢?于是我在生成环境运行nm ./libACE.so.6.0.3 | grep ACE_Service_Config | grep open,发现输出结果为:
0000000000190010 T _ZN18ACE_Service_Config4openEPKcS1_bbb
000000000018ff40 T _ZN18ACE_Service_Config4openEiPPcPKcbbb
000000000018f7d0 T _ZN18ACE_Service_Config6open_iEPKcS1_bbb
可以发现ACE_Service_Config::open函数导出了。之前的ACE库是我自己编译的,可能编译少了某些参数????把生成环境的ACE库放到我的目录下,代码编译成功。
3.1 调试正在运行的程序:
(1)使用ps aux | grep 程序名字:查看程序的进程号
(2)进入运行程序的Bin目录,然后执行gdb ./程序名
(3)进入gdb后,执行attach 程序进程号,即可调该程序
(4)下断点。在需要调试的地方打断点,由于我代码和运行的程序没有放在一个目录下,而且文件嵌套到很长的目录下,我需要使用dir目录设置相对目录。比如我需要在/home/svn/SAC100/trunk/Src/SAC-loginsight/Src/WebSvr/WebSvr.cpp下断点,而所有代码都嵌套到/home/svn/SAC100/trunk/Src/SAC-loginsight/Src了,我需要调用dir /home/svn/SAC100/trunk/Src/SAC-loginsight/Src设置相对目录,然后调用break WebSvr/WebSvr.cpp:209,在WebSvr/WebSvr.cpp处下断点。
(5)由于执行attach后,程序已经停下来了,需要执行c或continue让程序继续跑,当程序运行到WebSvr/WebSvr.cpp的209就停下来了。之后就可以单步调试代码了。
3.2 调试未执行的进程:(1)gdb ./程序名 (2) break 设置断点 (3)start开始调试 (4)continue:进入断点
4. gdb下修改代码路径:
在3中,调试代码时,我运行list main,发现总是提示
18 /data/svn/SAC100/trunk/Src/SAC-loginsight/Src/LAGatherServer/LAServer.cpp: No such file or directory
这是因为代码编译后我将代码的位置由/data/svn/SAC100修改为了/home/svn/SAC100,导致gdb总是报No such file or directory的错误,这时可以使用 set substitute-path设置路径替换规则:具体为:set substitute-path /data/svn/SAC100 /home/svn/SAC100,表示告诉gdb在看到/data/svn/SAC100的时候他会做自动替换成/home/svn/SAC100
set substitute-path用来修改相对路径,dir可以修改相对路径,具体可以参考《GDB源代码查找路径》 http://www.cnblogs.com/rickyk/p/4184860.html
5. cmake区分Debug和Release的方法:
在cmake中要编译debug模式的话,在CMakeLists.txt中添加如下两行
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb ")
SET(CMAKE_CXX_FLAGS_RELEASE "${ENV{CXXFLAGS} -O3 -Wall")
然后,在编译的时候,使用如下命令:
cmake -DCMAKE_BUILD_TYPE=Debug/Release path
第三个参数path是指项目的顶层路径
参考自: 《cmake Debug模式和Release模式》 http://blog.sina.com.cn/s/blog_6b02ec9a0100vahz.html
cmak总结:《linux下cmake编译C++工程之总结篇》 http://blog.csdn.net/boyxiaolong/article/details/24708201
《CMAKE的使用》 http://www.cnblogs.com/lidabo/p/3974305.html
6. 查看一个lib或bin是否带有调试信息的方法:
readelf -S libxxx.so |grep debug
《Linux下查看.so和可执行文件是否debug编译》 http://blog.csdn.net/gong_xucheng/article/details/23996145