configure.ac: Sort AC_CHECK_FUNCS() arguments alphabetically
[valgrind.git] / coregrind / m_libcprint.c
blob022209a12b8efa3b6fc3a23c3faa86d78d068658
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 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
155 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", VG_(clo_toolname));
156 VG_(printf_xml)("\n");
159 if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
161 if (VG_(clo_xml))
162 VG_(printf_xml)("<preamble>\n");
164 /* Tool details */
165 umsg_or_xml(VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
166 xpre,
167 VG_(details).name,
168 NULL == VG_(details).version ? "" : "-",
169 NULL == VG_(details).version ? "" : VG_(details).version,
170 VG_(details).description,
171 xpost);
173 if (VG_(strlen)(VG_(clo_toolname)) >= 4 &&
174 VG_STREQN(4, VG_(clo_toolname), "exp-")) {
175 umsg_or_xml("%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
176 xpre, xpost);
179 umsg_or_xml(VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
180 xpre, VG_(details).copyright_author, xpost);
182 /* Core details */
183 umsg_or_xml(
184 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
185 xpre, VG_(clo_verbosity) <= 1 ? VERSION : VERSION "-" VGGIT, xpost);
187 // Print the command line. At one point we wrapped at 80 chars and
188 // printed a '\' as a line joiner, but that makes it hard to cut and
189 // paste the command line (because of the "==pid==" prefixes), so we now
190 // favour utility and simplicity over aesthetics.
191 umsg_or_xml("%sCommand: ", xpre);
192 umsg_or_xml_arg(VG_(args_the_exename));
194 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client)); i++) {
195 HChar *s = *(HChar **)VG_(indexXA)( VG_(args_for_client), i);
196 umsg_or_xml(" ");
197 umsg_or_xml_arg(s);
199 umsg_or_xml("%s\n", xpost);
201 if (VG_(clo_xml))
202 VG_(printf_xml)("</preamble>\n");
205 // Print the parent PID, and other stuff, if necessary.
206 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
207 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
208 } else if (VG_(clo_xml)) {
209 VG_(printf_xml)("\n");
210 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
211 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
212 VG_(printf_xml)("<tool>%pS</tool>\n", VG_(clo_toolname));
213 if (VG_(clo_xml_fname_unexpanded) != NULL)
214 print_file_vars(VG_(clo_xml_fname_unexpanded));
215 if (VG_(clo_xml_user_comment)) {
216 /* Note: the user comment itself is XML and is therefore to
217 be passed through verbatim (%s) rather than escaped (%pS). */
218 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
219 VG_(clo_xml_user_comment));
221 VG_(printf_xml)("\n");
222 VG_(printf_xml)("<args>\n");
224 VG_(printf_xml)(" <vargv>\n");
225 if (VG_(name_of_launcher))
226 VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(name_of_launcher));
227 else
228 VG_(printf_xml)(" <exe>%pS</exe>\n", "(launcher name unknown)");
229 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
230 VG_(printf_xml)(
231 " <arg>%pS</arg>\n",
232 *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
234 VG_(printf_xml)(" </vargv>\n");
236 VG_(printf_xml)(" <argv>\n");
237 VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(args_the_exename));
238 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
239 VG_(printf_xml)(
240 " <arg>%pS</arg>\n",
241 *(HChar **) VG_(indexXA)( VG_(args_for_client), i));
243 VG_(printf_xml)(" </argv>\n");
245 VG_(printf_xml)("</args>\n");
248 // Last thing in the preamble is a blank line.
249 if (VG_(clo_xml))
250 VG_(printf_xml)("\n");
251 else if (VG_(clo_verbosity) > 0)
252 VG_(umsg)("\n");
254 if (VG_(clo_verbosity) > 1) {
255 # if defined(VGO_linux)
256 SysRes fd;
257 # endif
258 VexArch vex_arch;
259 VexArchInfo vex_archinfo;
260 if (!logging_to_fd)
261 VG_(message)(Vg_DebugMsg, "\n");
262 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
263 for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
264 VG_(message)(Vg_DebugMsg,
265 " %s\n",
266 *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
269 # if defined(VGO_linux)
270 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
271 fd = VG_(open)("/proc/version", VKI_O_RDONLY, 0);
272 if (sr_isError(fd)) {
273 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
274 } else {
275 const SizeT bufsiz = 255;
276 HChar version_buf[bufsiz+1];
277 VG_(message)(Vg_DebugMsg, " ");
278 Int n, fdno = sr_Res(fd);
279 do {
280 n = VG_(read)(fdno, version_buf, bufsiz);
281 if (n < 0) {
282 VG_(message)(Vg_DebugMsg, " error reading /proc/version\n");
283 break;
285 version_buf[n] = '\0';
286 VG_(message)(Vg_DebugMsg, "%s", version_buf);
287 } while (n == bufsiz);
288 VG_(message)(Vg_DebugMsg, "\n");
289 VG_(close)(fdno);
291 # elif defined(VGO_darwin)
292 VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
293 /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
294 however that syscall is OS X 10.10+ only. */
295 Int mib[] = {CTL_KERN, KERN_VERSION};
296 SizeT len;
297 VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
298 HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
299 VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
300 VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
301 VG_(free)( kernelVersion );
302 # elif defined(VGO_solaris)
303 /* There is no /proc/version file on Solaris so we try to get some
304 system information using the uname(2) syscall. */
305 struct vki_utsname uts;
306 VG_(message)(Vg_DebugMsg, "System information:\n");
307 SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
308 if (sr_isError(res))
309 VG_(message)(Vg_DebugMsg, " uname() failed\n");
310 else
311 VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
312 uts.sysname, uts.release, uts.version, uts.machine);
313 # endif
315 VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);
316 VG_(message)(
317 Vg_DebugMsg,
318 "Arch and hwcaps: %s, %s, %s\n",
319 LibVEX_ppVexArch ( vex_arch ),
320 LibVEX_ppVexEndness ( vex_archinfo.endness ),
321 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
323 VG_(message)(Vg_DebugMsg,
324 "Page sizes: currently %u, max supported %u\n",
325 (UInt) VKI_PAGE_SIZE, (UInt) VKI_MAX_PAGE_SIZE);
326 VG_(message)(Vg_DebugMsg,
327 "Valgrind library directory: %s\n", VG_(libdir));
331 /* ---------------------------------------------------------------------
332 Writing to file or a socket
333 ------------------------------------------------------------------ */
335 /* The destination sinks for normal and XML output. These have their
336 initial values here; they are set to final values by
337 m_main.main_process_cmd_line_options(). See comment at the top of
338 that function for the associated logic.
339 After startup, the gdbserver monitor command might temporarily
340 set the fd of log_output_sink to -2 to indicate that output is
341 to be given to gdb rather than output to the startup fd */
342 OutputSink VG_(log_output_sink) = { 2, VgLogTo_Fd, NULL }; /* 2 = stderr */
343 OutputSink VG_(xml_output_sink) = { -1, VgLogTo_Fd, NULL }; /* disabled */
345 static void revert_sink_to_stderr ( OutputSink *sink )
347 sink->fd = 2; /* stderr */
348 sink->type = VgLogTo_Fd;
349 VG_(free)(sink->fsname_expanded);
350 sink->fsname_expanded = NULL;
353 static Int prepare_sink_fd(const HChar *clo_fname_unexpanded, OutputSink *sink,
354 Bool is_xml)
356 vg_assert(clo_fname_unexpanded != NULL);
357 vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
359 // Nb: we overwrite an existing file of this name without asking
360 // any questions.
361 HChar *logfilename = VG_(expand_file_name)(
362 (is_xml) ? "--xml-file" : "--log-file",
363 clo_fname_unexpanded);
364 SysRes sres = VG_(open)(logfilename,
365 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
366 VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
367 if (!sr_isError(sres)) {
368 Int fd = sr_Res(sres);
369 sink->fsname_expanded = logfilename;
370 sink->type = VgLogTo_File;
371 return fd;
372 } else {
373 VG_(fmsg)("Cannot create %s file '%s': %s\n",
374 (is_xml) ? "XML" : "log", logfilename,
375 VG_(strerror)(sr_Err(sres)));
376 VG_(exit)(1);
377 /*NOTREACHED*/
381 static Int prepare_sink_socket(const HChar *clo_fname_unexpanded,
382 OutputSink *sink, Bool is_xml)
384 vg_assert(clo_fname_unexpanded != NULL);
385 vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
387 Int fd = VG_(connect_via_socket)(clo_fname_unexpanded);
388 if (fd == -1) {
389 VG_(fmsg)("Invalid %s spec of '%s'\n",
390 (is_xml) ? "--xml-socket" : "--log-socket",
391 clo_fname_unexpanded);
392 VG_(exit)(1);
393 /*NOTREACHED*/
395 if (fd == -2) {
396 VG_(umsg)("Failed to connect to %slogging server '%s'.\n"
397 "%s will be sent to stderr instead.\n",
398 (is_xml) ? "XML " : "",
399 clo_fname_unexpanded,
400 (is_xml) ? "XML output" : "Logging messages");
401 /* We don't change anything here. */
402 vg_assert(sink->fd == 2);
403 vg_assert(sink->type == VgLogTo_Fd);
404 return 2;
405 } else {
406 vg_assert(fd > 0);
407 sink->type = VgLogTo_Socket;
408 return fd;
412 static void finalize_sink_fd(OutputSink *sink, Int new_fd, Bool is_xml)
414 // Move new_fd into the safe range, so it doesn't conflict with any app fds.
415 Int safe_fd = VG_(fcntl)(new_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
416 if (safe_fd < 0) {
417 VG_(message)(Vg_UserMsg, "Valgrind: failed to move %s file descriptor "
418 "into safe range, using stderr\n",
419 (is_xml) ? "XML" : "log");
420 revert_sink_to_stderr(sink);
421 } else {
422 VG_(fcntl)(safe_fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
423 sink->fd = safe_fd;
427 /* Re-opens an output file sink when exanded file name differs from what we
428 have now. Returns 'True' if the sink was reopened */
429 static Bool reopen_sink_if_needed(const HChar *clo_fname_unexpanded,
430 OutputSink *sink, Bool is_xml)
432 if (sink->type == VgLogTo_File) {
433 /* Try to expand --log|xml-file again and see if it differs from what
434 we have now. */
435 HChar *logfilename = VG_(expand_file_name)(
436 (is_xml) ? "--xml-file" : "--log-file",
437 clo_fname_unexpanded);
438 if (VG_(strcmp)(logfilename, sink->fsname_expanded) != 0) {
439 Int fd = prepare_sink_fd(clo_fname_unexpanded, sink, is_xml);
440 finalize_sink_fd(sink, fd, is_xml);
441 return True;
443 VG_(free)(logfilename);
446 return False;
449 void VG_(logging_atfork_child)(ThreadId tid)
451 /* If --child-silent-after-fork=yes was specified, set the output file
452 descriptors to 'impossible' values. This is noticed by
453 send_bytes_to_logging_sink(), which duly stops writing any further
454 output. */
455 if (VG_(clo_child_silent_after_fork)) {
456 if (VG_(log_output_sink).type != VgLogTo_Socket) {
457 VG_(log_output_sink).fd = -1;
458 VG_(log_output_sink).type = VgLogTo_Fd;
460 if (VG_(xml_output_sink).type != VgLogTo_Socket) {
461 VG_(xml_output_sink).fd = -1;
462 VG_(xml_output_sink).type = VgLogTo_Fd;
464 } else {
465 if (reopen_sink_if_needed(VG_(clo_log_fname_unexpanded),
466 &VG_(log_output_sink), False) ||
467 reopen_sink_if_needed(VG_(clo_xml_fname_unexpanded),
468 &VG_(xml_output_sink), True)) {
469 VG_(print_preamble)(VG_(log_output_sink).type != VgLogTo_File);
474 /* Initializes normal log and xml sinks (of type fd, file, or socket).
475 Any problem encountered is considered a hard error and causes V. to exit.
477 Comments on how the logging options are handled:
479 User can specify:
480 --log-fd= for a fd to write to (default setting, fd = 2)
481 --log-file= for a file name to write to
482 --log-socket= for a socket to write to
484 As a result of examining these and doing relevant socket/file
485 opening, a final fd is established. This is stored in
486 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
487 specified, then it is stored in VG_(clo_log_fname_unexpanded), in m_options.
488 And then STR, after expansion of %p and %q templates within
489 it, is stored in VG_(log_output_sink), just in case anybody wants to know
490 what it is.
492 When printing, VG_(log_output_sink) is consulted to find the
493 fd to send output to.
495 Exactly analogous actions are undertaken for the XML output
496 channel, with the one difference that the default fd is -1, meaning
497 the channel is disabled by default. */
498 void VG_(init_log_xml_sinks)(VgLogTo log_to, VgLogTo xml_to,
499 Int /*initial*/log_fd, Int /*initial*/xml_fd)
501 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
502 // and we cannot change it until we know what we are changing it to is ok.
504 /* Start setting up logging now. After this is done, VG_(log_output_sink)
505 and (if relevant) VG_(xml_output_sink) should be connected to whatever
506 sink has been selected, and we indiscriminately chuck stuff into it
507 without worrying what the nature of it is.
508 Oh the wonder of Unix streams. */
510 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
511 vg_assert(VG_(log_output_sink).type == VgLogTo_Fd);
512 vg_assert(VG_(log_output_sink).fsname_expanded == NULL);
514 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
515 vg_assert(VG_(xml_output_sink).type == VgLogTo_Fd);
516 vg_assert(VG_(xml_output_sink).fsname_expanded == NULL);
518 /* --- set up the normal text output channel --- */
519 switch (log_to) {
520 case VgLogTo_Fd:
521 vg_assert(VG_(clo_log_fname_unexpanded) == NULL);
522 break;
524 case VgLogTo_File:
525 log_fd = prepare_sink_fd(VG_(clo_log_fname_unexpanded),
526 &VG_(log_output_sink), False);
527 break;
529 case VgLogTo_Socket:
530 log_fd = prepare_sink_socket(VG_(clo_log_fname_unexpanded),
531 &VG_(log_output_sink), False);
532 break;
535 /* --- set up the XML output channel --- */
536 switch (xml_to) {
537 case VgLogTo_Fd:
538 vg_assert(VG_(clo_xml_fname_unexpanded) == NULL);
539 break;
541 case VgLogTo_File:
542 xml_fd = prepare_sink_fd(VG_(clo_xml_fname_unexpanded),
543 &VG_(xml_output_sink), True);
544 break;
546 case VgLogTo_Socket:
547 xml_fd = prepare_sink_socket(VG_(clo_xml_fname_unexpanded),
548 &VG_(xml_output_sink), True);
549 break;
552 /* If we've got this far, and XML mode was requested, but no XML
553 output channel appears to have been specified, just stop. We
554 could continue, and XML output will simply vanish into nowhere,
555 but that is likely to confuse the hell out of users, which is
556 distinctly Ungood. */
557 if (VG_(clo_xml) && xml_fd == -1) {
558 VG_(fmsg_bad_option)(
559 "--xml=yes, but no XML destination specified",
560 "--xml=yes has been specified, but there is no XML output\n"
561 "destination. You must specify an XML output destination\n"
562 "using --xml-fd, --xml-file or --xml-socket.\n"
566 // Finalise the output fds: the log fd ..
567 if (log_fd >= 0) {
568 finalize_sink_fd(&VG_(log_output_sink), log_fd, False);
569 } else {
570 // If they said --log-fd=-1, don't print anything. Plausible for use in
571 // regression testing suites that use client requests to count errors.
572 VG_(log_output_sink).fd = -1;
573 VG_(log_output_sink).type = VgLogTo_Fd;
576 // Finalise the output fds: and the XML fd ..
577 if (xml_fd >= 0) {
578 finalize_sink_fd(&VG_(xml_output_sink), xml_fd, True);
579 } else {
580 // If they said --xml-fd=-1, don't print anything. Plausible for use in
581 // regression testing suites that use client requests to count errors.
582 VG_(xml_output_sink).fd = -1;
583 VG_(xml_output_sink).type = VgLogTo_Fd;
587 /* Do the low-level send of a message to the logging sink. */
588 static
589 void send_bytes_to_logging_sink ( OutputSink* sink, const HChar* msg, Int nbytes )
591 if (sink->type == VgLogTo_Socket) {
592 Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
593 if (rc == -1) {
594 // For example, the listener process died. Switch back to stderr.
595 revert_sink_to_stderr(sink);
596 VG_(write)( sink->fd, msg, nbytes );
598 } else {
599 /* sink->fd could have been set to -1 in the various
600 sys-wrappers for sys_fork, if --child-silent-after-fork=yes
601 is in effect. That is a signal that we should not produce
602 any more output. */
603 if (sink->fd >= 0)
604 VG_(write)( sink->fd, msg, nbytes );
605 else if (sink->fd == -2 && nbytes > 0)
606 /* send to gdb the provided data, which must be
607 a null terminated string with len >= 1 */
608 VG_(gdb_printf)("%s", msg);
613 /* ---------------------------------------------------------------------
614 printf() and friends
615 ------------------------------------------------------------------ */
617 /* --------- printf --------- */
619 typedef
620 struct {
621 HChar buf[512];
622 Int buf_used;
623 OutputSink* sink;
625 printf_buf_t;
627 // Adds a single char to the buffer. When the buffer gets sufficiently
628 // full, we write its contents to the logging sink.
629 static void add_to__printf_buf ( HChar c, void *p )
631 printf_buf_t *b = (printf_buf_t *)p;
633 if (b->buf_used > sizeof(b->buf) - 2 ) {
634 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
635 b->buf_used = 0;
637 b->buf[b->buf_used++] = c;
638 b->buf[b->buf_used] = 0;
639 vg_assert(b->buf_used < sizeof(b->buf));
642 static UInt vprintf_to_buf ( printf_buf_t* b,
643 const HChar *format, va_list vargs )
645 UInt ret = 0;
646 if (b->sink->fd >= 0 || b->sink->fd == -2) {
647 ret = VG_(debugLog_vprintf)
648 ( add_to__printf_buf, b, format, vargs );
650 return ret;
653 static UInt vprintf_WRK ( OutputSink* sink,
654 const HChar *format, va_list vargs )
656 printf_buf_t myprintf_buf
657 = { "", 0, sink };
658 UInt ret
659 = vprintf_to_buf(&myprintf_buf, format, vargs);
660 // Write out any chars left in the buffer.
661 if (myprintf_buf.buf_used > 0) {
662 send_bytes_to_logging_sink( myprintf_buf.sink,
663 myprintf_buf.buf,
664 myprintf_buf.buf_used );
666 return ret;
669 UInt VG_(vprintf) ( const HChar *format, va_list vargs )
671 return vprintf_WRK( &VG_(log_output_sink), format, vargs );
674 UInt VG_(printf) ( const HChar *format, ... )
676 UInt ret;
677 va_list vargs;
678 va_start(vargs, format);
679 ret = VG_(vprintf)(format, vargs);
680 va_end(vargs);
681 return ret;
684 UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs )
686 return vprintf_WRK( &VG_(xml_output_sink), format, vargs );
689 UInt VG_(printf_xml) ( const HChar *format, ... )
691 UInt ret;
692 va_list vargs;
693 va_start(vargs, format);
694 ret = VG_(vprintf_xml)(format, vargs);
695 va_end(vargs);
696 return ret;
699 static UInt emit_WRK ( const HChar* format, va_list vargs )
701 if (VG_(clo_xml)) {
702 return VG_(vprintf_xml)(format, vargs);
703 } else if (VG_(log_output_sink).fd == -2) {
704 return VG_(vprintf) (format, vargs);
705 } else {
706 return VG_(vmessage)(Vg_UserMsg, format, vargs);
709 UInt VG_(emit) ( const HChar* format, ... )
711 UInt ret;
712 va_list vargs;
713 va_start(vargs, format);
714 ret = emit_WRK(format, vargs);
715 va_end(vargs);
716 return ret;
719 /* --------- sprintf --------- */
721 /* If we had an explicit buf structure here, it would contain only one
722 field, indicating where the next char is to go. So use p directly
723 for that, rather than having it be a pointer to a structure. */
725 static void add_to__sprintf_buf ( HChar c, void *p )
727 HChar** b = p;
728 *(*b)++ = c;
731 UInt VG_(vsprintf) ( HChar* buf, const HChar *format, va_list vargs )
733 Int ret;
734 HChar* sprintf_ptr = buf;
736 ret = VG_(debugLog_vprintf)
737 ( add_to__sprintf_buf, &sprintf_ptr, format, vargs );
738 add_to__sprintf_buf('\0', &sprintf_ptr);
740 vg_assert(VG_(strlen)(buf) == ret);
742 return ret;
745 UInt VG_(sprintf) ( HChar* buf, const HChar *format, ... )
747 UInt ret;
748 va_list vargs;
749 va_start(vargs,format);
750 ret = VG_(vsprintf)(buf, format, vargs);
751 va_end(vargs);
752 return ret;
756 /* --------- snprintf --------- */
758 /* The return value of VG_(snprintf) and VG_(vsnprintf) differs from
759 what is defined in C99. Let S be the size of the buffer as given in
760 the 2nd argument.
761 Return value R:
762 R < S: The output string was successfully written to the buffer.
763 It is null-terminated and R == strlen( output string )
764 R == S: The supplied buffer was too small to hold the output string.
765 The first S-1 characters of the output string were written
766 to the buffer followed by the terminating null character.
769 typedef
770 struct {
771 HChar* buf;
772 Int buf_size;
773 Int buf_used;
775 snprintf_buf_t;
777 static void add_to__snprintf_buf ( HChar c, void* p )
779 snprintf_buf_t* b = p;
780 if (b->buf_size > 0 && b->buf_used < b->buf_size) {
781 b->buf[b->buf_used++] = c;
782 if (b->buf_used < b->buf_size)
783 b->buf[b->buf_used] = 0;
784 else
785 b->buf[b->buf_size-1] = 0; /* pre: b->buf_size > 0 */
789 UInt VG_(vsnprintf) ( HChar* buf, Int size, const HChar *format, va_list vargs )
791 snprintf_buf_t b;
792 b.buf = buf;
793 b.buf_size = size < 0 ? 0 : size;
794 b.buf_used = 0;
795 if (b.buf_size > 0)
796 b.buf[0] = 0; // ensure to null terminate buf if empty format
797 (void) VG_(debugLog_vprintf)
798 ( add_to__snprintf_buf, &b, format, vargs );
800 return b.buf_used;
803 UInt VG_(snprintf) ( HChar* buf, Int size, const HChar *format, ... )
805 UInt ret;
806 va_list vargs;
807 va_start(vargs,format);
808 ret = VG_(vsnprintf)(buf, size, format, vargs);
809 va_end(vargs);
810 return ret;
814 /* --------- vcbprintf --------- */
816 void VG_(vcbprintf)( void(*char_sink)(HChar, void* opaque),
817 void* opaque,
818 const HChar* format, va_list vargs )
820 (void) VG_(debugLog_vprintf)
821 ( char_sink, opaque, format, vargs );
825 /* --------- fprintf ---------- */
827 /* This is like [v]fprintf, except it writes to a file handle using
828 VG_(write). */
830 #define VGFILE_BUFSIZE 8192
832 struct _VgFile {
833 HChar buf[VGFILE_BUFSIZE];
834 UInt num_chars; // number of characters in buf
835 Int fd; // file descriptor to write to
839 static void add_to__vgfile ( HChar c, void *p )
841 VgFile *fp = p;
843 fp->buf[fp->num_chars++] = c;
845 if (fp->num_chars == VGFILE_BUFSIZE) {
846 VG_(write)(fp->fd, fp->buf, fp->num_chars);
847 fp->num_chars = 0;
851 VgFile *VG_(fopen)(const HChar *name, Int flags, Int mode)
853 SysRes res = VG_(open)(name, flags, mode);
855 if (sr_isError(res))
856 return NULL;
858 VgFile *fp = VG_(malloc)("fopen", sizeof(VgFile));
860 fp->fd = sr_Res(res);
861 fp->num_chars = 0;
863 return fp;
867 UInt VG_(vfprintf) ( VgFile *fp, const HChar *format, va_list vargs )
869 return VG_(debugLog_vprintf)(add_to__vgfile, fp, format, vargs);
872 UInt VG_(fprintf) ( VgFile *fp, const HChar *format, ... )
874 UInt ret;
875 va_list vargs;
876 va_start(vargs,format);
877 ret = VG_(vfprintf)(fp, format, vargs);
878 va_end(vargs);
879 return ret;
882 void VG_(fclose)( VgFile *fp )
884 // Flush the buffer.
885 if (fp->num_chars)
886 VG_(write)(fp->fd, fp->buf, fp->num_chars);
888 VG_(close)(fp->fd);
889 VG_(free)(fp);
893 /* ---------------------------------------------------------------------
894 elapsed_wallclock_time()
895 ------------------------------------------------------------------ */
897 /* Get the elapsed wallclock time since startup into buf, which must
898 16 chars long. This is unchecked. It also relies on the
899 millisecond timer having been set to zero by an initial read in
900 m_main during startup. */
902 void VG_(elapsed_wallclock_time) ( /*OUT*/HChar* buf, SizeT bufsize )
904 UInt t, ms, s, mins, hours, days;
906 vg_assert(bufsize > 20);
908 t = VG_(read_millisecond_timer)(); /* milliseconds */
910 ms = t % 1000;
911 t /= 1000; /* now in seconds */
913 s = t % 60;
914 t /= 60; /* now in minutes */
916 mins = t % 60;
917 t /= 60; /* now in hours */
919 hours = t % 24;
920 t /= 24; /* now in days */
922 days = t;
924 VG_(sprintf)(buf, "%02u:%02u:%02u:%02u.%03u ", days, hours, mins, s, ms);
928 /* ---------------------------------------------------------------------
929 message()
930 ------------------------------------------------------------------ */
932 /* A buffer for accumulating VG_(message) style output. This is
933 pretty much the same as VG_(printf)'s scheme, with two differences:
935 * The message buffer persists between calls, so that multiple
936 calls to VG_(message) can build up output.
938 * Whenever the first character on a line is emitted, the
939 ==PID== style preamble is stuffed in before it.
941 typedef
942 struct {
943 HChar buf[512+128];
944 Int buf_used;
945 Bool atLeft; /* notionally, is the next char position at the
946 leftmost column? */
947 /* Current message kind - changes from call to call */
948 VgMsgKind kind;
949 /* destination */
950 OutputSink* sink;
952 vmessage_buf_t;
954 static vmessage_buf_t vmessage_buf
955 = { "", 0, True, Vg_UserMsg, &VG_(log_output_sink) };
958 // Adds a single char to the buffer. We aim to have at least 128
959 // bytes free in the buffer, so that it's always possible to emit
960 // the preamble into the buffer if c happens to be the character
961 // following a \n. When the buffer gets too full, we write its
962 // contents to the logging sink.
963 static void add_to__vmessage_buf ( HChar c, void *p )
965 HChar tmp[64];
966 vmessage_buf_t* b = (vmessage_buf_t*)p;
968 vg_assert(b->buf_used >= 0 && b->buf_used < sizeof(b->buf)-128);
970 if (UNLIKELY(b->atLeft)) {
971 // insert preamble
972 HChar ch;
973 Int i, depth;
975 // Print one '>' in front of the messages for each level of
976 // self-hosting being performed.
977 // Do not print such '>' if sim hint "no-inner-prefix" given
978 // (useful to run regression tests in an outer/inner setup
979 // and avoid the diff failing due to these unexpected '>').
980 depth = RUNNING_ON_VALGRIND;
981 if (depth > 0
982 && !SimHintiS(SimHint_no_inner_prefix, VG_(clo_sim_hints))) {
983 if (depth > 10)
984 depth = 10; // ?!?!
985 for (i = 0; i < depth; i++) {
986 b->buf[b->buf_used++] = '>';
990 if (Vg_FailMsg == b->kind) {
991 // "valgrind: " prefix.
992 b->buf[b->buf_used++] = 'v';
993 b->buf[b->buf_used++] = 'a';
994 b->buf[b->buf_used++] = 'l';
995 b->buf[b->buf_used++] = 'g';
996 b->buf[b->buf_used++] = 'r';
997 b->buf[b->buf_used++] = 'i';
998 b->buf[b->buf_used++] = 'n';
999 b->buf[b->buf_used++] = 'd';
1000 b->buf[b->buf_used++] = ':';
1001 b->buf[b->buf_used++] = ' ';
1002 } else {
1003 switch (b->kind) {
1004 case Vg_UserMsg: ch = '='; break;
1005 case Vg_DebugMsg: ch = '-'; break;
1006 case Vg_ClientMsg: ch = '*'; break;
1007 default: ch = '?'; break;
1010 b->buf[b->buf_used++] = ch;
1011 b->buf[b->buf_used++] = ch;
1013 if (VG_(clo_time_stamp)) {
1014 VG_(elapsed_wallclock_time)(tmp, sizeof tmp);
1015 for (i = 0; tmp[i]; i++)
1016 b->buf[b->buf_used++] = tmp[i];
1019 VG_(sprintf)(tmp, "%d", VG_(getpid)());
1020 tmp[sizeof(tmp)-1] = 0;
1021 for (i = 0; tmp[i]; i++)
1022 b->buf[b->buf_used++] = tmp[i];
1024 b->buf[b->buf_used++] = ch;
1025 b->buf[b->buf_used++] = ch;
1026 b->buf[b->buf_used++] = ' ';
1029 /* We can't possibly have stuffed 96 chars in merely as a result
1030 of making the preamble (can we?) */
1031 vg_assert(b->buf_used < sizeof(b->buf)-32);
1034 b->buf[b->buf_used++] = c;
1035 b->buf[b->buf_used] = 0;
1037 if (b->buf_used >= sizeof(b->buf) - 128) {
1038 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
1039 b->buf_used = 0;
1042 b->atLeft = c == '\n';
1046 UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs )
1048 UInt ret;
1050 /* Note (carefully) that the buf persists from call to call, unlike
1051 with the other printf variants in earlier parts of this file. */
1052 vmessage_buf_t* b = &vmessage_buf; /* shorthand for convenience */
1054 /* We have to set this each call, so that the correct flavour
1055 of preamble is emitted at each \n. */
1056 b->kind = kind;
1058 ret = VG_(debugLog_vprintf) ( add_to__vmessage_buf,
1059 b, format, vargs );
1061 /* If the message finished exactly with a \n, then flush it at this
1062 point. If not, assume more bits of the same line will turn up
1063 in later messages, so don't bother to flush it right now. */
1065 if (b->atLeft && b->buf_used > 0) {
1066 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
1067 b->buf_used = 0;
1070 return ret;
1073 /* Send a simple single-part message. */
1074 UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... )
1076 UInt count;
1077 va_list vargs;
1078 va_start(vargs,format);
1079 count = VG_(vmessage) ( kind, format, vargs );
1080 va_end(vargs);
1081 return count;
1084 static void revert_to_stderr ( void )
1086 revert_sink_to_stderr(&VG_(log_output_sink));
1089 /* VG_(message) variants with hardwired first argument. */
1091 UInt VG_(fmsg) ( const HChar* format, ... )
1093 UInt count;
1094 va_list vargs;
1095 va_start(vargs,format);
1096 count = VG_(vmessage) ( Vg_FailMsg, format, vargs );
1097 va_end(vargs);
1098 return count;
1101 void VG_(fmsg_bad_option) ( const HChar* opt, const HChar* format, ... )
1103 va_list vargs;
1104 va_start(vargs,format);
1105 Bool fatal = VG_(Clo_Mode)() & cloEP;
1106 VgMsgKind mkind = fatal ? Vg_FailMsg : Vg_UserMsg;
1108 if (fatal)
1109 revert_to_stderr();
1110 VG_(message) (mkind, "Bad option: %s\n", opt);
1111 VG_(vmessage)(mkind, format, vargs );
1112 VG_(message) (mkind, "Use --help for more information or consult the user manual.\n");
1113 va_end(vargs);
1114 if (fatal)
1115 VG_(exit)(1);
1118 void VG_(fmsg_unknown_option) ( const HChar* opt)
1120 Bool fatal = VG_(Clo_Mode)() & cloEP;
1121 VgMsgKind mkind = fatal ? Vg_FailMsg : Vg_UserMsg;
1123 if (fatal)
1124 revert_to_stderr();
1126 VG_(message) (mkind, "Unknown option: %s\n", opt);
1127 VG_(message) (mkind, "Use --help for more information or consult the user manual.\n");
1128 if (fatal)
1129 VG_(exit)(1);
1132 UInt VG_(umsg) ( const HChar* format, ... )
1134 UInt count;
1135 va_list vargs;
1136 va_start(vargs,format);
1137 count = VG_(vmessage) ( Vg_UserMsg, format, vargs );
1138 va_end(vargs);
1139 return count;
1142 UInt VG_(dmsg) ( const HChar* format, ... )
1144 UInt count;
1145 va_list vargs;
1146 va_start(vargs,format);
1147 count = VG_(vmessage) ( Vg_DebugMsg, format, vargs );
1148 va_end(vargs);
1149 return count;
1152 /* Flush any output that has accumulated in vmessage_buf as a
1153 result of previous calls to VG_(message) et al. */
1154 void VG_(message_flush) ( void )
1156 vmessage_buf_t* b = &vmessage_buf;
1157 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
1158 b->buf_used = 0;
1161 __attribute__((noreturn))
1162 void VG_(err_missing_prog) ( void )
1164 revert_to_stderr();
1165 VG_(fmsg)("no program specified\n");
1166 VG_(fmsg)("Use --help for more information.\n");
1167 VG_(exit)(1);
1170 __attribute__((noreturn))
1171 void VG_(err_config_error) ( const HChar* format, ... )
1173 va_list vargs;
1174 va_start(vargs,format);
1175 revert_to_stderr();
1176 VG_(message) (Vg_FailMsg, "Startup or configuration error:\n ");
1177 VG_(vmessage)(Vg_FailMsg, format, vargs );
1178 VG_(message) (Vg_FailMsg, "Unable to start up properly. Giving up.\n");
1179 va_end(vargs);
1180 VG_(exit)(1);
1183 /* ---------------------------------------------------------------------
1184 VG_(sr_as_string)()
1185 ------------------------------------------------------------------ */
1187 #if defined(VGO_linux)
1188 // FIXME: Does this function need to be adjusted for MIPS's _valEx ?
1189 const HChar *VG_(sr_as_string) ( SysRes sr )
1191 static HChar buf[7+1+2+16+1+1]; // large enough
1193 if (sr_isError(sr))
1194 VG_(sprintf)(buf, "Failure(0x%" FMT_REGWORD "x)", (RegWord)sr_Err(sr));
1195 else
1196 VG_(sprintf)(buf, "Success(0x%" FMT_REGWORD "x)", (RegWord)sr_Res(sr));
1197 return buf;
1200 #elif defined(VGO_darwin) || defined(VGO_solaris)
1202 const HChar *VG_(sr_as_string) ( SysRes sr )
1204 static HChar buf[7+1+2+16+1+2+16+1+1]; // large enough
1206 if (sr_isError(sr))
1207 VG_(sprintf)(buf, "Failure(0x%lx)", sr_Err(sr));
1208 else
1209 VG_(sprintf)(buf, "Success(0x%lx:0x%lx)", sr_ResHI(sr), sr_Res(sr));
1210 return buf;
1213 #else
1215 #error unknown OS
1217 #endif
1219 /*--------------------------------------------------------------------*/
1220 /*--- end ---*/
1221 /*--------------------------------------------------------------------*/