Skip to content

Improve interactive debugging - #321

Open
casparvl wants to merge 23 commits into
EESSI:mainfrom
casparvl:improve_interactive_debugging
Open

casparvl wants to merge 23 commits into
EESSI:mainfrom
casparvl:improve_interactive_debugging

Conversation

@casparvl

@casparvl casparvl commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Problem
We often have issues reproducing build failures interactively. Currently, we have about three options:

  1. Run with EESSI-extend. This is the easiest, but also the most 'different' from the bot's build environment. It uses EESSI for dependencies, but it doesn't run in a build container.
  2. Run the bot/inspect.sh from the job dir of the failed build job. This script was designed to mimic bot/build.sh and drop you into an interactive shell in the failed build environment. However, it is very much outdated, and keeping it in sync currently requires a lot of code duplication from bot/build.sh. An example of how out-of-sync it is: it does not have any GPU support (no NVIDIA GPU support either).
  3. Try to set all relevant environment variables, extracted from the build log. Then, start a build container manually with the command reported in the build log. Then, try to build to reproduce the failure. This is potentially the most 'similar' in terms of environment to the build job, but very error prone, as it's easy to miss environment variables, or steps that are executed as part of bot/build.sh. It is also very time-consuming.

Proposed solution
The solution presented here is to tightly integrate an option for interactive debugging into the bot/build.sh, that will drop you into an interactive debugging shell if EESSI_INTERACTIVE_BUILD is set. To get an environment that is as similar as possible, one should call the job script that the bot submits interactively. I.e. if a bot is configured to use the default, that would be EESSI_INTERACTIVE_BUILD=<mode> eessi-bot-software-layer/scripts/bot-build.slurm.

mode supports three options:

  • shell - start a plain shell in the build container instead of running the build
  • before - run the build, but start a shell (inside the compat layer, EasyBuild loaded) right before EasyBuild is called
  • onfail - run the build, and start a shell when EasyBuild fails (or the build script exits non-zero)

The idea is that this is ran from the job directory left behind by the bot, with the failing build. By default, it will resume from the latest tarball of the build step (this is selectable). If accelerators are used, it will run for the last accelerator in the list by default (this is also selectable).

Limitations

  • If you're running this from a different user than the bot user, some things may fail on file permission - though typically this just means that things in the shared_fs_directory can not be updated (what's there can be used as long as your user has read permissions to that dir).
  • Currently, the bot/build.sh from software-layer hard-clones and links the software-layer-scripts/bot/build.sh. That results in an exit, because the script runs with set -e. My current hack is just to replace the bot/build.sh in the job dir with a one-liner: software-layer-scripts/bot/build.sh. We should fix this more properly, and maybe make the whole clone-business conditional on EESSI_INTERACTIVE_BUILD not being set.

Caspar van Leeuwen and others added 6 commits October 7, 2026 13:02
… in a container shell right away, or with hooks that drop you at the start of the loop over easystack files, or after an eb command has finished with non-zero exit. Also support debugging of accelerator builds by selecting a single accelerator - even if the initial build was multi-accelerator. Finally, make sure that we can resume from a build tarball, so that if a lot of dependencies have already been built, we don't have to redo it.
…r that the preferred way of debugging is to start at the bot-build.slurm level
…rget or the tarball to resume from up front
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
casparvl and others added 2 commits October 12, 2026 16:08
Co-authored-by: Caspar van Leeuwen <33718780+casparvl@users.noreply.github.com>
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
Comment thread bot/build.sh Outdated
casparvl and others added 9 commits October 12, 2026 16:49
Co-authored-by: Caspar van Leeuwen <33718780+casparvl@users.noreply.github.com>
…n interactive shell. Then, use read -p, and since this prints to stdout, do the whole selection conversation on stdout to avoid spreading it out
…arget / tarball

Simplify the selection of the accelerator target and the tarball to resume from
in interactive builds (EESSI_INTERACTIVE_BUILD): don't infer anything.

- If EESSI_INTERACTIVE_BUILD_ACCELERATOR / EESSI_INTERACTIVE_BUILD_RESUME_FROM is
  set, use it as given.
- If not, ask the user to choose from the available options if stdin is a
  terminal, and stop with an error naming the variable to set if it is not.
- Only choices with a single option are not asked: a single accelerator target,
  or no tarballs to resume from. We still ask whether to resume from a tarball
  or start from scratch if there is at least one tarball.

This removes the pairing of tarballs with accelerator targets, the suggested
defaults and the warnings about assumptions, position_of() and the
canonicalization of the tarball paths that was only needed for lookups. The
options are now only listed when we need to ask for them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…TOR_TARGET_OVERRIDE

EESSI_INTERACTIVE_BUILD_ACCELERATOR now takes the full name (e.g. accel/nvidia/cc80),
consistent with EESSI_ACCELERATOR_TARGET_OVERRIDE and with the names listed when asking.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@casparvl
casparvl requested a review from Neves-P October 12, 2026 18:48
@casparvl
casparvl marked this pull request as ready for review October 12, 2026 18:48
@Neves-P

