为什么“perf report”在 docker 中使用时在第二次运行时不显示函数名称?

use*_*418 5 linux perf docker

我正在尝试使用 docker 中的 Linux perf 命令来分析 ffmpeg。在第一次运行中,输出很好,“perf report”显示的所有函数名称都很好。在第二次运行中,它仅显示地址而不是函数名称。我正在使用一个在 docker 中运行 ffmpeg 两次的脚本。

脚本中使用的命令是:

perf record ffmpeg -y -i input.mp4 -c:v libx264 -b:v 1500k output1.mp4

sleep 5

perf record ffmpeg -y -i input.mp4 -c:v libx264 -b:v 1500k output1.mp4
Run Code Online (Sandbox Code Playgroud)

运行脚本的命令:

docker run -it --privileged -v $(pwd):/cwd myDocker:someTag /cwd/my_script.sh
Run Code Online (Sandbox Code Playgroud)

我注意到在第二次运行时,它在 perf.data 中找不到 libx264 库。

“perf report”的输出如下所示。非常感谢任何形式的帮助。

输出1:

# Overhead  Command  Shared Object       Symbol
# ........  .......  ..................  .........................................................
#

 6.35%  ffmpeg   libx264.so.148      [.] x264_cabac_block_residual_rd_internal_ssse3_lzcnt
 3.91%  ffmpeg   libx264.so.148      [.] x264_cabac_encode_decision_bmi2
 3.70%  ffmpeg   ffmpeg              [.] quantize_and_encode_band_cost_UPAIR
 2.94%  ffmpeg   libx264.so.148      [.] x264_me_search_ref
Run Code Online (Sandbox Code Playgroud)

输出2:

# Overhead  Command  Shared Object       Symbol
# ........  .......  ..................  .........................................................
#

 1.00%  ffmpeg    (deleted)         [.] 0x00000000000c6e87
 0.90%  ffmpeg    (deleted)         [.] 0x00000000000c82c1
 0.71%  ffmpeg    (deleted)         [.] 0x00000000000c82e2
 0.69%  ffmpeg    (deleted)         [.] 0x00000000000c6e98
Run Code Online (Sandbox Code Playgroud)

如果有人可以提供线索,我将不胜感激。

先感谢您。

编辑1:我还阅读了如何在程序中找到符号。该帖子没有回答我的问题,因为它没有解决我的情况。

编辑2:我还查看了perf可以在内核中找到符号,但在我的程序中找不到符号。如何修复它?。我的实验设置是正确的。

编辑3:当我在容器外运行脚本时,两次迭代都工作得很好。唯一的问题是当我在 docker 容器中运行时。

编辑 4:第一次运行后,我确保二进制和共享库对象对 ls 和 stat 命令都是可见的。

编辑 5:第一次运行后,我确保二进制和共享库对象对 nm 和 objdump 命令都是可见的。此外,这些命令显示正确的符号。

Ore*_*hon 1

我也遇到同样的情况。

要修复此问题,请将可执行文件复制到同一路径,只需后缀为 (deleted). 在你的情况下,它可能是:

sudo cp "/usr/bin/ffmpeg" "/usr/bin/ffmpeg (deleted)"

如果您将strace perf命令,您将看到这是它正在查找的文件路径。一旦你进行复制,它就会在那里找到符号。

看起来perf在某些已经无效的/proc路径上调用readlink ,从而获取带有“(已删除)”后缀的进程 exe 路径。它来自内核readlink实现代码,请参见这里:Broken symlinks and a oddly (deleted)