From 29ff6066e97cabd82bfe78de4392599107916632 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sat, 17 Nov 2007 22:29:25 +0000 Subject: [PATCH] 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 --- coregrind/m_libcprint.c | 7 ++++++- coregrind/m_main.c | 5 ++++- coregrind/m_options.c | 3 ++- coregrind/m_syswrap/syswrap-aix5.c | 9 +++++++++ coregrind/m_syswrap/syswrap-generic.c | 9 +++++++++ coregrind/m_syswrap/syswrap-linux.c | 7 +++++++ coregrind/pub_core_options.h | 6 ++++++ 7 files changed, 43 insertions(+), 3 deletions(-) diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c index a5129ef66..5ba8bb11d 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 ca9dc4b98..50f6cbb21 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 f5ed2846b..febf82c7d 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 2ac521a6c..a5617db08 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 936539412..ccea5c5fb 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 96cbe3714..c1769e5a8 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 09b97fcd1..15d33f6b1 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.