Neves-P commented Oct 14, 2026

Copy link
Copy Markdown
Member

I tried this out using the RUG Zen5 bot that builds for RTX6000 acel builds and it worked fine. Note: I didn't easily find a failed build, so I tried the shell and before options which dropped me where I expected to be dropped.

One thing I noticed, after interrupting a build (^C) it seems to start again the build process again and I couldn't figure out why. Do you also see this @casparvl ?

@laraPPr

laraPPr commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

Testing this now for LAMMPS. It works from the bot account like a charm. But if you try running it from another account you run into trouble.

@laraPPr

laraPPr commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

Oh this is anoying when you exit before it continues and now I'm stuck until LAMMPS fails in an hour let me try killing the proccess.

@casparvl

Copy link
Copy Markdown
Contributor Author

Is it a bug, or is it a feature? Yes, the build continues after you exit the debug shell. It is essentially a breakpoint that enables you to play around, then continue the build process. Maybe we can make that behaviour dependent on (another) environment variable, I don't know how EESSI that will be. For now, I think this is better than nothing - you might actually want to continue the build process, because you want to know if you encounter more bugs, or if you fixed anything by whatever you did interactively.

I agree though that it is extremely annoying that a ctrl+C doesn't work. I'm not sure why that is happening, and if it can easily be resolved. I'll check with my AI friend....

Caspar van Leeuwen and others added 2 commits October 15, 2026 17:06
The debug shell has job control, so it makes its own process group the terminal's
foreground group. That group was left behind as the foreground group after the shell
exited, so Ctrl+C no longer reached the build (observed: TPGID pointing at an empty
process group). Explicitly set our own process group as the foreground group again.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Interactive build: give the terminal back after the debug shell exits
@casparvl

Copy link
Copy Markdown
Contributor Author

Tried to fix it, it didn't work. The AI couldn't replicate it outside our container+startprefix environment anyway, so it was a bit of guess work in debugging. I'll look further next week.

Caspar van Leeuwen and others added 3 commits October 19, 2026 13:50
With job control the debug shell makes its own process group the terminal's foreground group
and tries to hand the terminal back to our group on exit. Inside the container that group is
not visible (created outside the PID namespace, getpgrp() returns 0), so the hand-back fails
and Ctrl+C no longer reaches the build after exiting the debug shell. Starting the debug
shell with +m means it never takes the terminal, so there is nothing to restore.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…t come first

'bash +m --rcfile ...' fails with "bash: --: invalid option": bash only accepts its
GNU long options (--rcfile) before the short options (+m).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@casparvl

Copy link
Copy Markdown
Contributor Author

This seems to be really tricky. If I understand things correctly, the reason that the ctrl+C isn't working is because after existing the debug shell is that a ctrl+C kills process that are in the same process group as your tty. Once the debug shell takes control, that's a different process group than the one running the EasyBuild process (and the container, and startprefix, etc, etc). That's fine: this means you could run manual commands there, and press ctrl+C to kill your manual process, without killing your entire container along with it.

The issue is that once you exit the debug shell, you want it to hand control back to the process group runnin EasyBuild/container/startprefix. That seems to happen automatically in a regular shell - but doesn't happen here since we are in a container. Claude then tried to 'force' it with a small python snippet in ec9035c but that failed with:

  tcsetpgrp: fg=882 mine=0
  Traceback (most recent call last):
    File "<string>", line 5, in <module>
      os.tcsetpgrp(fd, os.getpgrp())
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  ProcessLookupError: [Errno 3] No such process
  tcsetpgrp snippet failed (python3: /cvmfs/software.eessi.io/versions/2025.06/compat/linux/x86_64/usr/bin/python3)

This made Claude understand the issue: that process group doesn't exist IN the container, so we can't hand control back to it.

Then, it tried to add +m to run a shell without job control. The way I understand is that this would run the debug shell without job control "so that there is nothing to give back". Alas, it failed in the same way.

Claude is now churning on trying to actually reproduce the behavior itself using unsare, so it can do more fast trial-and-error. Seems it's getting somewhere, so I expect I will follow up on this message with another commit that attempts to fix things.

An interactive bash takes over the terminal (own process group becomes the foreground
group) and hands it back to its original group on exit. Inside the container that group
is not visible (our group was created outside the PID namespace, getpgrp() returns 0), so
the hand-back fails and Ctrl+C no longer reaches the build after exiting the debug shell.
'bash +m -i' does not avoid this, an interactive bash still takes over the terminal.

Use python's pty.spawn so the debug shell's job control only affects a pty of its own, and
pass the window size of the real terminal on via the rcfile. Verified in a PID namespace
(unshare --pid): Ctrl+C interrupts the build after exiting the debug shell, and Ctrl+C on a
command inside the debug shell leaves the shell alive.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants