sprofalyze fixes

. accumulate sprof_info
	. reset 'seen' endpoints for every file to keep in sync with kernel
	  profile stream
This commit is contained in:
Ben Gras 2013-01-14 20:43:11 +00:00
parent e9a6abd046
commit c096911b97

View file

@ -71,6 +71,8 @@ struct endpoint_info {
endpoint_t endpoint; endpoint_t endpoint;
struct binary_info *binary; struct binary_info *binary;
struct endpoint_info *hashtab_next; struct endpoint_info *hashtab_next;
struct endpoint_info *next;
char seen;
}; };
union sprof_record { union sprof_record {
@ -82,6 +84,7 @@ union sprof_record {
static struct binary_info *binaries; static struct binary_info *binaries;
static struct binary_info *binary_hashtab[BINARY_HASHTAB_SIZE]; static struct binary_info *binary_hashtab[BINARY_HASHTAB_SIZE];
static struct endpoint_info *endpoint_hashtab[ENDPOINT_HASHTAB_SIZE]; static struct endpoint_info *endpoint_hashtab[ENDPOINT_HASHTAB_SIZE];
static struct endpoint_info *endpoints;
static double minimum_perc = 1.0; static double minimum_perc = 1.0;
static struct sprof_info_s sprof_info; static struct sprof_info_s sprof_info;
@ -176,7 +179,10 @@ int main(int argc, char **argv) {
/* load samples */ /* load samples */
if (optind >= argc) usage(argv[0]); if (optind >= argc) usage(argv[0]);
for (; optind < argc; optind++) { for (; optind < argc; optind++) {
struct endpoint_info *e;
load_trace(argv[optind]); load_trace(argv[optind]);
for(e = endpoints; e; e = e->next)
e->seen = 0;
} }
/* print report */ /* print report */
@ -477,6 +483,7 @@ static void load_trace(const char *path) {
FILE *file; FILE *file;
unsigned size_info, size_sample, size_proc; unsigned size_info, size_sample, size_proc;
int samples_read; int samples_read;
static struct sprof_info_s sprof_info_perfile;
/* open trace file */ /* open trace file */
file = fopen(path, "rb"); file = fopen(path, "rb");
@ -501,7 +508,7 @@ static void load_trace(const char *path) {
"MINIX version that created this file\n", path); "MINIX version that created this file\n", path);
exit(1); exit(1);
} }
if (fread(&sprof_info, sizeof(sprof_info), 1, file) != 1) { if (fread(&sprof_info_perfile, sizeof(sprof_info_perfile), 1, file) != 1) {
fprintf(stderr, "error: totals missing in file \"%s\"\n", path); fprintf(stderr, "error: totals missing in file \"%s\"\n", path);
exit(1); exit(1);
} }
@ -531,11 +538,17 @@ static void load_trace(const char *path) {
(const union sprof_record *) (buffer + bufindex), (const union sprof_record *) (buffer + bufindex),
bufsize - bufindex, &samples_read); bufsize - bufindex, &samples_read);
} }
if (samples_read != sprof_info.system_samples) { if (samples_read != sprof_info_perfile.system_samples) {
fprintf(stderr, "warning: number of system samples (%d) in " fprintf(stderr, "warning: number of system samples (%d) in "
"\"%s\" does not match number of records (%d)\n", "\"%s\" does not match number of records (%d)\n",
sprof_info.system_samples, path, samples_read); sprof_info.system_samples, path, samples_read);
} }
sprof_info.system_samples += sprof_info_perfile.system_samples;
sprof_info.total_samples += sprof_info_perfile.total_samples;
sprof_info.idle_samples += sprof_info_perfile.idle_samples;
sprof_info.user_samples += sprof_info_perfile.user_samples;
fclose(file); fclose(file);
} }
@ -658,6 +671,8 @@ static void print_report_per_binary(const struct binary_info *binary) {
unsigned index, symbol_count; unsigned index, symbol_count;
int sample_threshold; int sample_threshold;
assert(binary->samples >= 0);
/* count number of symbols to display */ /* count number of symbols to display */
sample_threshold = binary->samples * minimum_perc / 100; sample_threshold = binary->samples * minimum_perc / 100;
symbol_count = count_symbols(binary, sample_threshold); symbol_count = count_symbols(binary, sample_threshold);
@ -719,6 +734,7 @@ static void print_reports_per_binary(void) {
samples_shown += binaries_sorted[i]->samples; samples_shown += binaries_sorted[i]->samples;
} }
print_separator(); print_separator();
printf("samples: %d shown: %d\n", sprof_info.system_samples, samples_shown);
printf("processes <%3.0f%% (not showing functions) %*.1f%% of system " printf("processes <%3.0f%% (not showing functions) %*.1f%% of system "
"process samples\n", minimum_perc, LINE_WIDTH - 67, "process samples\n", minimum_perc, LINE_WIDTH - 67,
percent(sprof_info.system_samples - samples_shown, sprof_info.system_samples)); percent(sprof_info.system_samples - samples_shown, sprof_info.system_samples));
@ -899,6 +915,11 @@ static size_t sample_process(const union sprof_record *data, size_t size,
/* do we know this endpoint? */ /* do we know this endpoint? */
ptr = endpoint_hashtab_get_ptr(data->proc.proc); ptr = endpoint_hashtab_get_ptr(data->proc.proc);
if ((epinfo = *ptr)) { if ((epinfo = *ptr)) {
if (!epinfo->seen) {
epinfo->seen = 1;
return sizeof(data->proc);
}
/* endpoint known, store sample */ /* endpoint known, store sample */
if (size < sizeof(data->sample)) goto error; if (size < sizeof(data->sample)) goto error;
sample_store(epinfo->binary, &data->sample); sample_store(epinfo->binary, &data->sample);
@ -910,6 +931,9 @@ static size_t sample_process(const union sprof_record *data, size_t size,
*ptr = epinfo = MALLOC_CHECKED(struct endpoint_info, 1); *ptr = epinfo = MALLOC_CHECKED(struct endpoint_info, 1);
memset(epinfo, 0, sizeof(struct endpoint_info)); memset(epinfo, 0, sizeof(struct endpoint_info));
epinfo->endpoint = data->proc.proc; epinfo->endpoint = data->proc.proc;
epinfo->seen = 1;
epinfo->next = endpoints;
endpoints = epinfo;
/* fetch binary based on process name in sample */ /* fetch binary based on process name in sample */
if (size < sizeof(data->proc)) goto error; if (size < sizeof(data->proc)) goto error;
@ -963,7 +987,9 @@ static void sample_store(struct binary_info *binary,
} }
if (symbol) { if (symbol) {
assert(symbol->samples >= 0);
symbol->samples++; symbol->samples++;
assert(symbol->samples >= 0);
} else if (!binary->no_more_warnings) { } else if (!binary->no_more_warnings) {
fprintf(stderr, "warning: address 0x%lx not associated with a " fprintf(stderr, "warning: address 0x%lx not associated with a "
"symbol\n", (unsigned long) sample->pc); "symbol\n", (unsigned long) sample->pc);