https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081
--- Comment #5 from Denis Khalikov <d.khalikov at partner dot samsung.com> --- As I understood libbacktrace has two main calls to symbolize pc. 1. backtrace_pcinfo /* Given a PC, find the file name, line number, and function name. */ 164 165 int 166 backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc, 167 backtrace_full_callback callback, 168 backtrace_error_callback error_callback, void *data) 169 { which initializing data with filename, line number and function name from debuginfo sections 817 if (!backtrace_dwarf_add (state, base_address, 818 sections[DEBUG_INFO].data, 819 sections[DEBUG_INFO].size, 820 sections[DEBUG_LINE].data, 821 sections[DEBUG_LINE].size, 822 sections[DEBUG_ABBREV].data, 823 sections[DEBUG_ABBREV].size, 824 sections[DEBUG_RANGES].data, 825 sections[DEBUG_RANGES].size, 826 sections[DEBUG_STR].data, 827 sections[DEBUG_STR].size, 828 ehdr.e_ident[EI_DATA] == ELFDATA2MSB, 829 error_callback, data, fileline_fn)) 830 goto fail; 831 832 *found_dwarf = 1; 179 /* Given a PC, find the symbol for it, and its value. */ 2. backtrace_syminfo int 182 backtrace_syminfo (struct backtrace_state *state, uintptr_t pc, 183 backtrace_syminfo_callback callback, 184 backtrace_error_callback error_callback, void *data) 185 { Which is using only symbol table to intialize specific data. No debug info needed. 748 if (!elf_initialize_syminfo (state, base_address, 749 symtab_view.data, symtab_shdr->sh_size, 750 strtab_view.data, strtab_shdr->sh_size, 751 error_callback, data, sdata)) Those two calls using in function 156 bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { 157 SymbolizeCodeCallbackArg data; 158 data.first = stack; 159 data.last = stack; 160 data.frames_symbolized = 0; 161 backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback, 162 ErrorCallback, &data); 163 if (data.frames_symbolized > 0) 164 return true; 165 backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback, 166 ErrorCallback, &data); 167 return (data.frames_symbolized > 0); 168 } with two callback: 1. 106 extern "C" { 107 static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr, 108 const char *filename, int lineno, 109 const char *function) { 110 SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata; 111 if (function) { 112 AddressInfo *info = cdata->get_new_frame(addr); 113 info->function = DemangleAlloc(function, /*always_alloc*/ true); 114 if (filename) 115 info->file = internal_strdup(filename); 116 info->line = lineno; 117 cdata->frames_symbolized++; 118 } 119 return 0; 120 } 2.122 static void SymbolizeCodeCallback(void *vdata, uintptr_t addr, 123 const char *symname, uintptr_t, uintptr_t) { 124 SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata; 125 if (symname) { 126 AddressInfo *info = cdata->get_new_frame(addr); 127 info->function = DemangleAlloc(symname, /*always_alloc*/ true); 128 cdata->frames_symbolized++; 129 } 130 } In my case we have partially valid data with line number, filename but we don't have valid function name because debuginfo doesn't provide DW_TAG_subprogram and libbacktrace can not find valid symbol for specific address, but this symbol was read from symbol table and have valid data. My point is to read all data we have from first callback and if we don't have valid function name we assume that pc is not properly symbolized and we go to bactrace_syminfo which will read symbol data and increment cdata->frames_symbolized++; In case those two functions using completely different data to generate backtrace. Thanks.