diff options
-rw-r--r-- | Android.mk | 15 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | pevent/Makefile.am | 5 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/cpu/cpu.cpp | 2 | ||||
-rw-r--r-- | src/perf/perf.h | 4 | ||||
-rw-r--r-- | src/process/do_process.cpp | 4 | ||||
-rw-r--r-- | traceevent/.deps/event-parse.Plo | 113 | ||||
-rw-r--r-- | traceevent/.deps/parse-filter.Plo | 112 | ||||
-rw-r--r-- | traceevent/.deps/parse-utils.Plo | 103 | ||||
-rw-r--r-- | traceevent/.deps/trace-seq.Plo | 96 | ||||
-rw-r--r-- | traceevent/Makefile.am | 7 | ||||
-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
@@ -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 |