static
void fprint_cost(int fd, EventMapping* es, ULong* cost)
{
- int p = CLG_(sprint_mappingcost)(outbuf, es, cost);
- VG_(sprintf)(outbuf+p, "\n");
+ HChar *mcost = CLG_(mappingcost_as_string)(es, cost);
+ VG_(sprintf)(outbuf, "%s\n", mcost);
my_fwrite(fd, outbuf, VG_(strlen)(outbuf));
+ CLG_FREE(mcost);
return;
}
static void fprint_cost_ln(int fd, const HChar* prefix,
EventMapping* em, ULong* cost)
{
- int p;
-
- p = VG_(sprintf)(outbuf, "%s", prefix);
- p += CLG_(sprint_mappingcost)(outbuf + p, em, cost);
- VG_(sprintf)(outbuf + p, "\n");
+ HChar *mcost = CLG_(mappingcost_as_string)(em, cost);
+ VG_(sprintf)(outbuf, "%s%s\n", prefix, mcost);
my_fwrite(fd, outbuf, VG_(strlen)(outbuf));
+ CLG_FREE(mcost);
}
static ULong bbs_done = 0;
my_fwrite(fd, buf, VG_(strlen)(buf));
/* "events:" line */
- i = VG_(sprintf)(buf, "events: ");
- CLG_(sprint_eventmapping)(buf+i, CLG_(dumpmap));
+ HChar *evmap = CLG_(eventmapping_as_string)(CLG_(dumpmap));
+ VG_(sprintf)(buf, "events: %s\n", evmap);
+ VG_(free)(evmap);
my_fwrite(fd, buf, VG_(strlen)(buf));
- my_fwrite(fd, "\n", 1);
/* summary lines */
sum = CLG_(get_eventset_cost)( CLG_(sets).full );
}
-/* Returns number of characters written */
-Int CLG_(sprint_eventmapping)(HChar* buf, EventMapping* em)
+/* Returns pointer to dynamically string. The string will be overwritten
+ with each invocation. */
+HChar *CLG_(eventmapping_as_string)(const EventMapping* em)
{
- Int i, pos = 0;
+ Int i;
EventGroup* eg;
CLG_ASSERT(em != 0);
+ XArray *xa = VG_(newXA)(VG_(malloc), "cl.events.emas", VG_(free),
+ sizeof(HChar));
+
for(i=0; i< em->size; i++) {
- if (pos>0) buf[pos++] = ' ';
+ if (i > 0) {
+ VG_(xaprintf)(xa, "%c", ' ');
+ }
eg = eventGroup[em->entry[i].group];
CLG_ASSERT(eg != 0);
- pos += VG_(sprintf)(buf + pos, "%s", eg->name[em->entry[i].index]);
+ VG_(xaprintf)(xa, "%s", eg->name[em->entry[i].index]);
}
- buf[pos] = 0;
+ VG_(xaprintf)(xa, "%c", '\0'); // zero terminate the string
+
+ HChar *buf = VG_(strdup)("cl.events.emas", VG_(indexXA)(xa, 0));
+ VG_(deleteXA)(xa);
- return pos;
+ return buf;
}
-/* Returns number of characters written */
-Int CLG_(sprint_mappingcost)(HChar* buf, EventMapping* em, ULong* c)
+/* Returns pointer to dynamically allocated string. Caller needs to
+ VG_(free) it. */
+HChar *CLG_(mappingcost_as_string)(const EventMapping* em, const ULong* c)
{
- Int i, pos, skipped = 0;
+ Int i, skipped = 0;
- if (!c || em->size==0) return 0;
+ if (!c || em->size==0) return VG_(strdup)("cl.events.mcas", "");
+
+ XArray *xa = VG_(newXA)(VG_(malloc), "cl.events.mcas", VG_(free),
+ sizeof(HChar));
/* At least one entry */
- pos = VG_(sprintf)(buf, "%llu", c[em->entry[0].offset]);
+ VG_(xaprintf)(xa, "%llu", c[em->entry[0].offset]);
for(i=1; i<em->size; i++) {
if (c[em->entry[i].offset] == 0) {
continue;
}
while(skipped>0) {
- buf[pos++] = ' ';
- buf[pos++] = '0';
+ VG_(xaprintf)(xa, " 0");
skipped--;
}
- buf[pos++] = ' ';
- pos += VG_(sprintf)(buf+pos, "%llu", c[em->entry[i].offset]);
+ VG_(xaprintf)(xa, " %llu", c[em->entry[i].offset]);
}
+ VG_(xaprintf)(xa, "%c", '\0'); // zero terminate the string
+
+ HChar *buf = VG_(strdup)("cl.events.mas", VG_(indexXA)(xa, 0));
+ VG_(deleteXA)(xa);
- return pos;
+ return buf;
}
/* Allocate space for an event mapping */
EventMapping* CLG_(get_eventmapping)(EventSet*);
void CLG_(append_event)(EventMapping*, const HChar*);
-/* Returns number of characters written */
-Int CLG_(sprint_eventmapping)(HChar* buf, EventMapping*);
-/* Returns number of characters written */
-Int CLG_(sprint_mappingcost)(HChar* buf, EventMapping*, ULong*);
+/* Returns event mapping as a character string. That string is dynamically
+ allocated and it is the caller's responsibility to free it.
+ The function never returns NULL. */
+HChar *CLG_(eventmapping_as_string)(const EventMapping*);
+/* Returns mapping cost as a character string. That string is dynamically
+ allocated and it is the caller's responsibility to free it.
+ The function never returns NULL. */
+HChar *CLG_(mappingcost_as_string)(const EventMapping*, const ULong*);
#endif /* CLG_EVENTS */
/* helper for dump_state_togdb */
static void dump_state_of_thread_togdb(thread_info* ti)
{
- static HChar buf[512];
static FullCost sum = 0, tmp = 0;
- Int t, p, i;
+ Int t, i;
BBCC *from, *to;
call_entry* ce;
+ HChar *mcost;
t = CLG_(current_tid);
CLG_(init_cost_lz)( CLG_(sets).full, &sum );
CLG_(add_diff_cost)( CLG_(sets).full, sum, ti->lastdump_cost,
ti->states.entry[0]->cost);
CLG_(copy_cost)( CLG_(sets).full, ti->lastdump_cost, tmp );
- CLG_(sprint_mappingcost)(buf, CLG_(dumpmap), sum);
- VG_(gdb_printf)("events-%d: %s\n", t, buf);
+ mcost = CLG_(mappingcost_as_string)(CLG_(dumpmap), sum);
+ VG_(gdb_printf)("events-%d: %s\n", t, mcost);
+ VG_(free)(mcost);
VG_(gdb_printf)("frames-%d: %d\n", t, CLG_(current_call_stack).sp);
ce = 0;
ce->enter_cost, CLG_(current_state).cost );
CLG_(copy_cost)( CLG_(sets).full, ce->enter_cost, tmp );
- p = VG_(sprintf)(buf, "events-%d-%d: ",t, i);
- CLG_(sprint_mappingcost)(buf + p, CLG_(dumpmap), sum );
- VG_(gdb_printf)("%s\n", buf);
+ mcost = CLG_(mappingcost_as_string)(CLG_(dumpmap), sum);
+ VG_(gdb_printf)("events-%d-%d: %s\n",t, i, mcost);
+ VG_(free)(mcost);
}
if (ce && ce->jcc) {
to = ce->jcc->to;
VG_(gdb_printf)("distinct-contexts: %d\n", CLG_(stat).distinct_contexts);
/* "events:" line. Given here because it will be dynamic in the future */
- p = VG_(sprintf)(buf, "events: ");
- CLG_(sprint_eventmapping)(buf+p, CLG_(dumpmap));
- VG_(gdb_printf)("%s\n", buf);
+ HChar *evmap = CLG_(eventmapping_as_string)(CLG_(dumpmap));
+ VG_(gdb_printf)("events: %s\n", evmap);
+ VG_(free)(evmap);
/* "part:" line (number of last part. Is 0 at start */
VG_(gdb_printf)("part: %d\n", CLG_(get_dump_counter)());
static
void finish(void)
{
- HChar buf[32+COSTS_LEN];
- HChar fmt[128];
+ HChar fmt[128]; // large enough
Int l1, l2, l3;
FullCost total;
VG_(message)(Vg_DebugMsg, "\n");
}
- CLG_(sprint_eventmapping)(buf, CLG_(dumpmap));
- VG_(message)(Vg_UserMsg, "Events : %s\n", buf);
- CLG_(sprint_mappingcost)(buf, CLG_(dumpmap), CLG_(total_cost));
- VG_(message)(Vg_UserMsg, "Collected : %s\n", buf);
+ HChar *evmap = CLG_(eventmapping_as_string)(CLG_(dumpmap));
+ VG_(message)(Vg_UserMsg, "Events : %s\n", evmap);
+ VG_(free)(evmap);
+ HChar *mcost = CLG_(mappingcost_as_string)(CLG_(dumpmap), CLG_(total_cost));
+ VG_(message)(Vg_UserMsg, "Collected : %s\n", mcost);
+ VG_(free)(mcost);
VG_(message)(Vg_UserMsg, "\n");
/* determine value widths for statistics */