The recent issue with pthread_atfork handlers reminded me of a scenario
that I know glibc handles, but it seems that Cygwin does not.  Test case:

== test.c ==
#include <dlfcn.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

typedef void(*func_type)(void);

int main(void)
{
  int wstatus = 0;
  func_type func = NULL;
  void *handle = dlopen("./testlib.so", RTLD_LAZY);
  if (!handle)
  {
    fprintf(stderr, "dlopen error: %s\n", dlerror());
    return 1;
  }

  func = (func_type)dlsym(handle, "func");
  if (!func)
  {
    fprintf(stderr, "dlsym error: %s\n", dlerror());
    return 1;
  }

  func();

  if (dlclose(handle))
  {
    fprintf(stderr, "dlclose error: %s\n", dlerror());
    return 1;
  }

  switch (fork())
  {
  case -1:
    perror("fork");
    return 1;
  case 0:
    printf("Hi from child!\n");
    return 0;
  default:
    if (wait(&wstatus) == -1)
    {
      perror("wait");
      return 1;
    }
    printf ("wstatus %d\n", wstatus);
    return WIFSIGNALED(wstatus) ? 128 + WTERMSIG(wstatus) : 
WEXITSTATUS(wstatus);
  }

  /* should not get here */
  return 123;
}

== testlib.c ==
#include <pthread.h>
#include <stdio.h>

static void prepare(void)
{
  printf("in prepare\n");
}

static void parent(void)
{
  printf("in parent\n");
}

static void child(void)
{
  printf("in child\n");
}

void func(void)
{
  int ret;
  if (ret = pthread_atfork(prepare, parent, child))
    fprintf(stderr, "pthread_atfork returned %d\n", ret);
}

== build commands ==
gcc -fPIC -shared -o testlib.so testlib.c
gcc -o test test.c
./test

== linux output ==
$ ./test
Hi from child!
wstatus 0

== Cygwin 3.6.1 output ==
$ ./test
$ echo $?
0
$ # WTF?
$ gdb ./test
...
(gdb) r

Thread 1 "test" received signal SIGSEGV, Segmentation fault.
0x00000004219b1030 in ?? ()
(gdb) bt
#0  0x00000004219b1030 in ?? ()
#1  0x00000001800ad1b2 in pthread::atforkprepare ()
    at ../../.././winsup/cygwin/thread.cc:2091
#2  0x000000018006bdcd in lock_pthread::lock_pthread (this=<synthetic pointer>)
    at 
/d/a/msys2-runtime/msys2-runtime/winsup/cygwin/local_includes/sigproc.h:136
#3  hold_everything::hold_everything (x=<synthetic pointer>: <optimized out>,
    this=<synthetic pointer>)
    at 
/d/a/msys2-runtime/msys2-runtime/winsup/cygwin/local_includes/sigproc.h:168
#4  dofork (proc=proc@entry=0x0,
    with_forkables=with_forkables@entry=0x7ffffcb9f)
    at ../../.././winsup/cygwin/fork.cc:640
#5  0x000000018006c239 in fork () at ../../.././winsup/cygwin/fork.cc:590
#6  0x000000018019f564 in _sigfe () at sigfe.s:35
#7  0x000000010040117e in main ()

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to