1.命令简介 nm命令是GNU Binutils二进制工具集的一员,用于显示目标文件中的符号。如果没有为nm命令指出目标文件,则nm假定目标文件是a.out。 nm命令显示的符号类型。...对于这样的符号,动态链接器将确保在整个过程中只有一个使用此名称和类型的符号。 U 该符号在当前文件中是未定义的,即该符号定义在别的文件中。...对于全局变量来说,在定义它的文件中,其符号类型为B或D,在使用它的文件中,其类型为U。 v,V 该符号是一个弱符号。当弱定义符号与正常定义符号链接时,使用正常定义符号时不会出错。...当弱定义符号与正常定义符号链接时,使用正常定义符号时不会出错。当链接未定义的弱未定义符号时,该符号的值将以系统特定的方式确定,且不会出错。...该任选项仅对于动态目标(例如特定类型的共享库)有意义 -f|--format=:format可以选取bsd、sysv或posix,该选项在GNU的nm中有用,默认为bsd
nm:显示目标文件中的符号; objdump:打印目标文件中的详细信息; readelf:显示关于 ELF 目标文件的信息。...之前在调试makefile文件的时候,链接动态库出错:libsrcpbl.so: undefined reference to 'gcProgramName'。...当链接时,可能出现多个常用符号同名,这时如果该符号值都被定义了,那么会被当作未定义的引用(重定义错误)】 "D" "d" The symbol is in...【未定义的符号,需要从其它对象文件中链接进来】 "u" The symbol is a unique global symbol....【显示动态符号(只对动态目标有效,如特定类型的共享库)】 -f format --format=format Use the output format
链接就是把相似的段放在一起,先找到段的偏移地址,再找出符号在段中的偏移,这样可以确定符号在整个可执行程序中的地址。...,这种未定义的符号都是因为该目标文件中有关于他们的重定位项,在链接器扫描完所有的输入目标文件后,所有这种未定义的符号都应该能在全局符号表中找到,否则报符号未定义错误。...有一个编译选项叫函数级别链接,可以使得某个函数或变量单独保存在一个段里面,都链接器需要用到某个函数时,就将它合并到输出文件中,对于没用到的函数则将他们抛弃,减少空间浪费,但这会减慢编译和链接过程,GCC...-a 显示所有的符号 nm -D 显示动态符号 nm -u 仅显示没有定义的外部符号 nm -defined-only 仅显示定义的符号 关于符号的说明: 如果符号类型是小写的,表明符号是局部符号,...I:该符号对另一个符号的间接引用 N:debug符号 R:该符号位于只读数据区 T:该符号位于代码段 U:该符号在当前文件未定义,定义在别的文件中 ?
该任选项仅对于动态目标(例如特定类型的共享库)有意义 -f, --format=FORMAT FORMAT 可取值 bsd、sysv 或 posix,该选项在 GNU nm 中有用,默认为 bsd -...对于不记录符号大小的目标文件格式,此选项不起作用,除非使用了--size sort,在这种情况下,将显示计算的大小 -s, --print-armap 当列出库中成员的符号时,同时列出索引。...只有在启用插件支持的情况下构建了工具链时,此选项才可用 --size-sort 按符号大小排列 --special-syms 显示目标相关的具体特殊含义的符号。...这些符号通常被特定目标文件用于某些特殊处理,当包含在正常符号列表中时通常不起作用。...合成符号是链接器为各种目的创建的特殊符号,默认情况下不会显示它们,因为它们不是二进制文件源代码的一部分 --target=BFDNAME 指定系统默认格式以外的目标文件格式 以上就是nm命令的简单用法
U AAA::BBB(int) 运行期间出错: U 该符号未定义过,需要自其他对象文件中链接进来 上面代码在a.cpp中书写,编译生成文件a.obj,没有问题。...但按照之前的说明,连接时将错误,因为找不到符号_ABC。...因为名字_ABC对应的地址栏还空着 原因:对象(函数 类)没有定义 一般原因 1 该符号 没有在当前cpp文件中实现 2 没有引入其他cpp文件(库) 回答:声明和定义区别 声明:定义一个符号...1.nm -D libxxx.so 打印出符号信息。...说明 1 ldd动态库是不显示静态库的名称的 2 静态库的代码在编译过程中已经被载入可执行程序 1 nm工具可以打印出库中的涉及到的所有符号,这里的库既可以是静态的也可以是动态的。
比如用nm查看main.o和foo.o [zhxia@ess ~]$ nm main.o U FOO 00000000 T main U表示在main.o中符号foo是未定义的,需要从外部链接进来...有人说foo.o里还有一个未定义符号printf,这个到哪里去 找?gcc总是会有很多默认链接的库和链接选项,这其中包括c的标准库,而printf就在c标准库中。...@ess ~]$ nm foo.o 00000000 T FOO U printf 可以看出,main.o里需要用到符号名为foo_但foo.o里提供的是FOO——不匹配。...就像c++要用c库,也需要在声明这个库中的函数时使用extern “C”,使c++编译器在编译这个函数时生成的符号名是C风格而不是C++风格。...但是因为main.o中还有一个未定义符号s_stop,而gcc默认只链接和c相关的库,所以这时使用gcc -osample main.o foo.o会报错,大概就是说s_stop未定义(unreferenced
目标文件函数隐藏初探 场景如下,需要以.o形式(静态库形式),发布一个库,给其他代码集成。生成库mylib.o之后,使用nm查看,可以查看到很多函数符号。...但这么修改之后,库本身的其他源文件,也无法使用该函数了,因为c语言中的static是将函数的作用域限定在了函数所在的源文件。...objcopy修改符号表 生成库之后,可使用工具链中的 objcopy 工具,修改符号表,将内部函数都修改为本地函数,这样外部代码无法直接链接到这些函数,只能使用指定的函数。...生成库之后,可使用工具链中的 strip 工具,裁剪符号表,将不打算给外界使用的函数,直接从符号表中删除。...此时,外部函数尝试链接使用,会报错 gcc main.c mylib.o -o main /tmp/cccUN3aL.o:在函数‘main’中: main.c:(.text+0x1e):对‘inner_fun1
这看起来完全不讲道理啊,凭什么同样一个库,链接 .a 和链接 .o 的结果不一样?这就要说到,编译器在链接 .a 和 .o 时的行为差别了。...当编译器链接 .o 的时候,它会将 .o 中的符号全部链接进最终文件中,而当链接 .a 的时候,编译器则是会看当前链接结果是否存在未定义的符号,如果没有,那就不链接这个 .a 文件里面的内容。...而如果有需要链接的符号,则尝试在 .a 文件中查找,如果找到了,就链接这个 .a 里面的内容,否则就跳过。...另外,这顺便也能解释另一件事情:如果 main 依赖于 liba.a,而 liba.a 依赖于 libb.a,那么我们在链接库的时候就需要先链接 liba.a 再链接 libb.a,否则就会出现符号未定义的问题...此时 liba.a 中依赖于 libb.a 的符号就是未定义的了。
;nm查看库中包含那些函数、ar生成静态库,查看库中包含那些.o文件、ldd查看程序依赖的.so文件;gcc/g++与库相关的参数-L,-l,-fPIC,-shared;静态库链接时搜索过程;动态库链接时...: 有时候可能需要查看一个库中到底有哪些函数,nm工具可以打印出库中的涉及到的所有符号,这里的库既可以是静态的也可以是动态的。...nm列出的符号有很多, 常见的有三种:: T类:是在库中定义的函数,用T表示,这是最常见的; U类:是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示; W类:是所谓的“弱态”符号...在Linux下,动态库和静态库同事存在时,gcc/g++的链接程序,默认链接的动态库。...在这个过程中,链接器将维持三个集合: 集合E:可重定位目标文件(*.o文件)的集合。 集合U:未解析(未定义)的符号集,即符号表中UNDEF的符号。
前言 C/C++程序的许多同学被静态库的依赖折腾,因为默认情况下要求被依赖的库放在依赖它的库后面,当一个程序或共享库依赖的静态库较多时,可能会陷入解决链接问题的坑中。...,这个在使用静态库时需要注意,否则会报符号找不到问题。...gcc -c a.c ar cr liba.a a.o gcc -c b.c ar cr libb.a b.o 虽然libb.a使用到了liba.o中的一些函数,但并不会将它们的定义包含进来,所以在链接...,-soname=libqhttpd.so -rpath 增加共享库搜索路径 --retain-symbols-file表示不丢弃未定义的符号和需要重定位的符号 --export-dynamic 创建一个动态连接的可执行程序时...(函数是一种符号),链接器不会将它们链接进共享库和可执行程序。
; 使用xcrun命令,查看下main.o中的符号: xcrun nm -nm main.o 终端显示效果如下: (undefined) external _NSLog...; 链接器链接多文件时会创建符号表,用于记录所有已经定义和未定义的符号; 出现相同符号,会报错:"ld:dumplicate symbols"; 在其他目标文件里没有找到到符号,会报错:"Undefined...symbols"; 另外,链接器在整理函数的符号调用关系时,可以帮助我们理清那些函数没有被调用,并自动去除掉; 2.重定位 将变量名、函数名这些符号定义与一个内存位置关联起来; 因为只有通过了绑定,机器才知道需要操作什么内存地址...但是这些符号都会被记录下来,在运行时再通过dlopen和dlsym动态链接绑定; 动态链接:作用于运行时,这样的优势在于:诸多类似UIKit这样的共享库将不必包含在每一个App包里。...比如:我们使用到的UIKit系统库,等到点击App真正开始运行之前,才会去链接依赖的UIKit,链接完成再运行App;
nm 作用:nm 命令是 linux 下自带的特定文件分析工具,一般用来检查分析二进制文件、库文件、可执行文件中的符号表,返回二进制文件中各段的信息,查看二进制目标文件的符号,主要就是函数名称以及全局变量...中的程序符号表 nm XXX # 查看所有符号,会打印出符号来源哪个地方 nm -nm XXX # 找到未定义的符号,也就是外部符号 nm -u XXX 前面我们曾经查看过xcodebuild的符号...,其中全部的类型包括: A 该符号的值在今后的链接中将不再改变; B 该符号放在 BSS 段中,通常是那些未初始化的全局变量; D 该符号放在普通的数据段中,通常是那些已经初始化的全局变量; T 该符号放在代码段中...,通常是那些全局非静态函数; U 该符号未定义过,需要自其他对象文件中链接进来; W 未明确指定的弱链接符号;同链接的其他对象文件中有它的定义就用上,否则就用一个系统特别指定的默认值。...-m 变更成员文件在备存文件中的次序。 -p 显示备存文件中的成员文件内容。 -q 将问家附加在备存文件末端。 -r 将文件插入备存文件中。 -t 显示备存文件中所包含的文件。
-b :指定目标代码输入文件的格式 -Bstatic:只使用静态库 -Bdynamic:只使用动态库 -Bsymbolic:把引用捆绑到共享库中的全局符号 -c <MRI-commandfile...脚本命令“FORCE_COMMON_ALLOCATION”具有相同的效果 -defsym:在输出文件中创建指定的全局符号 -demangle:在错误消息中还原符号名称 -e :使用指定的符号作为程序的初始执行点...-E,--export-dynamic:对于ELF格式文件,创建动态链接的可执行文件时,把所有符号添加到动态符号表 -f ,--auxiliary=:对于ELF格式共享对象,设置...org>:使用指定的地址作为bss段的起始点 -t,--trace:在处理输入文件时显示它们的名称 -u ,--undefined=:强制指定符号在输出文件中作为未定义符号...warn-once:对于每个未定义的符号只发出一次警告 -warn-section-align:如果为了对齐而改动了输出段地址,则发出警告 --whole-archive:对于指定的存档文件,在存档中包含所有文件
3.2、隐式方式使用动态库在程序中隐式使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明动态库名进行编译。...lib,/usr/libflag表示在什么时候解决未定义的符号(调用)。...取值有两个:1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。...6、查看库中的符号1、使用nm命令可以打印出库中涉及到的所有符号。...库既可以是静态库也可以是动态的常见的三种符号:①在库中被调用,但没有在库中定义(表明需要其他库支持),用U表示②在库中定义的函数,用T表示③“弱态”符号,他们虽然在库中被定义但是可能被其他库中同名的符号覆盖
一、编译阶段 nm 获取二进制文件包含的符号信息 strings 获取二进制文件包含的字符串常量 strip 去除二进制文件包含的符号...默认状态下调试符号不会被列出) -l 列出符号在源代码中对应的行号(指定这个参数后,nm将利用调试信息找出文件名以及符号的行号。...对于一个已定义符号,将会找出这个符号定义的行号,对于未定义符号,显示为空) -n 根据符号的地址来排序(默认是按符号名称的字母顺序排序的) -u 只列出未定义符号...strip(去除二进制文件里面包含的符号) 用途: 可执行程序减肥(通常只在已经调试和测试过的生成模块上,因为不能调试了) 反编译、反跟踪 readelf(显示目标文件详细信息) nm...参数: -a 在显示函数名或文件行号前显示地址 -b 指定二进制文件格式 -C 解析C++符号为用户级的名称,可指定解析样式 -e 指定二进制文件
上面的ld是链接器,是一个可执行程序,它的输入是一个或多个目标文件,如上面指令中的main.o。 也就是说,目标文件main.o中引用了func(),但链接器找不到它的定义。...显然,main.o中引用但未定义的func()被链接器在func.o中找到了。...即,链接器在面对一个目标文件时,如果碰到里面有未定义的引用,会在其他目标文件中查找,如果找不到,则报错“undefined reference to”。如果找到有且仅有一个,则pass。...而且,链接时输入目标文件的顺序与first defined here相关。 我们还是在main.cpp中只保留func()函数的声明,再单独编译汇编生成main.o。...接下来用nm看下main.o符号表中的内容: PS F:\Jungle\1.Program\4.C++\4.Compiler> g++ -S .
:main.cpp对print(int, int)未定义的引用。...原因分析 test.c我们使用的是C语言的编译器gcc进行编译的,其中的函数print编译之后,在符号表中的名字为 print,通过nm查看.o文件. $ gcc -c test.c $ nm test.o...g++ 进行链接,也就是 C++ 链接方式,程序在运行到调用 print 函数的代码时,会在符号表中寻找 _Z5printii(是按照C++的链接方法来寻找的,所以是找 _Z5printii 而不是找...print)的名字,发现找不到,所以会提示“未定义的引用” $ g++ -c test.c $ ls main.cpp makefile test.c test.h test.o $ nm test.o...,也就是在符号表中寻找print(这才是C++兼容C),这个时候是可以找到的,是不会报错的。
net.core.somaxconn = 262144 选项的默认值是128, 这个参数用于调节系统同时发起的tcp连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此,需要结合并发请求数来调节此值...默认状态下调试符号不会被列出) -l 列出符号在源代码中对应的行号(指定这个参数后, nm将利用调试信息找出文件名以及符号的行号。...对于一个已定义符号,将会找出这个符号定义的行号, 对于未定义符号,显示为空) -n 根据符号的地址来排序(默认是按符号名称的字母顺序排序的) -u 只列出未定义符号 常用nm -CAln xxx 等价于...可以根据符号还原对应的函数调用名,命令空间,类名 2.1.5 反编译,反跟踪 nm 程序可用于列举符号及其类型和值, 但是,要更仔细地研究目标文件中这些命名段的内容, 需要使用功能更强大的工具。...2.2.2 ldd 显示程序需要使用的动态库和实际使用的动态库 ldd -r .
链接器主要完成符号解析和重定位两个任务。 目标文件有三种形式:可重定位目标文件(.so);可执行目标文件(.exe),共享目标文件(.so)。...弱全局符号分配在 COMMON section 中,强全局符号分配在 .bss 中。 静态库用于共享重复的代码,链接器仅会拷贝需要的函数。也可以通过参数拷贝所有函数。...gcc 的静态库链接是按顺序进行的。...遇到目标文件 .o 时会把未定义和已定义的符号保存起来,遇到存档文件 .a 时,除了前面的操作,还会把 .a 的成员符号与未定义的符号比较,把匹配的成员符号对应的 .o 链接起来。...这样的话因为是顺序的,如果把静态库放在前面,则会错过后面目标文件的匹配,从而在链接完所有文件,却还是有未定义符号,结果编译报错。 所以一般做法是静态库文件放在最后。
有些linux命令看起来极其简单,只包含2个字符,但确有很强的功能性。看起来还是有些陌生的命令,不过在工作中别忘记它们的存在。...查找共享库中的函数 比如我查看oracle中的一些文件中的函数,可以这样 cd $ORACLE_HOME/rdbms R ----Read only symbol 。...子程序都是这种符号,比如文件中实现了一个函数function,则function就是这种符号; U ----未定义的符号。...如果文件中引用了不存在的函数,则这些未定义的函数就是这种类型; S ----未初始化的符号。比如全局变量int s ; 则s就是这种类型的符号。...但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。
领取专属 10元无门槛券
手把手带您无忧上云