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