[racket] SIGCHLD handler called in stderr

From: Sergey Khorev (sergey.khorev at gmail.com)
Date: Sun Dec 9 11:42:25 EST 2012

Hi Matthew,

>>   if(-1 == write(2, "SIGCHLD handler called (some thread has SIGCHLD
>> unblocked)\n", 59)) {
>
> That message is meant to indicate that something has gone seriously
> wrong.
>
> Can you say more about your platform? Also, if you can get a stack
> context where the printout happens, that would likely be useful.

Ah, ok. It was happeninng so often that I thought it's a normal flow.
The configuration is quite complex and involves other embedded
interpreters but I think I managed to find a small reproducible case
that demonstrates some problem with waitpid and I think it's related
to the SIGCHLD stuff.

Code below fails with "waitpid: No child pocesses" on Ubuntu 12.10 x86
with Racket 5.3.1. Racket 5.2.1 fails even on a single core system but
for 5.3.1 I needed a multicore one.

------------------------------------------------------------------------------------------
#define MZ_PRECISE_GC

#include <scheme.h>
#include <stdio.h>
#include <unistd.h>

#include "mzscheme_base3.c"

int mzscheme_env_main(Scheme_Env *env, int argc, char **argv);
int do_work();

int main(int argc, char **argv)
{
  return scheme_main_setup(1, mzscheme_env_main, argc, argv);
}

static Scheme_Env *static_env = NULL;

int mzscheme_env_main(Scheme_Env *env, int argc, char **argv)
{
  static_env = env;
  char q[1000];

  return do_work();
}

int do_work()
{
  pid_t child;
  Scheme_Object **local = NULL;
  MZ_GC_DECL_REG(1);
  MZ_GC_VAR_IN_REG(0, local);
  MZ_GC_REG();

  declare_modules(static_env);

  if (child = fork())
  {
    int status = 0;
    pid_t pid;
    do
    {
      sleep(1);
      pid = waitpid(child, &status, WNOHANG);
    }
    while (pid == 0);

    if (pid != -1 && WIFEXITED(status))
      printf("Terminated normally\n");
    else
    {
      perror("waitpid");
      printf("Terminated abnormally, pid: %d, status: %d\n", pid, status);
    }
  }
  else
    execve("/bin/true", 0, NULL);


  MZ_GC_UNREG();
  return 0;
}
------------------------------------------------------------------------------------------


On the other hand, the same code but without Racket works fine:

------------------------------------------------------------------------------------------
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
  pid_t child;
  if (child = fork())
  {
    int status = 0;
    pid_t pid;
    do
    {
      sleep(1);
      pid = waitpid(child, &status, WNOHANG);
    }
    while (pid == 0);

    if (pid != -1 && WIFEXITED(status))
      printf("Terminated normally\n");
    else
    {
      perror("waitpid");
      printf("Terminated abnormally, pid: %d, status: %d\n", pid, status);
    }
  }
  else
    execve("/bin/true", 0, NULL);
  return 0;
}

------------------------------------------------------------------------------------------

build command:
gcc mzt3.c -g -O0 -I /usr/local/include/racket -pthread -o mzt3
/usr/local/lib/libracket3m.a -lm -lffi -ldl

Am I missing anything?

Posted on the users mailing list.