1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
Index: coregrind/m_syswrap/syswrap-generic.c
===================================================================
--- coregrind/m_syswrap/syswrap-generic.c (revision 10399)
+++ coregrind/m_syswrap/syswrap-generic.c (working copy)
@@ -2558,6 +2558,15 @@
} else {
path = (Char*)ARG1;
+ if (VG_(clo_xml)) {
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "<execv/>");
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "</valgrindoutput>");
+ VG_(message)(Vg_UserMsg, "");
+ } else {
+ VG_(message)(Vg_UserMsg, "execv called - the tool will now quit");
+ }
}
// Set up the child's environment.
@@ -4093,4 +4102,3 @@
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
-
Index: coregrind/m_main.c
===================================================================
--- coregrind/m_main.c (revision 10399)
+++ coregrind/m_main.c (working copy)
@@ -755,15 +755,26 @@
If logging to file or a socket, write details of parent PID and
command line args, to help people trying to interpret the
results of a run which encompasses multiple processes. */
-static void print_preamble(Bool logging_to_fd, const char* toolname)
+
+// TODO(timurrrr): we add a non-static declaration of this function since
+// we need it in coregrind/m_libcproc.c
+// Should we move it to some header file?
+void print_preamble(Bool logging_to_fd, const char* toolname);
+
+void print_preamble(Bool logging_to_fd, const char* toolname)
{
HChar* xpre = VG_(clo_xml) ? " <line>" : "";
HChar* xpost = VG_(clo_xml) ? "</line>" : "";
Int i;
+ static const char* last_toolname = NULL;
vg_assert( VG_(args_for_client) );
vg_assert( VG_(args_for_valgrind) );
+ // This way you may pass toolname == NULL provided the first invocation
+ // with toolname != NULL takes place in valgrind_main().
+ toolname = (toolname == NULL ? last_toolname : toolname);
vg_assert( toolname );
+ last_toolname = toolname;
if (VG_(clo_xml)) {
VG_(message)(Vg_UserMsg, "<?xml version=\"1.0\"?>");
Index: coregrind/m_libcproc.c
===================================================================
--- coregrind/m_libcproc.c (revision 10399)
+++ coregrind/m_libcproc.c (working copy)
@@ -33,9 +33,12 @@
#include "pub_core_vkiscnums.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
+#include "pub_core_libcfile.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h"
#include "pub_core_libcsignal.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_options.h"
#include "pub_core_seqmatch.h"
#include "pub_core_mallocfree.h"
#include "pub_core_syscall.h"
@@ -703,10 +706,59 @@
(*atforks[i].parent)(tid);
}
+// Defined in m_main.c
+void print_preamble(Bool logging_to_fd, const char* toolname);
+
+// If --log-file=ABC%pXYZ is specified, we'd like to have separate log files
+// for each forked child.
+// If %p is present in the --log-file option, this function creates
+// a new log file and redirects the child's output to it.
+static void open_new_logfile_for_forked_child(void)
+{
+ SysRes sres;
+ Int tmp_log_fd = -1;
+ Char *logfilename, *clo_log_name;
+
+ clo_log_name = VG_(clo_log_name);
+ if (clo_log_name == NULL || !VG_(strstr)(clo_log_name, "%p")) {
+ // Don't create new log streams unless --log-file=ABC%pXYZ is specified.
+ return;
+ }
+
+ logfilename = VG_(expand_file_name)("--log-file", clo_log_name);
+ sres = VG_(open) (logfilename,
+ VKI_O_CREAT | VKI_O_WRONLY | VKI_O_TRUNC,
+ VKI_S_IRUSR | VKI_S_IWUSR);
+ if (!sr_isError(sres)) {
+ tmp_log_fd = sr_Res(sres);
+ // Move log_fd into the safe range,
+ // so it doesn't conflict with any app fds.
+ tmp_log_fd = VG_(fcntl) (tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
+ if (tmp_log_fd >= 0) {
+ VG_(clo_log_fd) = tmp_log_fd;
+ VG_(fcntl) (VG_(clo_log_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
+ } else {
+ VG_(message) (Vg_UserMsg,
+ "valgrind: failed to move logfile fd into safe range, "
+ "using stderr");
+ VG_(clo_log_fd) = 2; // stderr
+ }
+ } else {
+ VG_(message) (Vg_UserMsg,
+ "Can't create log file '%s' (%s); giving up!",
+ logfilename, VG_(strerror) (sr_Err(sres)));
+ VG_(core_panic)("Error creating log file for child process");
+ }
+
+ print_preamble(False, NULL);
+}
+
void VG_(do_atfork_child)(ThreadId tid)
{
Int i;
+ open_new_logfile_for_forked_child();
+
for (i = 0; i < n_atfork; i++)
if (atforks[i].child != NULL)
(*atforks[i].child)(tid);
|