Hey guys, not sure how I got on this discussion site but can someone please remove me from it, thanks!!!
Robbie On Jan 19, 2011, at 3:31 PM, Mathieu Desnoyers <[email protected]> wrote: > * Vincent Attard ([email protected]) wrote: >> This new plugin prints a formated output of each events in a trace. The >> output format is defined as a parameter with printf like syntax.It provides >> a default format easy to read and the original textDump format for backward >> compatibility. >> Updated: Use glib functions for solving buffer overflow problem and correct >> indentation. Add another format called "strace-like". >> >> Signed-off-by: Vincent Attard <[email protected]> >> Reviewed-by: Yannick Brosseau <[email protected]> >> --- >> lttv/modules/text/Makefile.am | 3 +- >> lttv/modules/text/formattedDump.c | 380 >> +++++++++++++++++++++++++++++++++++++ >> 2 files changed, 382 insertions(+), 1 deletions(-) >> create mode 100644 lttv/modules/text/formattedDump.c >> >> diff --git a/lttv/modules/text/Makefile.am b/lttv/modules/text/Makefile.am >> index 29e8990..4f11cb6 100644 >> --- a/lttv/modules/text/Makefile.am >> +++ b/lttv/modules/text/Makefile.am >> @@ -3,7 +3,7 @@ AM_LDFLAGS = $(MODULE_LDFLAGS) >> >> libdir = ${lttvplugindir} >> >> -lib_LTLIBRARIES = libtextDump.la libbatchAnalysis.la libtextFilter.la >> libprecomputeState.la libdepanalysis.la libsync_chain_batch.la >> +lib_LTLIBRARIES = libtextDump.la libbatchAnalysis.la libtextFilter.la >> libprecomputeState.la libdepanalysis.la libsync_chain_batch.la >> libformattedDump.la >> >> libtextDump_la_SOURCES = textDump.c >> libbatchAnalysis_la_SOURCES = batchAnalysis.c >> @@ -11,6 +11,7 @@ libtextFilter_la_SOURCES = textFilter.c >> libprecomputeState_la_SOURCES = precomputeState.c >> libdepanalysis_la_SOURCES = depanalysis.c sstack.c >> libsync_chain_batch_la_SOURCES = sync_chain_batch.c >> +libformattedDump_la_SOURCES = formattedDump.c >> >> noinst_HEADERS = \ >> batchanalysis.h \ >> diff --git a/lttv/modules/text/formattedDump.c >> b/lttv/modules/text/formattedDump.c >> new file mode 100644 >> index 0000000..fa3fe53 >> --- /dev/null >> +++ b/lttv/modules/text/formattedDump.c >> @@ -0,0 +1,380 @@ > > /* > * > > comments. > >> +/* This file is part of the Linux Trace Toolkit viewer >> + * Copyright (C) 2003-2004 Michel Dagenais >> + * 2005 Mathieu Desnoyers >> + * 2011 Vincent Attard <[email protected]> >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License Version 2 as >> + * published by the Free Software Foundation; >> + * >> + * 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 General Public License for more details. >> + * >> + * You should have received a copy of the GNU General Public License >> + * along with this program; if not, write to the Free Software >> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, >> + * MA 02111-1307, USA. >> + */ >> + >> +/* >> + * Formatted dump plugin prints a formatted output of each events in a >> trace. >> + * The output format is defined as a parameter. It provides a default format >> + * easy to read, a "strace-like" format and the original textDump format for >> + * backward compatibility. >> + */ >> + >> +#ifdef HAVE_CONFIG_H >> +#include <config.h> >> +#endif >> + >> +#include <lttv/lttv.h> >> +#include <lttv/option.h> >> +#include <lttv/module.h> >> +#include <lttv/hook.h> >> +#include <lttv/attribute.h> >> +#include <lttv/iattribute.h> >> +#include <lttv/stats.h> >> +#include <lttv/filter.h> >> +#include <lttv/print.h> >> +#include <ltt/ltt.h> >> +#include <ltt/event.h> >> +#include <ltt/trace.h> >> +#include <stdio.h> >> +#include <inttypes.h> >> +#include <string.h> >> +#include <stdlib.h> >> + >> +static gboolean a_no_field_names; >> +static gboolean a_state; >> +static gboolean a_text; >> +static gboolean a_strace; >> + >> +static char *a_file_name = NULL; >> +static char *a_format = NULL; >> + >> +static LttvHooks *before_traceset; >> +static LttvHooks *event_hook; >> + >> +static const char default_format[] = >> + "channel:%c event:%e timestamp:%t elapsed:%l cpu:%u pid:%d ppid:%i " >> + "tgpid:%g process:%p brand:%b state:%a payload:{ %m }"; >> +static const char textDump_format[] = >> + "%c.%e: %s.%n (%r/%c_%u), %d, %g, %p, %b, %i, %y, %a { %m }"; >> +static const char strace_format[] = "%e(%m) %s.%n"; >> + >> +static FILE *a_file; >> + >> +static GString *a_string; >> + >> +static gboolean open_output_file(void *hook_data, void *call_data) >> +{ >> + g_info("Open the output file"); >> + if (a_file_name == NULL) { >> + a_file = stdout; >> + } else { >> + a_file = fopen(a_file_name, "w"); >> + } >> + if (a_file == NULL) { >> + g_error("cannot open file %s", a_file_name); >> + } >> + return FALSE; >> +} >> + >> +static int write_event_content(void *hook_data, void *call_data) >> +{ >> + gboolean result; >> + >> + LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); >> + >> + LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; >> + >> + LttvTracefileState *tfs = (LttvTracefileState *)call_data; >> + >> + LttEvent *e; >> + >> + LttvAttributeValue value_filter; >> + >> + LttvFilter *filter; >> + >> + guint cpu = tfs->cpu; >> + LttvTraceState *ts = (LttvTraceState *)tfc->t_context; >> + LttvProcessState *process = ts->running_process[cpu]; >> + >> + e = ltt_tracefile_get_event(tfc->tf); >> + >> + result = lttv_iattribute_find_by_path(attributes, "filter/lttv_filter", >> + LTTV_POINTER, &value_filter); >> + g_assert(result); >> + filter = (LttvFilter *)*(value_filter.v_pointer); >> + >> + /* call to the filter if available */ >> + if (filter->head != NULL) { >> + if (!lttv_filter_tree_parse(filter->head, e, tfc->tf, >> + tfc->t_context->t, tfc, NULL, NULL)) { >> + return FALSE; > > indentation problem. > >> + } >> + } >> + >> + lttv_event_to_string(e, a_string, TRUE, !a_no_field_names, tfs); >> + >> + if (a_state) { >> + g_string_append_printf(a_string, "%s ", >> + g_quark_to_string(process->state->s)); >> + } >> + >> + g_string_append_printf(a_string, "\n"); >> + >> + fputs(a_string->str, a_file); >> + return FALSE; >> +} >> + >> +void lttv_event_to_string(LttEvent *e, GString *string_buffer, gboolean >> mandatory_fields, >> + gboolean field_names, LttvTracefileState *tfs) >> +{ >> + struct marker_field *field; >> + struct marker_info *info; >> + LttTime time; >> + >> + static LttTime time_prev = {0, 0}; >> + /* >> + * TODO: >> + * Added this static value into state.c and reset each time you do a >> + * seek for using it in the GUI. >> + */ >> + LttTime elapse; >> + const char *fmt; >> + int i; >> + >> + guint cpu = tfs->cpu; >> + LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context; >> + LttvProcessState *process = ts->running_process[cpu]; >> + >> + info = marker_get_info_from_id(tfs->parent.tf->mdata, e->event_id); >> + if (mandatory_fields) { >> + time = ltt_event_time(e); >> + /* Calculate elapsed time between current and previous event */ >> + if (time_prev.tv_sec == 0 && time_prev.tv_nsec == 0) { >> + time_prev = ltt_event_time(e); >> + elapse.tv_sec = 0; >> + elapse.tv_nsec = 0; >> + /* >> + * TODO: >> + * Keep in mind that you should add the ability to restore the >> previous >> + * event time to state.c if you want to reuse this code into the >> GUI. >> + */ > > indent problem. > >> + } else { >> + elapse = ltt_time_sub(time, time_prev); >> + time_prev = time; >> + } >> + } >> + if (a_text) { >> + /* textDump format (used with -T command option) */ >> + fmt = textDump_format; >> + } else if (a_strace) { >> + /* strace-like format (used with -S command option) */ >> + fmt = strace_format; >> + } else if (!a_format) { >> + /* Default format (used if no option) */ >> + fmt = default_format; >> + } else { >> + /* >> + * formattedDump format >> + * (used with -F command option following by the desired format) >> + */ >> + fmt = a_format; >> + } >> + >> + g_string_set_size(string_buffer, 0); >> + /* >> + * Switch case: >> + * all '%-' are replaced by the desired value in 'string_buffer' >> + */ >> + int len; > > local variables should be declared at the beginning of a block > (beginning of function or beginning of { } block), never within the > function code. > >> + len = strlen(fmt); >> + for (i = 0; i < len; i++) { >> + if (fmt[i] == '%') { >> + switch (fmt[++i]) { >> + case 't': >> + g_string_append_printf(string_buffer, >> + "%ld:%02ld:%02ld.%09ld", > > please remove some tabs here. > >> + time.tv_sec/3600, >> + (time.tv_sec%3600)/60, >> + time.tv_sec%60, >> + time.tv_nsec); >> + break; >> + case 'c': >> + g_string_append(string_buffer, >> + >> g_quark_to_string(ltt_tracefile_name(tfs->parent.tf))); >> + break; >> + case 'e': >> + g_string_append(string_buffer, >> + g_quark_to_string(info->name)); >> + break; >> + case 'd': >> + g_string_append_printf(string_buffer, "%u", process->pid); >> + break; >> + case 's': >> + g_string_append_printf(string_buffer, "%ld", time.tv_sec); >> + break; >> + case 'n': >> + g_string_append_printf(string_buffer, "%ld", time.tv_nsec); >> + break; >> + case 'i': >> + g_string_append_printf(string_buffer, "%u", process->ppid); >> + break; >> + case 'g': >> + g_string_append_printf(string_buffer, "%u", process->tgid); >> + break; >> + case 'p': >> + g_string_append(string_buffer, >> + g_quark_to_string(process->name)); >> + break; >> + case 'b': >> + g_string_append_printf(string_buffer, "%u", process->brand); >> + break; >> + case 'u': >> + g_string_append_printf(string_buffer, "%u", cpu); >> + break; >> + case 'l': >> + g_string_append_printf(string_buffer, "%ld.%09ld", >> + elapse.tv_sec, elapse.tv_nsec); >> + break; >> + case 'a': >> + g_string_append(string_buffer, >> + g_quark_to_string(process->state->t)); >> + break; >> + case 'm': >> + { >> + /* >> + * Get and print markers and tracepoints fields into >> + * 'string_buffer' >> + */ >> + if (marker_get_num_fields(info) == 0) >> + break; >> + for (field = marker_get_field(info, 0); >> + field != marker_get_field(info, >> marker_get_num_fields(info)); >> + field++) { >> + if (field != marker_get_field(info, 0)) { >> + g_string_append(string_buffer, ", "); >> + } >> + >> + lttv_print_field(e, field, string_buffer, >> field_names, tfs); >> + } >> + } >> + break; >> + case 'r': >> + g_string_append(string_buffer, g_quark_to_string( >> + >> ltt_trace_name(ltt_tracefile_get_trace(tfs->parent.tf)))); >> + break; >> + case '%': >> + g_string_append_c(string_buffer, '%'); >> + break; >> + case 'y': >> + g_string_append_printf(string_buffer, "0x%" PRIx64, >> + process->current_function); >> + break; >> + } >> + } else { >> + /* Copy every character if not equals to '%' */ > > "if not equal" > >> + g_string_append_c(string_buffer, fmt[i]); >> + } >> + } >> +} >> + >> +static void init() >> +{ >> + gboolean result; >> + >> + LttvAttributeValue value; >> + >> + LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); >> + >> + g_info("Init formattedDump.c"); >> + >> + a_string = g_string_new(""); >> + >> + a_file_name = NULL; >> + lttv_option_add("output", 'o', >> + "output file where the text is written", >> + "file name", >> + LTTV_OPT_STRING, &a_file_name, NULL, NULL); >> + >> + a_text = FALSE; >> + lttv_option_add("text", 'T', > > indent problem. > >> + "output the textDump format", >> + "", >> + LTTV_OPT_NONE, &a_text, NULL, NULL); >> + >> + a_strace = FALSE; >> + lttv_option_add("strace", 'S', > > indent problem. > > Thanks, > > Mathieu > >> + "output a \"strace-like\" format", >> + "", >> + LTTV_OPT_NONE, &a_strace, NULL, NULL); >> + >> + a_format = NULL; >> + lttv_option_add("format", 'F', >> + "output the desired format\n" >> + " FORMAT controls the output. Interpreted sequences >> are:\n" >> + "\n" >> + " %c channel name\n" >> + " %p process name\n" >> + " %e event name\n" >> + " %r path to trace\n" >> + " %t timestamp (e.g., 2:08:54.025684145)\n" >> + " %s seconds\n" >> + " %n nanoseconds\n" >> + " %l elapsed time with the previous event\n" >> + " %d pid\n" >> + " %i ppid\n" >> + " %g tgid\n" >> + " %u cpu\n" >> + " %b brand\n" >> + " %a state\n" >> + " %y memory address\n" >> + " %m markers and tracepoints fields\n", >> + "format string (e.g., \"channel:%c event:%e process:%p\")", >> + LTTV_OPT_STRING, &a_format, NULL, NULL); >> + >> + result = lttv_iattribute_find_by_path(attributes, "hooks/event", >> + LTTV_POINTER, &value); >> + g_assert(result); >> + event_hook = *(value.v_pointer); >> + g_assert(event_hook); >> + lttv_hooks_add(event_hook, write_event_content, NULL, >> LTTV_PRIO_DEFAULT); >> + >> + result = lttv_iattribute_find_by_path(attributes, >> "hooks/traceset/before", >> + LTTV_POINTER, &value); >> + g_assert(result); >> + before_traceset = *(value.v_pointer); >> + g_assert(before_traceset); >> + lttv_hooks_add(before_traceset, open_output_file, NULL, >> + LTTV_PRIO_DEFAULT); >> + >> +} >> + >> +static void destroy() >> +{ >> + g_info("Destroy formattedDump"); >> + >> + lttv_option_remove("format"); >> + >> + lttv_option_remove("output"); >> + >> + lttv_option_remove("text"); >> + >> + lttv_option_remove("strace"); >> + >> + g_string_free(a_string, TRUE); >> + >> + lttv_hooks_remove_data(event_hook, write_event_content, NULL); >> + >> + lttv_hooks_remove_data(before_traceset, open_output_file, NULL); >> + >> +} >> + >> + >> +LTTV_MODULE("formattedDump", "Print events with desired format in a file", >> + "Produce a detailed formatted text printout of a trace", >> + init, destroy, "batchAnalysis", "option") >> -- >> 1.7.0.4 >> >> >> _______________________________________________ >> ltt-dev mailing list >> [email protected] >> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev >> > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > ltt-dev mailing list > [email protected] > http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev _______________________________________________ ltt-dev mailing list [email protected] http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
