Skip site navigation (1)Skip section navigation (2)
Date:      08 Feb 2002 07:46:34 +0200
From:      Maxim Sobolev <sobomax@FreeBSD.org>
To:        jdp@FreeBSD.org, deischen@FreeBSD.org, jasone@FreeBSD.org, hackers@FreeBSD.org, jlemon@FreeBSD.org
Subject:   Linking libc before libc_r into application causes weird problems
Message-ID:  <1013147180.73417.2.camel@notebook>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi,

When working on updating port of Ximian Evolution to the latest released
version I have stuck to the problem - the new version of application
just hanged on startup on my 5-CURRENT box. After lot of digging and
debugging I found that the source of the problem is that the resulting
application had libc linked in before libc_r, which caused waitpid() in
the ORBit library just hang forever, even though child process died
almost instantly (I see zombie in the ps(1) output). When program was
relinked with -pthread flag, which seemingly forcing "right" order of
libc/libc_r (libc_r first) the problem disappeared. 

Based on the problematic code in the ORBit I had prepared short testcase
illustrating the problem and attaching it with this message. The problem
could be exposed by compiling the test.c using the following command: 

$ cc test.c -o test -lc -lc_r 

When either of -lc or -lc_r is omitted, or their order is reversed the
problem disappears. The problem doesn't exist on 4-STABLE. 

Any ideas, comments and suggestions are welcome. 

Thanks!

-Maxim



[-- Attachment #2 --]
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

int main()
{
    int childpid, exitstatus, itmp;
    sigset_t mask, omask;

    /* Block SIGCHLD so no one else can wait() on the child before we do. */
    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &mask, &omask);

    childpid = fork();

    if(!childpid) {
	int i;

	/* Do something useful */
	sleep(1);

	_exit(0);
    }

    while ((itmp = waitpid(childpid, &exitstatus, 0)) == -1 && errno == EINTR)
	continue;
    sigprocmask (SIG_SETMASK, &omask, NULL);
    exit(WEXITSTATUS(exitstatus));
}

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1013147180.73417.2.camel>