From 57863623329c5f01abe64f3feaf9bdb26c31ce6a Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Thu, 2 Jul 2020 14:53:54 -0400 Subject: tools lib traceevent: Add offset option for function plugin When the offset option is set for the function plugin enabled, it will display the offset of the functions along with their names. This helps in finding exactly where a function was called by its parent. trace-cmd report -O parent -O offset [..] rcuc/163-1330 [163] 740.653251: function: _raw_spin_lock+0x0 <-- rcu_cpu_kthread+0x4d8 Link: http://lore.kernel.org/linux-trace-devel/20200702174950.123454-2-tz.stoyanov@gmail.com Signed-off-by: Steven Rostedt (VMware) [ Ported from trace-cmd.git ] Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/lkml/20200702185704.986181512@goodmis.org Signed-off-by: Tzvetomir Stoyanov (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/plugins/plugin_function.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'tools/lib/traceevent/plugins/plugin_function.c') diff --git a/tools/lib/traceevent/plugins/plugin_function.c b/tools/lib/traceevent/plugins/plugin_function.c index 7770fcb78e0f..cafddd6be983 100644 --- a/tools/lib/traceevent/plugins/plugin_function.c +++ b/tools/lib/traceevent/plugins/plugin_function.c @@ -49,6 +49,13 @@ struct tep_plugin_option plugin_options[] = "Try to show function call indents, based on parents", .set = 1, }, + { + .name = "offset", + .plugin_alias = "ftrace", + .description = + "Show function names as well as their offsets", + .set = 0, + }, { .name = NULL, } @@ -56,6 +63,7 @@ struct tep_plugin_option plugin_options[] = static struct tep_plugin_option *ftrace_parent = &plugin_options[0]; static struct tep_plugin_option *ftrace_indent = &plugin_options[1]; +static struct tep_plugin_option *ftrace_offset = &plugin_options[2]; static void add_child(struct func_stack *stack, const char *child, int pos) { @@ -123,6 +131,18 @@ static int add_and_get_index(const char *parent, const char *child, int cpu) return 0; } +static void show_function(struct trace_seq *s, struct tep_handle *tep, + const char *func, unsigned long long function) +{ + unsigned long long offset; + + trace_seq_printf(s, "%s", func); + if (ftrace_offset->set) { + offset = tep_find_function_address(tep, function); + trace_seq_printf(s, "+0x%x ", (int)(function - offset)); + } +} + static int function_handler(struct trace_seq *s, struct tep_record *record, struct tep_event *event, void *context) { @@ -149,14 +169,14 @@ static int function_handler(struct trace_seq *s, struct tep_record *record, trace_seq_printf(s, "%*s", index*3, ""); if (func) - trace_seq_printf(s, "%s", func); + show_function(s, tep, func, function); else trace_seq_printf(s, "0x%llx", function); if (ftrace_parent->set) { trace_seq_printf(s, " <-- "); if (parent) - trace_seq_printf(s, "%s", parent); + show_function(s, tep, parent, pfunction); else trace_seq_printf(s, "0x%llx", pfunction); } -- cgit From 0dfceeffae187ace521333f2986673690a810fc6 Mon Sep 17 00:00:00 2001 From: "Tzvetomir Stoyanov (VMware)" Date: Thu, 2 Jul 2020 14:53:56 -0400 Subject: tools lib traceevent: Move kernel_stack event handler to "function" plugin. The "kernel_stack" event handler does not depend on any trace-cmd context, it can be used aside from the application. The code is moved to libtraceevent "function" plugin. Link: http://lore.kernel.org/linux-trace-devel/20190726124308.18735-2-tz.stoyanov@gmail.com Link: http://lore.kernel.org/linux-trace-devel/20200702174950.123454-4-tz.stoyanov@gmail.com Signed-off-by: Tzvetomir Stoyanov (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/lkml/20200702185705.284789930@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/plugins/plugin_function.c | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'tools/lib/traceevent/plugins/plugin_function.c') diff --git a/tools/lib/traceevent/plugins/plugin_function.c b/tools/lib/traceevent/plugins/plugin_function.c index cafddd6be983..c7d321968f39 100644 --- a/tools/lib/traceevent/plugins/plugin_function.c +++ b/tools/lib/traceevent/plugins/plugin_function.c @@ -184,11 +184,52 @@ static int function_handler(struct trace_seq *s, struct tep_record *record, return 0; } +static int +trace_stack_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + struct tep_format_field *field; + unsigned long long addr; + const char *func; + int long_size; + void *data = record->data; + + field = tep_find_any_field(event, "caller"); + if (!field) { + trace_seq_printf(s, "", "caller"); + return 0; + } + + trace_seq_puts(s, "\n"); + + long_size = tep_get_long_size(event->tep); + + for (data += field->offset; data < record->data + record->size; + data += long_size) { + addr = tep_read_number(event->tep, data, long_size); + + if ((long_size == 8 && addr == (unsigned long long)-1) || + ((int)addr == -1)) + break; + + func = tep_find_function(event->tep, addr); + if (func) + trace_seq_printf(s, "=> %s (%llx)\n", func, addr); + else + trace_seq_printf(s, "=> %llx\n", addr); + } + + return 0; +} + int TEP_PLUGIN_LOADER(struct tep_handle *tep) { tep_register_event_handler(tep, -1, "ftrace", "function", function_handler, NULL); + tep_register_event_handler(tep, -1, "ftrace", "kernel_stack", + trace_stack_handler, NULL); + tep_plugin_add_options("ftrace", plugin_options); return 0; -- cgit From 9b8179b38ba29c0c8fbfa09b2fe685edca0f6061 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Thu, 2 Jul 2020 14:53:57 -0400 Subject: tools lib traceevent: Add builtin handler for trace_marker_raw When something is written into trace_marker_raw, it goes in as a binary. But the printk_fmt() of the event that is created (raw_data)'s format file only prints the first byte of data: print fmt: "id:%04x %08x", REC->id, (int)REC->buf[0] This is not very useful if we want to see the full data output. Implement the processing of the raw_data event like it is in the kernel. Link: http://lore.kernel.org/linux-trace-devel/20200702174950.123454-5-tz.stoyanov@gmail.com Signed-off-by: Steven Rostedt (VMware) [ Ported from trace-cmd.git ] Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/lkml/20200702185705.445969275@goodmis.org Signed-off-by: Tzvetomir Stoyanov (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/plugins/plugin_function.c | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'tools/lib/traceevent/plugins/plugin_function.c') diff --git a/tools/lib/traceevent/plugins/plugin_function.c b/tools/lib/traceevent/plugins/plugin_function.c index c7d321968f39..7e8e29b43d1c 100644 --- a/tools/lib/traceevent/plugins/plugin_function.c +++ b/tools/lib/traceevent/plugins/plugin_function.c @@ -222,6 +222,44 @@ trace_stack_handler(struct trace_seq *s, struct tep_record *record, return 0; } +static int +trace_raw_data_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + struct tep_format_field *field; + unsigned long long id; + int long_size; + void *data = record->data; + + if (tep_get_field_val(s, event, "id", record, &id, 1)) + return trace_seq_putc(s, '!'); + + trace_seq_printf(s, "# %llx", id); + + field = tep_find_any_field(event, "buf"); + if (!field) { + trace_seq_printf(s, "", "buf"); + return 0; + } + + long_size = tep_get_long_size(event->tep); + + for (data += field->offset; data < record->data + record->size; + data += long_size) { + int size = sizeof(long); + int left = (record->data + record->size) - data; + int i; + + if (size > left) + size = left; + + for (i = 0; i < size; i++) + trace_seq_printf(s, " %02x", *(unsigned char *)(data + i)); + } + + return 0; +} + int TEP_PLUGIN_LOADER(struct tep_handle *tep) { tep_register_event_handler(tep, -1, "ftrace", "function", @@ -230,6 +268,9 @@ int TEP_PLUGIN_LOADER(struct tep_handle *tep) tep_register_event_handler(tep, -1, "ftrace", "kernel_stack", trace_stack_handler, NULL); + tep_register_event_handler(tep, -1, "ftrace", "raw_data", + trace_raw_data_handler, NULL); + tep_plugin_add_options("ftrace", plugin_options); return 0; -- cgit From 4e59ab93e2f4ace864467c946286ea353d8eeeba Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Thu, 2 Jul 2020 14:53:58 -0400 Subject: tools lib traceevent: Change to SPDX License format Replaced COPYING with a description of how the SPDX identifiers are used. Added a GPL-2.0 and LGPL-2.1 license file in the new LICENSES directory. Then removed all the license templates from the source files and replaced them with the corresponding SPDX identifier. Link: http://lore.kernel.org/linux-trace-devel/20200702174950.123454-6-tz.stoyanov@gmail.com Signed-off-by: Steven Rostedt (VMware) [ Ported from trace-cmd.git ] Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/lkml/20200702185705.601167185@goodmis.org Signed-off-by: Tzvetomir Stoyanov (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/plugins/plugin_function.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'tools/lib/traceevent/plugins/plugin_function.c') diff --git a/tools/lib/traceevent/plugins/plugin_function.c b/tools/lib/traceevent/plugins/plugin_function.c index 7e8e29b43d1c..807b16e1bf0f 100644 --- a/tools/lib/traceevent/plugins/plugin_function.c +++ b/tools/lib/traceevent/plugins/plugin_function.c @@ -1,21 +1,6 @@ +// SPDX-License-Identifier: LGPL-2.1 /* * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * 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; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include #include -- cgit