17 #include <traceevent/event-parse.h> 24 #include <linux/list.h> 28 #include <linux/kernel.h> 29 #include <linux/rbtree.h> 30 #include <linux/time64.h> 37 #include <subcmd/parse-options.h> 46 #define SUPPORT_OLD_POWER_EVENTS 1 47 #define PWR_EVENT_EXIT -1 137 #define TYPE_RUNNING 1 138 #define TYPE_WAITING 2 139 #define TYPE_BLOCKED 3 206 if (cursor->
pid == pid)
208 cursor = cursor->
next;
210 cursor =
zalloc(
sizeof(*cursor));
211 assert(cursor != NULL);
225 if (c->
comm && strcmp(c->
comm, comm) == 0) {
230 c->
comm = strdup(comm);
238 c->
comm = strdup(comm);
270 unsigned int cpu, u64
start, u64 end,
271 const char *backtrace)
287 sample =
zalloc(
sizeof(*sample));
288 assert(sample != NULL);
308 #define MAX_CPUS 4096 345 #ifdef SUPPORT_OLD_POWER_EVENTS 376 if (new_freq > 8000000)
379 pwr =
zalloc(
sizeof(*pwr));
398 if ((u64)new_freq > tchart->
max_freq)
404 if (new_freq == tchart->
max_freq - 1000)
409 int waker,
int wakee, u8
flags,
const char *backtrace)
417 we->
time = timestamp;
421 if ((flags & TRACE_FLAG_HARDIRQ) || (flags & TRACE_FLAG_SOFTIRQ))
442 int prev_pid,
int next_pid, u64 prev_state,
445 struct per_pid *p = NULL, *prev_p;
451 if (prev_p->current && prev_p->current->state !=
TYPE_NONE)
453 prev_p->current->state_since, timestamp,
465 if (prev_p->current) {
467 prev_p->current->state_since = timestamp;
483 u8
cpumode = PERF_RECORD_MISC_USER;
486 FILE *
f = open_memstream(&p, &p_len);
489 perror(
"open_memstream error");
497 fprintf(stderr,
"problem processing %d event, skipping it.\n",
502 for (i = 0; i < chain->
nr; i++) {
508 ip = chain->
ips[chain->
nr - i - 1];
510 if (ip >= PERF_CONTEXT_MAX) {
512 case PERF_CONTEXT_HV:
513 cpumode = PERF_RECORD_MISC_HYPERVISOR;
515 case PERF_CONTEXT_KERNEL:
516 cpumode = PERF_RECORD_MISC_KERNEL;
518 case PERF_CONTEXT_USER:
519 cpumode = PERF_RECORD_MISC_USER;
522 pr_debug(
"invalid callchain context: " 523 "%"PRId64
"\n", (s64) ip);
537 fprintf(f,
"..... %016" PRIx64
" %s\n", ip, tal.
sym->
name);
539 fprintf(f,
"..... %016" PRIx64
"\n", ip);
552 const char *backtrace);
562 if (evsel->
attr.sample_type & PERF_SAMPLE_TIME) {
571 return f(tchart, evsel, sample,
582 const char *backtrace __maybe_unused)
598 const char *backtrace __maybe_unused)
611 const char *backtrace)
625 const char *backtrace)
632 prev_state, backtrace);
636 #ifdef SUPPORT_OLD_POWER_EVENTS 641 const char *backtrace __maybe_unused)
654 const char *backtrace __maybe_unused)
664 const char *backtrace __maybe_unused)
683 for (cpu = 0; cpu <= tchart->
numcpus; cpu++) {
686 pwr =
zalloc(
sizeof(*pwr));
701 pwr =
zalloc(
sizeof(*pwr));
741 "previous event already started!\n");
750 sample =
zalloc(
sizeof(*sample));
784 "previous event already ended!\n");
788 if (sample->
type != type) {
789 pr_warning(
"Skip invalid end event: invalid event type!\n");
823 prev->
err == sample->
err &&
824 prev->
fd == sample->
fd &&
968 struct per_pid *new_list, *p, *cursor, *prev;
978 if (new_list == NULL) {
1003 cursor = cursor->
next;
1045 int from = 0, to = 0;
1046 char *task_from = NULL, *task_to = NULL;
1055 if (p->
pid == we->
waker && !from) {
1057 task_from = strdup(c->
comm);
1061 task_to = strdup(c->
comm);
1068 if (p->
pid == we->
waker && !from) {
1070 task_from = strdup(c->
comm);
1074 task_to = strdup(c->
comm);
1084 sprintf(task_from,
"[%i]", we->
waker);
1088 sprintf(task_to,
"[%i]", we->
wakee);
1091 if (we->
waker == -1)
1093 else if (from && to && abs(from - to) == 1)
1125 sample = sample->
next;
1159 sample->
err == -EAGAIN)
1170 sample->
err ?
"error" :
"sync",
1179 sample->
err ?
"error" :
"poll",
1188 sample->
err ?
"error" :
"disk",
1197 sample->
err ?
"error" :
"disk",
1206 sample->
err ?
"error" :
"net",
1215 sample->
err ?
"error" :
"net",
1224 bytes = bytes / 1024;
1228 bytes = bytes / 1024;
1232 bytes = bytes / 1024;
1237 sprintf(comm,
"%s:%i (%3.1f %sbytes)", c->
comm ?:
"", p->
pid, bytes, suf);
1285 sample = sample->
next;
1293 sprintf(comm,
"%s:%i (%3.1fms)", c->
comm, p->
pid, c->
total_time / (
double)NSEC_PER_MSEC);
1307 int pid = strtoull(
string, NULL, 10);
1308 struct process_filter *filt =
malloc(
sizeof(*filt));
1313 filt->
name = strdup(
string);
1317 process_filter = filt;
1322 struct process_filter *filt;
1323 if (!process_filter)
1330 if (strcmp(filt->
name, c->
comm) == 0)
1450 #define BYTES_THRESH (1 * 1024 * 1024) 1451 #define TIME_THRESH 10000000 1472 }
while (!process_filter && thresh && count < tchart->
proc_num);
1491 for (i = 0; i < tchart->
numcpus; i++)
1509 int fd __maybe_unused,
1527 fprintf(stderr,
"problem building topology\n");
1544 #ifdef SUPPORT_OLD_POWER_EVENTS 1605 .force = tchart->
force,
1612 if (session == NULL)
1626 power_tracepoints)) {
1627 pr_err(
"Initializing session tracepoint handlers failed\n");
1641 pr_info(
"Written %2.1f seconds of trace to %s.\n",
1650 unsigned int rec_argc, i;
1651 const char **rec_argv;
1655 const char *
const common_args[] = {
1656 "record",
"-a",
"-R",
"-c",
"1",
1658 unsigned int common_args_nr = ARRAY_SIZE(common_args);
1660 const char *
const disk_events[] = {
1661 "syscalls:sys_enter_read",
1662 "syscalls:sys_enter_pread64",
1663 "syscalls:sys_enter_readv",
1664 "syscalls:sys_enter_preadv",
1665 "syscalls:sys_enter_write",
1666 "syscalls:sys_enter_pwrite64",
1667 "syscalls:sys_enter_writev",
1668 "syscalls:sys_enter_pwritev",
1669 "syscalls:sys_enter_sync",
1670 "syscalls:sys_enter_sync_file_range",
1671 "syscalls:sys_enter_fsync",
1672 "syscalls:sys_enter_msync",
1674 "syscalls:sys_exit_read",
1675 "syscalls:sys_exit_pread64",
1676 "syscalls:sys_exit_readv",
1677 "syscalls:sys_exit_preadv",
1678 "syscalls:sys_exit_write",
1679 "syscalls:sys_exit_pwrite64",
1680 "syscalls:sys_exit_writev",
1681 "syscalls:sys_exit_pwritev",
1682 "syscalls:sys_exit_sync",
1683 "syscalls:sys_exit_sync_file_range",
1684 "syscalls:sys_exit_fsync",
1685 "syscalls:sys_exit_msync",
1687 unsigned int disk_events_nr = ARRAY_SIZE(disk_events);
1689 const char *
const net_events[] = {
1690 "syscalls:sys_enter_recvfrom",
1691 "syscalls:sys_enter_recvmmsg",
1692 "syscalls:sys_enter_recvmsg",
1693 "syscalls:sys_enter_sendto",
1694 "syscalls:sys_enter_sendmsg",
1695 "syscalls:sys_enter_sendmmsg",
1697 "syscalls:sys_exit_recvfrom",
1698 "syscalls:sys_exit_recvmmsg",
1699 "syscalls:sys_exit_recvmsg",
1700 "syscalls:sys_exit_sendto",
1701 "syscalls:sys_exit_sendmsg",
1702 "syscalls:sys_exit_sendmmsg",
1704 unsigned int net_events_nr = ARRAY_SIZE(net_events);
1706 const char *
const poll_events[] = {
1707 "syscalls:sys_enter_epoll_pwait",
1708 "syscalls:sys_enter_epoll_wait",
1709 "syscalls:sys_enter_poll",
1710 "syscalls:sys_enter_ppoll",
1711 "syscalls:sys_enter_pselect6",
1712 "syscalls:sys_enter_select",
1714 "syscalls:sys_exit_epoll_pwait",
1715 "syscalls:sys_exit_epoll_wait",
1716 "syscalls:sys_exit_poll",
1717 "syscalls:sys_exit_ppoll",
1718 "syscalls:sys_exit_pselect6",
1719 "syscalls:sys_exit_select",
1721 unsigned int poll_events_nr = ARRAY_SIZE(poll_events);
1723 rec_argc = common_args_nr +
1724 disk_events_nr * 4 +
1726 poll_events_nr * 4 +
1728 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
1730 if (rec_argv == NULL)
1733 if (asprintf(&filter,
"common_pid != %d", getpid()) < 0) {
1739 for (i = 0; i < common_args_nr; i++)
1740 *p++ = strdup(common_args[i]);
1742 for (i = 0; i < disk_events_nr; i++) {
1749 *p++ = strdup(disk_events[i]);
1753 for (i = 0; i < net_events_nr; i++) {
1760 *p++ = strdup(net_events[i]);
1764 for (i = 0; i < poll_events_nr; i++) {
1771 *p++ = strdup(poll_events[i]);
1776 for (i = 0; i < (
unsigned int)argc; i++)
1785 unsigned int rec_argc, i, j;
1786 const char **rec_argv;
1788 unsigned int record_elems;
1790 const char *
const common_args[] = {
1791 "record",
"-a",
"-R",
"-c",
"1",
1793 unsigned int common_args_nr = ARRAY_SIZE(common_args);
1795 const char *
const backtrace_args[] = {
1798 unsigned int backtrace_args_no = ARRAY_SIZE(backtrace_args);
1800 const char *
const power_args[] = {
1801 "-e",
"power:cpu_frequency",
1802 "-e",
"power:cpu_idle",
1804 unsigned int power_args_nr = ARRAY_SIZE(power_args);
1806 const char *
const old_power_args[] = {
1807 #ifdef SUPPORT_OLD_POWER_EVENTS 1808 "-e",
"power:power_start",
1809 "-e",
"power:power_end",
1810 "-e",
"power:power_frequency",
1813 unsigned int old_power_args_nr = ARRAY_SIZE(old_power_args);
1815 const char *
const tasks_args[] = {
1816 "-e",
"sched:sched_wakeup",
1817 "-e",
"sched:sched_switch",
1819 unsigned int tasks_args_nr = ARRAY_SIZE(tasks_args);
1821 #ifdef SUPPORT_OLD_POWER_EVENTS 1827 old_power_args_nr = 0;
1836 old_power_args_nr = 0;
1840 backtrace_args_no = 0;
1842 record_elems = common_args_nr + tasks_args_nr +
1843 power_args_nr + old_power_args_nr + backtrace_args_no;
1845 rec_argc = record_elems +
argc;
1846 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
1848 if (rec_argv == NULL)
1852 for (i = 0; i < common_args_nr; i++)
1853 *p++ = strdup(common_args[i]);
1855 for (i = 0; i < backtrace_args_no; i++)
1856 *p++ = strdup(backtrace_args[i]);
1858 for (i = 0; i < tasks_args_nr; i++)
1859 *p++ = strdup(tasks_args[i]);
1861 for (i = 0; i < power_args_nr; i++)
1862 *p++ = strdup(power_args[i]);
1864 for (i = 0; i < old_power_args_nr; i++)
1865 *p++ = strdup(old_power_args[i]);
1867 for (j = 0; j < (
unsigned int)argc; j++)
1875 int __maybe_unused unset)
1884 int __maybe_unused unset)
1886 unsigned long duration = strtoul(arg, NULL, 0);
1903 u64 *
value = opt->value;
1905 if (sscanf(arg,
"%" PRIu64
"%cs", value, &unit) > 0) {
1908 *value *= NSEC_PER_MSEC;
1911 *value *= NSEC_PER_USEC;
1931 .ordered_events =
true,
1934 .min_time = NSEC_PER_MSEC,
1938 const struct option timechart_common_options[] = {
1939 OPT_BOOLEAN(
'P',
"power-only", &tchart.
power_only,
"output power data only"),
1940 OPT_BOOLEAN(
'T',
"tasks-only", &tchart.
tasks_only,
"output processes data only"),
1943 const struct option timechart_options[] = {
1944 OPT_STRING(
'i',
"input", &
input_name,
"file",
"input file name"),
1945 OPT_STRING(
'o',
"output", &output_name,
"file",
"output file name"),
1947 OPT_CALLBACK(0,
"highlight", NULL,
"duration or task name",
1948 "highlight tasks. Pass duration in ns or process name.",
1950 OPT_CALLBACK(
'p',
"process", NULL,
"process",
1951 "process selector. Pass a pid or process name.",
1953 OPT_CALLBACK(0,
"symfs", NULL,
"directory",
1954 "Look for files with symbols relative to this directory",
1956 OPT_INTEGER(
'n',
"proc-num", &tchart.
proc_num,
1957 "min. number of tasks to print"),
1958 OPT_BOOLEAN(
't',
"topology", &tchart.
topology,
1959 "sort CPUs according to topology"),
1960 OPT_BOOLEAN(0,
"io-skip-eagain", &tchart.
skip_eagain,
1961 "skip EAGAIN errors"),
1962 OPT_CALLBACK(0,
"io-min-time", &tchart.
min_time,
"time",
1963 "all IO faster than min-time will visually appear longer",
1965 OPT_CALLBACK(0,
"io-merge-dist", &tchart.
merge_dist,
"time",
1966 "merge events that are merge-dist us apart",
1968 OPT_BOOLEAN(
'f',
"force", &tchart.
force,
"don't complain, do it"),
1969 OPT_PARENT(timechart_common_options),
1971 const char *
const timechart_subcommands[] = {
"record", NULL };
1972 const char *timechart_usage[] = {
1973 "perf timechart [<options>] {record}",
1976 const struct option timechart_record_options[] = {
1977 OPT_BOOLEAN(
'I',
"io-only", &tchart.
io_only,
1978 "record only IO data"),
1979 OPT_BOOLEAN(
'g',
"callchain", &tchart.
with_backtrace,
"record callchain"),
1980 OPT_PARENT(timechart_common_options),
1982 const char *
const timechart_record_usage[] = {
1983 "perf timechart record [<options>]",
1986 argc = parse_options_subcommand(argc, argv, timechart_options, timechart_subcommands,
1987 timechart_usage, PARSE_OPT_STOP_AT_NON_OPTION);
1990 pr_err(
"-P and -T options cannot be used at the same time.\n");
1994 if (argc && !strncmp(argv[0],
"rec", 3)) {
1995 argc = parse_options(argc, argv, timechart_record_options,
1996 timechart_record_usage,
1997 PARSE_OPT_STOP_AT_NON_OPTION);
2000 pr_err(
"-P and -T options cannot be used at the same time.\n");
2009 usage_with_options(timechart_usage, timechart_options);
static int process_sample_cpu_frequency(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused)
void svg_time_grid(double min_thickness)
static int parse_time(const struct option *opt, const char *arg, int __maybe_unused unset)
static struct process_filter * process_filter
void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
void svg_box(int Yslot, u64 start, u64 end, const char *type)
static void sched_switch(struct timechart *tchart, int cpu, u64 timestamp, int prev_pid, int next_pid, u64 prev_state, const char *backtrace)
int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample)
static int determine_display_tasks_filtered(struct timechart *tchart)
static int process_fork_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused)
static int process_exit_poll(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static int process_sample_power_frequency(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused)
void svg_text(int Yslot, u64 start, const char *text)
static int timechart__record(struct timechart *tchart, int argc, const char **argv)
int(* tracepoint_handler)(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace)
int cmd_record(int argc, const char **argv)
struct cpu_sample * samples
static void add_process_filter(const char *string)
static const char * cat_backtrace(union perf_event *event, struct perf_sample *sample, struct machine *machine)
static int process_enter_poll(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
void svg_wakeline(u64 start, int row1, int row2, const char *backtrace)
struct per_pidcomm * next
struct ip_callchain * callchain
void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
static int process_exit_write(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static int pid_end_io_sample(struct timechart *tchart, int pid, int type, u64 end, long ret)
static void write_svg_file(struct timechart *tchart, const char *filename)
struct perf_data_file file
static void p_state_change(struct timechart *tchart, int cpu, u64 timestamp, u64 new_freq)
static void end_sample_processing(struct timechart *tchart)
static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine)
static int determine_display_tasks(struct timechart *tchart, u64 threshold)
static int process_header(struct perf_file_section *section __maybe_unused, struct perf_header *ph, int feat, int fd __maybe_unused, void *data)
static const char * output_name
bool perf_session__has_traces(struct perf_session *session, const char *msg)
void svg_cstate(int cpu, u64 start, u64 end, int type)
void perf_session__delete(struct perf_session *session)
static int parse_process(const struct option *opt __maybe_unused, const char *arg, int __maybe_unused unset)
static u64 cpus_pstate_state[MAX_CPUS]
static int process_sample_sched_wakeup(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace)
static int process_enter_write(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
int cmd_timechart(int argc, const char **argv)
void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
static int __cmd_timechart(struct timechart *tchart, const char *output_name)
void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
void addr_location__put(struct addr_location *al)
static void draw_process_bars(struct timechart *tchart)
static void pid_set_comm(struct timechart *tchart, int pid, char *comm)
static int parse_highlight(const struct option *opt __maybe_unused, const char *arg, int __maybe_unused unset)
int symbol__config_symfs(const struct option *opt __maybe_unused, const char *dir, int unset __maybe_unused)
static int process_enter_read(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace)
#define pr_debug(fmt,...)
static struct perf_session * session
struct process_filter * next
int is_valid_tracepoint(const char *event_string)
static int process_enter_tx(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static int cpus_cstate_state[MAX_CPUS]
static int process_sample_sched_switch(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace)
void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
void svg_interrupt(u64 start, int row, const char *backtrace)
void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
void svg_io_legenda(void)
const char * svg_highlight_name
static void c_state_end(struct timechart *tchart, int cpu, u64 timestamp)
static void c_state_start(int cpu, u64 timestamp, int state)
int svg_build_topology_map(char *sib_core, int sib_core_nr, char *sib_thr, int sib_thr_nr)
static int pid_begin_io_sample(struct timechart *tchart, int pid, int type, u64 start, int fd)
u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, const char *name)
static int process_enter_sync(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static int process_exit_read(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static int perf_data__fd(struct perf_data *data)
static int use_old_power_events
void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
static struct per_pid * find_create_pid(struct timechart *tchart, int pid)
static void pid_put_sample(struct timechart *tchart, int pid, int type, unsigned int cpu, u64 start, u64 end, const char *backtrace)
struct power_event * power_events
static int timechart__io_record(int argc, const char **argv)
struct perf_event_header header
static void pid_exit(struct timechart *tchart, int pid, u64 timestamp)
struct strfilter * filter
struct perf_session * perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool)
static u64 cpus_cstate_start_times[MAX_CPUS]
void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
int perf_session__process_events(struct perf_session *session)
static int process_sample_power_start(struct timechart *tchart __maybe_unused, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused)
static void draw_io_bars(struct timechart *tchart)
void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace)
struct symbol * thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
struct sample_wrapper * next
static int process_exit_sync(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
struct perf_header header
static void sort_pids(struct timechart *tchart)
struct per_pid * all_data
int symbol__init(struct perf_env *env)
static int process_sample_power_end(struct timechart *tchart, struct perf_evsel *evsel __maybe_unused, struct perf_sample *sample, const char *backtrace __maybe_unused)
struct power_event * next
static void draw_c_p_states(struct timechart *tchart)
static int process_enter_rx(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
struct per_pidcomm * current
struct wake_event * wake_events
static int process_comm_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused)
static int passes_filter(struct per_pid *p, struct per_pidcomm *c)
#define pr_warning(fmt,...)
#define perf_session__set_tracepoints_handlers(session, array)
static void draw_wakeups(struct timechart *tchart)
static int process_exit_tx(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static u64 cpus_pstate_start_times[MAX_CPUS]
static void sched_wakeup(struct timechart *tchart, int cpu, u64 timestamp, int waker, int wakee, u8 flags, const char *backtrace)
static int determine_display_io_tasks(struct timechart *timechart, u64 threshold)
static void pid_fork(struct timechart *tchart, int pid, int ppid, u64 timestamp)
struct io_sample * io_samples
struct perf_event_attr attr
static void draw_cpu_usage(struct timechart *tchart)
static int process_sample_cpu_idle(struct timechart *tchart __maybe_unused, struct perf_evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused)
static int process_exit_rx(struct timechart *tchart, struct perf_evsel *evsel, struct perf_sample *sample)
static int process_exit_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused)
void static void * zalloc(size_t size)