| OLD | NEW |
| (Empty) |
| 1 Index: coregrind/m_syswrap/syswrap-generic.c | |
| 2 =================================================================== | |
| 3 --- coregrind/m_syswrap/syswrap-generic.c (revision 11243) | |
| 4 +++ coregrind/m_syswrap/syswrap-generic.c (working copy) | |
| 5 @@ -2575,6 +2575,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 11243) | |
| 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 11243) | |
| 32 +++ coregrind/m_main.c (working copy) | |
| 33 @@ -320,6 +320,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_(fmsg_bad_option)("--[xml|log]-file=<file>", | |
| 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 @@ -346,13 +404,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 @@ -525,9 +581,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 @@ -650,17 +710,20 @@ | |
| 127 | |
| 128 if (VG_(clo_gen_suppressions) > 0 && | |
| 129 !VG_(needs).core_errors && !VG_(needs).tool_errors) { | |
| 130 - VG_(fmsg_bad_option)("--gen-suppressions=yes", | |
| 131 - "Can't use --gen-suppressions= with %s\n" | |
| 132 - "because it doesn't generate errors.\n", VG_(details).name); | |
| 133 + VG_(message)(Vg_UserMsg, | |
| 134 + "Can't use --gen-suppressions= with this tool,\n"); | |
| 135 + VG_(message)(Vg_UserMsg, | |
| 136 + "as it doesn't generate errors.\n"); | |
| 137 + VG_(fmsg_bad_option)("--gen-suppressions=", "\n"); | |
| 138 } | |
| 139 | |
| 140 /* If XML output is requested, check that the tool actually | |
| 141 supports it. */ | |
| 142 if (VG_(clo_xml) && !VG_(needs).xml_output) { | |
| 143 VG_(clo_xml) = False; | |
| 144 - VG_(fmsg_bad_option)("--xml=yes", | |
| 145 + VG_(message)(Vg_UserMsg, | |
| 146 "%s does not support XML output.\n", VG_(details).name); | |
| 147 + VG_(fmsg_bad_option)("--xml=yes", "\n"); | |
| 148 /*NOTREACHED*/ | |
| 149 } | |
| 150 | |
| 151 @@ -744,27 +807,7 @@ | |
| 152 break; | |
| 153 | |
| 154 case VgLogTo_File: { | |
| 155 - Char* logfilename; | |
| 156 - | |
| 157 - vg_assert(log_fsname_unexpanded != NULL); | |
| 158 - vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */ | |
| 159 - | |
| 160 - // Nb: we overwrite an existing file of this name without asking | |
| 161 - // any questions. | |
| 162 - logfilename = VG_(expand_file_name)("--log-file", | |
| 163 - log_fsname_unexpanded); | |
| 164 - sres = VG_(open)(logfilename, | |
| 165 - VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, | |
| 166 - VKI_S_IRUSR|VKI_S_IWUSR); | |
| 167 - if (!sr_isError(sres)) { | |
| 168 - tmp_log_fd = sr_Res(sres); | |
| 169 - VG_(clo_log_fname_expanded) = logfilename; | |
| 170 - } else { | |
| 171 - VG_(fmsg)("can't create log file '%s': %s\n", | |
| 172 - logfilename, VG_(strerror)(sr_Err(sres))); | |
| 173 - VG_(exit)(1); | |
| 174 - /*NOTREACHED*/ | |
| 175 - } | |
| 176 + tmp_log_fd = reopen_output_fd(False); | |
| 177 break; | |
| 178 } | |
| 179 | |
| 180 @@ -803,30 +846,7 @@ | |
| 181 break; | |
| 182 | |
| 183 case VgLogTo_File: { | |
| 184 - Char* xmlfilename; | |
| 185 - | |
| 186 - vg_assert(xml_fsname_unexpanded != NULL); | |
| 187 - vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */ | |
| 188 - | |
| 189 - // Nb: we overwrite an existing file of this name without asking | |
| 190 - // any questions. | |
| 191 - xmlfilename = VG_(expand_file_name)("--xml-file", | |
| 192 - xml_fsname_unexpanded); | |
| 193 - sres = VG_(open)(xmlfilename, | |
| 194 - VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, | |
| 195 - VKI_S_IRUSR|VKI_S_IWUSR); | |
| 196 - if (!sr_isError(sres)) { | |
| 197 - tmp_xml_fd = sr_Res(sres); | |
| 198 - VG_(clo_xml_fname_expanded) = xmlfilename; | |
| 199 - /* strdup here is probably paranoid overkill, but ... */ | |
| 200 - *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2", | |
| 201 - xml_fsname_unexpanded ); | |
| 202 - } else { | |
| 203 - VG_(fmsg)("can't create XML file '%s': %s\n", | |
| 204 - xmlfilename, VG_(strerror)(sr_Err(sres))); | |
| 205 - VG_(exit)(1); | |
| 206 - /*NOTREACHED*/ | |
| 207 - } | |
| 208 + tmp_xml_fd = reopen_output_fd(True); | |
| 209 break; | |
| 210 } | |
| 211 | |
| 212 @@ -872,18 +892,7 @@ | |
| 213 // Finalise the output fds: the log fd .. | |
| 214 | |
| 215 if (tmp_log_fd >= 0) { | |
| 216 - // Move log_fd into the safe range, so it doesn't conflict with | |
| 217 - // any app fds. | |
| 218 - tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit)); | |
| 219 - if (tmp_log_fd < 0) { | |
| 220 - VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd " | |
| 221 - "into safe range, using stderr\n"); | |
| 222 - VG_(log_output_sink).fd = 2; // stderr | |
| 223 - VG_(log_output_sink).is_socket = False; | |
| 224 - } else { | |
| 225 - VG_(log_output_sink).fd = tmp_log_fd; | |
| 226 - VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC); | |
| 227 - } | |
| 228 + tmp_log_fd = move_fd_into_safe_range(tmp_log_fd, False); | |
| 229 } else { | |
| 230 // If they said --log-fd=-1, don't print anything. Plausible for use in | |
| 231 // regression testing suites that use client requests to count errors. | |
| 232 @@ -894,18 +903,7 @@ | |
| 233 // Finalise the output fds: and the XML fd .. | |
| 234 | |
| 235 if (tmp_xml_fd >= 0) { | |
| 236 - // Move xml_fd into the safe range, so it doesn't conflict with | |
| 237 - // any app fds. | |
| 238 - tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit)); | |
| 239 - if (tmp_xml_fd < 0) { | |
| 240 - VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd " | |
| 241 - "into safe range, using stderr\n"); | |
| 242 - VG_(xml_output_sink).fd = 2; // stderr | |
| 243 - VG_(xml_output_sink).is_socket = False; | |
| 244 - } else { | |
| 245 - VG_(xml_output_sink).fd = tmp_xml_fd; | |
| 246 - VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC); | |
| 247 - } | |
| 248 + tmp_xml_fd = move_fd_into_safe_range(tmp_xml_fd, True); | |
| 249 } else { | |
| 250 // If they said --xml-fd=-1, don't print anything. Plausible for use in | |
| 251 // regression testing suites that use client requests to count errors. | |
| 252 @@ -997,9 +995,12 @@ | |
| 253 If logging to file or a socket, write details of parent PID and | |
| 254 command line args, to help people trying to interpret the | |
| 255 results of a run which encompasses multiple processes. */ | |
| 256 -static void print_preamble ( Bool logging_to_fd, | |
| 257 - Char* xml_fname_unexpanded, | |
| 258 - const HChar* toolname ) | |
| 259 +// TODO(timurrrr): we add a non-static declaration of this function since | |
| 260 +// we need it in coregrind/m_libcproc.c | |
| 261 +// Should we move it to some header file? | |
| 262 +void print_preamble ( Bool logging_to_fd, const HChar* toolname ); | |
| 263 + | |
| 264 +void print_preamble ( Bool logging_to_fd, const HChar* toolname ) | |
| 265 { | |
| 266 Int i; | |
| 267 HChar* xpre = VG_(clo_xml) ? " <line>" : ""; | |
| 268 @@ -1007,9 +1008,15 @@ | |
| 269 UInt (*umsg_or_xml)( const HChar*, ... ) | |
| 270 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg); | |
| 271 | |
| 272 + static const char* last_toolname = NULL; | |
| 273 vg_assert( VG_(args_for_client) ); | |
| 274 vg_assert( VG_(args_for_valgrind) ); | |
| 275 + | |
| 276 + // This way you may pass toolname == NULL provided the first invocation | |
| 277 + // with toolname != NULL takes place in valgrind_main(). | |
| 278 + toolname = (toolname == NULL ? last_toolname : toolname); | |
| 279 vg_assert( toolname ); | |
| 280 + last_toolname = toolname; | |
| 281 | |
| 282 if (VG_(clo_xml)) { | |
| 283 VG_(printf_xml)("<?xml version=\"1.0\"?>\n"); | |
| 284 @@ -1021,13 +1028,13 @@ | |
| 285 VG_(printf_xml)("\n"); | |
| 286 } | |
| 287 | |
| 288 - if (VG_(clo_xml) || VG_(clo_verbosity > 0)) { | |
| 289 + if (VG_(clo_xml) || VG_(clo_verbosity) > 0) { | |
| 290 | |
| 291 if (VG_(clo_xml)) | |
| 292 VG_(printf_xml)("<preamble>\n"); | |
| 293 | |
| 294 /* Tool details */ | |
| 295 - umsg_or_xml( VG_(clo_xml) ? "%s%t%t%t, %t%s\n" : "%s%s%s%s, %s%s\n", | |
| 296 + umsg_or_xml( "%s%s%s%s, %s%s\n", | |
| 297 xpre, | |
| 298 VG_(details).name, | |
| 299 NULL == VG_(details).version ? "" : "-", | |
| 300 @@ -1043,8 +1050,7 @@ | |
| 301 ); | |
| 302 } | |
| 303 | |
| 304 - umsg_or_xml( VG_(clo_xml) ? "%s%t%s\n" : "%s%s%s\n", | |
| 305 - xpre, VG_(details).copyright_author, xpost ); | |
| 306 + umsg_or_xml("%s%s%s\n", xpre, VG_(details).copyright_author, xpost); | |
| 307 | |
| 308 /* Core details */ | |
| 309 umsg_or_xml( | |
| 310 @@ -1076,6 +1082,7 @@ | |
| 311 } | |
| 312 else | |
| 313 if (VG_(clo_xml)) { | |
| 314 + Char *xml_fname_unexpanded = VG_(clo_xml_fname_unexpanded); | |
| 315 VG_(printf_xml)("\n"); | |
| 316 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)()); | |
| 317 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)()); | |
| 318 @@ -1383,7 +1390,6 @@ | |
| 319 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug | |
| 320 ThreadId tid_main = VG_INVALID_THREADID; | |
| 321 Bool logging_to_fd = False; | |
| 322 - Char* xml_fname_unexpanded = NULL; | |
| 323 Int loglevel, i; | |
| 324 struct vki_rlimit zero = { 0, 0 }; | |
| 325 XArray* addr2dihandle = NULL; | |
| 326 @@ -1838,8 +1844,7 @@ | |
| 327 VG_(debugLog)(1, "main", | |
| 328 "(main_) Process Valgrind's command line options, " | |
| 329 "setup logging\n"); | |
| 330 - main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded, | |
| 331 - toolname ); | |
| 332 + main_process_cmd_line_options ( &logging_to_fd, toolname ); | |
| 333 | |
| 334 //-------------------------------------------------------------- | |
| 335 // Zeroise the millisecond counter by doing a first read of it. | |
| 336 @@ -1852,10 +1857,10 @@ | |
| 337 // p: tl_pre_clo_init [for 'VG_(details).name' and friends] | |
| 338 // p: main_process_cmd_line_options() | |
| 339 // [for VG_(clo_verbosity), VG_(clo_xml), | |
| 340 - // logging_to_fd, xml_fname_unexpanded] | |
| 341 + // logging_to_fd] | |
| 342 //-------------------------------------------------------------- | |
| 343 VG_(debugLog)(1, "main", "Print the preamble...\n"); | |
| 344 - print_preamble(logging_to_fd, xml_fname_unexpanded, toolname); | |
| 345 + print_preamble(logging_to_fd, toolname); | |
| 346 VG_(debugLog)(1, "main", "...finished the preamble\n"); | |
| 347 | |
| 348 //-------------------------------------------------------------- | |
| 349 Index: coregrind/m_libcproc.c | |
| 350 =================================================================== | |
| 351 --- coregrind/m_libcproc.c (revision 11243) | |
| 352 +++ coregrind/m_libcproc.c (working copy) | |
| 353 @@ -33,9 +33,12 @@ | |
| 354 #include "pub_core_vkiscnums.h" | |
| 355 #include "pub_core_libcbase.h" | |
| 356 #include "pub_core_libcassert.h" | |
| 357 +#include "pub_core_libcfile.h" | |
| 358 #include "pub_core_libcprint.h" | |
| 359 #include "pub_core_libcproc.h" | |
| 360 #include "pub_core_libcsignal.h" | |
| 361 +#include "pub_core_tooliface.h" | |
| 362 +#include "pub_core_options.h" | |
| 363 #include "pub_core_seqmatch.h" | |
| 364 #include "pub_core_mallocfree.h" | |
| 365 #include "pub_core_syscall.h" | |
| 366 @@ -722,10 +725,39 @@ | |
| 367 (*atforks[i].parent)(tid); | |
| 368 } | |
| 369 | |
| 370 +// Defined in m_main.c | |
| 371 +void print_preamble(Bool logging_to_fd, const char* toolname); | |
| 372 + | |
| 373 +Char* VG_(clo_log_fname_unexpanded) = NULL; | |
| 374 +Char* VG_(clo_xml_fname_unexpanded) = NULL; | |
| 375 + | |
| 376 +// If --log-file=ABC%pXYZ is specified, we'd like to have separate log files | |
| 377 +// for each forked child. | |
| 378 +// If %p is present in the --log-file option, this function creates | |
| 379 +// a new log file and redirects the child's output to it. | |
| 380 +static void open_new_logfile_for_forked_child(void) | |
| 381 +{ | |
| 382 + Int tmp_fd = -1; | |
| 383 + | |
| 384 + if (VG_(log_output_sink).is_socket == False && VG_(clo_log_fname_unexpanded)
!= NULL) { | |
| 385 + tmp_fd = reopen_output_fd(False); | |
| 386 + VG_(log_output_sink).fd = VG_(safe_fd)(tmp_fd); | |
| 387 + } | |
| 388 + | |
| 389 + if (VG_(xml_output_sink).is_socket == False && VG_(clo_xml_fname_unexpanded)
!= NULL) { | |
| 390 + tmp_fd = reopen_output_fd(True); | |
| 391 + VG_(xml_output_sink).fd = VG_(safe_fd)(tmp_fd); | |
| 392 + } | |
| 393 + | |
| 394 + print_preamble(False, NULL); | |
| 395 +} | |
| 396 + | |
| 397 void VG_(do_atfork_child)(ThreadId tid) | |
| 398 { | |
| 399 Int i; | |
| 400 | |
| 401 + open_new_logfile_for_forked_child(); | |
| 402 + | |
| 403 for (i = 0; i < n_atfork; i++) | |
| 404 if (atforks[i].child != NULL) | |
| 405 (*atforks[i].child)(tid); | |
| 406 Index: coregrind/pub_core_options.h | |
| 407 =================================================================== | |
| 408 --- coregrind/pub_core_options.h (revision 11243) | |
| 409 +++ coregrind/pub_core_options.h (working copy) | |
| 410 @@ -80,6 +80,9 @@ | |
| 411 extern Char* VG_(clo_log_fname_expanded); | |
| 412 extern Char* VG_(clo_xml_fname_expanded); | |
| 413 | |
| 414 +extern Char* VG_(clo_log_fname_unexpanded); | |
| 415 +extern Char* VG_(clo_xml_fname_unexpanded); | |
| 416 + | |
| 417 /* Add timestamps to log messages? default: NO */ | |
| 418 extern Bool VG_(clo_time_stamp); | |
| 419 | |
| OLD | NEW |