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-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