我分析了两个运行相同逻辑计算的二进制文件,一个用 Swift 编写,另一个用 C++ 编写。代码非常简单,只是在循环中进行一些数学计算。我正在使用 Swift docker 镜像 与
--privileged
一起运行。
现在,我知道系统库
libm.so
和 libc.so
在 docker 实例中被剥离,因此符号化可能不太好,但在这种情况下,共享对象在 C++ 代码中显示为 (deleted)
,但是不适用于 Swift 代码。
C++ 代码是用
-g -O3 -Wall -Wextra -pedantic -std=c++20 -fwrapv -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer
编译的。我用perf record -g
录制,这是perf report -g 'graph,1.0,caller
的输出。
Samples: 187K of event 'cpu-clock:pppH', Event count (approx.): 46774250000
Children Self Command Shared Object Symbol
+ 100.00% 0.00% profile profile [.] _start
+ 100.00% 0.00% profile (deleted) [.] 0x0000ffff88e274cc
+ 100.00% 0.00% profile (deleted) [.] 0x0000ffff88e273fc
+ 100.00% 0.00% profile profile [.] main
+ 76.43% 8.62% profile profile [.] synthetic
+ 32.22% 2.66% profile profile [.] siam100_integrand
+ 23.32% 0.00% profile (deleted) [.] 0x0000ffff88fe54e4
+ 23.32% 23.32% profile (deleted) [.] 0x00000000000354e4
+ 19.79% 0.00% profile (deleted) [.] 0x0000ffff88fe54d8
+ 19.79% 19.79% profile (deleted) [.] 0x00000000000354d8
+ 17.17% 0.00% profile (deleted) [.] 0x0000ffff88fe88f0
+ 17.17% 17.17% profile (deleted) [.] 0x00000000000388f0
+ 8.16% 8.16% profile (deleted) [.] 0x00000000000387f4
+ 8.16% 0.00% profile (deleted) [.] 0x0000ffff88fe87f4
+ 4.92% 4.92% profile (deleted) [.] 0x00000000000354b4
+ 4.92% 0.00% profile (deleted) [.] 0x0000ffff88fe54b4
+ 3.78% 3.78% profile profile [.] cos@plt
+ 2.22% 2.22% profile profile [.] log@plt
profile
是二进制文件的名称。删除的共享对象条目应该主要是 libm.so
、libc.so
和 kernel.kallsyms
。但是,在进入调试器时,我无法在性能报告输出中显示的地址处设置断点:例如Cannot access memory at address 0xffff88fe54e4
。
这是使用 swift 构建的二进制文件的相同报告。
Samples: 54K of event 'cpu-clock:pppH', Event count (approx.): 13628000000
Children Self Command Shared Object Symbol
+ 99.97% 0.00% Run Run [.] _start
+ 99.97% 0.00% Run libc.so.6 [.] __libc_start_main@@GLIBC_2.34
+ 99.97% 0.00% Run libc.so.6 [.] __libc_start_call_main
+ 99.97% 0.00% Run Run [.] Run_main
+ 43.46% 43.46% Run libm.so.6 [.] log@@GLIBC_2.29
+ 39.18% 7.92% Run Run [.] $s7BMDemos9synthetic__9iterCountS2d_SdSitF
+ 31.27% 31.26% Run libm.so.6 [.] __cos
+ 8.41% 8.41% Run libm.so.6 [.] __math_invalid
+ 5.97% 5.97% Run Run [.] log@plt
+ 2.94% 2.94% Run Run [.] cos@plt
二进制文件之间的另一个区别是,C++ 通过过程链接表直接跳转到
log
,而 Swift 则必须执行某种 dlsym
查找查找。这是我在单步执行调试器 asm 行时发现的。
所以,我有以下问题。
ldd -v
C++ 二进制文件linux-vdso.so.1 (0x0000ffff9a112000)
libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffff99e90000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff99df0000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff99c40000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff9a0d9000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffff99c10000)
Version information:
./profile:
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libm.so.6 (GLIBC_2.29) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libstdc++.so.6 (GLIBCXX_3.4.9) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.11) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /lib/aarch64-linux-gnu/libstdc++.so.6
/lib/aarch64-linux-gnu/libstdc++.so.6:
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libc.so.6 (GLIBC_2.33) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.25) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.18) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.32) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libgcc_s.so.1 (GCC_4.2.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.3) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_4.5.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
/lib/aarch64-linux-gnu/libm.so.6:
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
libc.so.6 (GLIBC_PRIVATE) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
/lib/aarch64-linux-gnu/libc.so.6:
ld-linux-aarch64.so.1 (GLIBC_PRIVATE) => /lib/ld-linux-aarch64.so.1
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/lib/aarch64-linux-gnu/libgcc_s.so.1:
libc.so.6 (GLIBC_2.35) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
ldd -v
Swift 二进制文件linux-vdso.so.1 (0x0000ffff8b009000)
libswiftCore.so => /usr/lib/swift/linux/libswiftCore.so (0x0000ffff8a960000)
libswift_Concurrency.so => /usr/lib/swift/linux/libswift_Concurrency.so (0x0000ffff8a8e0000)
libswift_StringProcessing.so => /usr/lib/swift/linux/libswift_StringProcessing.so (0x0000ffff8a800000)
libswift_RegexParser.so => /usr/lib/swift/linux/libswift_RegexParser.so (0x0000ffff8a6e0000)
libswiftGlibc.so => /usr/lib/swift/linux/libswiftGlibc.so (0x0000ffff8a6b0000)
libBlocksRuntime.so => /usr/lib/swift/linux/libBlocksRuntime.so (0x0000ffff8a690000)
libdispatch.so => /usr/lib/swift/linux/libdispatch.so (0x0000ffff8a610000)
libswiftDispatch.so => /usr/lib/swift/linux/libswiftDispatch.so (0x0000ffff8a5c0000)
libFoundation.so => /usr/lib/swift/linux/libFoundation.so (0x0000ffff89d40000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff89ca0000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff89af0000)
libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffff898c0000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffff89890000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff8afd0000)
libicuucswift.so.65 => /usr/lib/swift/linux/libicuucswift.so.65 (0x0000ffff89680000)
libicui18nswift.so.65 => /usr/lib/swift/linux/libicui18nswift.so.65 (0x0000ffff89360000)
libicudataswift.so.65 => /usr/lib/swift/linux/libicudataswift.so.65 (0x0000ffff878a0000)
Version information:
.build/release/Run:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.29) => /lib/aarch64-linux-gnu/libm.so.6
/usr/lib/swift/linux/libswiftCore.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.32) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.33) => /lib/aarch64-linux-gnu/libc.so.6
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.29) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.27) => /lib/aarch64-linux-gnu/libm.so.6
libgcc_s.so.1 (GCC_3.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.3) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libstdc++.so.6 (GLIBCXX_3.4.17) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (CXXABI_1.3.11) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.21) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.29) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.18) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.14) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (CXXABI_1.3) => /lib/aarch64-linux-gnu/libstdc++.so.6
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/usr/lib/swift/linux/libswift_Concurrency.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.32) => /lib/aarch64-linux-gnu/libc.so.6
libstdc++.so.6 (GLIBCXX_3.4.11) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (CXXABI_1.3) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.21) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.18) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.29) => /lib/aarch64-linux-gnu/libstdc++.so.6
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/usr/lib/swift/linux/libswift_StringProcessing.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/usr/lib/swift/linux/libswift_RegexParser.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/usr/lib/swift/linux/libswiftGlibc.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.27) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.35) => /lib/aarch64-linux-gnu/libm.so.6
/usr/lib/swift/linux/libBlocksRuntime.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
/usr/lib/swift/linux/libdispatch.so:
libc.so.6 (GLIBC_2.33) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.32) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
/usr/lib/swift/linux/libswiftDispatch.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/usr/lib/swift/linux/libFoundation.so:
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.33) => /lib/aarch64-linux-gnu/libc.so.6
libm.so.6 (GLIBC_2.35) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.29) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libgcc_s.so.1 (GCC_3.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.3.1) => /lib/aarch64-linux-gnu/libgcc_s.so.1
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/lib/aarch64-linux-gnu/libm.so.6:
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
libc.so.6 (GLIBC_PRIVATE) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
/lib/aarch64-linux-gnu/libc.so.6:
ld-linux-aarch64.so.1 (GLIBC_PRIVATE) => /lib/ld-linux-aarch64.so.1
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
/lib/aarch64-linux-gnu/libstdc++.so.6:
ld-linux-aarch64.so.1 (GLIBC_2.17) => /lib/ld-linux-aarch64.so.1
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libc.so.6 (GLIBC_2.33) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.25) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.18) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.32) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libgcc_s.so.1 (GCC_4.2.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.3) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_4.5.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
/lib/aarch64-linux-gnu/libgcc_s.so.1:
libc.so.6 (GLIBC_2.35) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
/usr/lib/swift/linux/libicuucswift.so.65:
libgcc_s.so.1 (GCC_3.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libm.so.6 (GLIBC_2.29) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libstdc++.so.6 (GLIBCXX_3.4.11) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (CXXABI_1.3) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.30) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /lib/aarch64-linux-gnu/libstdc++.so.6
libc.so.6 (GLIBC_2.34) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.33) => /lib/aarch64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
/usr/lib/swift/linux/libicui18nswift.so.65:
libgcc_s.so.1 (GCC_3.0) => /lib/aarch64-linux-gnu/libgcc_s.so.1
libstdc++.so.6 (CXXABI_1.3) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /lib/aarch64-linux-gnu/libstdc++.so.6
libm.so.6 (GLIBC_2.29) => /lib/aarch64-linux-gnu/libm.so.6
libm.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libm.so.6
libc.so.6 (GLIBC_2.17) => /lib/aarch64-linux-gnu/libc.so.6
出于某种原因,
perf report
尝试查找附加有 (deleted)
的可执行文件。创建名为 <executable name> (deleted)
的已分析可执行文件的副本最终工作得很好。
更好的选择是创建二进制文件的符号链接,这样重新编译就不会导致别名过时。