Commit a0ac7b3c authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo-4.17-20180323' of...

Merge tag 'perf-core-for-mingo-4.17-20180323' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

- Move non-TUI specific annotation routines out of the TUI browser so
  that it can be used in other UIs, and to demonstrate that introduce
  a 'perf annotate --stdio2' option that will apply those formatting
  routines to provide a non-interactive annotation mode (Arnaldo Carvalho de Melo)

- Add 'P' hotkey to the annotation TUI, so dump the current annotated
  symbol to a file, easing report thru e-mail, by getting rid of the
  spaces + right hand side scrollbar chars (Arnaldo Carvalho de Melo)

- Support --ignore-vmlinux to 'perf report' and 'perf annotate', that
  was already present in 'perf top', to use /proc/{kcore,kallsyms},
  allowing to see what is in fact running (patched stuff, alternatives,
  ftrace, etc), not the initial state of the kernel (vmlinux) (Arnaldo Carvalho de Melo)

- Support 'jump' instructions to a different function, treating them
  as 'call' instructions (Arnaldo Carvalho de Melo)

- Fix some jump artifacts when using vmlinux + ASM functions, where
  the ELF symtab for instance, for entry_SYSCALL_64 includes that and
  what comes after the 'syscall_return_via_sysret' label, but the
  objdump -dS prints the jump targets + offsets using the
  syscall_return_via_sysret address, which was confusing 'perf annotate'.
  See the cset comments for further info (Arnaldo Carvalho de Melo)

- Report error from dwfl_attach_state() in the unwind code (Martin Vuille)

