trace.c revision fb45fd5cfed8bdccd0859c7fc05449fc187e2d06
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Backtrace debugging 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "trace.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct dl_list active_references = 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ &active_references, &active_references }; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE_BFD 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <bfd.h> 217832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt 227832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#define DMGL_PARAMS (1 << 0) 237832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#define DMGL_ANSI (1 << 1) 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char *prg_fname = NULL; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic bfd *cached_abfd = NULL; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic asymbol **syms = NULL; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void get_prg_fname(void) 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char exe[50], fname[512]; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(exe, sizeof(exe) - 1, "/proc/%u/exe", getpid()); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = readlink(exe, fname, sizeof(fname) - 1); 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0 || len >= (int) sizeof(fname)) { 36fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "readlink: %s", strerror(errno)); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname[len] = '\0'; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prg_fname = strdup(fname); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic bfd * open_bfd(const char *fname) 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd *abfd; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char **matching; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abfd = bfd_openr(prg_fname, NULL); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (abfd == NULL) { 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "bfd_openr failed"); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bfd_check_format(abfd, bfd_archive)) { 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "bfd_check_format failed"); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_close(abfd); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!bfd_check_format_matches(abfd, bfd_object, &matching)) { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "bfd_check_format_matches failed"); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(matching); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_close(abfd); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return abfd; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void read_syms(bfd *abfd) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long storage, symcount; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_boolean dynamic = FALSE; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (syms) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(bfd_get_file_flags(abfd) & HAS_SYMS)) { 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "No symbols"); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt storage = bfd_get_symtab_upper_bound(abfd); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (storage == 0) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt storage = bfd_get_dynamic_symtab_upper_bound(abfd); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dynamic = TRUE; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (storage < 0) { 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Unknown symtab upper bound"); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt syms = malloc(storage); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (syms == NULL) { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to allocate memory for symtab " 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%ld bytes)", storage); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dynamic) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symcount = bfd_canonicalize_symtab(abfd, syms); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (symcount < 0) { 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to canonicalize %ssymtab", 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dynamic ? "dynamic " : ""); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(syms); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt syms = NULL; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct bfd_data { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_vma pc; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_boolean found; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *filename; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *function; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int line; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void find_addr_sect(bfd *abfd, asection *section, void *obj) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct bfd_data *data = obj; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_vma vma; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_size_type size; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->found) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(bfd_get_section_vma(abfd, section))) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vma = bfd_get_section_vma(abfd, section); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->pc < vma) 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size = bfd_get_section_size(section); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->pc >= vma + size) 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->found = bfd_find_nearest_line(abfd, section, syms, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pc - vma, 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data->filename, 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data->function, 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data->line); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_trace_bfd_addr(void *pc) 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd *abfd = cached_abfd; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct bfd_data data; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *aname = NULL; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *filename; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (abfd == NULL) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.pc = (bfd_vma) pc; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.found = FALSE; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_map_over_sections(abfd, find_addr_sect, &data); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data.found) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data.function) 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aname = bfd_demangle(abfd, data.function, 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DMGL_ANSI | DMGL_PARAMS); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = aname ? aname : data.function; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt filename = data.filename; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (filename) { 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end = os_strrchr(filename, '/'); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i = 0; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*filename && *filename == prg_fname[i] && 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt filename <= end) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt filename++; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, " %s() %s:%u", 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name, filename, data.line); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(aname); 1887d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt aname = NULL; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.found = bfd_find_inliner_info(abfd, &data.filename, 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data.function, &data.line); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (data.found); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * wpa_trace_bfd_addr2func(void *pc) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd *abfd = cached_abfd; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct bfd_data data; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (abfd == NULL) 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.pc = (bfd_vma) pc; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.found = FALSE; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bfd_map_over_sections(abfd, find_addr_sect, &data); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data.found) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data.function; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_trace_bfd_init(void) 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!prg_fname) { 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt get_prg_fname(); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!prg_fname) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cached_abfd) { 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cached_abfd = open_bfd(prg_fname); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cached_abfd) { 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to open bfd"); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt read_syms(cached_abfd); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!syms) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to read symbols"); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_trace_dump_funcname(const char *title, void *pc) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "WPA_TRACE: %s: %p", title, pc); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_bfd_init(); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_bfd_addr(pc); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPA_TRACE_BFD */ 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define wpa_trace_bfd_init() do { } while (0) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define wpa_trace_bfd_addr(pc) do { } while (0) 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define wpa_trace_bfd_addr2func(pc) NULL 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE_BFD */ 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_trace_dump_func(const char *title, void **btrace, int btrace_num) 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char **sym; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { TRACE_HEAD, TRACE_RELEVANT, TRACE_TAIL } state; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_bfd_init(); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "WPA_TRACE: %s - START", title); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sym = backtrace_symbols(btrace, btrace_num); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TRACE_HEAD; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < btrace_num; i++) { 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *func = wpa_trace_bfd_addr2func(btrace[i]); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (state == TRACE_HEAD && func && 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (os_strcmp(func, "wpa_trace_add_ref_func") == 0 || 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(func, "wpa_trace_check_ref") == 0 || 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(func, "wpa_trace_show") == 0)) 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (state == TRACE_TAIL && sym && sym[i] && 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strstr(sym[i], "__libc_start_main")) 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (state == TRACE_HEAD) 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TRACE_RELEVANT; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sym) 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "[%d]: %s", i, sym[i]); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "[%d]: ?? [%p]", i, btrace[i]); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_bfd_addr(btrace[i]); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (state == TRACE_RELEVANT && func && 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(func, "main") == 0) 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TRACE_TAIL; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(sym); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "WPA_TRACE: %s - END", title); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_trace_show(const char *title) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct info { 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_TRACE_INFO 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } info; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_record(&info); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_dump(title, &info); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr) 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr == NULL) 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ref->addr = addr; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_record(ref); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&active_references, &ref->list); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_trace_check_ref(const void *addr) 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_trace_ref *ref; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(ref, &active_references, struct wpa_trace_ref, list) { 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr != ref->addr) 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_show("Freeing referenced memory"); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_dump("Reference registration", ref); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort(); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 323