nagios and freebsd threads issue : help please ...
M. Warner Losh
imp at bsdimp.com
Mon Aug 22 14:11:55 GMT 2005
So there's something in the list, I've gone through and done a call
tree analysis to show the extensive and pervastive nature of the
functions that nagios calls after fork. I don't know if these are all
problems or not, since I don't know if some of these functions might
be called before the first thread is created with pthread_create.
However, any that are called after that clearly have undefined
behavior.
In message: <Pine.GSO.4.43.0508220654550.27356-100000 at sea.ntplx.net>
Daniel Eischen <deischen at freebsd.org> writes:
: > So, if any of these things is an issue, and you can point to a posix
: > things that says it is an issue, then I think that the problem can be
: > resolved.
:
: You can only execute async-signal-safe functions after a fork()
: from a threaded application. free(), malloc(), popen(), fgets(),
: are not async-signal-safe. The list of async-signal-safe functions
: are here:
:
: http://www.opengroup.org/onlinepubs/009695399/nframe.html
This can really be found at:
http://www.opengroup.org/onlinepubs/009695399/functions/chap02_04.html
The following table defines a set of functions that shall be either
reentrant or non-interruptible by signals and shall be
async-signal-safe. Therefore applications may invoke them, without
restriction, from signal-catching functions:
_Exit, _exit, abort, accept, access, aio_error, aio_return,
aio_suspend, alarm, bind, cfgetispeed, cfgetospeed, cfsetispeed,
cfsetospeed, chdir, chmod, chown, clock_gettime, close, connect,
creat, dup, dup2, execle, execve, fchmod, fchown, fcntl, fdatasync,
fork, fpathconf, fstat, fsync, ftruncate, getegid, geteuid, getgid,
getgroups, getpeername, getpgrp, getpid, getppid, getsockname,
getsockopt, getuid, kill, link, listen, lseek, lstat, mkdir, mkfifo,
open, pathconf, pause, pipe, poll, posix_trace_event, pselect, raise,
read, readlink, recv, recvfrom, recvmsg, rename, rmdir, select,
sem_post, send, sendmsg, sendto, setgid, setpgid, setsid, setsockopt,
setuid, shutdown, sigaction, sigaddset, sigdelset, sigemptyset,
sigfillset, sigismember, sleep, signal, sigpause, sigpending,
sigprocmask, sigqueue, sigset, sigsuspend, sockatmark, socket,
socketpair, stat, symlink, sysconf, tcdrain, tcflow, tcflush,
tcgetattr, tcgetpgrp, tcsendbreak, tcsetattr, tcsetpgrp, time,
timer_getoverrun, timer_gettime, timer_settime, times, umask, uname,
unlink, utime, wait, waitpid, write
[[Note, I reformatted the above ]].
: The restriction on fork() is here (20th bullet down):
:
: http://www.opengroup.org/onlinepubs/009695399/nframe.html
http://www.opengroup.org/onlinepubs/009695399/functions/fork.html
# A process shall be created with a single thread. If a multi-threaded
process calls fork(), the new process shall contain a replica of the
calling thread and its entire address space, possibly including the
states of mutexes and other resources. Consequently, to avoid
errors, the child process may only execute async-signal-safe
operations until such time as one of the exec functions is
called. [THR] [Option Start] Fork handlers may be established by
means of the pthread_atfork() function in order to maintain
application invariants across fork() calls. [Option End]
When the application calls fork() from a signal handler and any of
the fork handlers registered by pthread_atfork() calls a function that
is not asynch-signal-safe, the behavior is undefined.
Later, in the informative section, we have:
When a programmer is writing a multi-threaded program, the first
described use of fork(), creating new threads in the same program,
is provided by the pthread_create() function. The fork() function is
thus used only to run new programs, and the effects of calling
functions that require certain resources between the call to fork()
and the call to an exec function are undefined.
Note, the 'certain resources' here means non-async-signal-safe
functions.
This means that the following functions that nagios calls are unsafe:
In set_macro_environment_var:
malloc, strcpy, strcat, setenv, unsetenv, free
In set_argv_macro_environment:
snprintf
In free_memory (only used in the USE_MEMORY_PERFORMANCE_TWEAKS):
free
In my_system:
alarm,
(in the EMBEDDEDPERL case:
anything that perl can call,
strncpy,
printf)
popen,
strcpy,
fgets,
functions called by set_macro_environment_var,
set_argv_macro_environment, free_memory
In daemon_init:
snprintf, getrlimit, setrlimit, sprintf and anything else
that's done as part of the daemon after daemon_init (I didn't
do a call graph analysis on this).
write_to_logs_and_console
cleanup
broker_program_state
write_to_logs_and_console:
strlen, write_to_all_logs, write_to_console
write_to_log
fopen, fprintf, fclose
write_to_console
write_to_syslog
write_to_all_logs
write_to_syslog, write_to_log
write_to_syslog
syslog
(in the DEBUG0 defined case: printf for nearly all functions)
More information about the freebsd-hackers
mailing list