sprofalyze fixes
. accumulate sprof_info . reset 'seen' endpoints for every file to keep in sync with kernel profile stream
This commit is contained in:
parent
e9a6abd046
commit
c096911b97
1 changed files with 28 additions and 2 deletions
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue