|
From: <sv...@va...> - 2014-08-13 12:51:45
|
Author: florian
Date: Wed Aug 13 12:51:36 2014
New Revision: 14268
Log:
Implement a suggestion found in ms_main.c, namely to add the equivalent
of fprintf to m_libcprint.c The new functions are called
VG_(fdprintf) and VG_(vfdprintf) as they take in a file descriptor as
first argument.
Change massif and cachegrind to use those functions.
In massif, also eliminate the truncation of ip_desc. If does not appear
that ms_print has a buffer size limitation anywhere.
Modified:
branches/BUF_REMOVAL/cachegrind/cg_main.c
branches/BUF_REMOVAL/coregrind/m_libcprint.c
branches/BUF_REMOVAL/include/pub_tool_libcprint.h
branches/BUF_REMOVAL/massif/ms_main.c
Modified: branches/BUF_REMOVAL/cachegrind/cg_main.c
==============================================================================
--- branches/BUF_REMOVAL/cachegrind/cg_main.c (original)
+++ branches/BUF_REMOVAL/cachegrind/cg_main.c Wed Aug 13 12:51:36 2014
@@ -1384,8 +1384,6 @@
{
Int i, fd;
SysRes sres;
- // FIXME: use an xarray and VG_(xaprintf) instead
- HChar buf[512];
HChar *currFile = NULL, *currFn = NULL;
LineCC* lineCC;
@@ -1414,46 +1412,39 @@
// "desc:" lines (giving I1/D1/LL cache configuration). The spaces after
// the 2nd colon makes cg_annotate's output look nicer.
- VG_(sprintf)(buf, "desc: I1 cache: %s\n"
+ VG_(fdprintf)(fd, "desc: I1 cache: %s\n"
"desc: D1 cache: %s\n"
"desc: LL cache: %s\n",
I1.desc_line, D1.desc_line, LL.desc_line);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
// "cmd:" line
- VG_(strcpy)(buf, "cmd:");
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ VG_(fdprintf)(fd, "cmd:");
if (VG_(args_the_exename)) {
- VG_(write)(fd, " ", 1);
- VG_(write)(fd, VG_(args_the_exename),
- VG_(strlen)( VG_(args_the_exename) ));
+ VG_(fdprintf)(fd, " %s", VG_(args_the_exename));
}
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
if (arg) {
- VG_(write)(fd, " ", 1);
- VG_(write)(fd, arg, VG_(strlen)( arg ));
+ VG_(fdprintf)(fd, " %s", arg);
}
}
// "events:" line
if (clo_cache_sim && clo_branch_sim) {
- VG_(sprintf)(buf, "\nevents: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw "
+ VG_(fdprintf)(fd, "\nevents: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw "
"Bc Bcm Bi Bim\n");
}
else if (clo_cache_sim && !clo_branch_sim) {
- VG_(sprintf)(buf, "\nevents: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw "
+ VG_(fdprintf)(fd, "\nevents: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw "
"\n");
}
else if (!clo_cache_sim && clo_branch_sim) {
- VG_(sprintf)(buf, "\nevents: Ir "
+ VG_(fdprintf)(fd, "\nevents: Ir "
"Bc Bcm Bi Bim\n");
}
else {
- VG_(sprintf)(buf, "\nevents: Ir\n");
+ VG_(fdprintf)(fd, "\nevents: Ir\n");
}
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
// Traverse every lineCC
VG_(OSetGen_ResetIter)(CC_table);
while ( (lineCC = VG_(OSetGen_Next)(CC_table)) ) {
@@ -1465,8 +1456,7 @@
// the whole strings would have to be checked.
if ( lineCC->loc.file != currFile ) {
currFile = lineCC->loc.file;
- VG_(sprintf)(buf, "fl=%s\n", currFile);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ VG_(fdprintf)(fd, "fl=%s\n", currFile);
distinct_files++;
just_hit_a_new_file = True;
}
@@ -1476,14 +1466,13 @@
// in the old file, hence the just_hit_a_new_file test).
if ( just_hit_a_new_file || lineCC->loc.fn != currFn ) {
currFn = lineCC->loc.fn;
- VG_(sprintf)(buf, "fn=%s\n", currFn);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ VG_(fdprintf)(fd, "fn=%s\n", currFn);
distinct_fns++;
}
// Print the LineCC
if (clo_cache_sim && clo_branch_sim) {
- VG_(sprintf)(buf, "%u %llu %llu %llu"
+ VG_(fdprintf)(fd, "%u %llu %llu %llu"
" %llu %llu %llu"
" %llu %llu %llu"
" %llu %llu %llu %llu\n",
@@ -1495,7 +1484,7 @@
lineCC->Bi.b, lineCC->Bi.mp);
}
else if (clo_cache_sim && !clo_branch_sim) {
- VG_(sprintf)(buf, "%u %llu %llu %llu"
+ VG_(fdprintf)(fd, "%u %llu %llu %llu"
" %llu %llu %llu"
" %llu %llu %llu\n",
lineCC->loc.line,
@@ -1504,7 +1493,7 @@
lineCC->Dw.a, lineCC->Dw.m1, lineCC->Dw.mL);
}
else if (!clo_cache_sim && clo_branch_sim) {
- VG_(sprintf)(buf, "%u %llu"
+ VG_(fdprintf)(fd, "%u %llu"
" %llu %llu %llu %llu\n",
lineCC->loc.line,
lineCC->Ir.a,
@@ -1512,13 +1501,11 @@
lineCC->Bi.b, lineCC->Bi.mp);
}
else {
- VG_(sprintf)(buf, "%u %llu\n",
+ VG_(fdprintf)(fd, "%u %llu\n",
lineCC->loc.line,
lineCC->Ir.a);
}
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
// Update summary stats
Ir_total.a += lineCC->Ir.a;
Ir_total.m1 += lineCC->Ir.m1;
@@ -1540,7 +1527,7 @@
// Summary stats must come after rest of table, since we calculate them
// during traversal. */
if (clo_cache_sim && clo_branch_sim) {
- VG_(sprintf)(buf, "summary:"
+ VG_(fdprintf)(fd, "summary:"
" %llu %llu %llu"
" %llu %llu %llu"
" %llu %llu %llu"
@@ -1552,7 +1539,7 @@
Bi_total.b, Bi_total.mp);
}
else if (clo_cache_sim && !clo_branch_sim) {
- VG_(sprintf)(buf, "summary:"
+ VG_(fdprintf)(fd, "summary:"
" %llu %llu %llu"
" %llu %llu %llu"
" %llu %llu %llu\n",
@@ -1561,7 +1548,7 @@
Dw_total.a, Dw_total.m1, Dw_total.mL);
}
else if (!clo_cache_sim && clo_branch_sim) {
- VG_(sprintf)(buf, "summary:"
+ VG_(fdprintf)(fd, "summary:"
" %llu"
" %llu %llu %llu %llu\n",
Ir_total.a,
@@ -1569,12 +1556,11 @@
Bi_total.b, Bi_total.mp);
}
else {
- VG_(sprintf)(buf, "summary:"
+ VG_(fdprintf)(fd, "summary:"
" %llu\n",
Ir_total.a);
}
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
VG_(close)(fd);
}
@@ -1592,7 +1578,7 @@
static void cg_fini(Int exitcode)
{
static HChar buf1[128], buf2[128], buf3[128], buf4[123];
- static HChar fmt[128];
+ static HChar fmt[128]; // large enough
CacheCC D_total;
BranchCC B_total;
Modified: branches/BUF_REMOVAL/coregrind/m_libcprint.c
==============================================================================
--- branches/BUF_REMOVAL/coregrind/m_libcprint.c (original)
+++ branches/BUF_REMOVAL/coregrind/m_libcprint.c Wed Aug 13 12:51:36 2014
@@ -294,6 +294,61 @@
}
+/* --------- fdprintf ---------- */
+
+/* This is like [v]fprintf, except it writes to a file handle using
+ VG_(write). */
+
+#define FDPRINTF_BUFSIZE 1024
+
+typedef struct {
+ HChar buf[FDPRINTF_BUFSIZE];
+ UInt num_chars; // number of characters in buf
+ Int fd; // file descriptor to write to
+} fdprintf_buf;
+
+
+static void add_to__fdprintf_buf ( HChar c, void *p )
+{
+ fdprintf_buf *b = p;
+
+ b->buf[b->num_chars++] = c;
+
+ if (b->num_chars == FDPRINTF_BUFSIZE) {
+ VG_(write)(b->fd, b->buf, b->num_chars);
+ b->num_chars = 0;
+ }
+}
+
+
+UInt VG_(vfdprintf) ( Int fd, const HChar *format, va_list vargs )
+{
+ Int ret;
+ fdprintf_buf b;
+
+ b.fd = fd;
+ b.num_chars = 0;
+
+ ret = VG_(debugLog_vprintf)
+ ( add_to__fdprintf_buf, &b, format, vargs );
+
+ // Flush the buffer.
+ if (b.num_chars)
+ VG_(write)(b.fd, b.buf, b.num_chars);
+
+ return ret;
+}
+
+UInt VG_(fdprintf) ( Int fd, const HChar *format, ... )
+{
+ UInt ret;
+ va_list vargs;
+ va_start(vargs,format);
+ ret = VG_(vfdprintf)(fd, format, vargs);
+ va_end(vargs);
+ return ret;
+}
+
/* ---------------------------------------------------------------------
percentify()
------------------------------------------------------------------ */
Modified: branches/BUF_REMOVAL/include/pub_tool_libcprint.h
==============================================================================
--- branches/BUF_REMOVAL/include/pub_tool_libcprint.h (original)
+++ branches/BUF_REMOVAL/include/pub_tool_libcprint.h Wed Aug 13 12:51:36 2014
@@ -106,6 +106,11 @@
extern UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs )
PRINTF_CHECK(1, 0);
+extern UInt VG_(fdprintf) ( Int fd, const HChar *format, ... )
+ PRINTF_CHECK(2, 3);
+extern UInt VG_(vfdprintf) ( Int fd, const HChar *format, va_list vargs )
+ PRINTF_CHECK(2, 0);
+
/* Do a printf-style operation on either the XML
or normal output channel
or gdb output channel, depending on the setting of VG_(clo_xml)
Modified: branches/BUF_REMOVAL/massif/ms_main.c
==============================================================================
--- branches/BUF_REMOVAL/massif/ms_main.c (original)
+++ branches/BUF_REMOVAL/massif/ms_main.c Wed Aug 13 12:51:36 2014
@@ -2111,14 +2111,8 @@
//--- Writing snapshots ---//
//------------------------------------------------------------//
-HChar FP_buf[BUF_LEN];
-
-// XXX: implement f{,n}printf in m_libcprint.c eventually, and use it here.
-// Then change Cachegrind to use it too.
#define FP(format, args...) ({ \
- VG_(snprintf)(FP_buf, BUF_LEN, format, ##args); \
- FP_buf[BUF_LEN-1] = '\0'; /* Make sure the string is terminated. */ \
- VG_(write)(fd, (void*)FP_buf, VG_(strlen)(FP_buf)); \
+ VG_(fdprintf)(fd, format, ##args); \
})
// Nb: uses a static buffer, each call trashes the last string returned.
@@ -2195,25 +2189,14 @@
}
}
}
- // Nb: We treat this specially (ie. we don't use FP) so that if the
- // ip_desc is too long (eg. due to a long C++ function name), it'll
- // get truncated, but the '\n' is still there so its a valid file.
- // (At one point we were truncating without adding the '\n', which
- // caused bug #155929.)
- //
- // Also, we account for the length of the address in ip_desc when
- // truncating. (The longest address we could have is 18 chars: "0x"
- // plus 16 address digits.) This ensures that the truncated function
- // name always has the same length, which makes truncation
- // deterministic and thus makes testing easier.
- tl_assert(j <= 18);
- VG_(snprintf)(FP_buf, BUF_LEN, "%s\n", ip_desc);
- FP_buf[BUF_LEN-18+j-5] = '.'; // "..." at the end make the
- FP_buf[BUF_LEN-18+j-4] = '.'; // truncation more obvious.
- FP_buf[BUF_LEN-18+j-3] = '.';
- FP_buf[BUF_LEN-18+j-2] = '\n'; // The last char is '\n'.
- FP_buf[BUF_LEN-18+j-1] = '\0'; // The string is terminated.
- VG_(write)(fd, (void*)FP_buf, VG_(strlen)(FP_buf));
+
+ // It used to be that ip_desc was truncated at the end.
+ // But there does not seem to be a good reason for that. Besides,
+ // the string was truncated at the right, which is less than ideal.
+ // Truncation at the beginning of the string would be preferable.
+ // Think several nested namespaces in C++....
+ // Anyhow, we spit out the full-length string now.
+ FP("%s\n", ip_desc);
// Indent.
tl_assert(depth+1 < depth_str_len-1); // -1 for end NUL char
|