* [PATCH 0/4] perf tools: runtime fixes for Android @ 2012-09-13 22:07 Irina Tirdea 2012-09-13 22:07 ` [PATCH 1/4] perf tools: remove sscanf extension %as Irina Tirdea ` (3 more replies) 0 siblings, 4 replies; 17+ messages in thread From: Irina Tirdea @ 2012-09-13 22:07 UTC (permalink / raw) To: mingo, acme, a.p.zijlstra, rostedt Cc: paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea This is a set of patches with runtime fixes for Android. Any comments and suggestions are wellcome. Thanks, Irina Irina Tirdea (4): perf tools: remove sscanf extension %as perf stat: add compile-time option to disable --big-num perf archive: remove -f from the rm command perf archive: make f the last parameter for tar tools/perf/Makefile | 8 ++++++++ tools/perf/builtin-stat.c | 8 ++++++++ tools/perf/config/feature-tests.mak | 12 ++++++++++++ tools/perf/perf-archive.sh | 6 +++--- tools/perf/util/probe-event.c | 25 ++++++++++++++++++------- tools/perf/util/trace-event-parse.c | 18 ++++++++---------- 6 files changed, 57 insertions(+), 20 deletions(-) -- 1.7.9.5 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/4] perf tools: remove sscanf extension %as 2012-09-13 22:07 [PATCH 0/4] perf tools: runtime fixes for Android Irina Tirdea @ 2012-09-13 22:07 ` Irina Tirdea 2012-09-14 1:54 ` Namhyung Kim 2012-09-20 20:37 ` [PATCH v2 1/1] " irina.tirdea 2012-09-13 22:07 ` [PATCH 2/4] perf stat: add compile-time option to disable --big-num Irina Tirdea ` (2 subsequent siblings) 3 siblings, 2 replies; 17+ messages in thread From: Irina Tirdea @ 2012-09-13 22:07 UTC (permalink / raw) To: mingo, acme, a.p.zijlstra, rostedt Cc: paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea From: Irina Tirdea <irina.tirdea@intel.com> perf uses sscanf extension %as to read and allocate a string in the same step. This is a non-standard extension only present in new versions of glibc. Replacing the use of sscanf and %as with strtok_r calls in order to parse a given string into its components. This is needed in Android since bionic does not support %as extension for sscanf. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> --- tools/perf/util/probe-event.c | 25 ++++++++++++++++++------- tools/perf/util/trace-event-parse.c | 18 ++++++++---------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 4ce04c2..685ddcf 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, struct probe_trace_point *tp = &tev->point; char pr; char *p; + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; int ret, i, argc; char **argv; @@ -1116,14 +1117,19 @@ static int parse_probe_trace_command(const char *cmd, } /* Scan event and group name. */ - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", - &pr, (float *)(void *)&tev->group, - (float *)(void *)&tev->event); - if (ret != 3) { + argv0_str = strdup(argv[0]); + fmt1_str = strtok_r(argv0_str, ":", &fmt); + fmt2_str = strtok_r(NULL, "/", &fmt); + fmt3_str = strtok_r(NULL, " \t", &fmt); + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL + || fmt3_str == NULL) { semantic_error("Failed to parse event name: %s\n", argv[0]); ret = -EINVAL; goto out; } + pr = fmt1_str[0]; + tev->group = strdup(fmt2_str); + tev->event = strdup(fmt3_str); pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); tp->retprobe = (pr == 'r'); @@ -1135,10 +1141,13 @@ static int parse_probe_trace_command(const char *cmd, p++; } else p = argv[1]; - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, - &tp->offset); - if (ret == 1) + fmt1_str = strtok_r(p, "+", &fmt); + tp->symbol = strdup(fmt1_str); + fmt2_str = strtok_r(NULL, "", &fmt); + if (fmt2_str == NULL) tp->offset = 0; + else + tp->offset = strtoul(fmt2_str, NULL, 10); tev->nargs = argc - 2; tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); @@ -1162,6 +1171,8 @@ static int parse_probe_trace_command(const char *cmd, } ret = 0; out: + if (argv0_str) + free(argv0_str); argv_free(argv); return ret; } diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index aa4c860..3aabcd6 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent, char *next = NULL; char *addr_str; char *mod; - char ch; + char *fmt; line = strtok_r(file, "\n", &next); while (line) { mod = NULL; - sscanf(line, "%as %c %as\t[%as", - (float *)(void *)&addr_str, /* workaround gcc warning */ - &ch, (float *)(void *)&func, (float *)(void *)&mod); + addr_str = strtok_r(line, " ", &fmt); addr = strtoull(addr_str, NULL, 16); - free(addr_str); - - /* truncate the extra ']' */ + /* skip character */ + strtok_r(NULL, " ", &fmt); + func = strtok_r(NULL, "\t", &fmt); + mod = strtok_r(NULL, "]", &fmt); + /* truncate the extra '[' */ if (mod) - mod[strlen(mod) - 1] = 0; + mod = mod + 1; pevent_register_function(pevent, func, addr, mod); - free(func); - free(mod); line = strtok_r(NULL, "\n", &next); } -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] perf tools: remove sscanf extension %as 2012-09-13 22:07 ` [PATCH 1/4] perf tools: remove sscanf extension %as Irina Tirdea @ 2012-09-14 1:54 ` Namhyung Kim 2012-09-19 3:20 ` Masami Hiramatsu 2012-09-20 20:37 ` [PATCH v2 1/1] " irina.tirdea 1 sibling, 1 reply; 17+ messages in thread From: Namhyung Kim @ 2012-09-14 1:54 UTC (permalink / raw) To: Irina Tirdea Cc: mingo, acme, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea, masami.hiramatsu.pt Hi Irina, (Adding Masami to Cc) On Fri, 14 Sep 2012 01:07:40 +0300, Irina Tirdea wrote: > From: Irina Tirdea <irina.tirdea@intel.com> > > perf uses sscanf extension %as to read and allocate a > string in the same step. This is a non-standard extension > only present in new versions of glibc. > > Replacing the use of sscanf and %as with strtok_r calls > in order to parse a given string into its components. > This is needed in Android since bionic does not support > %as extension for sscanf. > > Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> > --- > tools/perf/util/probe-event.c | 25 ++++++++++++++++++------- > tools/perf/util/trace-event-parse.c | 18 ++++++++---------- > 2 files changed, 26 insertions(+), 17 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index 4ce04c2..685ddcf 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, > struct probe_trace_point *tp = &tev->point; > char pr; > char *p; > + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; > int ret, i, argc; > char **argv; > > @@ -1116,14 +1117,19 @@ static int parse_probe_trace_command(const char *cmd, > } > > /* Scan event and group name. */ > - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", > - &pr, (float *)(void *)&tev->group, > - (float *)(void *)&tev->event); > - if (ret != 3) { > + argv0_str = strdup(argv[0]); It seems you need to check return value of strdup. > + fmt1_str = strtok_r(argv0_str, ":", &fmt); > + fmt2_str = strtok_r(NULL, "/", &fmt); > + fmt3_str = strtok_r(NULL, " \t", &fmt); > + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL > + || fmt3_str == NULL) { > semantic_error("Failed to parse event name: %s\n", argv[0]); > ret = -EINVAL; > goto out; > } > + pr = fmt1_str[0]; > + tev->group = strdup(fmt2_str); > + tev->event = strdup(fmt3_str); > pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); > > tp->retprobe = (pr == 'r'); > @@ -1135,10 +1141,13 @@ static int parse_probe_trace_command(const char *cmd, > p++; > } else > p = argv[1]; > - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, > - &tp->offset); > - if (ret == 1) > + fmt1_str = strtok_r(p, "+", &fmt); > + tp->symbol = strdup(fmt1_str); Probably here too - although the original code didn't but I think it's needed. > + fmt2_str = strtok_r(NULL, "", &fmt); > + if (fmt2_str == NULL) > tp->offset = 0; > + else > + tp->offset = strtoul(fmt2_str, NULL, 10); > > tev->nargs = argc - 2; > tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); > @@ -1162,6 +1171,8 @@ static int parse_probe_trace_command(const char *cmd, > } > ret = 0; > out: > + if (argv0_str) > + free(argv0_str); The free() can handle a NULL pointer safely. > argv_free(argv); > return ret; > } ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] perf tools: remove sscanf extension %as 2012-09-14 1:54 ` Namhyung Kim @ 2012-09-19 3:20 ` Masami Hiramatsu 2012-09-20 19:13 ` Irina Tirdea 0 siblings, 1 reply; 17+ messages in thread From: Masami Hiramatsu @ 2012-09-19 3:20 UTC (permalink / raw) To: Namhyung Kim Cc: Irina Tirdea, mingo, acme, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea (2012/09/14 10:54), Namhyung Kim wrote: > Hi Irina, > > (Adding Masami to Cc) Thanks Irina and Namhyung :) > On Fri, 14 Sep 2012 01:07:40 +0300, Irina Tirdea wrote: >> From: Irina Tirdea <irina.tirdea@intel.com> >> >> perf uses sscanf extension %as to read and allocate a >> string in the same step. This is a non-standard extension >> only present in new versions of glibc. >> >> Replacing the use of sscanf and %as with strtok_r calls >> in order to parse a given string into its components. >> This is needed in Android since bionic does not support >> %as extension for sscanf. >> >> Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> >> --- >> tools/perf/util/probe-event.c | 25 ++++++++++++++++++------- >> tools/perf/util/trace-event-parse.c | 18 ++++++++---------- >> 2 files changed, 26 insertions(+), 17 deletions(-) >> >> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c >> index 4ce04c2..685ddcf 100644 >> --- a/tools/perf/util/probe-event.c >> +++ b/tools/perf/util/probe-event.c >> @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, >> struct probe_trace_point *tp = &tev->point; >> char pr; >> char *p; >> + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; >> int ret, i, argc; >> char **argv; >> >> @@ -1116,14 +1117,19 @@ static int parse_probe_trace_command(const char *cmd, >> } >> >> /* Scan event and group name. */ >> - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", >> - &pr, (float *)(void *)&tev->group, >> - (float *)(void *)&tev->event); >> - if (ret != 3) { >> + argv0_str = strdup(argv[0]); > > It seems you need to check return value of strdup. Agreed. >> + fmt1_str = strtok_r(argv0_str, ":", &fmt); >> + fmt2_str = strtok_r(NULL, "/", &fmt); >> + fmt3_str = strtok_r(NULL, " \t", &fmt); >> + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL >> + || fmt3_str == NULL) { >> semantic_error("Failed to parse event name: %s\n", argv[0]); >> ret = -EINVAL; >> goto out; >> } >> + pr = fmt1_str[0]; >> + tev->group = strdup(fmt2_str); >> + tev->event = strdup(fmt3_str); >> pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); >> >> tp->retprobe = (pr == 'r'); >> @@ -1135,10 +1141,13 @@ static int parse_probe_trace_command(const char *cmd, >> p++; >> } else >> p = argv[1]; >> - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, >> - &tp->offset); >> - if (ret == 1) >> + fmt1_str = strtok_r(p, "+", &fmt); >> + tp->symbol = strdup(fmt1_str); > > Probably here too - although the original code didn't but I think it's > needed. right, it should be fixed. >> + fmt2_str = strtok_r(NULL, "", &fmt); >> + if (fmt2_str == NULL) >> tp->offset = 0; >> + else >> + tp->offset = strtoul(fmt2_str, NULL, 10); >> >> tev->nargs = argc - 2; >> tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); >> @@ -1162,6 +1171,8 @@ static int parse_probe_trace_command(const char *cmd, >> } >> ret = 0; >> out: >> + if (argv0_str) >> + free(argv0_str); > > The free() can handle a NULL pointer safely. I don't care about it, since there are already lots of "if (ptr) free(ptr)" style code ;) > >> argv_free(argv); >> return ret; >> } Thank you! -- Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu.pt@hitachi.com ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] perf tools: remove sscanf extension %as 2012-09-19 3:20 ` Masami Hiramatsu @ 2012-09-20 19:13 ` Irina Tirdea 0 siblings, 0 replies; 17+ messages in thread From: Irina Tirdea @ 2012-09-20 19:13 UTC (permalink / raw) To: Masami Hiramatsu, Namhyung Kim Cc: mingo, acme, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea >> On Fri, 14 Sep 2012 01:07:40 +0300, Irina Tirdea wrote: >>> From: Irina Tirdea <irina.tirdea@intel.com> >>> >>> perf uses sscanf extension %as to read and allocate a >>> string in the same step. This is a non-standard extension >>> only present in new versions of glibc. >>> >>> Replacing the use of sscanf and %as with strtok_r calls >>> in order to parse a given string into its components. >>> This is needed in Android since bionic does not support >>> %as extension for sscanf. >>> >>> Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> >>> --- >>> tools/perf/util/probe-event.c | 25 ++++++++++++++++++------- >>> tools/perf/util/trace-event-parse.c | 18 ++++++++---------- >>> 2 files changed, 26 insertions(+), 17 deletions(-) >>> >>> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c >>> index 4ce04c2..685ddcf 100644 >>> --- a/tools/perf/util/probe-event.c >>> +++ b/tools/perf/util/probe-event.c >>> @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, >>> struct probe_trace_point *tp = &tev->point; >>> char pr; >>> char *p; >>> + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; >>> int ret, i, argc; >>> char **argv; >>> >>> @@ -1116,14 +1117,19 @@ static int parse_probe_trace_command(const char *cmd, >>> } >>> >>> /* Scan event and group name. */ >>> - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", >>> - &pr, (float *)(void *)&tev->group, >>> - (float *)(void *)&tev->event); >>> - if (ret != 3) { >>> + argv0_str = strdup(argv[0]); >> >> It seems you need to check return value of strdup. > > Agreed. Thanks for the review! I'll make the fixes and resend the patch. Irina ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/1] perf tools: remove sscanf extension %as 2012-09-13 22:07 ` [PATCH 1/4] perf tools: remove sscanf extension %as Irina Tirdea 2012-09-14 1:54 ` Namhyung Kim @ 2012-09-20 20:37 ` irina.tirdea 2012-09-21 15:29 ` Arnaldo Carvalho de Melo ` (2 more replies) 1 sibling, 3 replies; 17+ messages in thread From: irina.tirdea @ 2012-09-20 20:37 UTC (permalink / raw) To: mingo, acme, a.p.zijlstra, rostedt Cc: paulus, dsahern, namhyung.kim, linux-kernel, masami.hiramatsu.pt, Irina Tirdea From: Irina Tirdea <irina.tirdea@intel.com> perf uses sscanf extension %as to read and allocate a string in the same step. This is a non-standard extension only present in new versions of glibc. Replacing the use of sscanf and %as with strtok_r calls in order to parse a given string into its components. This is needed in Android since bionic does not support %as extension for sscanf. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> --- tools/perf/util/probe-event.c | 36 ++++++++++++++++++++++++++++------- tools/perf/util/trace-event-parse.c | 18 ++++++++---------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 4ce04c2..49a256e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, struct probe_trace_point *tp = &tev->point; char pr; char *p; + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; int ret, i, argc; char **argv; @@ -1116,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd, } /* Scan event and group name. */ - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", - &pr, (float *)(void *)&tev->group, - (float *)(void *)&tev->event); - if (ret != 3) { + argv0_str = strdup(argv[0]); + if (argv0_str == NULL) { + ret = -ENOMEM; + goto out; + } + fmt1_str = strtok_r(argv0_str, ":", &fmt); + fmt2_str = strtok_r(NULL, "/", &fmt); + fmt3_str = strtok_r(NULL, " \t", &fmt); + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL + || fmt3_str == NULL) { semantic_error("Failed to parse event name: %s\n", argv[0]); ret = -EINVAL; goto out; } + pr = fmt1_str[0]; + tev->group = strdup(fmt2_str); + tev->event = strdup(fmt3_str); + if (tev->group == NULL || tev->event == NULL) { + ret = -ENOMEM; + goto out; + } pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); tp->retprobe = (pr == 'r'); @@ -1135,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd, p++; } else p = argv[1]; - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, - &tp->offset); - if (ret == 1) + fmt1_str = strtok_r(p, "+", &fmt); + tp->symbol = strdup(fmt1_str); + if (tp->symbol == NULL) { + ret = -ENOMEM; + goto out; + } + fmt2_str = strtok_r(NULL, "", &fmt); + if (fmt2_str == NULL) tp->offset = 0; + else + tp->offset = strtoul(fmt2_str, NULL, 10); tev->nargs = argc - 2; tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); @@ -1162,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd, } ret = 0; out: + free(argv0_str); argv_free(argv); return ret; } diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index aa4c860..3aabcd6 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent, char *next = NULL; char *addr_str; char *mod; - char ch; + char *fmt; line = strtok_r(file, "\n", &next); while (line) { mod = NULL; - sscanf(line, "%as %c %as\t[%as", - (float *)(void *)&addr_str, /* workaround gcc warning */ - &ch, (float *)(void *)&func, (float *)(void *)&mod); + addr_str = strtok_r(line, " ", &fmt); addr = strtoull(addr_str, NULL, 16); - free(addr_str); - - /* truncate the extra ']' */ + /* skip character */ + strtok_r(NULL, " ", &fmt); + func = strtok_r(NULL, "\t", &fmt); + mod = strtok_r(NULL, "]", &fmt); + /* truncate the extra '[' */ if (mod) - mod[strlen(mod) - 1] = 0; + mod = mod + 1; pevent_register_function(pevent, func, addr, mod); - free(func); - free(mod); line = strtok_r(NULL, "\n", &next); } -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/1] perf tools: remove sscanf extension %as 2012-09-20 20:37 ` [PATCH v2 1/1] " irina.tirdea @ 2012-09-21 15:29 ` Arnaldo Carvalho de Melo 2012-09-24 7:13 ` Masami Hiramatsu 2012-09-27 5:35 ` [tip:perf/core] " tip-bot for Irina Tirdea 2 siblings, 0 replies; 17+ messages in thread From: Arnaldo Carvalho de Melo @ 2012-09-21 15:29 UTC (permalink / raw) To: irina.tirdea Cc: mingo, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, masami.hiramatsu.pt, Irina Tirdea Em Thu, Sep 20, 2012 at 11:37:50PM +0300, irina.tirdea@gmail.com escreveu: > From: Irina Tirdea <irina.tirdea@intel.com> > > perf uses sscanf extension %as to read and allocate a > string in the same step. This is a non-standard extension > only present in new versions of glibc. > > Replacing the use of sscanf and %as with strtok_r calls > in order to parse a given string into its components. > This is needed in Android since bionic does not support > %as extension for sscanf. Masami, can I have your Acked-by or even a Tested-by? - Arnaldo > Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> > --- > tools/perf/util/probe-event.c | 36 ++++++++++++++++++++++++++++------- > tools/perf/util/trace-event-parse.c | 18 ++++++++---------- > 2 files changed, 37 insertions(+), 17 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index 4ce04c2..49a256e 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, > struct probe_trace_point *tp = &tev->point; > char pr; > char *p; > + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; > int ret, i, argc; > char **argv; > > @@ -1116,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd, > } > > /* Scan event and group name. */ > - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", > - &pr, (float *)(void *)&tev->group, > - (float *)(void *)&tev->event); > - if (ret != 3) { > + argv0_str = strdup(argv[0]); > + if (argv0_str == NULL) { > + ret = -ENOMEM; > + goto out; > + } > + fmt1_str = strtok_r(argv0_str, ":", &fmt); > + fmt2_str = strtok_r(NULL, "/", &fmt); > + fmt3_str = strtok_r(NULL, " \t", &fmt); > + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL > + || fmt3_str == NULL) { > semantic_error("Failed to parse event name: %s\n", argv[0]); > ret = -EINVAL; > goto out; > } > + pr = fmt1_str[0]; > + tev->group = strdup(fmt2_str); > + tev->event = strdup(fmt3_str); > + if (tev->group == NULL || tev->event == NULL) { > + ret = -ENOMEM; > + goto out; > + } > pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); > > tp->retprobe = (pr == 'r'); > @@ -1135,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd, > p++; > } else > p = argv[1]; > - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, > - &tp->offset); > - if (ret == 1) > + fmt1_str = strtok_r(p, "+", &fmt); > + tp->symbol = strdup(fmt1_str); > + if (tp->symbol == NULL) { > + ret = -ENOMEM; > + goto out; > + } > + fmt2_str = strtok_r(NULL, "", &fmt); > + if (fmt2_str == NULL) > tp->offset = 0; > + else > + tp->offset = strtoul(fmt2_str, NULL, 10); > > tev->nargs = argc - 2; > tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); > @@ -1162,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd, > } > ret = 0; > out: > + free(argv0_str); > argv_free(argv); > return ret; > } > diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c > index aa4c860..3aabcd6 100644 > --- a/tools/perf/util/trace-event-parse.c > +++ b/tools/perf/util/trace-event-parse.c > @@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent, > char *next = NULL; > char *addr_str; > char *mod; > - char ch; > + char *fmt; > > line = strtok_r(file, "\n", &next); > while (line) { > mod = NULL; > - sscanf(line, "%as %c %as\t[%as", > - (float *)(void *)&addr_str, /* workaround gcc warning */ > - &ch, (float *)(void *)&func, (float *)(void *)&mod); > + addr_str = strtok_r(line, " ", &fmt); > addr = strtoull(addr_str, NULL, 16); > - free(addr_str); > - > - /* truncate the extra ']' */ > + /* skip character */ > + strtok_r(NULL, " ", &fmt); > + func = strtok_r(NULL, "\t", &fmt); > + mod = strtok_r(NULL, "]", &fmt); > + /* truncate the extra '[' */ > if (mod) > - mod[strlen(mod) - 1] = 0; > + mod = mod + 1; > > pevent_register_function(pevent, func, addr, mod); > - free(func); > - free(mod); > > line = strtok_r(NULL, "\n", &next); > } > -- > 1.7.9.5 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/1] perf tools: remove sscanf extension %as 2012-09-20 20:37 ` [PATCH v2 1/1] " irina.tirdea 2012-09-21 15:29 ` Arnaldo Carvalho de Melo @ 2012-09-24 7:13 ` Masami Hiramatsu 2012-09-27 5:35 ` [tip:perf/core] " tip-bot for Irina Tirdea 2 siblings, 0 replies; 17+ messages in thread From: Masami Hiramatsu @ 2012-09-24 7:13 UTC (permalink / raw) To: irina.tirdea Cc: mingo, acme, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea, yrl.pp-manager.tt (2012/09/21 5:37), irina.tirdea@gmail.com wrote: > From: Irina Tirdea <irina.tirdea@intel.com> > > perf uses sscanf extension %as to read and allocate a > string in the same step. This is a non-standard extension > only present in new versions of glibc. > > Replacing the use of sscanf and %as with strtok_r calls > in order to parse a given string into its components. > This is needed in Android since bionic does not support > %as extension for sscanf. OK, I've reviewed and tested, looks good! :) Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Thank you! > > Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> > --- > tools/perf/util/probe-event.c | 36 ++++++++++++++++++++++++++++------- > tools/perf/util/trace-event-parse.c | 18 ++++++++---------- > 2 files changed, 37 insertions(+), 17 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index 4ce04c2..49a256e 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, > struct probe_trace_point *tp = &tev->point; > char pr; > char *p; > + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; > int ret, i, argc; > char **argv; > > @@ -1116,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd, > } > > /* Scan event and group name. */ > - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", > - &pr, (float *)(void *)&tev->group, > - (float *)(void *)&tev->event); > - if (ret != 3) { > + argv0_str = strdup(argv[0]); > + if (argv0_str == NULL) { > + ret = -ENOMEM; > + goto out; > + } > + fmt1_str = strtok_r(argv0_str, ":", &fmt); > + fmt2_str = strtok_r(NULL, "/", &fmt); > + fmt3_str = strtok_r(NULL, " \t", &fmt); > + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL > + || fmt3_str == NULL) { > semantic_error("Failed to parse event name: %s\n", argv[0]); > ret = -EINVAL; > goto out; > } > + pr = fmt1_str[0]; > + tev->group = strdup(fmt2_str); > + tev->event = strdup(fmt3_str); > + if (tev->group == NULL || tev->event == NULL) { > + ret = -ENOMEM; > + goto out; > + } > pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); > > tp->retprobe = (pr == 'r'); > @@ -1135,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd, > p++; > } else > p = argv[1]; > - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, > - &tp->offset); > - if (ret == 1) > + fmt1_str = strtok_r(p, "+", &fmt); > + tp->symbol = strdup(fmt1_str); > + if (tp->symbol == NULL) { > + ret = -ENOMEM; > + goto out; > + } > + fmt2_str = strtok_r(NULL, "", &fmt); > + if (fmt2_str == NULL) > tp->offset = 0; > + else > + tp->offset = strtoul(fmt2_str, NULL, 10); > > tev->nargs = argc - 2; > tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); > @@ -1162,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd, > } > ret = 0; > out: > + free(argv0_str); > argv_free(argv); > return ret; > } > diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c > index aa4c860..3aabcd6 100644 > --- a/tools/perf/util/trace-event-parse.c > +++ b/tools/perf/util/trace-event-parse.c > @@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent, > char *next = NULL; > char *addr_str; > char *mod; > - char ch; > + char *fmt; > > line = strtok_r(file, "\n", &next); > while (line) { > mod = NULL; > - sscanf(line, "%as %c %as\t[%as", > - (float *)(void *)&addr_str, /* workaround gcc warning */ > - &ch, (float *)(void *)&func, (float *)(void *)&mod); > + addr_str = strtok_r(line, " ", &fmt); > addr = strtoull(addr_str, NULL, 16); > - free(addr_str); > - > - /* truncate the extra ']' */ > + /* skip character */ > + strtok_r(NULL, " ", &fmt); > + func = strtok_r(NULL, "\t", &fmt); > + mod = strtok_r(NULL, "]", &fmt); > + /* truncate the extra '[' */ > if (mod) > - mod[strlen(mod) - 1] = 0; > + mod = mod + 1; > > pevent_register_function(pevent, func, addr, mod); > - free(func); > - free(mod); > > line = strtok_r(NULL, "\n", &next); > } > -- Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu.pt@hitachi.com ^ permalink raw reply [flat|nested] 17+ messages in thread
* [tip:perf/core] perf tools: remove sscanf extension %as 2012-09-20 20:37 ` [PATCH v2 1/1] " irina.tirdea 2012-09-21 15:29 ` Arnaldo Carvalho de Melo 2012-09-24 7:13 ` Masami Hiramatsu @ 2012-09-27 5:35 ` tip-bot for Irina Tirdea 2 siblings, 0 replies; 17+ messages in thread From: tip-bot for Irina Tirdea @ 2012-09-27 5:35 UTC (permalink / raw) To: linux-tip-commits Cc: acme, linux-kernel, paulus, mingo, hpa, mingo, a.p.zijlstra, namhyung.kim, masami.hiramatsu.pt, rostedt, irina.tirdea, dsahern, tglx Commit-ID: bcbd004020bf0d725722be75da35fd326ff63ef4 Gitweb: http://git.kernel.org/tip/bcbd004020bf0d725722be75da35fd326ff63ef4 Author: Irina Tirdea <irina.tirdea@intel.com> AuthorDate: Thu, 20 Sep 2012 23:37:50 +0300 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Mon, 24 Sep 2012 11:49:31 -0300 perf tools: remove sscanf extension %as perf uses sscanf extension %as to read and allocate a string in the same step. This is a non-standard extension only present in new versions of glibc. Replacing the use of sscanf and %as with strtok_r calls in order to parse a given string into its components. This is needed in Android since bionic does not support %as extension for sscanf. Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/1348173470-4936-1-git-send-email-irina.tirdea@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/probe-event.c | 36 ++++++++++++++++++++++++++++------ tools/perf/util/trace-event-parse.c | 18 +++++++--------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 4ce04c2..49a256e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, struct probe_trace_point *tp = &tev->point; char pr; char *p; + char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; int ret, i, argc; char **argv; @@ -1116,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd, } /* Scan event and group name. */ - ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", - &pr, (float *)(void *)&tev->group, - (float *)(void *)&tev->event); - if (ret != 3) { + argv0_str = strdup(argv[0]); + if (argv0_str == NULL) { + ret = -ENOMEM; + goto out; + } + fmt1_str = strtok_r(argv0_str, ":", &fmt); + fmt2_str = strtok_r(NULL, "/", &fmt); + fmt3_str = strtok_r(NULL, " \t", &fmt); + if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL + || fmt3_str == NULL) { semantic_error("Failed to parse event name: %s\n", argv[0]); ret = -EINVAL; goto out; } + pr = fmt1_str[0]; + tev->group = strdup(fmt2_str); + tev->event = strdup(fmt3_str); + if (tev->group == NULL || tev->event == NULL) { + ret = -ENOMEM; + goto out; + } pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); tp->retprobe = (pr == 'r'); @@ -1135,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd, p++; } else p = argv[1]; - ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, - &tp->offset); - if (ret == 1) + fmt1_str = strtok_r(p, "+", &fmt); + tp->symbol = strdup(fmt1_str); + if (tp->symbol == NULL) { + ret = -ENOMEM; + goto out; + } + fmt2_str = strtok_r(NULL, "", &fmt); + if (fmt2_str == NULL) tp->offset = 0; + else + tp->offset = strtoul(fmt2_str, NULL, 10); tev->nargs = argc - 2; tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); @@ -1162,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd, } ret = 0; out: + free(argv0_str); argv_free(argv); return ret; } diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index aa4c860..3aabcd6 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent, char *next = NULL; char *addr_str; char *mod; - char ch; + char *fmt; line = strtok_r(file, "\n", &next); while (line) { mod = NULL; - sscanf(line, "%as %c %as\t[%as", - (float *)(void *)&addr_str, /* workaround gcc warning */ - &ch, (float *)(void *)&func, (float *)(void *)&mod); + addr_str = strtok_r(line, " ", &fmt); addr = strtoull(addr_str, NULL, 16); - free(addr_str); - - /* truncate the extra ']' */ + /* skip character */ + strtok_r(NULL, " ", &fmt); + func = strtok_r(NULL, "\t", &fmt); + mod = strtok_r(NULL, "]", &fmt); + /* truncate the extra '[' */ if (mod) - mod[strlen(mod) - 1] = 0; + mod = mod + 1; pevent_register_function(pevent, func, addr, mod); - free(func); - free(mod); line = strtok_r(NULL, "\n", &next); } ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/4] perf stat: add compile-time option to disable --big-num 2012-09-13 22:07 [PATCH 0/4] perf tools: runtime fixes for Android Irina Tirdea 2012-09-13 22:07 ` [PATCH 1/4] perf tools: remove sscanf extension %as Irina Tirdea @ 2012-09-13 22:07 ` Irina Tirdea 2012-09-14 5:40 ` Ingo Molnar 2012-09-23 21:48 ` [PATCH v2 1/1] perf stat: implement --big-num grouping Irina Tirdea 2012-09-13 22:07 ` [PATCH 3/4] perf archive: remove -f from the rm command Irina Tirdea 2012-09-13 22:07 ` [PATCH 4/4] perf archive: make f the last parameter for tar Irina Tirdea 3 siblings, 2 replies; 17+ messages in thread From: Irina Tirdea @ 2012-09-13 22:07 UTC (permalink / raw) To: mingo, acme, a.p.zijlstra, rostedt Cc: paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea From: Irina Tirdea <irina.tirdea@intel.com> In printf's format, ' is used to group the output with thousands' grouping characters for decimal conversion. Bionic does not support ' for printf. Add a compile-time option (NO_BIG_NUM) to disable the --big-num option from perf stat. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> --- tools/perf/Makefile | 8 ++++++++ tools/perf/builtin-stat.c | 8 ++++++++ tools/perf/config/feature-tests.mak | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 209774b..8daa781 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -768,6 +768,14 @@ else endif endif +ifdef NO_BIG_NUM + BASIC_CFLAGS += -DNO_BIG_NUM +else + ifneq ($(call try-cc,$(SOURCE_BIG_NUM),),y) + BASIC_CFLAGS += -DNO_BIG_NUM + endif +endif + ifdef ASCIIDOC8 export ASCIIDOC8 endif diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index dab347d..ad8013e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -188,7 +188,11 @@ static pid_t child_pid = -1; static bool null_run = false; static int detailed_run = 0; static bool sync_run = false; +#ifdef NO_BIG_NUM +static bool big_num = false; +#else static bool big_num = true; +#endif static int big_num_opt = -1; static const char *csv_sep = NULL; static bool csv_output = false; @@ -1075,12 +1079,14 @@ static const char * const stat_usage[] = { NULL }; +#ifndef NO_BIG_NUM static int stat__set_big_num(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset) { big_num_opt = unset ? 0 : 1; return 0; } +#endif static bool append_file; @@ -1112,9 +1118,11 @@ static const struct option options[] = { "detailed run - start a lot of events"), OPT_BOOLEAN('S', "sync", &sync_run, "call sync() before starting a run"), +#ifndef NO_BIG_NUM OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, "print large numbers with thousands\' separators", stat__set_big_num), +#endif OPT_STRING('C', "cpu", &target.cpu_list, "cpu", "list of cpus to monitor in system-wide"), OPT_BOOLEAN('A', "no-aggr", &no_aggr, diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 116690a..2e5fad7 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -193,3 +193,15 @@ int main(void) } endef endif + +ifndef NO_BIG_NUM +define SOURCE_BIG_NUM +#include <stdio.h> + +int main(void) +{ + printf(\"%'\''.2f\", 1234567.89); + return 0; +} +endef +endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] perf stat: add compile-time option to disable --big-num 2012-09-13 22:07 ` [PATCH 2/4] perf stat: add compile-time option to disable --big-num Irina Tirdea @ 2012-09-14 5:40 ` Ingo Molnar 2012-09-20 19:17 ` Irina Tirdea 2012-09-23 21:48 ` [PATCH v2 1/1] perf stat: implement --big-num grouping Irina Tirdea 1 sibling, 1 reply; 17+ messages in thread From: Ingo Molnar @ 2012-09-14 5:40 UTC (permalink / raw) To: Irina Tirdea Cc: mingo, acme, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea * Irina Tirdea <irina.tirdea@gmail.com> wrote: > From: Irina Tirdea <irina.tirdea@intel.com> > > In printf's format, ' is used to group the output with thousands' grouping > characters for decimal conversion. Bionic does not support ' for printf. Please try to solve compatibility without affecting the default output and big num is the default perf stat output. Could the big num output be implemented within perf, without relying on glibc's printf implementation? Thanks, Ingo ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] perf stat: add compile-time option to disable --big-num 2012-09-14 5:40 ` Ingo Molnar @ 2012-09-20 19:17 ` Irina Tirdea 0 siblings, 0 replies; 17+ messages in thread From: Irina Tirdea @ 2012-09-20 19:17 UTC (permalink / raw) To: Ingo Molnar Cc: mingo, acme, a.p.zijlstra, rostedt, paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea On Fri, Sep 14, 2012 at 8:40 AM, Ingo Molnar <mingo@kernel.org> wrote: > > * Irina Tirdea <irina.tirdea@gmail.com> wrote: > >> From: Irina Tirdea <irina.tirdea@intel.com> >> >> In printf's format, ' is used to group the output with thousands' grouping >> characters for decimal conversion. Bionic does not support ' for printf. > > Please try to solve compatibility without affecting the default > output and big num is the default perf stat output. Understood. > Could the big num output be implemented within perf, without > relying on glibc's printf implementation? > Yes. I'll write a function that does the grouping instead of using printf and send it for review instead of this patch. Thanks, Irina ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/1] perf stat: implement --big-num grouping 2012-09-13 22:07 ` [PATCH 2/4] perf stat: add compile-time option to disable --big-num Irina Tirdea 2012-09-14 5:40 ` Ingo Molnar @ 2012-09-23 21:48 ` Irina Tirdea 1 sibling, 0 replies; 17+ messages in thread From: Irina Tirdea @ 2012-09-23 21:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Ingo Molnar, Steven Rostedt, Peter Zijlstra Cc: LKML, Paul Mackerras, David Ahern, Namhyung Kim, Pekka Enberg, Jiri Olsa, Irina Tirdea From: Irina Tirdea <irina.tirdea@intel.com> In glibc, printf supports ' to group numbers with thousands' grouping characters. Bionic does not support ' for printf. Implement thousands's grouping for numbers according to locale. The implementation uses the algorithm from glibc (http://www.gnu.org/software/libc/). Bionic does not implement locales, so we need to add a configuration option NO_LOCALE. If NO_LOCALE is defined, default values for thousands separator and grouping are used. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> --- Changes in v2: This is a rewrite of http://lkml.org/lkml/2012/9/13/574 Instead of disabling big num for Android, I added the implementation in perf (as Ingo suggested). tools/perf/Makefile | 8 +++ tools/perf/builtin-stat.c | 112 ++++++++++++++++++++++++++++++++--- tools/perf/config/feature-tests.mak | 18 ++++++ 3 files changed, 131 insertions(+), 7 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 5077f8e..74e21cf 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -769,6 +769,14 @@ else endif endif +ifdef NO_LOCALE + BASIC_CFLAGS += -DNO_LOCALE +else + ifneq ($(call try-cc,$(SOURCE_LOCALE),),y) + BASIC_CFLAGS += -DNO_LOCALE + endif +endif + ifdef ASCIIDOC8 export ASCIIDOC8 endif diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e0f65fe..cb8b399 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -60,6 +60,8 @@ #include <sys/prctl.h> #include <locale.h> +/* max double number have E+308 + \0 + sign */ +#define MAX_NR_STR 310 #define DEFAULT_SEPARATOR " " #define CNTR_NOT_SUPPORTED "<not supported>" #define CNTR_NOT_COUNTED "<not counted>" @@ -744,18 +746,112 @@ static void print_ll_cache_misses(int cpu, fprintf(output, " of all LL-cache hits "); } +/* Group the digits according to the grouping rules of the current locale. + The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */ +static int group_number_locale(char *number, char **gnumber) +{ + const char *thousands_sep = NULL, *grouping = NULL; + int glen, tlen, dest_alloc_size, src_size, ret = 0, cnt; + char *dest_alloc_ptr, *dest_end, *src_start, *src_end; + +#ifdef NO_LOCALE + thousands_sep = ","; + grouping = "\x3"; +#else + struct lconv *lc = localeconv(); + if (lc != NULL) { + thousands_sep = lc->thousands_sep; + grouping = lc->grouping; + } +#endif + + *gnumber = NULL; + /* No grouping */ + if (thousands_sep == NULL || grouping == NULL || + *thousands_sep == '\0' || *grouping == CHAR_MAX || *grouping <= 0) { + *gnumber = strdup(number); + if (*gnumber == NULL) + ret = -ENOMEM; + goto out; + } + + glen = *grouping++; + tlen = strlen(thousands_sep); + + src_size = strlen(number); + /* Worst case scenario we have 1-character grouping */ + dest_alloc_size = (src_size + src_size * tlen) * sizeof(char); + dest_alloc_ptr = zalloc(dest_alloc_size); + if (dest_alloc_ptr == NULL) { + ret = -ENOMEM; + goto out; + } + /* -1 for '\0' */ + dest_end = dest_alloc_ptr + dest_alloc_size - 1; + + src_start = number; + src_end = number + src_size; + + while (src_end > src_start) { + *--dest_end = *--src_end; + if (--glen == 0 && src_end > src_start) { + /* A new group */ + cnt = tlen; + do + *--dest_end = thousands_sep[--cnt]; + while (cnt > 0); + + if (*grouping == CHAR_MAX || *grouping < 0) { + /* No further grouping to be done. + Copy the rest of the number. */ + do + *--dest_end = *--src_end; + while (src_end > src_start); + break; + } else if (*grouping != '\0') { + glen = *grouping++; + } else { + /* The previous grouping repeats ad infinitum */ + glen = grouping[-1]; + } + } + } + + /* Make a copy with the exact needed size of the grouped number */ + *gnumber = strdup(dest_end); + if (*gnumber == NULL) { + ret = -ENOMEM; + goto out_free_dest; + } + + /* fall through */ +out_free_dest: + free(dest_alloc_ptr); +out: + return ret; +} + static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) { double total, ratio = 0.0; char cpustr[16] = { '\0', }; const char *fmt; + char avgstr[MAX_NR_STR], *pavgstr; + int ret; - if (csv_output) - fmt = "%s%.0f%s%s"; - else if (big_num) - fmt = "%s%'18.0f%s%-25s"; - else - fmt = "%s%18.0f%s%-25s"; + sprintf(avgstr, "%.0f", avg); + pavgstr = avgstr; + + if (csv_output) { + fmt = "%s%s%s%s"; + } else { + fmt = "%s%18s%s%-25s"; + if (big_num) { + ret = group_number_locale(avgstr, &pavgstr); + if (ret < 0) + pavgstr = avgstr; + } + } if (no_aggr) sprintf(cpustr, "CPU%*d%s", @@ -764,7 +860,9 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) else cpu = 0; - fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel)); + fprintf(output, fmt, cpustr, pavgstr, csv_sep, perf_evsel__name(evsel)); + if (pavgstr != avgstr) + free(pavgstr); if (evsel->cgrp) fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 116690a..7e5c005 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -193,3 +193,21 @@ int main(void) } endef endif + +ifndef NO_LOCALE +define SOURCE_LOCALE +#include <locale.h> + +int main(void) +{ + char *thousands_sep, *grouping; + + struct lconv *lc = localeconv(); + if (lc != NULL) { + thousands_sep = lc->thousands_sep; + grouping = lc->grouping; + } + return 0; +} +endef +endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/4] perf archive: remove -f from the rm command 2012-09-13 22:07 [PATCH 0/4] perf tools: runtime fixes for Android Irina Tirdea 2012-09-13 22:07 ` [PATCH 1/4] perf tools: remove sscanf extension %as Irina Tirdea 2012-09-13 22:07 ` [PATCH 2/4] perf stat: add compile-time option to disable --big-num Irina Tirdea @ 2012-09-13 22:07 ` Irina Tirdea 2012-09-19 15:19 ` [tip:perf/core] perf archive: Remove " tip-bot for Irina Tirdea 2012-09-13 22:07 ` [PATCH 4/4] perf archive: make f the last parameter for tar Irina Tirdea 3 siblings, 1 reply; 17+ messages in thread From: Irina Tirdea @ 2012-09-13 22:07 UTC (permalink / raw) To: mingo, acme, a.p.zijlstra, rostedt Cc: paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea From: Irina Tirdea <irina.tirdea@intel.com> In Android, rm does not support the -f parameter. Remove -f from rm and make sure rm does not fail even if the files to be removed are not found. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> --- tools/perf/perf-archive.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index 95b6f8b..da94179 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -24,7 +24,7 @@ NOBUILDID=0000000000000000000000000000000000000000 perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS if [ ! -s $BUILDIDS ] ; then echo "perf archive: no build-ids found" - rm -f $BUILDIDS + rm $BUILDIDS || true exit 1 fi @@ -40,7 +40,7 @@ while read build_id ; do done tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST -rm -f $MANIFEST $BUILDIDS +rm $MANIFEST $BUILDIDS || true echo -e "Now please run:\n" echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n" echo "wherever you need to run 'perf report' on." -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [tip:perf/core] perf archive: Remove -f from the rm command 2012-09-13 22:07 ` [PATCH 3/4] perf archive: remove -f from the rm command Irina Tirdea @ 2012-09-19 15:19 ` tip-bot for Irina Tirdea 0 siblings, 0 replies; 17+ messages in thread From: tip-bot for Irina Tirdea @ 2012-09-19 15:19 UTC (permalink / raw) To: linux-tip-commits Cc: acme, linux-kernel, paulus, mingo, hpa, mingo, a.p.zijlstra, namhyung.kim, rostedt, irina.tirdea, dsahern, tglx Commit-ID: 73eb422c10aa2a4afc1100d1bd54974ed72ad373 Gitweb: http://git.kernel.org/tip/73eb422c10aa2a4afc1100d1bd54974ed72ad373 Author: Irina Tirdea <irina.tirdea@intel.com> AuthorDate: Fri, 14 Sep 2012 01:07:42 +0300 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Mon, 17 Sep 2012 13:10:27 -0300 perf archive: Remove -f from the rm command In Android, rm does not support the -f parameter. Remove -f from rm and make sure rm does not fail even if the files to be removed are not found. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/1347574063-22521-4-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/perf-archive.sh | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index 95b6f8b..da94179 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -24,7 +24,7 @@ NOBUILDID=0000000000000000000000000000000000000000 perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS if [ ! -s $BUILDIDS ] ; then echo "perf archive: no build-ids found" - rm -f $BUILDIDS + rm $BUILDIDS || true exit 1 fi @@ -40,7 +40,7 @@ while read build_id ; do done tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST -rm -f $MANIFEST $BUILDIDS +rm $MANIFEST $BUILDIDS || true echo -e "Now please run:\n" echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n" echo "wherever you need to run 'perf report' on." ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/4] perf archive: make f the last parameter for tar 2012-09-13 22:07 [PATCH 0/4] perf tools: runtime fixes for Android Irina Tirdea ` (2 preceding siblings ...) 2012-09-13 22:07 ` [PATCH 3/4] perf archive: remove -f from the rm command Irina Tirdea @ 2012-09-13 22:07 ` Irina Tirdea 2012-09-19 15:20 ` [tip:perf/core] perf archive: Make 'f' " tip-bot for Irina Tirdea 3 siblings, 1 reply; 17+ messages in thread From: Irina Tirdea @ 2012-09-13 22:07 UTC (permalink / raw) To: mingo, acme, a.p.zijlstra, rostedt Cc: paulus, dsahern, namhyung.kim, linux-kernel, Irina Tirdea From: Irina Tirdea <irina.tirdea@intel.com> On some systems, tar needs to specify the name of the archive immediately after the -f parameter. Change the order of the parameters so tar can run properly. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> --- tools/perf/perf-archive.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index da94179..e919306 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -39,7 +39,7 @@ while read build_id ; do echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST done -tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST +tar cjf $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST rm $MANIFEST $BUILDIDS || true echo -e "Now please run:\n" echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n" -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [tip:perf/core] perf archive: Make 'f' the last parameter for tar 2012-09-13 22:07 ` [PATCH 4/4] perf archive: make f the last parameter for tar Irina Tirdea @ 2012-09-19 15:20 ` tip-bot for Irina Tirdea 0 siblings, 0 replies; 17+ messages in thread From: tip-bot for Irina Tirdea @ 2012-09-19 15:20 UTC (permalink / raw) To: linux-tip-commits Cc: acme, linux-kernel, paulus, mingo, hpa, mingo, a.p.zijlstra, namhyung.kim, rostedt, irina.tirdea, dsahern, tglx Commit-ID: 87ff50a3192152944d8e65b485bbf3d03214d0b6 Gitweb: http://git.kernel.org/tip/87ff50a3192152944d8e65b485bbf3d03214d0b6 Author: Irina Tirdea <irina.tirdea@intel.com> AuthorDate: Fri, 14 Sep 2012 01:07:43 +0300 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Mon, 17 Sep 2012 13:10:42 -0300 perf archive: Make 'f' the last parameter for tar On some systems, tar needs to specify the name of the archive immediately after the -f parameter. Change the order of the parameters so tar can run properly. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/1347574063-22521-5-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/perf-archive.sh | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index da94179..e919306 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -39,7 +39,7 @@ while read build_id ; do echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST done -tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST +tar cjf $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST rm $MANIFEST $BUILDIDS || true echo -e "Now please run:\n" echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n" ^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-09-27 5:36 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-09-13 22:07 [PATCH 0/4] perf tools: runtime fixes for Android Irina Tirdea 2012-09-13 22:07 ` [PATCH 1/4] perf tools: remove sscanf extension %as Irina Tirdea 2012-09-14 1:54 ` Namhyung Kim 2012-09-19 3:20 ` Masami Hiramatsu 2012-09-20 19:13 ` Irina Tirdea 2012-09-20 20:37 ` [PATCH v2 1/1] " irina.tirdea 2012-09-21 15:29 ` Arnaldo Carvalho de Melo 2012-09-24 7:13 ` Masami Hiramatsu 2012-09-27 5:35 ` [tip:perf/core] " tip-bot for Irina Tirdea 2012-09-13 22:07 ` [PATCH 2/4] perf stat: add compile-time option to disable --big-num Irina Tirdea 2012-09-14 5:40 ` Ingo Molnar 2012-09-20 19:17 ` Irina Tirdea 2012-09-23 21:48 ` [PATCH v2 1/1] perf stat: implement --big-num grouping Irina Tirdea 2012-09-13 22:07 ` [PATCH 3/4] perf archive: remove -f from the rm command Irina Tirdea 2012-09-19 15:19 ` [tip:perf/core] perf archive: Remove " tip-bot for Irina Tirdea 2012-09-13 22:07 ` [PATCH 4/4] perf archive: make f the last parameter for tar Irina Tirdea 2012-09-19 15:20 ` [tip:perf/core] perf archive: Make 'f' " tip-bot for Irina Tirdea
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).