perf/core improvements and fixes:
User visible: - Fix documentation of :ppp modifier in 'perf list' (Andi Kleen) - Fix silly nodes bitfield bits/bytes length assertion in 'perf bench numa' (Jakub Jelen) - Remove redundant CPU output in libtraceevent (Steven Rostedt) - Remove 'core_id' check in topology 'perf test' (Sukadev Bhattiprolu) Infrastructure: - Record text offset in dso to calculate objdump address, to use with modules in addition to vDSO symbol address calculations (Wang Nan) - Move utilities.mak from perf to tools/scripts/ (Arnaldo Carvalho de Melo) - Add cpumode to the perf_sample struct, this way we don't need to pass the union event to the machine and thread resolving routines, shortening function signatures and allowing the future introduction of a way to use tracepoint events instead of the unavailable HW cycles counter on powerpc guests in perf kvm by just hooking on perf_evsel__parse_sample, at the end (Arnaldo Carvalho de Melo) - Remove/unexport die() related infrastructure, that at some point will finally be removed (Arnaldo Carvalho de Melo) - Adopt linux/stringify.h from the kernel sources, not to touch this kernel header from tools/ (Arnaldo Carvalho de Melo) - Stop using strbuf for things we can instead trivially use libc's asprintf() (Arnaldo Carvalho de Melo) - Ditch tools/lib/util/abspath.c, its only exported function was used at just one place and can be replaced by libc's realpath() (Arnaldo Carvalho de Melo) - Use strerror_r() in the llvm infrastructure, tread safe, its what is used elsewhere in tools/perf/ (Arnaldo Carvalho de Melo) Cleanups: - Removed misplaced or needless __maybe_unused/export (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJW8wWeAAoJENZQFvNTUqpAF9YP/iXdYDnav5mr8yRt1Vu88F0j rmnO0E6zHzH5PcEoMuSPYEea1IPKZcV2KyVWFsfzkbfZrsC05AkGOrHAs7v0jCyz 93p0/sH92Vy7ZTvE2slQJGKm2fgo3veV3ExEZDqdT5NNlzrIHVGshNYTma0wuduM NMdCdZe99KUuJFjqaUP9YCTr9VWF30Vu/AAOTUY7Xg6j7ZuJ47HchNxbOvCOp430 LtirOKRBmVyY8BOoKSDDyaZOOPz18k58z8bKVO2eQNN9wf6ZGjWIN5DpjBs9pdJa W4zhFbHxU272IZXVv8/K2hV1qenov4Ghn5i0oApBjaRGta6dBFhGmYk0zIATcpGV wkuB6OrQTGYnBcNCI9z/kyxdt7Km0X2ffruvFLPviz4d7Sa2W0Gmj2+4JgXaLipp Q/0H/iWcT1kv+SXT9yjWe2+QxgwbJlUJ96+aGEvqDQH23Hifxjx4wezNR98kK/s7 8IGxJEIOMmRocXeDeEZ8sKwqqan34IDrXKs2jMQSOonVVhR+dmvZicqSNwMTvMTn Sz36bsaKkWQtM3d97byx6EHDJn6aPEQlbY/YR6DqKgKmeFTQgs1lDvUp7SVUu1qp HwSDN7FgWbXAJVfxeoe0qBSZY9px+dCCh+qZmNN+TtD84IBgzrJpaSf6hzQ6FIie yTfVHvvkyUDep1KquQz9 =f41L -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo-20160323' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent Pull perf/core improvements and fixes: User visible fixes: - Fix documentation of :ppp modifier in 'perf list' (Andi Kleen) - Fix silly nodes bitfield bits/bytes length assertion in 'perf bench numa' (Jakub Jelen) - Remove redundant CPU output in libtraceevent (Steven Rostedt) - Remove 'core_id' check in topology 'perf test' (Sukadev Bhattiprolu) Infrastructure changes/fixes: - Record text offset in dso to calculate objdump address, to use with modules in addition to vDSO symbol address calculations (Wang Nan) - Move utilities.mak from perf to tools/scripts/ (Arnaldo Carvalho de Melo) - Add cpumode to the perf_sample struct, this way we don't need to pass the union event to the machine and thread resolving routines, shortening function signatures and allowing the future introduction of a way to use tracepoint events instead of the unavailable HW cycles counter on powerpc guests in perf kvm by just hooking on perf_evsel__parse_sample, at the end (Arnaldo Carvalho de Melo) - Remove/unexport die() related infrastructure, that at some point will finally be removed (Arnaldo Carvalho de Melo) - Adopt linux/stringify.h from the kernel sources, not to touch this kernel header from tools/ (Arnaldo Carvalho de Melo) - Stop using strbuf for things we can instead trivially use libc's asprintf() (Arnaldo Carvalho de Melo) - Ditch tools/lib/util/abspath.c, its only exported function was used at just one place and can be replaced by libc's realpath() (Arnaldo Carvalho de Melo) - Use strerror_r() in the llvm infrastructure, tread safe, its what is used elsewhere in tools/perf/ (Arnaldo Carvalho de Melo) Cleanups: - Removed misplaced or needless __maybe_unused/export (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
05f5ece76a
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __LINUX_STRINGIFY_H
|
||||||
|
#define __LINUX_STRINGIFY_H
|
||||||
|
|
||||||
|
/* Indirect stringification. Doing two levels allows the parameter to be a
|
||||||
|
* macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
|
||||||
|
* converts to "bar".
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __stringify_1(x...) #x
|
||||||
|
#define __stringify(x...) __stringify_1(x)
|
||||||
|
|
||||||
|
#endif /* !__LINUX_STRINGIFY_H */
|
|
@ -1,5 +1,5 @@
|
||||||
include ../../scripts/Makefile.include
|
include ../../scripts/Makefile.include
|
||||||
include ../../perf/config/utilities.mak # QUIET_CLEAN
|
include ../../scripts/utilities.mak # QUIET_CLEAN
|
||||||
|
|
||||||
ifeq ($(srctree),)
|
ifeq ($(srctree),)
|
||||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
include ../../scripts/Makefile.include
|
include ../../scripts/Makefile.include
|
||||||
include ../../perf/config/utilities.mak # QUIET_CLEAN
|
include ../../scripts/utilities.mak # QUIET_CLEAN
|
||||||
|
|
||||||
ifeq ($(srctree),)
|
ifeq ($(srctree),)
|
||||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||||
|
|
|
@ -5427,10 +5427,8 @@ void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pevent->latency_format) {
|
if (pevent->latency_format) {
|
||||||
trace_seq_printf(s, " %3d", record->cpu);
|
|
||||||
pevent_data_lat_fmt(pevent, s, record);
|
pevent_data_lat_fmt(pevent, s, record);
|
||||||
} else
|
}
|
||||||
trace_seq_printf(s, " [%03d]", record->cpu);
|
|
||||||
|
|
||||||
if (use_usec_format) {
|
if (use_usec_format) {
|
||||||
if (pevent->flags & PEVENT_NSEC_OUTPUT) {
|
if (pevent->flags & PEVENT_NSEC_OUTPUT) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
include ../../scripts/Makefile.include
|
include ../../scripts/Makefile.include
|
||||||
include ../config/utilities.mak
|
include ../../scripts/utilities.mak
|
||||||
|
|
||||||
MAN1_TXT= \
|
MAN1_TXT= \
|
||||||
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
|
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
|
||||||
|
|
|
@ -40,10 +40,12 @@ address should be. The 'p' modifier can be specified multiple times:
|
||||||
0 - SAMPLE_IP can have arbitrary skid
|
0 - SAMPLE_IP can have arbitrary skid
|
||||||
1 - SAMPLE_IP must have constant skid
|
1 - SAMPLE_IP must have constant skid
|
||||||
2 - SAMPLE_IP requested to have 0 skid
|
2 - SAMPLE_IP requested to have 0 skid
|
||||||
3 - SAMPLE_IP must have 0 skid
|
3 - SAMPLE_IP must have 0 skid, or uses randomization to avoid
|
||||||
|
sample shadowing effects.
|
||||||
|
|
||||||
For Intel systems precise event sampling is implemented with PEBS
|
For Intel systems precise event sampling is implemented with PEBS
|
||||||
which supports up to precise-level 2.
|
which supports up to precise-level 2, and precise level 3 for
|
||||||
|
some special cases
|
||||||
|
|
||||||
On AMD systems it is implemented using IBS (up to precise-level 2).
|
On AMD systems it is implemented using IBS (up to precise-level 2).
|
||||||
The precise modifier works with event types 0x76 (cpu-cycles, CPU
|
The precise modifier works with event types 0x76 (cpu-cycles, CPU
|
||||||
|
|
|
@ -3,7 +3,7 @@ include ../scripts/Makefile.include
|
||||||
# The default target of this Makefile is...
|
# The default target of this Makefile is...
|
||||||
all:
|
all:
|
||||||
|
|
||||||
include config/utilities.mak
|
include ../scripts/utilities.mak
|
||||||
|
|
||||||
# Define V to have a more verbose compile.
|
# Define V to have a more verbose compile.
|
||||||
#
|
#
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <linux/stringify.h>
|
||||||
#include "../../util/header.h"
|
|
||||||
#include "../../util/util.h"
|
|
||||||
|
|
||||||
#define mfspr(rn) ({unsigned long rval; \
|
#define mfspr(rn) ({unsigned long rval; \
|
||||||
asm volatile("mfspr %0," __stringify(rn) \
|
asm volatile("mfspr %0," __stringify(rn) \
|
||||||
|
|
|
@ -25,19 +25,17 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int bench_numa(int argc, const char **argv, const char *prefix);
|
int bench_numa(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_sched_messaging(int argc, const char **argv, const char *prefix);
|
int bench_sched_messaging(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_sched_pipe(int argc, const char **argv, const char *prefix);
|
int bench_sched_pipe(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_mem_memcpy(int argc, const char **argv,
|
int bench_mem_memcpy(int argc, const char **argv, const char *prefix);
|
||||||
const char *prefix __maybe_unused);
|
int bench_mem_memset(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_mem_memset(int argc, const char **argv, const char *prefix);
|
int bench_futex_hash(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_futex_hash(int argc, const char **argv, const char *prefix);
|
int bench_futex_wake(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_futex_wake(int argc, const char **argv, const char *prefix);
|
int bench_futex_wake_parallel(int argc, const char **argv, const char *prefix);
|
||||||
extern int bench_futex_wake_parallel(int argc, const char **argv,
|
int bench_futex_requeue(int argc, const char **argv, const char *prefix);
|
||||||
const char *prefix);
|
|
||||||
extern int bench_futex_requeue(int argc, const char **argv, const char *prefix);
|
|
||||||
/* pi futexes */
|
/* pi futexes */
|
||||||
extern int bench_futex_lock_pi(int argc, const char **argv, const char *prefix);
|
int bench_futex_lock_pi(int argc, const char **argv, const char *prefix);
|
||||||
|
|
||||||
#define BENCH_FORMAT_DEFAULT_STR "default"
|
#define BENCH_FORMAT_DEFAULT_STR "default"
|
||||||
#define BENCH_FORMAT_DEFAULT 0
|
#define BENCH_FORMAT_DEFAULT 0
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||||
|
|
||||||
#define MEMCPY_FN(fn, name, desc) \
|
#define MEMCPY_FN(fn, name, desc) \
|
||||||
extern void *fn(void *, const void *, size_t);
|
void *fn(void *, const void *, size_t);
|
||||||
|
|
||||||
#include "mem-memcpy-x86-64-asm-def.h"
|
#include "mem-memcpy-x86-64-asm-def.h"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||||
|
|
||||||
#define MEMSET_FN(fn, name, desc) \
|
#define MEMSET_FN(fn, name, desc) \
|
||||||
extern void *fn(void *, int, size_t);
|
void *fn(void *, int, size_t);
|
||||||
|
|
||||||
#include "mem-memset-x86-64-asm-def.h"
|
#include "mem-memset-x86-64-asm-def.h"
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,7 @@ static void bind_to_memnode(int node)
|
||||||
if (node == -1)
|
if (node == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask));
|
BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8);
|
||||||
nodemask = 1L << node;
|
nodemask = 1L << node;
|
||||||
|
|
||||||
ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
|
ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
|
||||||
|
|
|
@ -94,7 +94,7 @@ static int process_sample_event(struct perf_tool *tool,
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
pr_warning("problem processing %d event, skipping it.\n",
|
pr_warning("problem processing %d event, skipping it.\n",
|
||||||
event->header.type);
|
event->header.type);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -330,7 +330,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
|
||||||
struct hists *hists = evsel__hists(evsel);
|
struct hists *hists = evsel__hists(evsel);
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
pr_warning("problem processing %d event, skipping it.\n",
|
pr_warning("problem processing %d event, skipping it.\n",
|
||||||
event->header.type);
|
event->header.type);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -106,12 +106,14 @@ static void exec_woman_emacs(const char *path, const char *page)
|
||||||
|
|
||||||
if (!check_emacsclient_version()) {
|
if (!check_emacsclient_version()) {
|
||||||
/* This works only with emacsclient version >= 22. */
|
/* This works only with emacsclient version >= 22. */
|
||||||
struct strbuf man_page = STRBUF_INIT;
|
char *man_page;
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
path = "emacsclient";
|
path = "emacsclient";
|
||||||
strbuf_addf(&man_page, "(woman \"%s\")", page);
|
if (asprintf(&man_page, "(woman \"%s\")", page) > 0) {
|
||||||
execlp(path, "emacsclient", "-e", man_page.buf, NULL);
|
execlp(path, "emacsclient", "-e", man_page, NULL);
|
||||||
|
free(man_page);
|
||||||
|
}
|
||||||
warning("failed to exec '%s': %s", path,
|
warning("failed to exec '%s': %s", path,
|
||||||
strerror_r(errno, sbuf, sizeof(sbuf)));
|
strerror_r(errno, sbuf, sizeof(sbuf)));
|
||||||
}
|
}
|
||||||
|
@ -122,7 +124,7 @@ static void exec_man_konqueror(const char *path, const char *page)
|
||||||
const char *display = getenv("DISPLAY");
|
const char *display = getenv("DISPLAY");
|
||||||
|
|
||||||
if (display && *display) {
|
if (display && *display) {
|
||||||
struct strbuf man_page = STRBUF_INIT;
|
char *man_page;
|
||||||
const char *filename = "kfmclient";
|
const char *filename = "kfmclient";
|
||||||
char sbuf[STRERR_BUFSIZE];
|
char sbuf[STRERR_BUFSIZE];
|
||||||
|
|
||||||
|
@ -141,8 +143,10 @@ static void exec_man_konqueror(const char *path, const char *page)
|
||||||
filename = file;
|
filename = file;
|
||||||
} else
|
} else
|
||||||
path = "kfmclient";
|
path = "kfmclient";
|
||||||
strbuf_addf(&man_page, "man:%s(1)", page);
|
if (asprintf(&man_page, "man:%s(1)", page) > 0) {
|
||||||
execlp(path, filename, "newTab", man_page.buf, NULL);
|
execlp(path, filename, "newTab", man_page, NULL);
|
||||||
|
free(man_page);
|
||||||
|
}
|
||||||
warning("failed to exec '%s': %s", path,
|
warning("failed to exec '%s': %s", path,
|
||||||
strerror_r(errno, sbuf, sizeof(sbuf)));
|
strerror_r(errno, sbuf, sizeof(sbuf)));
|
||||||
}
|
}
|
||||||
|
@ -161,11 +165,13 @@ static void exec_man_man(const char *path, const char *page)
|
||||||
|
|
||||||
static void exec_man_cmd(const char *cmd, const char *page)
|
static void exec_man_cmd(const char *cmd, const char *page)
|
||||||
{
|
{
|
||||||
struct strbuf shell_cmd = STRBUF_INIT;
|
|
||||||
char sbuf[STRERR_BUFSIZE];
|
char sbuf[STRERR_BUFSIZE];
|
||||||
|
char *shell_cmd;
|
||||||
|
|
||||||
strbuf_addf(&shell_cmd, "%s %s", cmd, page);
|
if (asprintf(&shell_cmd, "%s %s", cmd, page) > 0) {
|
||||||
execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL);
|
execl("/bin/sh", "sh", "-c", shell_cmd, NULL);
|
||||||
|
free(shell_cmd);
|
||||||
|
}
|
||||||
warning("failed to exec '%s': %s", cmd,
|
warning("failed to exec '%s': %s", cmd,
|
||||||
strerror_r(errno, sbuf, sizeof(sbuf)));
|
strerror_r(errno, sbuf, sizeof(sbuf)));
|
||||||
}
|
}
|
||||||
|
@ -299,43 +305,33 @@ static int is_perf_command(const char *s)
|
||||||
is_in_cmdlist(&other_cmds, s);
|
is_in_cmdlist(&other_cmds, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *prepend(const char *prefix, const char *cmd)
|
|
||||||
{
|
|
||||||
size_t pre_len = strlen(prefix);
|
|
||||||
size_t cmd_len = strlen(cmd);
|
|
||||||
char *p = malloc(pre_len + cmd_len + 1);
|
|
||||||
memcpy(p, prefix, pre_len);
|
|
||||||
strcpy(p + pre_len, cmd);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *cmd_to_page(const char *perf_cmd)
|
static const char *cmd_to_page(const char *perf_cmd)
|
||||||
{
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
if (!perf_cmd)
|
if (!perf_cmd)
|
||||||
return "perf";
|
return "perf";
|
||||||
else if (!prefixcmp(perf_cmd, "perf"))
|
else if (!prefixcmp(perf_cmd, "perf"))
|
||||||
return perf_cmd;
|
return perf_cmd;
|
||||||
else
|
|
||||||
return prepend("perf-", perf_cmd);
|
return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_man_path(void)
|
static void setup_man_path(void)
|
||||||
{
|
{
|
||||||
struct strbuf new_path = STRBUF_INIT;
|
char *new_path;
|
||||||
const char *old_path = getenv("MANPATH");
|
const char *old_path = getenv("MANPATH");
|
||||||
|
|
||||||
/* We should always put ':' after our path. If there is no
|
/* We should always put ':' after our path. If there is no
|
||||||
* old_path, the ':' at the end will let 'man' to try
|
* old_path, the ':' at the end will let 'man' to try
|
||||||
* system-wide paths after ours to find the manual page. If
|
* system-wide paths after ours to find the manual page. If
|
||||||
* there is old_path, we need ':' as delimiter. */
|
* there is old_path, we need ':' as delimiter. */
|
||||||
strbuf_addstr(&new_path, system_path(PERF_MAN_PATH));
|
if (asprintf(&new_path, "%s:%s", system_path(PERF_MAN_PATH), old_path ?: "") > 0) {
|
||||||
strbuf_addch(&new_path, ':');
|
setenv("MANPATH", new_path, 1);
|
||||||
if (old_path)
|
free(new_path);
|
||||||
strbuf_addstr(&new_path, old_path);
|
} else {
|
||||||
|
error("Unable to setup man path");
|
||||||
setenv("MANPATH", new_path.buf, 1);
|
}
|
||||||
|
|
||||||
strbuf_release(&new_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exec_viewer(const char *name, const char *page)
|
static void exec_viewer(const char *name, const char *page)
|
||||||
|
@ -380,7 +376,7 @@ static int show_info_page(const char *perf_cmd)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_html_page_path(struct strbuf *page_path, const char *page)
|
static int get_html_page_path(char **page_path, const char *page)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
const char *html_path = system_path(PERF_HTML_PATH);
|
const char *html_path = system_path(PERF_HTML_PATH);
|
||||||
|
@ -392,10 +388,7 @@ static int get_html_page_path(struct strbuf *page_path, const char *page)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_init(page_path, 0);
|
return asprintf(page_path, "%s/%s.html", html_path, page);
|
||||||
strbuf_addf(page_path, "%s/%s.html", html_path, page);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -413,12 +406,12 @@ static void open_html(const char *path)
|
||||||
static int show_html_page(const char *perf_cmd)
|
static int show_html_page(const char *perf_cmd)
|
||||||
{
|
{
|
||||||
const char *page = cmd_to_page(perf_cmd);
|
const char *page = cmd_to_page(perf_cmd);
|
||||||
struct strbuf page_path; /* it leaks but we exec bellow */
|
char *page_path; /* it leaks but we exec bellow */
|
||||||
|
|
||||||
if (get_html_page_path(&page_path, page) != 0)
|
if (get_html_page_path(&page_path, page) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
open_html(page_path.buf);
|
open_html(page_path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,8 +131,7 @@ static int copy_bytes(struct perf_inject *inject, int fd, off_t size)
|
||||||
|
|
||||||
static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,
|
static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
struct perf_session *session
|
struct perf_session *session)
|
||||||
__maybe_unused)
|
|
||||||
{
|
{
|
||||||
struct perf_inject *inject = container_of(tool, struct perf_inject,
|
struct perf_inject *inject = container_of(tool, struct perf_inject,
|
||||||
tool);
|
tool);
|
||||||
|
@ -417,9 +416,6 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
|
||||||
{
|
{
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
u8 cpumode;
|
|
||||||
|
|
||||||
cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
|
|
||||||
thread = machine__findnew_thread(machine, sample->pid, sample->tid);
|
thread = machine__findnew_thread(machine, sample->pid, sample->tid);
|
||||||
if (thread == NULL) {
|
if (thread == NULL) {
|
||||||
|
@ -428,7 +424,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
|
||||||
goto repipe;
|
goto repipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al);
|
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al);
|
||||||
|
|
||||||
if (al.map != NULL) {
|
if (al.map != NULL) {
|
||||||
if (!al.map->dso->hit) {
|
if (!al.map->dso->hit) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ dump_raw_samples(struct perf_tool *tool,
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
||||||
event->header.type);
|
event->header.type);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
|
#include <linux/stringify.h>
|
||||||
|
|
||||||
struct report {
|
struct report {
|
||||||
struct perf_tool tool;
|
struct perf_tool tool;
|
||||||
|
@ -154,7 +155,7 @@ static int process_sample_event(struct perf_tool *tool,
|
||||||
};
|
};
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
pr_debug("problem processing %d event, skipping it.\n",
|
pr_debug("problem processing %d event, skipping it.\n",
|
||||||
event->header.type);
|
event->header.type);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -405,9 +405,7 @@ out:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_sample_iregs(union perf_event *event __maybe_unused,
|
static void print_sample_iregs(struct perf_sample *sample,
|
||||||
struct perf_sample *sample,
|
|
||||||
struct thread *thread __maybe_unused,
|
|
||||||
struct perf_event_attr *attr)
|
struct perf_event_attr *attr)
|
||||||
{
|
{
|
||||||
struct regs_dump *regs = &sample->intr_regs;
|
struct regs_dump *regs = &sample->intr_regs;
|
||||||
|
@ -476,10 +474,7 @@ mispred_str(struct branch_entry *br)
|
||||||
return br->flags.predicted ? 'P' : 'M';
|
return br->flags.predicted ? 'P' : 'M';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_sample_brstack(union perf_event *event __maybe_unused,
|
static void print_sample_brstack(struct perf_sample *sample)
|
||||||
struct perf_sample *sample,
|
|
||||||
struct thread *thread __maybe_unused,
|
|
||||||
struct perf_event_attr *attr __maybe_unused)
|
|
||||||
{
|
{
|
||||||
struct branch_stack *br = sample->branch_stack;
|
struct branch_stack *br = sample->branch_stack;
|
||||||
u64 i;
|
u64 i;
|
||||||
|
@ -498,14 +493,11 @@ static void print_sample_brstack(union perf_event *event __maybe_unused,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_sample_brstacksym(union perf_event *event __maybe_unused,
|
static void print_sample_brstacksym(struct perf_sample *sample,
|
||||||
struct perf_sample *sample,
|
struct thread *thread)
|
||||||
struct thread *thread __maybe_unused,
|
|
||||||
struct perf_event_attr *attr __maybe_unused)
|
|
||||||
{
|
{
|
||||||
struct branch_stack *br = sample->branch_stack;
|
struct branch_stack *br = sample->branch_stack;
|
||||||
struct addr_location alf, alt;
|
struct addr_location alf, alt;
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
u64 i, from, to;
|
u64 i, from, to;
|
||||||
|
|
||||||
if (!(br && br->nr))
|
if (!(br && br->nr))
|
||||||
|
@ -518,11 +510,11 @@ static void print_sample_brstacksym(union perf_event *event __maybe_unused,
|
||||||
from = br->entries[i].from;
|
from = br->entries[i].from;
|
||||||
to = br->entries[i].to;
|
to = br->entries[i].to;
|
||||||
|
|
||||||
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, from, &alf);
|
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
|
||||||
if (alf.map)
|
if (alf.map)
|
||||||
alf.sym = map__find_symbol(alf.map, alf.addr, NULL);
|
alf.sym = map__find_symbol(alf.map, alf.addr, NULL);
|
||||||
|
|
||||||
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, to, &alt);
|
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
|
||||||
if (alt.map)
|
if (alt.map)
|
||||||
alt.sym = map__find_symbol(alt.map, alt.addr, NULL);
|
alt.sym = map__find_symbol(alt.map, alt.addr, NULL);
|
||||||
|
|
||||||
|
@ -538,8 +530,7 @@ static void print_sample_brstacksym(union perf_event *event __maybe_unused,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_sample_addr(union perf_event *event,
|
static void print_sample_addr(struct perf_sample *sample,
|
||||||
struct perf_sample *sample,
|
|
||||||
struct thread *thread,
|
struct thread *thread,
|
||||||
struct perf_event_attr *attr)
|
struct perf_event_attr *attr)
|
||||||
{
|
{
|
||||||
|
@ -550,7 +541,7 @@ static void print_sample_addr(union perf_event *event,
|
||||||
if (!sample_addr_correlates_sym(attr))
|
if (!sample_addr_correlates_sym(attr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
perf_event__preprocess_sample_addr(event, sample, thread, &al);
|
thread__resolve(thread, &al, sample);
|
||||||
|
|
||||||
if (PRINT_FIELD(SYM)) {
|
if (PRINT_FIELD(SYM)) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
@ -567,8 +558,7 @@ static void print_sample_addr(union perf_event *event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_sample_bts(union perf_event *event,
|
static void print_sample_bts(struct perf_sample *sample,
|
||||||
struct perf_sample *sample,
|
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct thread *thread,
|
struct thread *thread,
|
||||||
struct addr_location *al)
|
struct addr_location *al)
|
||||||
|
@ -598,7 +588,7 @@ static void print_sample_bts(union perf_event *event,
|
||||||
((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
|
((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
|
||||||
!output[attr->type].user_set)) {
|
!output[attr->type].user_set)) {
|
||||||
printf(" => ");
|
printf(" => ");
|
||||||
print_sample_addr(event, sample, thread, attr);
|
print_sample_addr(sample, thread, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print_srcline_last)
|
if (print_srcline_last)
|
||||||
|
@ -747,7 +737,7 @@ static size_t data_src__printf(u64 data_src)
|
||||||
return printf("%-*s", maxlen, out);
|
return printf("%-*s", maxlen, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_event(struct perf_script *script, union perf_event *event,
|
static void process_event(struct perf_script *script,
|
||||||
struct perf_sample *sample, struct perf_evsel *evsel,
|
struct perf_sample *sample, struct perf_evsel *evsel,
|
||||||
struct addr_location *al)
|
struct addr_location *al)
|
||||||
{
|
{
|
||||||
|
@ -776,7 +766,7 @@ static void process_event(struct perf_script *script, union perf_event *event,
|
||||||
print_sample_flags(sample->flags);
|
print_sample_flags(sample->flags);
|
||||||
|
|
||||||
if (is_bts_event(attr)) {
|
if (is_bts_event(attr)) {
|
||||||
print_sample_bts(event, sample, evsel, thread, al);
|
print_sample_bts(sample, evsel, thread, al);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,7 +774,7 @@ static void process_event(struct perf_script *script, union perf_event *event,
|
||||||
event_format__print(evsel->tp_format, sample->cpu,
|
event_format__print(evsel->tp_format, sample->cpu,
|
||||||
sample->raw_data, sample->raw_size);
|
sample->raw_data, sample->raw_size);
|
||||||
if (PRINT_FIELD(ADDR))
|
if (PRINT_FIELD(ADDR))
|
||||||
print_sample_addr(event, sample, thread, attr);
|
print_sample_addr(sample, thread, attr);
|
||||||
|
|
||||||
if (PRINT_FIELD(DATA_SRC))
|
if (PRINT_FIELD(DATA_SRC))
|
||||||
data_src__printf(sample->data_src);
|
data_src__printf(sample->data_src);
|
||||||
|
@ -804,12 +794,12 @@ static void process_event(struct perf_script *script, union perf_event *event,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PRINT_FIELD(IREGS))
|
if (PRINT_FIELD(IREGS))
|
||||||
print_sample_iregs(event, sample, thread, attr);
|
print_sample_iregs(sample, attr);
|
||||||
|
|
||||||
if (PRINT_FIELD(BRSTACK))
|
if (PRINT_FIELD(BRSTACK))
|
||||||
print_sample_brstack(event, sample, thread, attr);
|
print_sample_brstack(sample);
|
||||||
else if (PRINT_FIELD(BRSTACKSYM))
|
else if (PRINT_FIELD(BRSTACKSYM))
|
||||||
print_sample_brstacksym(event, sample, thread, attr);
|
print_sample_brstacksym(sample, thread);
|
||||||
|
|
||||||
if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
|
if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
|
||||||
print_sample_bpf_output(sample);
|
print_sample_bpf_output(sample);
|
||||||
|
@ -905,7 +895,7 @@ static int process_sample_event(struct perf_tool *tool,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
pr_err("problem processing %d event, skipping it.\n",
|
pr_err("problem processing %d event, skipping it.\n",
|
||||||
event->header.type);
|
event->header.type);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -920,7 +910,7 @@ static int process_sample_event(struct perf_tool *tool,
|
||||||
if (scripting_ops)
|
if (scripting_ops)
|
||||||
scripting_ops->process_event(event, sample, evsel, &al);
|
scripting_ops->process_event(event, sample, evsel, &al);
|
||||||
else
|
else
|
||||||
process_event(scr, event, sample, evsel, &al);
|
process_event(scr, sample, evsel, &al);
|
||||||
|
|
||||||
out_put:
|
out_put:
|
||||||
addr_location__put(&al);
|
addr_location__put(&al);
|
||||||
|
|
|
@ -489,7 +489,7 @@ static const char *cat_backtrace(union perf_event *event,
|
||||||
if (!chain)
|
if (!chain)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
||||||
event->header.type);
|
event->header.type);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <linux/stringify.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
static volatile int done;
|
static volatile int done;
|
||||||
|
@ -728,7 +729,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
|
||||||
if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
|
if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
|
||||||
top->exact_samples++;
|
top->exact_samples++;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0)
|
if (machine__resolve(machine, &al, sample) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!top->kptr_restrict_warned &&
|
if (!top->kptr_restrict_warned &&
|
||||||
|
@ -809,7 +810,6 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
|
||||||
struct perf_session *session = top->session;
|
struct perf_session *session = top->session;
|
||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
struct machine *machine;
|
struct machine *machine;
|
||||||
u8 origin;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
|
while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
|
||||||
|
@ -822,12 +822,10 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
|
||||||
evsel = perf_evlist__id2evsel(session->evlist, sample.id);
|
evsel = perf_evlist__id2evsel(session->evlist, sample.id);
|
||||||
assert(evsel != NULL);
|
assert(evsel != NULL);
|
||||||
|
|
||||||
origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
|
|
||||||
if (event->header.type == PERF_RECORD_SAMPLE)
|
if (event->header.type == PERF_RECORD_SAMPLE)
|
||||||
++top->samples;
|
++top->samples;
|
||||||
|
|
||||||
switch (origin) {
|
switch (sample.cpumode) {
|
||||||
case PERF_RECORD_MISC_USER:
|
case PERF_RECORD_MISC_USER:
|
||||||
++top->us_samples;
|
++top->us_samples;
|
||||||
if (top->hide_user_symbols)
|
if (top->hide_user_symbols)
|
||||||
|
|
|
@ -2256,11 +2256,10 @@ static void print_location(FILE *f, struct perf_sample *sample,
|
||||||
|
|
||||||
static int trace__pgfault(struct trace *trace,
|
static int trace__pgfault(struct trace *trace,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
union perf_event *event,
|
union perf_event *event __maybe_unused,
|
||||||
struct perf_sample *sample)
|
struct perf_sample *sample)
|
||||||
{
|
{
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
char map_type = 'd';
|
char map_type = 'd';
|
||||||
struct thread_trace *ttrace;
|
struct thread_trace *ttrace;
|
||||||
|
@ -2279,7 +2278,7 @@ static int trace__pgfault(struct trace *trace,
|
||||||
if (trace->summary_only)
|
if (trace->summary_only)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
|
thread__find_addr_location(thread, sample->cpumode, MAP__FUNCTION,
|
||||||
sample->ip, &al);
|
sample->ip, &al);
|
||||||
|
|
||||||
trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output);
|
trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output);
|
||||||
|
@ -2292,11 +2291,11 @@ static int trace__pgfault(struct trace *trace,
|
||||||
|
|
||||||
fprintf(trace->output, "] => ");
|
fprintf(trace->output, "] => ");
|
||||||
|
|
||||||
thread__find_addr_location(thread, cpumode, MAP__VARIABLE,
|
thread__find_addr_location(thread, sample->cpumode, MAP__VARIABLE,
|
||||||
sample->addr, &al);
|
sample->addr, &al);
|
||||||
|
|
||||||
if (!al.map) {
|
if (!al.map) {
|
||||||
thread__find_addr_location(thread, cpumode,
|
thread__find_addr_location(thread, sample->cpumode,
|
||||||
MAP__FUNCTION, sample->addr, &al);
|
MAP__FUNCTION, sample->addr, &al);
|
||||||
|
|
||||||
if (al.map)
|
if (al.map)
|
||||||
|
|
|
@ -7,38 +7,38 @@
|
||||||
extern const char perf_usage_string[];
|
extern const char perf_usage_string[];
|
||||||
extern const char perf_more_info_string[];
|
extern const char perf_more_info_string[];
|
||||||
|
|
||||||
extern void list_common_cmds_help(void);
|
void list_common_cmds_help(void);
|
||||||
extern const char *help_unknown_cmd(const char *cmd);
|
const char *help_unknown_cmd(const char *cmd);
|
||||||
extern void prune_packed_objects(int);
|
void prune_packed_objects(int);
|
||||||
extern int read_line_with_nul(char *buf, int size, FILE *file);
|
int read_line_with_nul(char *buf, int size, FILE *file);
|
||||||
extern int check_pager_config(const char *cmd);
|
int check_pager_config(const char *cmd);
|
||||||
|
|
||||||
extern int cmd_annotate(int argc, const char **argv, const char *prefix);
|
int cmd_annotate(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_bench(int argc, const char **argv, const char *prefix);
|
int cmd_bench(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
|
int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_buildid_list(int argc, const char **argv, const char *prefix);
|
int cmd_buildid_list(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_config(int argc, const char **argv, const char *prefix);
|
int cmd_config(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_diff(int argc, const char **argv, const char *prefix);
|
int cmd_diff(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_evlist(int argc, const char **argv, const char *prefix);
|
int cmd_evlist(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_help(int argc, const char **argv, const char *prefix);
|
int cmd_help(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_sched(int argc, const char **argv, const char *prefix);
|
int cmd_sched(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_list(int argc, const char **argv, const char *prefix);
|
int cmd_list(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_record(int argc, const char **argv, const char *prefix);
|
int cmd_record(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_report(int argc, const char **argv, const char *prefix);
|
int cmd_report(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_stat(int argc, const char **argv, const char *prefix);
|
int cmd_stat(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_timechart(int argc, const char **argv, const char *prefix);
|
int cmd_timechart(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_top(int argc, const char **argv, const char *prefix);
|
int cmd_top(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_script(int argc, const char **argv, const char *prefix);
|
int cmd_script(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_version(int argc, const char **argv, const char *prefix);
|
int cmd_version(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_probe(int argc, const char **argv, const char *prefix);
|
int cmd_probe(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_kmem(int argc, const char **argv, const char *prefix);
|
int cmd_kmem(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_lock(int argc, const char **argv, const char *prefix);
|
int cmd_lock(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_kvm(int argc, const char **argv, const char *prefix);
|
int cmd_kvm(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_test(int argc, const char **argv, const char *prefix);
|
int cmd_test(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_trace(int argc, const char **argv, const char *prefix);
|
int cmd_trace(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_inject(int argc, const char **argv, const char *prefix);
|
int cmd_inject(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_mem(int argc, const char **argv, const char *prefix);
|
int cmd_mem(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_data(int argc, const char **argv, const char *prefix);
|
int cmd_data(int argc, const char **argv, const char *prefix);
|
||||||
|
|
||||||
extern int find_scripts(char **scripts_array, char **scripts_path_array);
|
int find_scripts(char **scripts_array, char **scripts_path_array);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -109,7 +109,7 @@ ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
|
||||||
CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
|
CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(src-perf)/config/utilities.mak
|
include $(srctree)/tools/scripts/utilities.mak
|
||||||
|
|
||||||
ifeq ($(call get-executable,$(FLEX)),)
|
ifeq ($(call get-executable,$(FLEX)),)
|
||||||
dummy := $(error Error: $(FLEX) is missing on this system, please install it)
|
dummy := $(error Error: $(FLEX) is missing on this system, please install it)
|
||||||
|
|
|
@ -293,7 +293,6 @@ static int process_sample_event(struct machine *machine,
|
||||||
{
|
{
|
||||||
struct perf_sample sample;
|
struct perf_sample sample;
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
u8 cpumode;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (perf_evlist__parse_sample(evlist, event, &sample)) {
|
if (perf_evlist__parse_sample(evlist, event, &sample)) {
|
||||||
|
@ -307,9 +306,7 @@ static int process_sample_event(struct machine *machine,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
ret = read_object_code(sample.ip, READLEN, sample.cpumode, thread, state);
|
||||||
|
|
||||||
ret = read_object_code(sample.ip, READLEN, cpumode, thread, state);
|
|
||||||
thread__put(thread);
|
thread__put(thread);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
|
|
||||||
static int mmap_handler(struct perf_tool *tool __maybe_unused,
|
static int mmap_handler(struct perf_tool *tool __maybe_unused,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
struct perf_sample *sample __maybe_unused,
|
struct perf_sample *sample,
|
||||||
struct machine *machine)
|
struct machine *machine)
|
||||||
{
|
{
|
||||||
return machine__process_mmap2_event(machine, event, NULL);
|
return machine__process_mmap2_event(machine, event, sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_live_machine(struct machine *machine)
|
static int init_live_machine(struct machine *machine)
|
||||||
|
|
|
@ -100,9 +100,11 @@ struct machine *setup_fake_machine(struct machines *machines)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
|
for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
|
||||||
|
struct perf_sample sample = {
|
||||||
|
.cpumode = PERF_RECORD_MISC_USER,
|
||||||
|
};
|
||||||
union perf_event fake_mmap_event = {
|
union perf_event fake_mmap_event = {
|
||||||
.mmap = {
|
.mmap = {
|
||||||
.header = { .misc = PERF_RECORD_MISC_USER, },
|
|
||||||
.pid = fake_mmap_info[i].pid,
|
.pid = fake_mmap_info[i].pid,
|
||||||
.tid = fake_mmap_info[i].pid,
|
.tid = fake_mmap_info[i].pid,
|
||||||
.start = fake_mmap_info[i].start,
|
.start = fake_mmap_info[i].start,
|
||||||
|
@ -114,7 +116,7 @@ struct machine *setup_fake_machine(struct machines *machines)
|
||||||
strcpy(fake_mmap_event.mmap.filename,
|
strcpy(fake_mmap_event.mmap.filename,
|
||||||
fake_mmap_info[i].filename);
|
fake_mmap_info[i].filename);
|
||||||
|
|
||||||
machine__process_mmap_event(machine, &fake_mmap_event, NULL);
|
machine__process_mmap_event(machine, &fake_mmap_event, &sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
|
for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
|
||||||
|
|
|
@ -81,11 +81,6 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
||||||
const union perf_event event = {
|
|
||||||
.header = {
|
|
||||||
.misc = PERF_RECORD_MISC_USER,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
struct hist_entry_iter iter = {
|
struct hist_entry_iter iter = {
|
||||||
.evsel = evsel,
|
.evsel = evsel,
|
||||||
.sample = &sample,
|
.sample = &sample,
|
||||||
|
@ -97,13 +92,13 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
|
||||||
else
|
else
|
||||||
iter.ops = &hist_iter_normal;
|
iter.ops = &hist_iter_normal;
|
||||||
|
|
||||||
|
sample.cpumode = PERF_RECORD_MISC_USER;
|
||||||
sample.pid = fake_samples[i].pid;
|
sample.pid = fake_samples[i].pid;
|
||||||
sample.tid = fake_samples[i].pid;
|
sample.tid = fake_samples[i].pid;
|
||||||
sample.ip = fake_samples[i].ip;
|
sample.ip = fake_samples[i].ip;
|
||||||
sample.callchain = (struct ip_callchain *)fake_callchains[i];
|
sample.callchain = (struct ip_callchain *)fake_callchains[i];
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(&event, machine, &al,
|
if (machine__resolve(machine, &al, &sample) < 0)
|
||||||
&sample) < 0)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
|
if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
|
||||||
|
|
|
@ -58,11 +58,6 @@ static int add_hist_entries(struct perf_evlist *evlist,
|
||||||
*/
|
*/
|
||||||
evlist__for_each(evlist, evsel) {
|
evlist__for_each(evlist, evsel) {
|
||||||
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
||||||
const union perf_event event = {
|
|
||||||
.header = {
|
|
||||||
.misc = PERF_RECORD_MISC_USER,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
struct hist_entry_iter iter = {
|
struct hist_entry_iter iter = {
|
||||||
.evsel = evsel,
|
.evsel = evsel,
|
||||||
.sample = &sample,
|
.sample = &sample,
|
||||||
|
@ -76,12 +71,12 @@ static int add_hist_entries(struct perf_evlist *evlist,
|
||||||
hists->dso_filter = NULL;
|
hists->dso_filter = NULL;
|
||||||
hists->symbol_filter_str = NULL;
|
hists->symbol_filter_str = NULL;
|
||||||
|
|
||||||
|
sample.cpumode = PERF_RECORD_MISC_USER;
|
||||||
sample.pid = fake_samples[i].pid;
|
sample.pid = fake_samples[i].pid;
|
||||||
sample.tid = fake_samples[i].pid;
|
sample.tid = fake_samples[i].pid;
|
||||||
sample.ip = fake_samples[i].ip;
|
sample.ip = fake_samples[i].ip;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(&event, machine, &al,
|
if (machine__resolve(machine, &al, &sample) < 0)
|
||||||
&sample) < 0)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
al.socket = fake_samples[i].socket;
|
al.socket = fake_samples[i].socket;
|
||||||
|
|
|
@ -76,17 +76,12 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
|
||||||
struct hists *hists = evsel__hists(evsel);
|
struct hists *hists = evsel__hists(evsel);
|
||||||
|
|
||||||
for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
|
for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
|
||||||
const union perf_event event = {
|
sample.cpumode = PERF_RECORD_MISC_USER;
|
||||||
.header = {
|
|
||||||
.misc = PERF_RECORD_MISC_USER,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
sample.pid = fake_common_samples[k].pid;
|
sample.pid = fake_common_samples[k].pid;
|
||||||
sample.tid = fake_common_samples[k].pid;
|
sample.tid = fake_common_samples[k].pid;
|
||||||
sample.ip = fake_common_samples[k].ip;
|
sample.ip = fake_common_samples[k].ip;
|
||||||
if (perf_event__preprocess_sample(&event, machine, &al,
|
|
||||||
&sample) < 0)
|
if (machine__resolve(machine, &al, &sample) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
he = __hists__add_entry(hists, &al, NULL,
|
he = __hists__add_entry(hists, &al, NULL,
|
||||||
|
@ -102,17 +97,10 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) {
|
for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) {
|
||||||
const union perf_event event = {
|
|
||||||
.header = {
|
|
||||||
.misc = PERF_RECORD_MISC_USER,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
sample.pid = fake_samples[i][k].pid;
|
sample.pid = fake_samples[i][k].pid;
|
||||||
sample.tid = fake_samples[i][k].pid;
|
sample.tid = fake_samples[i][k].pid;
|
||||||
sample.ip = fake_samples[i][k].ip;
|
sample.ip = fake_samples[i][k].ip;
|
||||||
if (perf_event__preprocess_sample(&event, machine, &al,
|
if (machine__resolve(machine, &al, &sample) < 0)
|
||||||
&sample) < 0)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
he = __hists__add_entry(hists, &al, NULL,
|
he = __hists__add_entry(hists, &al, NULL,
|
||||||
|
|
|
@ -51,11 +51,6 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
||||||
const union perf_event event = {
|
|
||||||
.header = {
|
|
||||||
.misc = PERF_RECORD_MISC_USER,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
struct hist_entry_iter iter = {
|
struct hist_entry_iter iter = {
|
||||||
.evsel = evsel,
|
.evsel = evsel,
|
||||||
.sample = &sample,
|
.sample = &sample,
|
||||||
|
@ -63,13 +58,13 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
|
||||||
.hide_unresolved = false,
|
.hide_unresolved = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sample.cpumode = PERF_RECORD_MISC_USER;
|
||||||
sample.cpu = fake_samples[i].cpu;
|
sample.cpu = fake_samples[i].cpu;
|
||||||
sample.pid = fake_samples[i].pid;
|
sample.pid = fake_samples[i].pid;
|
||||||
sample.tid = fake_samples[i].pid;
|
sample.tid = fake_samples[i].pid;
|
||||||
sample.ip = fake_samples[i].ip;
|
sample.ip = fake_samples[i].ip;
|
||||||
|
|
||||||
if (perf_event__preprocess_sample(&event, machine, &al,
|
if (machine__resolve(machine, &al, &sample) < 0)
|
||||||
&sample) < 0)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
|
if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
|
||||||
|
|
|
@ -55,7 +55,7 @@ static u64 he_get_acc_##_field(struct hist_entry *he) \
|
||||||
return he->stat_acc->_field; \
|
return he->stat_acc->_field; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \
|
static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt, \
|
||||||
struct perf_hpp *hpp, \
|
struct perf_hpp *hpp, \
|
||||||
struct hist_entry *he) \
|
struct hist_entry *he) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
libperf-y += abspath.o
|
|
||||||
libperf-y += alias.o
|
libperf-y += alias.o
|
||||||
libperf-y += annotate.o
|
libperf-y += annotate.o
|
||||||
libperf-y += build-id.o
|
libperf-y += build-id.o
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
#include "cache.h"
|
|
||||||
|
|
||||||
static const char *get_pwd_cwd(void)
|
|
||||||
{
|
|
||||||
static char cwd[PATH_MAX + 1];
|
|
||||||
char *pwd;
|
|
||||||
struct stat cwd_stat, pwd_stat;
|
|
||||||
if (getcwd(cwd, PATH_MAX) == NULL)
|
|
||||||
return NULL;
|
|
||||||
pwd = getenv("PWD");
|
|
||||||
if (pwd && strcmp(pwd, cwd)) {
|
|
||||||
stat(cwd, &cwd_stat);
|
|
||||||
if (!stat(pwd, &pwd_stat) &&
|
|
||||||
pwd_stat.st_dev == cwd_stat.st_dev &&
|
|
||||||
pwd_stat.st_ino == cwd_stat.st_ino) {
|
|
||||||
strlcpy(cwd, pwd, PATH_MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cwd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *make_nonrelative_path(const char *path)
|
|
||||||
{
|
|
||||||
static char buf[PATH_MAX + 1];
|
|
||||||
|
|
||||||
if (is_absolute_path(path)) {
|
|
||||||
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
|
|
||||||
die("Too long path: %.*s", 60, path);
|
|
||||||
} else {
|
|
||||||
const char *cwd = get_pwd_cwd();
|
|
||||||
if (!cwd)
|
|
||||||
die("Cannot determine the current working directory");
|
|
||||||
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
|
|
||||||
die("Too long path: %.*s", 60, path);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
|
@ -158,7 +158,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
|
||||||
|
|
||||||
int hist_entry__annotate(struct hist_entry *he, size_t privsize);
|
int hist_entry__annotate(struct hist_entry *he, size_t privsize);
|
||||||
|
|
||||||
int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym);
|
int symbol__annotate_init(struct map *map, struct symbol *sym);
|
||||||
int symbol__annotate_printf(struct symbol *sym, struct map *map,
|
int symbol__annotate_printf(struct symbol *sym, struct map *map,
|
||||||
struct perf_evsel *evsel, bool full_paths,
|
struct perf_evsel *evsel, bool full_paths,
|
||||||
int min_pcnt, int max_lines, int context);
|
int min_pcnt, int max_lines, int context);
|
||||||
|
|
|
@ -517,7 +517,7 @@ static inline void auxtrace__free(struct perf_session *session)
|
||||||
|
|
||||||
static inline struct auxtrace_record *
|
static inline struct auxtrace_record *
|
||||||
auxtrace_record__init(struct perf_evlist *evlist __maybe_unused,
|
auxtrace_record__init(struct perf_evlist *evlist __maybe_unused,
|
||||||
int *err __maybe_unused)
|
int *err)
|
||||||
{
|
{
|
||||||
*err = 0;
|
*err = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -28,7 +28,6 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
|
||||||
struct machine *machine)
|
struct machine *machine)
|
||||||
{
|
{
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
struct thread *thread = machine__findnew_thread(machine, sample->pid,
|
struct thread *thread = machine__findnew_thread(machine, sample->pid,
|
||||||
sample->tid);
|
sample->tid);
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al);
|
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al);
|
||||||
|
|
||||||
if (al.map != NULL)
|
if (al.map != NULL)
|
||||||
al.map->dso->hit = 1;
|
al.map->dso->hit = 1;
|
||||||
|
|
|
@ -26,14 +26,14 @@
|
||||||
extern const char *config_exclusive_filename;
|
extern const char *config_exclusive_filename;
|
||||||
|
|
||||||
typedef int (*config_fn_t)(const char *, const char *, void *);
|
typedef int (*config_fn_t)(const char *, const char *, void *);
|
||||||
extern int perf_default_config(const char *, const char *, void *);
|
int perf_default_config(const char *, const char *, void *);
|
||||||
extern int perf_config(config_fn_t fn, void *);
|
int perf_config(config_fn_t fn, void *);
|
||||||
extern int perf_config_int(const char *, const char *);
|
int perf_config_int(const char *, const char *);
|
||||||
extern u64 perf_config_u64(const char *, const char *);
|
u64 perf_config_u64(const char *, const char *);
|
||||||
extern int perf_config_bool(const char *, const char *);
|
int perf_config_bool(const char *, const char *);
|
||||||
extern int config_error_nonbool(const char *);
|
int config_error_nonbool(const char *);
|
||||||
extern const char *perf_config_dirname(const char *, const char *);
|
const char *perf_config_dirname(const char *, const char *);
|
||||||
extern const char *perf_etc_perfconfig(void);
|
const char *perf_etc_perfconfig(void);
|
||||||
|
|
||||||
char *alias_lookup(const char *alias);
|
char *alias_lookup(const char *alias);
|
||||||
int split_cmdline(char *cmdline, const char ***argv);
|
int split_cmdline(char *cmdline, const char ***argv);
|
||||||
|
@ -64,13 +64,9 @@ static inline int is_absolute_path(const char *path)
|
||||||
return path[0] == '/';
|
return path[0] == '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *make_nonrelative_path(const char *path);
|
|
||||||
char *strip_path_suffix(const char *path, const char *suffix);
|
char *strip_path_suffix(const char *path, const char *suffix);
|
||||||
|
|
||||||
extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||||
extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||||
|
|
||||||
extern char *perf_pathdup(const char *fmt, ...)
|
|
||||||
__attribute__((format (printf, 1, 2)));
|
|
||||||
|
|
||||||
#endif /* __PERF_CACHE_H */
|
#endif /* __PERF_CACHE_H */
|
||||||
|
|
|
@ -220,7 +220,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
|
||||||
bool hide_unresolved);
|
bool hide_unresolved);
|
||||||
|
|
||||||
extern const char record_callchain_help[];
|
extern const char record_callchain_help[];
|
||||||
extern int parse_callchain_record(const char *arg, struct callchain_param *param);
|
int parse_callchain_record(const char *arg, struct callchain_param *param);
|
||||||
int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
|
int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
|
||||||
int parse_callchain_report_opt(const char *arg);
|
int parse_callchain_report_opt(const char *arg);
|
||||||
int parse_callchain_top_opt(const char *arg);
|
int parse_callchain_top_opt(const char *arg);
|
||||||
|
@ -236,7 +236,7 @@ static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SKIP_CALLCHAIN_IDX
|
#ifdef HAVE_SKIP_CALLCHAIN_IDX
|
||||||
extern int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain);
|
int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain);
|
||||||
#else
|
#else
|
||||||
static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
|
static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
|
||||||
struct ip_callchain *chain __maybe_unused)
|
struct ip_callchain *chain __maybe_unused)
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct cgroup_sel {
|
||||||
|
|
||||||
|
|
||||||
extern int nr_cgroups; /* number of explicit cgroups defined */
|
extern int nr_cgroups; /* number of explicit cgroups defined */
|
||||||
extern void close_cgroup(struct cgroup_sel *cgrp);
|
void close_cgroup(struct cgroup_sel *cgrp);
|
||||||
extern int parse_cgroups(const struct option *opt, const char *str, int unset);
|
int parse_cgroups(const struct option *opt, const char *str, int unset);
|
||||||
|
|
||||||
#endif /* __CGROUP_H__ */
|
#endif /* __CGROUP_H__ */
|
||||||
|
|
|
@ -5,7 +5,7 @@ unsigned long perf_event_open_cloexec_flag(void);
|
||||||
|
|
||||||
#ifdef __GLIBC_PREREQ
|
#ifdef __GLIBC_PREREQ
|
||||||
#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__)
|
#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__)
|
||||||
extern int sched_getcpu(void) __THROW;
|
int sched_getcpu(void) __THROW;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -632,7 +632,7 @@ static bool is_flush_needed(struct ctf_stream *cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_sample_event(struct perf_tool *tool,
|
static int process_sample_event(struct perf_tool *tool,
|
||||||
union perf_event *_event __maybe_unused,
|
union perf_event *_event,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct machine *machine __maybe_unused)
|
struct machine *machine __maybe_unused)
|
||||||
|
|
|
@ -333,7 +333,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
|
||||||
sample_addr_correlates_sym(&evsel->attr)) {
|
sample_addr_correlates_sym(&evsel->attr)) {
|
||||||
struct addr_location addr_al;
|
struct addr_location addr_al;
|
||||||
|
|
||||||
perf_event__preprocess_sample_addr(event, sample, thread, &addr_al);
|
thread__resolve(thread, &addr_al, sample);
|
||||||
err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id,
|
err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id,
|
||||||
&es.addr_sym_db_id, &es.addr_offset);
|
&es.addr_sym_db_id, &es.addr_offset);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -162,6 +162,7 @@ struct dso {
|
||||||
u8 loaded;
|
u8 loaded;
|
||||||
u8 rel;
|
u8 rel;
|
||||||
u8 build_id[BUILD_ID_SIZE];
|
u8 build_id[BUILD_ID_SIZE];
|
||||||
|
u64 text_offset;
|
||||||
const char *short_name;
|
const char *short_name;
|
||||||
const char *long_name;
|
const char *long_name;
|
||||||
u16 long_name_len;
|
u16 long_name_len;
|
||||||
|
@ -301,7 +302,7 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
int dso__data_get_fd(struct dso *dso, struct machine *machine);
|
int dso__data_get_fd(struct dso *dso, struct machine *machine);
|
||||||
void dso__data_put_fd(struct dso *dso __maybe_unused);
|
void dso__data_put_fd(struct dso *dso);
|
||||||
void dso__data_close(struct dso *dso);
|
void dso__data_close(struct dso *dso);
|
||||||
|
|
||||||
off_t dso__data_size(struct dso *dso, struct machine *machine);
|
off_t dso__data_size(struct dso *dso, struct machine *machine);
|
||||||
|
|
|
@ -915,7 +915,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
|
||||||
tmp = "*";
|
tmp = "*";
|
||||||
else if (tag == DW_TAG_subroutine_type) {
|
else if (tag == DW_TAG_subroutine_type) {
|
||||||
/* Function pointer */
|
/* Function pointer */
|
||||||
strbuf_addf(buf, "(function_type)");
|
strbuf_add(buf, "(function_type)", 15);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (!dwarf_diename(&type))
|
if (!dwarf_diename(&type))
|
||||||
|
@ -932,7 +932,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
|
||||||
}
|
}
|
||||||
ret = die_get_typename(&type, buf);
|
ret = die_get_typename(&type, buf);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
strbuf_addf(buf, "%s", tmp);
|
strbuf_addstr(buf, tmp);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -951,7 +951,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
|
||||||
ret = die_get_typename(vr_die, buf);
|
ret = die_get_typename(vr_die, buf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_debug("Failed to get type, make it unknown.\n");
|
pr_debug("Failed to get type, make it unknown.\n");
|
||||||
strbuf_addf(buf, "(unknown_type)");
|
strbuf_add(buf, " (unknown_type)", 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
|
strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
|
||||||
|
@ -1013,7 +1013,7 @@ static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
strbuf_addf(buf, "]>");
|
strbuf_add(buf, "]>", 2);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(scopes);
|
free(scopes);
|
||||||
|
@ -1076,7 +1076,7 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
strbuf_addf(buf, "]>");
|
strbuf_add(buf, "]>", 2);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,48 +25,48 @@
|
||||||
#include <elfutils/version.h>
|
#include <elfutils/version.h>
|
||||||
|
|
||||||
/* Find the realpath of the target file */
|
/* Find the realpath of the target file */
|
||||||
extern const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname);
|
const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname);
|
||||||
|
|
||||||
/* Get DW_AT_comp_dir (should be NULL with older gcc) */
|
/* Get DW_AT_comp_dir (should be NULL with older gcc) */
|
||||||
extern const char *cu_get_comp_dir(Dwarf_Die *cu_die);
|
const char *cu_get_comp_dir(Dwarf_Die *cu_die);
|
||||||
|
|
||||||
/* Get a line number and file name for given address */
|
/* Get a line number and file name for given address */
|
||||||
extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
|
int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
|
||||||
const char **fname, int *lineno);
|
const char **fname, int *lineno);
|
||||||
|
|
||||||
/* Walk on funcitons at given address */
|
/* Walk on funcitons at given address */
|
||||||
extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||||
int (*callback)(Dwarf_Die *, void *), void *data);
|
int (*callback)(Dwarf_Die *, void *), void *data);
|
||||||
|
|
||||||
/* Ensure that this DIE is a subprogram and definition (not declaration) */
|
/* Ensure that this DIE is a subprogram and definition (not declaration) */
|
||||||
extern bool die_is_func_def(Dwarf_Die *dw_die);
|
bool die_is_func_def(Dwarf_Die *dw_die);
|
||||||
|
|
||||||
/* Ensure that this DIE is an instance of a subprogram */
|
/* Ensure that this DIE is an instance of a subprogram */
|
||||||
extern bool die_is_func_instance(Dwarf_Die *dw_die);
|
bool die_is_func_instance(Dwarf_Die *dw_die);
|
||||||
|
|
||||||
/* Compare diename and tname */
|
/* Compare diename and tname */
|
||||||
extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
|
bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
|
||||||
|
|
||||||
/* Matching diename with glob pattern */
|
/* Matching diename with glob pattern */
|
||||||
extern bool die_match_name(Dwarf_Die *dw_die, const char *glob);
|
bool die_match_name(Dwarf_Die *dw_die, const char *glob);
|
||||||
|
|
||||||
/* Get callsite line number of inline-function instance */
|
/* Get callsite line number of inline-function instance */
|
||||||
extern int die_get_call_lineno(Dwarf_Die *in_die);
|
int die_get_call_lineno(Dwarf_Die *in_die);
|
||||||
|
|
||||||
/* Get callsite file name of inlined function instance */
|
/* Get callsite file name of inlined function instance */
|
||||||
extern const char *die_get_call_file(Dwarf_Die *in_die);
|
const char *die_get_call_file(Dwarf_Die *in_die);
|
||||||
|
|
||||||
/* Get type die */
|
/* Get type die */
|
||||||
extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
|
Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Get a type die, but skip qualifiers and typedef */
|
/* Get a type die, but skip qualifiers and typedef */
|
||||||
extern Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
|
Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Check whether the DIE is signed or not */
|
/* Check whether the DIE is signed or not */
|
||||||
extern bool die_is_signed_type(Dwarf_Die *tp_die);
|
bool die_is_signed_type(Dwarf_Die *tp_die);
|
||||||
|
|
||||||
/* Get data_member_location offset */
|
/* Get data_member_location offset */
|
||||||
extern int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs);
|
int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs);
|
||||||
|
|
||||||
/* Return values for die_find_child() callbacks */
|
/* Return values for die_find_child() callbacks */
|
||||||
enum {
|
enum {
|
||||||
|
@ -77,29 +77,29 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Search child DIEs */
|
/* Search child DIEs */
|
||||||
extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
|
Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
|
||||||
int (*callback)(Dwarf_Die *, void *),
|
int (*callback)(Dwarf_Die *, void *),
|
||||||
void *data, Dwarf_Die *die_mem);
|
void *data, Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Search a non-inlined function including given address */
|
/* Search a non-inlined function including given address */
|
||||||
extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Search a non-inlined function with tail call at given address */
|
/* Search a non-inlined function with tail call at given address */
|
||||||
Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Search the top inlined function including given address */
|
/* Search the top inlined function including given address */
|
||||||
extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Search the deepest inlined function including given address */
|
/* Search the deepest inlined function including given address */
|
||||||
extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Walk on the instances of given DIE */
|
/* Walk on the instances of given DIE */
|
||||||
extern int die_walk_instances(Dwarf_Die *in_die,
|
int die_walk_instances(Dwarf_Die *in_die,
|
||||||
int (*callback)(Dwarf_Die *, void *), void *data);
|
int (*callback)(Dwarf_Die *, void *), void *data);
|
||||||
|
|
||||||
/* Walker on lines (Note: line number will not be sorted) */
|
/* Walker on lines (Note: line number will not be sorted) */
|
||||||
typedef int (* line_walk_callback_t) (const char *fname, int lineno,
|
typedef int (* line_walk_callback_t) (const char *fname, int lineno,
|
||||||
|
@ -109,22 +109,20 @@ typedef int (* line_walk_callback_t) (const char *fname, int lineno,
|
||||||
* Walk on lines inside given DIE. If the DIE is a subprogram, walk only on
|
* Walk on lines inside given DIE. If the DIE is a subprogram, walk only on
|
||||||
* the lines inside the subprogram, otherwise the DIE must be a CU DIE.
|
* the lines inside the subprogram, otherwise the DIE must be a CU DIE.
|
||||||
*/
|
*/
|
||||||
extern int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback,
|
int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data);
|
||||||
void *data);
|
|
||||||
|
|
||||||
/* Find a variable called 'name' at given address */
|
/* Find a variable called 'name' at given address */
|
||||||
extern Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
|
Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
|
||||||
Dwarf_Addr addr, Dwarf_Die *die_mem);
|
Dwarf_Addr addr, Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Find a member called 'name' */
|
/* Find a member called 'name' */
|
||||||
extern Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
|
Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Get the name of given variable DIE */
|
/* Get the name of given variable DIE */
|
||||||
extern int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf);
|
int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf);
|
||||||
|
|
||||||
/* Get the name and type of given variable DIE, stored as "type\tname" */
|
/* Get the name and type of given variable DIE, stored as "type\tname" */
|
||||||
extern int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf);
|
int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf);
|
||||||
extern int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
|
int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf);
|
||||||
struct strbuf *buf);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1295,12 +1295,9 @@ void thread__find_addr_location(struct thread *thread,
|
||||||
* Callers need to drop the reference to al->thread, obtained in
|
* Callers need to drop the reference to al->thread, obtained in
|
||||||
* machine__findnew_thread()
|
* machine__findnew_thread()
|
||||||
*/
|
*/
|
||||||
int perf_event__preprocess_sample(const union perf_event *event,
|
int machine__resolve(struct machine *machine, struct addr_location *al,
|
||||||
struct machine *machine,
|
struct perf_sample *sample)
|
||||||
struct addr_location *al,
|
|
||||||
struct perf_sample *sample)
|
|
||||||
{
|
{
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
struct thread *thread = machine__findnew_thread(machine, sample->pid,
|
struct thread *thread = machine__findnew_thread(machine, sample->pid,
|
||||||
sample->tid);
|
sample->tid);
|
||||||
|
|
||||||
|
@ -1315,11 +1312,11 @@ int perf_event__preprocess_sample(const union perf_event *event,
|
||||||
* events, but for older perf.data files there was no such thing, so do
|
* events, but for older perf.data files there was no such thing, so do
|
||||||
* it now.
|
* it now.
|
||||||
*/
|
*/
|
||||||
if (cpumode == PERF_RECORD_MISC_KERNEL &&
|
if (sample->cpumode == PERF_RECORD_MISC_KERNEL &&
|
||||||
machine__kernel_map(machine) == NULL)
|
machine__kernel_map(machine) == NULL)
|
||||||
machine__create_kernel_maps(machine);
|
machine__create_kernel_maps(machine);
|
||||||
|
|
||||||
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al);
|
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, al);
|
||||||
dump_printf(" ...... dso: %s\n",
|
dump_printf(" ...... dso: %s\n",
|
||||||
al->map ? al->map->dso->long_name :
|
al->map ? al->map->dso->long_name :
|
||||||
al->level == 'H' ? "[hypervisor]" : "<not found>");
|
al->level == 'H' ? "[hypervisor]" : "<not found>");
|
||||||
|
@ -1395,16 +1392,12 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void perf_event__preprocess_sample_addr(union perf_event *event,
|
void thread__resolve(struct thread *thread, struct addr_location *al,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample)
|
||||||
struct thread *thread,
|
|
||||||
struct addr_location *al)
|
|
||||||
{
|
{
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->addr, al);
|
||||||
|
|
||||||
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->addr, al);
|
|
||||||
if (!al->map)
|
if (!al->map)
|
||||||
thread__find_addr_map(thread, cpumode, MAP__VARIABLE,
|
thread__find_addr_map(thread, sample->cpumode, MAP__VARIABLE,
|
||||||
sample->addr, al);
|
sample->addr, al);
|
||||||
|
|
||||||
al->cpu = sample->cpu;
|
al->cpu = sample->cpu;
|
||||||
|
|
|
@ -192,6 +192,7 @@ struct perf_sample {
|
||||||
u64 data_src;
|
u64 data_src;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
u16 insn_len;
|
u16 insn_len;
|
||||||
|
u8 cpumode;
|
||||||
void *raw_data;
|
void *raw_data;
|
||||||
struct ip_callchain *callchain;
|
struct ip_callchain *callchain;
|
||||||
struct branch_stack *branch_stack;
|
struct branch_stack *branch_stack;
|
||||||
|
@ -597,10 +598,8 @@ int perf_event__process(struct perf_tool *tool,
|
||||||
|
|
||||||
struct addr_location;
|
struct addr_location;
|
||||||
|
|
||||||
int perf_event__preprocess_sample(const union perf_event *event,
|
int machine__resolve(struct machine *machine, struct addr_location *al,
|
||||||
struct machine *machine,
|
struct perf_sample *sample);
|
||||||
struct addr_location *al,
|
|
||||||
struct perf_sample *sample);
|
|
||||||
|
|
||||||
void addr_location__put(struct addr_location *al);
|
void addr_location__put(struct addr_location *al);
|
||||||
|
|
||||||
|
@ -608,10 +607,8 @@ struct thread;
|
||||||
|
|
||||||
bool is_bts_event(struct perf_event_attr *attr);
|
bool is_bts_event(struct perf_event_attr *attr);
|
||||||
bool sample_addr_correlates_sym(struct perf_event_attr *attr);
|
bool sample_addr_correlates_sym(struct perf_event_attr *attr);
|
||||||
void perf_event__preprocess_sample_addr(union perf_event *event,
|
void thread__resolve(struct thread *thread, struct addr_location *al,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample);
|
||||||
struct thread *thread,
|
|
||||||
struct addr_location *al);
|
|
||||||
|
|
||||||
const char *perf_event__name(unsigned int id);
|
const char *perf_event__name(unsigned int id);
|
||||||
|
|
||||||
|
|
|
@ -1643,6 +1643,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
|
||||||
data->stream_id = data->id = data->time = -1ULL;
|
data->stream_id = data->id = data->time = -1ULL;
|
||||||
data->period = evsel->attr.sample_period;
|
data->period = evsel->attr.sample_period;
|
||||||
data->weight = 0;
|
data->weight = 0;
|
||||||
|
data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
||||||
|
|
||||||
if (event->header.type != PERF_RECORD_SAMPLE) {
|
if (event->header.type != PERF_RECORD_SAMPLE) {
|
||||||
if (!evsel->attr.sample_id_all)
|
if (!evsel->attr.sample_id_all)
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
#define __GENELF_H__
|
#define __GENELF_H__
|
||||||
|
|
||||||
/* genelf.c */
|
/* genelf.c */
|
||||||
extern int jit_write_elf(int fd, uint64_t code_addr, const char *sym,
|
int jit_write_elf(int fd, uint64_t code_addr, const char *sym,
|
||||||
const void *code, int csize,
|
const void *code, int csize, void *debug, int nr_debug_entries);
|
||||||
void *debug, int nr_debug_entries);
|
|
||||||
/* genelf_debug.c */
|
/* genelf_debug.c */
|
||||||
extern int jit_add_debug_info(Elf *e, uint64_t code_addr,
|
int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries);
|
||||||
void *debug, int nr_debug_entries);
|
|
||||||
|
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
#define GEN_ELF_ARCH EM_ARM
|
#define GEN_ELF_ARCH EM_ARM
|
||||||
|
|
|
@ -1872,11 +1872,6 @@ static int process_cpu_topology(struct perf_file_section *section,
|
||||||
if (ph->needs_swap)
|
if (ph->needs_swap)
|
||||||
nr = bswap_32(nr);
|
nr = bswap_32(nr);
|
||||||
|
|
||||||
if (nr > (u32)cpu_nr) {
|
|
||||||
pr_debug("core_id number is too big."
|
|
||||||
"You may need to upgrade the perf tool.\n");
|
|
||||||
goto free_cpu;
|
|
||||||
}
|
|
||||||
ph->env.cpu[i].core_id = nr;
|
ph->env.cpu[i].core_id = nr;
|
||||||
|
|
||||||
ret = readn(fd, &nr, sizeof(nr));
|
ret = readn(fd, &nr, sizeof(nr));
|
||||||
|
|
|
@ -121,7 +121,7 @@ int perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
|
||||||
perf_event__handler_t process);
|
perf_event__handler_t process);
|
||||||
int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
|
int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
|
||||||
struct perf_evlist **pevlist);
|
struct perf_evlist **pevlist);
|
||||||
int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
|
int perf_event__process_event_update(struct perf_tool *tool,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
struct perf_evlist **pevlist);
|
struct perf_evlist **pevlist);
|
||||||
size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp);
|
size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp);
|
||||||
|
|
|
@ -670,7 +670,7 @@ iter_prepare_branch_entry(struct hist_entry_iter *iter, struct addr_location *al
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iter_add_single_branch_entry(struct hist_entry_iter *iter __maybe_unused,
|
iter_add_single_branch_entry(struct hist_entry_iter *iter,
|
||||||
struct addr_location *al __maybe_unused)
|
struct addr_location *al __maybe_unused)
|
||||||
{
|
{
|
||||||
/* to avoid calling callback function */
|
/* to avoid calling callback function */
|
||||||
|
|
|
@ -433,8 +433,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
|
||||||
struct perf_sample *sample, bool nonany_branch_mode);
|
struct perf_sample *sample, bool nonany_branch_mode);
|
||||||
|
|
||||||
struct option;
|
struct option;
|
||||||
int parse_filter_percentage(const struct option *opt __maybe_unused,
|
int parse_filter_percentage(const struct option *opt, const char *arg, int unset);
|
||||||
const char *arg, int unset __maybe_unused);
|
|
||||||
int perf_hist_config(const char *var, const char *value);
|
int perf_hist_config(const char *var, const char *value);
|
||||||
|
|
||||||
void perf_hpp_list__init(struct perf_hpp_list *list);
|
void perf_hpp_list__init(struct perf_hpp_list *list);
|
||||||
|
|
|
@ -678,7 +678,7 @@ static int intel_bts_process_auxtrace_event(struct perf_session *session,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int intel_bts_flush(struct perf_session *session __maybe_unused,
|
static int intel_bts_flush(struct perf_session *session,
|
||||||
struct perf_tool *tool __maybe_unused)
|
struct perf_tool *tool __maybe_unused)
|
||||||
{
|
{
|
||||||
struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
|
struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
|
||||||
|
|
|
@ -3,13 +3,9 @@
|
||||||
|
|
||||||
#include <data.h>
|
#include <data.h>
|
||||||
|
|
||||||
extern int jit_process(struct perf_session *session,
|
int jit_process(struct perf_session *session, struct perf_data_file *output,
|
||||||
struct perf_data_file *output,
|
struct machine *machine, char *filename, pid_t pid, u64 *nbytes);
|
||||||
struct machine *machine,
|
|
||||||
char *filename,
|
|
||||||
pid_t pid,
|
|
||||||
u64 *nbytes);
|
|
||||||
|
|
||||||
extern int jit_inject_record(const char *filename);
|
int jit_inject_record(const char *filename);
|
||||||
|
|
||||||
#endif /* __JIT_H__ */
|
#endif /* __JIT_H__ */
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
* Copyright (C) 2015, Huawei Inc.
|
* Copyright (C) 2015, Huawei Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "util.h"
|
#include <stdlib.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "llvm-utils.h"
|
#include "llvm-utils.h"
|
||||||
#include "cache.h"
|
|
||||||
|
|
||||||
#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \
|
#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \
|
||||||
"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
|
"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
|
||||||
|
@ -98,11 +98,12 @@ read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
size_t read_sz = 0, buf_sz = 0;
|
size_t read_sz = 0, buf_sz = 0;
|
||||||
|
char serr[STRERR_BUFSIZE];
|
||||||
|
|
||||||
file = popen(cmd, "r");
|
file = popen(cmd, "r");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
pr_err("ERROR: unable to popen cmd: %s\n",
|
pr_err("ERROR: unable to popen cmd: %s\n",
|
||||||
strerror(errno));
|
strerror_r(errno, serr, sizeof(serr)));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
|
||||||
|
|
||||||
if (ferror(file)) {
|
if (ferror(file)) {
|
||||||
pr_err("ERROR: error occurred when reading from pipe: %s\n",
|
pr_err("ERROR: error occurred when reading from pipe: %s\n",
|
||||||
strerror(errno));
|
strerror_r(errno, serr, sizeof(serr)));
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
@ -334,10 +335,18 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
|
||||||
unsigned int kernel_version;
|
unsigned int kernel_version;
|
||||||
char linux_version_code_str[64];
|
char linux_version_code_str[64];
|
||||||
const char *clang_opt = llvm_param.clang_opt;
|
const char *clang_opt = llvm_param.clang_opt;
|
||||||
char clang_path[PATH_MAX], nr_cpus_avail_str[64];
|
char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
|
||||||
|
char serr[STRERR_BUFSIZE];
|
||||||
char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
|
char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
|
||||||
const char *template = llvm_param.clang_bpf_cmd_template;
|
const char *template = llvm_param.clang_bpf_cmd_template;
|
||||||
|
|
||||||
|
if (path[0] != '-' && realpath(path, abspath) == NULL) {
|
||||||
|
err = errno;
|
||||||
|
pr_err("ERROR: problems with path %s: %s\n",
|
||||||
|
path, strerror_r(err, serr, sizeof(serr)));
|
||||||
|
return -err;
|
||||||
|
}
|
||||||
|
|
||||||
if (!template)
|
if (!template)
|
||||||
template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
|
template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
|
||||||
|
|
||||||
|
@ -362,7 +371,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
|
||||||
if (nr_cpus_avail <= 0) {
|
if (nr_cpus_avail <= 0) {
|
||||||
pr_err(
|
pr_err(
|
||||||
"WARNING:\tunable to get available CPUs in this system: %s\n"
|
"WARNING:\tunable to get available CPUs in this system: %s\n"
|
||||||
" \tUse 128 instead.\n", strerror(errno));
|
" \tUse 128 instead.\n", strerror_r(errno, serr, sizeof(serr)));
|
||||||
nr_cpus_avail = 128;
|
nr_cpus_avail = 128;
|
||||||
}
|
}
|
||||||
snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
|
snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
|
||||||
|
@ -387,8 +396,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
|
||||||
* stdin to be source file (testing).
|
* stdin to be source file (testing).
|
||||||
*/
|
*/
|
||||||
force_set_env("CLANG_SOURCE",
|
force_set_env("CLANG_SOURCE",
|
||||||
(path[0] == '-') ? path :
|
(path[0] == '-') ? path : abspath);
|
||||||
make_nonrelative_path(path));
|
|
||||||
|
|
||||||
pr_debug("llvm compiling command template: %s\n", template);
|
pr_debug("llvm compiling command template: %s\n", template);
|
||||||
err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
|
err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
|
||||||
|
|
|
@ -39,11 +39,10 @@ struct llvm_param {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct llvm_param llvm_param;
|
extern struct llvm_param llvm_param;
|
||||||
extern int perf_llvm_config(const char *var, const char *value);
|
int perf_llvm_config(const char *var, const char *value);
|
||||||
|
|
||||||
extern int llvm__compile_bpf(const char *path, void **p_obj_buf,
|
int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz);
|
||||||
size_t *p_obj_buf_sz);
|
|
||||||
|
|
||||||
/* This function is for test__llvm() use only */
|
/* This function is for test__llvm() use only */
|
||||||
extern int llvm__search_clang(void);
|
int llvm__search_clang(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1301,9 +1301,8 @@ out_problem:
|
||||||
|
|
||||||
int machine__process_mmap2_event(struct machine *machine,
|
int machine__process_mmap2_event(struct machine *machine,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
struct perf_sample *sample __maybe_unused)
|
struct perf_sample *sample)
|
||||||
{
|
{
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
enum map_type type;
|
enum map_type type;
|
||||||
|
@ -1312,8 +1311,8 @@ int machine__process_mmap2_event(struct machine *machine,
|
||||||
if (dump_trace)
|
if (dump_trace)
|
||||||
perf_event__fprintf_mmap2(event, stdout);
|
perf_event__fprintf_mmap2(event, stdout);
|
||||||
|
|
||||||
if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
|
if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
|
||||||
cpumode == PERF_RECORD_MISC_KERNEL) {
|
sample->cpumode == PERF_RECORD_MISC_KERNEL) {
|
||||||
ret = machine__process_kernel_mmap_event(machine, event);
|
ret = machine__process_kernel_mmap_event(machine, event);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_problem;
|
goto out_problem;
|
||||||
|
@ -1355,9 +1354,8 @@ out_problem:
|
||||||
}
|
}
|
||||||
|
|
||||||
int machine__process_mmap_event(struct machine *machine, union perf_event *event,
|
int machine__process_mmap_event(struct machine *machine, union perf_event *event,
|
||||||
struct perf_sample *sample __maybe_unused)
|
struct perf_sample *sample)
|
||||||
{
|
{
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
enum map_type type;
|
enum map_type type;
|
||||||
|
@ -1366,8 +1364,8 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
|
||||||
if (dump_trace)
|
if (dump_trace)
|
||||||
perf_event__fprintf_mmap(event, stdout);
|
perf_event__fprintf_mmap(event, stdout);
|
||||||
|
|
||||||
if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
|
if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
|
||||||
cpumode == PERF_RECORD_MISC_KERNEL) {
|
sample->cpumode == PERF_RECORD_MISC_KERNEL) {
|
||||||
ret = machine__process_kernel_mmap_event(machine, event);
|
ret = machine__process_kernel_mmap_event(machine, event);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_problem;
|
goto out_problem;
|
||||||
|
|
|
@ -94,7 +94,7 @@ int machine__process_aux_event(struct machine *machine,
|
||||||
union perf_event *event);
|
union perf_event *event);
|
||||||
int machine__process_itrace_start_event(struct machine *machine,
|
int machine__process_itrace_start_event(struct machine *machine,
|
||||||
union perf_event *event);
|
union perf_event *event);
|
||||||
int machine__process_switch_event(struct machine *machine __maybe_unused,
|
int machine__process_switch_event(struct machine *machine,
|
||||||
union perf_event *event);
|
union perf_event *event);
|
||||||
int machine__process_mmap_event(struct machine *machine, union perf_event *event,
|
int machine__process_mmap_event(struct machine *machine, union perf_event *event,
|
||||||
struct perf_sample *sample);
|
struct perf_sample *sample);
|
||||||
|
|
|
@ -22,19 +22,18 @@ struct tracepoint_path {
|
||||||
struct tracepoint_path *next;
|
struct tracepoint_path *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
|
struct tracepoint_path *tracepoint_id_to_path(u64 config);
|
||||||
extern struct tracepoint_path *tracepoint_name_to_path(const char *name);
|
struct tracepoint_path *tracepoint_name_to_path(const char *name);
|
||||||
extern bool have_tracepoints(struct list_head *evlist);
|
bool have_tracepoints(struct list_head *evlist);
|
||||||
|
|
||||||
const char *event_type(int type);
|
const char *event_type(int type);
|
||||||
|
|
||||||
extern int parse_events_option(const struct option *opt, const char *str,
|
int parse_events_option(const struct option *opt, const char *str, int unset);
|
||||||
int unset);
|
int parse_events(struct perf_evlist *evlist, const char *str,
|
||||||
extern int parse_events(struct perf_evlist *evlist, const char *str,
|
struct parse_events_error *error);
|
||||||
struct parse_events_error *error);
|
int parse_events_terms(struct list_head *terms, const char *str);
|
||||||
extern int parse_events_terms(struct list_head *terms, const char *str);
|
int parse_filter(const struct option *opt, const char *str, int unset);
|
||||||
extern int parse_filter(const struct option *opt, const char *str, int unset);
|
int exclude_perf(const struct option *opt, const char *arg, int unset);
|
||||||
extern int exclude_perf(const struct option *opt, const char *arg, int unset);
|
|
||||||
|
|
||||||
#define EVENTS_HELP_MAX (128*1024)
|
#define EVENTS_HELP_MAX (128*1024)
|
||||||
|
|
||||||
|
@ -183,7 +182,7 @@ void print_symbol_events(const char *event_glob, unsigned type,
|
||||||
void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
|
void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
|
||||||
bool name_only);
|
bool name_only);
|
||||||
int print_hwcache_events(const char *event_glob, bool name_only);
|
int print_hwcache_events(const char *event_glob, bool name_only);
|
||||||
extern int is_valid_tracepoint(const char *event_string);
|
int is_valid_tracepoint(const char *event_string);
|
||||||
|
|
||||||
int valid_event_mount(const char *eventfs);
|
int valid_event_mount(const char *eventfs);
|
||||||
char *parse_events_formats_error_string(char *additional_terms);
|
char *parse_events_formats_error_string(char *additional_terms);
|
||||||
|
|
|
@ -41,36 +41,6 @@ static char *cleanup_path(char *path)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *perf_vsnpath(char *buf, size_t n, const char *fmt, va_list args)
|
|
||||||
{
|
|
||||||
const char *perf_dir = get_perf_dir();
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = strlen(perf_dir);
|
|
||||||
if (n < len + 1)
|
|
||||||
goto bad;
|
|
||||||
memcpy(buf, perf_dir, len);
|
|
||||||
if (len && !is_dir_sep(perf_dir[len-1]))
|
|
||||||
buf[len++] = '/';
|
|
||||||
len += vsnprintf(buf + len, n - len, fmt, args);
|
|
||||||
if (len >= n)
|
|
||||||
goto bad;
|
|
||||||
return cleanup_path(buf);
|
|
||||||
bad:
|
|
||||||
strlcpy(buf, bad_path, n);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *perf_pathdup(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
char path[PATH_MAX];
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
(void)perf_vsnpath(path, sizeof(path), fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
return xstrdup(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *mkpath(const char *fmt, ...)
|
char *mkpath(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
|
@ -2179,7 +2179,7 @@ static int perf_probe_event__sprintf(const char *group, const char *event,
|
||||||
strbuf_addf(result, " in %s", module);
|
strbuf_addf(result, " in %s", module);
|
||||||
|
|
||||||
if (pev->nargs > 0) {
|
if (pev->nargs > 0) {
|
||||||
strbuf_addstr(result, " with");
|
strbuf_add(result, " with", 5);
|
||||||
for (i = 0; i < pev->nargs; i++) {
|
for (i = 0; i < pev->nargs; i++) {
|
||||||
ret = synthesize_perf_probe_arg(&pev->args[i],
|
ret = synthesize_perf_probe_arg(&pev->args[i],
|
||||||
buf, 128);
|
buf, 128);
|
||||||
|
|
|
@ -114,49 +114,44 @@ int init_probe_symbol_maps(bool user_only);
|
||||||
void exit_probe_symbol_maps(void);
|
void exit_probe_symbol_maps(void);
|
||||||
|
|
||||||
/* Command string to events */
|
/* Command string to events */
|
||||||
extern int parse_perf_probe_command(const char *cmd,
|
int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev);
|
||||||
struct perf_probe_event *pev);
|
int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev);
|
||||||
extern int parse_probe_trace_command(const char *cmd,
|
|
||||||
struct probe_trace_event *tev);
|
|
||||||
|
|
||||||
/* Events to command string */
|
/* Events to command string */
|
||||||
extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
|
char *synthesize_perf_probe_command(struct perf_probe_event *pev);
|
||||||
extern char *synthesize_probe_trace_command(struct probe_trace_event *tev);
|
char *synthesize_probe_trace_command(struct probe_trace_event *tev);
|
||||||
extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf,
|
int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len);
|
||||||
size_t len);
|
|
||||||
|
|
||||||
/* Check the perf_probe_event needs debuginfo */
|
/* Check the perf_probe_event needs debuginfo */
|
||||||
extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
|
bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
|
||||||
|
|
||||||
/* Release event contents */
|
/* Release event contents */
|
||||||
extern void clear_perf_probe_event(struct perf_probe_event *pev);
|
void clear_perf_probe_event(struct perf_probe_event *pev);
|
||||||
extern void clear_probe_trace_event(struct probe_trace_event *tev);
|
void clear_probe_trace_event(struct probe_trace_event *tev);
|
||||||
|
|
||||||
/* Command string to line-range */
|
/* Command string to line-range */
|
||||||
extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
|
int parse_line_range_desc(const char *cmd, struct line_range *lr);
|
||||||
|
|
||||||
/* Release line range members */
|
/* Release line range members */
|
||||||
extern void line_range__clear(struct line_range *lr);
|
void line_range__clear(struct line_range *lr);
|
||||||
|
|
||||||
/* Initialize line range */
|
/* Initialize line range */
|
||||||
extern int line_range__init(struct line_range *lr);
|
int line_range__init(struct line_range *lr);
|
||||||
|
|
||||||
extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
extern int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
extern int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
extern void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
extern int del_perf_probe_events(struct strfilter *filter);
|
int del_perf_probe_events(struct strfilter *filter);
|
||||||
|
|
||||||
extern int show_perf_probe_event(const char *group, const char *event,
|
int show_perf_probe_event(const char *group, const char *event,
|
||||||
struct perf_probe_event *pev,
|
struct perf_probe_event *pev,
|
||||||
const char *module, bool use_stdout);
|
const char *module, bool use_stdout);
|
||||||
extern int show_perf_probe_events(struct strfilter *filter);
|
int show_perf_probe_events(struct strfilter *filter);
|
||||||
extern int show_line_range(struct line_range *lr, const char *module,
|
int show_line_range(struct line_range *lr, const char *module, bool user);
|
||||||
bool user);
|
int show_available_vars(struct perf_probe_event *pevs, int npevs,
|
||||||
extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
|
struct strfilter *filter);
|
||||||
struct strfilter *filter);
|
int show_available_funcs(const char *module, struct strfilter *filter, bool user);
|
||||||
extern int show_available_funcs(const char *module, struct strfilter *filter,
|
|
||||||
bool user);
|
|
||||||
bool arch__prefers_symtab(void);
|
bool arch__prefers_symtab(void);
|
||||||
void arch__fix_tev_from_maps(struct perf_probe_event *pev,
|
void arch__fix_tev_from_maps(struct perf_probe_event *pev,
|
||||||
struct probe_trace_event *tev, struct map *map);
|
struct probe_trace_event *tev, struct map *map);
|
||||||
|
|
|
@ -1314,18 +1314,18 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
|
||||||
if (probe_conf.show_location_range) {
|
if (probe_conf.show_location_range) {
|
||||||
if (!externs) {
|
if (!externs) {
|
||||||
if (ret)
|
if (ret)
|
||||||
strbuf_addf(&buf, "[INV]\t");
|
strbuf_add(&buf, "[INV]\t", 6);
|
||||||
else
|
else
|
||||||
strbuf_addf(&buf, "[VAL]\t");
|
strbuf_add(&buf, "[VAL]\t", 6);
|
||||||
} else
|
} else
|
||||||
strbuf_addf(&buf, "[EXT]\t");
|
strbuf_add(&buf, "[EXT]\t", 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret2 = die_get_varname(die_mem, &buf);
|
ret2 = die_get_varname(die_mem, &buf);
|
||||||
|
|
||||||
if (!ret2 && probe_conf.show_location_range &&
|
if (!ret2 && probe_conf.show_location_range &&
|
||||||
!externs) {
|
!externs) {
|
||||||
strbuf_addf(&buf, "\t");
|
strbuf_addch(&buf, '\t');
|
||||||
ret2 = die_get_var_range(&af->pf.sp_die,
|
ret2 = die_get_var_range(&af->pf.sp_die,
|
||||||
die_mem, &buf);
|
die_mem, &buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,27 +34,25 @@ struct debuginfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This also tries to open distro debuginfo */
|
/* This also tries to open distro debuginfo */
|
||||||
extern struct debuginfo *debuginfo__new(const char *path);
|
struct debuginfo *debuginfo__new(const char *path);
|
||||||
extern void debuginfo__delete(struct debuginfo *dbg);
|
void debuginfo__delete(struct debuginfo *dbg);
|
||||||
|
|
||||||
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
|
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
|
||||||
extern int debuginfo__find_trace_events(struct debuginfo *dbg,
|
int debuginfo__find_trace_events(struct debuginfo *dbg,
|
||||||
struct perf_probe_event *pev,
|
struct perf_probe_event *pev,
|
||||||
struct probe_trace_event **tevs);
|
struct probe_trace_event **tevs);
|
||||||
|
|
||||||
/* Find a perf_probe_point from debuginfo */
|
/* Find a perf_probe_point from debuginfo */
|
||||||
extern int debuginfo__find_probe_point(struct debuginfo *dbg,
|
int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
|
||||||
unsigned long addr,
|
struct perf_probe_point *ppt);
|
||||||
struct perf_probe_point *ppt);
|
|
||||||
|
|
||||||
/* Find a line range */
|
/* Find a line range */
|
||||||
extern int debuginfo__find_line_range(struct debuginfo *dbg,
|
int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr);
|
||||||
struct line_range *lr);
|
|
||||||
|
|
||||||
/* Find available variables */
|
/* Find available variables */
|
||||||
extern int debuginfo__find_available_vars_at(struct debuginfo *dbg,
|
int debuginfo__find_available_vars_at(struct debuginfo *dbg,
|
||||||
struct perf_probe_event *pev,
|
struct perf_probe_event *pev,
|
||||||
struct variable_list **vls);
|
struct variable_list **vls);
|
||||||
|
|
||||||
/* Find a src file from a DWARF tag path */
|
/* Find a src file from a DWARF tag path */
|
||||||
int get_real_path(const char *raw_path, const char *comp_dir,
|
int get_real_path(const char *raw_path, const char *comp_dir,
|
||||||
|
|
|
@ -24,6 +24,6 @@
|
||||||
* sq_quote() in a real application.
|
* sq_quote() in a real application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
|
void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
|
||||||
|
|
||||||
#endif /* __PERF_QUOTE_H */
|
#endif /* __PERF_QUOTE_H */
|
||||||
|
|
|
@ -1107,12 +1107,11 @@ static struct machine *machines__find_for_cpumode(struct machines *machines,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
struct perf_sample *sample)
|
struct perf_sample *sample)
|
||||||
{
|
{
|
||||||
const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
||||||
struct machine *machine;
|
struct machine *machine;
|
||||||
|
|
||||||
if (perf_guest &&
|
if (perf_guest &&
|
||||||
((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
|
((sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
|
||||||
(cpumode == PERF_RECORD_MISC_GUEST_USER))) {
|
(sample->cpumode == PERF_RECORD_MISC_GUEST_USER))) {
|
||||||
u32 pid;
|
u32 pid;
|
||||||
|
|
||||||
if (event->header.type == PERF_RECORD_MMAP
|
if (event->header.type == PERF_RECORD_MMAP
|
||||||
|
|
|
@ -2225,7 +2225,7 @@ int hpp_dimension__add_output(unsigned col)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
|
static int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
|
||||||
struct perf_evlist *evlist __maybe_unused,
|
struct perf_evlist *evlist,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
|
@ -152,8 +152,7 @@ static const char *get_ratio_color(enum grc_type type, double ratio)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_stalled_cycles_frontend(int cpu,
|
static void print_stalled_cycles_frontend(int cpu,
|
||||||
struct perf_evsel *evsel
|
struct perf_evsel *evsel, double avg,
|
||||||
__maybe_unused, double avg,
|
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
double total, ratio = 0.0;
|
double total, ratio = 0.0;
|
||||||
|
@ -175,8 +174,7 @@ static void print_stalled_cycles_frontend(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_stalled_cycles_backend(int cpu,
|
static void print_stalled_cycles_backend(int cpu,
|
||||||
struct perf_evsel *evsel
|
struct perf_evsel *evsel, double avg,
|
||||||
__maybe_unused, double avg,
|
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
double total, ratio = 0.0;
|
double total, ratio = 0.0;
|
||||||
|
@ -194,7 +192,7 @@ static void print_stalled_cycles_backend(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_branch_misses(int cpu,
|
static void print_branch_misses(int cpu,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel,
|
||||||
double avg,
|
double avg,
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
|
@ -213,7 +211,7 @@ static void print_branch_misses(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_l1_dcache_misses(int cpu,
|
static void print_l1_dcache_misses(int cpu,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel,
|
||||||
double avg,
|
double avg,
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +230,7 @@ static void print_l1_dcache_misses(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_l1_icache_misses(int cpu,
|
static void print_l1_icache_misses(int cpu,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel,
|
||||||
double avg,
|
double avg,
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
|
@ -250,7 +248,7 @@ static void print_l1_icache_misses(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_dtlb_cache_misses(int cpu,
|
static void print_dtlb_cache_misses(int cpu,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel,
|
||||||
double avg,
|
double avg,
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
|
@ -268,7 +266,7 @@ static void print_dtlb_cache_misses(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_itlb_cache_misses(int cpu,
|
static void print_itlb_cache_misses(int cpu,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel,
|
||||||
double avg,
|
double avg,
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
|
@ -286,7 +284,7 @@ static void print_itlb_cache_misses(int cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_ll_cache_misses(int cpu,
|
static void print_ll_cache_misses(int cpu,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel,
|
||||||
double avg,
|
double avg,
|
||||||
struct perf_stat_output_ctx *out)
|
struct perf_stat_output_ctx *out)
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,13 @@ void strbuf_grow(struct strbuf *sb, size_t extra)
|
||||||
ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
|
ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strbuf_addch(struct strbuf *sb, int c)
|
||||||
|
{
|
||||||
|
strbuf_grow(sb, 1);
|
||||||
|
sb->buf[sb->len++] = c;
|
||||||
|
sb->buf[sb->len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
void strbuf_add(struct strbuf *sb, const void *data, size_t len)
|
void strbuf_add(struct strbuf *sb, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
strbuf_grow(sb, len);
|
strbuf_grow(sb, len);
|
||||||
|
@ -58,7 +65,7 @@ void strbuf_add(struct strbuf *sb, const void *data, size_t len)
|
||||||
strbuf_setlen(sb, sb->len + len);
|
strbuf_setlen(sb, sb->len + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
|
static void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
va_list ap_saved;
|
va_list ap_saved;
|
||||||
|
|
|
@ -51,16 +51,16 @@ struct strbuf {
|
||||||
#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
|
#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
|
||||||
|
|
||||||
/*----- strbuf life cycle -----*/
|
/*----- strbuf life cycle -----*/
|
||||||
extern void strbuf_init(struct strbuf *buf, ssize_t hint);
|
void strbuf_init(struct strbuf *buf, ssize_t hint);
|
||||||
extern void strbuf_release(struct strbuf *);
|
void strbuf_release(struct strbuf *buf);
|
||||||
extern char *strbuf_detach(struct strbuf *, size_t *);
|
char *strbuf_detach(struct strbuf *buf, size_t *);
|
||||||
|
|
||||||
/*----- strbuf size related -----*/
|
/*----- strbuf size related -----*/
|
||||||
static inline ssize_t strbuf_avail(const struct strbuf *sb) {
|
static inline ssize_t strbuf_avail(const struct strbuf *sb) {
|
||||||
return sb->alloc ? sb->alloc - sb->len - 1 : 0;
|
return sb->alloc ? sb->alloc - sb->len - 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void strbuf_grow(struct strbuf *, size_t);
|
void strbuf_grow(struct strbuf *buf, size_t);
|
||||||
|
|
||||||
static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
|
static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
|
||||||
if (!sb->alloc)
|
if (!sb->alloc)
|
||||||
|
@ -71,22 +71,17 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----- add data in your buffer -----*/
|
/*----- add data in your buffer -----*/
|
||||||
static inline void strbuf_addch(struct strbuf *sb, int c) {
|
void strbuf_addch(struct strbuf *sb, int c);
|
||||||
strbuf_grow(sb, 1);
|
|
||||||
sb->buf[sb->len++] = c;
|
|
||||||
sb->buf[sb->len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void strbuf_add(struct strbuf *, const void *, size_t);
|
void strbuf_add(struct strbuf *buf, const void *, size_t);
|
||||||
static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
|
static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
|
||||||
strbuf_add(sb, s, strlen(s));
|
strbuf_add(sb, s, strlen(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((format(printf,2,3)))
|
__attribute__((format(printf,2,3)))
|
||||||
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
|
void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
|
||||||
extern void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap);
|
|
||||||
|
|
||||||
/* XXX: if read fails, any partial read is undone */
|
/* XXX: if read fails, any partial read is undone */
|
||||||
extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
|
ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
|
||||||
|
|
||||||
#endif /* __PERF_STRBUF_H */
|
#endif /* __PERF_STRBUF_H */
|
||||||
|
|
|
@ -3,32 +3,31 @@
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
extern void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end);
|
void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end);
|
||||||
extern void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
|
void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
|
||||||
extern void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
|
void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
|
||||||
extern void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
|
void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
|
||||||
extern void svg_box(int Yslot, u64 start, u64 end, const char *type);
|
void svg_box(int Yslot, u64 start, u64 end, const char *type);
|
||||||
extern void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
|
void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
|
||||||
extern void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
|
void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
|
||||||
extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
|
void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
|
||||||
extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);
|
void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);
|
||||||
|
|
||||||
|
|
||||||
extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace);
|
void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace);
|
||||||
extern void svg_cstate(int cpu, u64 start, u64 end, int type);
|
void svg_cstate(int cpu, u64 start, u64 end, int type);
|
||||||
extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq);
|
void svg_pstate(int cpu, u64 start, u64 end, u64 freq);
|
||||||
|
|
||||||
|
|
||||||
extern void svg_time_grid(double min_thickness);
|
void svg_time_grid(double min_thickness);
|
||||||
extern void svg_io_legenda(void);
|
void svg_io_legenda(void);
|
||||||
extern void svg_legenda(void);
|
void svg_legenda(void);
|
||||||
extern void svg_wakeline(u64 start, int row1, int row2, const char *backtrace);
|
void svg_wakeline(u64 start, int row1, int row2, const char *backtrace);
|
||||||
extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace);
|
void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace);
|
||||||
extern void svg_interrupt(u64 start, int row, const char *backtrace);
|
void svg_interrupt(u64 start, int row, const char *backtrace);
|
||||||
extern void svg_text(int Yslot, u64 start, const char *text);
|
void svg_text(int Yslot, u64 start, const char *text);
|
||||||
extern void svg_close(void);
|
void svg_close(void);
|
||||||
extern int svg_build_topology_map(char *sib_core, int sib_core_nr,
|
int svg_build_topology_map(char *sib_core, int sib_core_nr, char *sib_thr, int sib_thr_nr);
|
||||||
char *sib_thr, int sib_thr_nr);
|
|
||||||
|
|
||||||
extern int svg_page_width;
|
extern int svg_page_width;
|
||||||
extern u64 svg_highlight;
|
extern u64 svg_highlight;
|
||||||
|
|
|
@ -793,6 +793,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
GElf_Ehdr ehdr;
|
GElf_Ehdr ehdr;
|
||||||
GElf_Shdr shdr;
|
GElf_Shdr shdr;
|
||||||
|
GElf_Shdr tshdr;
|
||||||
Elf_Data *syms, *opddata = NULL;
|
Elf_Data *syms, *opddata = NULL;
|
||||||
GElf_Sym sym;
|
GElf_Sym sym;
|
||||||
Elf_Scn *sec, *sec_strndx;
|
Elf_Scn *sec, *sec_strndx;
|
||||||
|
@ -832,6 +833,9 @@ int dso__load_sym(struct dso *dso, struct map *map,
|
||||||
sec = syms_ss->symtab;
|
sec = syms_ss->symtab;
|
||||||
shdr = syms_ss->symshdr;
|
shdr = syms_ss->symshdr;
|
||||||
|
|
||||||
|
if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL))
|
||||||
|
dso->text_offset = tshdr.sh_addr - tshdr.sh_offset;
|
||||||
|
|
||||||
if (runtime_ss->opdsec)
|
if (runtime_ss->opdsec)
|
||||||
opddata = elf_rawdata(runtime_ss->opdsec, NULL);
|
opddata = elf_rawdata(runtime_ss->opdsec, NULL);
|
||||||
|
|
||||||
|
@ -880,12 +884,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
|
||||||
* Handle any relocation of vdso necessary because older kernels
|
* Handle any relocation of vdso necessary because older kernels
|
||||||
* attempted to prelink vdso to its virtual address.
|
* attempted to prelink vdso to its virtual address.
|
||||||
*/
|
*/
|
||||||
if (dso__is_vdso(dso)) {
|
if (dso__is_vdso(dso))
|
||||||
GElf_Shdr tshdr;
|
map->reloc = map->start - dso->text_offset;
|
||||||
|
|
||||||
if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL))
|
|
||||||
map->reloc = map->start - tshdr.sh_addr + tshdr.sh_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
|
dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBELF_SUPPORT
|
#ifdef HAVE_LIBELF_SUPPORT
|
||||||
extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
||||||
GElf_Shdr *shp, const char *name, size_t *idx);
|
GElf_Shdr *shp, const char *name, size_t *idx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DMGL_PARAMS
|
#ifndef DMGL_PARAMS
|
||||||
|
|
|
@ -41,15 +41,9 @@ static void warn_builtin(const char *warn, va_list params)
|
||||||
/* If we are in a dlopen()ed .so write to a global variable would segfault
|
/* If we are in a dlopen()ed .so write to a global variable would segfault
|
||||||
* (ugh), so keep things static. */
|
* (ugh), so keep things static. */
|
||||||
static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
|
static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
|
||||||
static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;
|
|
||||||
static void (*error_routine)(const char *err, va_list params) = error_builtin;
|
static void (*error_routine)(const char *err, va_list params) = error_builtin;
|
||||||
static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
|
static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
|
||||||
|
|
||||||
void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)
|
|
||||||
{
|
|
||||||
die_routine = routine;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_warning_routine(void (*routine)(const char *err, va_list params))
|
void set_warning_routine(void (*routine)(const char *err, va_list params))
|
||||||
{
|
{
|
||||||
warn_routine = routine;
|
warn_routine = routine;
|
||||||
|
@ -65,7 +59,7 @@ void die(const char *err, ...)
|
||||||
va_list params;
|
va_list params;
|
||||||
|
|
||||||
va_start(params, err);
|
va_start(params, err);
|
||||||
die_routine(err, params);
|
die_builtin(err, params);
|
||||||
va_end(params);
|
va_end(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,25 +133,15 @@ extern char buildid_dir[];
|
||||||
#define PERF_GTK_DSO "libperf-gtk.so"
|
#define PERF_GTK_DSO "libperf-gtk.so"
|
||||||
|
|
||||||
/* General helper functions */
|
/* General helper functions */
|
||||||
extern void usage(const char *err) NORETURN;
|
void usage(const char *err) NORETURN;
|
||||||
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
||||||
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||||
extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||||
|
|
||||||
#include "../../../include/linux/stringify.h"
|
void set_warning_routine(void (*routine)(const char *err, va_list params));
|
||||||
|
|
||||||
#define DIE_IF(cnd) \
|
int prefixcmp(const char *str, const char *prefix);
|
||||||
do { if (cnd) \
|
void set_buildid_dir(const char *dir);
|
||||||
die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \
|
|
||||||
__stringify(cnd) "\n"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
|
|
||||||
extern void set_warning_routine(void (*routine)(const char *err, va_list params));
|
|
||||||
|
|
||||||
extern int prefixcmp(const char *str, const char *prefix);
|
|
||||||
extern void set_buildid_dir(const char *dir);
|
|
||||||
|
|
||||||
#ifdef __GLIBC_PREREQ
|
#ifdef __GLIBC_PREREQ
|
||||||
#if __GLIBC_PREREQ(2, 1)
|
#if __GLIBC_PREREQ(2, 1)
|
||||||
|
@ -172,8 +162,7 @@ static inline char *gitstrchrnul(const char *s, int c)
|
||||||
/*
|
/*
|
||||||
* Wrappers:
|
* Wrappers:
|
||||||
*/
|
*/
|
||||||
extern char *xstrdup(const char *str);
|
void *xrealloc(void *ptr, size_t size) __attribute__((weak));
|
||||||
extern void *xrealloc(void *ptr, size_t size) __attribute__((weak));
|
|
||||||
|
|
||||||
|
|
||||||
static inline void *zalloc(size_t size)
|
static inline void *zalloc(size_t size)
|
||||||
|
|
|
@ -12,18 +12,6 @@ static inline void release_pack_memory(size_t size __maybe_unused,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
char *xstrdup(const char *str)
|
|
||||||
{
|
|
||||||
char *ret = strdup(str);
|
|
||||||
if (!ret) {
|
|
||||||
release_pack_memory(strlen(str) + 1, -1);
|
|
||||||
ret = strdup(str);
|
|
||||||
if (!ret)
|
|
||||||
die("Out of memory, strdup failed");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *xrealloc(void *ptr, size_t size)
|
void *xrealloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
void *ret = realloc(ptr, size);
|
void *ret = realloc(ptr, size);
|
||||||
|
|
Loading…
Reference in New Issue