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.

Reply via email to