threads/65883: libkse's sigwait does not work after fork
Max Fomitchev
max.fomitchev at kaspersky.com
Thu Apr 22 05:50:21 PDT 2004
>Number: 65883
>Category: threads
>Synopsis: libkse's sigwait does not work after fork
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-threads
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Apr 22 05:50:21 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator: Max Fomitchev
>Release: 5.1-RELEASE, 5.2-RELEASE, 5-CURRENT
>Organization:
Kaspersky Labs
>Environment:
FreeBSD freebsd-smtpgw.testlab2k.avp.ru 5.1-RELEASE FreeBSD 5.1-RELEASE #0: Thu Jun 5 02:55:42 GMT 2003 root at wv1u.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC i386
>Description:
sigwait() call cannot receive a signal after fork() if the following code (simplified model of my current application) linked with libkse. This code works well with a various thread libraries (libc_r for example).
Another interesting feature, if you do not start threads explicitly at all, sigwait() will receive SIGINT from the scheduler(???) and the program exits.
//kse_test.c begin
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
static pthread_mutex_t m_lock;
static int ended;
static void *thr (void *arg)
{
for (;;)
{
pthread_mutex_lock(&m_lock);
if (ended == 1)
{
pthread_mutex_unlock(&m_lock);
break;
}
pthread_mutex_unlock(&m_lock);
sleep(1);
}
return NULL;
}
static int dmn()
{
switch (fork())
{
case 0: break;
case -1: return -1;
default: _exit(0);
}
if (setsid() < 0)
return -1;
switch (fork())
{
case 0: break;
case -1: return -1;
default: _exit(0);
}
return 0;
}
static int close_ios()
{
int fd_l = 0;
int fd = 0;
errno = 0;
chdir("/");
fd_l = sysconf(_SC_OPEN_MAX);
if ((fd_l < 0) || (errno != 0))
return -1;
for (fd = 0; fd < fd_l; fd++)
close(fd);
return 0;
}
static void signal_manager()
{
int sign = 0;
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGINT); //exit
sigprocmask(SIG_BLOCK, &sigs, NULL);
for (;;)
{
sigwait(&sigs, &sign);
switch (sign)
{
case SIGINT:
pthread_mutex_lock(&m_lock);
ended = 1;
pthread_mutex_unlock(&m_lock);
return;
default: continue;
}
}
}
int main(int argc, const char *argv[])
{
pthread_mutexattr_t mattr;
pthread_attr_t pattr;
pthread_t tid1, tid2;
void *exit_status;
ended = 0;
if (dmn() != 0)
return 10;
if (close_ios() != 0)
return 20;
if ((pthread_attr_init(&pattr) != 0) ||
(pthread_attr_setdetachstate(&pattr,
PTHREAD_CREATE_JOINABLE) != 0))
return 30;
if ((pthread_mutexattr_init(&mattr) != 0) ||
(pthread_mutex_init(&m_lock, &mattr) != 0))
return 40;
if (pthread_create(&tid1, &pattr, thr, NULL) != 0)
return 51;
if (pthread_create(&tid2, &pattr, thr, NULL) != 0)
return 52;
signal_manager();
pthread_join(tid1, &exit_status);
pthread_join(tid2, &exit_status);
return 0;
}
//kse_test.c end
>How-To-Repeat:
bash-2.05b# gcc -v
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.2.2 [FreeBSD] 20030205 (release)
bash-2.05b# gcc kse_test.c -o kse_test -lc_r
bash-2.05b# ldd kse_test
kse_test:
libc_r.so.5 => /usr/lib/libc_r.so.5 (0x2806b000)
libc.so.5 => /usr/lib/libc.so.5 (0x2808e000)
bash-2.05b# ./kse_test; echo $?
0
bash-2.05b# ps -ax | grep kse_test
62277 ?? S 0:00.00 ./kse_test
bash-2.05b# kill -INT 62277
bash-2.05b# ps -ax | grep kse_test
bash-2.05b# gcc kse_test.c -o kse_test -lkse
bash-2.05b# ldd kse_test
kse_test:
libkse.so.1 => /usr/lib/libkse.so.1 (0x2806b000)
libc.so.5 => /usr/lib/libc.so.5 (0x2808b000)
bash-2.05b# ./kse_test; echo $?
0
bash-2.05b# ps -ax | grep kse_test
62288 ?? S 0:00.00 ./kse_test
bash-2.05b# kill -INT 62288
bash-2.05b# ps -ax | grep kse_test
62288 ?? R 0:00.00 ./kse_test
bash-2.05b# kill -9 62288
bash-2.05b# ps -ax | grep kse_test
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-threads
mailing list