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-2012 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" 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 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. 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 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 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 139 UInt VG_(vprintf) ( const HChar *format, va_list vargs ) 140 { 141 return vprintf_WRK( &VG_(log_output_sink), format, vargs ); 142 } 143 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 154 UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs ) 155 { 156 return vprintf_WRK( &VG_(xml_output_sink), format, vargs ); 157 } 158 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 176 static void add_to__sprintf_buf ( HChar c, void *p ) 177 { 178 HChar** b = p; 179 *(*b)++ = c; 180 } 181 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 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 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 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 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 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'. 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 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. 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 // Do not print such '>' if sim hint "no-inner-prefix" given 400 // (useful to run regression tests in an outer/inner setup 401 // and avoid the diff failing due to these unexpected '>'). 402 depth = RUNNING_ON_VALGRIND; 403 if (depth > 0 && !VG_(strstr)(VG_(clo_sim_hints), "no-inner-prefix")) { 404 if (depth > 10) 405 depth = 10; // ?!?! 406 for (i = 0; i < depth; i++) { 407 b->buf[b->buf_used++] = '>'; 408 } 409 } 410 411 if (Vg_FailMsg == b->kind) { 412 // "valgrind: " prefix. 413 b->buf[b->buf_used++] = 'v'; 414 b->buf[b->buf_used++] = 'a'; 415 b->buf[b->buf_used++] = 'l'; 416 b->buf[b->buf_used++] = 'g'; 417 b->buf[b->buf_used++] = 'r'; 418 b->buf[b->buf_used++] = 'i'; 419 b->buf[b->buf_used++] = 'n'; 420 b->buf[b->buf_used++] = 'd'; 421 b->buf[b->buf_used++] = ':'; 422 b->buf[b->buf_used++] = ' '; 423 } else { 424 switch (b->kind) { 425 case Vg_UserMsg: ch = '='; break; 426 case Vg_DebugMsg: ch = '-'; break; 427 case Vg_ClientMsg: ch = '*'; break; 428 default: ch = '?'; break; 429 } 430 431 b->buf[b->buf_used++] = ch; 432 b->buf[b->buf_used++] = ch; 433 434 if (VG_(clo_time_stamp)) { 435 VG_(memset)(tmp, 0, sizeof(tmp)); 436 VG_(elapsed_wallclock_time)(tmp); 437 tmp[sizeof(tmp)-1] = 0; 438 for (i = 0; tmp[i]; i++) 439 b->buf[b->buf_used++] = tmp[i]; 440 } 441 442 VG_(sprintf)(tmp, "%d", VG_(getpid)()); 443 tmp[sizeof(tmp)-1] = 0; 444 for (i = 0; tmp[i]; i++) 445 b->buf[b->buf_used++] = tmp[i]; 446 447 b->buf[b->buf_used++] = ch; 448 b->buf[b->buf_used++] = ch; 449 b->buf[b->buf_used++] = ' '; 450 } 451 452 /* We can't possibly have stuffed 96 chars in merely as a result 453 of making the preamble (can we?) */ 454 vg_assert(b->buf_used < sizeof(b->buf)-32); 455 } 456 457 b->buf[b->buf_used++] = c; 458 b->buf[b->buf_used] = 0; 459 460 if (b->buf_used >= sizeof(b->buf) - 128) { 461 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used ); 462 b->buf_used = 0; 463 } 464 465 b->atLeft = c == '\n'; 466 } 467 468 469 UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs ) 470 { 471 UInt ret; 472 473 /* Note (carefully) that the buf persists from call to call, unlike 474 with the other printf variants in earlier parts of this file. */ 475 vmessage_buf_t* b = &vmessage_buf; /* shorthand for convenience */ 476 477 /* We have to set this each call, so that the correct flavour 478 of preamble is emitted at each \n. */ 479 b->kind = kind; 480 481 ret = VG_(debugLog_vprintf) ( add_to__vmessage_buf, 482 b, format, vargs ); 483 484 /* If the message finished exactly with a \n, then flush it at this 485 point. If not, assume more bits of the same line will turn up 486 in later messages, so don't bother to flush it right now. */ 487 488 if (b->atLeft && b->buf_used > 0) { 489 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used ); 490 b->buf_used = 0; 491 } 492 493 return ret; 494 } 495 496 /* Send a simple single-part message. */ 497 UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... ) 498 { 499 UInt count; 500 va_list vargs; 501 va_start(vargs,format); 502 count = VG_(vmessage) ( kind, format, vargs ); 503 va_end(vargs); 504 return count; 505 } 506 507 static void revert_to_stderr ( void ) 508 { 509 VG_(log_output_sink).fd = 2; /* stderr */ 510 VG_(log_output_sink).is_socket = False; 511 } 512 513 /* VG_(message) variants with hardwired first argument. */ 514 515 UInt VG_(fmsg) ( const HChar* format, ... ) 516 { 517 UInt count; 518 va_list vargs; 519 va_start(vargs,format); 520 count = VG_(vmessage) ( Vg_FailMsg, format, vargs ); 521 va_end(vargs); 522 return count; 523 } 524 525 void VG_(fmsg_bad_option) ( HChar* opt, const HChar* format, ... ) 526 { 527 va_list vargs; 528 va_start(vargs,format); 529 revert_to_stderr(); 530 VG_(message) (Vg_FailMsg, "Bad option: %s\n", opt); 531 VG_(vmessage)(Vg_FailMsg, format, vargs ); 532 VG_(message) (Vg_FailMsg, "Use --help for more information or consult the user manual.\n"); 533 VG_(exit)(1); 534 va_end(vargs); 535 } 536 537 UInt VG_(umsg) ( const HChar* format, ... ) 538 { 539 UInt count; 540 va_list vargs; 541 va_start(vargs,format); 542 count = VG_(vmessage) ( Vg_UserMsg, format, vargs ); 543 va_end(vargs); 544 return count; 545 } 546 547 UInt VG_(dmsg) ( const HChar* format, ... ) 548 { 549 UInt count; 550 va_list vargs; 551 va_start(vargs,format); 552 count = VG_(vmessage) ( Vg_DebugMsg, format, vargs ); 553 va_end(vargs); 554 return count; 555 } 556 557 /* Flush any output that has accumulated in vmessage_buf as a 558 result of previous calls to VG_(message) et al. */ 559 void VG_(message_flush) ( void ) 560 { 561 vmessage_buf_t* b = &vmessage_buf; 562 send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used ); 563 b->buf_used = 0; 564 } 565 566 __attribute__((noreturn)) 567 void VG_(err_missing_prog) ( void ) 568 { 569 revert_to_stderr(); 570 VG_(fmsg)("no program specified\n"); 571 VG_(fmsg)("Use --help for more information.\n"); 572 VG_(exit)(1); 573 } 574 575 __attribute__((noreturn)) 576 void VG_(err_config_error) ( Char* format, ... ) 577 { 578 va_list vargs; 579 va_start(vargs,format); 580 revert_to_stderr(); 581 VG_(message) (Vg_FailMsg, "Startup or configuration error:\n "); 582 VG_(vmessage)(Vg_FailMsg, format, vargs ); 583 VG_(message) (Vg_FailMsg, "Unable to start up properly. Giving up.\n"); 584 VG_(exit)(1); 585 va_end(vargs); 586 } 587 588 589 /*--------------------------------------------------------------------*/ 590 /*--- end ---*/ 591 /*--------------------------------------------------------------------*/ 592 593