blob: 777f91880cdb1ffac3a789a98e55ca5988d4782e [file] [log] [blame]
Namhyung Kimf048d542013-09-11 14:09:28 +09001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <linux/kernel.h>
6
7#include "util/util.h"
8#include "util/debug.h"
9
10static int addr2line(const char *dso_name, unsigned long addr,
11 char **file, unsigned int *line_nr)
12{
13 FILE *fp;
14 char cmd[PATH_MAX];
15 char *filename = NULL;
16 size_t len;
17 char *sep;
18 int ret = 0;
19
20 scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64,
21 dso_name, addr);
22
23 fp = popen(cmd, "r");
24 if (fp == NULL) {
25 pr_warning("popen failed for %s\n", dso_name);
26 return 0;
27 }
28
29 if (getline(&filename, &len, fp) < 0 || !len) {
30 pr_warning("addr2line has no output for %s\n", dso_name);
31 goto out;
32 }
33
34 sep = strchr(filename, '\n');
35 if (sep)
36 *sep = '\0';
37
38 if (!strcmp(filename, "??:0")) {
39 pr_debug("no debugging info in %s\n", dso_name);
40 free(filename);
41 goto out;
42 }
43
44 sep = strchr(filename, ':');
45 if (sep) {
46 *sep++ = '\0';
47 *file = filename;
48 *line_nr = strtoul(sep, NULL, 0);
49 ret = 1;
50 }
51out:
52 pclose(fp);
53 return ret;
54}
55
56char *get_srcline(const char *dso_name, unsigned long addr)
57{
58 char *file;
59 unsigned line;
Namhyung Kim58d91a02013-09-11 14:09:29 +090060 char *srcline = SRCLINE_UNKNOWN;
Namhyung Kimf048d542013-09-11 14:09:28 +090061 size_t size;
62
Namhyung Kim58d91a02013-09-11 14:09:29 +090063 if (dso_name[0] == '[')
64 goto out;
65
66 if (!strncmp(dso_name, "/tmp/perf-", 10))
67 goto out;
68
Namhyung Kimf048d542013-09-11 14:09:28 +090069 if (!addr2line(dso_name, addr, &file, &line))
Namhyung Kim58d91a02013-09-11 14:09:29 +090070 goto out;
Namhyung Kimf048d542013-09-11 14:09:28 +090071
72 /* just calculate actual length */
73 size = snprintf(NULL, 0, "%s:%u", file, line) + 1;
74
75 srcline = malloc(size);
76 if (srcline)
77 snprintf(srcline, size, "%s:%u", file, line);
78 else
79 srcline = SRCLINE_UNKNOWN;
80
81 free(file);
Namhyung Kim58d91a02013-09-11 14:09:29 +090082out:
Namhyung Kimf048d542013-09-11 14:09:28 +090083 return srcline;
84}
85
86void free_srcline(char *srcline)
87{
88 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
89 free(srcline);
90}