https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

Tom de Vries <vries at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |vries at gcc dot gnu.org

--- Comment #10 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #4)
> (In reply to Denis Khalikov from comment #3)
> > This fix
> > 111   AddressInfo *info = cdata->get_new_frame(addr);
> > 112   if (filename)
> > 113     info->file = internal_strdup(filename);
> > 114   info->line = lineno;
> > 115   if (function) {
> > 116     info->function = DemangleAlloc(function, /*always_alloc*/ true);
> > 117     cdata->frames_symbolized++;
> > 118   }
> > 119   return 0;
> > 120 }
> 
> I think you should just return 0; early if function == NULL and
> cdata->frames_symbolized > 0, trying to augment that case with
> backtrace_syminfo doesn't look right.

I don't think it can happen that frames_symbolized > 0 and backtrace_syminfo
gets called, because of the 'if (data.frames_symbolized > 0) return true' here:
...
bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  SymbolizeCodeCallbackArg data;
  data.first = stack;
  data.last = stack;
  data.frames_symbolized = 0;
  backtrace_pcinfo((backtrace_state *)state_, addr,
SymbolizeCodePCInfoCallback,
                   ErrorCallback, &data);
  if (data.frames_symbolized > 0)
    return true;
  backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,
                    ErrorCallback, &data);
  return (data.frames_symbolized > 0);
}
...

(In reply to Jakub Jelinek from comment #6)
> The thing is that for backtrace_pcinfo the callback can be called multiple
> times.
> And IMNSHO the hack you want to do (fill in file/line in the
> backtrace_pcinfo call and function during backtrace_syminfo) is something
> you want to do only if backtrace_pcinfo calls the callback just once.

So how about:
...
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
b/libsanitizer/sanitizer_common
/sanitizer_symbolizer_libbacktrace.cc
index eebc30b124d..79db5d49fba 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
@@ -109,14 +109,13 @@ static int SymbolizeCodePCInfoCallback(void *vdata,
uintptr_t addr,
                                        const char *filename, int lineno,
                                        const char *function) {
   SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
-  if (function) {
-    AddressInfo *info = cdata->get_new_frame(addr);
+  AddressInfo *info = cdata->get_new_frame(addr);
+  if (filename)
+    info->file = internal_strdup(filename);
+  info->line = lineno;
+  if (function)
     info->function = DemangleAlloc(function, /*always_alloc*/ true);
-    if (filename)
-      info->file = internal_strdup(filename);
-    info->line = lineno;
-    cdata->frames_symbolized++;
-  }
+  cdata->frames_symbolized++;
   return 0;
 }

@@ -161,7 +160,11 @@ bool LibbacktraceSymbolizer::SymbolizePC(uptr addr,
SymbolizedStack *stack) {
   data.frames_symbolized = 0;
   backtrace_pcinfo((backtrace_state *)state_, addr,
SymbolizeCodePCInfoCallback,
                    ErrorCallback, &data);
-  if (data.frames_symbolized > 0)
+  if (data.frames_symbolized == 1 && data.last->info.function == 0)
+    /* Augment the frame by trying to fill in the missing function with
+       backtrace_syminfo.  */
+    data.frames_symbolized = 0;
+  else if (data.frames_symbolized > 0)
     return true;
   backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,
                     ErrorCallback, &data);
...
?

Reply via email to