📄 ptt_view.c
字号:
/* Copyright (C) 2004,2005,2006 Bull S.A. * * This library 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; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <assert.h>#include "types.h"#include "modules.h"extern ptt_event_data_t ptt_event_array[];extern struct export export_paje;extern struct export export_raw;extern struct export export_text;extern struct give_name give_name;extern struct read_trace read_trace;extern struct file_spliter file_spliter;extern struct interval interval;extern struct filter filter;struct export *export;static ptt_header_t head;static int accept_event [EVT_LAST] = {[0 ... EVT_LAST-1] = 1};static int paje = 0;static void error (char *err, ...) { va_list ap; fprintf(stderr, "Error : "); va_start(ap, err); vfprintf(stderr, err, ap); va_end(ap); fprintf(stderr, "\n"); exit (1);}static void warning (char *err, ...) { va_list ap; fprintf(stderr, "Warning : "); va_start(ap, err); vfprintf(stderr, err, ap); va_end(ap); fprintf(stderr, "\n");}static void list_event () { ptt_event_t ret; fprintf (stderr, "PTT event :\n"); for (ret = EVT_NULL+1; ret < EVT_LAST; ret++) fprintf (stderr, "\t%s\n", ptt_event_array[ret].name);}static int eventstr2enum (int *p, int and, char * str) { ptt_event_t ret; int count = 0; int len = strlen (str); for (ret = EVT_NULL; ret < EVT_LAST; ret++) { if (strncmp (ptt_event_array[ret].name, str, len) == 0 && (!and || p[ret])) { p[ret] = 1; count++; } else if (and) p[ret] = 0; } if (!count) warning ("%s* no matching event, ignoring", str); return count;}static int eventstr2enumr(int *p, int and, char * str) { ptt_event_t ret; int count = 0; int len = strlen (str); for (ret = EVT_NULL; ret < EVT_LAST; ret++) { int len_evt = strlen (ptt_event_array[ret].name); if (len_evt >= len && strcmp (ptt_event_array[ret].name + len_evt - len, str) == 0 && (!and || p[ret])) { p[ret] = 1; count++; } else if (and) p[ret] = 0; } if (!count) warning("*%s no matching event, ignoring", str); return count;}static void and (int *p1d, int *p2) { ptt_event_t ret; for (ret = EVT_NULL; ret < EVT_LAST; ret++) if (!p2[ret]) p1d [ret] = 0;}static void usage(char * name) { if (paje) fprintf (stderr, "%s [options] input_file\n" "\ninput options :\n" " -i file : input file name\n" "\noutput options :\n" " -o file : output file name\n" " -s {pid,pidx,tid} : split output\n" " -a alias_file : use alias to describe objects" "\nfilter options :\n" " -p pid[,pid...] : search for pid\n" " -n name[,name...] : search for name\n" " -z start:end : event filter\n" " -Z start:end : time filter\n" " -e : trace only I/O\n" "\ndisplay options :\n" " -d : show thread attribute and thread state\n" " -m : mask thread attribute and thread state\n" " no option : mask thread attribute and show thread state\n" , name); else fprintf (stderr, "%s [options] input_file\n" "\ninput options :\n" " -i file : input file name\n" "\noutput options :\n" " -o file : output file name\n" " -r : raw export\n" " -t : text export\n" " -s {pid,pidx,tid} : split output\n" " -a alias_file : use alias to describe objects" "\nfilter options :\n" " -e patern[,patern...] : search for paterns* event\n" " -E patern[,patern...] : search for *paterns event\n" " -l : list avaible events\n" " -p pid[,pid...] : search for pid\n" " -n name[,name...] : search for name\n" " -z start:end : event filter\n" " -Z start:end : time filter\n" "\ndisplay options :\n" " -m : mask pid\n" " -d : show pid\n" " -T : no time division\n" , name); exit (1);}static int init (int argc, char ** argv) { const char * optstring = "+e:E:rtgs:i:o:a:z:Z:dmTp:n:h::l"; signed char c; int ret; /* for paje : display thread state and not thread attribute * for textual output : display pid */ int export_display = 1; int export_time_div = 1; /* filter optipn */ pid_t *list_pid = NULL; int accept_event_tmp [EVT_LAST]; char **list_names = NULL; /* read option */ char *input_file = NULL; int interval_mode = INT_NULL; unsigned long long itv_min = 0, itv_max = 0; /* output option */ char *output_file = NULL; int output_mode = SPLIT_NULL; char *alias_file = NULL; /* check if we are ptt_view or ptt_paje */ int name_len = strlen (argv[0]); if (name_len >= 8 /*strlen("ptt_paje")*/ && strcmp(argv[0] + name_len - 8, "ptt_paje") == 0) { paje = 1; export = &export_paje; optstring = "+es:i:o:a:z:Z:p:n:h::dm"; } else export = &export_raw; opterr = 0; while ((c = getopt (argc, argv, optstring)) != EOF) { switch (c) { case 'p': { char *pos = optarg; int number = 2; /* there is n-1 comma + lead 0 */ if (list_pid) { warning ("Only one -p option is allowed"); continue; } /* count the number of entry */ while (*pos && (pos = strchr (pos, ','))) { number++; pos++; } list_pid = malloc (number * sizeof (pid_t)); list_pid[--number] = 0; while (optarg) { pid_t pid = atoi (strsep (&optarg ,",")); list_pid[--number] = pid; } assert(number == 0); continue; } case 'n': { char *pos = optarg; int number = 2; /* there is n-1 comma + lead 0 */ if (list_names) { warning("Only one -n option is allowed"); continue; } /* count the number of entry */ while (*pos && (pos = strchr (pos, ','))) { number++; pos++; } list_names = malloc (number * sizeof (char*)); list_names[--number] = NULL; while (optarg) { list_names[--number] = strsep (&optarg ,","); } assert(number == 0); continue; } case 's': if (strcmp (optarg, "pid") == 0) output_mode = SPLIT_PID; else if (strcmp (optarg, "tid") == 0) output_mode = SPLIT_TID; else if (strcmp (optarg, "pidx") == 0) output_mode = SPLIT_PID_FULL; else error("unknow -s argument"); continue; case 'o': if (strcmp (optarg, "-") == 0) output_mode = SPLIT_STDOUT; else output_file = optarg; continue; case 'a': alias_file = optarg; continue; case 'i': input_file = optarg; continue; case 'z': case 'Z': if (optarg[0] == ':') { itv_min = 0; if (!*(optarg+1)) { warning ("':' is not an interval"); continue; } itv_max = atoll (optarg+1); } else { itv_min = atoi (strsep (&optarg ,":")); if (!optarg) error ("missing `:' in %c\n", c); if (optarg[0] == 0) itv_max = -1LL; else itv_max = atoll (strsep (&optarg ,":")); } if (c == 'z') interval_mode = INT_EVT; else interval_mode = INT_TIME; continue; case 'h': usage (argv[0]); continue; case 'd': /* for paje : display thread attribute and thread state * for textual output : display pid */ export_display = 2; continue; case 'm': /* for paje : mask thread attribute and thread state * for textual output : mask pid */ export_display = 0; continue; case 'T': /* for paje : nothing * for textual output : no time division */ export_time_div = 0; continue; } if (paje) { switch (c) { case 'e': memset (accept_event_tmp, 0, sizeof (accept_event_tmp)); eventstr2enumr (accept_event_tmp, 0, "_IN"); eventstr2enumr (accept_event_tmp, 0, "_OUT"); eventstr2enumr (accept_event_tmp, 0, "THREAD_JOIN"); eventstr2enumr (accept_event_tmp, 0, "THREAD_SET_PD"); eventstr2enumr (accept_event_tmp, 0, "_USER_FUNC"); eventstr2enumr (accept_event_tmp, 0, "_INIT"); eventstr2enumr (accept_event_tmp, 0, "_DESTROY"); and (accept_event, accept_event_tmp); export_display = 0; break; case '?': warning("Unknow option -%c", optopt); break; default: warning("Unknow option -%c", c); break; } continue; } switch (c) { case 'r': export = &export_raw; break; case 't': export = &export_text; break; case 'g': export = &export_paje; break; case 'e': memset(accept_event_tmp, 0, sizeof (accept_event_tmp)); while (optarg) eventstr2enum (accept_event_tmp, 0, strsep (&optarg ,",")); and (accept_event, accept_event_tmp); break; case 'E': memset (accept_event_tmp, 0, sizeof (accept_event_tmp)); while (optarg) eventstr2enumr (accept_event_tmp, 0, strsep (&optarg ,",")); and (accept_event, accept_event_tmp); break; case 'l': list_event (); exit (0); case '?': warning ("Unknow option -%c", optopt); break; default: warning ("Unknow option -%c", c); break; } } /* init all module * interval and name are used by read_trace and must be init before */ ret = interval.init (interval_mode, &itv_min, &itv_max); if (ret < 0) return ret; ret = give_name.init(alias_file); if (ret < 0) return ret; if (!input_file) input_file = argv[optind]; ret = read_trace.init(input_file, &head); if (ret < 0) return ret; ret = export->init(&head, export_display, export_time_div); if (ret < 0) return ret; ret = file_spliter.init(output_file, output_mode); if (ret < 0) return ret; ret = filter.init(list_pid, accept_event, list_names); if (ret < 0) return ret; return 0;}#define CLOSE(x) if ((x).close) (x).close()static void close_modules () { CLOSE (filter); CLOSE (file_spliter); CLOSE (*export); CLOSE (read_trace); CLOSE (give_name); CLOSE (interval);} int main (int argc, char ** argv) { long long list_longlong [PTT_MAXARG]; int list_int [PTT_MAXARG]; unsigned int list_uint [PTT_MAXARG]; char *list_name [PTT_MAXARG+1]; /* +1: array is NULL terminated */ int ret; ptt_event_t event; ptt_timestamp_t time; pid_t pid; if (init (argc, argv) < 0) { usage(argv[0]); return 1; } while((ret = read_trace.read (&pid, &time, &event, list_name, list_int, list_uint, list_longlong)) > 0) { FILE *fd = file_spliter.getfd (pid, list_name[0], event, list_int); if (fd == NULL) error ("file_spliter.getfd"); ret = filter.accept (pid, event, list_name); if (ret < 0) error ("filter.accept"); else if (ret == 0) continue; if (export->write (fd, time, pid, event, list_name, list_int, list_uint, list_longlong) < 0) error ("export->write"); } if (ret < 0) error ("read"); close_modules (); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -