Home | History | Annotate | Download | only in coregrind
      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 (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       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 
    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. */
    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 
    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 
    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 
    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 
    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 
    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. */
    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))
    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))
    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