• А кто-нибудь сталкивался с такой фигнёй на linux:
    — есть parent и child process.
    — child уже zombie: "1775 ? Zl 0:00 [sandbox_worker] <defunct>", все треды у него в том же состоянии.
    — wait() в parent этого неудачника не подбирает
    — если сделать kill -9 1775, то wait() внезапно срабатывает и зомби подчищается.

    Я что-то не врубаюсь, как такое может случиться.
    ♡ recommended by @oxpa

Replies (6)

  • @blaze, Я не сталкивался, так что пальцем в небо. А треды у него джойнуты?
  • @Kim, Некому join уже делать. Все сдохли.
  • @blaze, Ну собственно вот что случилось go.googlesource.com

    If the main thread exits using pthread_exit, then it enters a non-waitable zombie state. It will still produce an immediate PTRACE_O_TRACEEXIT event, but the WIFEXITED event will be delayed until the entire process exits. This state exists so that shells don't think the process is done until all of the threads have exited.

    То есть хоть один живой тред у тебя всё таки остался.

    Вот в качестве примера:

    $ cat test.c
    #include <pthread.h>
    void *PrintHello(void *threadid)
    {
    sleep(10);
    pthread_exit(NULL);
    }
    int main (int argc, char *argv[])
    {
    pthread_t thread;
    pthread_create(&thread, NULL, PrintHello, NULL);
    pthread_exit(NULL);
    }
    $ gcc test.c -lpthread
    $ ./a.out & sleep 1 ; for f in proc$!/task/*/stat; do echo "$f: $(cut -d' ' -f2,3 $f)"; done
    /proc/21343/task/21343/stat: (a.out) Z
    /proc/21343/task/21345/stat: (a.out) S
  • @Kim, Хотел было сказать, что это не так, но при внимательном разглядывании и правда есть какие-то живые треды.

    Но это работает только если main thread делает pthread_exit(), а у меня ничего подобного не происходит. Он или убит сигналом, или сделал обычный return из main().
  • @blaze, Ну смотри, живые треды есть, значит точка найдена правильная. Дальше нужо либо найти где ты вызвал pthread_exit (например в atexit или в обработчике сигнала), либо раскурить как в данное состояние нас заводит pthread_exit.

    От тебя столько инфы, что у тебя там может быть что-нибудь не-сишное где рантайм языка сам дёрнул pthread_exit
  • @Kim, BTW, мы докопались тут до причин и оказалось, что все смотревшие на этот глюк неправильно понимали как работают процессы и потоки в linux.

    Процесс жив до тех пор, пока в нём жив хотя бы один тред. Вообще любой, ядру пофиг housekeeping это от malloc или ещё чего. Detached тоже ни на что не влияет.

    Единственная причина, по которой завершение главного треда в норме выпиливает процесс — libc на выходе из main вызывает sys_exit_group. А у других потоков нет.

    Мой мир никогда не будет прежним.