system() call causes core dump

Mel Flynn mel.flynn+fbsd.questions at mailing.thruhere.net
Wed Nov 4 00:49:51 UTC 2009


On Saturday 31 October 2009 21:52:37 Peter Steele wrote:
> >In UNIX it is not safe to perform arbitrary actions after forking a
> > multi-threaded process.  You're basically expected to call exec soon
> > after the fork, although you can do certain other work if you are very
> > careful.
> >
> >The reason for this is that after the fork, only one thread will be
> > running in the child, and if that thread tries to acquire a lock or other
> > formerly-shared resource it may deadlock or crash, because the child
> > process is no longer accessing the same memory location as the threads in
> > the parent process (it gets a separate copy of the address space at the
> > time of fork, which may not be in a consistent state from the point of
> > view of the thread library).
> 
> I am not calling fork explicitly. The thread I'm running in was created
>  with pthread_create(). The fork() in the stack trace in my original email
>  is being called by the system() function as it spawns off the process it
>  is supposed want to run. Is there a safe way to call system() within a
>  pthread?

Either I'm very lucky, or popen is better suited for this, as I have this 
running on various machines, 24/7:

#define PING_CMD \
    "ping -n -c 50 %s 2>/dev/null|egrep 'round-trip|packets received'"

/* worker thread main loop */
void *monitor_host(void *data)
{
...
    if( -1 == asprintf(&cmd, PING_CMD, ip) )
    {
        warnl("Failed to construct command");
        *ex = EX_OSERR;
        return(ex);
    }

....

    while( !signalled )
    {
        if( (cmd_p = popen(cmd, "r")) == NULL )
        {
            warnl("Failed to run command %s", cmd);
            *ex = EX_OSERR;
            return(ex);
        }

        EV_SET(&ch, fileno(cmd_p), EVFILT_READ, EV_ADD|EV_ENABLE,
                0, 0, NULL);
        for( ;; )
        {
            int nev;

            if( signalled ||
                    (nev = kevent(kq, &ch, 1, &ev, 1, &timeout)) == -1 )
            {
                if( signalled == SIGHUP )
                    goto closeproc;
                else
                    goto cleanup;
            }

            if( nev )
                break;
        }
        /* read fp, store in db */
    }
}
-- 
Mel


More information about the freebsd-questions mailing list