Date: Wed, 4 Nov 2009 01:49:48 +0100 From: Mel Flynn <mel.flynn+fbsd.questions@mailing.thruhere.net> To: freebsd-questions@freebsd.org Cc: Peter Steele <psteele@maxiscale.com> Subject: Re: system() call causes core dump Message-ID: <200911040149.48701.mel.flynn%2Bfbsd.questions@mailing.thruhere.net> In-Reply-To: <7B9397B189EB6E46A5EE7B4C8A4BB7CB327D11A9@MBX03.exg5.exghost.com> References: <7B9397B189EB6E46A5EE7B4C8A4BB7CB327D117F@MBX03.exg5.exghost.com> <4AEC5E02.8040705@FreeBSD.org> <7B9397B189EB6E46A5EE7B4C8A4BB7CB327D11A9@MBX03.exg5.exghost.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911040149.48701.mel.flynn%2Bfbsd.questions>
