aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris E Ferron <chris.e.ferron@linux.intel.com>2012-07-27 09:22:28 -0700
committerChris E Ferron <chris.e.ferron@linux.intel.com>2012-07-27 09:26:33 -0700
commitce22d9d47abe1bf90467d4a30ccdadf1f2c9a540 (patch)
tree114011546ea36da7f1825f872f0659540b704d3f
parent6e14e6ef3f286f0b70e454c45f46c4d235208ece (diff)
rebase pevent code to upstream kernel version of tools lib traceevent.
This will allow me to keep update and align with the libary code until it is usable without building it local.
-rw-r--r--Android.mk15
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac2
-rw-r--r--pevent/Makefile.am5
-rw-r--r--src/Makefile.am2
-rw-r--r--src/cpu/cpu.cpp2
-rw-r--r--src/perf/perf.h4
-rw-r--r--src/process/do_process.cpp4
-rw-r--r--traceevent/.deps/event-parse.Plo113
-rw-r--r--traceevent/.deps/parse-filter.Plo112
-rw-r--r--traceevent/.deps/parse-utils.Plo103
-rw-r--r--traceevent/.deps/trace-seq.Plo96
-rw-r--r--traceevent/Makefile.am7
-rw-r--r--traceevent/event-parse.c (renamed from pevent/parse-events.c)405
-rw-r--r--traceevent/event-parse.h (renamed from pevent/parse-events.h)90
-rw-r--r--traceevent/event-utils.h (renamed from pevent/util.h)21
-rw-r--r--traceevent/parse-filter.c (renamed from pevent/parse-filter.c)84
-rw-r--r--traceevent/parse-utils.c (renamed from pevent/parse-utils.c)0
-rw-r--r--traceevent/trace-seq.c (renamed from pevent/trace-seq.c)8
19 files changed, 853 insertions, 222 deletions
diff --git a/Android.mk b/Android.mk
index e70cc45..a46a288 100644
--- a/Android.mk
+++ b/Android.mk
@@ -5,7 +5,7 @@ LOCAL_MODULE_TAGS := debug
LOCAL_SHARED_LIBRARIES := libstlport \
libnl \
libpci \
- libparseevent \
+ libtraceevnet \
LOCAL_MODULE := powertop
#LOCAL_CFLAGS += -Wall -O2 -g -fno-omit-frame-pointer -fstack-protector -Wshadow -Wformat -D_FORTIFY_SOURCE=2
@@ -66,12 +66,11 @@ LOCAL_SRC_FILES += \
src/devlist.cpp \
src/calibrate/calibrate.cpp \
src/lib.cpp \
- pevent/parse-events.c \
- pevent/parse-filter.c \
- pevent/trace-seq.c \
- pevent/parse-events.h \
- pevent/parse-utils.c \
- pevent/util.h
-
+ traceevent/event-parse.c \
+ traceevent/event-parse.h \
+ traceevent/event-utils.h \
+ traceevent/parse-filter.c \
+ traceevent/parse-utils.c \
+ traceevent/trace-seq.c
include $(BUILD_EXECUTABLE)
diff --git a/Makefile.am b/Makefile.am
index f222fa3..f5e466b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = pevent src po doc
+SUBDIRS = traceevent src po doc
EXTRA_DIST = README TODO Android.mk COPYING autogen.sh
diff --git a/configure.ac b/configure.ac
index e9d0ae7..3f5775f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@ AC_PREREQ([2.68])
AC_INIT([powertop], [2.0], [powertop@lists.01.org])
AM_INIT_AUTOMAKE([-Wall foreign ])
AC_LANG([C++])
-AC_CONFIG_FILES([Makefile src/Makefile pevent/Makefile po/Makefile.in doc/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile traceevent/Makefile po/Makefile.in doc/Makefile])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
diff --git a/pevent/Makefile.am b/pevent/Makefile.am
deleted file mode 100644
index 5f9d810..0000000
--- a/pevent/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-noinst_LTLIBRARIES = libparseevent.la
-libparseevent_la_SOURCES = parse-events.c parse-filter.c trace-seq.c parse-events.h parse-utils.c util.h
-
-
-
diff --git a/src/Makefile.am b/src/Makefile.am
index 23625a2..d0976fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,7 +38,7 @@ powertop_CXXFLAGS = -fno-omit-frame-pointer -fstack-protector -Wall -Wshadow -Wf
powertop_CPPFLAGS = -D_FORTIFY_SOURCE=2 $(NCURSES_CFLAGS) $(PCIUTILS_CFLAGS) $(LIBNL_CFLAGS) $(GLIB2_CFLAGS) $(LIBZ_CFLAGS) -DLOCALEDIR=\"$(localedir)\"
-powertop_LDADD = ../pevent/libparseevent.la
+powertop_LDADD = ../traceevent/libtraceevnet.la
AM_LDFLAGS = $(LIBS) $(NCURSES_LIBS) $(PCIUTILS_LIBS) $(LIBNL_LIBS) $(LIBZ_LIBS) $(PTHREAD_LIBS) $(RESOLV_LIBS)
diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp
index 941bcff..eb0a46c 100644
--- a/src/cpu/cpu.cpp
+++ b/src/cpu/cpu.cpp
@@ -903,7 +903,7 @@ struct power_entry {
void perf_power_bundle::handle_trace_point(void *trace, int cpunr, uint64_t time)
{
struct event_format *event;
- struct record rec; /* holder */
+ struct pevent_record rec; /* holder */
class abstract_cpu *cpu;
int type;
diff --git a/src/perf/perf.h b/src/perf/perf.h
index f361968..ee072ae 100644
--- a/src/perf/perf.h
+++ b/src/perf/perf.h
@@ -27,10 +27,12 @@
#include <iostream>
+
extern "C" {
-#include "../pevent/parse-events.h"
+ #include "../traceevent/event-parse.h"
}
+
using namespace std;
class perf_event {
diff --git a/src/process/do_process.cpp b/src/process/do_process.cpp
index 731fe3e..11e6680 100644
--- a/src/process/do_process.cpp
+++ b/src/process/do_process.cpp
@@ -186,7 +186,7 @@ int dont_blame_me(char *comm)
return 0;
}
-static void dbg_printf_pevent_info(struct event_format *event, struct record *rec)
+static void dbg_printf_pevent_info(struct event_format *event, struct pevent_record *rec)
{
static struct trace_seq s;
@@ -216,7 +216,7 @@ static char * get_pevent_field_str(void *trace, struct event_format *event, stru
void perf_process_bundle::handle_trace_point(void *trace, int cpu, uint64_t time)
{
struct event_format *event;
- struct record rec; /* holder */
+ struct pevent_record rec; /* holder */
struct format_field *field;
unsigned long long val;
int type;
diff --git a/traceevent/.deps/event-parse.Plo b/traceevent/.deps/event-parse.Plo
new file mode 100644
index 0000000..292c4eb
--- /dev/null
+++ b/traceevent/.deps/event-parse.Plo
@@ -0,0 +1,113 @@
+event-parse.lo: event-parse.c /usr/include/stdio.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
+ /usr/include/gnu/stubs-64.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h /usr/include/stdlib.h \
+ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/xlocale.h \
+ /usr/include/sys/types.h /usr/include/time.h /usr/include/sys/select.h \
+ /usr/include/bits/select.h /usr/include/bits/sigset.h \
+ /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+ /usr/include/bits/pthreadtypes.h /usr/include/alloca.h \
+ /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/ctype.h /usr/include/errno.h \
+ /usr/include/bits/errno.h /usr/include/linux/errno.h \
+ /usr/include/asm/errno.h /usr/include/asm-generic/errno.h \
+ /usr/include/asm-generic/errno-base.h event-parse.h /usr/include/regex.h \
+ event-utils.h
+
+/usr/include/stdio.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/bits/waitflags.h:
+
+/usr/include/bits/waitstatus.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/bits/byteswap.h:
+
+/usr/include/xlocale.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+/usr/include/ctype.h:
+
+/usr/include/errno.h:
+
+/usr/include/bits/errno.h:
+
+/usr/include/linux/errno.h:
+
+/usr/include/asm/errno.h:
+
+/usr/include/asm-generic/errno.h:
+
+/usr/include/asm-generic/errno-base.h:
+
+event-parse.h:
+
+/usr/include/regex.h:
+
+event-utils.h:
diff --git a/traceevent/.deps/parse-filter.Plo b/traceevent/.deps/parse-filter.Plo
new file mode 100644
index 0000000..73afcf0
--- /dev/null
+++ b/traceevent/.deps/parse-filter.Plo
@@ -0,0 +1,112 @@
+parse-filter.lo: parse-filter.c /usr/include/stdio.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
+ /usr/include/gnu/stubs-64.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h /usr/include/stdlib.h \
+ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/sys/types.h \
+ /usr/include/time.h /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/sigset.h /usr/include/bits/time.h \
+ /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+ /usr/include/alloca.h /usr/include/string.h /usr/include/xlocale.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h \
+ /usr/include/errno.h /usr/include/bits/errno.h \
+ /usr/include/linux/errno.h /usr/include/asm/errno.h \
+ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \
+ event-parse.h /usr/include/regex.h event-utils.h /usr/include/ctype.h
+
+/usr/include/stdio.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/bits/waitflags.h:
+
+/usr/include/bits/waitstatus.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/bits/byteswap.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/xlocale.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+/usr/include/errno.h:
+
+/usr/include/bits/errno.h:
+
+/usr/include/linux/errno.h:
+
+/usr/include/asm/errno.h:
+
+/usr/include/asm-generic/errno.h:
+
+/usr/include/asm-generic/errno-base.h:
+
+event-parse.h:
+
+/usr/include/regex.h:
+
+event-utils.h:
+
+/usr/include/ctype.h:
diff --git a/traceevent/.deps/parse-utils.Plo b/traceevent/.deps/parse-utils.Plo
new file mode 100644
index 0000000..d699114
--- /dev/null
+++ b/traceevent/.deps/parse-utils.Plo
@@ -0,0 +1,103 @@
+parse-utils.lo: parse-utils.c /usr/include/stdio.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
+ /usr/include/gnu/stubs-64.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h /usr/include/stdlib.h \
+ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/sys/types.h \
+ /usr/include/time.h /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/sigset.h /usr/include/bits/time.h \
+ /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+ /usr/include/alloca.h /usr/include/string.h /usr/include/xlocale.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h \
+ /usr/include/errno.h /usr/include/bits/errno.h \
+ /usr/include/linux/errno.h /usr/include/asm/errno.h \
+ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h
+
+/usr/include/stdio.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/bits/waitflags.h:
+
+/usr/include/bits/waitstatus.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/bits/byteswap.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/xlocale.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+/usr/include/errno.h:
+
+/usr/include/bits/errno.h:
+
+/usr/include/linux/errno.h:
+
+/usr/include/asm/errno.h:
+
+/usr/include/asm-generic/errno.h:
+
+/usr/include/asm-generic/errno-base.h:
diff --git a/traceevent/.deps/trace-seq.Plo b/traceevent/.deps/trace-seq.Plo
new file mode 100644
index 0000000..b3c2e7a
--- /dev/null
+++ b/traceevent/.deps/trace-seq.Plo
@@ -0,0 +1,96 @@
+trace-seq.lo: trace-seq.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
+ /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
+ /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h /usr/include/stdlib.h \
+ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/sys/types.h \
+ /usr/include/time.h /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/sigset.h /usr/include/bits/time.h \
+ /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+ /usr/include/alloca.h /usr/include/string.h /usr/include/xlocale.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h event-parse.h \
+ /usr/include/regex.h event-utils.h /usr/include/ctype.h
+
+/usr/include/stdio.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stdarg.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/bits/waitflags.h:
+
+/usr/include/bits/waitstatus.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/bits/byteswap.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/xlocale.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+event-parse.h:
+
+/usr/include/regex.h:
+
+event-utils.h:
+
+/usr/include/ctype.h:
diff --git a/traceevent/Makefile.am b/traceevent/Makefile.am
new file mode 100644
index 0000000..d3ee608
--- /dev/null
+++ b/traceevent/Makefile.am
@@ -0,0 +1,7 @@
+noinst_LTLIBRARIES = libtraceevnet.la
+libtraceevnet_la_SOURCES = event-parse.c \
+ event-parse.h \
+ event-utils.h \
+ parse-filter.c\
+ parse-utils.c \
+ trace-seq.c
diff --git a/pevent/parse-events.c b/traceevent/event-parse.c
index 58716e9..5f34aa3 100644
--- a/pevent/parse-events.c
+++ b/traceevent/event-parse.c
@@ -1,8 +1,7 @@
/*
- * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rosted <srostedt@redhat.com>
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
- *
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
@@ -15,11 +14,9 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The parts for function graph printing was taken and modified from the
* Linux Kernel that were written by
@@ -35,12 +32,16 @@
#include <ctype.h>
#include <errno.h>
-#include "parse-events.h"
+#include "event-parse.h"
+#include "event-utils.h"
static const char *input_buf;
static unsigned long long input_buf_ptr;
static unsigned long long input_buf_siz;
+static int is_flag_field;
+static int is_symbolic_field;
+
static int show_warning = 1;
#define do_warning(fmt, ...) \
@@ -261,7 +262,7 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
cmdlines[pevent->cmdline_count].comm = strdup(comm);
if (!cmdlines[pevent->cmdline_count].comm)
die("malloc comm");
-
+
if (cmdlines[pevent->cmdline_count].comm)
pevent->cmdline_count++;
@@ -466,8 +467,10 @@ int pevent_register_function(struct pevent *pevent, char *func,
item->mod = NULL;
item->addr = addr;
- pevent->funclist = item;
+ if (!item->func || (mod && !item->mod))
+ die("malloc func");
+ pevent->funclist = item;
pevent->func_count++;
return 0;
@@ -510,12 +513,12 @@ struct printk_list {
static int printk_cmp(const void *a, const void *b)
{
- const struct func_map *fa = a;
- const struct func_map *fb = b;
+ const struct printk_map *pa = a;
+ const struct printk_map *pb = b;
- if (fa->addr < fb->addr)
+ if (pa->addr < pb->addr)
return -1;
- if (fa->addr > fb->addr)
+ if (pa->addr > pb->addr)
return 1;
return 0;
@@ -582,10 +585,13 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
item = malloc_or_die(sizeof(*item));
item->next = pevent->printklist;
- pevent->printklist = item;
item->printk = strdup(fmt);
item->addr = addr;
+ if (!item->printk)
+ die("malloc fmt");
+
+ pevent->printklist = item;
pevent->printk_count++;
return 0;
@@ -615,7 +621,9 @@ static struct event_format *alloc_event(void)
{
struct event_format *event;
- event = malloc_or_die(sizeof(*event));
+ event = malloc(sizeof(*event));
+ if (!event)
+ return NULL;
memset(event, 0, sizeof(*event));
return event;
@@ -625,12 +633,8 @@ static void add_event(struct pevent *pevent, struct event_format *event)
{
int i;
- if (!pevent->events)
- pevent->events = malloc_or_die(sizeof(event));
- else
- pevent->events =
- realloc(pevent->events, sizeof(event) *
- (pevent->nr_events + 1));
+ pevent->events = realloc(pevent->events, sizeof(event) *
+ (pevent->nr_events + 1));
if (!pevent->events)
die("Can not allocate events");
@@ -696,6 +700,10 @@ static void free_arg(struct print_arg *arg)
free_arg(arg->symbol.field);
free_flag_sym(arg->symbol.symbols);
break;
+ case PRINT_HEX:
+ free_arg(arg->hex.field);
+ free_arg(arg->hex.size);
+ break;
case PRINT_TYPE:
free(arg->typecast.type);
free_arg(arg->typecast.item);
@@ -774,6 +782,25 @@ int pevent_peek_char(void)
return __peek_char();
}
+static int extend_token(char **tok, char *buf, int size)
+{
+ char *newtok = realloc(*tok, size);
+
+ if (!newtok) {
+ free(*tok);
+ *tok = NULL;
+ return -1;
+ }
+
+ if (!*tok)
+ strcpy(newtok, buf);
+ else
+ strcat(newtok, buf);
+ *tok = newtok;
+
+ return 0;
+}
+
static enum event_type force_token(const char *str, char **tok);
static enum event_type __read_token(char **tok)
@@ -858,17 +885,10 @@ static enum event_type __read_token(char **tok)
do {
if (i == (BUFSIZ - 1)) {
buf[i] = 0;
- if (*tok) {
- *tok = realloc(*tok, tok_size + BUFSIZ);
- if (!*tok)
- return EVENT_NONE;
- strcat(*tok, buf);
- } else
- *tok = strdup(buf);
+ tok_size += BUFSIZ;
- if (!*tok)
+ if (extend_token(tok, buf, tok_size) < 0)
return EVENT_NONE;
- tok_size += BUFSIZ;
i = 0;
}
last_ch = ch;
@@ -907,17 +927,10 @@ static enum event_type __read_token(char **tok)
while (get_type(__peek_char()) == type) {
if (i == (BUFSIZ - 1)) {
buf[i] = 0;
- if (*tok) {
- *tok = realloc(*tok, tok_size + BUFSIZ);
- if (!*tok)
- return EVENT_NONE;
- strcat(*tok, buf);
- } else
- *tok = strdup(buf);
+ tok_size += BUFSIZ;
- if (!*tok)
+ if (extend_token(tok, buf, tok_size) < 0)
return EVENT_NONE;
- tok_size += BUFSIZ;
i = 0;
}
ch = __read_char();
@@ -926,14 +939,7 @@ static enum event_type __read_token(char **tok)
out:
buf[i] = 0;
- if (*tok) {
- *tok = realloc(*tok, tok_size + i);
- if (!*tok)
- return EVENT_NONE;
- strcat(*tok, buf);
- } else
- *tok = strdup(buf);
- if (!*tok)
+ if (extend_token(tok, buf, tok_size + i + 1) < 0)
return EVENT_NONE;
if (type == EVENT_ITEM) {
@@ -969,7 +975,7 @@ static enum event_type force_token(const char *str, char **tok)
unsigned long long save_input_buf_ptr;
unsigned long long save_input_buf_siz;
enum event_type type;
-
+
/* save off the current input pointers */
save_input_buf = input_buf;
save_input_buf_ptr = input_buf_ptr;
@@ -1254,9 +1260,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
field->flags |= FIELD_IS_POINTER;
if (field->type) {
- field->type = realloc(field->type,
- strlen(field->type) +
- strlen(last_token) + 2);
+ char *new_type;
+ new_type = realloc(field->type,
+ strlen(field->type) +
+ strlen(last_token) + 2);
+ if (!new_type) {
+ free(last_token);
+ goto fail;
+ }
+ field->type = new_type;
strcat(field->type, " ");
strcat(field->type, last_token);
free(last_token);
@@ -1281,6 +1293,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
if (strcmp(token, "[") == 0) {
enum event_type last_type = type;
char *brackets = token;
+ char *new_brackets;
int len;
field->flags |= FIELD_IS_ARRAY;
@@ -1300,9 +1313,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f
len = 1;
last_type = type;
- brackets = realloc(brackets,
- strlen(brackets) +
- strlen(token) + len);
+ new_brackets = realloc(brackets,
+ strlen(brackets) +
+ strlen(token) + len);
+ if (!new_brackets) {
+ free(brackets);
+ goto fail;
+ }
+ brackets = new_brackets;
if (len == 2)
strcat(brackets, " ");
strcat(brackets, token);
@@ -1318,7 +1336,12 @@ static int event_read_fields(struct event_format *event, struct format_field **f
free_token(token);
- brackets = realloc(brackets, strlen(brackets) + 2);
+ new_brackets = realloc(brackets, strlen(brackets) + 2);
+ if (!new_brackets) {
+ free(brackets);
+ goto fail;
+ }
+ brackets = new_brackets;
strcat(brackets, "]");
/* add brackets to type */
@@ -1329,10 +1352,16 @@ static int event_read_fields(struct event_format *event, struct format_field **f
* the format: type [] item;
*/
if (type == EVENT_ITEM) {
- field->type = realloc(field->type,
- strlen(field->type) +
- strlen(field->name) +
- strlen(brackets) + 2);
+ char *new_type;
+ new_type = realloc(field->type,
+ strlen(field->type) +
+ strlen(field->name) +
+ strlen(brackets) + 2);
+ if (!new_type) {
+ free(brackets);
+ goto fail;
+ }
+ field->type = new_type;
strcat(field->type, " ");
strcat(field->type, field->name);
free_token(field->name);
@@ -1340,9 +1369,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
field->name = token;
type = read_token(&token);
} else {
- field->type = realloc(field->type,
- strlen(field->type) +
- strlen(brackets) + 1);
+ char *new_type;
+ new_type = realloc(field->type,
+ strlen(field->type) +
+ strlen(brackets) + 1);
+ if (!new_type) {
+ free(brackets);
+ goto fail;
+ }
+ field->type = new_type;
strcat(field->type, brackets);
}
free(brackets);
@@ -1433,8 +1468,11 @@ static int event_read_fields(struct event_format *event, struct format_field **f
fail:
free_token(token);
fail_expect:
- if (field)
+ if (field) {
+ free(field->type);
+ free(field->name);
free(field);
+ }
return -1;
}
@@ -1711,6 +1749,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
if (set_op_prio(arg) == -1) {
event->flags |= EVENT_FL_FAILED;
+ /* arg->op.op (= token) will be freed at out_free */
+ arg->op.op = NULL;
goto out_free;
}
@@ -1720,10 +1760,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
/* could just be a type pointer */
if ((strcmp(arg->op.op, "*") == 0) &&
type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
+ char *new_atom;
+
if (left->type != PRINT_ATOM)
die("bad pointer type");
- left->atom.atom = realloc(left->atom.atom,
+ new_atom = realloc(left->atom.atom,
strlen(left->atom.atom) + 3);
+ if (!new_atom)
+ goto out_free;
+
+ left->atom.atom = new_atom;
strcat(left->atom.atom, " *");
free(arg->op.op);
*arg = *left;
@@ -1794,6 +1840,16 @@ process_entry(struct event_format *event __unused, struct print_arg *arg,
arg->type = PRINT_FIELD;
arg->field.name = field;
+ if (is_flag_field) {
+ arg->field.field = pevent_find_any_field(event, arg->field.name);
+ arg->field.field->flags |= FIELD_IS_FLAG;
+ is_flag_field = 0;
+ } else if (is_symbolic_field) {
+ arg->field.field = pevent_find_any_field(event, arg->field.name);
+ arg->field.field->flags |= FIELD_IS_SYMBOLIC;
+ is_symbolic_field = 0;
+ }
+
type = read_token(&token);
*tok = token;
@@ -2113,6 +2169,13 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
free_token(token);
type = process_arg(event, arg, &token);
+
+ if (type == EVENT_OP)
+ type = process_op(event, arg, &token);
+
+ if (type == EVENT_ERROR)
+ goto out_free;
+
if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free;
@@ -2123,6 +2186,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
if (value == NULL)
goto out_free;
field->value = strdup(value);
+ if (field->value == NULL)
+ goto out_free;
free_arg(arg);
arg = alloc_arg();
@@ -2136,6 +2201,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
if (value == NULL)
goto out_free;
field->str = strdup(value);
+ if (field->str == NULL)
+ goto out_free;
free_arg(arg);
arg = NULL;
@@ -2237,6 +2304,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
}
static enum event_type
+process_hex(struct event_format *event, struct print_arg *arg, char **tok)
+{
+ struct print_arg *field;
+ enum event_type type;
+ char *token;
+
+ memset(arg, 0, sizeof(*arg));
+ arg->type = PRINT_HEX;
+
+ field = alloc_arg();
+ type = process_arg(event, field, &token);
+
+ if (test_type_token(type, token, EVENT_DELIM, ","))
+ goto out_free;
+
+ arg->hex.field = field;
+
+ free_token(token);
+
+ field = alloc_arg();
+ type = process_arg(event, field, &token);
+
+ if (test_type_token(type, token, EVENT_DELIM, ")"))
+ goto out_free;
+
+ arg->hex.size = field;
+
+ free_token(token);
+ type = read_token_item(tok);
+ return type;
+
+ out_free:
+ free_arg(field);
+ free_token(token);
+ *tok = NULL;
+ return EVENT_ERROR;
+}
+
+static enum event_type
process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
{
struct format_field *field;
@@ -2277,17 +2383,18 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
arg = alloc_arg();
type = process_arg(event, arg, &token);
if (type == EVENT_ERROR)
- goto out_free;
+ goto out_free_arg;
if (!test_type_token(type, token, EVENT_OP, "]"))
- goto out_free;
+ goto out_free_arg;
free_token(token);
type = read_token_item(tok);
return type;
+ out_free_arg:
+ free_arg(arg);
out_free:
- free(arg);
free_token(token);
*tok = NULL;
return EVENT_ERROR;
@@ -2456,12 +2563,18 @@ process_function(struct event_format *event, struct print_arg *arg,
if (strcmp(token, "__print_flags") == 0) {
free_token(token);
+ is_flag_field = 1;
return process_flags(event, arg, tok);
}
if (strcmp(token, "__print_symbolic") == 0) {
free_token(token);
+ is_symbolic_field = 1;
return process_symbols(event, arg, tok);
}
+ if (strcmp(token, "__print_hex") == 0) {
+ free_token(token);
+ return process_hex(event, arg, tok);
+ }
if (strcmp(token, "__get_str") == 0) {
free_token(token);
return process_str(event, arg, tok);
@@ -2515,7 +2628,16 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
}
/* atoms can be more than one token long */
while (type == EVENT_ITEM) {
- atom = realloc(atom, strlen(atom) + strlen(token) + 2);
+ char *new_atom;
+ new_atom = realloc(atom,
+ strlen(atom) + strlen(token) + 2);
+ if (!new_atom) {
+ free(atom);
+ *tok = NULL;
+ free_token(token);
+ return EVENT_ERROR;
+ }
+ atom = new_atom;
strcat(atom, " ");
strcat(atom, token);
free_token(token);
@@ -2656,7 +2778,7 @@ static int event_read_print(struct event_format *event)
token = cat;
goto concat;
}
-
+
if (test_type_token(type, token, EVENT_DELIM, ","))
goto fail;
@@ -2970,6 +3092,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
break;
case PRINT_FLAGS:
case PRINT_SYMBOL:
+ case PRINT_HEX:
break;
case PRINT_TYPE:
val = eval_num_arg(data, size, event, arg->typecast.item);
@@ -3189,11 +3312,13 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
{
struct pevent *pevent = event->pevent;
struct print_flag_sym *flag;
+ struct format_field *field;
unsigned long long val, fval;
unsigned long addr;
char *str;
+ unsigned char *hex;
int print;
- int len;
+ int i, len;
switch (arg->type) {
case PRINT_NULL:
@@ -3203,27 +3328,29 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
print_str_to_seq(s, format, len_arg, arg->atom.atom);
return;
case PRINT_FIELD:
- if (!arg->field.field) {
- arg->field.field = pevent_find_any_field(event, arg->field.name);
- if (!arg->field.field)
+ field = arg->field.field;
+ if (!field) {
+ field = pevent_find_any_field(event, arg->field.name);
+ if (!field)
die("field %s not found", arg->field.name);
+ arg->field.field = field;
}
/* Zero sized fields, mean the rest of the data */
- len = arg->field.field->size ? : size - arg->field.field->offset;
+ len = field->size ? : size - field->offset;
/*
* Some events pass in pointers. If this is not an array
* and the size is the same as long_size, assume that it
* is a pointer.
*/
- if (!(arg->field.field->flags & FIELD_IS_ARRAY) &&
- arg->field.field->size == pevent->long_size) {
- addr = *(unsigned long *)(data + arg->field.field->offset);
+ if (!(field->flags & FIELD_IS_ARRAY) &&
+ field->size == pevent->long_size) {
+ addr = *(unsigned long *)(data + field->offset);
trace_seq_printf(s, "%lx", addr);
break;
}
str = malloc_or_die(len + 1);
- memcpy(str, data + arg->field.field->offset, len);
+ memcpy(str, data + field->offset, len);
str[len] = 0;
print_str_to_seq(s, format, len_arg, str);
free(str);
@@ -3256,6 +3383,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
}
}
break;
+ case PRINT_HEX:
+ field = arg->hex.field->field.field;
+ if (!field) {
+ str = arg->hex.field->field.name;
+ field = pevent_find_any_field(event, str);
+ if (!field)
+ die("field %s not found", str);
+ arg->hex.field->field.field = field;
+ }
+ hex = data + field->offset;
+ len = eval_num_arg(data, size, event, arg->hex.size);
+ for (i = 0; i < len; i++) {
+ if (i)
+ trace_seq_putc(s, ' ');
+ trace_seq_printf(s, "%02x", hex[i]);
+ }
+ break;
case PRINT_TYPE:
break;
@@ -3338,6 +3482,10 @@ process_defined_func(struct trace_seq *s, void *data, int size,
string = malloc_or_die(sizeof(*string));
string->next = strings;
string->str = strdup(str.buffer);
+ if (!string->str)
+ die("malloc str");
+
+ args[i] = (unsigned long long)string->str;
strings = string;
trace_seq_destroy(&str);
break;
@@ -3350,6 +3498,7 @@ process_defined_func(struct trace_seq *s, void *data, int size,
break;
}
farg = farg->next;
+ param = param->next;
}
ret = (*func_handle->func)(s, args);
@@ -3441,6 +3590,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
break;
case 2:
vsize = 8;
+ break;
default:
vsize = ls; /* ? */
break;
@@ -3475,6 +3625,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
arg->next = NULL;
arg->type = PRINT_BSTRING;
arg->string.string = strdup(bptr);
+ if (!arg->string.string)
+ break;
bptr += strlen(bptr) + 1;
*next = arg;
next = &arg->next;
@@ -3579,6 +3731,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
}
+static int is_printable_array(char *p, unsigned int len)
+{
+ unsigned int i;
+
+ for (i = 0; i < len && p[i]; i++)
+ if (!isprint(p[i]))
+ return 0;
+ return 1;
+}
+
static void print_event_fields(struct trace_seq *s, void *data, int size,
struct event_format *event)
{
@@ -3598,7 +3760,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
len = offset >> 16;
offset &= 0xffff;
}
- if (field->flags & FIELD_IS_STRING) {
+ if (field->flags & FIELD_IS_STRING &&
+ is_printable_array(data + offset, len)) {
trace_seq_printf(s, "%s", (char *)data + offset);
} else {
trace_seq_puts(s, "ARRAY[");
@@ -3609,6 +3772,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
*((unsigned char *)data + offset + i));
}
trace_seq_putc(s, ']');
+ field->flags &= ~FIELD_IS_STRING;
}
} else {
val = pevent_read_number(event->pevent, data + field->offset,
@@ -3785,14 +3949,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
break;
}
}
- if (pevent->long_size == 8 && ls) {
+ if (pevent->long_size == 8 && ls &&
+ sizeof(long) != 8) {
char *p;
ls = 2;
/* make %l into %ll */
p = strchr(format, 'l');
if (p)
- memmove(p, p+1, strlen(p)+1);
+ memmove(p+1, p, strlen(p)+1);
else if (strcmp(format, "%p") == 0)
strcpy(format, "0x%llx");
}
@@ -3869,15 +4034,14 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
* pevent_data_lat_fmt - parse the data for the latency format
* @pevent: a handle to the pevent
* @s: the trace_seq to write to
- * @data: the raw data to read from
- * @size: currently unused.
+ * @record: the record to read from
*
* This parses out the Latency format (interrupts disabled,
* need rescheduling, in hard/soft interrupt, preempt count
* and lock depth) and places it into the trace_seq.
*/
void pevent_data_lat_fmt(struct pevent *pevent,
- struct trace_seq *s, struct record *record)
+ struct trace_seq *s, struct pevent_record *record)
{
static int check_lock_depth = 1;
static int check_migrate_disable = 1;
@@ -3956,7 +4120,7 @@ void pevent_data_lat_fmt(struct pevent *pevent,
*
* This returns the event id from the @rec.
*/
-int pevent_data_type(struct pevent *pevent, struct record *rec)
+int pevent_data_type(struct pevent *pevent, struct pevent_record *rec)
{
return trace_parse_common_type(pevent, rec->data);
}
@@ -3980,7 +4144,7 @@ struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type
*
* This returns the PID from a raw data.
*/
-int pevent_data_pid(struct pevent *pevent, struct record *rec)
+int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec)
{
return parse_common_pid(pevent, rec->data);
}
@@ -4005,16 +4169,13 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
* pevent_data_comm_from_pid - parse the data into the print format
* @s: the trace_seq to write to
* @event: the handle to the event
- * @cpu: the cpu the event was recorded on
- * @data: the raw data
- * @size: the size of the raw data
- * @nsecs: the timestamp of the event
+ * @record: the record to read from
*
* This parses the raw @data using the given @event information and
* writes the print format into the trace_seq.
*/
void pevent_event_info(struct trace_seq *s, struct event_format *event,
- struct record *record)
+ struct pevent_record *record)
{
int print_pretty = 1;
@@ -4034,21 +4195,22 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event,
}
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
- struct record *record)
+ struct pevent_record *record)
{
static char *spaces = " "; /* 20 spaces */
struct event_format *event;
unsigned long secs;
unsigned long usecs;
+ unsigned long nsecs;
const char *comm;
void *data = record->data;
int type;
int pid;
int len;
+ int p;
secs = record->ts / NSECS_PER_SEC;
- usecs = record->ts - secs * NSECS_PER_SEC;
- usecs = (usecs + 500) / NSECS_PER_USEC;
+ nsecs = record->ts - secs * NSECS_PER_SEC;
if (record->size < 0) {
do_warning("ug! negative record size %d", record->size);
@@ -4073,7 +4235,15 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
} else
trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
- trace_seq_printf(s, " %5lu.%06lu: %s: ", secs, usecs, event->name);
+ if (pevent->flags & PEVENT_NSEC_OUTPUT) {
+ usecs = nsecs;
+ p = 9;
+ } else {
+ usecs = (nsecs + 500) / NSECS_PER_USEC;
+ p = 6;
+ }
+
+ trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name);
/* Space out the event names evenly. */
len = strlen(event->name);
@@ -4279,6 +4449,13 @@ static void print_args(struct print_arg *args)
trace_seq_destroy(&s);
printf(")");
break;
+ case PRINT_HEX:
+ printf("__print_hex(");
+ print_args(args->hex.field);
+ printf(", ");
+ print_args(args->hex.size);
+ printf(")");
+ break;
case PRINT_STRING:
case PRINT_BSTRING:
printf("__get_str(%s)", args->string.string);
@@ -4535,12 +4712,14 @@ int pevent_parse_event(struct pevent *pevent,
if (strcmp(event->name, "bprint") == 0)
event->flags |= EVENT_FL_ISBPRINT;
}
-
+
event->id = event_read_id();
if (event->id < 0)
die("failed to read event id");
event->system = strdup(sys);
+ if (!event->system)
+ die("failed to allocate system");
/* Add pevent to event so that it can be referenced */
event->pevent = pevent;
@@ -4582,6 +4761,11 @@ int pevent_parse_event(struct pevent *pevent,
list = &arg->next;
arg->type = PRINT_FIELD;
arg->field.name = strdup(field->name);
+ if (!arg->field.name) {
+ do_warning("failed to allocate field name");
+ event->flags |= EVENT_FL_FAILED;
+ return -1;
+ }
arg->field.field = field;
}
return 0;
@@ -4601,7 +4785,7 @@ int pevent_parse_event(struct pevent *pevent,
}
int get_field_val(struct trace_seq *s, struct format_field *field,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err)
{
if (!field) {
@@ -4634,7 +4818,7 @@ int get_field_val(struct trace_seq *s, struct format_field *field,
* On failure, it returns NULL.
*/
void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
int *len, int err)
{
struct format_field *field;
@@ -4681,7 +4865,7 @@ void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
* Returns 0 on success -1 on field not found.
*/
int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err)
{
struct format_field *field;
@@ -4706,7 +4890,7 @@ int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
* Returns 0 on success -1 on field not found.
*/
int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err)
{
struct format_field *field;
@@ -4731,7 +4915,7 @@ int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
* Returns 0 on success -1 on field not found.
*/
int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err)
{
struct format_field *field;
@@ -4753,11 +4937,11 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
* @record: The record with the field name.
* @err: print default error if failed.
*
- * Returns: 0 on success, -1 field not fould, or 1 if buffer is full.
+ * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
*/
int pevent_print_num_field(struct trace_seq *s, const char *fmt,
struct event_format *event, const char *name,
- struct record *record, int err)
+ struct pevent_record *record, int err)
{
struct format_field *field = pevent_find_field(event, name);
unsigned long long val;
@@ -4795,11 +4979,12 @@ static void free_func_handle(struct pevent_function_handler *func)
* pevent_register_print_function - register a helper function
* @pevent: the handle to the pevent
* @func: the function to process the helper function
+ * @ret_type: the return type of the helper function
* @name: the name of the helper function
* @parameters: A list of enum pevent_func_arg_type
*
* Some events may have helper functions in the print format arguments.
- * This allows a plugin to dynmically create a way to process one
+ * This allows a plugin to dynamically create a way to process one
* of these functions.
*
* The @parameters is a variable list of pevent_func_arg_type enums that
@@ -4870,12 +5055,13 @@ int pevent_register_print_function(struct pevent *pevent,
}
/**
- * pevent_register_event_handle - register a way to parse an event
+ * pevent_register_event_handler - register a way to parse an event
* @pevent: the handle to the pevent
* @id: the id of the event to register
* @sys_name: the system name the event belongs to
* @event_name: the name of the event
* @func: the function to call to parse the event information
+ * @context: the data to be passed to @func
*
* This function allows a developer to override the parsing of
* a given event. If for some reason the default print format
@@ -4925,6 +5111,11 @@ int pevent_register_event_handler(struct pevent *pevent,
if (sys_name)
handle->sys_name = strdup(sys_name);
+ if ((event_name && !handle->event_name) ||
+ (sys_name && !handle->sys_name)) {
+ die("Failed to allocate event/sys name");
+ }
+
handle->func = func;
handle->next = pevent->handlers;
pevent->handlers = handle;
@@ -5075,5 +5266,5 @@ void pevent_free(struct pevent *pevent)
void pevent_unref(struct pevent *pevent)
{
- pevent_free(pevent);
+ pevent_free(pevent);
}
diff --git a/pevent/parse-events.h b/traceevent/event-parse.h
index 5d5d195..1a486ae 100644
--- a/pevent/parse-events.h
+++ b/traceevent/event-parse.h
@@ -1,8 +1,7 @@
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
- *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
@@ -15,11 +14,9 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#ifndef _PARSE_EVENTS_H
#define _PARSE_EVENTS_H
@@ -42,7 +39,7 @@
#define DEBUG_RECORD 0
#endif
-struct record {
+struct pevent_record {
unsigned long long ts;
unsigned long long offset;
long long missed_events; /* buffer dropped events before */
@@ -52,10 +49,10 @@ struct record {
int cpu;
int ref_count;
int locked; /* Do not free, even if ref_count is zero */
- void *r_private;
+ void *p_private;
#if DEBUG_RECORD
- struct record *prev;
- struct record *next;
+ struct pevent_record *prev;
+ struct pevent_record *next;
long alloc_addr;
#endif
};
@@ -94,7 +91,7 @@ struct pevent;
struct event_format;
typedef int (*pevent_event_handler_func)(struct trace_seq *s,
- struct record *record,
+ struct pevent_record *record,
struct event_format *event,
void *context);
@@ -170,6 +167,8 @@ enum format_flags {
FIELD_IS_STRING = 8,
FIELD_IS_DYNAMIC = 16,
FIELD_IS_LONG = 32,
+ FIELD_IS_FLAG = 64,
+ FIELD_IS_SYMBOLIC = 128,
};
struct format_field {
@@ -212,7 +211,7 @@ struct print_flag_sym {
};
struct print_arg_typecast {
- char *type;
+ char *type;
struct print_arg *item;
};
@@ -227,6 +226,11 @@ struct print_arg_symbol {
struct print_flag_sym *symbols;
};
+struct print_arg_hex {
+ struct print_arg *field;
+ struct print_arg *size;
+};
+
struct print_arg_dynarray {
struct format_field *field;
struct print_arg *index;
@@ -254,6 +258,7 @@ enum print_arg_type {
PRINT_FIELD,
PRINT_FLAGS,
PRINT_SYMBOL,
+ PRINT_HEX,
PRINT_TYPE,
PRINT_STRING,
PRINT_BSTRING,
@@ -271,6 +276,7 @@ struct print_arg {
struct print_arg_typecast typecast;
struct print_arg_flags flags;
struct print_arg_symbol symbol;
+ struct print_arg_hex hex;
struct print_arg_func func;
struct print_arg_string string;
struct print_arg_op op;
@@ -335,6 +341,10 @@ enum pevent_func_arg_type {
PEVENT_FUNC_ARG_MAX_TYPES
};
+enum pevent_flag {
+ PEVENT_NSEC_OUTPUT = 1, /* output in NSECS */
+};
+
struct cmdline;
struct cmdline_list;
struct func_map;
@@ -374,6 +384,7 @@ struct pevent {
struct printk_list *printklist;
unsigned int printk_count;
+
struct event_format **events;
int nr_events;
struct event_format **sort_events;
@@ -385,7 +396,7 @@ struct pevent {
int pid_offset;
int pid_size;
- int pc_offset;
+ int pc_offset;
int pc_size;
int flags_offset;
@@ -398,6 +409,8 @@ struct pevent {
int test_filters;
+ int flags;
+
struct format_field *bprint_ip_field;
struct format_field *bprint_fmt_field;
struct format_field *bprint_buf_field;
@@ -405,27 +418,14 @@ struct pevent {
struct event_handler *handlers;
struct pevent_function_handler *func_handlers;
- int parsing_failures;
-
/* cache */
struct event_format *last_event;
};
-/* Can be overridden */
-void die(const char *fmt, ...);
-void *malloc_or_die(unsigned int size);
-void warning(const char *fmt, ...);
-void pr_stat(const char *fmt, ...);
-void vpr_stat(const char *fmt, va_list ap);
-
-/* Always available */
-void __die(const char *fmt, ...);
-void __warning(const char *fmt, ...);
-void __pr_stat(const char *fmt, ...);
-
-void __vdie(const char *fmt, ...);
-void __vwarning(const char *fmt, ...);
-void __vpr_stat(const char *fmt, ...);
+static inline void pevent_set_flag(struct pevent *pevent, int flag)
+{
+ pevent->flags |= flag;
+}
static inline unsigned short
__data2host2(struct pevent *pevent, unsigned short data)
@@ -504,7 +504,7 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
int pevent_pid_is_registered(struct pevent *pevent, int pid);
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
- struct record *record);
+ struct pevent_record *record);
int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
int long_size);
@@ -513,22 +513,22 @@ int pevent_parse_event(struct pevent *pevent, const char *buf,
unsigned long size, const char *sys);
void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
int *len, int err);
int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err);
int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err);
int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
- const char *name, struct record *record,
+ const char *name, struct pevent_record *record,
unsigned long long *val, int err);
int pevent_print_num_field(struct trace_seq *s, const char *fmt,
struct event_format *event, const char *name,
- struct record *record, int err);
+ struct pevent_record *record, int err);
int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name,
pevent_event_handler_func func, void *context);
@@ -538,8 +538,8 @@ int pevent_register_print_function(struct pevent *pevent,
char *name, ...);
struct format_field *pevent_find_common_field(struct event_format *event, const char *name);
-struct format_field *pevent_find_field(struct event_format *event,const char *name);
-struct format_field *pevent_find_any_field(struct event_format *event,const char *name);
+struct format_field *pevent_find_field(struct event_format *event, const char *name);
+struct format_field *pevent_find_any_field(struct event_format *event, const char *name);
const char *pevent_find_function(struct pevent *pevent, unsigned long long addr);
unsigned long long
@@ -554,13 +554,13 @@ struct event_format *
pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
void pevent_data_lat_fmt(struct pevent *pevent,
- struct trace_seq *s, struct record *record);
-int pevent_data_type(struct pevent *pevent, struct record *rec);
+ struct trace_seq *s, struct pevent_record *record);
+int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type);
-int pevent_data_pid(struct pevent *pevent, struct record *rec);
+int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
void pevent_event_info(struct trace_seq *s, struct event_format *event,
- struct record *record);
+ struct pevent_record *record);
struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type);
struct format_field **pevent_event_common_fields(struct event_format *event);
@@ -780,7 +780,7 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
int pevent_filter_match(struct event_filter *filter,
- struct record *record);
+ struct pevent_record *record);
int pevent_event_filtered(struct event_filter *filter,
int event_id);
@@ -806,4 +806,6 @@ int pevent_filter_copy(struct event_filter *dest, struct event_filter *source);
int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
enum filter_trivial_type type);
-#endif
+int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2);
+
+#endif /* _PARSE_EVENTS_H */
diff --git a/pevent/util.h b/traceevent/event-utils.h
index c725437..0829638 100644
--- a/pevent/util.h
+++ b/traceevent/event-utils.h
@@ -1,7 +1,6 @@
/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
- *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,9 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@@ -26,6 +23,22 @@
#include <ctype.h>
+/* Can be overridden */
+void die(const char *fmt, ...);
+void *malloc_or_die(unsigned int size);
+void warning(const char *fmt, ...);
+void pr_stat(const char *fmt, ...);
+void vpr_stat(const char *fmt, va_list ap);
+
+/* Always available */
+void __die(const char *fmt, ...);
+void __warning(const char *fmt, ...);
+void __pr_stat(const char *fmt, ...);
+
+void __vdie(const char *fmt, ...);
+void __vwarning(const char *fmt, ...);
+void __vpr_stat(const char *fmt, ...);
+
static inline char *strim(char *string)
{
char *ret;
diff --git a/pevent/parse-filter.c b/traceevent/parse-filter.c
index 0ce0122..ad17855 100644
--- a/pevent/parse-filter.c
+++ b/traceevent/parse-filter.c
@@ -1,8 +1,7 @@
/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
- *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
@@ -15,9 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@@ -28,8 +25,8 @@
#include <errno.h>
#include <sys/types.h>
-#include "parse-events.h"
-#include "util.h"
+#include "event-parse.h"
+#include "event-utils.h"
#define COMM "COMM"
@@ -99,7 +96,7 @@ static enum event_type read_token(char **tok)
(strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
pevent_peek_char() == '~') {
/* append it */
- *tok = malloc(3);
+ *tok = malloc_or_die(3);
sprintf(*tok, "%c%c", *token, '~');
free_token(token);
/* Now remove the '~' from the buffer */
@@ -151,17 +148,11 @@ add_filter_type(struct event_filter *filter, int id)
if (filter_type)
return filter_type;
- if (!filter->filters)
- filter->event_filters =
- malloc_or_die(sizeof(*filter->event_filters));
- else {
- filter->event_filters =
- realloc(filter->event_filters,
- sizeof(*filter->event_filters) *
- (filter->filters + 1));
- if (!filter->event_filters)
- die("Could not allocate filter");
- }
+ filter->event_filters = realloc(filter->event_filters,
+ sizeof(*filter->event_filters) *
+ (filter->filters + 1));
+ if (!filter->event_filters)
+ die("Could not allocate filter");
for (i = 0; i < filter->filters; i++) {
if (filter->event_filters[i].event_id > id)
@@ -328,9 +319,8 @@ static void free_events(struct event_list *events)
}
static struct filter_arg *
-create_arg_item(struct event_format *event,
- const char *token, enum filter_arg_type type,
- char **error_str)
+create_arg_item(struct event_format *event, const char *token,
+ enum event_type type, char **error_str)
{
struct format_field *field;
struct filter_arg *arg;
@@ -1484,7 +1474,7 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
{
struct filter_type *filter_type;
int count = 0;
- int *ids;
+ int *ids = NULL;
int i;
if (!filter->filters)
@@ -1508,10 +1498,8 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
default:
break;
}
- if (count)
- ids = realloc(ids, sizeof(*ids) * (count + 1));
- else
- ids = malloc(sizeof(*ids));
+
+ ids = realloc(ids, sizeof(*ids) * (count + 1));
if (!ids)
die("Can't allocate ids");
ids[count++] = filter_type->event_id;
@@ -1564,10 +1552,10 @@ int pevent_filter_event_has_trivial(struct event_filter *filter,
}
static int test_filter(struct event_format *event,
- struct filter_arg *arg, struct record *record);
+ struct filter_arg *arg, struct pevent_record *record);
static const char *
-get_comm(struct event_format *event, struct record *record)
+get_comm(struct event_format *event, struct pevent_record *record)
{
const char *comm;
int pid;
@@ -1579,7 +1567,7 @@ get_comm(struct event_format *event, struct record *record)
static unsigned long long
get_value(struct event_format *event,
- struct format_field *field, struct record *record)
+ struct format_field *field, struct pevent_record *record)
{
unsigned long long val;
@@ -1588,7 +1576,7 @@ get_value(struct event_format *event,
const char *name;
name = get_comm(event, record);
- return (unsigned long long)name;
+ return (unsigned long)name;
}
pevent_read_number_field(field, record->data, &val);
@@ -1610,10 +1598,10 @@ get_value(struct event_format *event,
}
static unsigned long long
-get_arg_value(struct event_format *event, struct filter_arg *arg, struct record *record);
+get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record);
static unsigned long long
-get_exp_value(struct event_format *event, struct filter_arg *arg, struct record *record)
+get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
{
unsigned long long lval, rval;
@@ -1659,7 +1647,7 @@ get_exp_value(struct event_format *event, struct filter_arg *arg, struct record
}
static unsigned long long
-get_arg_value(struct event_format *event, struct filter_arg *arg, struct record *record)
+get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
{
switch (arg->type) {
case FILTER_ARG_FIELD:
@@ -1680,7 +1668,7 @@ get_arg_value(struct event_format *event, struct filter_arg *arg, struct record
}
static int test_num(struct event_format *event,
- struct filter_arg *arg, struct record *record)
+ struct filter_arg *arg, struct pevent_record *record)
{
unsigned long long lval, rval;
@@ -1712,7 +1700,7 @@ static int test_num(struct event_format *event,
}
}
-static const char *get_field_str(struct filter_arg *arg, struct record *record)
+static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
{
struct event_format *event;
struct pevent *pevent;
@@ -1755,7 +1743,7 @@ static const char *get_field_str(struct filter_arg *arg, struct record *record)
}
static int test_str(struct event_format *event,
- struct filter_arg *arg, struct record *record)
+ struct filter_arg *arg, struct pevent_record *record)
{
const char *val;
@@ -1785,7 +1773,7 @@ static int test_str(struct event_format *event,
}
static int test_op(struct event_format *event,
- struct filter_arg *arg, struct record *record)
+ struct filter_arg *arg, struct pevent_record *record)
{
switch (arg->op.type) {
case FILTER_OP_AND:
@@ -1806,7 +1794,7 @@ static int test_op(struct event_format *event,
}
static int test_filter(struct event_format *event,
- struct filter_arg *arg, struct record *record)
+ struct filter_arg *arg, struct pevent_record *record)
{
switch (arg->type) {
case FILTER_ARG_BOOLEAN:
@@ -1871,7 +1859,7 @@ int pevent_event_filtered(struct event_filter *filter,
* -2 - if no filters exist
*/
int pevent_filter_match(struct event_filter *filter,
- struct record *record)
+ struct pevent_record *record)
{
struct pevent *pevent = filter->pevent;
struct filter_type *filter_type;
@@ -2030,11 +2018,13 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
char *lstr;
char *rstr;
char *op;
- char *str;
+ char *str = NULL;
int len;
lstr = arg_to_str(filter, arg->exp.left);
rstr = arg_to_str(filter, arg->exp.right);
+ if (!lstr || !rstr)
+ goto out;
switch (arg->exp.type) {
case FILTER_EXP_ADD:
@@ -2074,6 +2064,7 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
str = malloc_or_die(len);
snprintf(str, len, "%s %s %s", lstr, op, rstr);
+out:
free(lstr);
free(rstr);
@@ -2090,6 +2081,8 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
lstr = arg_to_str(filter, arg->num.left);
rstr = arg_to_str(filter, arg->num.right);
+ if (!lstr || !rstr)
+ goto out;
switch (arg->num.type) {
case FILTER_CMP_EQ:
@@ -2126,6 +2119,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
break;
}
+out:
free(lstr);
free(rstr);
return str;
@@ -2276,7 +2270,12 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil
/* The best way to compare complex filters is with strings */
str1 = arg_to_str(filter1, filter_type1->filter);
str2 = arg_to_str(filter2, filter_type2->filter);
- result = strcmp(str1, str2) != 0;
+ if (str1 && str2)
+ result = strcmp(str1, str2) != 0;
+ else
+ /* bail out if allocation fails */
+ result = 1;
+
free(str1);
free(str2);
if (result)
@@ -2287,3 +2286,4 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil
return 0;
return 1;
}
+
diff --git a/pevent/parse-utils.c b/traceevent/parse-utils.c
index f023a13..f023a13 100644
--- a/pevent/parse-utils.c
+++ b/traceevent/parse-utils.c
diff --git a/pevent/trace-seq.c b/traceevent/trace-seq.c
index 7bebb5d..b1ccc92 100644
--- a/pevent/trace-seq.c
+++ b/traceevent/trace-seq.c
@@ -1,7 +1,6 @@
/*
* Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
- *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,9 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@@ -26,7 +23,8 @@
#include <string.h>
#include <stdarg.h>
-#include "parse-events.h"
+#include "event-parse.h"
+#include "event-utils.h"
/*
* The TRACE_SEQ_POISON is to catch the use of using