linux下进行C/C++开发时经常需要使用nm,objdump,ldd工具来分析定位问题,本篇文章就对其做个总结:
1.测试程序
TestSo.h
#pragma once
#include <iostream>
extern "C" int CTypeAdd(int x, int y);
extern "C" int CTypeSub(int x, int y);
int TestAdd(const int &a, const int &b);
int TestSub(const int &a, const int &b);
class TestClass {
public:
TestClass();
~TestClass();
int getIvalue();
std::string getSvalue();
void showValue();
private:
int m_iValue;
std::string m_sValue;
};
TestSo.cpp
#include "TestSo.h"
int CTypeAdd(int x, int y) {
return x + y;
}
int CTypeSub(int x, int y) {
return x - y;
}
int TestAdd(const int &a, const int &b) {
return a + b;
}
int TestSub(const int &a, const int &b) {
return a - b;
}
TestClass::TestClass() {
m_iValue = 110;
m_sValue = "My Test So";
}
TestClass::~TestClass() {
}
int TestClass::getIvalue() {
return m_iValue;
}
std::string TestClass::getSvalue() {
return m_sValue;
}
void TestClass::showValue() {
std::cout << m_sValue.c_str() << " " << m_iValue << std::endl;
}
main.cpp
#include <iostream>
#include "TestSo.h"
using namespace std;
int main() {
std::cout << "start main ..." << std::endl;
std::cout << "========== C type call ==========" << std::endl;
std::cout << CTypeAdd(1, 2) << " " << CTypeSub(1, 2) << std::endl;
std::cout << "========== C++ type call ==========" << std::endl;
std::cout << TestAdd(111, 222) << " " << TestSub(111, 222) << std::endl;
TestClass test;
test.showValue();
std::cout << test.getIvalue() << " " << test.getSvalue() << std::endl;
return 0;
}
生成so动态库:
g++ -std=c++11 -g TestSo.cpp -fPIC -shared -o libTestSo.so
生成可执行程序:
g++ -std=c++11 main.cpp -L. -lTestSo -o main
程序运行结果如下:
export LD_LIBRARY_PATH=.
./main
程序目录结构如下:
2.objdump
objdump是一个gcc工具, 可以查看目标文件或者可执行文件的各个段信息。可以显示有关文件的大量不同信息。 objdump也可以显示符号,并且在联机帮助页中明确指出“这与nm程序提供的信息类似,但显示格式不同”
常用命令:objdump -tT libTestSo.so
objdump -tT libTestSo.so 显示如下:
libTestSo.so: file format elf64-x86-64
SYMBOL TABLE:
00000000000001c8 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
00000000000001f0 l d .gnu.hash 0000000000000000 .gnu.hash
0000000000000260 l d .dynsym 0000000000000000 .dynsym
00000000000005c0 l d .dynstr 0000000000000000 .dynstr
0000000000000992 l d .gnu.version 0000000000000000 .gnu.version
00000000000009e0 l d .gnu.version_r 0000000000000000 .gnu.version_r
0000000000000a60 l d .rela.dyn 0000000000000000 .rela.dyn
0000000000000b80 l d .rela.plt 0000000000000000 .rela.plt
0000000000000c88 l d .init 0000000000000000 .init
0000000000000ca0 l d .plt 0000000000000000 .plt
0000000000000d60 l d .plt.got 0000000000000000 .plt.got
0000000000000d70 l d .text 0000000000000000 .text
0000000000001034 l d .fini 0000000000000000 .fini
000000000000103d l d .rodata 0000000000000000 .rodata
000000000000104c l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr
00000000000010c0 l d .eh_frame 0000000000000000 .eh_frame
00000000000012a4 l d .gcc_except_table 0000000000000000 .gcc_except_table
0000000000201dd0 l d .init_array 0000000000000000 .init_array
0000000000201de0 l d .fini_array 0000000000000000 .fini_array
0000000000201de8 l d .dynamic 0000000000000000 .dynamic
0000000000201fc8 l d .got 0000000000000000 .got
0000000000202000 l d .got.plt 0000000000000000 .got.plt
0000000000202070 l d .data 0000000000000000 .data
0000000000202080 l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000000d70 l F .text 0000000000000000 deregister_tm_clones
0000000000000db0 l F .text 0000000000000000 register_tm_clones
0000000000000e00 l F .text 0000000000000000 __do_global_dtors_aux
0000000000202080 l O .bss 0000000000000001 completed.7698
0000000000201de0 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry
0000000000000e40 l F .text 0000000000000000 frame_dummy
0000000000201dd0 l O .init_array 0000000000000000 __frame_dummy_init_array_entry
0000000000000000 l df *ABS* 0000000000000000 TestSo.cpp
000000000000103d l O .rodata 0000000000000001 _ZStL19piecewise_construct
0000000000202081 l O .bss 0000000000000001 _ZStL8__ioinit
0000000000000fd6 l F .text 0000000000000049 _Z41__static_initialization_and_destruction_0ii
000000000000101f l F .text 0000000000000015 _GLOBAL__sub_I_TestSo.cpp
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
00000000000012a0 l O .eh_frame 0000000000000000 __FRAME_END__
0000000000000000 l df *ABS* 0000000000000000
0000000000202078 l O .data 0000000000000008 DW.ref.__gxx_personality_v0
000000000000104c l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR
0000000000202000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000202080 l O .data 0000000000000000 __TMC_END__
0000000000202070 l O .data 0000000000000000 __dso_handle
0000000000201de8 l O .dynamic 0000000000000000 _DYNAMIC
0000000000000e70 g F .text 000000000000001c _Z7TestAddRKiS0_
0000000000000000 F *UND* 0000000000000000 _ZNSolsEi@@GLIBCXX_3.4
0000000000000f30 g F .text 0000000000000010 _ZN9TestClass9getIvalueEv
0000000000000000 w *UND* 0000000000000000 __gmon_start__
0000000000001034 g F .fini 0000000000000000 _fini
0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 F *UND* 0000000000000000 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4
0000000000000000 F *UND* 0000000000000000 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21
0000000000000e4a g F .text 0000000000000014 CTypeAdd
0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 F *UND* 0000000000000000 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
0000000000000f40 g F .text 000000000000002d _ZN9TestClass9getSvalueB5cxx11Ev
0000000000000000 w F *UND* 0000000000000000 __cxa_finalize@@GLIBC_2.2.5
0000000000000f6e g F .text 0000000000000068 _ZN9TestClass9showValueEv
0000000000000f10 g F .text 000000000000001f _ZN9TestClassD1Ev
0000000000000e5e g F .text 0000000000000012 CTypeSub
0000000000000eaa g F .text 0000000000000065 _ZN9TestClassC2Ev
0000000000000000 O *UND* 0000000000000000 _ZSt4cout@@GLIBCXX_3.4
0000000000000e8c g F .text 000000000000001e _Z7TestSubRKiS0_
0000000000000f10 g F .text 000000000000001f _ZN9TestClassD2Ev
0000000000202080 g .bss 0000000000000000 __bss_start
0000000000000eaa g F .text 0000000000000065 _ZN9TestClassC1Ev
0000000000202088 g .bss 0000000000000000 _end
0000000000000000 F *UND* 0000000000000000 _ZNSolsEPFRSoS_E@@GLIBCXX_3.4
0000000000000000 F *UND* 0000000000000000 _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv@@GLIBCXX_3.4.21
0000000000000000 F *UND* 0000000000000000 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4
0000000000000000 F *UND* 0000000000000000 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_@@GLIBCXX_3.4.21
0000000000202080 g .data 0000000000000000 _edata
0000000000000000 F *UND* 0000000000000000 __gxx_personality_v0@@CXXABI_1.3
0000000000000000 F *UND* 0000000000000000 _Unwind_Resume@@GCC_3.0
0000000000000c88 g F .init 0000000000000000 _init
0000000000000000 F *UND* 0000000000000000 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc@@GLIBCXX_3.4.21
DYNAMIC SYMBOL TABLE:
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 _ZNSolsEi
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 _ZNSt8ios_base4InitC1Ev
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_atexit
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 _ZNSt8ios_base4InitD1Ev
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
0000000000000000 DO *UND* 0000000000000000 GLIBCXX_3.4 _ZSt4cout
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 _ZNSolsEPFRSoS_E
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_
0000000000000000 DF *UND* 0000000000000000 CXXABI_1.3 __gxx_personality_v0
0000000000000000 DF *UND* 0000000000000000 GCC_3.0 _Unwind_Resume
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc
0000000000000e70 g DF .text 000000000000001c Base _Z7TestAddRKiS0_
0000000000000f30 g DF .text 0000000000000010 Base _ZN9TestClass9getIvalueEv
0000000000000e4a g DF .text 0000000000000014 Base CTypeAdd
0000000000202088 g D .bss 0000000000000000 Base _end
0000000000202080 g D .data 0000000000000000 Base _edata
0000000000000f40 g DF .text 000000000000002d Base _ZN9TestClass9getSvalueB5cxx11Ev
0000000000000e5e g DF .text 0000000000000012 Base CTypeSub
0000000000000e8c g DF .text 000000000000001e Base _Z7TestSubRKiS0_
0000000000202080 g D .bss 0000000000000000 Base __bss_start
0000000000000c88 g DF .init 0000000000000000 Base _init
0000000000001034 g DF .fini 0000000000000000 Base _fini
0000000000000f6e g DF .text 0000000000000068 Base _ZN9TestClass9showValueEv
0000000000000f10 g DF .text 000000000000001f Base _ZN9TestClassD1Ev
0000000000000eaa g DF .text 0000000000000065 Base _ZN9TestClassC2Ev
0000000000000f10 g DF .text 000000000000001f Base _ZN9TestClassD2Ev
0000000000000eaa g DF .text 0000000000000065 Base _ZN9TestClassC1Ev
3.nm
nm是linux中用来列出目标文件的符号清单,也是一个gcc工具
常用命令:nm -AD libTestSo.so
常用的options:
-A 在每个符号信息的前面打印所在对象文件名称;
-C 输出demangle过了的符号名称;
-D 打印动态符号;
-l 使用对象文件中的调试信息打印出所在源文件及行号;使用 -l 时,必须保证你的对象文件中带有符号调式信息,这一般要求你在编译的时候指定一个 -g 选项,见 Linux:Gcc。
-n 按照地址/符号值来排序;
-u 打印出那些未定义的符号;
使用nm前,最好先用Linux的file查看对象文件所属处理器架构,然后再用相应交叉版本的nm工具。
so符号表中的U t d b r B含义
U:代表so中调用了这个接口,但没有具体实现
T:代表so中有该函数的具体实现代码
列出My.so中未定义的符号
nm -u libTestSo.so 显示如下:
libTestSo.so:0000000000202080 B __bss_start
libTestSo.so:0000000000000e4a T CTypeAdd
libTestSo.so:0000000000000e5e T CTypeSub
libTestSo.so: U __cxa_atexit
libTestSo.so: w __cxa_finalize
libTestSo.so:0000000000202080 D _edata
libTestSo.so:0000000000202088 B _end
libTestSo.so:0000000000001034 T _fini
libTestSo.so: w __gmon_start__
libTestSo.so: U __gxx_personality_v0
libTestSo.so:0000000000000c88 T _init
libTestSo.so: w _ITM_deregisterTMCloneTable
libTestSo.so: w _ITM_registerTMCloneTable
libTestSo.so: U _Unwind_Resume
libTestSo.so:0000000000000e70 T _Z7TestAddRKiS0_
libTestSo.so:0000000000000e8c T _Z7TestSubRKiS0_
libTestSo.so:0000000000000f30 T _ZN9TestClass9getIvalueEv
libTestSo.so:0000000000000f40 T _ZN9TestClass9getSvalueB5cxx11Ev
libTestSo.so:0000000000000f6e T _ZN9TestClass9showValueEv
libTestSo.so:0000000000000eaa T _ZN9TestClassC1Ev
libTestSo.so:0000000000000eaa T _ZN9TestClassC2Ev
libTestSo.so:0000000000000f10 T _ZN9TestClassD1Ev
libTestSo.so:0000000000000f10 T _ZN9TestClassD2Ev
libTestSo.so: U _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv
libTestSo.so: U _ZNSolsEi
libTestSo.so: U _ZNSolsEPFRSoS_E
libTestSo.so: U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc
libTestSo.so: U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_
libTestSo.so: U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev
libTestSo.so: U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
libTestSo.so: U _ZNSt8ios_base4InitC1Ev
libTestSo.so: U _ZNSt8ios_base4InitD1Ev
libTestSo.so: U _ZSt4cout
libTestSo.so: U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
libTestSo.so: U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
4.ldd
ldd用来打印或者查看程序运行所需的共享库,常用来解决程序因缺少某个库文件而不能运行的一些问题。ldd不是一个可执行程序,而只是一个shell脚本。
--help 获取指令帮助信息;
--version 打印指令版本号;
-d,–data-relocs 执行重定位和报告任何丢失的对象;
-r, --function-relocs 执行数据对象和函数的重定位,并且报告任何丢失的对象和函数;
-u, --unused 打印未使用的直接依赖;
-v, --verbose 详细信息模式,打印所有相关信息;
ldd libTestSo.so 显示如下:
linux-vdso.so.1 (0x00007fff00f73000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa90af47000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa90ad2f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa90a93e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa90a5a0000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa90b4d3000)
//关于linux下动态库的使用可以参考如下博客:
https://www.dandelioncloud.cn/article/details/1571390345416241154
// Linux下C语言系统编程学习的两个网站
https://www.yiibai.com/unix_system_calls/mmap.html
https://www.coolcou.com/linux-kernel/linux-kernel-references/linux-malloc-free-implementation-principle.html