|
@@ -258,21 +258,33 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
|
|
|
#ifdef HAVE_DWARF_SUPPORT
|
|
|
|
|
|
/* Open new debuginfo of given module */
|
|
|
-static struct debuginfo *open_debuginfo(const char *module)
|
|
|
+static struct debuginfo *open_debuginfo(const char *module, bool silent)
|
|
|
{
|
|
|
const char *path = module;
|
|
|
+ struct debuginfo *ret;
|
|
|
|
|
|
if (!module || !strchr(module, '/')) {
|
|
|
path = kernel_get_module_path(module);
|
|
|
if (!path) {
|
|
|
- pr_err("Failed to find path of %s module.\n",
|
|
|
- module ?: "kernel");
|
|
|
+ if (!silent)
|
|
|
+ pr_err("Failed to find path of %s module.\n",
|
|
|
+ module ?: "kernel");
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
- return debuginfo__new(path);
|
|
|
+ ret = debuginfo__new(path);
|
|
|
+ if (!ret && !silent) {
|
|
|
+ pr_warning("The %s file has no debug information.\n", path);
|
|
|
+ if (!module || !strtailcmp(path, ".ko"))
|
|
|
+ pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, ");
|
|
|
+ else
|
|
|
+ pr_warning("Rebuild with -g, ");
|
|
|
+ pr_warning("or install an appropriate debuginfo package.\n");
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int get_text_start_address(const char *exec, unsigned long *address)
|
|
|
{
|
|
|
Elf *elf;
|
|
@@ -333,15 +345,13 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
|
|
|
pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
|
|
|
tp->module ? : "kernel");
|
|
|
|
|
|
- dinfo = open_debuginfo(tp->module);
|
|
|
+ dinfo = open_debuginfo(tp->module, verbose == 0);
|
|
|
if (dinfo) {
|
|
|
ret = debuginfo__find_probe_point(dinfo,
|
|
|
(unsigned long)addr, pp);
|
|
|
debuginfo__delete(dinfo);
|
|
|
- } else {
|
|
|
- pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n", addr);
|
|
|
+ } else
|
|
|
ret = -ENOENT;
|
|
|
- }
|
|
|
|
|
|
if (ret > 0) {
|
|
|
pp->retprobe = tp->retprobe;
|
|
@@ -457,13 +467,11 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
|
|
|
struct debuginfo *dinfo;
|
|
|
int ntevs, ret = 0;
|
|
|
|
|
|
- dinfo = open_debuginfo(target);
|
|
|
+ dinfo = open_debuginfo(target, !need_dwarf);
|
|
|
|
|
|
if (!dinfo) {
|
|
|
- if (need_dwarf) {
|
|
|
- pr_warning("Failed to open debuginfo file.\n");
|
|
|
+ if (need_dwarf)
|
|
|
return -ENOENT;
|
|
|
- }
|
|
|
pr_debug("Could not open debuginfo. Try to use symbols.\n");
|
|
|
return 0;
|
|
|
}
|
|
@@ -565,7 +573,7 @@ static int get_real_path(const char *raw_path, const char *comp_dir,
|
|
|
|
|
|
static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
|
|
|
{
|
|
|
- char buf[LINEBUF_SIZE];
|
|
|
+ char buf[LINEBUF_SIZE], sbuf[STRERR_BUFSIZE];
|
|
|
const char *color = show_num ? "" : PERF_COLOR_BLUE;
|
|
|
const char *prefix = NULL;
|
|
|
|
|
@@ -585,7 +593,8 @@ static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
|
|
|
return 1;
|
|
|
error:
|
|
|
if (ferror(fp)) {
|
|
|
- pr_warning("File read error: %s\n", strerror(errno));
|
|
|
+ pr_warning("File read error: %s\n",
|
|
|
+ strerror_r(errno, sbuf, sizeof(sbuf)));
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
@@ -618,13 +627,12 @@ static int __show_line_range(struct line_range *lr, const char *module)
|
|
|
FILE *fp;
|
|
|
int ret;
|
|
|
char *tmp;
|
|
|
+ char sbuf[STRERR_BUFSIZE];
|
|
|
|
|
|
/* Search a line range */
|
|
|
- dinfo = open_debuginfo(module);
|
|
|
- if (!dinfo) {
|
|
|
- pr_warning("Failed to open debuginfo file.\n");
|
|
|
+ dinfo = open_debuginfo(module, false);
|
|
|
+ if (!dinfo)
|
|
|
return -ENOENT;
|
|
|
- }
|
|
|
|
|
|
ret = debuginfo__find_line_range(dinfo, lr);
|
|
|
debuginfo__delete(dinfo);
|
|
@@ -656,7 +664,7 @@ static int __show_line_range(struct line_range *lr, const char *module)
|
|
|
fp = fopen(lr->path, "r");
|
|
|
if (fp == NULL) {
|
|
|
pr_warning("Failed to open %s: %s\n", lr->path,
|
|
|
- strerror(errno));
|
|
|
+ strerror_r(errno, sbuf, sizeof(sbuf)));
|
|
|
return -errno;
|
|
|
}
|
|
|
/* Skip to starting line number */
|
|
@@ -772,9 +780,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
- dinfo = open_debuginfo(module);
|
|
|
+ dinfo = open_debuginfo(module, false);
|
|
|
if (!dinfo) {
|
|
|
- pr_warning("Failed to open debuginfo file.\n");
|
|
|
ret = -ENOENT;
|
|
|
goto out;
|
|
|
}
|
|
@@ -1405,8 +1412,7 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
|
|
|
|
|
|
return tmp - buf;
|
|
|
error:
|
|
|
- pr_debug("Failed to synthesize perf probe argument: %s\n",
|
|
|
- strerror(-ret));
|
|
|
+ pr_debug("Failed to synthesize perf probe argument: %d\n", ret);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -1455,8 +1461,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
|
|
|
|
|
|
return buf;
|
|
|
error:
|
|
|
- pr_debug("Failed to synthesize perf probe point: %s\n",
|
|
|
- strerror(-ret));
|
|
|
+ pr_debug("Failed to synthesize perf probe point: %d\n", ret);
|
|
|
free(buf);
|
|
|
return NULL;
|
|
|
}
|
|
@@ -1782,7 +1787,7 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
|
|
|
|
|
|
static void print_open_warning(int err, bool is_kprobe)
|
|
|
{
|
|
|
- char sbuf[128];
|
|
|
+ char sbuf[STRERR_BUFSIZE];
|
|
|
|
|
|
if (err == -ENOENT) {
|
|
|
const char *config;
|
|
@@ -1812,7 +1817,7 @@ static void print_both_open_warning(int kerr, int uerr)
|
|
|
pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
|
|
|
"or/and CONFIG_UPROBE_EVENTS.\n");
|
|
|
else {
|
|
|
- char sbuf[128];
|
|
|
+ char sbuf[STRERR_BUFSIZE];
|
|
|
pr_warning("Failed to open kprobe events: %s.\n",
|
|
|
strerror_r(-kerr, sbuf, sizeof(sbuf)));
|
|
|
pr_warning("Failed to open uprobe events: %s.\n",
|
|
@@ -1876,7 +1881,7 @@ static struct strlist *get_probe_trace_command_rawlist(int fd)
|
|
|
p[idx] = '\0';
|
|
|
ret = strlist__add(sl, buf);
|
|
|
if (ret < 0) {
|
|
|
- pr_debug("strlist__add failed: %s\n", strerror(-ret));
|
|
|
+ pr_debug("strlist__add failed (%d)\n", ret);
|
|
|
strlist__delete(sl);
|
|
|
return NULL;
|
|
|
}
|
|
@@ -1935,7 +1940,7 @@ static int __show_perf_probe_events(int fd, bool is_kprobe)
|
|
|
|
|
|
rawlist = get_probe_trace_command_rawlist(fd);
|
|
|
if (!rawlist)
|
|
|
- return -ENOENT;
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
strlist__for_each(ent, rawlist) {
|
|
|
ret = parse_probe_trace_command(ent->s, &tev);
|
|
@@ -2002,6 +2007,8 @@ static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
|
|
|
|
|
|
memset(&tev, 0, sizeof(tev));
|
|
|
rawlist = get_probe_trace_command_rawlist(fd);
|
|
|
+ if (!rawlist)
|
|
|
+ return NULL;
|
|
|
sl = strlist__new(true, NULL);
|
|
|
strlist__for_each(ent, rawlist) {
|
|
|
ret = parse_probe_trace_command(ent->s, &tev);
|
|
@@ -2031,6 +2038,7 @@ static int write_probe_trace_event(int fd, struct probe_trace_event *tev)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
char *buf = synthesize_probe_trace_command(tev);
|
|
|
+ char sbuf[STRERR_BUFSIZE];
|
|
|
|
|
|
if (!buf) {
|
|
|
pr_debug("Failed to synthesize probe trace event.\n");
|
|
@@ -2042,7 +2050,7 @@ static int write_probe_trace_event(int fd, struct probe_trace_event *tev)
|
|
|
ret = write(fd, buf, strlen(buf));
|
|
|
if (ret <= 0)
|
|
|
pr_warning("Failed to write event: %s\n",
|
|
|
- strerror(errno));
|
|
|
+ strerror_r(errno, sbuf, sizeof(sbuf)));
|
|
|
}
|
|
|
free(buf);
|
|
|
return ret;
|
|
@@ -2056,7 +2064,7 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
|
|
|
/* Try no suffix */
|
|
|
ret = e_snprintf(buf, len, "%s", base);
|
|
|
if (ret < 0) {
|
|
|
- pr_debug("snprintf() failed: %s\n", strerror(-ret));
|
|
|
+ pr_debug("snprintf() failed: %d\n", ret);
|
|
|
return ret;
|
|
|
}
|
|
|
if (!strlist__has_entry(namelist, buf))
|
|
@@ -2072,7 +2080,7 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
|
|
|
for (i = 1; i < MAX_EVENT_INDEX; i++) {
|
|
|
ret = e_snprintf(buf, len, "%s_%d", base, i);
|
|
|
if (ret < 0) {
|
|
|
- pr_debug("snprintf() failed: %s\n", strerror(-ret));
|
|
|
+ pr_debug("snprintf() failed: %d\n", ret);
|
|
|
return ret;
|
|
|
}
|
|
|
if (!strlist__has_entry(namelist, buf))
|
|
@@ -2437,7 +2445,8 @@ static int __del_trace_probe_event(int fd, struct str_node *ent)
|
|
|
printf("Removed event: %s\n", ent->s);
|
|
|
return 0;
|
|
|
error:
|
|
|
- pr_warning("Failed to delete event: %s\n", strerror(-ret));
|
|
|
+ pr_warning("Failed to delete event: %s\n",
|
|
|
+ strerror_r(-ret, buf, sizeof(buf)));
|
|
|
return ret;
|
|
|
}
|
|
|
|