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