From: Julian Seward Date: Sat, 17 Nov 2007 22:29:25 +0000 (+0000) Subject: Add a new flag, --child-silent-after-fork=no|yes [no]. When enabled, X-Git-Tag: svn/VALGRIND_3_3_0~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29ff6066e97cabd82bfe78de4392599107916632;p=thirdparty%2Fvalgrind.git Add a new flag, --child-silent-after-fork=no|yes [no]. When enabled, causes child processes after fork to fall completely silent, which can make the output a lot less confusing. In addition it is pretty much essential in XML output mode, so as to avoid mixing up any child XML output with the parent's. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7177 --- diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c index a5129ef66a..5ba8bb11d5 100644 --- a/coregrind/m_libcprint.c +++ b/coregrind/m_libcprint.c @@ -53,7 +53,12 @@ Bool VG_(logging_to_socket) = False; static void send_bytes_to_logging_sink ( Char* msg, Int nbytes ) { if (!VG_(logging_to_socket)) { - VG_(write)( VG_(clo_log_fd), msg, nbytes ); + /* VG_(clo_log_fd) could have been set to -1 in the various + sys-wrappers for sys_fork, if --child-silent-after-fork=yes + is in effect. That is a signal that we should not produce + any more output. */ + if (VG_(clo_log_fd) >= 0) + VG_(write)( VG_(clo_log_fd), msg, nbytes ); } else { Int rc = VG_(write_socket)( VG_(clo_log_fd), msg, nbytes ); if (rc == -1) { diff --git a/coregrind/m_main.c b/coregrind/m_main.c index ca9dc4b98d..50f6cbb218 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -114,7 +114,8 @@ static void usage_NORETURN ( Bool debug_help ) " --version show version\n" " -q --quiet run silently; only print error msgs\n" " -v --verbose be more verbose, incl counts of errors\n" -" --trace-children=no|yes Valgrind-ise child processes? [no]\n" +" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n" +" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n" " --track-fds=no|yes track open file descriptors? [no]\n" " --time-stamp=no|yes add timestamps to log messages? [no]\n" " --log-fd= log messages to file descriptor [2=stderr]\n" @@ -370,6 +371,8 @@ static Bool process_cmd_line_options( UInt* client_auxv, const char* toolname ) else VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) else VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) else VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) + else VG_BOOL_CLO(arg, "--child-silent-after-fork", + VG_(clo_child_silent_after_fork)) else VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) else VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) else VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) diff --git a/coregrind/m_options.c b/coregrind/m_options.c index f5ed2846b2..febf82c7de 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -50,7 +50,8 @@ Bool VG_(clo_xml) = False; HChar* VG_(clo_xml_user_comment) = NULL; Bool VG_(clo_demangle) = True; Bool VG_(clo_trace_children) = False; -Int VG_(clo_log_fd) = 2; +Bool VG_(clo_child_silent_after_fork) = False; +Int VG_(clo_log_fd) = 2; /* must be signed, as -1 is possible. */ Char* VG_(clo_log_name) = NULL; Char* VG_(clo_log_file_qualifier) = NULL; Bool VG_(clo_time_stamp) = False; diff --git a/coregrind/m_syswrap/syswrap-aix5.c b/coregrind/m_syswrap/syswrap-aix5.c index 2ac521a6c9..a5617db081 100644 --- a/coregrind/m_syswrap/syswrap-aix5.c +++ b/coregrind/m_syswrap/syswrap-aix5.c @@ -1321,13 +1321,22 @@ PRE(sys_kfork) /* COPY OF GENERIC */ SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) ); if (SUCCESS && RES == 0) { + /* child */ VG_(do_atfork_child)(tid); /* restore signal mask */ VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); + + /* If --child-silent-after-fork=yes was specified, set the + logging file descriptor to an 'impossible' value. This is + noticed by send_bytes_to_logging_sink in m_libcprint.c, which + duly stops writing any further logging output. */ + if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork)) + VG_(clo_log_fd) = -1; } else if (SUCCESS && RES > 0) { + /* parent */ PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES); /* restore signal mask */ diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 936539412e..ccea5c5fb0 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2895,13 +2895,22 @@ PRE(sys_fork) SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) ); if (SUCCESS && RES == 0) { + /* child */ VG_(do_atfork_child)(tid); /* restore signal mask */ VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); + + /* If --child-silent-after-fork=yes was specified, set the + logging file descriptor to an 'impossible' value. This is + noticed by send_bytes_to_logging_sink in m_libcprint.c, which + duly stops writing any further logging output. */ + if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork)) + VG_(clo_log_fd) = -1; } else if (SUCCESS && RES > 0) { + /* parent */ PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES); /* restore signal mask */ diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 96cbe37149..c1769e5a89 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -333,6 +333,13 @@ SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, /* restore signal mask */ VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); + + /* If --child-silent-after-fork=yes was specified, set the + logging file descriptor to an 'impossible' value. This is + noticed by send_bytes_to_logging_sink in m_libcprint.c, which + duly stops writing any further logging output. */ + if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork)) + VG_(clo_log_fd) = -1; } else if (!res.isError && res.res > 0) { diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index 09b97fcd1f..15d33f6b15 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -61,6 +61,12 @@ extern Int VG_(clo_sanity_level); extern Bool VG_(clo_demangle); /* Simulate child processes? default: NO */ extern Bool VG_(clo_trace_children); +/* After a fork, the child's output can become confusingly + intermingled with the parent's output. This is especially + problematic when VG_(clo_xml) is True. Setting + VG_(clo_child_silent_after_fork) causes children to fall silent + after fork() calls. */ +extern Bool VG_(clo_child_silent_after_fork); /* Where logging output is to be sent to.