1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*--------------------------------------------------------------------*/
4 /*--- Libc printing. m_libcprint.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2017 Julian Seward
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
= '_';
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
]);
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
);
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
)
101 if (format
[i
] == '%') {
102 // We saw a '%'. What's next...
104 if ('q' == format
[i
]) {
106 if ('{' == format
[i
]) {
107 // Get the env var name, print its contents.
108 UInt begin_qualname
= ++i
;
110 if ('}' == format
[i
]) {
111 UInt qualname_len
= i
- begin_qualname
;
112 HChar qualname
[qualname_len
+ 1];
113 VG_(strncpy
)(qualname
, format
+ begin_qualname
,
115 qualname
[qualname_len
] = '\0';
116 HChar
*qual
= VG_(getenv
)(qualname
);
118 VG_(printf_xml
)("<logfilequalifier> <var>%pS</var> "
119 "<value>%pS</value> </logfilequalifier>\n",
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
) );
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");
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) {
166 VG_(printf_xml
)("<preamble>\n");
169 umsg_or_xml(VG_(clo_xml
) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
172 NULL
== VG_(details
).version
? "" : "-",
173 NULL
== VG_(details
).version
? "" : VG_(details
).version
,
174 VG_(details
).description
,
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",
183 umsg_or_xml(VG_(clo_xml
) ? "%s%pS%s\n" : "%s%s%s\n",
184 xpre
, VG_(details
).copyright_author
, xpost
);
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
);
203 umsg_or_xml("%s\n", xpost
);
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
));
232 VG_(printf_xml
)(" <exe>%pS</exe>\n", "(launcher name unknown)");
233 for (UInt i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++) {
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
++) {
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.
254 VG_(printf_xml
)("\n");
255 else if (VG_(clo_verbosity
) > 0)
258 if (VG_(clo_verbosity
) > 1) {
259 # if defined(VGO_linux)
263 VexArchInfo vex_archinfo
;
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
,
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");
279 const SizeT bufsiz
= 255;
280 HChar version_buf
[bufsiz
+1];
281 VG_(message
)(Vg_DebugMsg
, " ");
282 Int n
, fdno
= sr_Res(fd
);
284 n
= VG_(read
)(fdno
, version_buf
, bufsiz
);
286 VG_(message
)(Vg_DebugMsg
, " error reading /proc/version\n");
289 version_buf
[n
] = '\0';
290 VG_(message
)(Vg_DebugMsg
, "%s", version_buf
);
291 } while (n
== bufsiz
);
292 VG_(message
)(Vg_DebugMsg
, "\n");
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
};
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
);
313 VG_(message
)(Vg_DebugMsg
, " uname() failed\n");
315 VG_(message
)(Vg_DebugMsg
, " %s %s %s %s\n",
316 uts
.sysname
, uts
.release
, uts
.version
, uts
.machine
);
319 VG_(machine_get_VexArchInfo
)(&vex_arch
, &vex_archinfo
);
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
,
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
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
;
377 VG_(fmsg
)("Cannot create %s file '%s': %s\n",
378 (is_xml
) ? "XML" : "log", logfilename
,
379 VG_(strerror
)(sr_Err(sres
)));
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
);
393 VG_(fmsg
)("Invalid %s spec of '%s'\n",
394 (is_xml
) ? "--xml-socket" : "--log-socket",
395 clo_fname_unexpanded
);
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
);
411 sink
->type
= VgLogTo_Socket
;
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
));
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
);
426 VG_(fcntl
)(safe_fd
, VKI_F_SETFD
, VKI_FD_CLOEXEC
);
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
432 if (sink
->type
!= VgLogTo_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
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
);
453 VG_(free
)(logfilename
);
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
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
;
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:
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
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 --- */
531 vg_assert(VG_(clo_log_fname_unexpanded
) == NULL
);
535 log_fd
= prepare_sink_fd(VG_(clo_log_fname_unexpanded
),
536 &VG_(log_output_sink
), False
);
540 log_fd
= prepare_sink_socket(VG_(clo_log_fname_unexpanded
),
541 &VG_(log_output_sink
), False
);
545 /* --- set up the XML output channel --- */
548 vg_assert(VG_(clo_xml_fname_unexpanded
) == NULL
);
552 xml_fd
= prepare_sink_fd(VG_(clo_xml_fname_unexpanded
),
553 &VG_(xml_output_sink
), True
);
557 xml_fd
= prepare_sink_socket(VG_(clo_xml_fname_unexpanded
),
558 &VG_(xml_output_sink
), True
);
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 ..
578 finalize_sink_fd(&VG_(log_output_sink
), log_fd
, False
);
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 ..
588 finalize_sink_fd(&VG_(xml_output_sink
), xml_fd
, True
);
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. */
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
);
604 // For example, the listener process died. Switch back to stderr.
605 revert_sink_to_stderr(sink
);
606 VG_(write
)( sink
->fd
, msg
, nbytes
);
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
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 /* ---------------------------------------------------------------------
625 ------------------------------------------------------------------ */
627 /* --------- printf --------- */
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
);
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
)
656 if (b
->sink
->fd
>= 0 || b
->sink
->fd
== -2) {
657 ret
= VG_(debugLog_vprintf
)
658 ( add_to__printf_buf
, b
, format
, vargs
);
663 static UInt
vprintf_WRK ( OutputSink
* sink
,
664 const HChar
*format
, va_list vargs
)
666 printf_buf_t myprintf_buf
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
,
674 myprintf_buf
.buf_used
);
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
, ... )
688 va_start(vargs
, format
);
689 ret
= VG_(vprintf
)(format
, vargs
);
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
, ... )
703 va_start(vargs
, format
);
704 ret
= VG_(vprintf_xml
)(format
, vargs
);
709 static UInt
emit_WRK ( const HChar
* format
, va_list vargs
)
712 return VG_(vprintf_xml
)(format
, vargs
);
713 } else if (VG_(log_output_sink
).fd
== -2) {
714 return VG_(vprintf
) (format
, vargs
);
716 return VG_(vmessage
)(Vg_UserMsg
, format
, vargs
);
719 UInt
VG_(emit
) ( const HChar
* format
, ... )
723 va_start(vargs
, format
);
724 ret
= emit_WRK(format
, vargs
);
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
)
741 UInt
VG_(vsprintf
) ( HChar
* buf
, const HChar
*format
, va_list vargs
)
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
);
755 UInt
VG_(sprintf
) ( HChar
* buf
, const HChar
*format
, ... )
759 va_start(vargs
,format
);
760 ret
= VG_(vsprintf
)(buf
, format
, vargs
);
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
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.
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;
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
)
803 b
.buf_size
= size
< 0 ? 0 : size
;
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
);
813 UInt
VG_(snprintf
) ( HChar
* buf
, Int size
, const HChar
*format
, ... )
817 va_start(vargs
,format
);
818 ret
= VG_(vsnprintf
)(buf
, size
, format
, vargs
);
824 /* --------- vcbprintf --------- */
826 void VG_(vcbprintf
)( void(*char_sink
)(HChar
, 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
840 #define VGFILE_BUFSIZE 8192
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
)
853 fp
->buf
[fp
->num_chars
++] = c
;
855 if (fp
->num_chars
== VGFILE_BUFSIZE
) {
856 VG_(write
)(fp
->fd
, fp
->buf
, fp
->num_chars
);
861 VgFile
*VG_(fopen
)(const HChar
*name
, Int flags
, Int mode
)
863 SysRes res
= VG_(open
)(name
, flags
, mode
);
868 VgFile
*fp
= VG_(malloc
)("fopen", sizeof(VgFile
));
870 fp
->fd
= sr_Res(res
);
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
, ... )
886 va_start(vargs
,format
);
887 ret
= VG_(vfprintf
)(fp
, format
, vargs
);
892 void VG_(fclose
)( VgFile
*fp
)
896 VG_(write
)(fp
->fd
, fp
->buf
, fp
->num_chars
);
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 */
921 t
/= 1000; /* now in seconds */
924 t
/= 60; /* now in minutes */
927 t
/= 60; /* now in hours */
930 t
/= 24; /* now in days */
934 VG_(sprintf
)(buf
, "%02u:%02u:%02u:%02u.%03u ", days
, hours
, mins
, s
, ms
);
938 /* ---------------------------------------------------------------------
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.
955 Bool atLeft
; /* notionally, is the next char position at the
957 /* Current message kind - changes from call to call */
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
)
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
)) {
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
;
992 && !SimHintiS(SimHint_no_inner_prefix
, VG_(clo_sim_hints
))) {
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
++] = ' ';
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
);
1052 b
->atLeft
= c
== '\n';
1056 UInt
VG_(vmessage
) ( VgMsgKind kind
, const HChar
* format
, va_list vargs
)
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. */
1068 ret
= VG_(debugLog_vprintf
) ( add_to__vmessage_buf
,
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
);
1083 /* Send a simple single-part message. */
1084 UInt
VG_(message
) ( VgMsgKind kind
, const HChar
* format
, ... )
1088 va_start(vargs
,format
);
1089 count
= VG_(vmessage
) ( kind
, format
, vargs
);
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
, ... )
1105 va_start(vargs
,format
);
1106 count
= VG_(vmessage
) ( Vg_FailMsg
, format
, vargs
);
1111 void VG_(fmsg_bad_option
) ( const HChar
* opt
, const HChar
* format
, ... )
1114 va_start(vargs
,format
);
1115 Bool fatal
= VG_(Clo_Mode
)() & cloEP
;
1116 VgMsgKind mkind
= fatal
? Vg_FailMsg
: Vg_UserMsg
;
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");
1128 void VG_(fmsg_unknown_option
) ( const HChar
* opt
)
1130 Bool fatal
= VG_(Clo_Mode
)() & cloEP
;
1131 VgMsgKind mkind
= fatal
? Vg_FailMsg
: Vg_UserMsg
;
1136 VG_(message
) (mkind
, "Unknown option: %s\n", opt
);
1137 VG_(message
) (mkind
, "Use --help for more information or consult the user manual.\n");
1142 UInt
VG_(umsg
) ( const HChar
* format
, ... )
1146 va_start(vargs
,format
);
1147 count
= VG_(vmessage
) ( Vg_UserMsg
, format
, vargs
);
1152 UInt
VG_(dmsg
) ( const HChar
* format
, ... )
1156 va_start(vargs
,format
);
1157 count
= VG_(vmessage
) ( Vg_DebugMsg
, format
, vargs
);
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
);
1171 __attribute__((noreturn
))
1172 void VG_(err_missing_prog
) ( void )
1175 VG_(fmsg
)("no program specified\n");
1176 VG_(fmsg
)("Use --help for more information.\n");
1180 __attribute__((noreturn
))
1181 void VG_(err_config_error
) ( const HChar
* format
, ... )
1184 va_start(vargs
,format
);
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");
1193 /* ---------------------------------------------------------------------
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
1204 VG_(sprintf
)(buf
, "Failure(0x%" FMT_REGWORD
"x)", (RegWord
)sr_Err(sr
));
1206 VG_(sprintf
)(buf
, "Success(0x%" FMT_REGWORD
"x)", (RegWord
)sr_Res(sr
));
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
1217 VG_(sprintf
)(buf
, "Failure(0x%lx)", sr_Err(sr
));
1219 VG_(sprintf
)(buf
, "Success(0x%lx:0x%lx)", sr_ResHI(sr
), sr_Res(sr
));
1229 /*--------------------------------------------------------------------*/
1231 /*--------------------------------------------------------------------*/