cregit-Linux how code gets into the kernel

Release 4.10 tools/perf/util/trace-event-read.c

Directory: tools/perf/util
/*
 * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 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 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
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include "../perf.h"
#include "util.h"
#include "trace-event.h"
#include "debug.h"


static int input_fd;


static ssize_t trace_data_size;

static bool repipe;


static int __do_read(int fd, void *buf, int size) { int rsize = size; while (size) { int ret = read(fd, buf, size); if (ret <= 0) return -1; if (repipe) { int retw = write(STDOUT_FILENO, buf, ret); if (retw <= 0 || retw != ret) { pr_debug("repiping input file"); return -1; } } size -= ret; buf += ret; } return rsize; }

Contributors

PersonTokensPropCommitsCommitProp
tom zanussitom zanussi9191.92%266.67%
namhyung kimnamhyung kim88.08%133.33%
Total99100.00%3100.00%


static int do_read(void *data, int size) { int r; r = __do_read(input_fd, data, size); if (r <= 0) { pr_debug("reading input file (size expected=%d received=%d)", size, r); return -1; } trace_data_size += r; return r; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt4072.73%125.00%
namhyung kimnamhyung kim1018.18%250.00%
tom zanussitom zanussi59.09%125.00%
Total55100.00%4100.00%

/* If it fails, the next read will report it */
static void skip(int size) { char buf[BUFSIZ]; int r; while (size) { r = size > BUFSIZ ? BUFSIZ : size; do_read(buf, r); size -= r; }; }

Contributors

PersonTokensPropCommitsCommitProp
tom zanussitom zanussi4597.83%150.00%
namhyung kimnamhyung kim12.17%150.00%
Total46100.00%2100.00%


static unsigned int read4(struct pevent *pevent) { unsigned int data; if (do_read(&data, 4) < 0) return 0; return __data2host4(pevent, data); }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt2564.10%250.00%
namhyung kimnamhyung kim923.08%125.00%
arnaldo carvalho de meloarnaldo carvalho de melo512.82%125.00%
Total39100.00%4100.00%


static unsigned long long read8(struct pevent *pevent) { unsigned long long data; if (do_read(&data, 8) < 0) return 0; return __data2host8(pevent, data); }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt2765.85%250.00%
namhyung kimnamhyung kim921.95%125.00%
arnaldo carvalho de meloarnaldo carvalho de melo512.20%125.00%
Total41100.00%4100.00%


