From: Julian Seward Date: Sun, 3 Nov 2002 11:44:36 +0000 (+0000) Subject: Robustification of logging to a socket. If the listener process dies X-Git-Tag: svn/VALGRIND_1_9_4~174 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=72edb7fc20d693b8395b7c4e3cea171cd44a6bb2;p=thirdparty%2Fvalgrind.git Robustification of logging to a socket. If the listener process dies or for whatever reason hangs up the connection, don't let valgrind get SIGPIPE; instead just switch back to spewing messages on stderr. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1273 --- diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 2793b9ada3..d9ff25bca5 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -875,11 +875,21 @@ extern Int VG_(select)( Int n, extern Int VG_(nanosleep)( const struct vki_timespec *req, struct vki_timespec *rem ); -extern Int VG_(write_socket)( Int sd, void *msg, Int count ); +extern Int VG_(write_socket)( Int sd, void *msg, Int count ); /* --- Connecting over the network --- */ extern Int VG_(connect_via_socket)( UChar* str ); + +/* --------------------------------------------------------------------- + Exports of vg_message.c + ------------------------------------------------------------------ */ + +/* Low-level -- send bytes directly to the message sink. Do not + use. */ +extern void VG_(send_bytes_to_logging_sink) ( Char* msg, Int nbytes ); + + /* --------------------------------------------------------------------- Definitions for the JITter (vg_translate.c, vg_to_ucode.c, vg_from_ucode.c). diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index 30fcac7363..85eebc174e 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -1102,14 +1102,18 @@ static void process_cmd_line_options ( void ) } if (eventually_logfile_fd == -2) { VG_(message)(Vg_UserMsg, - "Failed to connect to logging server `%s'; giving up", + "valgrind: failed to connect to logging server `%s'.", VG_(clo_logfile_name) ); - VG_(bad_option)( - "--logsocket= (timeout during connect)"); - } - vg_assert(eventually_logfile_fd > 0); - VG_(clo_logfile_fd) = eventually_logfile_fd; - VG_(logging_to_filedes) = False; + VG_(message)(Vg_UserMsg, + "Log messages will sent to stderr instead." ); + VG_(message)(Vg_UserMsg, + "" ); + /* We don't change anything here. */ + } else { + vg_assert(eventually_logfile_fd > 0); + VG_(clo_logfile_fd) = eventually_logfile_fd; + VG_(logging_to_filedes) = False; + } break; } diff --git a/coregrind/vg_messages.c b/coregrind/vg_messages.c index 02e79c8e2c..5f1ba2bfc9 100644 --- a/coregrind/vg_messages.c +++ b/coregrind/vg_messages.c @@ -86,12 +86,28 @@ void VG_(end_msg) ( void ) { if (VG_(clo_logfile_fd) >= 0) { add_to_buf('\n'); - if (VG_(logging_to_filedes)) - VG_(write)( - VG_(clo_logfile_fd), vg_mbuf, VG_(strlen)(vg_mbuf)); - else - VG_(write_socket)( - VG_(clo_logfile_fd), vg_mbuf, VG_(strlen)(vg_mbuf)); + VG_(send_bytes_to_logging_sink) ( + vg_mbuf, VG_(strlen)(vg_mbuf) ); + } +} + + +/* Do the low-level send of a message to the logging sink. */ +void VG_(send_bytes_to_logging_sink) ( Char* msg, Int nbytes ) +{ + Int rc; + if (VG_(logging_to_filedes)) { + VG_(write)( VG_(clo_logfile_fd), msg, nbytes ); + } else { + rc = VG_(write_socket)( VG_(clo_logfile_fd), msg, nbytes ); + if (rc == -1) { + /* for example, the listener process died. Switch back to + stderr. */ + VG_(logging_to_filedes) = True; + VG_(clo_log_to) = VgLogTo_Fd; + VG_(clo_logfile_fd) = 2; + VG_(write)( VG_(clo_logfile_fd), msg, nbytes ); + } } } diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c index 1bcf0372c2..aea7c63385 100644 --- a/coregrind/vg_mylibc.c +++ b/coregrind/vg_mylibc.c @@ -631,12 +631,8 @@ static void add_to_myprintf_buf ( Char c ) { if (n_myprintf_buf >= 100-10 /*paranoia*/ ) { if (VG_(clo_logfile_fd) >= 0) { - if (VG_(logging_to_filedes)) - VG_(write) - (VG_(clo_logfile_fd), myprintf_buf, VG_(strlen)(myprintf_buf)); - else - VG_(write_socket) - (VG_(clo_logfile_fd), myprintf_buf, VG_(strlen)(myprintf_buf)); + VG_(send_bytes_to_logging_sink)( + myprintf_buf, VG_(strlen)(myprintf_buf) ); } n_myprintf_buf = 0; myprintf_buf[n_myprintf_buf] = 0; @@ -656,12 +652,7 @@ UInt VG_(printf) ( const char *format, ... ) ret = VG_(vprintf) ( add_to_myprintf_buf, format, vargs ); if (n_myprintf_buf > 0 && VG_(clo_logfile_fd) >= 0) { - if (VG_(logging_to_filedes)) - VG_(write) - ( VG_(clo_logfile_fd), myprintf_buf, n_myprintf_buf); - else - VG_(write_socket) - ( VG_(clo_logfile_fd), myprintf_buf, n_myprintf_buf); + VG_(send_bytes_to_logging_sink)( myprintf_buf, n_myprintf_buf ); } va_end(vargs); @@ -1455,6 +1446,7 @@ struct vki_in_addr { /* kernel, include/linux/socket.h */ typedef unsigned short vki_sa_family_t; #define AF_INET 2 /* Internet IP Protocol */ +#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ /* kernel, ./include/asm-i386/socket.h */ #define SOCK_STREAM 1 /* stream (connection) socket */ @@ -1625,7 +1617,12 @@ Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int VG_(write_socket)( Int sd, void *msg, Int count ) { /* This is actually send(). */ - Int flags = 0; + + /* Requests not to send SIGPIPE on errors on stream oriented + sockets when the other end breaks the connection. The EPIPE + error is still returned. */ + Int flags = MSG_NOSIGNAL; + Int res; UInt args[4]; args[0] = sd;