static void call_summary_pers(FILE *outf) { int i, j; int call_cum, error_cum; struct timeval tv_cum, dtv; double percent; char *dashes = "-------------------------"; char error_str[16]; int *sorted_count = calloc(sizeof(int), nsyscalls); if (!sorted_count) { fprintf(stderr, "strace: out of memory for call summary\n"); return; } call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0; if (overhead.tv_sec == -1) { tv_mul(&overhead, &shortest, 8); tv_div(&overhead, &overhead, 10); } for (i = 0; i < nsyscalls; i++) { sorted_count[i] = i; if (counts == NULL || counts[i].calls == 0) continue; tv_mul(&dtv, &overhead, counts[i].calls); tv_sub(&counts[i].time, &counts[i].time, &dtv); call_cum += counts[i].calls; error_cum += counts[i].errors; tv_add(&tv_cum, &tv_cum, &counts[i].time); } if (counts && sortfun) qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun); fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n", "% time", "seconds", "usecs/call", "calls", "errors", "syscall"); fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n", dashes, dashes, dashes, dashes, dashes, dashes); if (counts) { for (i = 0; i < nsyscalls; i++) { j = sorted_count[i]; if (counts[j].calls == 0) continue; tv_div(&dtv, &counts[j].time, counts[j].calls); if (counts[j].errors) sprintf(error_str, "%d", counts[j].errors); else error_str[0] = '\0'; percent = (100.0 * tv_float(&counts[j].time) / tv_float(&tv_cum)); fprintf(outf, "%6.2f %11.6f %11ld %9d %9.9s %s\n", percent, tv_float(&counts[j].time), (long) 1000000 * dtv.tv_sec + dtv.tv_usec, counts[j].calls, error_str, sysent[j].sys_name); } } free(sorted_count); fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n", dashes, dashes, dashes, dashes, dashes, dashes); if (error_cum) sprintf(error_str, "%d", error_cum); else error_str[0] = '\0'; fprintf(outf, "%6.6s %11.6f %11.11s %9d %9.9s %s\n", "100.00", tv_float(&tv_cum), "", call_cum, error_str, "total"); }
static void call_summary_pers(FILE *outf) { unsigned int i; int call_cum, error_cum; struct timeval tv_cum, dtv; double float_tv_cum; double percent; const char *dashes = "----------------"; char error_str[sizeof(int)*3]; int *sorted_count; fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n", "% time", "seconds", "usecs/call", "calls", "errors", "syscall"); fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n", dashes, dashes, dashes, dashes, dashes, dashes); sorted_count = xcalloc(sizeof(int), nsyscalls); call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0; if (overhead.tv_sec == -1) { tv_mul(&overhead, &shortest, 8); tv_div(&overhead, &overhead, 10); } for (i = 0; i < nsyscalls; i++) { sorted_count[i] = i; if (counts == NULL || counts[i].calls == 0) continue; tv_mul(&dtv, &overhead, counts[i].calls); tv_sub(&counts[i].time, &counts[i].time, &dtv); call_cum += counts[i].calls; error_cum += counts[i].errors; tv_add(&tv_cum, &tv_cum, &counts[i].time); } float_tv_cum = tv_float(&tv_cum); if (counts) { if (sortfun) qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun); for (i = 0; i < nsyscalls; i++) { double float_syscall_time; int idx = sorted_count[i]; struct call_counts *cc = &counts[idx]; if (cc->calls == 0) continue; tv_div(&dtv, &cc->time, cc->calls); error_str[0] = '\0'; if (cc->errors) sprintf(error_str, "%u", cc->errors); float_syscall_time = tv_float(&cc->time); percent = (100.0 * float_syscall_time); if (percent != 0.0) percent /= float_tv_cum; /* else: float_tv_cum can be 0.0 too and we get 0/0 = NAN */ fprintf(outf, "%6.2f %11.6f %11lu %9u %9.9s %s\n", percent, float_syscall_time, (long) (1000000 * dtv.tv_sec + dtv.tv_usec), cc->calls, error_str, sysent[idx].sys_name); } } free(sorted_count); fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n", dashes, dashes, dashes, dashes, dashes, dashes); error_str[0] = '\0'; if (error_cum) sprintf(error_str, "%u", error_cum); fprintf(outf, "%6.6s %11.6f %11.11s %9u %9.9s %s\n", "100.00", float_tv_cum, "", call_cum, error_str, "total"); }