NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.28k stars 13.53k forks source link

Missing python dependency for `bashreadline` of `bcc` #328743

Open willhansen opened 1 month ago

willhansen commented 1 month ago

Describe the bug

Package: nixpkgs#bcc command: bashreadline result:

Traceback (most recent call last):
  File "/nix/store/gkrlrdcn1qil6qkw96x8f4n7whqvq7hi-bcc-0.30.0/share/bcc/tools/.bashreadline-wrapped", line 21, in <module>
    from elftools.elf.elffile import ELFFile
ModuleNotFoundError: No module named 'elftools'

Steps To Reproduce

Steps to reproduce the behavior:

  1. Install nixpkgs#bcc
  2. run bashreadlline

I was able to reproduce this in a fresh docker container (even if I don't expect it to fully work with bpf after the python stuff is sorted out)

docker run \
  --rm \
  -it \
  --workdir="/root" \
  nixos/nix \
  bash -c '
  mkdir -p ".config/nix" && \
  echo "experimental-features = nix-command flakes" > ".config/nix/nix.conf" && \
  nix profile install nixpkgs#bcc --impure && \
  bashreadline \
  '

Expected behavior

No python error.

Additional context

nixpkgs#bcc was installed via standalone home-manager, using unstable nixpkgs. Main OS is Linux Mint.

Running the command sudo $(which bashreadline) results in the exact same error

Notify maintainers

@ragnard @Mic92 @thoughtpolice @martinetd

Metadata

 - system: `"x86_64-linux"`
 - host os: `Linux 5.15.0-113-generic, Linux Mint, 21.3 (Virginia), nobuild`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.19.3`
 - channels(root): `"nixpkgs"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixpkgs`

Add a :+1: reaction to issues you find important.

martinetd commented 1 month ago

hmpf, we don't even really need elfutils here as we know our readline version is recent enough in nixpkgs, let's just remove that code and pick the new symbol directly.

(I've reproduced the bug this fixes with the old symbol name)

I'm also fixing that we need to pass the path to libreadline manually on nixos, it's still possible to override it with -s and another path.

(But frankly I consider these bcc scripts to be examples that can be hacked rather complete examples, so if it doesn't work 100% you ought to be able to figure it out -- the bpftrace tools/bashreadline.bt has the exact same problems (missing the first command & not hooking the right path) and I don't think it really matters)

willhansen commented 1 month ago

I'm also fixing that we need to pass the path to libreadline manually on nixos

@martinetd, could you expand on that? I'm trying to switch over to bpftrace, and that sounds related to my current issue (which I acknowledge is a bit of a tangent).

  ██will@will-pc 🯰🯳 ~  ꧁ ꧂   𐁙   𐙀   ៚ 𑜿  𐃆 𐼽 ꫝꫜ  𐀢꩜  𒓎    ꘐ
██  🯁🯂🯃mysudo bpftrace -e 'uretprobe:'"$(realpath $(which bash))"':readline {time("%H:%M:%S  ");printf("%-6d %s\n", pid, str(retval));}'                                   ⌚ 2024-07-21 20:59:40-07:00   130 ↵
Attaching 1 probe...
ERROR: Could not resolve symbol: /nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:readline, cannot attach probe.
  ██will@will-pc 🯰🯳 ~  ꧁ ꧂   𐁙   𐙀   ៚ 𑜿  𐃆 𐼽 ꫝꫜ  𐀢꩜  𒓎    ꘐ
██  🯁🯂🯃mysudo bpftrace -l 'uretprobe:'"$(realpath $(which bash))"':*readline*'                                                                                             ⌚ 2024-07-21 20:59:41-07:00   255 ↵
uretprobe:/nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:initialize_readline
uretprobe:/nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:pcomp_set_readline_variables
uretprobe:/nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:posix_readline_initialize
uretprobe:/nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:readline_set_char_offset
uretprobe:/nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:yy_readline_get
uretprobe:/nix/store/bh6w9sbfz2m5w1bd4cg2ndw1s66agkfd-bash-interactive-5.2p26/bin/bash:yy_readline_unget
martinetd commented 1 month ago

We don't build bash with the built-in readline, you need to hook on libreadline (ldd on bash to get the path)

$ ldd $(which bash) | grep libreadline
        libreadline.so.8 => /nix/store/zbrzpn46fkhk61c84w7kd65idrj3pxqp-readline-8.2p10/lib/libreadline.so.8 (0x00007479594f0000)
$ sudo bpftrace -e 'uretprobe:/nix/store/zbrzpn46fkhk61c84w7kd65idrj3pxqp-readline-8.2p10/lib/libreadline.so.8:readline_internal_teardown { printf("%s\n", str(retval)); }'

(Note if you upgraded you might have plenty of libreadlines alive in old shells, check /proc/$$/maps if that didn't work)