How to use linux perf in a conda environment
1
vote
0
answers
52
views
I'm trying to use linux
perf
program in a conda environment, but the perf
program seems to ignore the conda environment. I installed the conda-forge::linux-perf
package in my conda environment, but when I run it I get this error:
$ perf record ls
perf: error while loading shared libraries: libdebuginfod.so.1: cannot open shared object file: No such file or directory
The library is installed in my conda environment:
$ ls $CONDA_PREFIX/lib/*debuginfod*
/home/pcarter/anaconda3/envs/spec_density/lib/libdebuginfod-0.191.so /home/pcarter/anaconda3/envs/spec_density/lib/libdebuginfod.so.1
/home/pcarter/anaconda3/envs/spec_density/lib/libdebuginfod.so
But perf
is not looking in this directory for libraries. Using strace
, I'm able to see where it is only looking in the base system directories, not the conda ones.
execve("/home/pcarter/anaconda3/envs/spec_density/bin/perf", ["perf", "record", "ls"], 0x7ffe078205b0 /* 99 vars */) = 0
access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory)
brk(NULL) = 0x556c19e15000
fcntl(0, F_GETFD) = 0
fcntl(1, F_GETFD) = 0
fcntl(2, F_GETFD) = 0
access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory)
readlink("/proc/self/exe", "/home/pcarter/anaconda3/envs/spe"..., 4096) = 50
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=138259, ...}) = 0
mmap(NULL, 138259, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9bf8a59000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 l\0\0\0\0\0\0"..., 832) = 832
...
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/haswell/x86_64/libdebuginfod.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls/haswell/x86_64", 0x7fffe984d610) = -1 ENOENT (No such file or directory)
...
openat(AT_FDCWD, "/usr/lib/libdebuginfod.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
This is not what happens for other conda installed programs. Looking at strace
output for running the nasm
program, it is looking at the conda lib directory.
execve("/home/pcarter/anaconda3/envs/spec_density/bin/nasm", ["nasm"], 0x7ffffc123b60 /* 99 vars */) = 0
brk(NULL) = 0x189a000
readlink("/proc/self/exe", "/home/pcarter/anaconda3/envs/spe"..., 4096) = 50
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/haswell/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/haswell/x86_64", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/haswell/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/haswell", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/x86_64", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/tls", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/haswell/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/haswell/x86_64", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/haswell/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/haswell", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib/x86_64", 0x7ffe9d0a04f0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pcarter/anaconda3/envs/spec_density/bin/../lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/pcarter/anaconda3/envs/spec_density/bin/../lib", {st_mode=S_IFDIR|0755, st_size=20480, ...}) = 0
Is this a security feature of perf
? If so, what do I need to do to fix this?
FYI: I followed the instructions at this [page](https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html) to enable my conda perf
program to have the capabilities it needs.
$ sudo getcap /home/pcarter/anaconda3/envs/spec_density/bin/perf
/home/pcarter/anaconda3/envs/spec_density/bin/perf cap_sys_ptrace,cap_syslog,cap_perfmon=ep
**Update**
I found a work around, but still don't completely understand what is going on. Using sudo
to run perf
as *root* fixes the issue.
$ sudo $CONDA_PREFIX/bin/perf record ls
# Output of ls redacted here
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.021 MB perf.data (7 samples) ]
(I have to specify the path to perf
here since I'm using sudo
which uses the *root* user's PATH
) It looks like conda sets up the library search path using RPATH
in the executable. If you use readelf
to look at the perf
binary, it returns:
$ readelf -d $CONDA_PREFIX/bin/perf
Dynamic section at offset 0x948bc0 contains 45 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libelf.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdebuginfod.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdw.so.1]
0x0000000000000001 (NEEDED) Shared library: [libunwind-x86_64.so.8]
0x0000000000000001 (NEEDED) Shared library: [libunwind.so.8]
0x0000000000000001 (NEEDED) Shared library: [liblzma.so.5]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.3]
0x0000000000000001 (NEEDED) Shared library: [libpython3.12.so.1.0]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libzstd.so.1]
0x0000000000000001 (NEEDED) Shared library: [libcap.so.2]
0x0000000000000001 (NEEDED) Shared library: [libnuma.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../lib]
where $ORIGIN
represents the directory the executable is in. So RPATH
does point to the conda lib
directory. However, perf
seems to be setup to ignore this depending on properties of the user running it. It does use it for *root* but not for my user account. I assume this is for security reasons. Is there a way to enable this for my user account?
Asked by pcarter
(111 rep)
Mar 3, 2025, 10:17 PM
Last activity: Mar 4, 2025, 11:37 PM
Last activity: Mar 4, 2025, 11:37 PM