Skip to contentSkip to conversation

perf: Fix accidentally preprocessed snprintf callback

PATCH Superseded Frederic Weisbecker 3 participants 7 messages Apr 14, 2010 perf events

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 perf: Fix accidentally preprocessed snprintf callback

struct sort_entry has a callback named snprintf that turns an entry into a string result.

But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

	ent->snprintf(...)

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, rename struct sort_entry::snprintf() callback to to_string(), assuming at least Java methods naming won't ever conflict with perf.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Ingo Molnar <[email protected]>
---
 tools/perf/util/hist.c |    4 ++--
 tools/perf/util/sort.c |   10 +++++-----
 tools/perf/util/sort.h |    4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)
tools/perf/util/hist.c +2 -2
index 18cf8b3..d07eccd 100644
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
 			continue;
 
 		ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
-		ret += se->snprintf(self, s + ret, size - ret,
-				    se->width ? *se->width : 0);
+		ret += se->to_string(self, s + ret, size - ret,
+				     se->width ? *se->width : 0);
 	}
 
 	return ret;
tools/perf/util/sort.c +5 -5
index 9d24d4b..b8acf51 100644
@@ -32,7 +32,7 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
 struct sort_entry sort_thread = {
 	.header = "Command:  Pid",
 	.cmp	= sort__thread_cmp,
-	.snprintf = hist_entry__thread_snprintf,
+	.to_string = hist_entry__thread_snprintf,
 	.width	= &threads__col_width,
 };
 
@@ -40,27 +40,27 @@ struct sort_entry sort_comm = {
 	.header		= "Command",
 	.cmp		= sort__comm_cmp,
 	.collapse	= sort__comm_collapse,
-	.snprintf	= hist_entry__comm_snprintf,
+	.to_string	= hist_entry__comm_snprintf,
 	.width		= &comms__col_width,
 };
 
 struct sort_entry sort_dso = {
 	.header = "Shared Object",
 	.cmp	= sort__dso_cmp,
-	.snprintf = hist_entry__dso_snprintf,
+	.to_string   = hist_entry__dso_snprintf,
 	.width	= &dsos__col_width,
 };
 
 struct sort_entry sort_sym = {
 	.header = "Symbol",
 	.cmp	= sort__sym_cmp,
-	.snprintf = hist_entry__sym_snprintf,
+	.to_string = hist_entry__sym_snprintf,
 };
 
 struct sort_entry sort_parent = {
 	.header = "Parent symbol",
 	.cmp	= sort__parent_cmp,
-	.snprintf = hist_entry__parent_snprintf,
+	.to_string = hist_entry__parent_snprintf,
 	.width	= &parent_symbol__col_width,
 };
 
tools/perf/util/sort.h +2 -2
index 6d7b4be..3a29fb5 100644
@@ -82,8 +82,8 @@ struct sort_entry {
 
 	int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
 	int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
-	int	(*snprintf)(struct hist_entry *self, char *bf, size_t size,
-			    unsigned int width);
+	int	(*to_string)(struct hist_entry *self, char *bf, size_t size,
+			     unsigned int width);
 	unsigned int *width;
 	bool	elide;
 };
Signature · 1 line
1.6.2.3
#1 lore raw
Quoted 9 lines · Frederic Weisbecker

struct sort_entry has a callback named snprintf that turns an entry into a string result.

But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

	ent->snprintf(...)
Quoted 8 lines

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, rename struct sort_entry::snprintf() callback to to_string(), assuming at least Java methods naming won't ever conflict with perf.

Note I'm not entirely happy with this to_string() renaming. May be append_string() would have been better. I don't know. snprintf() was just too good.
If you think about something else, don't hesistate to change, or I can change it myself if you want.

Thanks.

#2 lore raw

Em Wed, Apr 14, 2010 at 02:41:16AM +0200, Frederic Weisbecker escreveu:

Quoted 20 lines · Frederic Weisbecker
Quoted 9 lines

struct sort_entry has a callback named snprintf that turns an entry into a string result.

But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

	ent->snprintf(...)
Quoted 8 lines

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, rename struct sort_entry::snprintf() callback to to_string(), assuming at least Java methods naming won't ever conflict with perf.

Quoted 5 lines

Note I'm not entirely happy with this to_string() renaming. May be append_string() would have been better. I don't know. snprintf() was just too good.
If you think about something else, don't hesistate to change, or I can change it myself if you want.

psnprintf() I guess, the intent was exactly to mean that it is indeed similar to snprintf... dammit, there is already a psnprintf out there :-\

Perhaps just do it as ->he_snprintf and have the other methods as well prefixed with he as a shorthand for hist_entry, that is what the methods operate, besides the string, ok?

- Arnaldo

#3 lore raw
Quoted 27 lines · Arnaldo Carvalho de Melo

Em Wed, Apr 14, 2010 at 02:41:16AM +0200, Frederic Weisbecker escreveu:

Quoted 20 lines · Frederic Weisbecker
Quoted 9 lines

struct sort_entry has a callback named snprintf that turns an entry into a string result.

But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

	ent->snprintf(...)
Quoted 8 lines

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, rename struct sort_entry::snprintf() callback to to_string(), assuming at least Java methods naming won't ever conflict with perf.

Quoted 5 lines

Note I'm not entirely happy with this to_string() renaming. May be append_string() would have been better. I don't know. snprintf() was just too good.
If you think about something else, don't hesistate to change, or I can change it myself if you want.

Quoted 7 lines

psnprintf() I guess, the intent was exactly to mean that it is indeed similar to snprintf... dammit, there is already a psnprintf out there :-\

Perhaps just do it as ->he_snprintf and have the other methods as well prefixed with he as a shorthand for hist_entry, that is what the methods operate, besides the string, ok?

Sure, I'll resend.

This is going to be se_sprintf() though, as it's about sort_entry, not hist_entry :)

Thanks.

#4 lore raw

PATCH v2 1/1 struct sort_entry has a callback named snprintf that turns an entry into a string result.

In reply to Arnaldo Carvalho de Melo

But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

        ent->snprintf(...)

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, prepend struct sort_entry callbacks with an "se_" prefix.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Ingo Molnar <[email protected]>
---
 tools/perf/util/hist.c |   28 ++++++++++++++--------------
 tools/perf/util/sort.c |   42 +++++++++++++++++++++---------------------
 tools/perf/util/sort.h |   12 ++++++------
 3 files changed, 41 insertions(+), 41 deletions(-)
tools/perf/util/hist.c +14 -14
index 18cf8b3..9c2b874 100644
@@ -68,7 +68,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
 	int64_t cmp = 0;
 
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
-		cmp = se->cmp(left, right);
+		cmp = se->se_cmp(left, right);
 		if (cmp)
 			break;
 	}
@@ -85,7 +85,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
 		int64_t (*f)(struct hist_entry *, struct hist_entry *);
 
-		f = se->collapse ?: se->cmp;
+		f = se->se_collapse ?: se->se_cmp;
 
 		cmp = f(left, right);
 		if (cmp)
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
 			continue;
 
 		ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
-		ret += se->snprintf(self, s + ret, size - ret,
-				    se->width ? *se->width : 0);
+		ret += se->se_snprintf(self, s + ret, size - ret,
+				       se->se_width ? *se->se_width : 0);
 	}
 
 	return ret;
@@ -564,7 +564,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
 	if (sort__first_dimension == SORT_COMM) {
 		struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
 							 typeof(*se), list);
-		left_margin = se->width ? *se->width : 0;
+		left_margin = se->se_width ? *se->se_width : 0;
 		left_margin -= thread__comm_len(self->thread);
 	}
 
@@ -615,22 +615,22 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
 		if (se->elide)
 			continue;
 		if (sep) {
-			fprintf(fp, "%c%s", *sep, se->header);
+			fprintf(fp, "%c%s", *sep, se->se_header);
 			continue;
 		}
-		width = strlen(se->header);
-		if (se->width) {
+		width = strlen(se->se_header);
+		if (se->se_width) {
 			if (symbol_conf.col_width_list_str) {
 				if (col_width) {
-					*se->width = atoi(col_width);
+					*se->se_width = atoi(col_width);
 					col_width = strchr(col_width, ',');
 					if (col_width)
 						++col_width;
 				}
 			}
-			width = *se->width = max(*se->width, width);
+			width = *se->se_width = max(*se->se_width, width);
 		}
-		fprintf(fp, "  %*s", width, se->header);
+		fprintf(fp, "  %*s", width, se->se_header);
 	}
 	fprintf(fp, "\n");
 
@@ -652,10 +652,10 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
 			continue;
 
 		fprintf(fp, "  ");
-		if (se->width)
-			width = *se->width;
+		if (se->se_width)
+			width = *se->se_width;
 		else
-			width = strlen(se->header);
+			width = strlen(se->se_header);
 		for (i = 0; i < width; i++)
 			fprintf(fp, ".");
 	}
tools/perf/util/sort.c +21 -21

66 lines not on this page · raw message

tools/perf/util/sort.h +6 -6
index 6d7b4be..1d857aa 100644
@@ -78,13 +78,13 @@ enum sort_type {
 struct sort_entry {
 	struct list_head list;
 
-	const char *header;
+	const char *se_header;
 
-	int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
-	int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
-	int	(*snprintf)(struct hist_entry *self, char *bf, size_t size,
-			    unsigned int width);
-	unsigned int *width;
+	int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
+	int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
+	int	(*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+			       unsigned int width);
+	unsigned int *se_width;
 	bool	elide;
 };
 
Signature · 1 line
1.6.2.3
#5 lore raw

PATCH v3 1/1 perf: Fix accidentally preprocessed snprintf callback

In reply to Frederic Weisbecker

struct sort_entry has a callback named snprintf that turns an entry into a string result.
But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

        ent->snprintf(...)

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, prepend struct sort_entry callbacks with an "se_" prefix.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Ingo Molnar <[email protected]>
---
 tools/perf/util/hist.c |   28 ++++++++++++++--------------
 tools/perf/util/sort.c |   42 +++++++++++++++++++++---------------------
 tools/perf/util/sort.h |   12 ++++++------
 3 files changed, 41 insertions(+), 41 deletions(-)
tools/perf/util/hist.c +14 -14
index 18cf8b3..9c2b874 100644
@@ -68,7 +68,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
 	int64_t cmp = 0;
 
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
-		cmp = se->cmp(left, right);
+		cmp = se->se_cmp(left, right);
 		if (cmp)
 			break;
 	}
@@ -85,7 +85,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
 		int64_t (*f)(struct hist_entry *, struct hist_entry *);
 
-		f = se->collapse ?: se->cmp;
+		f = se->se_collapse ?: se->se_cmp;
 
 		cmp = f(left, right);
 		if (cmp)
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
 			continue;
 
 		ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
-		ret += se->snprintf(self, s + ret, size - ret,
-				    se->width ? *se->width : 0);
+		ret += se->se_snprintf(self, s + ret, size - ret,
+				       se->se_width ? *se->se_width : 0);
 	}
 
 	return ret;
@@ -564,7 +564,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
 	if (sort__first_dimension == SORT_COMM) {
 		struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
 							 typeof(*se), list);
-		left_margin = se->width ? *se->width : 0;
+		left_margin = se->se_width ? *se->se_width : 0;
 		left_margin -= thread__comm_len(self->thread);
 	}
 
@@ -615,22 +615,22 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
 		if (se->elide)
 			continue;
 		if (sep) {
-			fprintf(fp, "%c%s", *sep, se->header);
+			fprintf(fp, "%c%s", *sep, se->se_header);
 			continue;
 		}
-		width = strlen(se->header);
-		if (se->width) {
+		width = strlen(se->se_header);
+		if (se->se_width) {
 			if (symbol_conf.col_width_list_str) {
 				if (col_width) {
-					*se->width = atoi(col_width);
+					*se->se_width = atoi(col_width);
 					col_width = strchr(col_width, ',');
 					if (col_width)
 						++col_width;
 				}
 			}
-			width = *se->width = max(*se->width, width);
+			width = *se->se_width = max(*se->se_width, width);
 		}
-		fprintf(fp, "  %*s", width, se->header);
+		fprintf(fp, "  %*s", width, se->se_header);
 	}
 	fprintf(fp, "\n");
 
@@ -652,10 +652,10 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
 			continue;
 
 		fprintf(fp, "  ");
-		if (se->width)
-			width = *se->width;
+		if (se->se_width)
+			width = *se->se_width;
 		else
-			width = strlen(se->header);
+			width = strlen(se->se_header);
 		for (i = 0; i < width; i++)
 			fprintf(fp, ".");
 	}
tools/perf/util/sort.c +21 -21

66 lines not on this page · raw message

tools/perf/util/sort.h +6 -6
index 6d7b4be..1d857aa 100644
@@ -78,13 +78,13 @@ enum sort_type {
 struct sort_entry {
 	struct list_head list;
 
-	const char *header;
+	const char *se_header;
 
-	int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
-	int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
-	int	(*snprintf)(struct hist_entry *self, char *bf, size_t size,
-			    unsigned int width);
-	unsigned int *width;
+	int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
+	int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
+	int	(*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+			       unsigned int width);
+	unsigned int *se_width;
 	bool	elide;
 };
 
Signature · 1 line
1.6.2.3
#6 lore raw

Em Wed, Apr 14, 2010 at 07:11:29PM +0200, Frederic Weisbecker escreveu:

Quoted 8 lines

struct sort_entry has a callback named snprintf that turns an entry into a string result.
But there are glibc versions that implement snprintf through a macro. The following expression is then going to get the snprintf call preprocessed:

        ent->snprintf(...)
Quoted 7 lines

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, prepend struct sort_entry callbacks with an "se_" prefix.

Thanks, I'll queue this one up

- Arnaldo