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