OLD | NEW |
| (Empty) |
1 Index: coregrind/m_syswrap/syswrap-generic.c | |
2 =================================================================== | |
3 --- coregrind/m_syswrap/syswrap-generic.c (revision 10880) | |
4 +++ coregrind/m_syswrap/syswrap-generic.c (working copy) | |
5 @@ -2563,6 +2563,11 @@ | |
6 | |
7 } else { | |
8 path = (Char*)ARG1; | |
9 + if (VG_(clo_xml)) { | |
10 + VG_(printf_xml)("\n<execv/>\n\n</valgrindoutput>\n\n"); | |
11 + } else { | |
12 + VG_(umsg)("execv called - the tool will now quit\n"); | |
13 + } | |
14 } | |
15 | |
16 // Set up the child's environment. | |
17 Index: coregrind/pub_core_libcfile.h | |
18 =================================================================== | |
19 --- coregrind/pub_core_libcfile.h (revision 10880) | |
20 +++ coregrind/pub_core_libcfile.h (working copy) | |
21 @@ -41,6 +41,7 @@ | |
22 | |
23 /* Move an fd into the Valgrind-safe range */ | |
24 extern Int VG_(safe_fd) ( Int oldfd ); | |
25 +extern Int reopen_output_fd(Bool xml); | |
26 extern Int VG_(fcntl) ( Int fd, Int cmd, Addr arg ); | |
27 | |
28 /* Convert an fd into a filename */ | |
29 Index: coregrind/m_main.c | |
30 =================================================================== | |
31 --- coregrind/m_main.c (revision 10880) | |
32 +++ coregrind/m_main.c (working copy) | |
33 @@ -313,6 +313,64 @@ | |
34 } | |
35 } | |
36 | |
37 +Int reopen_output_fd(Bool xml) { | |
38 + // Returns FD | |
39 + Char *filename = NULL; | |
40 + Char *fsname_unexpanded = xml ? VG_(clo_xml_fname_unexpanded) : | |
41 + VG_(clo_log_fname_unexpanded); | |
42 + const Char *output_type = xml ? "xml" : "log"; | |
43 + Int ret = -1; | |
44 + SysRes sres; | |
45 + | |
46 + vg_assert(fsname_unexpanded != NULL); | |
47 + vg_assert(VG_(strlen)(fsname_unexpanded) <= 900); /* paranoia */ | |
48 + | |
49 + // Nb: we overwrite an existing file of this name without asking | |
50 + // any questions. | |
51 + filename = VG_(expand_file_name)(xml ? "--xml-file" : "--log-file", | |
52 + fsname_unexpanded); | |
53 + sres = VG_(open)(filename, | |
54 + VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, | |
55 + VKI_S_IRUSR|VKI_S_IWUSR); | |
56 + if (!sr_isError(sres)) { | |
57 + ret = sr_Res(sres); | |
58 + if (xml) | |
59 + VG_(clo_xml_fname_expanded) = filename; | |
60 + else | |
61 + VG_(clo_log_fname_expanded) = filename; | |
62 + | |
63 + /* strdup here is probably paranoid overkill, but ... */ | |
64 + // TODO: do we need to do anything with it? | |
65 + /* *fsname_unexpanded = VG_(strdup)( "main.mpclo.2", | |
66 + xml_fsname_unexpanded ); */ | |
67 + } else { | |
68 + VG_(message)(Vg_UserMsg, | |
69 + "Can't create %s file '%s' (%s); giving up!\n", | |
70 + output_type, filename, VG_(strerror)(sr_Err(sres))); | |
71 + VG_(err_bad_option)( | |
72 + "--[xml|log]-file=<file> (didn't work out for some reason.)"); | |
73 + /*NOTREACHED*/ | |
74 + } | |
75 + | |
76 + return ret; | |
77 +} | |
78 + | |
79 +static Int move_fd_into_safe_range(Int fd, Bool xml) { | |
80 + OutputSink *sink = xml ? &(VG_(xml_output_sink)) : &(VG_(log_output_sink)); | |
81 + // Move fd into the safe range, so it doesn't conflict with any app fds. | |
82 + fd = VG_(fcntl)(fd, VKI_F_DUPFD, VG_(fd_hard_limit)); | |
83 + if (fd < 0) { | |
84 + VG_(printf)("valgrind: failed to move %s file fd " | |
85 + "into safe range, using stderr\n", xml ? "XML" : "log"); | |
86 + sink->fd = 2; // stderr | |
87 + sink->is_socket = False; | |
88 + } else { | |
89 + sink->fd = fd; | |
90 + VG_(fcntl)(fd, VKI_F_SETFD, VKI_FD_CLOEXEC); | |
91 + } | |
92 + return fd; | |
93 +} | |
94 + | |
95 /* The main processing for command line options. See comments above | |
96 on early_process_cmd_line_options. | |
97 | |
98 @@ -339,13 +397,11 @@ | |
99 */ | |
100 static | |
101 void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd, | |
102 - /*OUT*/Char** xml_fname_unexpanded, | |
103 const HChar* toolname ) | |
104 { | |
105 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr) | |
106 // and we cannot change it until we know what we are changing it to is | |
107 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point. | |
108 - SysRes sres; | |
109 Int i, tmp_log_fd, tmp_xml_fd; | |
110 Int toolname_len = VG_(strlen)(toolname); | |
111 Char* tmp_str; // Used in a couple of places. | |
112 @@ -514,9 +570,13 @@ | |
113 | |
114 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) { | |
115 log_to = VgLogTo_File; | |
116 + VG_(clo_log_fname_unexpanded) = | |
117 + VG_(strdup)("", log_fsname_unexpanded); | |
118 } | |
119 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) { | |
120 xml_to = VgLogTo_File; | |
121 + VG_(clo_xml_fname_unexpanded) = | |
122 + VG_(strdup)("", xml_fsname_unexpanded); | |
123 } | |
124 | |
125 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) { | |
126 @@ -716,29 +776,7 @@ | |
127 break; | |
128 | |
129 case VgLogTo_File: { | |
130 - Char* logfilename; | |
131 - | |
132 - vg_assert(log_fsname_unexpanded != NULL); | |
133 - vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */ | |
134 - | |
135 - // Nb: we overwrite an existing file of this name without asking | |
136 - // any questions. | |
137 - logfilename = VG_(expand_file_name)("--log-file", | |
138 - log_fsname_unexpanded); | |
139 - sres = VG_(open)(logfilename, | |
140 - VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, | |
141 - VKI_S_IRUSR|VKI_S_IWUSR); | |
142 - if (!sr_isError(sres)) { | |
143 - tmp_log_fd = sr_Res(sres); | |
144 - VG_(clo_log_fname_expanded) = logfilename; | |
145 - } else { | |
146 - VG_(message)(Vg_UserMsg, | |
147 - "Can't create log file '%s' (%s); giving up!\n", | |
148 - logfilename, VG_(strerror)(sr_Err(sres))); | |
149 - VG_(err_bad_option)( | |
150 - "--log-file=<file> (didn't work out for some reason.)"); | |
151 - /*NOTREACHED*/ | |
152 - } | |
153 + tmp_log_fd = reopen_output_fd(False); | |
154 break; | |
155 } | |
156 | |
157 @@ -784,32 +822,7 @@ | |
158 break; | |
159 | |
160 case VgLogTo_File: { | |
161 - Char* xmlfilename; | |
162 - | |
163 - vg_assert(xml_fsname_unexpanded != NULL); | |
164 - vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */ | |
165 - | |
166 - // Nb: we overwrite an existing file of this name without asking | |
167 - // any questions. | |
168 - xmlfilename = VG_(expand_file_name)("--xml-file", | |
169 - xml_fsname_unexpanded); | |
170 - sres = VG_(open)(xmlfilename, | |
171 - VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, | |
172 - VKI_S_IRUSR|VKI_S_IWUSR); | |
173 - if (!sr_isError(sres)) { | |
174 - tmp_xml_fd = sr_Res(sres); | |
175 - VG_(clo_xml_fname_expanded) = xmlfilename; | |
176 - /* strdup here is probably paranoid overkill, but ... */ | |
177 - *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2", | |
178 - xml_fsname_unexpanded ); | |
179 - } else { | |
180 - VG_(message)(Vg_UserMsg, | |
181 - "Can't create XML file '%s' (%s); giving up!\n", | |
182 - xmlfilename, VG_(strerror)(sr_Err(sres))); | |
183 - VG_(err_bad_option)( | |
184 - "--xml-file=<file> (didn't work out for some reason.)"); | |
185 - /*NOTREACHED*/ | |
186 - } | |
187 + tmp_xml_fd = reopen_output_fd(True); | |
188 break; | |
189 } | |
190 | |
191 @@ -864,18 +877,7 @@ | |
192 // Finalise the output fds: the log fd .. | |
193 | |
194 if (tmp_log_fd >= 0) { | |
195 - // Move log_fd into the safe range, so it doesn't conflict with | |
196 - // any app fds. | |
197 - tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit)); | |
198 - if (tmp_log_fd < 0) { | |
199 - VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd " | |
200 - "into safe range, using stderr\n"); | |
201 - VG_(log_output_sink).fd = 2; // stderr | |
202 - VG_(log_output_sink).is_socket = False; | |
203 - } else { | |
204 - VG_(log_output_sink).fd = tmp_log_fd; | |
205 - VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC); | |
206 - } | |
207 + tmp_log_fd = move_fd_into_safe_range(tmp_log_fd, False); | |
208 } else { | |
209 // If they said --log-fd=-1, don't print anything. Plausible for use in | |
210 // regression testing suites that use client requests to count errors. | |
211 @@ -886,18 +888,7 @@ | |
212 // Finalise the output fds: and the XML fd .. | |
213 | |
214 if (tmp_xml_fd >= 0) { | |
215 - // Move xml_fd into the safe range, so it doesn't conflict with | |
216 - // any app fds. | |
217 - tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit)); | |
218 - if (tmp_xml_fd < 0) { | |
219 - VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd " | |
220 - "into safe range, using stderr\n"); | |
221 - VG_(xml_output_sink).fd = 2; // stderr | |
222 - VG_(xml_output_sink).is_socket = False; | |
223 - } else { | |
224 - VG_(xml_output_sink).fd = tmp_xml_fd; | |
225 - VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC); | |
226 - } | |
227 + tmp_xml_fd = move_fd_into_safe_range(tmp_xml_fd, True); | |
228 } else { | |
229 // If they said --xml-fd=-1, don't print anything. Plausible for use in | |
230 // regression testing suites that use client requests to count errors. | |
231 @@ -989,9 +980,12 @@ | |
232 If logging to file or a socket, write details of parent PID and | |
233 command line args, to help people trying to interpret the | |
234 results of a run which encompasses multiple processes. */ | |
235 -static void print_preamble ( Bool logging_to_fd, | |
236 - Char* xml_fname_unexpanded, | |
237 - const HChar* toolname ) | |
238 +// TODO(timurrrr): we add a non-static declaration of this function since | |
239 +// we need it in coregrind/m_libcproc.c | |
240 +// Should we move it to some header file? | |
241 +void print_preamble ( Bool logging_to_fd, const HChar* toolname ); | |
242 + | |
243 +void print_preamble ( Bool logging_to_fd, const HChar* toolname ) | |
244 { | |
245 Int i; | |
246 HChar* xpre = VG_(clo_xml) ? " <line>" : ""; | |
247 @@ -999,9 +993,15 @@ | |
248 UInt (*umsg_or_xml)( const HChar*, ... ) | |
249 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg); | |
250 | |
251 + static const char* last_toolname = NULL; | |
252 vg_assert( VG_(args_for_client) ); | |
253 vg_assert( VG_(args_for_valgrind) ); | |
254 + | |
255 + // This way you may pass toolname == NULL provided the first invocation | |
256 + // with toolname != NULL takes place in valgrind_main(). | |
257 + toolname = (toolname == NULL ? last_toolname : toolname); | |
258 vg_assert( toolname ); | |
259 + last_toolname = toolname; | |
260 | |
261 if (VG_(clo_xml)) { | |
262 VG_(printf_xml)("<?xml version=\"1.0\"?>\n"); | |
263 @@ -1013,7 +1013,7 @@ | |
264 VG_(printf_xml)("\n"); | |
265 } | |
266 | |
267 - if (VG_(clo_xml) || VG_(clo_verbosity > 0)) { | |
268 + if (VG_(clo_xml) || VG_(clo_verbosity) > 0) { | |
269 | |
270 if (VG_(clo_xml)) | |
271 VG_(printf_xml)("<preamble>\n"); | |
272 @@ -1067,6 +1067,7 @@ | |
273 } | |
274 else | |
275 if (VG_(clo_xml)) { | |
276 + Char *xml_fname_unexpanded = VG_(clo_xml_fname_unexpanded); | |
277 VG_(printf_xml)("\n"); | |
278 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)()); | |
279 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)()); | |
280 @@ -1374,7 +1375,6 @@ | |
281 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug | |
282 ThreadId tid_main = VG_INVALID_THREADID; | |
283 Bool logging_to_fd = False; | |
284 - Char* xml_fname_unexpanded = NULL; | |
285 Int loglevel, i; | |
286 struct vki_rlimit zero = { 0, 0 }; | |
287 XArray* addr2dihandle = NULL; | |
288 @@ -1872,8 +1872,7 @@ | |
289 VG_(debugLog)(1, "main", | |
290 "(main_) Process Valgrind's command line options, " | |
291 "setup logging\n"); | |
292 - main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded, | |
293 - toolname ); | |
294 + main_process_cmd_line_options ( &logging_to_fd, toolname ); | |
295 | |
296 //-------------------------------------------------------------- | |
297 // Zeroise the millisecond counter by doing a first read of it. | |
298 @@ -1886,10 +1885,10 @@ | |
299 // p: tl_pre_clo_init [for 'VG_(details).name' and friends] | |
300 // p: main_process_cmd_line_options() | |
301 // [for VG_(clo_verbosity), VG_(clo_xml), | |
302 - // logging_to_fd, xml_fname_unexpanded] | |
303 + // logging_to_fd] | |
304 //-------------------------------------------------------------- | |
305 VG_(debugLog)(1, "main", "Print the preamble...\n"); | |
306 - print_preamble(logging_to_fd, xml_fname_unexpanded, toolname); | |
307 + print_preamble(logging_to_fd, toolname); | |
308 VG_(debugLog)(1, "main", "...finished the preamble\n"); | |
309 | |
310 //-------------------------------------------------------------- | |
311 Index: coregrind/m_libcproc.c | |
312 =================================================================== | |
313 --- coregrind/m_libcproc.c (revision 10880) | |
314 +++ coregrind/m_libcproc.c (working copy) | |
315 @@ -33,9 +33,12 @@ | |
316 #include "pub_core_vkiscnums.h" | |
317 #include "pub_core_libcbase.h" | |
318 #include "pub_core_libcassert.h" | |
319 +#include "pub_core_libcfile.h" | |
320 #include "pub_core_libcprint.h" | |
321 #include "pub_core_libcproc.h" | |
322 #include "pub_core_libcsignal.h" | |
323 +#include "pub_core_tooliface.h" | |
324 +#include "pub_core_options.h" | |
325 #include "pub_core_seqmatch.h" | |
326 #include "pub_core_mallocfree.h" | |
327 #include "pub_core_syscall.h" | |
328 @@ -708,10 +711,39 @@ | |
329 (*atforks[i].parent)(tid); | |
330 } | |
331 | |
332 +// Defined in m_main.c | |
333 +void print_preamble(Bool logging_to_fd, const char* toolname); | |
334 + | |
335 +Char* VG_(clo_log_fname_unexpanded) = NULL; | |
336 +Char* VG_(clo_xml_fname_unexpanded) = NULL; | |
337 + | |
338 +// If --log-file=ABC%pXYZ is specified, we'd like to have separate log files | |
339 +// for each forked child. | |
340 +// If %p is present in the --log-file option, this function creates | |
341 +// a new log file and redirects the child's output to it. | |
342 +static void open_new_logfile_for_forked_child(void) | |
343 +{ | |
344 + Int tmp_fd = -1; | |
345 + | |
346 + if (VG_(log_output_sink).is_socket == False && VG_(clo_log_fname_unexpanded)
!= NULL) { | |
347 + tmp_fd = reopen_output_fd(False); | |
348 + VG_(log_output_sink).fd = VG_(safe_fd)(tmp_fd); | |
349 + } | |
350 + | |
351 + if (VG_(xml_output_sink).is_socket == False && VG_(clo_xml_fname_unexpanded)
!= NULL) { | |
352 + tmp_fd = reopen_output_fd(True); | |
353 + VG_(xml_output_sink).fd = VG_(safe_fd)(tmp_fd); | |
354 + } | |
355 + | |
356 + print_preamble(False, NULL); | |
357 +} | |
358 + | |
359 void VG_(do_atfork_child)(ThreadId tid) | |
360 { | |
361 Int i; | |
362 | |
363 + open_new_logfile_for_forked_child(); | |
364 + | |
365 for (i = 0; i < n_atfork; i++) | |
366 if (atforks[i].child != NULL) | |
367 (*atforks[i].child)(tid); | |
368 Index: coregrind/pub_core_options.h | |
369 =================================================================== | |
370 --- coregrind/pub_core_options.h (revision 10880) | |
371 +++ coregrind/pub_core_options.h (working copy) | |
372 @@ -74,6 +74,9 @@ | |
373 extern Char* VG_(clo_log_fname_expanded); | |
374 extern Char* VG_(clo_xml_fname_expanded); | |
375 | |
376 +extern Char* VG_(clo_log_fname_unexpanded); | |
377 +extern Char* VG_(clo_xml_fname_unexpanded); | |
378 + | |
379 /* Add timestamps to log messages? default: NO */ | |
380 extern Bool VG_(clo_time_stamp); | |
381 | |
OLD | NEW |