1
2 /*--------------------------------------------------------------------*/
3 /*--- Libc printing. m_libcprint.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2011 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_debuglog.h"
34 #include "pub_core_gdbserver.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_libcassert.h"
37 #include "pub_core_libcfile.h" // VG_(write)(), VG_(write_socket)()
38 #include "pub_core_libcprint.h"
39 #include "pub_core_libcproc.h" // VG_(getpid)(), VG_(read_millisecond_timer()
40 #include "pub_core_options.h"
41 #include "valgrind.h" // For RUNNING_ON_VALGRIND
42
43
44 /* ---------------------------------------------------------------------
45 Writing to file or a socket
46 ------------------------------------------------------------------ */
47
48 /* The destination sinks for normal and XML output. These have their
49 initial values here; they are set to final values by
50 m_main.main_process_cmd_line_options(). See comment at the top of
51 that function for the associated logic.
52 After startup, the gdbserver monitor command might temporarily
53 set the fd of log_output_sink to -2 to indicate that output is
54 to be given to gdb rather than output to the startup fd */
55 OutputSink VG_(log_output_sink) = { 2, False }; /* 2 = stderr */
56 OutputSink VG_(xml_output_sink) = { -1, False }; /* disabled */
57
58 /* Do the low-level send of a message to the logging sink. */
59 static
send_bytes_to_logging_sink(OutputSink * sink,Char * msg,Int nbytes)60 void send_bytes_to_logging_sink ( OutputSink* sink, Char* msg, Int nbytes )
61 {
62 if (sink->is_socket) {
63 Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
64 if (rc == -1) {
65 // For example, the listener process died. Switch back to stderr.
66 sink->is_socket = False;
67 sink->fd = 2;
68 VG_(write)( sink->fd, msg, nbytes );
69 }
70 } else {
71 /* sink->fd could have been set to -1 in the various
72 sys-wrappers for sys_fork, if --child-silent-after-fork=yes
73 is in effect. That is a signal that we should not produce
74 any more output. */
75 if (sink->fd >= 0)
76 VG_(write)( sink->fd, msg, nbytes );
77 else if (sink->fd == -2)
78 VG_(gdb_printf)("%s", msg);
79 }
80 }
81
82
83 /* ---------------------------------------------------------------------
84 printf() and friends
85 ------------------------------------------------------------------ */
86
87 /* --------- printf --------- */
88
89 typedef
90 struct {
91 HChar buf[512];
92 Int buf_used;
93 OutputSink* sink;
94 }
95 printf_buf_t;
96
97 // Adds a single char to the buffer. When the buffer gets sufficiently
98 // full, we write its contents to the logging sink.
add_to__printf_buf(HChar c,void * p)99 static void add_to__printf_buf ( HChar c, void *p )
100 {
101 printf_buf_t *b = (printf_buf_t *)p;
102
103 if (b->buf_used > sizeof(b->buf) - 2 ) {
104 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
105 b->buf_used = 0;
106 }
107 b->buf[b->buf_used++] = c;
108 b->buf[b->buf_used] = 0;
109 tl_assert(b->buf_used < sizeof(b->buf));
110 }
111
vprintf_to_buf(printf_buf_t * b,const HChar * format,va_list vargs)112 static UInt vprintf_to_buf ( printf_buf_t* b,
113 const HChar *format, va_list vargs )
114 {
115 UInt ret = 0;
116 if (b->sink->fd >= 0 || b->sink->fd == -2) {
117 ret = VG_(debugLog_vprintf)
118 ( add_to__printf_buf, b, format, vargs );
119 }
120 return ret;
121 }
122
vprintf_WRK(OutputSink * sink,const HChar * format,va_list vargs)123 static UInt vprintf_WRK ( OutputSink* sink,
124 const HChar *format, va_list vargs )
125 {
126 printf_buf_t myprintf_buf
127 = { "", 0, sink };
128 UInt ret
129 = vprintf_to_buf(&myprintf_buf, format, vargs);
130 // Write out any chars left in the buffer.
131 if (myprintf_buf.buf_used > 0) {
132 send_bytes_to_logging_sink( myprintf_buf.sink,
133 myprintf_buf.buf,
134 myprintf_buf.buf_used );
135 }
136 return ret;
137 }
138
VG_(vprintf)139 UInt VG_(vprintf) ( const HChar *format, va_list vargs )
140 {
141 return vprintf_WRK( &VG_(log_output_sink), format, vargs );
142 }
143
VG_(printf)144 UInt VG_(printf) ( const HChar *format, ... )
145 {
146 UInt ret;
147 va_list vargs;
148 va_start(vargs, format);
149 ret = VG_(vprintf)(format, vargs);
150 va_end(vargs);
151 return ret;
152 }
153
VG_(vprintf_xml)154 UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs )
155 {
156 return vprintf_WRK( &VG_(xml_output_sink), format, vargs );
157 }
158
VG_(printf_xml)159 UInt VG_(printf_xml) ( const HChar *format, ... )
160 {
161 UInt ret;
162 va_list vargs;
163 va_start(vargs, format);
164 ret = VG_(vprintf_xml)(format, vargs);
165 va_end(vargs);
166 return ret;
167 }
168
169
170 /* --------- sprintf --------- */
171
172 /* If we had an explicit buf structure here, it would contain only one
173 field, indicating where the next char is to go. So use p directly
174 for that, rather than having it be a pointer to a structure. */
175
add_to__sprintf_buf(HChar c,void * p)176 static void add_to__sprintf_buf ( HChar c, void *p )
177 {
178 HChar** b = p;
179 *(*b)++ = c;
180 }
181
VG_(vsprintf)182 UInt VG_(vsprintf) ( Char* buf, const HChar *format, va_list vargs )
183 {
184 Int ret;
185 HChar* sprintf_ptr = buf;
186
187 ret = VG_(debugLog_vprintf)
188 ( add_to__sprintf_buf, &sprintf_ptr, format, vargs );
189 add_to__sprintf_buf('\0', &sprintf_ptr);
190
191 vg_assert(VG_(strlen)(buf) == ret);
192
193 return ret;
194 }
195
VG_(sprintf)196 UInt VG_(sprintf) ( Char* buf, const HChar *format, ... )
197 {
198 UInt ret;
199 va_list vargs;
200 va_start(vargs,format);
201 ret = VG_(vsprintf)(buf, format, vargs);
202 va_end(vargs);
203 return ret;
204 }
205
206
207 /* --------- snprintf --------- */
208
209 typedef
210 struct {
211 HChar* buf;
212 Int buf_size;
213 Int buf_used;
214 }
215 snprintf_buf_t;
216
add_to__snprintf_buf(HChar c,void * p)217 static void add_to__snprintf_buf ( HChar c, void* p )
218 {
219 snprintf_buf_t* b = p;
220 if (b->buf_size > 0 && b->buf_used < b->buf_size) {
221 b->buf[b->buf_used++] = c;
222 if (b->buf_used < b->buf_size)
223 b->buf[b->buf_used] = 0;
224 else
225 b->buf[b->buf_size-1] = 0; /* pre: b->buf_size > 0 */
226 }
227 }
228
VG_(vsnprintf)229 UInt VG_(vsnprintf) ( Char* buf, Int size, const HChar *format, va_list vargs )
230 {
231 snprintf_buf_t b;
232 b.buf = buf;
233 b.buf_size = size < 0 ? 0 : size;
234 b.buf_used = 0;
235
236 (void) VG_(debugLog_vprintf)
237 ( add_to__snprintf_buf, &b, format, vargs );
238
239 return b.buf_used;
240 }
241
VG_(snprintf)242 UInt VG_(snprintf) ( Char* buf, Int size, const HChar *format, ... )
243 {
244 UInt ret;
245 va_list vargs;
246 va_start(vargs,format);
247 ret = VG_(vsnprintf)(buf, size, format, vargs);
248 va_end(vargs);
249 return ret;
250 }
251
252
253 /* --------- vcbprintf --------- */
254
VG_(vcbprintf)255 void VG_(vcbprintf)( void(*char_sink)(HChar, void* opaque),
256 void* opaque,
257 const HChar* format, va_list vargs )
258 {
259 (void) VG_(debugLog_vprintf)
260 ( char_sink, opaque, format, vargs );
261 }
262
263
264 /* ---------------------------------------------------------------------
265 percentify()
266 ------------------------------------------------------------------ */
267
268 // Percentify n/m with d decimal places. Includes the '%' symbol at the end.
269 // Right justifies in 'buf'.
VG_(percentify)270 void VG_(percentify)(ULong n, ULong m, UInt d, Int n_buf, char buf[])
271 {
272 Int i, len, space;
273 ULong p1;
274 Char fmt[32];
275
276 if (m == 0) {
277 // Have to generate the format string in order to be flexible about
278 // the width of the field.
279 VG_(sprintf)(fmt, "%%-%ds", n_buf);
280 // fmt is now "%<n_buf>s" where <d> is 1,2,3...
281 VG_(sprintf)(buf, fmt, "--%");
282 return;
283 }
284
285 p1 = (100*n) / m;
286
287 if (d == 0) {
288 VG_(sprintf)(buf, "%lld%%", p1);
289 } else {
290 ULong p2;
291 UInt ex;
292 switch (d) {
293 case 1: ex = 10; break;
294 case 2: ex = 100; break;
295 case 3: ex = 1000; break;
296 default: VG_(tool_panic)("Currently can only handle 3 decimal places");
297 }
298 p2 = ((100*n*ex) / m) % ex;
299 // Have to generate the format string in order to be flexible about
300 // the width of the post-decimal-point part.
301 VG_(sprintf)(fmt, "%%lld.%%0%dlld%%%%", d);
302 // fmt is now "%lld.%0<d>lld%%" where <d> is 1,2,3...
303 VG_(sprintf)(buf, fmt, p1, p2);
304 }
305
306 len = VG_(strlen)(buf);
307 space = n_buf - len;
308 if (space < 0) space = 0; /* Allow for v. small field_width */
309 i = len;
310
311 /* Right justify in field */
312 for ( ; i >= 0; i--) buf[i + space] = buf[i];
313 for (i = 0; i < space; i++) buf[i] = ' ';
314 }
315
316
317 /* ---------------------------------------------------------------------
318 elapsed_wallclock_time()
319 ------------------------------------------------------------------ */
320
321 /* Get the elapsed wallclock time since startup into buf, which must
322 16 chars long. This is unchecked. It also relies on the
323 millisecond timer having been set to zero by an initial read in
324 m_main during startup. */
325
VG_(elapsed_wallclock_time)326 void VG_(elapsed_wallclock_time) ( /*OUT*/HChar* buf )
327 {
328 UInt t, ms, s, mins, hours, days;
329
330 t = VG_(read_millisecond_timer)(); /* milliseconds */
331
332 ms = t % 1000;
333 t /= 1000; /* now in seconds */
334
335 s = t % 60;
336 t /= 60; /* now in minutes */
337
338 mins = t % 60;
339 t /= 60; /* now in hours */
340
341 hours = t % 24;
342 t /= 24; /* now in days */
343
344 days = t;
345
346 VG_(sprintf)(buf, "%02u:%02u:%02u:%02u.%03u ", days, hours, mins, s, ms);
347 }
348
349
350 /* ---------------------------------------------------------------------
351 message()
352 ------------------------------------------------------------------ */
353
354 /* A buffer for accumulating VG_(message) style output. This is
355 pretty much the same as VG_(printf)'s scheme, with two differences:
356
357 * The message buffer persists between calls, so that multiple
358 calls to VG_(message) can build up output.
359
360 * Whenever the first character on a line is emitted, the
361 ==PID== style preamble is stuffed in before it.
362 */
363 typedef
364 struct {
365 HChar buf[512+128];
366 Int buf_used;
367 Bool atLeft; /* notionally, is the next char position at the
368 leftmost column? */
369 /* Current message kind - changes from call to call */
370 VgMsgKind kind;
371 /* destination */
372 OutputSink* sink;
373 }
374 vmessage_buf_t;
375
376 static vmessage_buf_t vmessage_buf
377 = { "", 0, True, Vg_UserMsg, &VG_(log_output_sink) };
378
379
380 // Adds a single char to the buffer. We aim to have at least 128
381 // bytes free in the buffer, so that it's always possible to emit
382 // the preamble into the buffer if c happens to be the character
383 // following a \n. When the buffer gets too full, we write its
384 // contents to the logging sink.
add_to__vmessage_buf(HChar c,void * p)385 static void add_to__vmessage_buf ( HChar c, void *p )
386 {
387 HChar tmp[64];
388 vmessage_buf_t* b = (vmessage_buf_t*)p;
389
390 vg_assert(b->buf_used >= 0 && b->buf_used < sizeof(b->buf)-128);
391
392 if (UNLIKELY(b->atLeft)) {
393 // insert preamble
394 HChar ch;
395 Int i, depth;
396
397 // Print one '>' in front of the messages for each level of
398 // self-hosting being performed.
399 depth = RUNNING_ON_VALGRIND;
400 if (depth > 10)
401 depth = 10; // ?!?!
402 for (i = 0; i < depth; i++) {
403 b->buf[b->buf_used++] = '>';
404 }
405
406 if (Vg_FailMsg == b->kind) {
407 // "valgrind: " prefix.
408 b->buf[b->buf_used++] = 'v';
409 b->buf[b->buf_used++] = 'a';
410 b->buf[b->buf_used++] = 'l';
411 b->buf[b->buf_used++] = 'g';
412 b->buf[b->buf_used++] = 'r';
413 b->buf[b->buf_used++] = 'i';
414 b->buf[b->buf_used++] = 'n';
415 b->buf[b->buf_used++] = 'd';
416 b->buf[b->buf_used++] = ':';
417 b->buf[b->buf_used++] = ' ';
418 } else {
419 switch (b->kind) {
420 case Vg_UserMsg: ch = '='; break;
421 case Vg_DebugMsg: ch = '-'; break;
422 case Vg_ClientMsg: ch = '*'; break;
423 default: ch = '?'; break;
424 }
425
426 b->buf[b->buf_used++] = ch;
427 b->buf[b->buf_used++] = ch;
428
429 if (VG_(clo_time_stamp)) {
430 VG_(memset)(tmp, 0, sizeof(tmp));
431 VG_(elapsed_wallclock_time)(tmp);
432 tmp[sizeof(tmp)-1] = 0;
433 for (i = 0; tmp[i]; i++)
434 b->buf[b->buf_used++] = tmp[i];
435 }
436
437 VG_(sprintf)(tmp, "%d", VG_(getpid)());
438 tmp[sizeof(tmp)-1] = 0;
439 for (i = 0; tmp[i]; i++)
440 b->buf[b->buf_used++] = tmp[i];
441
442 b->buf[b->buf_used++] = ch;
443 b->buf[b->buf_used++] = ch;
444 b->buf[b->buf_used++] = ' ';
445 }
446
447 /* We can't possibly have stuffed 96 chars in merely as a result
448 of making the preamble (can we?) */
449 vg_assert(b->buf_used < sizeof(b->buf)-32);
450 }
451
452 b->buf[b->buf_used++] = c;
453 b->buf[b->buf_used] = 0;
454
455 if (b->buf_used >= sizeof(b->buf) - 128) {
456 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
457 b->buf_used = 0;
458 }
459
460 b->atLeft = c == '\n';
461 }
462
463
VG_(vmessage)464 UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs )
465 {
466 UInt ret;
467
468 /* Note (carefully) that the buf persists from call to call, unlike
469 with the other printf variants in earlier parts of this file. */
470 vmessage_buf_t* b = &vmessage_buf; /* shorthand for convenience */
471
472 /* We have to set this each call, so that the correct flavour
473 of preamble is emitted at each \n. */
474 b->kind = kind;
475
476 ret = VG_(debugLog_vprintf) ( add_to__vmessage_buf,
477 b, format, vargs );
478
479 /* If the message finished exactly with a \n, then flush it at this
480 point. If not, assume more bits of the same line will turn up
481 in later messages, so don't bother to flush it right now. */
482
483 if (b->atLeft && b->buf_used > 0) {
484 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
485 b->buf_used = 0;
486 }
487
488 return ret;
489 }
490
491 /* Send a simple single-part message. */
VG_(message)492 UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... )
493 {
494 UInt count;
495 va_list vargs;
496 va_start(vargs,format);
497 count = VG_(vmessage) ( kind, format, vargs );
498 va_end(vargs);
499 return count;
500 }
501
revert_to_stderr(void)502 static void revert_to_stderr ( void )
503 {
504 VG_(log_output_sink).fd = 2; /* stderr */
505 VG_(log_output_sink).is_socket = False;
506 }
507
508 /* VG_(message) variants with hardwired first argument. */
509
VG_(fmsg)510 UInt VG_(fmsg) ( const HChar* format, ... )
511 {
512 UInt count;
513 va_list vargs;
514 va_start(vargs,format);
515 count = VG_(vmessage) ( Vg_FailMsg, format, vargs );
516 va_end(vargs);
517 return count;
518 }
519
VG_(fmsg_bad_option)520 void VG_(fmsg_bad_option) ( HChar* opt, const HChar* format, ... )
521 {
522 va_list vargs;
523 va_start(vargs,format);
524 revert_to_stderr();
525 VG_(message) (Vg_FailMsg, "Bad option: %s\n", opt);
526 VG_(vmessage)(Vg_FailMsg, format, vargs );
527 VG_(message) (Vg_FailMsg, "Use --help for more information or consult the user manual.\n");
528 VG_(exit)(1);
529 va_end(vargs);
530 }
531
VG_(umsg)532 UInt VG_(umsg) ( const HChar* format, ... )
533 {
534 UInt count;
535 va_list vargs;
536 va_start(vargs,format);
537 count = VG_(vmessage) ( Vg_UserMsg, format, vargs );
538 va_end(vargs);
539 return count;
540 }
541
VG_(dmsg)542 UInt VG_(dmsg) ( const HChar* format, ... )
543 {
544 UInt count;
545 va_list vargs;
546 va_start(vargs,format);
547 count = VG_(vmessage) ( Vg_DebugMsg, format, vargs );
548 va_end(vargs);
549 return count;
550 }
551
552 /* Flush any output that has accumulated in vmessage_buf as a
553 result of previous calls to VG_(message) et al. */
VG_(message_flush)554 void VG_(message_flush) ( void )
555 {
556 vmessage_buf_t* b = &vmessage_buf;
557 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
558 b->buf_used = 0;
559 }
560
561 __attribute__((noreturn))
VG_(err_missing_prog)562 void VG_(err_missing_prog) ( void )
563 {
564 revert_to_stderr();
565 VG_(fmsg)("no program specified\n");
566 VG_(fmsg)("Use --help for more information.\n");
567 VG_(exit)(1);
568 }
569
570 __attribute__((noreturn))
VG_(err_config_error)571 void VG_(err_config_error) ( Char* format, ... )
572 {
573 va_list vargs;
574 va_start(vargs,format);
575 revert_to_stderr();
576 VG_(message) (Vg_FailMsg, "Startup or configuration error:\n ");
577 VG_(vmessage)(Vg_FailMsg, format, vargs );
578 VG_(message) (Vg_FailMsg, "Unable to start up properly. Giving up.\n");
579 VG_(exit)(1);
580 va_end(vargs);
581 }
582
583
584 /*--------------------------------------------------------------------*/
585 /*--- end ---*/
586 /*--------------------------------------------------------------------*/
587
588