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, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #include "vgversion.h"
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_debuglog.h"
37 #include "pub_core_gdbserver.h" // VG_(gdb_printf)
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcfile.h" // VG_(write)(), VG_(write_socket)()
41 #include "pub_core_libcprint.h"
42 #include "pub_core_libcproc.h" // VG_(getpid)(), VG_(read_millisecond_timer()
43 #include "pub_core_mallocfree.h" // VG_(malloc)
44 #include "pub_core_machine.h" // VG_(machine_get_VexArchInfo)
45 #include "pub_core_options.h"
46 #include "pub_core_clreq.h" // For RUNNING_ON_VALGRIND
47 #include "pub_core_clientstate.h"
48 #include "pub_core_syscall.h" // VG_(strerror)
49 #include "pub_core_tooliface.h" // VG_(details)
52 /*====================================================================*/
53 /*=== Printing the preamble ===*/
54 /*====================================================================*/
56 // Returns a strdup'd copy of |str| in which characters which are not in the
57 // obviously-harmless-ASCII range are replaced with '_'. Not doing this has
58 // been observed to cause xfce4-terminal to assert. Caller takes ownership
59 // of the returned string.
60 static HChar
* sanitise_arg (const HChar
* arg
)
62 HChar
* clone
= VG_(strdup
)("m_libcprint.sanitise_arg", arg
);
63 for (HChar
* p
= clone
; *p
; p
++) {
64 UInt c
= * ((UChar
*)p
);
65 if (c
< 32 || c
> 127) c
= '_';
71 // Print the argument, escaping any chars that require it.
72 static void umsg_arg(const HChar
*unsanitised_arg
)
74 HChar
* arg
= sanitise_arg(unsanitised_arg
);
75 SizeT len
= VG_(strlen
)(arg
);
76 const HChar
*special
= " \\<>";
77 for (UInt i
= 0; i
< len
; i
++) {
78 if (VG_(strchr
)(special
, arg
[i
])) {
79 VG_(umsg
)("\\"); // escape with a backslash if necessary
81 VG_(umsg
)("%c", arg
[i
]);
86 // Send output to the XML-stream and escape any XML meta-characters.
87 static void xml_arg(const HChar
*unsanitised_arg
)
89 HChar
* arg
= sanitise_arg(unsanitised_arg
);
90 VG_(printf_xml
)("%pS", arg
);
94 // Write the name and value of log file qualifiers to the xml file.
95 // We can safely assume here that the format string is well-formed.
96 // It has been checked earlier in VG_(expand_file_name) when processing
97 // command line options.
98 static void print_file_vars(const HChar
*format
)
103 if (format
[i
] == '%') {
104 // We saw a '%'. What's next...
106 if ('q' == format
[i
]) {
108 if ('{' == format
[i
]) {
109 // Get the env var name, print its contents.
110 UInt begin_qualname
= ++i
;
112 if ('}' == format
[i
]) {
113 UInt qualname_len
= i
- begin_qualname
;
114 HChar qualname
[qualname_len
+ 1];
115 VG_(strncpy
)(qualname
, format
+ begin_qualname
,
117 qualname
[qualname_len
] = '\0';
118 HChar
*qual
= VG_(getenv
)(qualname
);
120 VG_(printf_xml
)("<logfilequalifier> <var>%pS</var> "
121 "<value>%pS</value> </logfilequalifier>\n",
135 /* Ok, the logging sink is running now. Print a suitable preamble.
136 If logging to file or a socket, write details of parent PID and
137 command line args, to help people trying to interpret the
138 results of a run which encompasses multiple processes. */
139 void VG_(print_preamble
)(Bool logging_to_fd
)
141 const HChar
*xpre
= VG_(clo_xml
) ? " <line>" : "";
142 const HChar
*xpost
= VG_(clo_xml
) ? "</line>" : "";
143 UInt (*umsg_or_xml
)( const HChar
*, ... )
144 = VG_(clo_xml
) ? VG_(printf_xml
) : VG_(umsg
);
145 void (*umsg_or_xml_arg
)( const HChar
*) = VG_(clo_xml
) ? xml_arg
: umsg_arg
;
147 vg_assert( VG_(args_for_client
) );
148 vg_assert( VG_(args_for_valgrind
) );
149 vg_assert( VG_(clo_toolname
) );
152 VG_(printf_xml
)("<?xml version=\"1.0\"?>\n");
153 VG_(printf_xml
)("\n");
154 VG_(printf_xml
)("<valgrindoutput>\n");
155 VG_(printf_xml
)("\n");
156 VG_(printf_xml
)("<protocolversion>4</protocolversion>\n");
157 VG_(printf_xml
)("<protocoltool>%s</protocoltool>\n", VG_(clo_toolname
));
158 VG_(printf_xml
)("\n");
161 if (VG_(clo_xml
) || VG_(clo_verbosity
) > 0) {
164 VG_(printf_xml
)("<preamble>\n");
167 umsg_or_xml(VG_(clo_xml
) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
170 NULL
== VG_(details
).version
? "" : "-",
171 NULL
== VG_(details
).version
? "" : VG_(details
).version
,
172 VG_(details
).description
,
175 if (VG_(strlen
)(VG_(clo_toolname
)) >= 4 &&
176 VG_STREQN(4, VG_(clo_toolname
), "exp-")) {
177 umsg_or_xml("%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
181 umsg_or_xml(VG_(clo_xml
) ? "%s%pS%s\n" : "%s%s%s\n",
182 xpre
, VG_(details
).copyright_author
, xpost
);
186 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
187 xpre
, VG_(clo_verbosity
) <= 1 ? VERSION
: VERSION
"-" VGGIT
, xpost
);
189 // Print the command line. At one point we wrapped at 80 chars and
190 // printed a '\' as a line joiner, but that makes it hard to cut and
191 // paste the command line (because of the "==pid==" prefixes), so we now
192 // favour utility and simplicity over aesthetics.
193 umsg_or_xml("%sCommand: ", xpre
);
194 umsg_or_xml_arg(VG_(args_the_exename
));
196 for (UInt i
= 0; i
< VG_(sizeXA
)( VG_(args_for_client
)); i
++) {
197 HChar
*s
= *(HChar
**)VG_(indexXA
)( VG_(args_for_client
), i
);
201 umsg_or_xml("%s\n", xpost
);
204 VG_(printf_xml
)("</preamble>\n");
207 // Print the parent PID, and other stuff, if necessary.
208 if (!VG_(clo_xml
) && VG_(clo_verbosity
) > 0 && !logging_to_fd
) {
209 VG_(umsg
)("Parent PID: %d\n", VG_(getppid
)());
210 } else if (VG_(clo_xml
)) {
211 VG_(printf_xml
)("\n");
212 VG_(printf_xml
)("<pid>%d</pid>\n", VG_(getpid
)());
213 VG_(printf_xml
)("<ppid>%d</ppid>\n", VG_(getppid
)());
214 VG_(printf_xml
)("<tool>%pS</tool>\n", VG_(clo_toolname
));
215 if (VG_(clo_xml_fname_unexpanded
) != NULL
)
216 print_file_vars(VG_(clo_xml_fname_unexpanded
));
217 if (VG_(clo_xml_user_comment
)) {
218 /* Note: the user comment itself is XML and is therefore to
219 be passed through verbatim (%s) rather than escaped (%pS). */
220 VG_(printf_xml
)("<usercomment>%s</usercomment>\n",
221 VG_(clo_xml_user_comment
));
223 VG_(printf_xml
)("\n");
224 VG_(printf_xml
)("<args>\n");
226 VG_(printf_xml
)(" <vargv>\n");
227 if (VG_(name_of_launcher
))
228 VG_(printf_xml
)(" <exe>%pS</exe>\n", VG_(name_of_launcher
));
230 VG_(printf_xml
)(" <exe>%pS</exe>\n", "(launcher name unknown)");
231 for (UInt i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++) {
234 *(HChar
**) VG_(indexXA
)( VG_(args_for_valgrind
), i
));
236 VG_(printf_xml
)(" </vargv>\n");
238 VG_(printf_xml
)(" <argv>\n");
239 VG_(printf_xml
)(" <exe>%pS</exe>\n", VG_(args_the_exename
));
240 for (UInt i
= 0; i
< VG_(sizeXA
)( VG_(args_for_client
) ); i
++) {
243 *(HChar
**) VG_(indexXA
)( VG_(args_for_client
), i
));
245 VG_(printf_xml
)(" </argv>\n");
247 VG_(printf_xml
)("</args>\n");
250 // Last thing in the preamble is a blank line.
252 VG_(printf_xml
)("\n");
253 else if (VG_(clo_verbosity
) > 0)
256 if (VG_(clo_verbosity
) > 1) {
257 # if defined(VGO_linux)
261 VexArchInfo vex_archinfo
;
263 VG_(message
)(Vg_DebugMsg
, "\n");
264 VG_(message
)(Vg_DebugMsg
, "Valgrind options:\n");
265 for (UInt i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++) {
266 VG_(message
)(Vg_DebugMsg
,
268 *(HChar
**) VG_(indexXA
)( VG_(args_for_valgrind
), i
));
271 # if defined(VGO_linux)
272 VG_(message
)(Vg_DebugMsg
, "Contents of /proc/version:\n");
273 fd
= VG_(open
)("/proc/version", VKI_O_RDONLY
, 0);
274 if (sr_isError(fd
)) {
275 VG_(message
)(Vg_DebugMsg
, " can't open /proc/version\n");
277 const SizeT bufsiz
= 255;
278 HChar version_buf
[bufsiz
+1];
279 VG_(message
)(Vg_DebugMsg
, " ");
280 Int n
, fdno
= sr_Res(fd
);
282 n
= VG_(read
)(fdno
, version_buf
, bufsiz
);
284 VG_(message
)(Vg_DebugMsg
, " error reading /proc/version\n");
287 version_buf
[n
] = '\0';
288 VG_(message
)(Vg_DebugMsg
, "%s", version_buf
);
289 } while (n
== bufsiz
);
290 VG_(message
)(Vg_DebugMsg
, "\n");
293 # elif defined(VGO_darwin)
294 VG_(message
)(Vg_DebugMsg
, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
295 /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
296 however that syscall is OS X 10.10+ only. */
297 Int mib
[] = {CTL_KERN
, KERN_VERSION
};
299 VG_(sysctl
)(mib
, sizeof(mib
)/sizeof(Int
), NULL
, &len
, NULL
, 0);
300 HChar
*kernelVersion
= VG_(malloc
)("main.pp.1", len
);
301 VG_(sysctl
)(mib
, sizeof(mib
)/sizeof(Int
), kernelVersion
, &len
, NULL
, 0);
302 VG_(message
)(Vg_DebugMsg
, " %s\n", kernelVersion
);
303 VG_(free
)( kernelVersion
);
304 # elif defined(VGO_solaris)
305 /* There is no /proc/version file on Solaris so we try to get some
306 system information using the uname(2) syscall. */
307 struct vki_utsname uts
;
308 VG_(message
)(Vg_DebugMsg
, "System information:\n");
309 SysRes res
= VG_(do_syscall1
)(__NR_uname
, (UWord
)&uts
);
311 VG_(message
)(Vg_DebugMsg
, " uname() failed\n");
313 VG_(message
)(Vg_DebugMsg
, " %s %s %s %s\n",
314 uts
.sysname
, uts
.release
, uts
.version
, uts
.machine
);
317 VG_(machine_get_VexArchInfo
)(&vex_arch
, &vex_archinfo
);
320 "Arch and hwcaps: %s, %s, %s\n",
321 LibVEX_ppVexArch ( vex_arch
),
322 LibVEX_ppVexEndness ( vex_archinfo
.endness
),
323 LibVEX_ppVexHwCaps ( vex_arch
, vex_archinfo
.hwcaps
)
325 VG_(message
)(Vg_DebugMsg
,
326 "Page sizes: currently %u, max supported %u\n",
327 (UInt
) VKI_PAGE_SIZE
, (UInt
) VKI_MAX_PAGE_SIZE
);
328 VG_(message
)(Vg_DebugMsg
,
329 "Valgrind library directory: %s\n", VG_(libdir
));
333 /* ---------------------------------------------------------------------
334 Writing to file or a socket
335 ------------------------------------------------------------------ */
337 /* The destination sinks for normal and XML output. These have their
338 initial values here; they are set to final values by
339 m_main.main_process_cmd_line_options(). See comment at the top of
340 that function for the associated logic.
341 After startup, the gdbserver monitor command might temporarily
342 set the fd of log_output_sink to -2 to indicate that output is
343 to be given to gdb rather than output to the startup fd */
344 OutputSink
VG_(log_output_sink
) = { 2, VgLogTo_Fd
, NULL
}; /* 2 = stderr */
345 OutputSink
VG_(xml_output_sink
) = { -1, VgLogTo_Fd
, NULL
}; /* disabled */
347 static void revert_sink_to_stderr ( OutputSink
*sink
)
349 sink
->fd
= 2; /* stderr */
350 sink
->type
= VgLogTo_Fd
;
351 VG_(free
)(sink
->fsname_expanded
);
352 sink
->fsname_expanded
= NULL
;
355 static Int
prepare_sink_fd(const HChar
*clo_fname_unexpanded
, OutputSink
*sink
,
358 vg_assert(clo_fname_unexpanded
!= NULL
);
359 vg_assert(VG_(strlen
)(clo_fname_unexpanded
) <= 900); /* paranoia */
361 // Nb: we overwrite an existing file of this name without asking
363 HChar
*logfilename
= VG_(expand_file_name
)(
364 (is_xml
) ? "--xml-file" : "--log-file",
365 clo_fname_unexpanded
);
366 SysRes sres
= VG_(open
)(logfilename
,
367 VKI_O_CREAT
|VKI_O_WRONLY
|VKI_O_TRUNC
,
368 VKI_S_IRUSR
|VKI_S_IWUSR
|VKI_S_IRGRP
|VKI_S_IROTH
);
369 if (!sr_isError(sres
)) {
370 Int fd
= sr_Res(sres
);
371 sink
->fsname_expanded
= logfilename
;
372 sink
->type
= VgLogTo_File
;
375 VG_(fmsg
)("Cannot create %s file '%s': %s\n",
376 (is_xml
) ? "XML" : "log", logfilename
,
377 VG_(strerror
)(sr_Err(sres
)));
383 static Int
prepare_sink_socket(const HChar
*clo_fname_unexpanded
,
384 OutputSink
*sink
, Bool is_xml
)
386 vg_assert(clo_fname_unexpanded
!= NULL
);
387 vg_assert(VG_(strlen
)(clo_fname_unexpanded
) <= 900); /* paranoia */
389 Int fd
= VG_(connect_via_socket
)(clo_fname_unexpanded
);
391 VG_(fmsg
)("Invalid %s spec of '%s'\n",
392 (is_xml
) ? "--xml-socket" : "--log-socket",
393 clo_fname_unexpanded
);
398 VG_(umsg
)("Failed to connect to %slogging server '%s'.\n"
399 "%s will be sent to stderr instead.\n",
400 (is_xml
) ? "XML " : "",
401 clo_fname_unexpanded
,
402 (is_xml
) ? "XML output" : "Logging messages");
403 /* We don't change anything here. */
404 vg_assert(sink
->fd
== 2);
405 vg_assert(sink
->type
== VgLogTo_Fd
);
409 sink
->type
= VgLogTo_Socket
;
414 static void finalize_sink_fd(OutputSink
*sink
, Int new_fd
, Bool is_xml
)
416 // Move new_fd into the safe range, so it doesn't conflict with any app fds.
417 Int safe_fd
= VG_(fcntl
)(new_fd
, VKI_F_DUPFD
, VG_(fd_hard_limit
));
419 VG_(message
)(Vg_UserMsg
, "Valgrind: failed to move %s file descriptor "
420 "into safe range, using stderr\n",
421 (is_xml
) ? "XML" : "log");
422 revert_sink_to_stderr(sink
);
424 VG_(fcntl
)(safe_fd
, VKI_F_SETFD
, VKI_FD_CLOEXEC
);
429 /* Re-opens an output file sink when exanded file name differs from what we
430 have now. Returns 'True' if the sink was reopened */
431 static Bool
reopen_sink_if_needed(const HChar
*clo_fname_unexpanded
,
432 OutputSink
*sink
, Bool is_xml
)
434 if (sink
->type
== VgLogTo_File
) {
435 /* Try to expand --log|xml-file again and see if it differs from what
437 HChar
*logfilename
= VG_(expand_file_name
)(
438 (is_xml
) ? "--xml-file" : "--log-file",
439 clo_fname_unexpanded
);
440 if (VG_(strcmp
)(logfilename
, sink
->fsname_expanded
) != 0) {
441 Int fd
= prepare_sink_fd(clo_fname_unexpanded
, sink
, is_xml
);
442 finalize_sink_fd(sink
, fd
, is_xml
);
445 VG_(free
)(logfilename
);
451 void VG_(logging_atfork_child
)(ThreadId tid
)
453 /* If --child-silent-after-fork=yes was specified, set the output file
454 descriptors to 'impossible' values. This is noticed by
455 send_bytes_to_logging_sink(), which duly stops writing any further
457 if (VG_(clo_child_silent_after_fork
)) {
458 if (VG_(log_output_sink
).type
!= VgLogTo_Socket
) {
459 VG_(log_output_sink
).fd
= -1;
460 VG_(log_output_sink
).type
= VgLogTo_Fd
;
462 if (VG_(xml_output_sink
).type
!= VgLogTo_Socket
) {
463 VG_(xml_output_sink
).fd
= -1;
464 VG_(xml_output_sink
).type
= VgLogTo_Fd
;
467 if (reopen_sink_if_needed(VG_(clo_log_fname_unexpanded
),
468 &VG_(log_output_sink
), False
) ||
469 reopen_sink_if_needed(VG_(clo_xml_fname_unexpanded
),
470 &VG_(xml_output_sink
), True
)) {
471 VG_(print_preamble
)(VG_(log_output_sink
).type
!= VgLogTo_File
);
476 /* Initializes normal log and xml sinks (of type fd, file, or socket).
477 Any problem encountered is considered a hard error and causes V. to exit.
479 Comments on how the logging options are handled:
482 --log-fd= for a fd to write to (default setting, fd = 2)
483 --log-file= for a file name to write to
484 --log-socket= for a socket to write to
486 As a result of examining these and doing relevant socket/file
487 opening, a final fd is established. This is stored in
488 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
489 specified, then it is stored in VG_(clo_log_fname_unexpanded), in m_options.
490 And then STR, after expansion of %p and %q templates within
491 it, is stored in VG_(log_output_sink), just in case anybody wants to know
494 When printing, VG_(log_output_sink) is consulted to find the
495 fd to send output to.
497 Exactly analogous actions are undertaken for the XML output
498 channel, with the one difference that the default fd is -1, meaning
499 the channel is disabled by default. */
500 void VG_(init_log_xml_sinks
)(VgLogTo log_to
, VgLogTo xml_to
,
501 Int
/*initial*/log_fd
, Int
/*initial*/xml_fd
)
503 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
504 // and we cannot change it until we know what we are changing it to is ok.
506 /* Start setting up logging now. After this is done, VG_(log_output_sink)
507 and (if relevant) VG_(xml_output_sink) should be connected to whatever
508 sink has been selected, and we indiscriminately chuck stuff into it
509 without worrying what the nature of it is.
510 Oh the wonder of Unix streams. */
512 vg_assert(VG_(log_output_sink
).fd
== 2 /* stderr */);
513 vg_assert(VG_(log_output_sink
).type
== VgLogTo_Fd
);
514 vg_assert(VG_(log_output_sink
).fsname_expanded
== NULL
);
516 vg_assert(VG_(xml_output_sink
).fd
== -1 /* disabled */);
517 vg_assert(VG_(xml_output_sink
).type
== VgLogTo_Fd
);
518 vg_assert(VG_(xml_output_sink
).fsname_expanded
== NULL
);
520 /* --- set up the normal text output channel --- */
523 vg_assert(VG_(clo_log_fname_unexpanded
) == NULL
);
527 log_fd
= prepare_sink_fd(VG_(clo_log_fname_unexpanded
),
528 &VG_(log_output_sink
), False
);
532 log_fd
= prepare_sink_socket(VG_(clo_log_fname_unexpanded
),
533 &VG_(log_output_sink
), False
);
537 /* --- set up the XML output channel --- */
540 vg_assert(VG_(clo_xml_fname_unexpanded
) == NULL
);
544 xml_fd
= prepare_sink_fd(VG_(clo_xml_fname_unexpanded
),
545 &VG_(xml_output_sink
), True
);
549 xml_fd
= prepare_sink_socket(VG_(clo_xml_fname_unexpanded
),
550 &VG_(xml_output_sink
), True
);
554 /* If we've got this far, and XML mode was requested, but no XML
555 output channel appears to have been specified, just stop. We
556 could continue, and XML output will simply vanish into nowhere,
557 but that is likely to confuse the hell out of users, which is
558 distinctly Ungood. */
559 if (VG_(clo_xml
) && xml_fd
== -1) {
560 VG_(fmsg_bad_option
)(
561 "--xml=yes, but no XML destination specified",
562 "--xml=yes has been specified, but there is no XML output\n"
563 "destination. You must specify an XML output destination\n"
564 "using --xml-fd, --xml-file or --xml-socket.\n"
568 // Finalise the output fds: the log fd ..
570 finalize_sink_fd(&VG_(log_output_sink
), log_fd
, False
);
572 // If they said --log-fd=-1, don't print anything. Plausible for use in
573 // regression testing suites that use client requests to count errors.
574 VG_(log_output_sink
).fd
= -1;
575 VG_(log_output_sink
).type
= VgLogTo_Fd
;
578 // Finalise the output fds: and the XML fd ..
580 finalize_sink_fd(&VG_(xml_output_sink
), xml_fd
, True
);
582 // If they said --xml-fd=-1, don't print anything. Plausible for use in
583 // regression testing suites that use client requests to count errors.
584 VG_(xml_output_sink
).fd
= -1;
585 VG_(xml_output_sink
).type
= VgLogTo_Fd
;
589 /* Do the low-level send of a message to the logging sink. */
591 void send_bytes_to_logging_sink ( OutputSink
* sink
, const HChar
* msg
, Int nbytes
)
593 if (sink
->type
== VgLogTo_Socket
) {
594 Int rc
= VG_(write_socket
)( sink
->fd
, msg
, nbytes
);
596 // For example, the listener process died. Switch back to stderr.
597 revert_sink_to_stderr(sink
);
598 VG_(write
)( sink
->fd
, msg
, nbytes
);
601 /* sink->fd could have been set to -1 in the various
602 sys-wrappers for sys_fork, if --child-silent-after-fork=yes
603 is in effect. That is a signal that we should not produce
606 VG_(write
)( sink
->fd
, msg
, nbytes
);
607 else if (sink
->fd
== -2 && nbytes
> 0)
608 /* send to gdb the provided data, which must be
609 a null terminated string with len >= 1 */
610 VG_(gdb_printf
)("%s", msg
);
615 /* ---------------------------------------------------------------------
617 ------------------------------------------------------------------ */
619 /* --------- printf --------- */
629 // Adds a single char to the buffer. When the buffer gets sufficiently
630 // full, we write its contents to the logging sink.
631 static void add_to__printf_buf ( HChar c
, void *p
)
633 printf_buf_t
*b
= (printf_buf_t
*)p
;
635 if (b
->buf_used
> sizeof(b
->buf
) - 2 ) {
636 send_bytes_to_logging_sink( b
->sink
, b
->buf
, b
->buf_used
);
639 b
->buf
[b
->buf_used
++] = c
;
640 b
->buf
[b
->buf_used
] = 0;
641 vg_assert(b
->buf_used
< sizeof(b
->buf
));
644 static UInt
vprintf_to_buf ( printf_buf_t
* b
,
645 const HChar
*format
, va_list vargs
)
648 if (b
->sink
->fd
>= 0 || b
->sink
->fd
== -2) {
649 ret
= VG_(debugLog_vprintf
)
650 ( add_to__printf_buf
, b
, format
, vargs
);
655 static UInt
vprintf_WRK ( OutputSink
* sink
,
656 const HChar
*format
, va_list vargs
)
658 printf_buf_t myprintf_buf
661 = vprintf_to_buf(&myprintf_buf
, format
, vargs
);
662 // Write out any chars left in the buffer.
663 if (myprintf_buf
.buf_used
> 0) {
664 send_bytes_to_logging_sink( myprintf_buf
.sink
,
666 myprintf_buf
.buf_used
);
671 UInt
VG_(vprintf
) ( const HChar
*format
, va_list vargs
)
673 return vprintf_WRK( &VG_(log_output_sink
), format
, vargs
);
676 UInt
VG_(printf
) ( const HChar
*format
, ... )
680 va_start(vargs
, format
);
681 ret
= VG_(vprintf
)(format
, vargs
);
686 UInt
VG_(vprintf_xml
) ( const HChar
*format
, va_list vargs
)
688 return vprintf_WRK( &VG_(xml_output_sink
), format
, vargs
);
691 UInt
VG_(printf_xml
) ( const HChar
*format
, ... )
695 va_start(vargs
, format
);
696 ret
= VG_(vprintf_xml
)(format
, vargs
);
701 static UInt
emit_WRK ( const HChar
* format
, va_list vargs
)
704 return VG_(vprintf_xml
)(format
, vargs
);
705 } else if (VG_(log_output_sink
).fd
== -2) {
706 return VG_(vprintf
) (format
, vargs
);
708 return VG_(vmessage
)(Vg_UserMsg
, format
, vargs
);
711 UInt
VG_(emit
) ( const HChar
* format
, ... )
715 va_start(vargs
, format
);
716 ret
= emit_WRK(format
, vargs
);
721 /* --------- sprintf --------- */
723 /* If we had an explicit buf structure here, it would contain only one
724 field, indicating where the next char is to go. So use p directly
725 for that, rather than having it be a pointer to a structure. */
727 static void add_to__sprintf_buf ( HChar c
, void *p
)
733 UInt
VG_(vsprintf
) ( HChar
* buf
, const HChar
*format
, va_list vargs
)
736 HChar
* sprintf_ptr
= buf
;
738 ret
= VG_(debugLog_vprintf
)
739 ( add_to__sprintf_buf
, &sprintf_ptr
, format
, vargs
);
740 add_to__sprintf_buf('\0', &sprintf_ptr
);
742 vg_assert(VG_(strlen
)(buf
) == ret
);
747 UInt
VG_(sprintf
) ( HChar
* buf
, const HChar
*format
, ... )
751 va_start(vargs
,format
);
752 ret
= VG_(vsprintf
)(buf
, format
, vargs
);
758 /* --------- snprintf --------- */
760 /* The return value of VG_(snprintf) and VG_(vsnprintf) differs from
761 what is defined in C99. Let S be the size of the buffer as given in
764 R < S: The output string was successfully written to the buffer.
765 It is null-terminated and R == strlen( output string )
766 R == S: The supplied buffer was too small to hold the output string.
767 The first S-1 characters of the output string were written
768 to the buffer followed by the terminating null character.
779 static void add_to__snprintf_buf ( HChar c
, void* p
)
781 snprintf_buf_t
* b
= p
;
782 if (b
->buf_size
> 0 && b
->buf_used
< b
->buf_size
) {
783 b
->buf
[b
->buf_used
++] = c
;
784 if (b
->buf_used
< b
->buf_size
)
785 b
->buf
[b
->buf_used
] = 0;
787 b
->buf
[b
->buf_size
-1] = 0; /* pre: b->buf_size > 0 */
791 UInt
VG_(vsnprintf
) ( HChar
* buf
, Int size
, const HChar
*format
, va_list vargs
)
795 b
.buf_size
= size
< 0 ? 0 : size
;
798 b
.buf
[0] = 0; // ensure to null terminate buf if empty format
799 (void) VG_(debugLog_vprintf
)
800 ( add_to__snprintf_buf
, &b
, format
, vargs
);
805 UInt
VG_(snprintf
) ( HChar
* buf
, Int size
, const HChar
*format
, ... )
809 va_start(vargs
,format
);
810 ret
= VG_(vsnprintf
)(buf
, size
, format
, vargs
);
816 /* --------- vcbprintf --------- */
818 void VG_(vcbprintf
)( void(*char_sink
)(HChar
, void* opaque
),
820 const HChar
* format
, va_list vargs
)
822 (void) VG_(debugLog_vprintf
)
823 ( char_sink
, opaque
, format
, vargs
);
827 /* --------- fprintf ---------- */
829 /* This is like [v]fprintf, except it writes to a file handle using
832 #define VGFILE_BUFSIZE 8192
835 HChar buf
[VGFILE_BUFSIZE
];
836 UInt num_chars
; // number of characters in buf
837 Int fd
; // file descriptor to write to
841 static void add_to__vgfile ( HChar c
, void *p
)
845 fp
->buf
[fp
->num_chars
++] = c
;
847 if (fp
->num_chars
== VGFILE_BUFSIZE
) {
848 VG_(write
)(fp
->fd
, fp
->buf
, fp
->num_chars
);
853 VgFile
*VG_(fopen
)(const HChar
*name
, Int flags
, Int mode
)
855 SysRes res
= VG_(open
)(name
, flags
, mode
);
860 VgFile
*fp
= VG_(malloc
)("fopen", sizeof(VgFile
));
862 fp
->fd
= sr_Res(res
);
869 UInt
VG_(vfprintf
) ( VgFile
*fp
, const HChar
*format
, va_list vargs
)
871 return VG_(debugLog_vprintf
)(add_to__vgfile
, fp
, format
, vargs
);
874 UInt
VG_(fprintf
) ( VgFile
*fp
, const HChar
*format
, ... )
878 va_start(vargs
,format
);
879 ret
= VG_(vfprintf
)(fp
, format
, vargs
);
884 void VG_(fclose
)( VgFile
*fp
)
888 VG_(write
)(fp
->fd
, fp
->buf
, fp
->num_chars
);
895 /* ---------------------------------------------------------------------
896 elapsed_wallclock_time()
897 ------------------------------------------------------------------ */
899 /* Get the elapsed wallclock time since startup into buf, which must
900 16 chars long. This is unchecked. It also relies on the
901 millisecond timer having been set to zero by an initial read in
902 m_main during startup. */
904 void VG_(elapsed_wallclock_time
) ( /*OUT*/HChar
* buf
, SizeT bufsize
)
906 UInt t
, ms
, s
, mins
, hours
, days
;
908 vg_assert(bufsize
> 20);
910 t
= VG_(read_millisecond_timer
)(); /* milliseconds */
913 t
/= 1000; /* now in seconds */
916 t
/= 60; /* now in minutes */
919 t
/= 60; /* now in hours */
922 t
/= 24; /* now in days */
926 VG_(sprintf
)(buf
, "%02u:%02u:%02u:%02u.%03u ", days
, hours
, mins
, s
, ms
);
930 /* ---------------------------------------------------------------------
932 ------------------------------------------------------------------ */
934 /* A buffer for accumulating VG_(message) style output. This is
935 pretty much the same as VG_(printf)'s scheme, with two differences:
937 * The message buffer persists between calls, so that multiple
938 calls to VG_(message) can build up output.
940 * Whenever the first character on a line is emitted, the
941 ==PID== style preamble is stuffed in before it.
947 Bool atLeft
; /* notionally, is the next char position at the
949 /* Current message kind - changes from call to call */
956 static vmessage_buf_t vmessage_buf
957 = { "", 0, True
, Vg_UserMsg
, &VG_(log_output_sink
) };
960 // Adds a single char to the buffer. We aim to have at least 128
961 // bytes free in the buffer, so that it's always possible to emit
962 // the preamble into the buffer if c happens to be the character
963 // following a \n. When the buffer gets too full, we write its
964 // contents to the logging sink.
965 static void add_to__vmessage_buf ( HChar c
, void *p
)
968 vmessage_buf_t
* b
= (vmessage_buf_t
*)p
;
970 vg_assert(b
->buf_used
>= 0 && b
->buf_used
< sizeof(b
->buf
)-128);
972 if (UNLIKELY(b
->atLeft
)) {
977 // Print one '>' in front of the messages for each level of
978 // self-hosting being performed.
979 // Do not print such '>' if sim hint "no-inner-prefix" given
980 // (useful to run regression tests in an outer/inner setup
981 // and avoid the diff failing due to these unexpected '>').
982 depth
= RUNNING_ON_VALGRIND
;
984 && !SimHintiS(SimHint_no_inner_prefix
, VG_(clo_sim_hints
))) {
987 for (i
= 0; i
< depth
; i
++) {
988 b
->buf
[b
->buf_used
++] = '>';
992 if (Vg_FailMsg
== b
->kind
) {
993 // "valgrind: " prefix.
994 b
->buf
[b
->buf_used
++] = 'v';
995 b
->buf
[b
->buf_used
++] = 'a';
996 b
->buf
[b
->buf_used
++] = 'l';
997 b
->buf
[b
->buf_used
++] = 'g';
998 b
->buf
[b
->buf_used
++] = 'r';
999 b
->buf
[b
->buf_used
++] = 'i';
1000 b
->buf
[b
->buf_used
++] = 'n';
1001 b
->buf
[b
->buf_used
++] = 'd';
1002 b
->buf
[b
->buf_used
++] = ':';
1003 b
->buf
[b
->buf_used
++] = ' ';
1006 case Vg_UserMsg
: ch
= '='; break;
1007 case Vg_DebugMsg
: ch
= '-'; break;
1008 case Vg_ClientMsg
: ch
= '*'; break;
1009 default: ch
= '?'; break;
1012 b
->buf
[b
->buf_used
++] = ch
;
1013 b
->buf
[b
->buf_used
++] = ch
;
1015 if (VG_(clo_time_stamp
)) {
1016 VG_(elapsed_wallclock_time
)(tmp
, sizeof tmp
);
1017 for (i
= 0; tmp
[i
]; i
++)
1018 b
->buf
[b
->buf_used
++] = tmp
[i
];
1021 VG_(sprintf
)(tmp
, "%d", VG_(getpid
)());
1022 tmp
[sizeof(tmp
)-1] = 0;
1023 for (i
= 0; tmp
[i
]; i
++)
1024 b
->buf
[b
->buf_used
++] = tmp
[i
];
1026 b
->buf
[b
->buf_used
++] = ch
;
1027 b
->buf
[b
->buf_used
++] = ch
;
1028 b
->buf
[b
->buf_used
++] = ' ';
1031 /* We can't possibly have stuffed 96 chars in merely as a result
1032 of making the preamble (can we?) */
1033 vg_assert(b
->buf_used
< sizeof(b
->buf
)-32);
1036 b
->buf
[b
->buf_used
++] = c
;
1037 b
->buf
[b
->buf_used
] = 0;
1039 if (b
->buf_used
>= sizeof(b
->buf
) - 128) {
1040 send_bytes_to_logging_sink( b
->sink
, b
->buf
, b
->buf_used
);
1044 b
->atLeft
= c
== '\n';
1048 UInt
VG_(vmessage
) ( VgMsgKind kind
, const HChar
* format
, va_list vargs
)
1052 /* Note (carefully) that the buf persists from call to call, unlike
1053 with the other printf variants in earlier parts of this file. */
1054 vmessage_buf_t
* b
= &vmessage_buf
; /* shorthand for convenience */
1056 /* We have to set this each call, so that the correct flavour
1057 of preamble is emitted at each \n. */
1060 ret
= VG_(debugLog_vprintf
) ( add_to__vmessage_buf
,
1063 /* If the message finished exactly with a \n, then flush it at this
1064 point. If not, assume more bits of the same line will turn up
1065 in later messages, so don't bother to flush it right now. */
1067 if (b
->atLeft
&& b
->buf_used
> 0) {
1068 send_bytes_to_logging_sink( b
->sink
, b
->buf
, b
->buf_used
);
1075 /* Send a simple single-part message. */
1076 UInt
VG_(message
) ( VgMsgKind kind
, const HChar
* format
, ... )
1080 va_start(vargs
,format
);
1081 count
= VG_(vmessage
) ( kind
, format
, vargs
);
1086 static void revert_to_stderr ( void )
1088 revert_sink_to_stderr(&VG_(log_output_sink
));
1091 /* VG_(message) variants with hardwired first argument. */
1093 UInt
VG_(fmsg
) ( const HChar
* format
, ... )
1097 va_start(vargs
,format
);
1098 count
= VG_(vmessage
) ( Vg_FailMsg
, format
, vargs
);
1103 void VG_(fmsg_bad_option
) ( const HChar
* opt
, const HChar
* format
, ... )
1106 va_start(vargs
,format
);
1108 VG_(message
) (Vg_FailMsg
, "Bad option: %s\n", opt
);
1109 VG_(vmessage
)(Vg_FailMsg
, format
, vargs
);
1110 VG_(message
) (Vg_FailMsg
, "Use --help for more information or consult the user manual.\n");
1115 void VG_(fmsg_unknown_option
) ( const HChar
* opt
)
1118 VG_(message
) (Vg_FailMsg
, "Unknown option: %s\n", opt
);
1119 VG_(message
) (Vg_FailMsg
, "Use --help for more information or consult the user manual.\n");
1123 UInt
VG_(umsg
) ( const HChar
* format
, ... )
1127 va_start(vargs
,format
);
1128 count
= VG_(vmessage
) ( Vg_UserMsg
, format
, vargs
);
1133 UInt
VG_(dmsg
) ( const HChar
* format
, ... )
1137 va_start(vargs
,format
);
1138 count
= VG_(vmessage
) ( Vg_DebugMsg
, format
, vargs
);
1143 /* Flush any output that has accumulated in vmessage_buf as a
1144 result of previous calls to VG_(message) et al. */
1145 void VG_(message_flush
) ( void )
1147 vmessage_buf_t
* b
= &vmessage_buf
;
1148 send_bytes_to_logging_sink( b
->sink
, b
->buf
, b
->buf_used
);
1152 __attribute__((noreturn
))
1153 void VG_(err_missing_prog
) ( void )
1156 VG_(fmsg
)("no program specified\n");
1157 VG_(fmsg
)("Use --help for more information.\n");
1161 __attribute__((noreturn
))
1162 void VG_(err_config_error
) ( const HChar
* format
, ... )
1165 va_start(vargs
,format
);
1167 VG_(message
) (Vg_FailMsg
, "Startup or configuration error:\n ");
1168 VG_(vmessage
)(Vg_FailMsg
, format
, vargs
);
1169 VG_(message
) (Vg_FailMsg
, "Unable to start up properly. Giving up.\n");
1174 /* ---------------------------------------------------------------------
1176 ------------------------------------------------------------------ */
1178 #if defined(VGO_linux)
1179 // FIXME: Does this function need to be adjusted for MIPS's _valEx ?
1180 const HChar
*VG_(sr_as_string
) ( SysRes sr
)
1182 static HChar buf
[7+1+2+16+1+1]; // large enough
1185 VG_(sprintf
)(buf
, "Failure(0x%" FMT_REGWORD
"x)", (RegWord
)sr_Err(sr
));
1187 VG_(sprintf
)(buf
, "Success(0x%" FMT_REGWORD
"x)", (RegWord
)sr_Res(sr
));
1191 #elif defined(VGO_darwin) || defined(VGO_solaris)
1193 const HChar
*VG_(sr_as_string
) ( SysRes sr
)
1195 static HChar buf
[7+1+2+16+1+2+16+1+1]; // large enough
1198 VG_(sprintf
)(buf
, "Failure(0x%lx)", sr_Err(sr
));
1200 VG_(sprintf
)(buf
, "Success(0x%lx:0x%lx)", sr_ResHI(sr
), sr_Res(sr
));
1210 /*--------------------------------------------------------------------*/
1212 /*--------------------------------------------------------------------*/