[Sanitizer] Add rudimentary support for using libbacktrace in symbolizer.

Kostya Serebryany kcc at google.com
Mon Jan 13 03:17:05 PST 2014


Jakub, thanks for the patch.
I'd like Alexey to handle this and the next one -- he will reply later,
most likely around ~Thu/Fri this week.

--kcc


On Fri, Jan 10, 2014 at 2:15 PM, Jakub Jelinek <jakub at redhat.com> wrote:

> On Thu, Jan 09, 2014 at 03:11:16PM -0800, Chandler Carruth wrote:
> > I've mailed out a patch to the LLVM developer's policy which should
> clarify
> > this. The only thing that would help is for the authors of these three
> > patches (and the fourth patch I found later) to just email a copy of the
> > patch to llvm-commits, or if any of you have commit access to directly
> > commit the patch.
>
> Here I'm submitting my contribution to the libbacktrace sanitization patch,
> which has been posted in
> http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02338.html
> Note that Alexey has made quite a few changes to the patch that has been
> eventually committed as r196875, so is this post sufficient for Alexey
> to commit again his r196875 change?
>
> --- lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc.jj
> 2013-11-12 19:35:30.000000000 +0100
> +++ lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc  2013-11-19
> 16:54:56.831724908 +0100
> @@ -21,6 +21,7 @@
>  #include "sanitizer_placement_new.h"
>  #include "sanitizer_procmaps.h"
>  #include "sanitizer_symbolizer.h"
> +#include "sanitizer_symbolizer_libbacktrace.h"
>
>  #include <errno.h>
>  #include <stdlib.h>
> @@ -367,9 +368,11 @@ class InternalSymbolizer {
>  class POSIXSymbolizer : public Symbolizer {
>   public:
>    POSIXSymbolizer(ExternalSymbolizer *external_symbolizer,
> +                 LibbacktraceSymbolizer *libbacktrace_symbolizer,
>                    InternalSymbolizer *internal_symbolizer)
>        : Symbolizer(),
>          external_symbolizer_(external_symbolizer),
> +       libbacktrace_symbolizer_(libbacktrace_symbolizer),
>          internal_symbolizer_(internal_symbolizer) {}
>
>    uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) {
> @@ -381,7 +384,19 @@ class POSIXSymbolizer : public Symbolize
>        return 0;
>      const char *module_name = module->full_name();
>      uptr module_offset = addr - module->base_address();
> -    const char *str = SendCommand(false, module_name, module_offset);
> +    const char *str = NULL;
> +    if (libbacktrace_symbolizer_)
> +      {
> +       mu_.CheckLocked();
> +       uptr ret
> +         = libbacktrace_symbolizer_->SymbolizeCode(addr, frames,
> max_frames,
> +                                                   module_name,
> +                                                   module_offset);
> +       if (ret)
> +         return ret;
> +      }
> +    else
> +      str = SendCommand(false, module_name, module_offset);
>      if (str == 0) {
>        // External symbolizer was not initialized or failed. Fill only data
>        // about module name and offset.
> @@ -444,6 +459,11 @@ class POSIXSymbolizer : public Symbolize
>      info->address = addr;
>      info->module = internal_strdup(module_name);
>      info->module_offset = module_offset;
> +    if (libbacktrace_symbolizer_) {
> +      mu_.CheckLocked();
> +      libbacktrace_symbolizer_->SymbolizeData(info);
> +      return true;
> +    }
>      const char *str = SendCommand(true, module_name, module_offset);
>      if (str == 0)
>        return true;
> @@ -455,7 +477,9 @@ class POSIXSymbolizer : public Symbolize
>    }
>
>    bool IsAvailable() {
> -    return internal_symbolizer_ != 0 || external_symbolizer_ != 0;
> +    return internal_symbolizer_ != 0 ||
> +          libbacktrace_symbolizer_ != 0 ||
> +          external_symbolizer_ != 0;
>    }
>
>    bool IsExternalAvailable() {
> @@ -573,14 +597,19 @@ class POSIXSymbolizer : public Symbolize
>
>    ExternalSymbolizer *external_symbolizer_;        // Leaked.
>    InternalSymbolizer *const internal_symbolizer_;  // Leaked.
> +  LibbacktraceSymbolizer *libbacktrace_symbolizer_;  // Leaked.
>  };
>
>  Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) {
>    InternalSymbolizer* internal_symbolizer =
>        InternalSymbolizer::get(&symbolizer_allocator_);
> +  LibbacktraceSymbolizer* libbacktrace_symbolizer = 0;
>    ExternalSymbolizer *external_symbolizer = 0;
>
> -  if (!internal_symbolizer) {
> +  if (!internal_symbolizer)
> +    libbacktrace_symbolizer =
> +      LibbacktraceSymbolizer::get(&symbolizer_allocator_);
> +  if (!internal_symbolizer && !libbacktrace_symbolizer) {
>      if (!path_to_external || path_to_external[0] == '\0')
>        path_to_external = FindPathToBinary("llvm-symbolizer");
>
> @@ -593,7 +622,8 @@ Symbolizer *Symbolizer::PlatformInit(con
>    }
>
>    return new(symbolizer_allocator_)
> -      POSIXSymbolizer(external_symbolizer, internal_symbolizer);
> +      POSIXSymbolizer(external_symbolizer, libbacktrace_symbolizer,
> +                     internal_symbolizer);
>  }
>
>  }  // namespace __sanitizer
>
> --- lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc.jj
>  2013-11-19 16:41:37.811809494 +0100
> +++ lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc   2013-11-19
> 16:56:34.111233379 +0100
> @@ -0,0 +1,151 @@
> +//===-- sanitizer_symbolizer_libbacktrace.cc
> ------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file is shared between AddressSanitizer and ThreadSanitizer
> +// run-time libraries.
> +// Libbacktrace implementation of symbolizer parts.
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "sanitizer_platform.h"
> +#if SANITIZER_POSIX
> +#include "sanitizer_allocator_internal.h"
> +#include "sanitizer_common.h"
> +#include "sanitizer_internal_defs.h"
> +#include "sanitizer_linux.h"
> +#include "sanitizer_placement_new.h"
> +#include "sanitizer_procmaps.h"
> +#include "sanitizer_symbolizer.h"
> +#include "sanitizer_symbolizer_libbacktrace.h"
> +
> +#include <stdlib.h>
> +#include <unistd.h>
> +
> +#ifdef SANITIZER_LIBBACKTRACE
> +#include "backtrace-supported.h"
> +#if SANITIZER_POSIX && BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC
> +#include "backtrace.h"
> +#else
> +#undef SANITIZER_LIBBACKTRACE
> +#endif
> +#endif
> +
> +namespace __sanitizer {
> +
> +#ifdef SANITIZER_LIBBACKTRACE
> +namespace {
> +
> +struct SymbolizeCodeData {
> +  AddressInfo *frames;
> +  uptr n_frames;
> +  uptr max_frames;
> +  const char *module_name;
> +  uptr module_offset;
> +};
> +
> +extern "C" {
> +
> +static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,
> +                                      const char *filename, int lineno,
> +                                      const char *function) {
> +  SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;
> +  if (function) {
> +    AddressInfo *info = &cdata->frames[cdata->n_frames++];
> +    info->Clear();
> +    info->FillAddressAndModuleInfo(addr, cdata->module_name,
> cdata->module_offset);
> +    info->function = internal_strdup(function);
> +    if (filename)
> +      info->file = internal_strdup(filename);
> +    info->line = lineno;
> +    if (cdata->n_frames == cdata->max_frames)
> +      return 1;
> +  }
> +  return 0;
> +}
> +
> +static void SymbolizeCodeCallback(void *vdata, uintptr_t addr,
> +                                 const char *symname, uintptr_t,
> uintptr_t) {
> +  SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;
> +  if (symname) {
> +    AddressInfo *info = &cdata->frames[0];
> +    info->Clear();
> +    info->FillAddressAndModuleInfo(addr, cdata->module_name,
> cdata->module_offset);
> +    info->function = internal_strdup(symname);
> +    cdata->n_frames = 1;
> +  }
> +}
> +
> +static void SymbolizeDataCallback(void *vdata, uintptr_t,
> +                                 const char *symname,
> +                                 uintptr_t symval, uintptr_t symsize) {
> +  DataInfo *info = (DataInfo *)vdata;
> +  if (symname && symval) {
> +    info->name = internal_strdup(symname);
> +    info->start = symval;
> +    info->size = symsize;
> +  }
> +}
> +
> +static void ErrorCallback(void *, const char *, int) {
> +}
> +
> +}
> +
> +}
> +
> +LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator
> *alloc) {
> +  void *state
> +    = (void *) backtrace_create_state("/proc/self/exe", 0, ErrorCallback,
> NULL);
> +  if (!state)
> +    return 0;
> +  return new(*alloc) LibbacktraceSymbolizer(state);
> +}
> +
> +uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,
> +                                          uptr max_frames,
> +                                          const char *module_name,
> +                                          uptr module_offset) {
> +  SymbolizeCodeData data;
> +  data.frames = frames;
> +  data.n_frames = 0;
> +  data.max_frames = max_frames;
> +  data.module_name = module_name;
> +  data.module_offset = module_offset;
> +  backtrace_pcinfo((backtrace_state) state_, addr,
> SymbolizeCodePCInfoCallback,
> +                  ErrorCallback, &data);
> +  if (data.n_frames)
> +    return data.n_frames;
> +  backtrace_syminfo((backtrace_state) state_, addr, SymbolizeCodeCallback,
> +                   ErrorCallback, &data);
> +  return data.n_frames;
> +}
> +
> +void LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) {
> +  backtrace_syminfo((backtrace_state) state_, info->address,
> +                   SymbolizeDataCallback, ErrorCallback, info);
> +}
> +
> +#else
> +
> +LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *) {
> +  return 0;
> +}
> +
> +uptr LibbacktraceSymbolizer::SymbolizeCode(uptr, AddressInfo *, uptr,
> +                                          const char *, uptr) {
> +  return 0;
> +}
> +
> +void LibbacktraceSymbolizer::SymbolizeData(DataInfo *) {
> +}
> +
> +#endif
> +
> +}  // namespace __sanitizer
> +
> +#endif  // SANITIZER_POSIX
> --- lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h.jj 2013-11-19
> 16:41:32.286843717 +0100
> +++ lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h    2013-11-19
> 16:52:16.448544275 +0100
> @@ -0,0 +1,36 @@
> +//===-- sanitizer_symbolizer_libbacktrace.h
> -------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file is shared between AddressSanitizer and ThreadSanitizer
> +// run-time libraries.
> +// POSIX-specific implementation of symbolizer parts.
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "sanitizer_platform.h"
> +#include "sanitizer_common.h"
> +#include "sanitizer_symbolizer.h"
> +
> +namespace __sanitizer {
> +
> +class LibbacktraceSymbolizer {
> + public:
> +  static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc);
> +
> +  uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames,
> +                    const char *module_name, uptr module_offset);
> +
> +  void SymbolizeData(DataInfo *info);
> +
> + private:
> +  LibbacktraceSymbolizer(void *state) : state_(state) { }
> +
> +  void *state_;        // Leaked.
> +};
> +
> +}
>
>
>         Jakub
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140113/453d4274/attachment.html>


More information about the llvm-commits mailing list