This is an archive of the discontinued LLVM Phabricator instance.

[ASAN] ASAN is not properly calling libbacktrace to symbolize program
AbandonedPublic

Authored by denis13 on Jun 13 2017, 8:39 AM.

Details

Summary

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

There could be a situation when .debug_info has
valid file/line data but doesn't has a dwarf tag
(DW_TAG_subprogram) which represents function address
and name, in this case libbacktrace can not read
symbol info from .debug_info but can read this info from
syminfo table.

Diff Detail

Event Timeline

denis13 created this revision.Jun 13 2017, 8:39 AM
m.ostapenko added inline comments.
lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
113

This doesn't look correct to me. Why do we bail out if function is not NULL? Shouldn't we use (!function && cdata->frames_symbolized > 0) istead? Also please include more context into the patch (git diff -U999999) or something like that.

denis13 added inline comments.Jun 13 2017, 9:29 AM
lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
113

Thanks, my fault.

m.ostapenko added inline comments.Jun 13 2017, 11:06 AM
lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
113

Hm, still can't get this. As far as I can understand, this callback is called before SymbolizeCodeCallback and cdata->frames_symbolized > 0 becomes true only if somewhere before we executed line 121 where we have function != NULL. So, the situation with (!function && cdata->frames_symbolized > 0) corresponds to inlined calls (when multiple locations correspond to one PC), right? But in this case, won't we miss filename and lineno for that inlined functions? Or perhaps I'm missing something?

denis13 added inline comments.Jun 14 2017, 1:20 AM
lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
113

Thanks for question.

This fix cover situation with code written on assembler as it mentioned in PR sanitizer/81081
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081.

In this case we don't have any information about inlined this function or not, because we don't have specific debug info generated by compiler. All debug info generated by "as" and for that reason doesn't contain any tag which represents function (DW_TAG_subprogram).

In other case this code

if (function == NULL && cdata->frames_symbolized)

cover situation with function was inlined and we can't find valid address

2585 static int
2586 report_inlined_functions (uintptr_t pc, struct function *function,
2587                           backtrace_full_callback callback, void *data,
2588                           const char **filename, int *lineno)
2589 {
2590   struct function_addrs *function_addrs;
2591   struct function *inlined;
2592   int ret;
2593 
2594   if (function->function_addrs_count == 0)
2595     return 0;
2596 
2597   function_addrs = ((struct function_addrs *)
2598                     bsearch (&pc, function->function_addrs,
2599                              function->function_addrs_count,
2600                              sizeof (struct function_addrs),
2601                              function_addrs_search));
2602   if (function_addrs == NULL)
2603     return 0;
2604 
2605   while (((size_t) (function_addrs - function->function_addrs) + 1
2606           < function->function_addrs_count)
2607          && pc >= (function_addrs + 1)->low
2608          && pc < (function_addrs + 1)->high)
2609     ++function_addrs;
2610
vries added a subscriber: vries.Feb 21 2019, 1:52 AM

I've filed an alternative patch for the same problem here ( https://reviews.llvm.org/D58493 ), hoping that the alternative patch will address the concerns raised in this review.

Thanks,

  • Tom
denis13 abandoned this revision.Jan 16 2020, 8:17 AM