From: Harald Hoyer Date: Thu, 7 Mar 2013 07:52:54 +0000 (+0100) Subject: bootchart: add parameter "-C" to expand process names to the full cmdline X-Git-Tag: v198~36 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=e90f9fa4d1cab6f73fc502fe9ef705c1bb2912a0 bootchart: add parameter "-C" to expand process names to the full cmdline --- diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index af573da0f..543037dae 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -76,6 +76,7 @@ bool entropy = false; bool initcall = true; bool relative = false; bool filter = true; +bool show_cmdline = false; bool pss = false; int samples; int len = 500; /* we record len+1 (1 start sample) */ @@ -150,6 +151,7 @@ int main(int argc, char *argv[]) {"output", required_argument, NULL, 'o'}, {"init", required_argument, NULL, 'i'}, {"no-filter", no_argument, NULL, 'F'}, + {"cmdline", no_argument, NULL, 'C'}, {"help", no_argument, NULL, 'h'}, {"scale-x", required_argument, NULL, 'x'}, {"scale-y", required_argument, NULL, 'y'}, @@ -159,7 +161,7 @@ int main(int argc, char *argv[]) gind = 0; - i = getopt_long(argc, argv, "erpf:n:o:i:Fhx:y:", opts, &gind); + i = getopt_long(argc, argv, "erpf:n:o:i:FChx:y:", opts, &gind); if (i == -1) break; switch (i) { @@ -175,6 +177,9 @@ int main(int argc, char *argv[]) case 'F': filter = false; break; + case 'C': + show_cmdline = true; + break; case 'n': r = safe_atoi(optarg, &len); if (r < 0) diff --git a/src/bootchart/bootchart.h b/src/bootchart/bootchart.h index ea26c93c4..c42f97140 100644 --- a/src/bootchart/bootchart.h +++ b/src/bootchart/bootchart.h @@ -61,7 +61,7 @@ struct ps_struct { struct ps_struct *next; /* siblings */ /* must match - otherwise it's a new process with same PID */ - char name[16]; + char name[256]; int pid; int ppid; @@ -101,6 +101,7 @@ extern struct cpu_stat_struct cpustat[]; extern int pscount; extern bool relative; extern bool filter; +extern bool show_cmdline; extern bool pss; extern bool entropy; extern bool initcall; diff --git a/src/bootchart/log.c b/src/bootchart/log.c index cf6c3a73f..1e3f4a9e8 100644 --- a/src/bootchart/log.c +++ b/src/bootchart/log.c @@ -95,6 +95,26 @@ static char *bufgetline(char *buf) return c; } +static int pid_cmdline_strncpy(char *buffer, int pid, size_t buf_len) { + char filename[PATH_MAX]; + int _cleanup_close_ fd=-1; + ssize_t n; + + sprintf(filename, "%d/cmdline", pid); + fd = openat(procfd, filename, O_RDONLY); + if (fd < 0) + return -errno; + + n = read(fd, buffer, buf_len-1); + if (n > 0) { + int i; + for (i = 0; i < n; i++) + if (buffer[i] == '\0') + buffer[i] = ' '; + buffer[n] = '\0'; + } + return 0; +} void log_sample(int sample) { @@ -273,7 +293,12 @@ schedstat_next: if (!sscanf(buf, "%s %*s %*s", key)) continue; - strncpy(ps->name, key, 16); + strncpy(ps->name, key, 256); + + /* cmdline */ + if (show_cmdline) + pid_cmdline_strncpy(ps->name, pid, 256); + /* discard line 2 */ m = bufgetline(buf); if (!m) @@ -433,7 +458,11 @@ catch_rename: if (!sscanf(buf, "%s %*s %*s", key)) continue; - strncpy(ps->name, key, 16); + strncpy(ps->name, key, 256); + + /* cmdline */ + if (show_cmdline) + pid_cmdline_strncpy(ps->name, pid, 256); } } } diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index f8a377687..4c78abda6 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -267,6 +267,20 @@ static void svg_graph_box(int height) } } +/* xml comments must not contain "--" */ +static char* xml_comment_encode(const char* name) { + char *enc_name, *p; + + enc_name = strdup(name); + if (!enc_name) + return NULL; + + for (p = enc_name; *p; p++) + if (p[0] == '-' && p[1] == '-') + p[1] = '_'; + + return enc_name; +} static void svg_pss_graph(void) { @@ -369,7 +383,7 @@ static void svg_pss_graph(void) top = bottom + ps->sample[i].pss; /* draw a label with the process / PID */ if ((i == 1) || (ps->sample[i - 1].pss <= (100 * scale_y))) - svg(" %s [%i]\n", + svg(" [%i]\n", time_to_graph(sampletime[i] - graph_start), kb_to_graph(1000000.0 - bottom - ((top - bottom) / 2)), ps->name, @@ -383,10 +397,17 @@ static void svg_pss_graph(void) svg("\n\n\n"); ps = ps_first; while (ps->next_ps) { + char _cleanup_free_*enc_name; ps = ps->next_ps; if (!ps) continue; - svg("\n", ps->name, ps->pid, + svg("\n", enc_name, ps->pid, ps->ppid, ps->total); /* it would be nice if we could use exec_start from /proc/pid/sched, @@ -898,7 +925,7 @@ static void svg_ps_bars(void) w = ps->first; /* text label of process name */ - svg(" %s [%i] %.03fs\n", + svg(" [%i]%.03fs\n", time_to_graph(sampletime[w] - graph_start) + 5.0, ps_to_graph(j) + 14.0, ps->name, @@ -1002,7 +1029,7 @@ static void svg_top_ten_cpu(void) svg("Top CPU consumers:\n"); for (n = 0; n < 10; n++) - svg("%3.03fs - %s[%d]\n", + svg("%3.03fs - [%d]\n", 20 + (n * 13), top[n]->total, top[n]->name, @@ -1037,7 +1064,7 @@ static void svg_top_ten_pss(void) svg("Top PSS consumers:\n"); for (n = 0; n < 10; n++) - svg("%dK - %s[%d]\n", + svg("%dK - [%d]\n", 20 + (n * 13), top[n]->pss_max, top[n]->name,