static char *read_string(void) { char buf[BUFSIZ]; char *str = NULL; int size = 0; off_t r; char c; for (;;) { r = read(input_fd, &c, 1); if (r < 0) { pr_debug("reading input file"); goto out; } if (!r) { pr_debug("no data"); goto out; } if (repipe) { int retw = write(STDOUT_FILENO, &c, 1); if (retw <= 0 || retw != r) { pr_debug("repiping input file string"); goto out; } } buf[size++] = c; if (!c) break; } trace_data_size += size; str = malloc(size); if (str) memcpy(str, buf, size); out: return str; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt9155.49%114.29%
tom zanussitom zanussi4628.05%228.57%
namhyung kimnamhyung kim2615.85%342.86%
xiao guangrongxiao guangrong10.61%114.29%
Total164100.00%7100.00%


static int read_proc_kallsyms(struct pevent *pevent) { unsigned int size; size = read4(pevent); if (!size) return 0; /* * Just skip it, now that we configure libtraceevent to use the * tools/perf/ symbol resolver. * * We need to skip it so that we can continue parsing old perf.data * files, that contains this /proc/kallsyms payload. * * Newer perf.data files will have just the 4-bytes zeros "kallsyms * payload", so that older tools can continue reading it and interpret * it as "no kallsyms payload is present". */ lseek(input_fd, size, SEEK_CUR); trace_data_size += size; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt2655.32%125.00%
arnaldo carvalho de meloarnaldo carvalho de melo1429.79%250.00%
namhyung kimnamhyung kim714.89%125.00%
Total47100.00%4100.00%


static int read_ftrace_printk(struct pevent *pevent) { unsigned int size; char *buf; /* it can have 0 size */ size = read4(pevent); if (!size) return 0; buf = malloc(size); if (buf == NULL) return -1; if (do_read(buf, size) < 0) { free(buf); return -1; } parse_ftrace_printk(pevent, buf, size); free(buf); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt4751.65%125.00%
namhyung kimnamhyung kim3538.46%250.00%
arnaldo carvalho de meloarnaldo carvalho de melo99.89%125.00%
Total91100.00%4100.00%


static int read_header_files(struct pevent *pevent) { unsigned long long size; char *header_page; char buf[BUFSIZ]; int ret = 0; if (do_read(buf, 12) < 0) return -1; if (memcmp(buf, "header_page", 12) != 0) { pr_debug("did not read header page"); return -1; } size = read8(pevent); header_page = malloc(size); if (header_page == NULL) return -1; if (do_read(header_page, size) < 0) { pr_debug("did not read header page"); free(header_page); return -1; } if (!pevent_parse_header_page(pevent, header_page, size, pevent_get_long_size(pevent))) { /* * The commit field in the page is of type long, * use that instead, since it represents the kernel. */ pevent_set_long_size(pevent, pevent->header_page_size_size); } free(header_page); if (do_read(buf, 13) < 0) return -1; if (memcmp(buf, "header_event", 13) != 0) { pr_debug("did not read header event"); return -1; } size = read8(pevent); skip(size); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim12258.37%571.43%
steven rostedtsteven rostedt7736.84%114.29%
arnaldo carvalho de meloarnaldo carvalho de melo104.78%114.29%
Total209100.00%7100.00%


static int read_ftrace_file(struct pevent *pevent, unsigned long long size) { char *buf; buf = malloc(size); if (buf == NULL) return -1; if (do_read(buf, size) < 0) { free(buf); return -1; } parse_ftrace_file(pevent, buf, size); free(buf); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt3850.00%125.00%
namhyung kimnamhyung kim3140.79%250.00%
arnaldo carvalho de meloarnaldo carvalho de melo79.21%125.00%
Total76100.00%4100.00%


static int read_event_file(struct pevent *pevent, char *sys, unsigned long long size) { char *buf; buf = malloc(size); if (buf == NULL) return -1; if (do_read(buf, size) < 0) { free(buf); return -1; } parse_event_file(pevent, buf, size, sys); free(buf); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt4453.66%125.00%
namhyung kimnamhyung kim3137.80%250.00%
arnaldo carvalho de meloarnaldo carvalho de melo78.54%125.00%
Total82100.00%4100.00%


static int read_ftrace_files(struct pevent *pevent) { unsigned long long size; int count; int i; int ret; count = read4(pevent); for (i = 0; i < count; i++) { size = read8(pevent); ret = read_ftrace_file(pevent, size); if (ret) return ret; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt4561.64%133.33%
namhyung kimnamhyung kim1621.92%133.33%
arnaldo carvalho de meloarnaldo carvalho de melo1216.44%133.33%
Total73100.00%3100.00%


static int read_event_files(struct pevent *pevent) { unsigned long long size; char *sys; int systems; int count; int i,x; int ret; systems = read4(pevent); for (i = 0; i < systems; i++) { sys = read_string(); if (sys == NULL) return -1; count = read4(pevent); for (x=0; x < count; x++) { size = read8(pevent); ret = read_event_file(pevent, sys, size); if (ret) return ret; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt8066.12%133.33%
namhyung kimnamhyung kim2621.49%133.33%
arnaldo carvalho de meloarnaldo carvalho de melo1512.40%133.33%
Total121100.00%3100.00%


ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe) { char buf[BUFSIZ]; char test[] = { 23, 8, 68 }; char *version; int show_version = 0; int show_funcs = 0; int show_printk = 0; ssize_t size = -1; int file_bigendian; int host_bigendian; int file_long_size; int file_page_size; struct pevent *pevent = NULL; int err; repipe = __repipe; input_fd = fd; if (do_read(buf, 3) < 0) return -1; if (memcmp(buf, test, 3) != 0) { pr_debug("no trace data in the file"); return -1; } if (do_read(buf, 7) < 0) return -1; if (memcmp(buf, "tracing", 7) != 0) { pr_debug("not a trace file (missing 'tracing' tag)"); return -1; } version = read_string(); if (version == NULL) return -1; if (show_version) printf("version = %s\n", version); free(version); if (do_read(buf, 1) < 0) return -1; file_bigendian = buf[0]; host_bigendian = bigendian(); if (trace_event__init(tevent)) { pr_debug("trace_event__init failed"); goto out; } pevent = tevent->pevent; pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); pevent_set_file_bigendian(pevent, file_bigendian); pevent_set_host_bigendian(pevent, host_bigendian); if (do_read(buf, 1) < 0) goto out; file_long_size = buf[0]; file_page_size = read4(pevent); if (!file_page_size) goto out; pevent_set_long_size(pevent, file_long_size); pevent_set_page_size(pevent, file_page_size); err = read_header_files(pevent); if (err) goto out; err = read_ftrace_files(pevent); if (err) goto out; err = read_event_files(pevent); if (err) goto out; err = read_proc_kallsyms(pevent); if (err) goto out; err = read_ftrace_printk(pevent); if (err) goto out; size = trace_data_size; repipe = false; if (show_funcs) { pevent_print_funcs(pevent); } else if (show_printk) { pevent_print_printk(pevent); } pevent = NULL; out: if (pevent) trace_event__cleanup(tevent); return size; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim18542.24%847.06%
steven rostedtsteven rostedt15936.30%211.76%
jiri olsajiri olsa388.68%15.88%
arnaldo carvalho de meloarnaldo carvalho de melo235.25%211.76%
tom zanussitom zanussi214.79%211.76%
ingo molnaringo molnar92.05%15.88%
frederic weisbeckerfrederic weisbecker30.68%15.88%
Total438100.00%17100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt74945.50%28.33%
namhyung kimnamhyung kim51731.41%1041.67%
tom zanussitom zanussi21613.12%312.50%
arnaldo carvalho de meloarnaldo carvalho de melo1076.50%312.50%
jiri olsajiri olsa412.49%28.33%
ingo molnaringo molnar90.55%14.17%
frederic weisbeckerfrederic weisbecker60.36%28.33%
xiao guangrongxiao guangrong10.06%14.17%
Total1646100.00%24100.00%
Directory: tools/perf/util
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.