FreeBSD Helgrind: turn off check for locks held on exit for FreeBSD 14.2
[valgrind.git] / coregrind / m_libcprint.c
blob593889da9d1bdc6980e232f26a734e812d3d50d2
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*--------------------------------------------------------------------*/
4 /*--- Libc printing. m_libcprint.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright (C) 2000-2017 Julian Seward
12 jseward@acm.org
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #include "vgversion.h"
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_debuglog.h"
35 #include "pub_core_gdbserver.h" // VG_(gdb_printf)
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcassert.h"
38 #include "pub_core_libcfile.h" // VG_(write)(), VG_(write_socket)()
39 #include "pub_core_libcprint.h"
40 #include "pub_core_libcproc.h" // VG_(getpid)(), VG_(read_millisecond_timer()
41 #include "pub_core_mallocfree.h" // VG_(malloc)
42 #include "pub_core_machine.h" // VG_(machine_get_VexArchInfo)
43 #include "pub_core_options.h"
44 #include "pub_core_clreq.h" // For RUNNING_ON_VALGRIND
45 #include "pub_core_clientstate.h"
46 #include "pub_core_syscall.h" // VG_(strerror)
47 #include "pub_core_tooliface.h" // VG_(details)
50 /*====================================================================*/
51 /*=== Printing the preamble ===*/
52 /*====================================================================*/
54 // Returns a strdup'd copy of |str| in which characters which are not in the
55 // obviously-harmless-ASCII range are replaced with '_'. Not doing this has
56 // been observed to cause xfce4-terminal to assert. Caller takes ownership
57 // of the returned string.
58 static HChar* sanitise_arg (const HChar* arg)
60 HChar* clone = VG_(strdup)("m_libcprint.sanitise_arg", arg);
61 for (HChar* p = clone; *p; p++) {
62 UInt c = * ((UChar*)p);
63 if (c < 32 || c > 127) c = '_';
64 *p = (HChar)c;
66 return clone;
69 // Print the argument, escaping any chars that require it.
70 static void umsg_arg(const HChar *unsanitised_arg)
72 HChar* arg = sanitise_arg(unsanitised_arg);
73 SizeT len = VG_(strlen)(arg);
74 const HChar *special = " \\<>";
75 for (UInt i = 0; i < len; i++) {
76 if (VG_(strchr)(special, arg[i])) {
77 VG_(umsg)("\\"); // escape with a backslash if necessary
79 VG_(umsg)("%c", arg[i]);
81 VG_(free)(arg);
84 // Send output to the XML-stream and escape any XML meta-characters.
85 static void xml_arg(const HChar *unsanitised_arg)
87 HChar* arg = sanitise_arg(unsanitised_arg);
88 VG_(printf_xml)("%pS", arg);
89 VG_(free)(arg);
92 // Write the name and value of log file qualifiers to the xml file.
93 // We can safely assume here that the format string is well-formed.
94 // It has been checked earlier in VG_(expand_file_name) when processing
95 // command line options.
96 static void print_file_vars(const HChar *format)
98 UInt i = 0;
100 while (format[i]) {
101 if (format[i] == '%') {
102 // We saw a '%'. What's next...
103 i++;
104 if ('q' == format[i]) {
105 i++;
106 if ('{' == format[i]) {
107 // Get the env var name, print its contents.
108 UInt begin_qualname = ++i;
109 while (True) {
110 if ('}' == format[i]) {
111 UInt qualname_len = i - begin_qualname;
112 HChar qualname[qualname_len + 1];
113 VG_(strncpy)(qualname, format + begin_qualname,
114 qualname_len);
115 qualname[qualname_len] = '\0';
116 HChar *qual = VG_(getenv)(qualname);
117 i++;
118 VG_(printf_xml)("<logfilequalifier> <var>%pS</var> "
119 "<value>%pS</value> </logfilequalifier>\n",
120 qualname, qual);
121 break;
123 i++;
127 } else {
128 i++;
133 /* Ok, the logging sink is running now. Print a suitable preamble.
134 If logging to file or a socket, write details of parent PID and
135 command line args, to help people trying to interpret the
136 results of a run which encompasses multiple processes. */
137 void VG_(print_preamble)(Bool logging_to_fd)
139 const HChar *xpre = VG_(clo_xml) ? " <line>" : "";
140 const HChar *xpost = VG_(clo_xml) ? "</line>" : "";
141 UInt (*umsg_or_xml)( const HChar *, ... )
142 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
143 void (*umsg_or_xml_arg)( const HChar *) = VG_(clo_xml) ? xml_arg : umsg_arg;
145 vg_assert( VG_(args_for_client) );
146 vg_assert( VG_(args_for_valgrind) );
147 vg_assert( VG_(clo_toolname) );
149 if (VG_(clo_xml)) {
150 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
151 VG_(printf_xml)("\n");
152 VG_(printf_xml)("<valgrindoutput>\n");
153 VG_(printf_xml)("\n");
154 /* track-fds introduced some new elements. */
155 if (VG_(clo_track_fds))
156 VG_(printf_xml)("<protocolversion>5</protocolversion>\n");
157 else
158 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
159 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", VG_(clo_toolname));
160 VG_(printf_xml)("\n");
163 if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
165 if (VG_(clo_xml))
166 VG_(printf_xml)("<preamble>\n");
168 /* Tool details */
169 umsg_or_xml(VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
170 xpre,
171 VG_(details).name,
172 NULL == VG_(details).version ? "" : "-",
173 NULL == VG_(details).version ? "" : VG_(details).version,
174 VG_(details).description,
175 xpost);
177 if (VG_(strlen)(VG_(clo_toolname)) >= 4 &&
178 VG_STREQN(4, VG_(clo_toolname), "exp-")) {
179 umsg_or_xml("%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
180 xpre, xpost);
183 umsg_or_xml(VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
184 xpre, VG_(details).copyright_author, xpost);
186 /* Core details */
187 umsg_or_xml(
188 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
189 xpre, VG_(clo_verbosity) <= 1 ? VERSION : VERSION "-" VGGIT, xpost);
191 // Print the command line. At one point we wrapped at 80 chars and
192 // printed a '\' as a line joiner, but that makes it hard to cut and
193 // paste the command line (because of the "==pid==" prefixes), so we now
194 // favour utility and simplicity over aesthetics.
195 umsg_or_xml("%sCommand: ", xpre);
196 umsg_or_xml_arg(VG_(args_the_exename));
198 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client)); i++) {
199 HChar *s = *(HChar **)VG_(indexXA)( VG_(args_for_client), i);
200 umsg_or_xml(" ");
201 umsg_or_xml_arg(s);
203 umsg_or_xml("%s\n", xpost);
205 if (VG_(clo_xml))
206 VG_(printf_xml)("</preamble>\n");
209 // Print the parent PID, and other stuff, if necessary.
210 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
211 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
212 } else if (VG_(clo_xml)) {
213 VG_(printf_xml)("\n");
214 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
215 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
216 VG_(printf_xml)("<tool>%pS</tool>\n", VG_(clo_toolname));
217 if (VG_(clo_xml_fname_unexpanded) != NULL)
218 print_file_vars(VG_(clo_xml_fname_unexpanded));
219 if (VG_(clo_xml_user_comment)) {
220 /* Note: the user comment itself is XML and is therefore to
221 be passed through verbatim (%s) rather than escaped (%pS). */
222 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
223 VG_(clo_xml_user_comment));
225 VG_(printf_xml)("\n");
226 VG_(printf_xml)("<args>\n");
228 VG_(printf_xml)(" <vargv>\n");
229 if (VG_(name_of_launcher))
230 VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(name_of_launcher));
231 else
232 VG_(printf_xml)(" <exe>%pS</exe>\n", "(launcher name unknown)");
233 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
234 VG_(printf_xml)(
235 " <arg>%pS</arg>\n",
236 *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
238 VG_(printf_xml)(" </vargv>\n");
240 VG_(printf_xml)(" <argv>\n");
241 VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(args_the_exename));
242 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
243 VG_(printf_xml)(
244 " <arg>%pS</arg>\n",
245 *(HChar **) VG_(indexXA)( VG_(args_for_client), i));
247 VG_(printf_xml)(" </argv>\n");
249 VG_(printf_xml)("</args>\n");
252 // Last thing in the preamble is a blank line.
253 if (VG_(clo_xml))
254 VG_(printf_xml)("\n");
255 else if (VG_(clo_verbosity) > 0)
256 VG_(umsg)("\n");
258 if (VG_(clo_verbosity) > 1) {
259 # if defined(VGO_linux)
260 SysRes fd;
261 # endif
262 VexArch vex_arch;
263 VexArchInfo vex_archinfo;
264 if (!logging_to_fd)
265 VG_(message)(Vg_DebugMsg, "\n");
266 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
267 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
268 VG_(message)(Vg_DebugMsg,
269 " %s\n",
270 *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
273 # if defined(VGO_linux)
274 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
275 fd = VG_(open)("/proc/version", VKI_O_RDONLY, 0);
276 if (sr_isError(fd)) {
277 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
278 } else {
279 const SizeT bufsiz = 255;
280 HChar version_buf[bufsiz+1];
281 VG_(message)(Vg_DebugMsg, " ");
282 Int n, fdno = sr_Res(fd);
283 do {
284 n = VG_(read)(fdno, version_buf, bufsiz);
285 if (n < 0) {
286 VG_(message)(Vg_DebugMsg, " error reading /proc/version\n");
287 break;
289 version_buf[n] = '\0';
290 VG_(message)(Vg_DebugMsg, "%s", version_buf);
291 } while (n == bufsiz);
292 VG_(message)(Vg_DebugMsg, "\n");
293 VG_(close)(fdno);
295 # elif defined(VGO_darwin)
296 VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
297 /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
298 however that syscall is OS X 10.10+ only. */
299 Int mib[] = {CTL_KERN, KERN_VERSION};
300 SizeT len;
301 VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
302 HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
303 VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
304 VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
305 VG_(free)( kernelVersion );
306 # elif defined(VGO_solaris)
307 /* There is no /proc/version file on Solaris so we try to get some
308 system information using the uname(2) syscall. */
309 struct vki_utsname uts;
310 VG_(message)(Vg_DebugMsg, "System information:\n");
311 SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
312 if (sr_isError(res))
313 VG_(message)(Vg_DebugMsg, " uname() failed\n");
314 else
315 VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
316 uts.sysname, uts.release, uts.version, uts.machine);
317 # endif
319 VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);
320 VG_(message)(
321 Vg_DebugMsg,
322 "Arch and hwcaps: %s, %s, %s\n",
323 LibVEX_ppVexArch ( vex_arch ),
324 LibVEX_ppVexEndness ( vex_archinfo.endness ),
325 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
327 VG_(message)(Vg_DebugMsg,
328 "Page sizes: currently %u, max supported %u\n",
329 (UInt) VKI_PAGE_SIZE, (UInt) VKI_MAX_PAGE_SIZE);
330 VG_(message)(Vg_DebugMsg,
331 "Valgrind library directory: %s\n", VG_(libdir));
335 /* ---------------------------------------------------------------------
336 Writing to file or a socket
337 ------------------------------------------------------------------ */
339 /* The destination sinks for normal and XML output. These have their
340 initial values here; they are set to final values by
341 m_main.main_process_cmd_line_options(). See comment at the top of
342 that function for the associated logic.
343 After startup, the gdbserver monitor command might temporarily
344 set the fd of log_output_sink to -2 to indicate that output is
345 to be given to gdb rather than output to the startup fd */
346 OutputSink VG_(log_output_sink) = { 2, VgLogTo_Fd, NULL }; /* 2 = stderr */
347 OutputSink VG_(xml_output_sink) = { -1, VgLogTo_Fd, NULL }; /* disabled */
349 static void revert_sink_to_stderr ( OutputSink *sink )
351 sink->fd = 2; /* stderr */
352 sink->type = VgLogTo_Fd;
353 VG_(free)(sink->fsname_expanded);
354 sink->fsname_expanded = NULL;
357 static Int prepare_sink_fd(const HChar *clo_fname_unexpanded, OutputSink *sink,
358 Bool is_xml)
360 vg_assert(clo_fname_unexpanded != NULL);
361 vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
363 // Nb: we overwrite an existing file of this name without asking
364 // any questions.
365 HChar *logfilename = VG_(expand_file_name)(
366 (is_xml) ? "--xml-file" : "--log-file",
367 clo_fname_unexpanded);
368 SysRes sres = VG_(open)(logfilename,
369 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
370 VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
371 if (!sr_isError(sres)) {
372 Int fd = sr_Res(sres);
373 sink->fsname_expanded = logfilename;
374 sink->type = VgLogTo_File;
375 return fd;
376 } else {
377 VG_(fmsg)("Cannot create %s file '%s': %s\n",
378 (is_xml) ? "XML" : "log", logfilename,
379 VG_(strerror)(sr_Err(sres)));
380 VG_(exit)(1);
381 /*NOTREACHED*/
385 static Int prepare_sink_socket(const HChar *clo_fname_unexpanded,
386 OutputSink *sink, Bool is_xml)
388 vg_assert(clo_fname_unexpanded != NULL);
389 vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
391 Int fd = VG_(connect_via_socket)(clo_fname_unexpanded);
392 if (fd == -1) {
393 VG_(fmsg)("Invalid %s spec of '%s'\n",
394 (is_xml) ? "--xml-socket" : "--log-socket",
395 clo_fname_unexpanded);
396 VG_(exit)(1);
397 /*NOTREACHED*/
399 if (fd == -2) {
400 VG_(umsg)("Failed to connect to %slogging server '%s'.\n"
401 "%s will be sent to stderr instead.\n",
402 (is_xml) ? "XML " : "",
403 clo_fname_unexpanded,
404 (is_xml) ? "XML output" : "Logging messages");
405 /* We don't change anything here. */
406 vg_assert(sink->fd == 2);
407 vg_assert(sink->type == VgLogTo_Fd);
408 return 2;
409 } else {
410 vg_assert(fd > 0);
411 sink->type = VgLogTo_Socket;
412 return fd;
416 static void finalize_sink_fd(OutputSink *sink, Int new_fd, Bool is_xml)
418 // Move new_fd into the safe range, so it doesn't conflict with any app fds.
419 Int safe_fd = VG_(fcntl)(new_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
420 if (safe_fd < 0) {
421 VG_(message)(Vg_UserMsg, "Valgrind: failed to move %s file descriptor "
422 "into safe range, using stderr\n",
423 (is_xml) ? "XML" : "log");
424 revert_sink_to_stderr(sink);
425 } else {
426 VG_(fcntl)(safe_fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
427 sink->fd = safe_fd;
428 /* If we created the new_fd (VgLogTo_File or VgLogTo_Socket), then we
429 don't need the original file descriptor open anymore. We only need
430 to keep it open if it was an existing fd given by the user (or
431 stderr). */
432 if (sink->type != VgLogTo_Fd)
433 VG_(close)(new_fd);
437 /* Re-opens an output file sink when exanded file name differs from what we
438 have now. Returns 'True' if the sink was reopened */
439 static Bool reopen_sink_if_needed(const HChar *clo_fname_unexpanded,
440 OutputSink *sink, Bool is_xml)
442 if (sink->type == VgLogTo_File) {
443 /* Try to expand --log|xml-file again and see if it differs from what
444 we have now. */
445 HChar *logfilename = VG_(expand_file_name)(
446 (is_xml) ? "--xml-file" : "--log-file",
447 clo_fname_unexpanded);
448 if (VG_(strcmp)(logfilename, sink->fsname_expanded) != 0) {
449 Int fd = prepare_sink_fd(clo_fname_unexpanded, sink, is_xml);
450 finalize_sink_fd(sink, fd, is_xml);
451 return True;
453 VG_(free)(logfilename);
456 return False;
459 void VG_(logging_atfork_child)(ThreadId tid)
461 /* If --child-silent-after-fork=yes was specified, set the output file
462 descriptors to 'impossible' values. This is noticed by
463 send_bytes_to_logging_sink(), which duly stops writing any further
464 output. */
465 if (VG_(clo_child_silent_after_fork)) {
466 if (VG_(log_output_sink).type != VgLogTo_Socket) {
467 VG_(log_output_sink).fd = -1;
468 VG_(log_output_sink).type = VgLogTo_Fd;
470 if (VG_(xml_output_sink).type != VgLogTo_Socket) {
471 VG_(xml_output_sink).fd = -1;
472 VG_(xml_output_sink).type = VgLogTo_Fd;
474 } else {
475 if (reopen_sink_if_needed(VG_(clo_log_fname_unexpanded),
476 &VG_(log_output_sink), False) ||
477 reopen_sink_if_needed(VG_(clo_xml_fname_unexpanded),
478 &VG_(xml_output_sink), True)) {
479 VG_(print_preamble)(VG_(log_output_sink).type != VgLogTo_File);
484 /* Initializes normal log and xml sinks (of type fd, file, or socket).
485 Any problem encountered is considered a hard error and causes V. to exit.
487 Comments on how the logging options are handled:
489 User can specify:
490 --log-fd= for a fd to write to (default setting, fd = 2)
491 --log-file= for a file name to write to
492 --log-socket= for a socket to write to
494 As a result of examining these and doing relevant socket/file
495 opening, a final fd is established. This is stored in
496 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
497 specified, then it is stored in VG_(clo_log_fname_unexpanded), in m_options.
498 And then STR, after expansion of %p and %q templates within
499 it, is stored in VG_(log_output_sink), just in case anybody wants to know
500 what it is.
502 When printing, VG_(log_output_sink) is consulted to find the
503 fd to send output to.
505 Exactly analogous actions are undertaken for the XML output
506 channel, with the one difference that the default fd is -1, meaning
507 the channel is disabled by default. */
508 void VG_(init_log_xml_sinks)(VgLogTo log_to, VgLogTo xml_to,
509 Int /*initial*/log_fd, Int /*initial*/xml_fd)
511 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
512 // and we cannot change it until we know what we are changing it to is ok.
514 /* Start setting up logging now. After this is done, VG_(log_output_sink)
515 and (if relevant) VG_(xml_output_sink) should be connected to whatever
516 sink has been selected, and we indiscriminately chuck stuff into it
517 without worrying what the nature of it is.
518 Oh the wonder of Unix streams. */
520 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
521 vg_assert(VG_(log_output_sink).type == VgLogTo_Fd);
522 vg_assert(VG_(log_output_sink).fsname_expanded == NULL);
524 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
525 vg_assert(VG_(xml_output_sink).type == VgLogTo_Fd);
526 vg_assert(VG_(xml_output_sink).fsname_expanded == NULL);
528 /* --- set up the normal text output channel --- */
529 switch (log_to) {
530 case VgLogTo_Fd:
531 vg_assert(VG_(clo_log_fname_unexpanded) == NULL);
532 break;
534 case VgLogTo_File:
535 log_fd = prepare_sink_fd(VG_(clo_log_fname_unexpanded),
536 &VG_(log_output_sink), False);
537 break;
539 case VgLogTo_Socket:
540 log_fd = prepare_sink_socket(VG_(clo_log_fname_unexpanded),
541 &VG_(log_output_sink), False);
542 break;
545 /* --- set up the XML output channel --- */
546 switch (xml_to) {
547 case VgLogTo_Fd:
548 vg_assert(VG_(clo_xml_fname_unexpanded) == NULL);
549 break;
551 case VgLogTo_File:
552 xml_fd = prepare_sink_fd(VG_(clo_xml_fname_unexpanded),
553 &VG_(xml_output_sink), True);
554 break;
556 case VgLogTo_Socket:
557 xml_fd = prepare_sink_socket(VG_(clo_xml_fname_unexpanded),
558 &VG_(xml_output_sink), True);
559 break;
562 /* If we've got this far, and XML mode was requested, but no XML
563 output channel appears to have been specified, just stop. We
564 could continue, and XML output will simply vanish into nowhere,
565 but that is likely to confuse the hell out of users, which is
566 distinctly Ungood. */
567 if (VG_(clo_xml) && xml_fd == -1) {
568 VG_(fmsg_bad_option)(
569 "--xml=yes, but no XML destination specified",
570 "--xml=yes has been specified, but there is no XML output\n"
571 "destination. You must specify an XML output destination\n"
572 "using --xml-fd, --xml-file or --xml-socket.\n"
576 // Finalise the output fds: the log fd ..
577 if (log_fd >= 0) {
578 finalize_sink_fd(&VG_(log_output_sink), log_fd, False);
579 } else {
580 // If they said --log-fd=-1, don't print anything. Plausible for use in
581 // regression testing suites that use client requests to count errors.
582 VG_(log_output_sink).fd = -1;
583 VG_(log_output_sink).type = VgLogTo_Fd;
586 // Finalise the output fds: and the XML fd ..
587 if (xml_fd >= 0) {
588 finalize_sink_fd(&VG_(xml_output_sink), xml_fd, True);
589 } else {
590 // If they said --xml-fd=-1, don't print anything. Plausible for use in
591 // regression testing suites that use client requests to count errors.
592 VG_(xml_output_sink).fd = -1;
593 VG_(xml_output_sink).type = VgLogTo_Fd;
597 /* Do the low-level send of a message to the logging sink. */
598 static
599 void send_bytes_to_logging_sink ( OutputSink* sink, const HChar* msg, Int nbytes )
601 if (sink->type == VgLogTo_Socket) {
602 Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
603 if (rc == -1) {
604 // For example, the listener process died. Switch back to stderr.
605 revert_sink_to_stderr(sink);
606 VG_(write)( sink->fd, msg, nbytes );
608 } else {
609 /* sink->fd could have been set to -1 in the various
610 sys-wrappers for sys_fork, if --child-silent-after-fork=yes
611 is in effect. That is a signal that we should not produce
612 any more output. */
613 if (sink->fd >= 0)
614 VG_(write)( sink->fd, msg, nbytes );
615 else if (sink->fd == -2 && nbytes > 0)
616 /* send to gdb the provided data, which must be
617 a null terminated string with len >= 1 */
618 VG_(gdb_printf)("%s", msg);
623 /* ---------------------------------------------------------------------
624 printf() and friends
625 ------------------------------------------------------------------ */
627 /* --------- printf --------- */
629 typedef
630 struct {
631 HChar buf[512];
632 Int buf_used;
633 OutputSink* sink;
635 printf_buf_t;
637 // Adds a single char to the buffer. When the buffer gets sufficiently
638 // full, we write its contents to the logging sink.
639 static void add_to__printf_buf ( HChar c, void *p )
641 printf_buf_t *b = (printf_buf_t *)p;
643 if (b->buf_used > sizeof(b->buf) - 2 ) {
644 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
645 b->buf_used = 0;
647 b->buf[b->buf_used++] = c;
648 b->buf[b->buf_used] = 0;
649 vg_assert(b->buf_used < sizeof(b->buf));
652 static UInt vprintf_to_buf ( printf_buf_t* b,
653 const HChar *format, va_list vargs )
655 UInt ret = 0;
656 if (b->sink->fd >= 0 || b->sink->fd == -2) {
657 ret = VG_(debugLog_vprintf)
658 ( add_to__printf_buf, b, format, vargs );
660 return ret;
663 static UInt vprintf_WRK ( OutputSink* sink,
664 const HChar *format, va_list vargs )
666 printf_buf_t myprintf_buf
667 = { "", 0, sink };
668 UInt ret
669 = vprintf_to_buf(&myprintf_buf, format, vargs);
670 // Write out any chars left in the buffer.
671 if (myprintf_buf.buf_used > 0) {
672 send_bytes_to_logging_sink( myprintf_buf.sink,
673 myprintf_buf.buf,
674 myprintf_buf.buf_used );
676 return ret;
679 UInt VG_(vprintf) ( const HChar *format, va_list vargs )
681 return vprintf_WRK( &VG_(log_output_sink), format, vargs );
684 UInt VG_(printf) ( const HChar *format, ... )
686 UInt ret;
687 va_list vargs;
688 va_start(vargs, format);
689 ret = VG_(vprintf)(format, vargs);
690 va_end(vargs);
691 return ret;
694 UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs )
696 return vprintf_WRK( &VG_(xml_output_sink), format, vargs );
699 UInt VG_(printf_xml) ( const HChar *format, ... )
701 UInt ret;
702 va_list vargs;
703 va_start(vargs, format);
704 ret = VG_(vprintf_xml)(format, vargs);
705 va_end(vargs);
706 return ret;
709 static UInt emit_WRK ( const HChar* format, va_list vargs )
711 if (VG_(clo_xml)) {
712 return VG_(vprintf_xml)(format, vargs);
713 } else if (VG_(log_output_sink).fd == -2) {
714 return VG_(vprintf) (format, vargs);
715 } else {
716 return VG_(vmessage)(Vg_UserMsg, format, vargs);
719 UInt VG_(emit) ( const HChar* format, ... )
721 UInt ret;
722 va_list vargs;
723 va_start(vargs, format);
724 ret = emit_WRK(format, vargs);
725 va_end(vargs);
726 return ret;
729 /* --------- sprintf --------- */
731 /* If we had an explicit buf structure here, it would contain only one
732 field, indicating where the next char is to go. So use p directly
733 for that, rather than having it be a pointer to a structure. */
735 static void add_to__sprintf_buf ( HChar c, void *p )
737 HChar** b = p;
738 *(*b)++ = c;
741 UInt VG_(vsprintf) ( HChar* buf, const HChar *format, va_list vargs )
743 Int ret;
744 HChar* sprintf_ptr = buf;
746 ret = VG_(debugLog_vprintf)
747 ( add_to__sprintf_buf, &sprintf_ptr, format, vargs );
748 add_to__sprintf_buf('\0', &sprintf_ptr);
750 vg_assert(VG_(strlen)(buf) == ret);
752 return ret;
755 UInt VG_(sprintf) ( HChar* buf, const HChar *format, ... )
757 UInt ret;
758 va_list vargs;
759 va_start(vargs,format);
760 ret = VG_(vsprintf)(buf, format, vargs);
761 va_end(vargs);
762 return ret;
766 /* --------- snprintf --------- */
768 /* The return value of VG_(snprintf) and VG_(vsnprintf) differs from
769 what is defined in C99. Let S be the size of the buffer as given in
770 the 2nd argument.
771 Return value R:
772 R < S: The output string was successfully written to the buffer.
773 It is null-terminated and R == strlen( output string )
774 R == S: The supplied buffer was too small to hold the output string.
775 The first S-1 characters of the output string were written
776 to the buffer followed by the terminating null character.
779 typedef
780 struct {
781 HChar* buf;
782 Int buf_size;
783 Int buf_used;
785 snprintf_buf_t;
787 static void add_to__snprintf_buf ( HChar c, void* p )
789 snprintf_buf_t* b = p;
790 if (b->buf_size > 0 && b->buf_used < b->buf_size) {
791 b->buf[b->buf_used++] = c;
792 if (b->buf_used < b->buf_size)
793 b->buf[b->buf_used] = 0;
794 else
795 b->buf[b->buf_size-1] = 0; /* pre: b->buf_size > 0 */
799 UInt VG_(vsnprintf) ( HChar* buf, Int size, const HChar *format, va_list vargs )
801 snprintf_buf_t b;
802 b.buf = buf;
803 b.buf_size = size < 0 ? 0 : size;
804 b.buf_used = 0;
805 if (b.buf_size > 0)
806 b.buf[0] = 0; // ensure to null terminate buf if empty format
807 (void) VG_(debugLog_vprintf)
808 ( add_to__snprintf_buf, &b, format, vargs );
810 return b.buf_used;
813 UInt VG_(snprintf) ( HChar* buf, Int size, const HChar *format, ... )
815 UInt ret;
816 va_list vargs;
817 va_start(vargs,format);
818 ret = VG_(vsnprintf)(buf, size, format, vargs);
819 va_end(vargs);
820 return ret;
824 /* --------- vcbprintf --------- */
826 void VG_(vcbprintf)( void(*char_sink)(HChar, void* opaque),
827 void* opaque,
828 const HChar* format, va_list vargs )
830 (void) VG_(debugLog_vprintf)
831 ( char_sink, opaque, format, vargs );
835 /* --------- fprintf ---------- */
837 /* This is like [v]fprintf, except it writes to a file handle using
838 VG_(write). */
840 #define VGFILE_BUFSIZE 8192
842 struct _VgFile {
843 HChar buf[VGFILE_BUFSIZE];
844 UInt num_chars; // number of characters in buf
845 Int fd; // file descriptor to write to
849 static void add_to__vgfile ( HChar c, void *p )
851 VgFile *fp = p;
853 fp->buf[fp->num_chars++] = c;
855 if (fp->num_chars == VGFILE_BUFSIZE) {
856 VG_(write)(fp->fd, fp->buf, fp->num_chars);
857 fp->num_chars = 0;
861 VgFile *VG_(fopen)(const HChar *name, Int flags, Int mode)
863 SysRes res = VG_(open)(name, flags, mode);
865 if (sr_isError(res))
866 return NULL;
868 VgFile *fp = VG_(malloc)("fopen", sizeof(VgFile));
870 fp->fd = sr_Res(res);
871 fp->num_chars = 0;
873 return fp;
877 UInt VG_(vfprintf) ( VgFile *fp, const HChar *format, va_list vargs )
879 return VG_(debugLog_vprintf)(add_to__vgfile, fp, format, vargs);
882 UInt VG_(fprintf) ( VgFile *fp, const HChar *format, ... )
884 UInt ret;
885 va_list vargs;
886 va_start(vargs,format);
887 ret = VG_(vfprintf)(fp, format, vargs);
888 va_end(vargs);
889 return ret;
892 void VG_(fclose)( VgFile *fp )
894 // Flush the buffer.
895 if (fp->num_chars)
896 VG_(write)(fp->fd, fp->buf, fp->num_chars);
898 VG_(close)(fp->fd);
899 VG_(free)(fp);
903 /* ---------------------------------------------------------------------
904 elapsed_wallclock_time()
905 ------------------------------------------------------------------ */
907 /* Get the elapsed wallclock time since startup into buf, which must
908 16 chars long. This is unchecked. It also relies on the
909 millisecond timer having been set to zero by an initial read in
910 m_main during startup. */
912 void VG_(elapsed_wallclock_time) ( /*OUT*/HChar* buf, SizeT bufsize )
914 UInt t, ms, s, mins, hours, days;
916 vg_assert(bufsize > 20);
918 t = VG_(read_millisecond_timer)(); /* milliseconds */
920 ms = t % 1000;
921 t /= 1000; /* now in seconds */
923 s = t % 60;
924 t /= 60; /* now in minutes */
926 mins = t % 60;
927 t /= 60; /* now in hours */
929 hours = t % 24;
930 t /= 24; /* now in days */
932 days = t;
934 VG_(sprintf)(buf, "%02u:%02u:%02u:%02u.%03u ", days, hours, mins, s, ms);
938 /* ---------------------------------------------------------------------
939 message()
940 ------------------------------------------------------------------ */
942 /* A buffer for accumulating VG_(message) style output. This is
943 pretty much the same as VG_(printf)'s scheme, with two differences:
945 * The message buffer persists between calls, so that multiple
946 calls to VG_(message) can build up output.
948 * Whenever the first character on a line is emitted, the
949 ==PID== style preamble is stuffed in before it.
951 typedef
952 struct {
953 HChar buf[512+128];
954 Int buf_used;
955 Bool atLeft; /* notionally, is the next char position at the
956 leftmost column? */
957 /* Current message kind - changes from call to call */
958 VgMsgKind kind;
959 /* destination */
960 OutputSink* sink;
962 vmessage_buf_t;
964 static vmessage_buf_t vmessage_buf
965 = { "", 0, True, Vg_UserMsg, &VG_(log_output_sink) };
968 // Adds a single char to the buffer. We aim to have at least 128
969 // bytes free in the buffer, so that it's always possible to emit
970 // the preamble into the buffer if c happens to be the character
971 // following a \n. When the buffer gets too full, we write its
972 // contents to the logging sink.
973 static void add_to__vmessage_buf ( HChar c, void *p )
975 HChar tmp[64];
976 vmessage_buf_t* b = (vmessage_buf_t*)p;
978 vg_assert(b->buf_used >= 0 && b->buf_used < sizeof(b->buf)-128);
980 if (UNLIKELY(b->atLeft)) {
981 // insert preamble
982 HChar ch;
983 Int i, depth;
985 // Print one '>' in front of the messages for each level of
986 // self-hosting being performed.
987 // Do not print such '>' if sim hint "no-inner-prefix" given
988 // (useful to run regression tests in an outer/inner setup
989 // and avoid the diff failing due to these unexpected '>').
990 depth = RUNNING_ON_VALGRIND;
991 if (depth > 0
992 && !SimHintiS(SimHint_no_inner_prefix, VG_(clo_sim_hints))) {
993 if (depth > 10)
994 depth = 10; // ?!?!
995 for (i = 0; i < depth; i++) {
996 b->buf[b->buf_used++] = '>';
1000 if (Vg_FailMsg == b->kind) {
1001 // "valgrind: " prefix.
1002 b->buf[b->buf_used++] = 'v';
1003 b->buf[b->buf_used++] = 'a';
1004 b->buf[b->buf_used++] = 'l';
1005 b->buf[b->buf_used++] = 'g';
1006 b->buf[b->buf_used++] = 'r';
1007 b->buf[b->buf_used++] = 'i';
1008 b->buf[b->buf_used++] = 'n';
1009 b->buf[b->buf_used++] = 'd';
1010 b->buf[b->buf_used++] = ':';
1011 b->buf[b->buf_used++] = ' ';
1012 } else {
1013 switch (b->kind) {
1014 case Vg_UserMsg: ch = '='; break;
1015 case Vg_DebugMsg: ch = '-'; break;
1016 case Vg_ClientMsg: ch = '*'; break;
1017 default: ch = '?'; break;
1020 b->buf[b->buf_used++] = ch;
1021 b->buf[b->buf_used++] = ch;
1023 if (VG_(clo_time_stamp)) {
1024 VG_(elapsed_wallclock_time)(tmp, sizeof tmp);
1025 for (i = 0; tmp[i]; i++)
1026 b->buf[b->buf_used++] = tmp[i];
1029 VG_(sprintf)(tmp, "%d", VG_(getpid)());
1030 tmp[sizeof(tmp)-1] = 0;
1031 for (i = 0; tmp[i]; i++)
1032 b->buf[b->buf_used++] = tmp[i];
1034 b->buf[b->buf_used++] = ch;
1035 b->buf[b->buf_used++] = ch;
1036 b->buf[b->buf_used++] = ' ';
1039 /* We can't possibly have stuffed 96 chars in merely as a result
1040 of making the preamble (can we?) */
1041 vg_assert(b->buf_used < sizeof(b->buf)-32);
1044 b->buf[b->buf_used++] = c;
1045 b->buf[b->buf_used] = 0;
1047 if (b->buf_used >= sizeof(b->buf) - 128) {
1048 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
1049 b->buf_used = 0;
1052 b->atLeft = c == '\n';
1056 UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs )
1058 UInt ret;
1060 /* Note (carefully) that the buf persists from call to call, unlike
1061 with the other printf variants in earlier parts of this file. */
1062 vmessage_buf_t* b = &vmessage_buf; /* shorthand for convenience */
1064 /* We have to set this each call, so that the correct flavour
1065 of preamble is emitted at each \n. */
1066 b->kind = kind;
1068 ret = VG_(debugLog_vprintf) ( add_to__vmessage_buf,
1069 b, format, vargs );
1071 /* If the message finished exactly with a \n, then flush it at this
1072 point. If not, assume more bits of the same line will turn up
1073 in later messages, so don't bother to flush it right now. */
1075 if (b->atLeft && b->buf_used > 0) {
1076 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
1077 b->buf_used = 0;
1080 return ret;
1083 /* Send a simple single-part message. */
1084 UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... )
1086 UInt count;
1087 va_list vargs;
1088 va_start(vargs,format);
1089 count = VG_(vmessage) ( kind, format, vargs );
1090 va_end(vargs);
1091 return count;
1094 static void revert_to_stderr ( void )
1096 revert_sink_to_stderr(&VG_(log_output_sink));
1099 /* VG_(message) variants with hardwired first argument. */
1101 UInt VG_(fmsg) ( const HChar* format, ... )
1103 UInt count;
1104 va_list vargs;
1105 va_start(vargs,format);
1106 count = VG_(vmessage) ( Vg_FailMsg, format, vargs );
1107 va_end(vargs);
1108 return count;
1111 void VG_(fmsg_bad_option) ( const HChar* opt, const HChar* format, ... )
1113 va_list vargs;
1114 va_start(vargs,format);
1115 Bool fatal = VG_(Clo_Mode)() & cloEP;
1116 VgMsgKind mkind = fatal ? Vg_FailMsg : Vg_UserMsg;
1118 if (fatal)
1119 revert_to_stderr();
1120 VG_(message) (mkind, "Bad option: %s\n", opt);
1121 VG_(vmessage)(mkind, format, vargs );
1122 VG_(message) (mkind, "Use --help for more information or consult the user manual.\n");
1123 va_end(vargs);
1124 if (fatal)
1125 VG_(exit)(1);
1128 void VG_(fmsg_unknown_option) ( const HChar* opt)
1130 Bool fatal = VG_(Clo_Mode)() & cloEP;
1131 VgMsgKind mkind = fatal ? Vg_FailMsg : Vg_UserMsg;
1133 if (fatal)
1134 revert_to_stderr();
1136 VG_(message) (mkind, "Unknown option: %s\n", opt);
1137 VG_(message) (mkind, "Use --help for more information or consult the user manual.\n");
1138 if (fatal)
1139 VG_(exit)(1);
1142 UInt VG_(umsg) ( const HChar* format, ... )
1144 UInt count;
1145 va_list vargs;
1146 va_start(vargs,format);
1147 count = VG_(vmessage) ( Vg_UserMsg, format, vargs );
1148 va_end(vargs);
1149 return count;
1152 UInt VG_(dmsg) ( const HChar* format, ... )
1154 UInt count;
1155 va_list vargs;
1156 va_start(vargs,format);
1157 count = VG_(vmessage) ( Vg_DebugMsg, format, vargs );
1158 va_end(vargs);
1159 return count;
1162 /* Flush any output that has accumulated in vmessage_buf as a
1163 result of previous calls to VG_(message) et al. */
1164 void VG_(message_flush) ( void )
1166 vmessage_buf_t* b = &vmessage_buf;
1167 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
1168 b->buf_used = 0;
1171 __attribute__((noreturn))
1172 void VG_(err_missing_prog) ( void )
1174 revert_to_stderr();
1175 VG_(fmsg)("no program specified\n");
1176 VG_(fmsg)("Use --help for more information.\n");
1177 VG_(exit)(1);
1180 __attribute__((noreturn))
1181 void VG_(err_config_error) ( const HChar* format, ... )
1183 va_list vargs;
1184 va_start(vargs,format);
1185 revert_to_stderr();
1186 VG_(message) (Vg_FailMsg, "Startup or configuration error:\n ");
1187 VG_(vmessage)(Vg_FailMsg, format, vargs );
1188 VG_(message) (Vg_FailMsg, "Unable to start up properly. Giving up.\n");
1189 va_end(vargs);
1190 VG_(exit)(1);
1193 /* ---------------------------------------------------------------------
1194 VG_(sr_as_string)()
1195 ------------------------------------------------------------------ */
1197 #if defined(VGO_linux) || defined(VGO_freebsd)
1198 // FIXME: Does this function need to be adjusted for MIPS's _valEx ?
1199 const HChar *VG_(sr_as_string) ( SysRes sr )
1201 static HChar buf[7+1+2+16+1+1]; // large enough
1203 if (sr_isError(sr))
1204 VG_(sprintf)(buf, "Failure(0x%" FMT_REGWORD "x)", (RegWord)sr_Err(sr));
1205 else
1206 VG_(sprintf)(buf, "Success(0x%" FMT_REGWORD "x)", (RegWord)sr_Res(sr));
1207 return buf;
1210 #elif defined(VGO_darwin) || defined(VGO_solaris)
1212 const HChar *VG_(sr_as_string) ( SysRes sr )
1214 static HChar buf[7+1+2+16+1+2+16+1+1]; // large enough
1216 if (sr_isError(sr))
1217 VG_(sprintf)(buf, "Failure(0x%lx)", sr_Err(sr));
1218 else
1219 VG_(sprintf)(buf, "Success(0x%lx:0x%lx)", sr_ResHI(sr), sr_Res(sr));
1220 return buf;
1223 #else
1225 #error unknown OS
1227 #endif
1229 /*--------------------------------------------------------------------*/
1230 /*--- end ---*/
1231 /*--------------------------------------------------------------------*/