Bash: wait ne rend pas la main

Top Page

Reply to this message
Author: Vincent Riquer
Date:  
To: guilde
Subject: Bash: wait ne rend pas la main
Bonjour la liste,

Je rencontre un bug des plus étranges dans un script bash. Le script effectue
des traitements en parallèle. La fin des processus fils est vérifiée par
polling¹ avec kill -0. Je récupère ensuite le statut avec wait :

(Code complet : 
https://forge.riquer.fr/p/AtOM/source/tree/master/lib/workers/check et 
https://forge.riquer.fr/p/AtOM/source/tree/master/lib/workers/destroy)
checkworkers() {
        for key in ${!workers[@]} # workers est un tableau listant les PID des 
                                  # traitements en cours
        do
                if ! kill -0 ${workers[key]} 2>/dev/null
                then
                        if wait ${workers[key]}
                        then
                                # Youpi
                        else
                                # Oops
                        fi
                fi
        done
}


Ça marche très bien 4999 fois sur 5000, mais de temps en temps, wait ne rend
pas la main, alors que le PID en question n'existe plus (n'apparaît pas dans
(h)top, /proc/$PID n'existe pas, …). J'ai vérifié avec strace, Bash est bloqué
sur waitpid(…).

Je suis à la fois incapable de montrer que c'est un bug dans bash ou la libc
et incapable de trouver une quelconque cause dans mon code (si le process
n'existe pas, waitpid() *doit* rendre la main – ou alors j'ai pas compris).

Si vous avez des solutions, des idées d'autres tests à faire, ou juste si vous
avez déjà rencontré le même souci, je suis preneur.

Versions:
$ dpkg -l bash libc6 linux-image-*|grep ii
ii bash                         4.2+dfsg-0.1 amd64 GNU Bourne Again SHell
ii libc6:amd64                  2.17-93      amd64 Embedded GNU C Library: 
Shared libraries
ii linux-image-3.2.0-4-rt-amd64 3.2.51-1     amd64 Linux 3.2 for 64-bit PCs, 
PREEMPT_RT


¹ J'avais d'abord tenté d'utiliser des signaux, mais me suis heurté au fait
que malloc() soit interdit dans ce contexte.