All of lore.kernel.org
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Ze Xia <xiaze2017@stu.xjtu.edu.cn>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@red-hat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	linux-perf-users@vger.kernel.org
Subject: Re: Bug with 'perf script --symfs'?
Date: Fri, 12 Jul 2024 15:13:57 -0500	[thread overview]
Message-ID: <ZpGOhXCAdz8ks6Y2@google.com> (raw)
In-Reply-To: <1a8b2c39.69b.1909152714b.Coremail.xiaze2017@stu.xjtu.edu.cn>

Hello,

On Mon, Jul 08, 2024 at 03:50:17PM +0800, Ze Xia wrote:
> Hi,
> 
> I think I found that `perf script --symfs` option and automatic namespace attaching seems to conflict.
> 
> Environment: kernel version `6.5.0-41-generic`, distribution `ubuntu22.04`, arch `x86_64`
> 
> Behavior: In `perf script`, if a process is inside another namespace than the default (e.g. inside a docker container), perf script will try to attach to that namespace to read debug info. However, if `--symfs` option is provided, then it will search for debug files with `symfs` prefix *inside the namespace*. Usually the symfs directory isn't present in the namespace, thus I see this behavior as inappropriate.
> 
> To reproduce: I run commands below on a ubuntu machine with docker installed. Any glibc based distro without musl installed should also reproduce the issue, as musl isn't present at host but present in the docker container.
> 
> In one terminal (create the process to be profiled):
> 
>     $ docker run -it --rm --name test-symfs --net=host alpine
>     # now we're inside the container
>     $ apk add musl-dbg
>     $ dd if=/dev/zero of=/dev/null
>     # it stucks here, don't kill it yet
> 
> In another terminal (profiling):
> 
>     $ perf record -a -g sleep 1
>     $ perf script > success.perf
>     $ grep musl success.perf | head -n 10
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
> 
> Thanks to automatic namespace attaching, this works. Problem comes with `--symfs` option:
> 
>     $ docker cp test-symfs:/ ./symfs
>     $ perf script --symfs ./symfs > fail.perf
>     $ grep musl fail.perf | head -n 10
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 [unknown] (/lib/ld-musl-x86_64.so.1)
> 
> We can't find the symbol any more.
> 
> Rerun the `perf script` with `strace`:
> 
>     $ strace -o fail.strace perf script --symfs ./symfs > fail.perf
>     $ grep musl fail.strace | grep stat
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1", 0x7ffce53b7030, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1", 0x7ffce53b2140, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//usr/lib/debug/lib/ld-musl-x86_64.so.1.debug", 0x7ffce53b41a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//usr/lib/debug/lib/ld-musl-x86_64.so.1", 0x7ffce53b41a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1", 0x7ffce53b41a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/.debug/ld-musl-x86_64.so.1", 0x7ffce53b41a0, 0) = -1 ENOENT (No such file or directory)
> 
> Note how `./symfs/` is included in all those calls.
> 
> Rerun the success case with strace:
> 
>     $ strace -o success.strace perf script > success.perf
>     $ grep musl success.strace | grep stat
>     newfstatat(AT_FDCWD, "/lib/ld-musl-x86_64.so.1", {st_mode=S_IFREG|0755, st_size=649832, ...}, 0) = 0
>     newfstatat(AT_FDCWD, "ld-musl-x86_64.so.1.debug", 0x7ffe0949a350, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "/lib/ld-musl-x86_64.so.1.debug", 0x7ffe0949a350, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "/lib/.debug/ld-musl-x86_64.so.1.debug", 0x7ffe0949a350, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "/usr/lib/debug/lib/ld-musl-x86_64.so.1.debug", {st_mode=S_IFREG|0755, st_size=2892848, ...}, 0) = 0
>     newfstatat(AT_FDCWD, "/usr/lib/debug/lib/ld-musl-x86_64.so.1.debug", {st_mode=S_IFREG|0755, st_size=2892848, ...}, 0) = 0
> 
> Note that the calls without `./symfs/` worked, because perf is inside the container's namespace.
> 
> To prove that our symfs indeed contains the debug info, we can stop the `dd` command inside docker and rerun `perf script` without `--symfs` option, it also succeeds:
> 
>     $ strace -o success2.strace perf script --symfs ./symfs > success2.perf
>     $ grep musl success2.perf | head -n 10
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>             75fbf5143992 __cp_end+0x0 (/lib/ld-musl-x86_64.so.1)
>     $ grep musl success2.strace | grep stat
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1", 0x7ffe14d3d6a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1", {st_mode=S_IFREG|0755, st_size=649832, ...}, 0) = 0
>     newfstatat(AT_FDCWD, "ld-musl-x86_64.so.1.debug", 0x7ffe14d387a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1.debug", 0x7ffe14d387a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/.debug/ld-musl-x86_64.so.1.debug", 0x7ffe14d387a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "/usr/lib/debug./symfs//lib/ld-musl-x86_64.so.1.debug", 0x7ffe14d387a0, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//usr/lib/debug/lib/ld-musl-x86_64.so.1.debug", {st_mode=S_IFREG|0755, st_size=2892848, ...}, 0) = 0
>     newfstatat(AT_FDCWD, "./symfs//usr/lib/debug/lib/ld-musl-x86_64.so.1", 0x7ffe14d3a810, 0) = -1 ENOENT (No such file or directory)
>     newfstatat(AT_FDCWD, "./symfs//lib/ld-musl-x86_64.so.1", {st_mode=S_IFREG|0755, st_size=649832, ...}, 0) = 0
> 
> As the `dd` process is dead now, `perf script` will not attach to its namespace. It reads debug info from our symfs, and it worked.
> 
> Expected Behavior: `symfs` is prefixed only if no namespace attaching happened. Or, to be conversative, try twice, with or without `--symfs`.

I'm not sure if it's the reasonable expectation.  With --symfs, you can
expect it will prefix the path to all DSO paths.  The namespace makes
things complicated but I think the symfs behaivor is simple.  There's no
guarantee if the symfs is always out of the namespace, right?

Thanks,
Namhyung


      reply	other threads:[~2024-07-12 20:14 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-08  7:50 Bug with 'perf script --symfs'? Ze Xia
2024-07-12 20:13 ` Namhyung Kim [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZpGOhXCAdz8ks6Y2@google.com \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@red-hat.com \
    --cc=peterz@infradead.org \
    --cc=xiaze2017@stu.xjtu.edu.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.