• bash: trap recursion leads to segfault

    From vallor@vallor@cultnix.org to comp.unix.shell on Wed Sep 24 07:16:25 2025
    From Newsgroup: comp.unix.shell

    $ ./try.sh
    ^CSegmentation fault (core dumped)

    - ->% cut here %<- -
    #!/bin/bash

    thandler() {
    #trap SIGHUP
    kill -1 0
    }

    sleep 1000000 &
    trap thandler SIGPIPE SIGHUP SIGINT EXIT

    sleep 30
    - ->% cut here %<- -

    If I uncomment the SIGHUP reset in the trap handler,
    it works fine.

    Is that expected behavior, to reset a trap after trapping
    a signal?

    (BTW, this is a demonstration -- in my actual script, I have
    an ssh command running in the background to do port-forwarding,
    and my main process is vncviewer from tigervnc, using the
    ssh connection.)
    --
    -v
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Wed Sep 24 16:51:48 2025
    From Newsgroup: comp.unix.shell

    On 2025-09-24, vallor <vallor@cultnix.org> wrote:
    $ ./try.sh
    ^CSegmentation fault (core dumped)

    - ->% cut here %<- -
    #!/bin/bash

    thandler() {
    #trap SIGHUP
    kill -1 0
    }

    sleep 1000000 &

    This line is not necessary for repro.

    trap thandler SIGPIPE SIGHUP SIGINT EXIT

    sleep 30
    - ->% cut here %<- -

    If I uncomment the SIGHUP reset in the trap handler,
    it works fine.

    Is that expected behavior, to reset a trap after trapping
    a signal?

    The script raises raising a trapped signal while still executing its
    signal handler. That's going to have to put new signal handling material
    on the stack, so if that repeats, the stack will exhaust.

    Suggested fix to stop the recursion: register a separate trap command
    for each signal which passes the signal. The in the handler, avoid
    raising SIGHUP if that is the signal already being handled:

    #!/bin/bash

    thandler() {
    local sig=$1
    printf "caught %s\n" $sig

    if [ $sig != SIGHUP ] ; then
    kill -HUP 0
    fi
    }

    for sig in SIGPIPE SIGHUP SIGINT EXIT; do
    trap "thandler $sig" $sig
    done

    sleep 30


    Test:

    $ ./trapseg.sh
    ^Ccaught SIGINT
    caught SIGHUP
    caught EXIT
    caught SIGHUP
    !130!
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2