我正在链接一个外部库(通过wierd进程,mpicc + Cython +等),但我有一个奇怪的链接过程行为.
有两个.o文件,libpetsc4py.o和PETSc.o它们被链接到一个.so文件PETSc.so
一个包含一个未定义的符号 __pyx_tp_new_8petsc4py_5PETSc_Object
[zheltkov@compiler-2 src]$ nm libpetsc4py.o | grep __pyx_tp_new_8petsc4py_5PETSc_Object
U __pyx_tp_new_8petsc4py_5PETSc_Object
Run Code Online (Sandbox Code Playgroud)
它在另一个.o文件中定义:
[zheltkov@compiler-2 src]$ nm PETSc.o | grep __pyx_tp_new_8petsc4py_5PETSc_Object
00000000001b92f0 t __pyx_tp_new_8petsc4py_5PETSc_Object
Run Code Online (Sandbox Code Playgroud)
然后,完成链接(编译行很奇怪,对不起)
mpicc -pthread -fPIC -wd1572 -g -shared -fno-strict-aliasing -g -O2 -DNDEBUG -O2 -g
build/temp.linux-x86_64-2.7/arch-linux2-c-debug/src/PETSc.o build/temp.linux-x86_64-
2.7/arch- linux2-c-debug/src/libpetsc4py.o -L/home/users/zheltkov/tmp/petsc-3.3/arch
-linux2-c-debug/lib -L/home/users/zheltkov/ivan/soft/epd7.2/lib
-Wl,rpath,/home/users/zheltkov/tmp/petsc-3.3/arch-linux2-c-debug/lib
-Wl,-rpath,/home/users/zheltkov/ivan/soft/epd7.2/lib -lpetsc -lpython2.7 -o
build/lib.linux-x86_64-2.7/petsc4py/lib/a rch-linux2-c-debug/PETSc.so -lX11 -Wl,
-rpath,/home/users/zheltkov/tmp/petsc-3.3/arch-linux2-c-debug/lib
-L/home/users/zheltkov/tmp/petsc-3.3/arch-linux2-c-debug/lib -lfftw3_mpi -lfftw3 -lHYPRE
-Wl,-rpath,/opt/intel/impi/4.1.0.030/intel64/lib
-L/opt/intel/impi/4.1.0.030/intel64/lib -Wl,
-rpath,/opt/intel/composer_xe_2013.2.146/mkl/lib/intel64
-L/opt/intel/composer_xe_2013.2.146/mkl/lib/intel64
-Wl,-rpath,/opt/intel/composer_xe_2013.2.146/compiler/lib/intel64
-L/opt/intel/composer_xe_2013.2.146/compiler/lib/intel64 -Wl,
-rpath,/usr/lib/gcc/x86_64-redhat-linux/4.4.6 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.6
-Wl,- rpath,/mnt/data/users/dm4/vol9/zheltkov/tmp/petsc-3.3/-Xlinker -lmpigc4
-Wl,-rpath,/opt/intel/mpi-rt/4.1 -lml -lpthread -Wl,-rpath,
/opt/intel/composer_xe_2013/mkl/lib/intel64
-L/opt/intel/composer_xe_2013/mkl/lib/intel64 …Run Code Online (Sandbox Code Playgroud) 当我查看我的库中的符号时nm mylib.a,我看到一些重复的条目,如下所示:
000000000002d130 S __ZN7quadmat11SpAddLeavesC1EPNS_14BlockContainerEPy
00000000000628a8 S __ZN7quadmat11SpAddLeavesC1EPNS_14BlockContainerEPy.eh
Run Code Online (Sandbox Code Playgroud)
通过管道输送c++filt:
000000000002d130 S quadmat::SpAddLeaves::SpAddLeaves(quadmat::BlockContainer*, unsigned long long*)
00000000000628a8 S quadmat::SpAddLeaves::SpAddLeaves(quadmat::BlockContainer*, unsigned long long*) (.eh)
Run Code Online (Sandbox Code Playgroud)
这.eh意味着什么,这个额外符号用于什么?
我发现它与异常处理有关.但为什么这会使用额外的符号?
(我用clang注意到这一点)
我在运行时遇到未定义的符号错误,当我在相关库中查找符号时,我得到结果:
nm -C -D /home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit/libScannerBitCAPI.so | grep empty_
U YAML::detail::node_data::empty_scalar[abi:cxx11]
00000000002b5860 T YAML::detail::node_data::empty_scalar[abi:cxx11]()
Run Code Online (Sandbox Code Playgroud)
但这怎么可能呢?该符号既未定义,又在库中?什么?或者这些实际上是不同的符号?当损坏时,名称确实略有不同:
nm -D /home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit/libScannerBitCAPI.so | grep empty_
U _ZN4YAML6detail9node_data12empty_scalarB5cxx11E
00000000002b5860 T _ZN4YAML6detail9node_data12empty_scalarB5cxx11Ev
Run Code Online (Sandbox Code Playgroud)
这有道理吗?
我需要帮助来删除我的iOS应用程序中已知的错误选择器。
苹果拒绝了我的应用程序,说:
关于准则2.3.1,此应用已通过验证,包含错误的选择器,例如
- x7kQPFEZS4af59md1eVMqf42YSTGAZVO:和i5B8qlaSJwvmVviceDOQkqQ0vwGq35XMmtV81zlsmHnws。
我尝试运行列出所有符号的nm命令,然后使用grep搜索上述选择器:
grep -r x7kQPFEZS4af59md1eVMqf42YSTGAZVO。
grep -r i5B8qlaSJwvmVviceDOQkqQ0vwGq35XMmtV81zlsmHnws。
两个grep都显示以下结果:
二进制文件./Payload/MyAppName.app/MyAppName匹配
MyAppName是一个二进制文件(unix可执行文件)。
如何进一步进行操作,并从我的iOS应用程序中删除这些错误的选择器?(或至少找到创建此选择器的代码/框架)
我的项目由几个静态库组成,这些库在最后一步中链接在一起.现在我遇到了问题,库的链接顺序很重要(否则我得到一个未定义的符号链接器错误).有时我遇到问题,我必须重新排序链接库(-lcommon -lsetup -lcontrol等).目前这是一个愚蠢的试验和错误:重新排序,编译,检查错误,重新排序,编译等等.
所以我写了一个小程序来向我展示库间依赖关系,并生成链接库的顺序.它从nm读取定义的('T','B'等)和未定义的符号('U')并从中删除弱符号('w','W','v'和'V') '未定义的符号列表'.现在它为每个未定义的符号确定解析它的库.
但我的程序向我展示了循环依赖...我的错误是什么?
如果它们真的存在,我根本无法联系......那么在分析nm输出时我错过了什么?或者正在分析nm输出而不是解决这些依赖关系?
libcommon.a:
U _ZN15HardwareUnit23GetHardwareSerialNumberEv
libhardware.a:
00000484 T _ZN15HardwareUnit23GetHardwareSerialNumberEv
libsecurityaccess.a:
U _ZN15HardwareUnit23GetHardwareSerialNumberEv
---
libhardware.a:
U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
libsecurityaccess.a:
00004020 T _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
Run Code Online (Sandbox Code Playgroud) 我构建了一个名为InterfaceLayer.so的动态库.我打电话的时候:
> nm InterfaceLayer
Run Code Online (Sandbox Code Playgroud)
作为输出,我得到一些看起来像这样的符号:
00000e28 T _Z5startv
Run Code Online (Sandbox Code Playgroud)
虽然我期待它是" 开始 ",就像我在代码中定义的函数的名称一样.
有线索吗?
TKZ
我正在努力使用正确的命令来执行以下操作:
找到包含特定符号的所有共享库(*.so).
这就是我尝试过的:
find -iname '*.so*' -exec nm {} \; | grep -H _ZN6QDebugD1Ev
Run Code Online (Sandbox Code Playgroud)
上面给出了一些带有符号的输出,但没有找到符号出现的文件名.我给grep告诉它打印文件名的任何标志都会丢失,因为grep是从stdin提供的.
(standard input): U _ZN6QDebugD1Ev
(standard input): U _ZN6QDebugD1Ev
(standard input): U _ZN6QDebugD1Ev
(standard input): U _ZN6QDebugD1Ev
(standard input):0015e928 T _ZN6QDebugD1Ev
(standard input): U _ZN6QDebugD1Ev
(standard input): U _ZN6QDebugD1Ev
(standard input): U _ZN6QDebugD1Ev
Run Code Online (Sandbox Code Playgroud)
另一种尝试:
find -iname '*.so*' -exec nm {} \; -exec grep _ZN6QDebugD1Ev {} \;
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为两个高管完全独立.
我该怎么办?
请使用以下源代码:
struct Foo {
Foo(){}
};
Foo f;
Run Code Online (Sandbox Code Playgroud)
使用时clang++,它会为构造函数创建一个符号:
clang++ -c foo.cpp
nm -C foo.o | grep Foo
0000000000000000 W Foo::Foo()
Run Code Online (Sandbox Code Playgroud)
但是,在编译时g++,它会为构造函数创建多个符号:
g++ -c foo.cpp;
nm -C foo.o | grep Foo
0000000000000000 W Foo::Foo()
0000000000000000 W Foo::Foo()
0000000000000000 n Foo::Foo()
Run Code Online (Sandbox Code Playgroud)
为什么会g++在同一个目标文件中创建重复的弱符号?
我唯一的理论是它与内联有关,但这只是猜测.
我应该注意,受损的名称如下所示:
g++ -c foo.cpp; nm foo.o | grep Foo
0000000000000000 W _ZN3FooC1Ev
0000000000000000 W _ZN3FooC2Ev
0000000000000000 n _ZN3FooC5Ev
Run Code Online (Sandbox Code Playgroud)
因此,尽管未重整名称是相同的,ZN3FooC1Ev并且ZN3FooC2Ev是不同的.
我有 2 个静态库,它们的编译方式不同。在这一点上,我不明白其中的区别。
我只是想了解,对于一个库中的相同符号,该符号的地址是 0。而在另一个库中则不同于零。这是什么意思?
$ nm works/libdriver.a | grep mbedtls_cipher_setup
0000000000000487 T tls_cipher_setup
$ nm not_works/libdriver.a | grep mbedtls_cipher_setup
0000000000000000 T tls_cipher_setup
Run Code Online (Sandbox Code Playgroud)
当链接器使用这些库进行链接时会有什么区别?
就我而言,如果我使用works/libdriver.a库,链接就会成功通过。但是,当我使用 not_works/libdriver.a 库时,相同的链接会生成多重定义错误,而符号 tls_cipher_setup 是生成此错误的众多错误之一。
我在mylib.h中有这样的代码,然后使用它来创建mylib.so。有没有办法检查.so中如何定义MY_MACROS?
#ifdef SWITCH_CONDITION
#define MY_MACROS 0
#else
#define MY_MACROS 1
#endif
Run Code Online (Sandbox Code Playgroud)
如果那是一个函数,我会简单地做
nm mylib.so | grep myfunction
Run Code Online (Sandbox Code Playgroud)
有没有办法对宏做同样的事情?
PS应该是因为
> grep MY_MACROS mylib.so
> Binary file mylib.so matches
Run Code Online (Sandbox Code Playgroud)