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