[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bug in module "misc/syslog.c" of glibc-2.3.1
From: |
Achim Gsell |
Subject: |
Bug in module "misc/syslog.c" of glibc-2.3.1 |
Date: |
Thu, 13 Feb 2003 21:30:37 +0100 |
User-agent: |
KMail/1.5 |
Hi,
today we discussed an odd behavior of the syslog(3) function on the syslog-ng
mailing list. If syslog-ng opens "/dev/log" as a UNIX_DGRAM socket everything
works fine. But if syslog-ng opens "/dev/log" as a UNIX_STREAM socket
messages may be lost after a restart of the daemon. A strace of the program
#include <syslog.h>
int main( int argc, char *argv[] ) {
int cnt=0;
openlog( argv[0], LOG_NDELAY|LOG_PID, LOG_DAEMON );
while( 1 ) {
syslog( LOG_INFO, "%d", ++cnt );
sleep( 5 );
}
return( 0 );
}
reveals the problem:
rt_sigaction(SIGPIPE, {0x804d8d0, [], 0x4000000}, {SIG_DFL}, 8) = 0
send(3, "<30>Feb 13 21:04:15 ./syslog_tes"..., 44, 0) = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) ---
close(3) = 0
sigreturn() = ? (mask now [RTMIN])
rt_sigaction(SIGPIPE, {SIG_DFL}, NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [RTMIN], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [RTMIN], NULL, 8) = 0
nanosleep({5, 0}, <unfinished ...>
Lets take a look into the source:
if (!connected || __send(LogFile, buf, bufsize, 0) < 0)
{
if (connected)
{
/* Try to reopen the syslog connection. Maybe it went
down. */
closelog_internal ();
openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
}
if (!connected || __send(LogFile, buf, bufsize, 0) < 0)
{
closelog_internal (); /* attempt re-open next time */
/*
* Output the message to the console; don't worry
* about blocking, if console blocks everything will.
* Make sure the error reported is the one from the
* syslogd failure.
*/
if (LogStat & LOG_CONS &&
(fd = __open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0)
{
dprintf (fd, "%s\r\n", buf + msgoff);
(void)__close(fd);
}
}
}
if (sigpipe == 0)
__sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
If we are connected and __send() returns with an error, there should be a
connect(2) and a second send(2) in the strace output. But they aren't. The
reason is that __send() returns with a value >= 0 even if send(2) returns
with -1. The "sigpipe_handler()" seems to be non-reentrant! I removed the
"closelog_internal ()" - in my opinion it's unnecessary - from the handler
and everythings works fine.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- syslog.c.orig 2003-02-13 19:49:44.000000000 +0100
+++ syslog.c 2003-02-13 21:25:15.000000000 +0100
@@ -351,7 +351,6 @@
static void
sigpipe_handler (int signo)
{
- closelog_internal ();
}
static void
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Best regards
Achim Gsell
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Bug in module "misc/syslog.c" of glibc-2.3.1,
Achim Gsell <=