- Reference Py_None before returning it in the python extension (Petr Machata)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 7054e4e0 980b68ec
...@@ -55,6 +55,9 @@ OPTIONS ...@@ -55,6 +55,9 @@ OPTIONS
--vmlinux=<file>:: --vmlinux=<file>::
vmlinux pathname. vmlinux pathname.
--ignore-vmlinux::
Ignore vmlinux files.
-m:: -m::
--modules:: --modules::
Load module symbols. WARNING: use only with -k and LIVE kernel. Load module symbols. WARNING: use only with -k and LIVE kernel.
...@@ -69,6 +72,8 @@ OPTIONS ...@@ -69,6 +72,8 @@ OPTIONS
--stdio:: Use the stdio interface. --stdio:: Use the stdio interface.
--stdio2:: Use the stdio2 interface, non-interactive, uses the TUI formatting.
--stdio-color=<mode>:: --stdio-color=<mode>::
'always', 'never' or 'auto', allowing configuring color output 'always', 'never' or 'auto', allowing configuring color output
via the command line, in addition to via "color.ui" .perfconfig. via the command line, in addition to via "color.ui" .perfconfig.
......
...@@ -296,6 +296,9 @@ OPTIONS ...@@ -296,6 +296,9 @@ OPTIONS
--vmlinux=<file>:: --vmlinux=<file>::
vmlinux pathname vmlinux pathname
--ignore-vmlinux::
Ignore vmlinux files.
--kallsyms=<file>:: --kallsyms=<file>::
kallsyms pathname kallsyms pathname
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
#include <linux/compiler.h> #include <linux/compiler.h>
static int s390_call__parse(struct arch *arch, struct ins_operands *ops, static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
struct map *map) struct map_symbol *ms)
{ {
char *endptr, *tok, *name; char *endptr, *tok, *name;
struct map *map = ms->map;
struct addr_map_symbol target = { struct addr_map_symbol target = {
.map = map, .map = map,
}; };
...@@ -54,7 +55,7 @@ static struct ins_ops s390_call_ops = { ...@@ -54,7 +55,7 @@ static struct ins_ops s390_call_ops = {
static int s390_mov__parse(struct arch *arch __maybe_unused, static int s390_mov__parse(struct arch *arch __maybe_unused,
struct ins_operands *ops, struct ins_operands *ops,
struct map *map __maybe_unused) struct map_symbol *ms __maybe_unused)
{ {
char *s = strchr(ops->raw, ','), *target, *endptr; char *s = strchr(ops->raw, ','), *target, *endptr;
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
struct perf_annotate { struct perf_annotate {
struct perf_tool tool; struct perf_tool tool;
struct perf_session *session; struct perf_session *session;
bool use_tui, use_stdio, use_gtk; bool use_tui, use_stdio, use_stdio2, use_gtk;
bool full_paths; bool full_paths;
bool print_line; bool print_line;
bool skip_missing; bool skip_missing;
...@@ -202,6 +202,11 @@ static int process_branch_callback(struct perf_evsel *evsel, ...@@ -202,6 +202,11 @@ static int process_branch_callback(struct perf_evsel *evsel,
return ret; return ret;
} }
static bool has_annotation(struct perf_annotate *ann)
{
return ui__has_annotation() || ann->use_stdio2;
}
static int perf_evsel__add_sample(struct perf_evsel *evsel, static int perf_evsel__add_sample(struct perf_evsel *evsel,
struct perf_sample *sample, struct perf_sample *sample,
struct addr_location *al, struct addr_location *al,
...@@ -212,7 +217,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, ...@@ -212,7 +217,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
struct hist_entry *he; struct hist_entry *he;
int ret; int ret;
if ((!ann->has_br_stack || !ui__has_annotation()) && if ((!ann->has_br_stack || !has_annotation(ann)) &&
ann->sym_hist_filter != NULL && ann->sym_hist_filter != NULL &&
(al->sym == NULL || (al->sym == NULL ||
strcmp(ann->sym_hist_filter, al->sym->name) != 0)) { strcmp(ann->sym_hist_filter, al->sym->name) != 0)) {
...@@ -236,7 +241,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, ...@@ -236,7 +241,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
*/ */
process_branch_stack(sample->branch_stack, al, sample); process_branch_stack(sample->branch_stack, al, sample);
if (ann->has_br_stack && ui__has_annotation()) if (ann->has_br_stack && has_annotation(ann))
return process_branch_callback(evsel, sample, al, ann, machine); return process_branch_callback(evsel, sample, al, ann, machine);
he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true); he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true);
...@@ -282,8 +287,11 @@ static int hist_entry__tty_annotate(struct hist_entry *he, ...@@ -282,8 +287,11 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct perf_annotate *ann) struct perf_annotate *ann)
{ {
return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel, if (!ann->use_stdio2)
ann->print_line, ann->full_paths, 0, 0); return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel,
ann->print_line, ann->full_paths, 0, 0);
return symbol__tty_annotate2(he->ms.sym, he->ms.map, evsel,
ann->print_line, ann->full_paths);
} }
static void hists__find_annotations(struct hists *hists, static void hists__find_annotations(struct hists *hists,
...@@ -487,6 +495,9 @@ int cmd_annotate(int argc, const char **argv) ...@@ -487,6 +495,9 @@ int cmd_annotate(int argc, const char **argv)
OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"), OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"), OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"),
OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"), OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"),
OPT_BOOLEAN(0, "stdio2", &annotate.use_stdio2, "Use the stdio interface"),
OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
"don't load vmlinux even if found"),
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"), "file", "vmlinux pathname"),
OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
...@@ -563,13 +574,15 @@ int cmd_annotate(int argc, const char **argv) ...@@ -563,13 +574,15 @@ int cmd_annotate(int argc, const char **argv)
if (ret < 0) if (ret < 0)
goto out_delete; goto out_delete;
annotation_config__init();
symbol_conf.try_vmlinux_path = true; symbol_conf.try_vmlinux_path = true;
ret = symbol__init(&annotate.session->header.env); ret = symbol__init(&annotate.session->header.env);
if (ret < 0) if (ret < 0)
goto out_delete; goto out_delete;
if (annotate.use_stdio) if (annotate.use_stdio || annotate.use_stdio2)
use_browser = 0; use_browser = 0;
else if (annotate.use_tui) else if (annotate.use_tui)
use_browser = 1; use_browser = 1;
...@@ -578,7 +591,7 @@ int cmd_annotate(int argc, const char **argv) ...@@ -578,7 +591,7 @@ int cmd_annotate(int argc, const char **argv)
setup_browser(true); setup_browser(true);
if (use_browser == 1 && annotate.has_br_stack) { if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack) {
sort__mode = SORT_MODE__BRANCH; sort__mode = SORT_MODE__BRANCH;
if (setup_sorting(annotate.session->evlist) < 0) if (setup_sorting(annotate.session->evlist) < 0)
usage_with_options(annotate_usage, options); usage_with_options(annotate_usage, options);
......
...@@ -1018,6 +1018,8 @@ int cmd_report(int argc, const char **argv) ...@@ -1018,6 +1018,8 @@ int cmd_report(int argc, const char **argv)
OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"), OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"),
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"), "file", "vmlinux pathname"),
OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
"don't load vmlinux even if found"),
OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
"file", "kallsyms pathname"), "file", "kallsyms pathname"),
OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
...@@ -1340,6 +1342,7 @@ int cmd_report(int argc, const char **argv) ...@@ -1340,6 +1342,7 @@ int cmd_report(int argc, const char **argv)
symbol_conf.priv_size += sizeof(u32); symbol_conf.priv_size += sizeof(u32);
symbol_conf.sort_by_name = true; symbol_conf.sort_by_name = true;
} }
annotation_config__init();
} }
if (symbol__init(&session->header.env) < 0) if (symbol__init(&session->header.env) < 0)
......
...@@ -1493,6 +1493,8 @@ int cmd_top(int argc, const char **argv) ...@@ -1493,6 +1493,8 @@ int cmd_top(int argc, const char **argv)
if (status < 0) if (status < 0)
goto out_delete_evlist; goto out_delete_evlist;
annotation_config__init();
symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
if (symbol__init(NULL) < 0) if (symbol__init(NULL) < 0)
return -1; return -1;
......
...@@ -56,12 +56,17 @@ void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const ...@@ -56,12 +56,17 @@ void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const
slsmg_write_nstring(msg, width); slsmg_write_nstring(msg, width);
} }
void ui_browser__vprintf(struct ui_browser *browser __maybe_unused, const char *fmt, va_list args)
{
slsmg_vprintf(fmt, args);
}
void ui_browser__printf(struct ui_browser *browser __maybe_unused, const char *fmt, ...) void ui_browser__printf(struct ui_browser *browser __maybe_unused, const char *fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
slsmg_vprintf(fmt, args); ui_browser__vprintf(browser, fmt, args);
va_end(args); va_end(args);
} }
...@@ -779,6 +784,4 @@ void ui_browser__init(void) ...@@ -779,6 +784,4 @@ void ui_browser__init(void)
struct ui_browser_colorset *c = &ui_browser__colorsets[i++]; struct ui_browser_colorset *c = &ui_browser__colorsets[i++];
sltt_set_color(c->colorset, c->name, c->fg, c->bg); sltt_set_color(c->colorset, c->name, c->fg, c->bg);
} }
annotate_browser__init();
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#define _PERF_UI_BROWSER_H_ 1 #define _PERF_UI_BROWSER_H_ 1
#include <linux/types.h> #include <linux/types.h>
#include <stdarg.h>
#define HE_COLORSET_TOP 50 #define HE_COLORSET_TOP 50
#define HE_COLORSET_MEDIUM 51 #define HE_COLORSET_MEDIUM 51
...@@ -40,6 +41,7 @@ void ui_browser__reset_index(struct ui_browser *browser); ...@@ -40,6 +41,7 @@ void ui_browser__reset_index(struct ui_browser *browser);
void ui_browser__gotorc(struct ui_browser *browser, int y, int x); void ui_browser__gotorc(struct ui_browser *browser, int y, int x);
void ui_browser__write_nstring(struct ui_browser *browser, const char *msg, void ui_browser__write_nstring(struct ui_browser *browser, const char *msg,
unsigned int width); unsigned int width);
void ui_browser__vprintf(struct ui_browser *browser, const char *fmt, va_list args);
void ui_browser__printf(struct ui_browser *browser, const char *fmt, ...); void ui_browser__printf(struct ui_browser *browser, const char *fmt, ...);
void ui_browser__write_graph(struct ui_browser *browser, int graph); void ui_browser__write_graph(struct ui_browser *browser, int graph);
void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
...@@ -77,5 +79,4 @@ void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int wh ...@@ -77,5 +79,4 @@ void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int wh
unsigned int ui_browser__list_head_refresh(struct ui_browser *browser); unsigned int ui_browser__list_head_refresh(struct ui_browser *browser);
void ui_browser__init(void); void ui_browser__init(void);
void annotate_browser__init(void);
#endif /* _PERF_UI_BROWSER_H_ */ #endif /* _PERF_UI_BROWSER_H_ */
This diff is collapsed.
This diff is collapsed.
...@@ -28,6 +28,7 @@ struct ins_operands { ...@@ -28,6 +28,7 @@ struct ins_operands {
u64 addr; u64 addr;
s64 offset; s64 offset;
bool offset_avail; bool offset_avail;
bool outside;
} target; } target;
union { union {
struct { struct {
...@@ -46,7 +47,7 @@ struct arch; ...@@ -46,7 +47,7 @@ struct arch;
struct ins_ops { struct ins_ops {
void (*free)(struct ins_operands *ops); void (*free)(struct ins_operands *ops);
int (*parse)(struct arch *arch, struct ins_operands *ops, struct map *map); int (*parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms);
int (*scnprintf)(struct ins *ins, char *bf, size_t size, int (*scnprintf)(struct ins *ins, char *bf, size_t size,
struct ins_operands *ops); struct ins_operands *ops);
}; };
...@@ -58,6 +59,21 @@ bool ins__is_lock(const struct ins *ins); ...@@ -58,6 +59,21 @@ bool ins__is_lock(const struct ins *ins);
int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops);
bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2);
#define ANNOTATION__IPC_WIDTH 6
#define ANNOTATION__CYCLES_WIDTH 6
struct annotation_options {
bool hide_src_code,
use_offset,
jump_arrows,
show_linenr,
show_nr_jumps,
show_nr_samples,
show_total_period;
};
extern struct annotation_options annotation__default_options;
struct annotation; struct annotation;
struct sym_hist_entry { struct sym_hist_entry {
...@@ -77,10 +93,13 @@ struct annotation_line { ...@@ -77,10 +93,13 @@ struct annotation_line {
s64 offset; s64 offset;
char *line; char *line;
int line_nr; int line_nr;
int jump_sources;
float ipc; float ipc;
u64 cycles; u64 cycles;
size_t privsize; size_t privsize;
char *path; char *path;
u32 idx;
int idx_asm;
int samples_nr; int samples_nr;
struct annotation_data samples[0]; struct annotation_data samples[0];
}; };
...@@ -98,14 +117,40 @@ static inline struct disasm_line *disasm_line(struct annotation_line *al) ...@@ -98,14 +117,40 @@ static inline struct disasm_line *disasm_line(struct annotation_line *al)
return al ? container_of(al, struct disasm_line, al) : NULL; return al ? container_of(al, struct disasm_line, al) : NULL;
} }
static inline bool disasm_line__has_offset(const struct disasm_line *dl) /*
* Is this offset in the same function as the line it is used?
* asm functions jump to other functions, for instance.
*/
static inline bool disasm_line__has_local_offset(const struct disasm_line *dl)
{ {
return dl->ops.target.offset_avail; return dl->ops.target.offset_avail && !dl->ops.target.outside;
} }
/*
* Can we draw an arrow from the jump to its target, for instance? I.e.
* is the jump and its target in the same function?
*/
bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym);
void disasm_line__free(struct disasm_line *dl); void disasm_line__free(struct disasm_line *dl);
struct annotation_line * struct annotation_line *
annotation_line__next(struct annotation_line *pos, struct list_head *head); annotation_line__next(struct annotation_line *pos, struct list_head *head);
struct annotation_write_ops {
bool first_line, current_entry, change_color;
int width;
void *obj;
int (*set_color)(void *obj, int color);
void (*set_percent_color)(void *obj, double percent, bool current);
int (*set_jumps_percent_color)(void *obj, int nr, bool current);
void (*printf)(void *obj, const char *fmt, ...);
void (*write_graph)(void *obj, int graph);
};
double annotation_line__max_percent(struct annotation_line *al, struct annotation *notes);
void annotation_line__write(struct annotation_line *al, struct annotation *notes,
struct annotation_write_ops *ops);
int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw); int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
size_t disasm__fprintf(struct list_head *head, FILE *fp); size_t disasm__fprintf(struct list_head *head, FILE *fp);
void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel); void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel);
...@@ -151,9 +196,47 @@ struct annotated_source { ...@@ -151,9 +196,47 @@ struct annotated_source {
struct annotation { struct annotation {
pthread_mutex_t lock; pthread_mutex_t lock;
u64 max_coverage; u64 max_coverage;
u64 start;
struct annotation_options *options;
struct annotation_line **offsets;
int nr_events;
int nr_jumps;
int max_jump_sources;
int nr_entries;
int nr_asm_entries;
u16 max_line_len;
struct {
u8 addr;
u8 jumps;
u8 target;
u8 min_addr;
u8 max_addr;
} widths;
bool have_cycles;
struct annotated_source *src; struct annotated_source *src;
}; };
static inline int annotation__cycles_width(struct annotation *notes)
{
return notes->have_cycles ? ANNOTATION__IPC_WIDTH + ANNOTATION__CYCLES_WIDTH : 0;
}
static inline int annotation__pcnt_width(struct annotation *notes)
{
return (notes->options->show_total_period ? 12 : 7) * notes->nr_events;
}
static inline bool annotation_line__filter(struct annotation_line *al, struct annotation *notes)
{
return notes->options->hide_src_code && al->offset == -1;
}
void annotation__set_offsets(struct annotation *notes, s64 size);
void annotation__compute_ipc(struct annotation *notes, size_t size);
void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym);
void annotation__update_column_widths(struct annotation *notes);
void annotation__init_column_widths(struct annotation *notes, struct symbol *sym);
static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx)
{ {
return (((void *)&notes->src->histograms) + return (((void *)&notes->src->histograms) +
...@@ -181,6 +264,10 @@ void symbol__annotate_zero_histograms(struct symbol *sym); ...@@ -181,6 +264,10 @@ void symbol__annotate_zero_histograms(struct symbol *sym);
int symbol__annotate(struct symbol *sym, struct map *map, int symbol__annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, size_t privsize, struct perf_evsel *evsel, size_t privsize,
struct arch **parch); struct arch **parch);
int symbol__annotate2(struct symbol *sym, struct map *map,
struct perf_evsel *evsel,
struct annotation_options *options,
struct arch **parch);
enum symbol_disassemble_errno { enum symbol_disassemble_errno {
SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
...@@ -205,16 +292,23 @@ int symbol__strerror_disassemble(struct symbol *sym, struct map *map, ...@@ -205,16 +292,23 @@ int symbol__strerror_disassemble(struct symbol *sym, struct map *map,
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);
int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp);
void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
void annotated_source__purge(struct annotated_source *as); void annotated_source__purge(struct annotated_source *as);
int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel);
bool ui__has_annotation(void); bool ui__has_annotation(void);
int symbol__tty_annotate(struct symbol *sym, struct map *map, int symbol__tty_annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, bool print_lines, struct perf_evsel *evsel, bool print_lines,
bool full_paths, int min_pcnt, int max_lines); bool full_paths, int min_pcnt, int max_lines);
int symbol__tty_annotate2(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, bool print_lines,
bool full_paths);
#ifdef HAVE_SLANG_SUPPORT #ifdef HAVE_SLANG_SUPPORT
int symbol__tui_annotate(struct symbol *sym, struct map *map, int symbol__tui_annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, struct perf_evsel *evsel,
...@@ -232,4 +326,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, ...@@ -232,4 +326,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
extern const char *disassembler_style; extern const char *disassembler_style;
void annotation_config__init(void);
#endif /* __PERF_ANNOTATE_H */ #endif /* __PERF_ANNOTATE_H */
...@@ -1004,8 +1004,10 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, ...@@ -1004,8 +1004,10 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
return PyErr_NoMemory(); return PyErr_NoMemory();
evsel = perf_evlist__event2evsel(evlist, event); evsel = perf_evlist__event2evsel(evlist, event);
if (!evsel) if (!evsel) {
Py_INCREF(Py_None);
return Py_None; return Py_None;
}
pevent->evsel = evsel; pevent->evsel = evsel;
......
...@@ -236,7 +236,8 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, ...@@ -236,7 +236,8 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
if (err) if (err)
goto out; goto out;
if (!dwfl_attach_state(ui->dwfl, EM_NONE, thread->tid, &callbacks, ui)) err = !dwfl_attach_state(ui->dwfl, EM_NONE, thread->tid, &callbacks, ui);
if (err)
goto out; goto out;
err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui); err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment