1 // SPDX-License-Identifier: GPL-2.0
2 #include "addr2line.h"
3 #include "debug.h"
4 #include "dso.h"
5 #include "string2.h"
6 #include "srcline.h"
7 #include "symbol.h"
8 #include "symbol_conf.h"
9
10 #include <api/io.h>
11 #include <linux/zalloc.h>
12 #include <subcmd/run-command.h>
13
14 #include <inttypes.h>
15 #include <signal.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #define MAX_INLINE_NEST 1024
20
21 /* If addr2line doesn't return data for 1 second then timeout. */
22 int addr2line_timeout_ms = 1 * 1000;
23
filename_split(char * filename,unsigned int * line_nr)24 static int filename_split(char *filename, unsigned int *line_nr)
25 {
26 char *sep;
27
28 sep = strchr(filename, '\n');
29 if (sep)
30 *sep = '\0';
31
32 if (!strcmp(filename, "??:0"))
33 return 0;
34
35 sep = strchr(filename, ':');
36 if (sep) {
37 *sep++ = '\0';
38 *line_nr = strtoul(sep, NULL, 0);
39 return 1;
40 }
41 pr_debug("addr2line missing ':' in filename split\n");
42 return 0;
43 }
44
addr2line_subprocess_cleanup(struct child_process * a2l)45 static void addr2line_subprocess_cleanup(struct child_process *a2l)
46 {
47 if (a2l->pid != -1) {
48 kill(a2l->pid, SIGKILL);
49 finish_command(a2l); /* ignore result, we don't care */
50 a2l->pid = -1;
51 close(a2l->in);
52 close(a2l->out);
53 }
54
55 free(a2l);
56 }
57
addr2line_subprocess_init(const char * addr2line_path,const char * binary_path)58 static struct child_process *addr2line_subprocess_init(const char *addr2line_path,
59 const char *binary_path)
60 {
61 const char *argv[] = {
62 addr2line_path ?: "addr2line",
63 "-e", binary_path,
64 "-a", "-i", "-f", NULL
65 };
66 struct child_process *a2l = zalloc(sizeof(*a2l));
67 int start_command_status = 0;
68
69 if (a2l == NULL) {
70 pr_err("Failed to allocate memory for addr2line");
71 return NULL;
72 }
73
74 a2l->pid = -1;
75 a2l->in = -1;
76 a2l->out = -1;
77 a2l->no_stderr = 1;
78
79 a2l->argv = argv;
80 start_command_status = start_command(a2l);
81 a2l->argv = NULL; /* it's not used after start_command; avoid dangling pointers */
82
83 if (start_command_status != 0) {
84 pr_warning("could not start addr2line (%s) for %s: start_command return code %d\n",
85 addr2line_path, binary_path, start_command_status);
86 addr2line_subprocess_cleanup(a2l);
87 return NULL;
88 }
89
90 return a2l;
91 }
92
93 enum a2l_style {
94 BROKEN,
95 GNU_BINUTILS,
96 LLVM,
97 };
98
addr2line_configure(struct child_process * a2l,const char * dso_name)99 static enum a2l_style addr2line_configure(struct child_process *a2l, const char *dso_name)
100 {
101 static bool cached;
102 static enum a2l_style style;
103
104 if (!cached) {
105 char buf[128];
106 struct io io;
107 int ch;
108 int lines;
109
110 if (write(a2l->in, ",\n", 2) != 2)
111 return BROKEN;
112
113 io__init(&io, a2l->out, buf, sizeof(buf));
114 ch = io__get_char(&io);
115 if (ch == ',') {
116 style = LLVM;
117 cached = true;
118 lines = 1;
119 pr_debug3("Detected LLVM addr2line style\n");
120 } else if (ch == '0') {
121 style = GNU_BINUTILS;
122 cached = true;
123 lines = 3;
124 pr_debug3("Detected binutils addr2line style\n");
125 } else {
126 if (!symbol_conf.disable_add2line_warn) {
127 char *output = NULL;
128 size_t output_len;
129
130 io__getline(&io, &output, &output_len);
131 pr_warning("%s %s: addr2line configuration failed\n",
132 __func__, dso_name);
133 pr_warning("\t%c%s", ch, output);
134 }
135 pr_debug("Unknown/broken addr2line style\n");
136 return BROKEN;
137 }
138 while (lines) {
139 ch = io__get_char(&io);
140 if (ch <= 0)
141 break;
142 if (ch == '\n')
143 lines--;
144 }
145 /* Ignore SIGPIPE in the event addr2line exits. */
146 signal(SIGPIPE, SIG_IGN);
147 }
148 return style;
149 }
150
read_addr2line_record(struct io * io,enum a2l_style style,const char * dso_name,u64 addr,bool first,char ** function,char ** filename,unsigned int * line_nr)151 static int read_addr2line_record(struct io *io,
152 enum a2l_style style,
153 const char *dso_name,
154 u64 addr,
155 bool first,
156 char **function,
157 char **filename,
158 unsigned int *line_nr)
159 {
160 /*
161 * Returns:
162 * -1 ==> error
163 * 0 ==> sentinel (or other ill-formed) record read
164 * 1 ==> a genuine record read
165 */
166 char *line = NULL;
167 size_t line_len = 0;
168 unsigned int dummy_line_nr = 0;
169 int ret = -1;
170
171 if (function != NULL)
172 zfree(function);
173
174 if (filename != NULL)
175 zfree(filename);
176
177 if (line_nr != NULL)
178 *line_nr = 0;
179
180 /*
181 * Read the first line. Without an error this will be:
182 * - for the first line an address like 0x1234,
183 * - the binutils sentinel 0x0000000000000000,
184 * - the llvm-addr2line the sentinel ',' character,
185 * - the function name line for an inlined function.
186 */
187 if (io__getline(io, &line, &line_len) < 0 || !line_len)
188 goto error;
189
190 pr_debug3("%s %s: addr2line read address for sentinel: %s", __func__, dso_name, line);
191 if (style == LLVM && line_len == 2 && line[0] == ',') {
192 /* Found the llvm-addr2line sentinel character. */
193 zfree(&line);
194 return 0;
195 } else if (style == GNU_BINUTILS && (!first || addr != 0)) {
196 int zero_count = 0, non_zero_count = 0;
197 /*
198 * Check for binutils sentinel ignoring it for the case the
199 * requested address is 0.
200 */
201
202 /* A given address should always start 0x. */
203 if (line_len >= 2 || line[0] != '0' || line[1] != 'x') {
204 for (size_t i = 2; i < line_len; i++) {
205 if (line[i] == '0')
206 zero_count++;
207 else if (line[i] != '\n')
208 non_zero_count++;
209 }
210 if (!non_zero_count) {
211 int ch;
212
213 if (first && !zero_count) {
214 /* Line was erroneous just '0x'. */
215 goto error;
216 }
217 /*
218 * Line was 0x0..0, the sentinel for binutils. Remove
219 * the function and filename lines.
220 */
221 zfree(&line);
222 do {
223 ch = io__get_char(io);
224 } while (ch > 0 && ch != '\n');
225 do {
226 ch = io__get_char(io);
227 } while (ch > 0 && ch != '\n');
228 return 0;
229 }
230 }
231 }
232 /* Read the second function name line (if inline data then this is the first line). */
233 if (first && (io__getline(io, &line, &line_len) < 0 || !line_len))
234 goto error;
235
236 pr_debug3("%s %s: addr2line read line: %s", __func__, dso_name, line);
237 if (function != NULL)
238 *function = strdup(strim(line));
239
240 zfree(&line);
241 line_len = 0;
242
243 /* Read the third filename and line number line. */
244 if (io__getline(io, &line, &line_len) < 0 || !line_len)
245 goto error;
246
247 pr_debug3("%s %s: addr2line filename:number : %s", __func__, dso_name, line);
248 if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0 &&
249 style == GNU_BINUTILS) {
250 ret = 0;
251 goto error;
252 }
253
254 if (filename != NULL)
255 *filename = strdup(line);
256
257 zfree(&line);
258 line_len = 0;
259
260 return 1;
261
262 error:
263 free(line);
264 if (function != NULL)
265 zfree(function);
266 if (filename != NULL)
267 zfree(filename);
268 return ret;
269 }
270
inline_list__append_record(struct dso * dso,struct inline_node * node,struct symbol * sym,const char * function,const char * filename,unsigned int line_nr)271 static int inline_list__append_record(struct dso *dso,
272 struct inline_node *node,
273 struct symbol *sym,
274 const char *function,
275 const char *filename,
276 unsigned int line_nr)
277 {
278 struct symbol *inline_sym = new_inline_sym(dso, sym, function);
279
280 return inline_list__append(inline_sym, srcline_from_fileline(filename, line_nr), node);
281 }
282
cmd__addr2line(const char * dso_name,u64 addr,char ** file,unsigned int * line_nr,struct dso * dso,bool unwind_inlines,struct inline_node * node,struct symbol * sym __maybe_unused)283 int cmd__addr2line(const char *dso_name, u64 addr,
284 char **file, unsigned int *line_nr,
285 struct dso *dso,
286 bool unwind_inlines,
287 struct inline_node *node,
288 struct symbol *sym __maybe_unused)
289 {
290 struct child_process *a2l = dso__a2l(dso);
291 char *record_function = NULL;
292 char *record_filename = NULL;
293 unsigned int record_line_nr = 0;
294 int record_status = -1;
295 int ret = 0;
296 size_t inline_count = 0;
297 int len;
298 char buf[128];
299 ssize_t written;
300 struct io io = { .eof = false };
301 enum a2l_style a2l_style;
302
303 if (!a2l) {
304 if (!filename__has_section(dso_name, ".debug_line"))
305 goto out;
306
307 dso__set_a2l(dso,
308 addr2line_subprocess_init(symbol_conf.addr2line_path, dso_name));
309 a2l = dso__a2l(dso);
310 }
311
312 if (a2l == NULL) {
313 if (!symbol_conf.disable_add2line_warn)
314 pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__, dso_name);
315 goto out;
316 }
317 a2l_style = addr2line_configure(a2l, dso_name);
318 if (a2l_style == BROKEN)
319 goto out;
320
321 /*
322 * Send our request and then *deliberately* send something that can't be
323 * interpreted as a valid address to ask addr2line about (namely,
324 * ","). This causes addr2line to first write out the answer to our
325 * request, in an unbounded/unknown number of records, and then to write
326 * out the lines "0x0...0", "??" and "??:0", for GNU binutils, or ","
327 * for llvm-addr2line, so that we can detect when it has finished giving
328 * us anything useful.
329 */
330 len = snprintf(buf, sizeof(buf), "%016"PRIx64"\n,\n", addr);
331 written = len > 0 ? write(a2l->in, buf, len) : -1;
332 if (written != len) {
333 if (!symbol_conf.disable_add2line_warn)
334 pr_warning("%s %s: could not send request\n", __func__, dso_name);
335 goto out;
336 }
337 io__init(&io, a2l->out, buf, sizeof(buf));
338 io.timeout_ms = addr2line_timeout_ms;
339 switch (read_addr2line_record(&io, a2l_style, dso_name, addr, /*first=*/true,
340 &record_function, &record_filename, &record_line_nr)) {
341 case -1:
342 if (!symbol_conf.disable_add2line_warn)
343 pr_warning("%s %s: could not read first record\n", __func__, dso_name);
344 goto out;
345 case 0:
346 /*
347 * The first record was invalid, so return failure, but first
348 * read another record, since we sent a sentinel ',' for the
349 * sake of detected the last inlined function. Treat this as the
350 * first of a record as the ',' generates a new start with GNU
351 * binutils, also force a non-zero address as we're no longer
352 * reading that record.
353 */
354 switch (read_addr2line_record(&io, a2l_style, dso_name,
355 /*addr=*/1, /*first=*/true,
356 NULL, NULL, NULL)) {
357 case -1:
358 if (!symbol_conf.disable_add2line_warn)
359 pr_warning("%s %s: could not read sentinel record\n",
360 __func__, dso_name);
361 break;
362 case 0:
363 /* The sentinel as expected. */
364 break;
365 default:
366 if (!symbol_conf.disable_add2line_warn)
367 pr_warning("%s %s: unexpected record instead of sentinel",
368 __func__, dso_name);
369 break;
370 }
371 goto out;
372 default:
373 /* First record as expected. */
374 break;
375 }
376
377 if (file) {
378 *file = strdup(record_filename);
379 ret = 1;
380 }
381 if (line_nr)
382 *line_nr = record_line_nr;
383
384 if (unwind_inlines) {
385 if (node && inline_list__append_record(dso, node, sym,
386 record_function,
387 record_filename,
388 record_line_nr)) {
389 ret = 0;
390 goto out;
391 }
392 }
393
394 /*
395 * We have to read the records even if we don't care about the inline
396 * info. This isn't the first record and force the address to non-zero
397 * as we're reading records beyond the first.
398 */
399 while ((record_status = read_addr2line_record(&io,
400 a2l_style,
401 dso_name,
402 /*addr=*/1,
403 /*first=*/false,
404 &record_function,
405 &record_filename,
406 &record_line_nr)) == 1) {
407 if (unwind_inlines && node && inline_count++ < MAX_INLINE_NEST) {
408 if (inline_list__append_record(dso, node, sym,
409 record_function,
410 record_filename,
411 record_line_nr)) {
412 ret = 0;
413 goto out;
414 }
415 ret = 1; /* found at least one inline frame */
416 }
417 }
418
419 out:
420 free(record_function);
421 free(record_filename);
422 if (io.eof) {
423 dso__set_a2l(dso, NULL);
424 addr2line_subprocess_cleanup(a2l);
425 }
426 return ret;
427 }
428
dso__free_a2l(struct dso * dso)429 void dso__free_a2l(struct dso *dso)
430 {
431 struct child_process *a2l = dso__a2l(dso);
432
433 if (!a2l)
434 return;
435
436 addr2line_subprocess_cleanup(a2l);
437
438 dso__set_a2l(dso, NULL);
439 }
440