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 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 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 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 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 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 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 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 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