perf/core improvements and fixes
. Fix build for another rbtree.c change, from Adrian Hunter. . Fixes for perf to build on Android, from Irina Tirdea. . Make 'perf diff' command work with evsel hists, from Jiri Olsa. . Use the only field_sep var that is set up: symbol_conf.field_sep, fix from Jiri Olsa. . .gitignore compiled python binaries, from Namhyung Kim. . Get rid of die() in more libtraceevent places, from Namhyung Kim. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJQSqBrAAoJENZQFvNTUqpAWO4P/RRxxu1gCn4a3llvoJi4x0Ql rtTXeBS1jHZPCH8uFxS2qhN8SHD8rLoVB0czx4Fs+jISwrq9hXP0DSVY+710yivM 2F2O/0JU88dhbSGgQ5prCLqzdUQCzeg4nn1qThwHZgfuoA3wJ9mDVmqIj0urIiN+ URMEU9mjkxPk4Dn1zi9Fb+fUDcCcgXTxjVIcIzKyNgEVnBRvomcILLAWaR40oshs ZTslLTWa7VSAzJaPPHHBlSa+r93JfbKlU3q18Ly2BmytxQLNfQmALHNY42L3VxWj 1rz0ylAvC7I8qOK1teMly9ecYrKNPeTj9du54loee6wrMrsXd/14BWVEiDdyGEFv ChSEd/Tr6tgivj+TQ2IMlAA41ya0WG2SjOjzGXWpQ64BKtQUH9LuBbP+x6xuhGAh cnVW3HnbY9YufEaCbyTQ3PNLwuoJDy3xa6PtTzadNhyrYWlcnNP+T6B/sV6jBh0B RSw4FbNlJqqaP1bGrcuwLASVqQvEwLBRFVu4OEb5yI1Q/oAua497iz1NzMtrRk9G wpC5Ac21eJX+9HKV2KG+It5xmKsg3gQqPQpG1P7itRCOSrJAQjUzMNZkaFdH4Exo oatLZZk3P4qvhkjEh3SqAgiUHNYzCWBaAW2M50sgvvGH1jNIOy/gw7l4yU9YlwY5 TEFw0MYKK+gDhR1SbISk =0L9W -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: * Fix build for another rbtree.c change, from Adrian Hunter. * Fixes for perf to build on Android, from Irina Tirdea. * Make 'perf diff' command work with evsel hists, from Jiri Olsa. * Use the only field_sep var that is set up: symbol_conf.field_sep, fix from Jiri Olsa. * .gitignore compiled python binaries, from Namhyung Kim. * Get rid of die() in more libtraceevent places, from Namhyung Kim. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
ef34eb4da3
|
@ -3889,8 +3889,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
|
||||||
goto cont_process;
|
goto cont_process;
|
||||||
case '*':
|
case '*':
|
||||||
/* The argument is the length. */
|
/* The argument is the length. */
|
||||||
if (!arg)
|
if (!arg) {
|
||||||
die("no argument match");
|
do_warning("no argument match");
|
||||||
|
event->flags |= EVENT_FL_FAILED;
|
||||||
|
goto out_failed;
|
||||||
|
}
|
||||||
len_arg = eval_num_arg(data, size, event, arg);
|
len_arg = eval_num_arg(data, size, event, arg);
|
||||||
len_as_arg = 1;
|
len_as_arg = 1;
|
||||||
arg = arg->next;
|
arg = arg->next;
|
||||||
|
@ -3923,15 +3926,21 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'u':
|
case 'u':
|
||||||
if (!arg)
|
if (!arg) {
|
||||||
die("no argument match");
|
do_warning("no argument match");
|
||||||
|
event->flags |= EVENT_FL_FAILED;
|
||||||
|
goto out_failed;
|
||||||
|
}
|
||||||
|
|
||||||
len = ((unsigned long)ptr + 1) -
|
len = ((unsigned long)ptr + 1) -
|
||||||
(unsigned long)saveptr;
|
(unsigned long)saveptr;
|
||||||
|
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
if (len > 31)
|
if (len > 31) {
|
||||||
die("bad format!");
|
do_warning("bad format!");
|
||||||
|
event->flags |= EVENT_FL_FAILED;
|
||||||
|
len = 31;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(format, saveptr, len);
|
memcpy(format, saveptr, len);
|
||||||
format[len] = 0;
|
format[len] = 0;
|
||||||
|
@ -3995,19 +4004,26 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
|
||||||
trace_seq_printf(s, format, (long long)val);
|
trace_seq_printf(s, format, (long long)val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die("bad count (%d)", ls);
|
do_warning("bad count (%d)", ls);
|
||||||
|
event->flags |= EVENT_FL_FAILED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (!arg)
|
if (!arg) {
|
||||||
die("no matching argument");
|
do_warning("no matching argument");
|
||||||
|
event->flags |= EVENT_FL_FAILED;
|
||||||
|
goto out_failed;
|
||||||
|
}
|
||||||
|
|
||||||
len = ((unsigned long)ptr + 1) -
|
len = ((unsigned long)ptr + 1) -
|
||||||
(unsigned long)saveptr;
|
(unsigned long)saveptr;
|
||||||
|
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
if (len > 31)
|
if (len > 31) {
|
||||||
die("bad format!");
|
do_warning("bad format!");
|
||||||
|
event->flags |= EVENT_FL_FAILED;
|
||||||
|
len = 31;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(format, saveptr, len);
|
memcpy(format, saveptr, len);
|
||||||
format[len] = 0;
|
format[len] = 0;
|
||||||
|
@ -4025,6 +4041,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
|
||||||
trace_seq_putc(s, *ptr);
|
trace_seq_putc(s, *ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event->flags & EVENT_FL_FAILED) {
|
||||||
|
out_failed:
|
||||||
|
trace_seq_printf(s, "[FAILED TO PARSE]");
|
||||||
|
}
|
||||||
|
|
||||||
if (args) {
|
if (args) {
|
||||||
free_args(args);
|
free_args(args);
|
||||||
free(bprint_fmt);
|
free(bprint_fmt);
|
||||||
|
@ -4812,8 +4833,8 @@ int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
|
||||||
msg = strerror_r(errnum, buf, buflen);
|
msg = strerror_r(errnum, buf, buflen);
|
||||||
if (msg != buf) {
|
if (msg != buf) {
|
||||||
size_t len = strlen(msg);
|
size_t len = strlen(msg);
|
||||||
char *c = mempcpy(buf, msg, min(buflen-1, len));
|
memcpy(buf, msg, min(buflen - 1, len));
|
||||||
*c = '\0';
|
*(buf + min(buflen - 1, len)) = '\0';
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5059,6 +5080,7 @@ int pevent_register_print_function(struct pevent *pevent,
|
||||||
struct pevent_func_params *param;
|
struct pevent_func_params *param;
|
||||||
enum pevent_func_arg_type type;
|
enum pevent_func_arg_type type;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
func_handle = find_func_handler(pevent, name);
|
func_handle = find_func_handler(pevent, name);
|
||||||
if (func_handle) {
|
if (func_handle) {
|
||||||
|
@ -5071,14 +5093,21 @@ int pevent_register_print_function(struct pevent *pevent,
|
||||||
remove_func_handler(pevent, name);
|
remove_func_handler(pevent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
func_handle = malloc_or_die(sizeof(*func_handle));
|
func_handle = malloc(sizeof(*func_handle));
|
||||||
|
if (!func_handle) {
|
||||||
|
do_warning("Failed to allocate function handler");
|
||||||
|
return PEVENT_ERRNO__MEM_ALLOC_FAILED;
|
||||||
|
}
|
||||||
memset(func_handle, 0, sizeof(*func_handle));
|
memset(func_handle, 0, sizeof(*func_handle));
|
||||||
|
|
||||||
func_handle->ret_type = ret_type;
|
func_handle->ret_type = ret_type;
|
||||||
func_handle->name = strdup(name);
|
func_handle->name = strdup(name);
|
||||||
func_handle->func = func;
|
func_handle->func = func;
|
||||||
if (!func_handle->name)
|
if (!func_handle->name) {
|
||||||
die("Failed to allocate function name");
|
do_warning("Failed to allocate function name");
|
||||||
|
free(func_handle);
|
||||||
|
return PEVENT_ERRNO__MEM_ALLOC_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
next_param = &(func_handle->params);
|
next_param = &(func_handle->params);
|
||||||
va_start(ap, name);
|
va_start(ap, name);
|
||||||
|
@ -5088,11 +5117,17 @@ int pevent_register_print_function(struct pevent *pevent,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) {
|
if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) {
|
||||||
warning("Invalid argument type %d", type);
|
do_warning("Invalid argument type %d", type);
|
||||||
|
ret = PEVENT_ERRNO__INVALID_ARG_TYPE;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
param = malloc_or_die(sizeof(*param));
|
param = malloc(sizeof(*param));
|
||||||
|
if (!param) {
|
||||||
|
do_warning("Failed to allocate function param");
|
||||||
|
ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
param->type = type;
|
param->type = type;
|
||||||
param->next = NULL;
|
param->next = NULL;
|
||||||
|
|
||||||
|
@ -5110,7 +5145,7 @@ int pevent_register_print_function(struct pevent *pevent,
|
||||||
out_free:
|
out_free:
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
free_func_handle(func_handle);
|
free_func_handle(func_handle);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5162,7 +5197,12 @@ int pevent_register_event_handler(struct pevent *pevent,
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
/* Save for later use. */
|
/* Save for later use. */
|
||||||
handle = malloc_or_die(sizeof(*handle));
|
handle = malloc(sizeof(*handle));
|
||||||
|
if (!handle) {
|
||||||
|
do_warning("Failed to allocate event handler");
|
||||||
|
return PEVENT_ERRNO__MEM_ALLOC_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
memset(handle, 0, sizeof(*handle));
|
memset(handle, 0, sizeof(*handle));
|
||||||
handle->id = id;
|
handle->id = id;
|
||||||
if (event_name)
|
if (event_name)
|
||||||
|
@ -5172,7 +5212,11 @@ int pevent_register_event_handler(struct pevent *pevent,
|
||||||
|
|
||||||
if ((event_name && !handle->event_name) ||
|
if ((event_name && !handle->event_name) ||
|
||||||
(sys_name && !handle->sys_name)) {
|
(sys_name && !handle->sys_name)) {
|
||||||
die("Failed to allocate event/sys name");
|
do_warning("Failed to allocate event/sys name");
|
||||||
|
free((void *)handle->event_name);
|
||||||
|
free((void *)handle->sys_name);
|
||||||
|
free(handle);
|
||||||
|
return PEVENT_ERRNO__MEM_ALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->func = func;
|
handle->func = func;
|
||||||
|
|
|
@ -351,7 +351,8 @@ enum pevent_flag {
|
||||||
_PE(READ_ID_FAILED, "failed to read event id"), \
|
_PE(READ_ID_FAILED, "failed to read event id"), \
|
||||||
_PE(READ_FORMAT_FAILED, "failed to read event format"), \
|
_PE(READ_FORMAT_FAILED, "failed to read event format"), \
|
||||||
_PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
|
_PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
|
||||||
_PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace")
|
_PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
|
||||||
|
_PE(INVALID_ARG_TYPE, "invalid argument type")
|
||||||
|
|
||||||
#undef _PE
|
#undef _PE
|
||||||
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
|
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
|
||||||
|
|
|
@ -21,3 +21,5 @@ config.mak
|
||||||
config.mak.autogen
|
config.mak.autogen
|
||||||
*-bison.*
|
*-bison.*
|
||||||
*-flex.*
|
*-flex.*
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
|
|
@ -17,6 +17,9 @@ captured via perf record.
|
||||||
|
|
||||||
If no parameters are passed it will assume perf.data.old and perf.data.
|
If no parameters are passed it will assume perf.data.old and perf.data.
|
||||||
|
|
||||||
|
The differential profile is displayed only for events matching both
|
||||||
|
specified perf.data files.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
-M::
|
-M::
|
||||||
|
|
|
@ -755,6 +755,14 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef NO_BACKTRACE
|
||||||
|
BASIC_CFLAGS += -DNO_BACKTRACE
|
||||||
|
else
|
||||||
|
ifneq ($(call try-cc,$(SOURCE_BACKTRACE),),y)
|
||||||
|
BASIC_CFLAGS += -DNO_BACKTRACE
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef ASCIIDOC8
|
ifdef ASCIIDOC8
|
||||||
export ASCIIDOC8
|
export ASCIIDOC8
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "util/event.h"
|
#include "util/event.h"
|
||||||
#include "util/hist.h"
|
#include "util/hist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
|
#include "util/evlist.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/sort.h"
|
#include "util/sort.h"
|
||||||
|
@ -24,11 +25,6 @@ static char diff__default_sort_order[] = "dso,symbol";
|
||||||
static bool force;
|
static bool force;
|
||||||
static bool show_displacement;
|
static bool show_displacement;
|
||||||
|
|
||||||
struct perf_diff {
|
|
||||||
struct perf_tool tool;
|
|
||||||
struct perf_session *session;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hists__add_entry(struct hists *self,
|
static int hists__add_entry(struct hists *self,
|
||||||
struct addr_location *al, u64 period)
|
struct addr_location *al, u64 period)
|
||||||
{
|
{
|
||||||
|
@ -37,14 +33,12 @@ static int hists__add_entry(struct hists *self,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diff__process_sample_event(struct perf_tool *tool,
|
static int diff__process_sample_event(struct perf_tool *tool __used,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel __used,
|
struct perf_evsel *evsel,
|
||||||
struct machine *machine)
|
struct machine *machine)
|
||||||
{
|
{
|
||||||
struct perf_diff *_diff = container_of(tool, struct perf_diff, tool);
|
|
||||||
struct perf_session *session = _diff->session;
|
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) {
|
if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) {
|
||||||
|
@ -56,26 +50,24 @@ static int diff__process_sample_event(struct perf_tool *tool,
|
||||||
if (al.filtered || al.sym == NULL)
|
if (al.filtered || al.sym == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (hists__add_entry(&session->hists, &al, sample->period)) {
|
if (hists__add_entry(&evsel->hists, &al, sample->period)) {
|
||||||
pr_warning("problem incrementing symbol period, skipping event\n");
|
pr_warning("problem incrementing symbol period, skipping event\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->hists.stats.total_period += sample->period;
|
evsel->hists.stats.total_period += sample->period;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct perf_diff diff = {
|
static struct perf_tool tool = {
|
||||||
.tool = {
|
.sample = diff__process_sample_event,
|
||||||
.sample = diff__process_sample_event,
|
.mmap = perf_event__process_mmap,
|
||||||
.mmap = perf_event__process_mmap,
|
.comm = perf_event__process_comm,
|
||||||
.comm = perf_event__process_comm,
|
.exit = perf_event__process_task,
|
||||||
.exit = perf_event__process_task,
|
.fork = perf_event__process_task,
|
||||||
.fork = perf_event__process_task,
|
.lost = perf_event__process_lost,
|
||||||
.lost = perf_event__process_lost,
|
.ordered_samples = true,
|
||||||
.ordered_samples = true,
|
.ordering_requires_timestamps = true,
|
||||||
.ordering_requires_timestamps = true,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
|
static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
|
||||||
|
@ -146,34 +138,71 @@ static void hists__match(struct hists *older, struct hists *newer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
|
||||||
|
struct perf_evlist *evlist)
|
||||||
|
{
|
||||||
|
struct perf_evsel *e;
|
||||||
|
|
||||||
|
list_for_each_entry(e, &evlist->entries, node)
|
||||||
|
if (perf_evsel__match2(evsel, e))
|
||||||
|
return e;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int __cmd_diff(void)
|
static int __cmd_diff(void)
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret, i;
|
||||||
#define older (session[0])
|
#define older (session[0])
|
||||||
#define newer (session[1])
|
#define newer (session[1])
|
||||||
struct perf_session *session[2];
|
struct perf_session *session[2];
|
||||||
|
struct perf_evlist *evlist_new, *evlist_old;
|
||||||
|
struct perf_evsel *evsel;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
older = perf_session__new(input_old, O_RDONLY, force, false,
|
older = perf_session__new(input_old, O_RDONLY, force, false,
|
||||||
&diff.tool);
|
&tool);
|
||||||
newer = perf_session__new(input_new, O_RDONLY, force, false,
|
newer = perf_session__new(input_new, O_RDONLY, force, false,
|
||||||
&diff.tool);
|
&tool);
|
||||||
if (session[0] == NULL || session[1] == NULL)
|
if (session[0] == NULL || session[1] == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < 2; ++i) {
|
for (i = 0; i < 2; ++i) {
|
||||||
diff.session = session[i];
|
ret = perf_session__process_events(session[i], &tool);
|
||||||
ret = perf_session__process_events(session[i], &diff.tool);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
hists__output_resort(&session[i]->hists);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_displacement)
|
evlist_old = older->evlist;
|
||||||
hists__resort_entries(&older->hists);
|
evlist_new = newer->evlist;
|
||||||
|
|
||||||
|
list_for_each_entry(evsel, &evlist_new->entries, node)
|
||||||
|
hists__output_resort(&evsel->hists);
|
||||||
|
|
||||||
|
list_for_each_entry(evsel, &evlist_old->entries, node) {
|
||||||
|
hists__output_resort(&evsel->hists);
|
||||||
|
|
||||||
|
if (show_displacement)
|
||||||
|
hists__resort_entries(&evsel->hists);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(evsel, &evlist_new->entries, node) {
|
||||||
|
struct perf_evsel *evsel_old;
|
||||||
|
|
||||||
|
evsel_old = evsel_match(evsel, evlist_old);
|
||||||
|
if (!evsel_old)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
|
||||||
|
perf_evsel__name(evsel));
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
hists__match(&evsel_old->hists, &evsel->hists);
|
||||||
|
hists__fprintf(&evsel->hists, &evsel_old->hists,
|
||||||
|
show_displacement, true, 0, 0, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
hists__match(&older->hists, &newer->hists);
|
|
||||||
hists__fprintf(&newer->hists, &older->hists,
|
|
||||||
show_displacement, true, 0, 0, stdout);
|
|
||||||
out_delete:
|
out_delete:
|
||||||
for (i = 0; i < 2; ++i)
|
for (i = 0; i < 2; ++i)
|
||||||
perf_session__delete(session[i]);
|
perf_session__delete(session[i]);
|
||||||
|
|
|
@ -179,3 +179,17 @@ int main(void)
|
||||||
}
|
}
|
||||||
endef
|
endef
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef NO_BACKTRACE
|
||||||
|
define SOURCE_BACKTRACE
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
backtrace(NULL, 0);
|
||||||
|
backtrace_symbols(NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
endef
|
||||||
|
endif
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "util/run-command.h"
|
#include "util/run-command.h"
|
||||||
#include "util/parse-events.h"
|
#include "util/parse-events.h"
|
||||||
#include "util/debugfs.h"
|
#include "util/debugfs.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
const char perf_usage_string[] =
|
const char perf_usage_string[] =
|
||||||
"perf [--version] [--help] COMMAND [ARGS]";
|
"perf [--version] [--help] COMMAND [ARGS]";
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/rbtree.h>
|
#include <linux/rbtree.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
struct ins;
|
struct ins;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ static char *test_file(int size)
|
||||||
int fd, i;
|
int fd, i;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
fd = mkostemp(templ, O_CREAT|O_WRONLY|O_TRUNC);
|
fd = mkstemp(templ);
|
||||||
|
|
||||||
buf = malloc(size);
|
buf = malloc(size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
|
|
@ -124,6 +124,13 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads);
|
||||||
(evsel->attr.type == PERF_TYPE_##t && \
|
(evsel->attr.type == PERF_TYPE_##t && \
|
||||||
evsel->attr.config == PERF_COUNT_##c)
|
evsel->attr.config == PERF_COUNT_##c)
|
||||||
|
|
||||||
|
static inline bool perf_evsel__match2(struct perf_evsel *e1,
|
||||||
|
struct perf_evsel *e2)
|
||||||
|
{
|
||||||
|
return (e1->attr.type == e2->attr.type) &&
|
||||||
|
(e1->attr.config == e2->attr.config);
|
||||||
|
}
|
||||||
|
|
||||||
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
|
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
|
||||||
int cpu, int thread, bool scale);
|
int cpu, int thread, bool scale);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
#include "levenshtein.h"
|
#include "levenshtein.h"
|
||||||
#include "help.h"
|
#include "help.h"
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
|
void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
#include <stdbool.h>
|
||||||
#include "../../../../include/linux/rbtree.h"
|
#include "../../../../include/linux/rbtree.h"
|
||||||
|
|
|
@ -36,9 +36,7 @@ struct perf_session {
|
||||||
struct pevent *pevent;
|
struct pevent *pevent;
|
||||||
/*
|
/*
|
||||||
* FIXME: Need to split this up further, we need global
|
* FIXME: Need to split this up further, we need global
|
||||||
* stats + per event stats. 'perf diff' also needs
|
* stats + per event stats.
|
||||||
* to properly support multiple events in a single
|
|
||||||
* perf.data file.
|
|
||||||
*/
|
*/
|
||||||
struct hists hists;
|
struct hists hists;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
|
@ -12,8 +12,6 @@ int sort__branch_mode = -1; /* -1 = means not set */
|
||||||
|
|
||||||
enum sort_type sort__first_dimension;
|
enum sort_type sort__first_dimension;
|
||||||
|
|
||||||
char * field_sep;
|
|
||||||
|
|
||||||
LIST_HEAD(hist_entry__sort_list);
|
LIST_HEAD(hist_entry__sort_list);
|
||||||
|
|
||||||
static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
||||||
|
@ -23,11 +21,11 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
n = vsnprintf(bf, size, fmt, ap);
|
n = vsnprintf(bf, size, fmt, ap);
|
||||||
if (field_sep && n > 0) {
|
if (symbol_conf.field_sep && n > 0) {
|
||||||
char *sep = bf;
|
char *sep = bf;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
sep = strchr(sep, *field_sep);
|
sep = strchr(sep, *symbol_conf.field_sep);
|
||||||
if (sep == NULL)
|
if (sep == NULL)
|
||||||
break;
|
break;
|
||||||
*sep = '.';
|
*sep = '.';
|
||||||
|
|
|
@ -32,7 +32,6 @@ extern const char default_sort_order[];
|
||||||
extern int sort__need_collapse;
|
extern int sort__need_collapse;
|
||||||
extern int sort__has_parent;
|
extern int sort__has_parent;
|
||||||
extern int sort__branch_mode;
|
extern int sort__branch_mode;
|
||||||
extern char *field_sep;
|
|
||||||
extern struct sort_entry sort_comm;
|
extern struct sort_entry sort_comm;
|
||||||
extern struct sort_entry sort_dso;
|
extern struct sort_entry sort_dso;
|
||||||
extern struct sort_entry sort_sym;
|
extern struct sort_entry sort_sym;
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#include <linux/rbtree.h>
|
#include <linux/rbtree.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
|
#if defined(__BIONIC__)
|
||||||
|
#include <libgen.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_LIBELF_SUPPORT
|
#ifndef NO_LIBELF_SUPPORT
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
struct perf_evlist;
|
struct perf_evlist;
|
||||||
struct perf_evsel;
|
struct perf_evsel;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "../perf.h"
|
#include "../perf.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#ifndef NO_BACKTRACE
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -163,6 +165,7 @@ size_t hex_width(u64 v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Obtain a backtrace and print it to stdout. */
|
/* Obtain a backtrace and print it to stdout. */
|
||||||
|
#ifndef NO_BACKTRACE
|
||||||
void dump_stack(void)
|
void dump_stack(void)
|
||||||
{
|
{
|
||||||
void *array[16];
|
void *array[16];
|
||||||
|
@ -177,3 +180,6 @@ void dump_stack(void)
|
||||||
|
|
||||||
free(strings);
|
free(strings);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void dump_stack(void) {}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue