Interleave source code with assembly code. Enabled by default,
disable with --no-source.
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
-M::
--disassembler-style=:: Set disassembler style for objdump.
--force::
Don't do ownership validation.
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
-b::
--baseline-only::
--max-stack::
Maximum number of functions to display in backtrace, default 5.
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
--time::
Only analyze samples within given time window: <start>,<stop>. Times
--source=PATH::
Specify path to kernel source.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
+
-v::
--verbose::
Be more verbose (show parsed arguments, etc).
--force::
Don't do ownership validation.
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
-C::
--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
Show all scheduling events followed by a summary by thread with min,
max, and average run times (in sec) and relative stddev.
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
-V::
--cpu-visual::
--kallsyms=<file>::
kallsyms pathname
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
-G::
--hide-call-graph::
-f::
--force::
Don't complain, do it.
---symfs=<directory>::
- Look for files with symbols relative to this directory.
+--symfs=<directory[,layout]>::
+ Look for files with symbols relative to this directory. The optional
+ layout can be 'hierarchy' (default, matches full path) or 'flat'
+ (only matches base name). This is useful when debug files are stored
+ in a flat directory structure.
-n::
--proc-num::
Print task info for at least given number of tasks.
Use parent filter to see specific call path: perf report -p <regex>
List events using substring match: perf list <keyword>
To see list of saved events and attributes: perf evlist -v
-Use --symfs <dir> if your symbol files are in non-standard locations
+Use --symfs <dir>[,layout] if your symbol files are in non-standard locations.
To see callchains in a more compact form: perf report -g folded
To see call chains by final symbol taking CPU time (bottom up) use perf report -G
Show individual samples with: perf script
&annotate.group_set,
"Show event group information together"),
OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"),
- OPT_CALLBACK(0, "symfs", NULL, "directory",
- "Look for files with symbols relative to this directory",
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
symbol__config_symfs),
OPT_BOOLEAN(0, "source", &annotate_opts.annotate_src,
"Interleave source code with assembly code (default)"),
OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
"separator for columns, no spaces will be added between "
"columns '.' is reserved."),
- OPT_CALLBACK(0, "symfs", NULL, "directory",
- "Look for files with symbols relative to this directory",
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
symbol__config_symfs),
OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
"Display call chains if present"),
OPT_UINTEGER(0, "max-stack", &kwork.max_stack,
"Maximum number of functions to display backtrace."),
- OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
- "Look for files with symbols relative to this directory"),
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
+ symbol__config_symfs),
OPT_STRING(0, "time", &kwork.time_str, "str",
"Time span for analysis (start,stop)"),
OPT_STRING('C', "cpu", &kwork.cpu_list, "cpu",
OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
"Enable kernel symbol demangling"),
OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
- OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
- "Look for files with symbols relative to this directory"),
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
+ symbol__config_symfs),
OPT_CALLBACK(0, "target-ns", NULL, "pid",
"target pid for namespace contexts", opt_set_target_ns),
OPT_BOOLEAN(0, "bootconfig", &probe_conf.bootconfig,
"columns '.' is reserved."),
OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
"Only display entries resolved to a symbol"),
- OPT_CALLBACK(0, "symfs", NULL, "directory",
- "Look for files with symbols relative to this directory",
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
symbol__config_symfs),
OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
"list of cpus to profile"),
"Display call chains if present (default on)"),
OPT_UINTEGER(0, "max-stack", &sched.max_stack,
"Maximum number of functions to display backtrace."),
- OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
- "Look for files with symbols relative to this directory"),
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
+ symbol__config_symfs),
OPT_BOOLEAN('s', "summary", &sched.summary_only,
"Show only syscall summary with statistics"),
OPT_BOOLEAN('S', "with-summary", &sched.summary,
"file", "kallsyms pathname"),
OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
"When printing symbols do not display call chain"),
- OPT_CALLBACK(0, "symfs", NULL, "directory",
- "Look for files with symbols relative to this directory",
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
symbol__config_symfs),
OPT_CALLBACK('F', "fields", NULL, "str",
"comma separated output fields prepend with 'type:'. "
OPT_CALLBACK('p', "process", NULL, "process",
"process selector. Pass a pid or process name.",
parse_process),
- OPT_CALLBACK(0, "symfs", NULL, "directory",
- "Look for files with symbols relative to this directory",
+ OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP,
symbol__config_symfs),
OPT_INTEGER('n', "proc-num", &tchart.proc_num,
"min. number of tasks to print"),
.time_quantum = 100 * NSEC_PER_MSEC, /* 100ms */
.show_hist_headers = true,
.symfs = "",
+ .symfs_layout_flat = false,
.event_group = true,
.inline_name = true,
.res_sample = 0,
const char *dir, int unset __maybe_unused)
{
char *bf = NULL;
+ char *layout_str;
+ char *dir_copy;
int ret;
- symbol_conf.symfs = strdup(dir);
- if (symbol_conf.symfs == NULL)
- return -ENOMEM;
+ layout_str = strrchr(dir, ',');
+ if (layout_str) {
+ size_t dir_len = layout_str - dir;
+
+ dir_copy = strndup(dir, dir_len);
+ if (dir_copy == NULL)
+ return -ENOMEM;
+
+ symbol_conf.symfs = dir_copy;
+
+ layout_str++;
+ if (!strcmp(layout_str, "flat"))
+ symbol_conf.symfs_layout_flat = true;
+ else if (!strcmp(layout_str, "hierarchy"))
+ symbol_conf.symfs_layout_flat = false;
+ else {
+ pr_err("Invalid layout: '%s', use 'hierarchy' or 'flat'\n",
+ layout_str);
+ free(dir_copy);
+ return -EINVAL;
+ }
+ } else {
+ symbol_conf.symfs = strdup(dir);
+ if (symbol_conf.symfs == NULL)
+ return -ENOMEM;
+ symbol_conf.symfs_layout_flat = false;
+ }
/* skip the locally configured cache if a symfs is given, and
* config buildid dir to symfs/.debug
*/
- ret = asprintf(&bf, "%s/%s", dir, ".debug");
+ ret = asprintf(&bf, "%s/%s", symbol_conf.symfs, ".debug");
if (ret < 0)
return -ENOMEM;
#include <linux/list.h>
#include <linux/rbtree.h>
#include <stdio.h>
+#include <errno.h>
#include "addr_location.h"
#include "path.h"
#include "symbol_conf.h"
static inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
{
+ if (symbol_conf.symfs_layout_flat) {
+ char *path_copy = strdup(path);
+ char *base;
+ int ret;
+
+ if (!path_copy)
+ return -ENOMEM;
+ base = basename(path_copy);
+ ret = path__join(bf, size, symbol_conf.symfs, base);
+ free(path_copy);
+ return ret;
+ }
return path__join(bf, size, symbol_conf.symfs, path);
}
size_t symbol__fprintf(struct symbol *sym, FILE *fp);
bool symbol__restricted_filename(const char *filename,
const char *restricted_filename);
+
+#define SYMFS_HELP "setup root directory which contains debug files:\n" \
+ "\t\t\t\t" "directory:\tLook for files with symbols relative to this directory.\n" \
+ "\t\t\t\t" "layout: \tLayout of files, 'hierarchy' matches full path (default), 'flat' only matches base name.\n"
+
int symbol__config_symfs(const struct option *opt __maybe_unused,
const char *dir, int unset __maybe_unused);
*tid_list,
*addr_list;
const char *symfs;
+ bool symfs_layout_flat;
int res_sample;
int pad_output_len_dso;
int group_sort_idx;