aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2013-01-24 15:46:43 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-01-25 10:49:28 -0500
commite23c1a5578cf32ed3a7ac9dde59a2de0a52ff812 (patch)
treed58e6e41a4d8ff4f5e437225607e4fdb86cd12d3 /tools/lib
parenta2d28d0c198b65fac28ea6212f5f8edc77b29c27 (diff)
tools lib traceevent: Handle dynamic array's element size properly
Fixing the dynamic array format field parsing. Currently the event_read_fields function could segfault while parsing dynamic array other than string type. The reason is the event->pevent does not need to be set and gets dereferenced unconditionaly. Also adding proper initialization of field->elementsize based on the parsed dynamic type. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> 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/1359060403-32422-1-git-send-email-jolsa@redhat.com [ committer note: Made a char pointer parameter const, as requested by Steven ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/traceevent/event-parse.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index bb8b3db0e583..82b0606dcb8a 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -1223,6 +1223,34 @@ static int field_is_long(struct format_field *field)
1223 return 0; 1223 return 0;
1224} 1224}
1225 1225
1226static unsigned int type_size(const char *name)
1227{
1228 /* This covers all FIELD_IS_STRING types. */
1229 static struct {
1230 const char *type;
1231 unsigned int size;
1232 } table[] = {
1233 { "u8", 1 },
1234 { "u16", 2 },
1235 { "u32", 4 },
1236 { "u64", 8 },
1237 { "s8", 1 },
1238 { "s16", 2 },
1239 { "s32", 4 },
1240 { "s64", 8 },
1241 { "char", 1 },
1242 { },
1243 };
1244 int i;
1245
1246 for (i = 0; table[i].type; i++) {
1247 if (!strcmp(table[i].type, name))
1248 return table[i].size;
1249 }
1250
1251 return 0;
1252}
1253
1226static int event_read_fields(struct event_format *event, struct format_field **fields) 1254static int event_read_fields(struct event_format *event, struct format_field **fields)
1227{ 1255{
1228 struct format_field *field = NULL; 1256 struct format_field *field = NULL;
@@ -1232,6 +1260,8 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1232 int count = 0; 1260 int count = 0;
1233 1261
1234 do { 1262 do {
1263 unsigned int size_dynamic = 0;
1264
1235 type = read_token(&token); 1265 type = read_token(&token);
1236 if (type == EVENT_NEWLINE) { 1266 if (type == EVENT_NEWLINE) {
1237 free_token(token); 1267 free_token(token);
@@ -1390,6 +1420,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1390 field->type = new_type; 1420 field->type = new_type;
1391 strcat(field->type, " "); 1421 strcat(field->type, " ");
1392 strcat(field->type, field->name); 1422 strcat(field->type, field->name);
1423 size_dynamic = type_size(field->name);
1393 free_token(field->name); 1424 free_token(field->name);
1394 strcat(field->type, brackets); 1425 strcat(field->type, brackets);
1395 field->name = token; 1426 field->name = token;
@@ -1478,10 +1509,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1478 if (field->flags & FIELD_IS_ARRAY) { 1509 if (field->flags & FIELD_IS_ARRAY) {
1479 if (field->arraylen) 1510 if (field->arraylen)
1480 field->elementsize = field->size / field->arraylen; 1511 field->elementsize = field->size / field->arraylen;
1512 else if (field->flags & FIELD_IS_DYNAMIC)
1513 field->elementsize = size_dynamic;
1481 else if (field->flags & FIELD_IS_STRING) 1514 else if (field->flags & FIELD_IS_STRING)
1482 field->elementsize = 1; 1515 field->elementsize = 1;
1483 else 1516 else if (field->flags & FIELD_IS_LONG)
1484 field->elementsize = event->pevent->long_size; 1517 field->elementsize = event->pevent ?
1518 event->pevent->long_size :
1519 sizeof(long);
1485 } else 1520 } else
1486 field->elementsize = field->size; 1521 field->elementsize = field->size;
1487 1522