[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Infinite loop with error trap and subshell

From: Chet Ramey
Subject: Re: Infinite loop with error trap and subshell
Date: Sat, 30 Oct 2021 16:03:53 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.2.1

On 10/29/21 6:29 PM, Samir Aguiar wrote:

We have a script that prints the call stack inside an ERR trap. The code invokes the `caller` built-in in a while loop that is piped to another while loop, which uses `read` to parse the output of `caller` and pretty-print it. However, after updating to Bash 5.1 the script now leads to an infinite number of processes being spawn and the error handler being called over and over. Prior to that version this did not happen.

OK. First, the function inherits the ERR trap because of the `extdebug'
setting. The subshell that's started to run the while loop in the pipeline
inherits the ERR trap from its parent (the shell function) and is where the
ERR trap gets triggered again, and where the `knowledge' that the shell is
running a trap handler is discarded.

There is a discussion about inheriting trap handlers and allowing recursive
trap handler calls at

My colleague Philipp Gesang and I have come up with a sample script to reproduce the problem. The ERR trap will create a flag file when it gets called again to indicate that infinite forking *would* occur, in which case it will exit with 99. An exit code of 0 means that nothing wrong would happen. The invocation of `/bin/false` (or similar) inside the while loop is mandatory for the problem to be triggered.

The question is whether or not the subshell should `know' that it's
executing as part of a trap handler. The reason it might need to know this,
as you discovered, is so the internal function responsible for running trap
handlers can suppress recursive trap handlers.

A subshell is created as a copy of its parent, including state, though trap
handlers are usually reset to their inherited values (in this case, the
extdebug setting inhibits that resetting for the shell's special signals,
so the subshell keeps the ERR trap).

Should trap handlers be able to run recursively? That is, in an ERR trap
handler (which is a special pseudo-signal), should a failing command cause
the trap handler to run again? This is how other trap handlers behave.

If trap handlers should be allowed to run recursively, should that extend
to the special shell pseudo-signals (ERR/RETURN/DEBUG) or be restricted to
the ones that correspond to actual signals? The shell allows the special
pseudo-signals to run trap handlers recursively.

If you put these things together, you see what happens. The subshell
started to run the forked while loop inherits the ERR trap `forgets' that
it's running a trap handler to allow recursive trap handlers.

So what about this process should be changed?

``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU

reply via email to

[Prev in Thread] Current Thread [Next in Thread]