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