From f7c5c06c5dad0011cebfaab5f0131096c05b3e55 Mon Sep 17 00:00:00 2001 From: Florian Krohm Date: Fri, 12 Dec 2014 19:32:10 +0000 Subject: [PATCH] Add limited support for printing floating point numbers to VG_(debugLog_vprintf). Remove function VG_(percentify) and fix up its call sites (part of fixing BZ #337869. Allow the width in a format specification to be '*', i.e. the width is given as an additional function argument. The limitations for printing floating point numbers are: (1) %f is the only supported format. Width and precision can be specified. (2) Funny numbers (NaN and such) are not supported. (3) Floating point numbers need to be benign in the sense that their integral part fits into an ULong. This is good enough for our purposes. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14806 --- cachegrind/cg_main.c | 64 +++++------- callgrind/main.c | 10 +- coregrind/m_debuglog.c | 120 +++++++++++++++++++++- coregrind/m_libcprint.c | 52 ---------- coregrind/m_sbprofile.c | 49 ++++++--- coregrind/m_translate.c | 22 ++-- include/pub_tool_libcprint.h | 5 - lackey/lk_main.c | 10 +- lackey/tests/true.stderr.exp | 2 +- massif/ms_main.c | 17 +-- massif/tests/insig.post.exp | 2 +- massif/tests/thresholds_5_0.post.exp | 6 +- massif/tests/zero1.post.exp | 4 +- memcheck/mc_main.c | 8 +- none/tests/Makefile.am | 2 + none/tests/unit_debuglog.c | 148 +++++++++++++++++++++++++++ none/tests/unit_debuglog.stderr.exp | 107 +++++++++++++++++++ none/tests/unit_debuglog.vgtest | 2 + 18 files changed, 466 insertions(+), 164 deletions(-) create mode 100644 none/tests/unit_debuglog.c create mode 100644 none/tests/unit_debuglog.stderr.exp create mode 100644 none/tests/unit_debuglog.vgtest diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 20fafbc5f0..559eea910a 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -1563,7 +1563,6 @@ static UInt ULong_width(ULong n) static void cg_fini(Int exitcode) { - static HChar buf1[128], buf2[128], buf3[128], buf4[123]; // FIXME static HChar fmt[128]; // OK; large enough CacheCC D_total; @@ -1599,11 +1598,10 @@ static void cg_fini(Int exitcode) VG_(umsg)(fmt, "LLi misses: ", Ir_total.mL); if (0 == Ir_total.a) Ir_total.a = 1; - VG_(percentify)(Ir_total.m1, Ir_total.a, 2, l1+1, buf1); - VG_(umsg)("I1 miss rate: %s\n", buf1); - - VG_(percentify)(Ir_total.mL, Ir_total.a, 2, l1+1, buf1); - VG_(umsg)("LLi miss rate: %s\n", buf1); + VG_(umsg)("I1 miss rate: %*.2f%%\n", l1, + Ir_total.m1 * 100.0 / Ir_total.a); + VG_(umsg)("LLi miss rate: %*.2f%%\n", l1, + Ir_total.mL * 100.0 / Ir_total.a); VG_(umsg)("\n"); /* D cache results. Use the D_refs.rd and D_refs.wr values to @@ -1626,15 +1624,14 @@ static void cg_fini(Int exitcode) if (0 == D_total.a) D_total.a = 1; if (0 == Dr_total.a) Dr_total.a = 1; if (0 == Dw_total.a) Dw_total.a = 1; - VG_(percentify)( D_total.m1, D_total.a, 1, l1+1, buf1); - VG_(percentify)(Dr_total.m1, Dr_total.a, 1, l2+1, buf2); - VG_(percentify)(Dw_total.m1, Dw_total.a, 1, l3+1, buf3); - VG_(umsg)("D1 miss rate: %s (%s + %s )\n", buf1, buf2,buf3); - - VG_(percentify)( D_total.mL, D_total.a, 1, l1+1, buf1); - VG_(percentify)(Dr_total.mL, Dr_total.a, 1, l2+1, buf2); - VG_(percentify)(Dw_total.mL, Dw_total.a, 1, l3+1, buf3); - VG_(umsg)("LLd miss rate: %s (%s + %s )\n", buf1, buf2,buf3); + VG_(umsg)("D1 miss rate: %*.1f%% (%*.1f%% + %*.1f%% )\n", + l1, D_total.m1 * 100.0 / D_total.a, + l2, Dr_total.m1 * 100.0 / Dr_total.a, + l3, Dw_total.m1 * 100.0 / Dw_total.a); + VG_(umsg)("LLd miss rate: %*.1f%% (%*.1f%% + %*.1f%% )\n", + l1, D_total.mL * 100.0 / D_total.a, + l2, Dr_total.mL * 100.0 / Dr_total.a, + l3, Dw_total.mL * 100.0 / Dw_total.a); VG_(umsg)("\n"); /* LL overall results */ @@ -1651,10 +1648,10 @@ static void cg_fini(Int exitcode) VG_(umsg)(fmt, "LL misses: ", LL_total_m, LL_total_mr, LL_total_mw); - VG_(percentify)(LL_total_m, (Ir_total.a + D_total.a), 1, l1+1, buf1); - VG_(percentify)(LL_total_mr, (Ir_total.a + Dr_total.a), 1, l2+1, buf2); - VG_(percentify)(LL_total_mw, Dw_total.a, 1, l3+1, buf3); - VG_(umsg)("LL miss rate: %s (%s + %s )\n", buf1, buf2,buf3); + VG_(umsg)("LL miss rate: %*.1f%% (%*.1f%% + %*.1f%% )\n", + l1, LL_total_m * 100.0 / (Ir_total.a + D_total.a), + l2, LL_total_mr * 100.0 / (Ir_total.a + Dr_total.a), + l3, LL_total_mw * 100.0 / Dw_total.a); } /* If branch profiling is enabled, show branch overall results. */ @@ -1675,11 +1672,10 @@ static void cg_fini(Int exitcode) VG_(umsg)(fmt, "Mispredicts: ", B_total.mp, Bc_total.mp, Bi_total.mp); - VG_(percentify)(B_total.mp, B_total.b, 1, l1+1, buf1); - VG_(percentify)(Bc_total.mp, Bc_total.b, 1, l2+1, buf2); - VG_(percentify)(Bi_total.mp, Bi_total.b, 1, l3+1, buf3); - - VG_(umsg)("Mispred rate: %s (%s + %s )\n", buf1, buf2,buf3); + VG_(umsg)("Mispred rate: %*.1f%% (%*.1f%% + %*.1f%% )\n", + l1, B_total.mp * 100.0 / B_total.b, + l2, Bc_total.mp * 100.0 / Bc_total.b, + l3, Bi_total.mp * 100.0 / Bi_total.b); } // Various stats @@ -1695,18 +1691,14 @@ static void cg_fini(Int exitcode) VG_(dmsg)("cachegrind: distinct instrs Gen: %d\n", distinct_instrsGen); VG_(dmsg)("cachegrind: debug lookups : %d\n", debug_lookups); - VG_(percentify)(full_debugs, debug_lookups, 1, 6, buf1); - VG_(percentify)(file_line_debugs, debug_lookups, 1, 6, buf2); - VG_(percentify)(fn_debugs, debug_lookups, 1, 6, buf3); - VG_(percentify)(no_debugs, debug_lookups, 1, 6, buf4); - VG_(dmsg)("cachegrind: with full info:%s (%d)\n", - buf1, full_debugs); - VG_(dmsg)("cachegrind: with file/line info:%s (%d)\n", - buf2, file_line_debugs); - VG_(dmsg)("cachegrind: with fn name info:%s (%d)\n", - buf3, fn_debugs); - VG_(dmsg)("cachegrind: with zero info:%s (%d)\n", - buf4, no_debugs); + VG_(dmsg)("cachegrind: with full info:%6.1f%% (%d)\n", + full_debugs * 100.0 / debug_lookups, full_debugs); + VG_(dmsg)("cachegrind: with file/line info:%6.1f%% (%d)\n", + file_line_debugs * 100.0 / debug_lookups, file_line_debugs); + VG_(dmsg)("cachegrind: with fn name info:%6.1f%% (%d)\n", + fn_debugs * 100.0 / debug_lookups, fn_debugs); + VG_(dmsg)("cachegrind: with zero info:%6.1f%% (%d)\n", + no_debugs * 100.0 / debug_lookups, no_debugs); VG_(dmsg)("cachegrind: string table size: %lu\n", VG_(OSetGen_Size)(stringTable)); diff --git a/callgrind/main.c b/callgrind/main.c index 740213123b..0180ec6490 100644 --- a/callgrind/main.c +++ b/callgrind/main.c @@ -1775,7 +1775,6 @@ static UInt ULong_width(ULong n) static void branchsim_printstat(int l1, int l2, int l3) { - static HChar buf1[128], buf2[128], buf3[128]; static HChar fmt[128]; // large enough FullCost total; ULong Bc_total_b, Bc_total_mp, Bi_total_b, Bi_total_mp; @@ -1803,11 +1802,10 @@ void branchsim_printstat(int l1, int l2, int l3) VG_(umsg)(fmt, "Mispredicts: ", B_total_mp, Bc_total_mp, Bi_total_mp); - VG_(percentify)(B_total_mp, B_total_b, 1, l1+1, buf1); - VG_(percentify)(Bc_total_mp, Bc_total_b, 1, l2+1, buf2); - VG_(percentify)(Bi_total_mp, Bi_total_b, 1, l3+1, buf3); - - VG_(umsg)("Mispred rate: %s (%s + %s )\n", buf1, buf2,buf3); + VG_(umsg)("Mispred rate: %*.1f%% (%*.1f%% + %*.1f%% )\n", + l1, B_total_mp * 100.0 / B_total_b, + l2, Bc_total_mp * 100.0 / Bc_total_b, + l3, Bi_total_mp * 100.0 / Bi_total_b); } static diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c index 5ae2a5df1e..47a27500f4 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -1,3 +1,4 @@ +/* -*- mode: C; c-basic-offset: 3; -*- */ /*--------------------------------------------------------------------*/ /*--- Debug (not-for-user) logging; also vprintf. m_debuglog.c ---*/ @@ -730,7 +731,7 @@ VG_(debugLog_vprintf) ( UInt ret = 0; Int i; Int flags; - Int width; + Int width, precision; Int n_ls = 0; Bool is_long, caps; @@ -758,6 +759,7 @@ VG_(debugLog_vprintf) ( flags = 0; n_ls = 0; width = 0; /* length of the field. */ + precision = -1; /* unspecified precision */ while (1) { switch (format[i]) { case '(': @@ -787,9 +789,29 @@ VG_(debugLog_vprintf) ( } parse_fieldwidth: /* Compute the field length. */ - while (format[i] >= '0' && format[i] <= '9') { - width *= 10; - width += format[i++] - '0'; + if (format[i] == '*') { + width = va_arg(vargs, Int); + ++i; + } else { + while (format[i] >= '0' && format[i] <= '9') { + width *= 10; + width += format[i++] - '0'; + } + } + /* Parse precision, if any. Only meaningful for %f. For all other + format specifiers the precision will be silently ignored. */ + if (format[i] == '.') { + ++i; + if (format[i] == '*') { + precision = va_arg(vargs, Int); + ++i; + } else { + precision = 0; + while (format[i] >= '0' && format[i] <= '9') { + precision *= 10; + precision += format[i++] - '0'; + } + } } while (format[i] == 'l') { i++; @@ -888,6 +910,96 @@ VG_(debugLog_vprintf) ( flags, width, str, format[i]=='S'); break; } + case 'f': { + /* Print a floating point number in the format x.y without + any exponent. Capabilities are extremely limited, basically + a joke, but good enough for our needs. */ + Double val = va_arg (vargs, Double); + Bool is_negative = False; + Int cnt; + + if (val < 0.0) { + is_negative = True; + val = - val; + } + /* If the integral part of the floating point number cannot be + represented by an ULONG_MAX, print '*' characters */ + if (val > (Double)(~0ULL)) { + if (width == 0) width = 6; // say + for (cnt = 0; cnt < width; ++cnt) + send('*', send_arg2); + ret += width; + break; + } + /* The integral part of the floating point number is representable + by an ULong. */ + ULong ipval = val; + Double frac = val - ipval; + + if (precision == -1) precision = 6; // say + + /* Silently limit the precision to 10 digits. */ + if (precision > 10) precision = 10; + + /* If fracional part is not printed (precision == 0), may have to + round up */ + if (precision == 0 && frac >= 0.5) + ipval += 1; + + /* Find out how many characters are needed to print the number */ + + /* The integral part... */ + UInt ipwidth, num_digit = 1; // at least one digit + ULong x, old_x = 0; + for (x = 10; ; old_x = x, x *= 10, ++num_digit) { + if (x <= old_x) break; // overflow occurred + if (ipval < x) break; + } + ipwidth = num_digit; // width of integral part. + if (is_negative) ++num_digit; + if (precision != 0) + num_digit += 1 + precision; + + // Print the number + + // Fill in blanks on the left + if (num_digit < width && (flags & VG_MSG_LJUSTIFY) == 0) { + for (cnt = 0; cnt < width - num_digit; ++cnt) + send(' ', send_arg2); + ret += width - num_digit; + } + // Sign, maybe + if (is_negative) { + send('-', send_arg2); + ret += 1; + } + // Integral part + ret += myvprintf_int64(send, send_arg2, 0, 10, ipwidth, False, + ipval); + // Decimal point and fractional part + if (precision != 0) { + send('.', send_arg2); + ret += 1; + + // Fractional part + ULong factor = 1; + for (cnt = 0; cnt < precision; ++cnt) + factor *= 10; + ULong frval = frac * factor; + if ((frac * factor - frval) > 0.5) // round up + frval += 1; + frval %= factor; + ret += myvprintf_int64(send, send_arg2, VG_MSG_ZJUSTIFY, 10, + precision, False, frval); + } + // Fill in blanks on the right + if (num_digit < width && (flags & VG_MSG_LJUSTIFY) != 0) { + for (cnt = 0; cnt < width - num_digit; ++cnt) + send(' ', send_arg2); + ret += width - num_digit; + } + break; + } // case 'y': { /* %y - print symbol */ // Addr a = va_arg(vargs, Addr); diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c index 3617c039a8..fbd3d4c4b8 100644 --- a/coregrind/m_libcprint.c +++ b/coregrind/m_libcprint.c @@ -362,58 +362,6 @@ void VG_(fclose)( VgFile *fp ) VG_(free)(fp); } -/* --------------------------------------------------------------------- - percentify() - ------------------------------------------------------------------ */ - -// Percentify n/m with d decimal places. Includes the '%' symbol at the end. -// Right justifies in 'buf'. -void VG_(percentify)(ULong n, ULong m, UInt d, Int n_buf, HChar buf[]) -{ - Int i, len, space; - ULong p1; - HChar fmt[32]; // large enough - - if (m == 0) { - // Have to generate the format string in order to be flexible about - // the width of the field. - VG_(sprintf)(fmt, "%%%ds", n_buf); - // fmt is now "%s" where is 1,2,3... - VG_(sprintf)(buf, fmt, "--%"); - return; - } - - p1 = (100*n) / m; - - if (d == 0) { - VG_(sprintf)(buf, "%llu%%", p1); // FIXME: unsafe - } else { - ULong p2; - UInt ex; - switch (d) { - case 1: ex = 10; break; - case 2: ex = 100; break; - case 3: ex = 1000; break; - default: VG_(core_panic)("Currently can only handle 3 decimal places"); - } - p2 = ((100*n*ex) / m) % ex; - // Have to generate the format string in order to be flexible about - // the width of the post-decimal-point part. - VG_(sprintf)(fmt, "%%llu.%%0%ullu%%%%", d); - // fmt is now "%llu.%0llu%%" where is 1,2,3... - VG_(sprintf)(buf, fmt, p1, p2); // FIXME: unsafe - } - - len = VG_(strlen)(buf); - space = n_buf - len; - if (space < 0) space = 0; /* Allow for v. small field_width */ - i = len; - - /* Right justify in field */ - for ( ; i >= 0; i--) buf[i + space] = buf[i]; - for (i = 0; i < space; i++) buf[i] = ' '; -} - /* --------------------------------------------------------------------- elapsed_wallclock_time() diff --git a/coregrind/m_sbprofile.c b/coregrind/m_sbprofile.c index 0be07dd9cf..7ed995090d 100644 --- a/coregrind/m_sbprofile.c +++ b/coregrind/m_sbprofile.c @@ -50,7 +50,6 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, ULong score_total, ULong ecs_done ) { ULong score_cumul, score_cumul_saved, score_here; - HChar buf_cumul[10], buf_here[10]; Int r; /* must be signed */ HChar ecs_txt[50]; @@ -89,12 +88,18 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, score_here = tops[r].score; score_cumul += score_here; - VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); - VG_(percentify)(score_here, score_total, 2, 6, buf_here); - VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n", + + /* Careful: do not divide by zero. score_total == 0 implies + score_cumul == 0 and also score_here == 0. */ + Double percent_cumul = + score_total == 0 ? 100.0 : score_cumul * 100.0 / score_total; + Double percent_here = + score_total == 0 ? 100.0 : score_here * 100.0 / score_total; + + VG_(printf)("%3d: (%9lld %5.2f%%) %9lld %5.2f%% 0x%llx %s\n", r, - score_cumul, buf_cumul, - score_here, buf_here, tops[r].addr, name ); + score_cumul, percent_cumul, + score_here, percent_here, tops[r].addr, name); } score_cumul_saved = score_cumul; @@ -122,15 +127,21 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, score_here = tops[r].score; score_cumul += score_here; - VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); - VG_(percentify)(score_here, score_total, 2, 6, buf_here); + + /* Careful: do not divide by zero. score_total == 0 implies + score_cumul == 0 and also score_here == 0. */ + Double percent_cumul = + score_total == 0 ? 100.0 : score_cumul * 100.0 / score_total; + Double percent_here = + score_total == 0 ? 100.0 : score_here * 100.0 / score_total; + VG_(printf)("\n"); VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin SB rank %d " "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r); - VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n", + VG_(printf)("%3d: (%9lld %5.2f%%) %9lld %5.2f%% 0x%llx %s\n", r, - score_cumul, buf_cumul, - score_here, buf_here, tops[r].addr, name ); + score_cumul, percent_cumul, + score_here, percent_here, tops[r].addr, name ); VG_(printf)("\n"); VG_(discard_translations)(tops[r].addr, 1, "bb profile"); VG_(translate)(0, tops[r].addr, True, VG_(clo_profyle_flags), 0, True); @@ -151,12 +162,18 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, VG_(get_fnname_w_offset)(tops[r].addr, &name); score_here = tops[r].score; - VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); - VG_(percentify)(score_here, score_total, 2, 6, buf_here); - VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n", + + /* Careful: do not divide by zero. score_total == 0 implies + score_cumul == 0 and also score_here == 0. */ + Double percent_cumul = + score_total == 0 ? 100.0 : score_cumul * 100.0 / score_total; + Double percent_here = + score_total == 0 ? 100.0 : score_here * 100.0 / score_total; + + VG_(printf)("%3d: (%9lld %5.2f%%) %9lld %5.2f%% 0x%llx %s\n", r, - score_cumul, buf_cumul, - score_here, buf_here, tops[r].addr, name ); + score_cumul, percent_cumul, + score_here, percent_here, tops[r].addr, name ); score_cumul -= score_here; } VG_(printf)("rank ---cumulative--- -----self-----\n"); diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index b5d10fbb22..816b5f2652 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -73,23 +73,25 @@ static UInt n_SP_updates_generic_unknown = 0; void VG_(print_translation_stats) ( void ) { - HChar buf[7]; UInt n_SP_updates = n_SP_updates_fast + n_SP_updates_generic_known + n_SP_updates_generic_unknown; - VG_(percentify)(n_SP_updates_fast, n_SP_updates, 1, 6, buf); + if (n_SP_updates == 0) { + VG_(message)(Vg_DebugMsg, "translate: no SP updates identified\n"); + return; + } VG_(message)(Vg_DebugMsg, - "translate: fast SP updates identified: %'u (%s)\n", - n_SP_updates_fast, buf ); + "translate: fast SP updates identified: %'u (%3.1f%%)\n", + n_SP_updates_fast, n_SP_updates_fast * 100.0 / n_SP_updates ); - VG_(percentify)(n_SP_updates_generic_known, n_SP_updates, 1, 6, buf); VG_(message)(Vg_DebugMsg, - "translate: generic_known SP updates identified: %'u (%s)\n", - n_SP_updates_generic_known, buf ); + "translate: generic_known SP updates identified: %'u (%3.1f%%)\n", + n_SP_updates_generic_known, + n_SP_updates_generic_known * 100.0 / n_SP_updates ); - VG_(percentify)(n_SP_updates_generic_unknown, n_SP_updates, 1, 6, buf); VG_(message)(Vg_DebugMsg, - "translate: generic_unknown SP updates identified: %'u (%s)\n", - n_SP_updates_generic_unknown, buf ); + "translate: generic_unknown SP updates identified: %'u (%3.1f%%)\n", + n_SP_updates_generic_unknown, + n_SP_updates_generic_unknown * 100.0 / n_SP_updates ); } /*------------------------------------------------------------*/ diff --git a/include/pub_tool_libcprint.h b/include/pub_tool_libcprint.h index f71469a573..adfedb60f5 100644 --- a/include/pub_tool_libcprint.h +++ b/include/pub_tool_libcprint.h @@ -63,11 +63,6 @@ extern UInt VG_(vsnprintf)( HChar* buf, Int size, const HChar *format, va_list vargs ) PRINTF_CHECK(3, 0); -// Percentify n/m with d decimal places. Includes the '%' symbol at the end. -// Right justifies in 'buf'. -extern void VG_(percentify)(ULong n, ULong m, UInt d, Int n_buf, HChar buf[]); - - /* --------------------------------------------------------------------- Output-printing functions ------------------------------------------------------------------ */ diff --git a/lackey/lk_main.c b/lackey/lk_main.c index 485707c4ff..b2ca1ff0e5 100644 --- a/lackey/lk_main.c +++ b/lackey/lk_main.c @@ -997,10 +997,6 @@ IRSB* lk_instrument ( VgCallbackClosure* closure, static void lk_fini(Int exitcode) { - HChar percentify_buf[5]; /* Two digits, '%' and 0. */ - const int percentify_size = sizeof(percentify_buf) - 1; - const int percentify_decs = 0; - tl_assert(clo_fnname); tl_assert(clo_fnname[0]); @@ -1014,10 +1010,8 @@ static void lk_fini(Int exitcode) VG_(umsg)("\n"); VG_(umsg)("Jccs:\n"); VG_(umsg)(" total: %'llu\n", total_Jccs); - VG_(percentify)(taken_Jccs, (total_Jccs ? total_Jccs : 1), - percentify_decs, percentify_size, percentify_buf); - VG_(umsg)(" taken: %'llu (%s)\n", - taken_Jccs, percentify_buf); + VG_(umsg)(" taken: %'llu (%.0f%%)\n", + taken_Jccs, taken_Jccs * 100.0 / total_Jccs ?: 1); VG_(umsg)("\n"); VG_(umsg)("Executed:\n"); diff --git a/lackey/tests/true.stderr.exp b/lackey/tests/true.stderr.exp index 9a14875872..0f1c3647cb 100644 --- a/lackey/tests/true.stderr.exp +++ b/lackey/tests/true.stderr.exp @@ -4,7 +4,7 @@ Counted ... calls to main() Jccs: total: ... - taken: ... ( ...%) + taken: ... (...%) Executed: SBs entered: ... diff --git a/massif/ms_main.c b/massif/ms_main.c index 450379dd15..01daaf0416 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -2105,18 +2105,6 @@ IRSB* ms_instrument ( VgCallbackClosure* closure, #define FP(format, args...) ({ VG_(fprintf)(fp, format, ##args); }) -// Nb: uses a static buffer, each call trashes the last string returned. -static const HChar* make_perc(double x) -{ - static HChar mbuf[32]; - - VG_(percentify)((ULong)(x * 100), 10000, 2, 6, mbuf); - // XXX: this is bogus if the denominator was zero -- resulting string is - // something like "0 --%") - if (' ' == mbuf[0]) mbuf[0] = '0'; - return mbuf; -} - static void pp_snapshot_SXPt(VgFile *fp, SXPt* sxpt, Int depth, HChar* depth_str, Int depth_str_len, SizeT snapshot_heap_szB, SizeT snapshot_total_szB) @@ -2225,9 +2213,8 @@ static void pp_snapshot_SXPt(VgFile *fp, SXPt* sxpt, Int depth, case InsigSXPt: { const HChar* s = ( 1 == sxpt->Insig.n_xpts ? "," : "s, all" ); - FP("%sn0: %lu in %d place%s below massif's threshold (%s)\n", - depth_str, sxpt->szB, sxpt->Insig.n_xpts, s, - make_perc(clo_threshold)); + FP("%sn0: %lu in %d place%s below massif's threshold (%.2f%%)\n", + depth_str, sxpt->szB, sxpt->Insig.n_xpts, s, clo_threshold); break; } diff --git a/massif/tests/insig.post.exp b/massif/tests/insig.post.exp index 5963decfeb..5a4abd5f1b 100644 --- a/massif/tests/insig.post.exp +++ b/massif/tests/insig.post.exp @@ -70,7 +70,7 @@ Number of snapshots: 24 87.28% (16,688B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. ->83.68% (16,000B) 0x........: main (insig.c:8) | -->01.34% (256B) in 16 places, all below massif's threshold (00.99%) +->01.34% (256B) in 16 places, all below massif's threshold (0.99%) | ->01.26% (240B) 0x........: main (insig.c:9) | diff --git a/massif/tests/thresholds_5_0.post.exp b/massif/tests/thresholds_5_0.post.exp index b54bd88ef7..96ee9df8dd 100644 --- a/massif/tests/thresholds_5_0.post.exp +++ b/massif/tests/thresholds_5_0.post.exp @@ -52,7 +52,7 @@ Number of snapshots: 10 | | | ->05.00% (4,000B) 0x........: main (thresholds.c:54) | | -| ->01.50% (1,200B) in 2 places, all below massif's threshold (05.00%) +| ->01.50% (1,200B) in 2 places, all below massif's threshold (5.00%) | ->20.00% (16,000B) 0x........: main (thresholds.c:55) | @@ -60,7 +60,7 @@ Number of snapshots: 10 | ->09.00% (7,200B) 0x........: a7550 (thresholds.c:39) | | ->09.00% (7,200B) 0x........: main (thresholds.c:52) | | -| ->04.00% (3,200B) in 2 places, all below massif's threshold (05.00%) +| ->04.00% (3,200B) in 2 places, all below massif's threshold (5.00%) | -->00.50% (400B) in 1 place, below massif's threshold (05.00%) +->00.50% (400B) in 1 place, below massif's threshold (5.00%) diff --git a/massif/tests/zero1.post.exp b/massif/tests/zero1.post.exp index db640cb679..cddd70ef02 100644 --- a/massif/tests/zero1.post.exp +++ b/massif/tests/zero1.post.exp @@ -46,7 +46,7 @@ Number of snapshots: 21 8 0 0 0 0 0 9 0 0 0 0 0 00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. -->00.00% (0B) in 5 places, all below massif's threshold (01.00%) +->00.00% (0B) in 5 places, all below massif's threshold (1.00%) -------------------------------------------------------------------------------- n time(B) total(B) useful-heap(B) extra-heap(B) stacks(B) @@ -62,7 +62,7 @@ Number of snapshots: 21 18 0 0 0 0 0 19 0 0 0 0 0 00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. -->00.00% (0B) in 10 places, all below massif's threshold (01.00%) +->00.00% (0B) in 10 places, all below massif's threshold (1.00%) -------------------------------------------------------------------------------- n time(B) total(B) useful-heap(B) extra-heap(B) stacks(B) diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 86a9574dbf..5cd2414151 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -965,11 +965,9 @@ static void gcSecVBitTable(void) VG_(OSetGen_Destroy)(secVBitTable); secVBitTable = secVBitTable2; - if (VG_(clo_verbosity) > 1) { - HChar percbuf[7]; - VG_(percentify)(n_survivors, n_nodes, 1, 6, percbuf); - VG_(message)(Vg_DebugMsg, "memcheck GC: %d nodes, %d survivors (%s)\n", - n_nodes, n_survivors, percbuf); + if (VG_(clo_verbosity) > 1 && n_nodes != 0) { + VG_(message)(Vg_DebugMsg, "memcheck GC: %d nodes, %d survivors (%.1f%%)\n", + n_nodes, n_survivors, n_survivors * 100.0 / n_nodes); } // Increase table size if necessary. diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index daa8c8ba4f..b9a1767f73 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -175,6 +175,7 @@ EXTRA_DIST = \ threadederrno.vgtest \ timestamp.stderr.exp timestamp.vgtest \ tls.vgtest tls.stderr.exp tls.stdout.exp \ + unit_debuglog.stderr.exp unit_debuglog.vgtest \ vgprintf.stderr.exp vgprintf.vgtest \ process_vm_readv_writev.stderr.exp process_vm_readv_writev.vgtest @@ -211,6 +212,7 @@ check_PROGRAMS = \ tls \ tls.so \ tls2.so \ + unit_debuglog \ valgrind_cpp_test \ vgprintf \ coolo_sigaction \ diff --git a/none/tests/unit_debuglog.c b/none/tests/unit_debuglog.c new file mode 100644 index 0000000000..1fecb3031f --- /dev/null +++ b/none/tests/unit_debuglog.c @@ -0,0 +1,148 @@ +/* Test %f format specifier */ +#include +#include +#include +#include + +#include "pub_core_basics.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcprint.h" + +#undef vg_assert +#define vg_assert(e) assert(e) +#undef vg_assert2 +#define vg_assert2(e, fmt, args...) assert(e) + +#include "coregrind/m_debuglog.c" + +void run(const char *format, ...) +{ + int n, num_stars, i1, i2; + const char *p; + printf_buf buf; + va_list vargs; + + // Count number of '*' in format + num_stars = 0; + for (p = format; *p; ++p) + if (*p == '*') ++num_stars; + + va_start(vargs, format); + fprintf(stderr, "%s\tprintf = ", format); + switch (num_stars) { + case 0: + n = fprintf(stderr, format, va_arg(vargs, Double)); + break; + case 1: + i1 = va_arg(vargs, int); + n = fprintf(stderr, format, i1, va_arg(vargs, Double)); + break; + case 2: + i1 = va_arg(vargs, int); + i2 = va_arg(vargs, int); + n = fprintf(stderr, format, i1, i2, va_arg(vargs, Double)); + break; + } + fprintf(stderr, "\twrote %3d chars\n", n); + va_end(vargs); + + buf.n = 0; + buf.buf[0] = 0; + + fprintf(stderr, "%s\tdebuglog = ", format); + va_start(vargs, format); + n = VG_(debugLog_vprintf)(add_to_buf, &buf, format, vargs); + va_end(vargs); + + emit(buf.buf, strlen(buf.buf)); + fprintf(stderr, "\twrote %3d chars\n", n); +} + + +int main(int argc, char *argv[]) +{ + double value; + + fprintf(stderr, "...testing value 0\n"); + value = 0.0; + run("|%f|", value); + run("|%2f|", value); + run("|%9f|", value); + run("|%8.0f|", value); + run("|%8.1f|", value); + run("|%8.2f|", value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing value 3.7 (with rounding)\n"); + value = 3.7; + run("|%f|", value); + run("|%4f|", value); + run("|%9f|", value); + run("|%4.0f|", value); + run("|%4.1f|", value); + run("|%4.2f|", value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing value 123.01\n"); + value = 123.01; + run("|%f|", value); + run("|%4f|", value); + run("|%9f|", value); + run("|%8.0f|", value); + run("|%8.1f|", value); + run("|%8.2f|", value); + run("|%8.3f|", value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing value 3.0019 (with rounding)\n"); + value = 3.0019; + run("|%f|", value); + run("|%10f|", value); + run("|%10.0f|", value); + run("|%10.3f|", value); + run("|%10.4f|", value); + run("|%.4f|", value); + run("|%.9f|", value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing value -123.456 (with rounding)\n"); + value = -123.456; + run("|%f|", value); + run("|%10f|", value); + run("|%10.0f|", value); + run("|%10.1f|", value); + run("|%10.2f|", value); + run("|%10.3f|", value); + run("|%10.4f|", value); + run("|%10.5f|", value); + run("|%.4f|", value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing value = -123.456 width = '*'\n"); + value = -123.456; + run("|%*f|", 10, value); + run("|%*f|", 2, value); + run("|%*f.1|", 10, value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing precision = '*'\n"); + value = -123.456; + run("|%.*f|", 10, value); + run("|%.*f|", 2, value); + run("|%10.*f|", 2, value); + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing width/precision = '*'\n"); + value = -123.456; + run("|%*.*f|", 20, 5, value); + run("|%*.*f|", 1, 4, value); + + + fprintf(stderr, "\n"); + fprintf(stderr, "...testing left justification\n"); + value = 3.1415; + run("|%10f|", value); + run("|%-10f|", value); + return 0; +} diff --git a/none/tests/unit_debuglog.stderr.exp b/none/tests/unit_debuglog.stderr.exp new file mode 100644 index 0000000000..7e8e87ac84 --- /dev/null +++ b/none/tests/unit_debuglog.stderr.exp @@ -0,0 +1,107 @@ +...testing value 0 +|%f| printf = |0.000000| wrote 10 chars +|%f| debuglog = |0.000000| wrote 10 chars +|%2f| printf = |0.000000| wrote 10 chars +|%2f| debuglog = |0.000000| wrote 10 chars +|%9f| printf = | 0.000000| wrote 11 chars +|%9f| debuglog = | 0.000000| wrote 11 chars +|%8.0f| printf = | 0| wrote 10 chars +|%8.0f| debuglog = | 0| wrote 10 chars +|%8.1f| printf = | 0.0| wrote 10 chars +|%8.1f| debuglog = | 0.0| wrote 10 chars +|%8.2f| printf = | 0.00| wrote 10 chars +|%8.2f| debuglog = | 0.00| wrote 10 chars + +...testing value 3.7 (with rounding) +|%f| printf = |3.700000| wrote 10 chars +|%f| debuglog = |3.700000| wrote 10 chars +|%4f| printf = |3.700000| wrote 10 chars +|%4f| debuglog = |3.700000| wrote 10 chars +|%9f| printf = | 3.700000| wrote 11 chars +|%9f| debuglog = | 3.700000| wrote 11 chars +|%4.0f| printf = | 4| wrote 6 chars +|%4.0f| debuglog = | 4| wrote 6 chars +|%4.1f| printf = | 3.7| wrote 6 chars +|%4.1f| debuglog = | 3.7| wrote 6 chars +|%4.2f| printf = |3.70| wrote 6 chars +|%4.2f| debuglog = |3.70| wrote 6 chars + +...testing value 123.01 +|%f| printf = |123.010000| wrote 12 chars +|%f| debuglog = |123.010000| wrote 12 chars +|%4f| printf = |123.010000| wrote 12 chars +|%4f| debuglog = |123.010000| wrote 12 chars +|%9f| printf = |123.010000| wrote 12 chars +|%9f| debuglog = |123.010000| wrote 12 chars +|%8.0f| printf = | 123| wrote 10 chars +|%8.0f| debuglog = | 123| wrote 10 chars +|%8.1f| printf = | 123.0| wrote 10 chars +|%8.1f| debuglog = | 123.0| wrote 10 chars +|%8.2f| printf = | 123.01| wrote 10 chars +|%8.2f| debuglog = | 123.01| wrote 10 chars +|%8.3f| printf = | 123.010| wrote 10 chars +|%8.3f| debuglog = | 123.010| wrote 10 chars + +...testing value 3.0019 (with rounding) +|%f| printf = |3.001900| wrote 10 chars +|%f| debuglog = |3.001900| wrote 10 chars +|%10f| printf = | 3.001900| wrote 12 chars +|%10f| debuglog = | 3.001900| wrote 12 chars +|%10.0f| printf = | 3| wrote 12 chars +|%10.0f| debuglog = | 3| wrote 12 chars +|%10.3f| printf = | 3.002| wrote 12 chars +|%10.3f| debuglog = | 3.002| wrote 12 chars +|%10.4f| printf = | 3.0019| wrote 12 chars +|%10.4f| debuglog = | 3.0019| wrote 12 chars +|%.4f| printf = |3.0019| wrote 8 chars +|%.4f| debuglog = |3.0019| wrote 8 chars +|%.9f| printf = |3.001900000| wrote 13 chars +|%.9f| debuglog = |3.001900000| wrote 13 chars + +...testing value -123.456 (with rounding) +|%f| printf = |-123.456000| wrote 13 chars +|%f| debuglog = |-123.456000| wrote 13 chars +|%10f| printf = |-123.456000| wrote 13 chars +|%10f| debuglog = |-123.456000| wrote 13 chars +|%10.0f| printf = | -123| wrote 12 chars +|%10.0f| debuglog = | -123| wrote 12 chars +|%10.1f| printf = | -123.5| wrote 12 chars +|%10.1f| debuglog = | -123.5| wrote 12 chars +|%10.2f| printf = | -123.46| wrote 12 chars +|%10.2f| debuglog = | -123.46| wrote 12 chars +|%10.3f| printf = | -123.456| wrote 12 chars +|%10.3f| debuglog = | -123.456| wrote 12 chars +|%10.4f| printf = | -123.4560| wrote 12 chars +|%10.4f| debuglog = | -123.4560| wrote 12 chars +|%10.5f| printf = |-123.45600| wrote 12 chars +|%10.5f| debuglog = |-123.45600| wrote 12 chars +|%.4f| printf = |-123.4560| wrote 11 chars +|%.4f| debuglog = |-123.4560| wrote 11 chars + +...testing value = -123.456 width = '*' +|%*f| printf = |-123.456000| wrote 13 chars +|%*f| debuglog = |-123.456000| wrote 13 chars +|%*f| printf = |-123.456000| wrote 13 chars +|%*f| debuglog = |-123.456000| wrote 13 chars +|%*f.1| printf = |-123.456000.1| wrote 15 chars +|%*f.1| debuglog = |-123.456000.1| wrote 15 chars + +...testing precision = '*' +|%.*f| printf = |-123.4560000000| wrote 17 chars +|%.*f| debuglog = |-123.4560000000| wrote 17 chars +|%.*f| printf = |-123.46| wrote 9 chars +|%.*f| debuglog = |-123.46| wrote 9 chars +|%10.*f| printf = | -123.46| wrote 12 chars +|%10.*f| debuglog = | -123.46| wrote 12 chars + +...testing width/precision = '*' +|%*.*f| printf = | -123.45600| wrote 22 chars +|%*.*f| debuglog = | -123.45600| wrote 22 chars +|%*.*f| printf = |-123.4560| wrote 11 chars +|%*.*f| debuglog = |-123.4560| wrote 11 chars + +...testing left justification +|%10f| printf = | 3.141500| wrote 12 chars +|%10f| debuglog = | 3.141500| wrote 12 chars +|%-10f| printf = |3.141500 | wrote 12 chars +|%-10f| debuglog = |3.141500 | wrote 12 chars diff --git a/none/tests/unit_debuglog.vgtest b/none/tests/unit_debuglog.vgtest new file mode 100644 index 0000000000..1caaaf531d --- /dev/null +++ b/none/tests/unit_debuglog.vgtest @@ -0,0 +1,2 @@ +prog: unit_debuglog +vgopts: -q -- 2.47.3