[compiler-rt] r182372 - [nolibc] Move symbolizer to RTSanitizerCommonLibc, and make it optional using a weak symbol.

Peter Collingbourne peter at pcc.me.uk
Tue May 21 05:08:38 PDT 2013


Author: pcc
Date: Tue May 21 07:08:37 2013
New Revision: 182372

URL: http://llvm.org/viewvc/llvm-project?rev=182372&view=rev
Log:
[nolibc] Move symbolizer to RTSanitizerCommonLibc, and make it optional using a weak symbol.

Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc
      - copied, changed from r182369, compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc
      - copied, changed from r182369, compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc
Removed:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc
Modified:
    compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h

Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=182372&r1=182371&r2=182372&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Tue May 21 07:08:37 2013
@@ -13,9 +13,7 @@ set(SANITIZER_SOURCES
   sanitizer_printf.cc
   sanitizer_stackdepot.cc
   sanitizer_stacktrace.cc
-  sanitizer_symbolizer.cc
   sanitizer_symbolizer_itanium.cc
-  sanitizer_symbolizer_linux.cc
   sanitizer_symbolizer_mac.cc
   sanitizer_symbolizer_win.cc
   sanitizer_thread_registry.cc
@@ -27,6 +25,8 @@ set(SANITIZER_LIBCDEP_SOURCES
   sanitizer_linux_libcdep.cc
   sanitizer_posix_libcdep.cc
   sanitizer_stoptheworld_linux_libcdep.cc
+  sanitizer_symbolizer_libcdep.cc
+  sanitizer_symbolizer_linux_libcdep.cc
   )
 
 # Explicitly list all sanitizer_common headers. Not all of these are

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc?rev=182372&r1=182371&r2=182372&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc Tue May 21 07:08:37 2013
@@ -85,7 +85,7 @@ void StackTrace::PrintStack(const uptr *
         frame_num++;
       }
     }
-    if (symbolize && addr_frames_num == 0) {
+    if (symbolize && addr_frames_num == 0 && SymbolizeCode) {
       // Use our own (online) symbolizer, if necessary.
       addr_frames_num = SymbolizeCode(pc, addr_frames.data(),
                                       addr_frames.size());

Removed: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=182371&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (removed)
@@ -1,453 +0,0 @@
-//===-- sanitizer_symbolizer.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. See sanitizer_symbolizer.h for details.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common.h"
-#include "sanitizer_placement_new.h"
-#include "sanitizer_procmaps.h"
-#include "sanitizer_symbolizer.h"
-
-namespace __sanitizer {
-
-void AddressInfo::Clear() {
-  InternalFree(module);
-  InternalFree(function);
-  InternalFree(file);
-  internal_memset(this, 0, sizeof(AddressInfo));
-}
-
-LoadedModule::LoadedModule(const char *module_name, uptr base_address) {
-  full_name_ = internal_strdup(module_name);
-  base_address_ = base_address;
-  n_ranges_ = 0;
-}
-
-void LoadedModule::addAddressRange(uptr beg, uptr end) {
-  CHECK_LT(n_ranges_, kMaxNumberOfAddressRanges);
-  ranges_[n_ranges_].beg = beg;
-  ranges_[n_ranges_].end = end;
-  n_ranges_++;
-}
-
-bool LoadedModule::containsAddress(uptr address) const {
-  for (uptr i = 0; i < n_ranges_; i++) {
-    if (ranges_[i].beg <= address && address < ranges_[i].end)
-      return true;
-  }
-  return false;
-}
-
-// Extracts the prefix of "str" that consists of any characters not
-// present in "delims" string, and copies this prefix to "result", allocating
-// space for it.
-// Returns a pointer to "str" after skipping extracted prefix and first
-// delimiter char.
-static const char *ExtractToken(const char *str, const char *delims,
-                                char **result) {
-  uptr prefix_len = internal_strcspn(str, delims);
-  *result = (char*)InternalAlloc(prefix_len + 1);
-  internal_memcpy(*result, str, prefix_len);
-  (*result)[prefix_len] = '\0';
-  const char *prefix_end = str + prefix_len;
-  if (*prefix_end != '\0') prefix_end++;
-  return prefix_end;
-}
-
-// Same as ExtractToken, but converts extracted token to integer.
-static const char *ExtractInt(const char *str, const char *delims,
-                              int *result) {
-  char *buff;
-  const char *ret = ExtractToken(str, delims, &buff);
-  if (buff != 0) {
-    *result = (int)internal_atoll(buff);
-  }
-  InternalFree(buff);
-  return ret;
-}
-
-static const char *ExtractUptr(const char *str, const char *delims,
-                               uptr *result) {
-  char *buff;
-  const char *ret = ExtractToken(str, delims, &buff);
-  if (buff != 0) {
-    *result = (uptr)internal_atoll(buff);
-  }
-  InternalFree(buff);
-  return ret;
-}
-
-// ExternalSymbolizer encapsulates communication between the tool and
-// external symbolizer program, running in a different subprocess,
-// For now we assume the following protocol:
-// For each request of the form
-//   <module_name> <module_offset>
-// passed to STDIN, external symbolizer prints to STDOUT response:
-//   <function_name>
-//   <file_name>:<line_number>:<column_number>
-//   <function_name>
-//   <file_name>:<line_number>:<column_number>
-//   ...
-//   <empty line>
-class ExternalSymbolizer {
- public:
-  ExternalSymbolizer(const char *path, int input_fd, int output_fd)
-      : path_(path),
-        input_fd_(input_fd),
-        output_fd_(output_fd),
-        times_restarted_(0) {
-    CHECK(path_);
-    CHECK_NE(input_fd_, kInvalidFd);
-    CHECK_NE(output_fd_, kInvalidFd);
-  }
-
-  char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
-    CHECK(module_name);
-    internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n",
-                      is_data ? "DATA " : "", module_name, module_offset);
-    if (!writeToSymbolizer(buffer_, internal_strlen(buffer_)))
-      return 0;
-    if (!readFromSymbolizer(buffer_, kBufferSize))
-      return 0;
-    return buffer_;
-  }
-
-  bool Restart() {
-    if (times_restarted_ >= kMaxTimesRestarted) return false;
-    times_restarted_++;
-    internal_close(input_fd_);
-    internal_close(output_fd_);
-    return StartSymbolizerSubprocess(path_, &input_fd_, &output_fd_);
-  }
-
-  void Flush() {
-  }
-
- private:
-  bool readFromSymbolizer(char *buffer, uptr max_length) {
-    if (max_length == 0)
-      return true;
-    uptr read_len = 0;
-    while (true) {
-      uptr just_read = internal_read(input_fd_, buffer + read_len,
-                                     max_length - read_len);
-      // We can't read 0 bytes, as we don't expect external symbolizer to close
-      // its stdout.
-      if (just_read == 0 || just_read == (uptr)-1) {
-        Report("WARNING: Can't read from symbolizer at fd %d\n", input_fd_);
-        return false;
-      }
-      read_len += just_read;
-      // Empty line marks the end of symbolizer output.
-      if (read_len >= 2 && buffer[read_len - 1] == '\n' &&
-                           buffer[read_len - 2] == '\n') {
-        break;
-      }
-    }
-    return true;
-  }
-
-  bool writeToSymbolizer(const char *buffer, uptr length) {
-    if (length == 0)
-      return true;
-    uptr write_len = internal_write(output_fd_, buffer, length);
-    if (write_len == 0 || write_len == (uptr)-1) {
-      Report("WARNING: Can't write to symbolizer at fd %d\n", output_fd_);
-      return false;
-    }
-    return true;
-  }
-
-  const char *path_;
-  int input_fd_;
-  int output_fd_;
-
-  static const uptr kBufferSize = 16 * 1024;
-  char buffer_[kBufferSize];
-
-  static const uptr kMaxTimesRestarted = 5;
-  uptr times_restarted_;
-};
-
-static LowLevelAllocator symbolizer_allocator;  // Linker initialized.
-
-#if SANITIZER_SUPPORTS_WEAK_HOOKS
-extern "C" {
-SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
-bool __sanitizer_symbolize_code(const char *ModuleName, u64 ModuleOffset,
-                                char *Buffer, int MaxLength);
-SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
-bool __sanitizer_symbolize_data(const char *ModuleName, u64 ModuleOffset,
-                                char *Buffer, int MaxLength);
-SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_symbolize_flush();
-}  // extern "C"
-
-class InternalSymbolizer {
- public:
-  typedef bool (*SanitizerSymbolizeFn)(const char*, u64, char*, int);
-
-  static InternalSymbolizer *get() {
-    if (__sanitizer_symbolize_code != 0 &&
-        __sanitizer_symbolize_data != 0) {
-      void *mem = symbolizer_allocator.Allocate(sizeof(InternalSymbolizer));
-      return new(mem) InternalSymbolizer();
-    }
-    return 0;
-  }
-
-  char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
-    SanitizerSymbolizeFn symbolize_fn = is_data ? __sanitizer_symbolize_data
-                                                : __sanitizer_symbolize_code;
-    if (symbolize_fn(module_name, module_offset, buffer_, kBufferSize))
-      return buffer_;
-    return 0;
-  }
-
-  void Flush() {
-    if (__sanitizer_symbolize_flush)
-      __sanitizer_symbolize_flush();
-  }
-
- private:
-  InternalSymbolizer() { }
-
-  static const int kBufferSize = 16 * 1024;
-  char buffer_[kBufferSize];
-};
-#else  // SANITIZER_SUPPORTS_WEAK_HOOKS
-
-class InternalSymbolizer {
- public:
-  static InternalSymbolizer *get() { return 0; }
-  char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
-    return 0;
-  }
-  void Flush() {
-  }
-};
-
-#endif  // SANITIZER_SUPPORTS_WEAK_HOOKS
-
-class Symbolizer {
-  // This class has no constructor, as global constructors are forbidden in
-  // sanitizer_common. It should be linker initialized instead.
- public:
-  uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) {
-    if (max_frames == 0)
-      return 0;
-    LoadedModule *module = FindModuleForAddress(addr);
-    if (module == 0)
-      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);
-    if (str == 0) {
-      // External symbolizer was not initialized or failed. Fill only data
-      // about module name and offset.
-      AddressInfo *info = &frames[0];
-      info->Clear();
-      info->FillAddressAndModuleInfo(addr, module_name, module_offset);
-      return 1;
-    }
-    uptr frame_id = 0;
-    for (frame_id = 0; frame_id < max_frames; frame_id++) {
-      AddressInfo *info = &frames[frame_id];
-      char *function_name = 0;
-      str = ExtractToken(str, "\n", &function_name);
-      CHECK(function_name);
-      if (function_name[0] == '\0') {
-        // There are no more frames.
-        break;
-      }
-      info->Clear();
-      info->FillAddressAndModuleInfo(addr, module_name, module_offset);
-      info->function = function_name;
-      // Parse <file>:<line>:<column> buffer.
-      char *file_line_info = 0;
-      str = ExtractToken(str, "\n", &file_line_info);
-      CHECK(file_line_info);
-      const char *line_info = ExtractToken(file_line_info, ":", &info->file);
-      line_info = ExtractInt(line_info, ":", &info->line);
-      line_info = ExtractInt(line_info, "", &info->column);
-      InternalFree(file_line_info);
-
-      // Functions and filenames can be "??", in which case we write 0
-      // to address info to mark that names are unknown.
-      if (0 == internal_strcmp(info->function, "??")) {
-        InternalFree(info->function);
-        info->function = 0;
-      }
-      if (0 == internal_strcmp(info->file, "??")) {
-        InternalFree(info->file);
-        info->file = 0;
-      }
-    }
-    if (frame_id == 0) {
-      // Make sure we return at least one frame.
-      AddressInfo *info = &frames[0];
-      info->Clear();
-      info->FillAddressAndModuleInfo(addr, module_name, module_offset);
-      frame_id = 1;
-    }
-    return frame_id;
-  }
-
-  bool SymbolizeData(uptr addr, DataInfo *info) {
-    LoadedModule *module = FindModuleForAddress(addr);
-    if (module == 0)
-      return false;
-    const char *module_name = module->full_name();
-    uptr module_offset = addr - module->base_address();
-    internal_memset(info, 0, sizeof(*info));
-    info->address = addr;
-    info->module = internal_strdup(module_name);
-    info->module_offset = module_offset;
-    const char *str = SendCommand(true, module_name, module_offset);
-    if (str == 0)
-      return true;
-    str = ExtractToken(str, "\n", &info->name);
-    str = ExtractUptr(str, " ", &info->start);
-    str = ExtractUptr(str, "\n", &info->size);
-    info->start += module->base_address();
-    return true;
-  }
-
-  bool InitializeExternalSymbolizer(const char *path_to_symbolizer) {
-    int input_fd, output_fd;
-    if (!StartSymbolizerSubprocess(path_to_symbolizer, &input_fd, &output_fd))
-      return false;
-    void *mem = symbolizer_allocator.Allocate(sizeof(ExternalSymbolizer));
-    external_symbolizer_ = new(mem) ExternalSymbolizer(path_to_symbolizer,
-                                                       input_fd, output_fd);
-    return true;
-  }
-
-  bool IsSymbolizerAvailable() {
-    if (internal_symbolizer_ == 0)
-      internal_symbolizer_ = InternalSymbolizer::get();
-    return internal_symbolizer_ || external_symbolizer_;
-  }
-
-  void Flush() {
-    if (internal_symbolizer_)
-      internal_symbolizer_->Flush();
-    if (external_symbolizer_)
-      external_symbolizer_->Flush();
-  }
-
- private:
-  char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
-    // First, try to use internal symbolizer.
-    if (!IsSymbolizerAvailable()) {
-      return 0;
-    }
-    if (internal_symbolizer_) {
-      return internal_symbolizer_->SendCommand(is_data, module_name,
-                                               module_offset);
-    }
-    // Otherwise, fall back to external symbolizer.
-    if (external_symbolizer_ == 0) {
-      ReportExternalSymbolizerError(
-          "WARNING: Trying to symbolize code, but external "
-          "symbolizer is not initialized!\n");
-      return 0;
-    }
-    for (;;) {
-      char *reply = external_symbolizer_->SendCommand(is_data, module_name,
-          module_offset);
-      if (reply)
-        return reply;
-      // Try to restart symbolizer subprocess. If we don't succeed, forget
-      // about it and don't try to use it later.
-      if (!external_symbolizer_->Restart()) {
-        ReportExternalSymbolizerError(
-            "WARNING: Failed to use and restart external symbolizer!\n");
-        external_symbolizer_ = 0;
-        return 0;
-      }
-    }
-  }
-
-  LoadedModule *FindModuleForAddress(uptr address) {
-    bool modules_were_reloaded = false;
-    if (modules_ == 0 || !modules_fresh_) {
-      modules_ = (LoadedModule*)(symbolizer_allocator.Allocate(
-          kMaxNumberOfModuleContexts * sizeof(LoadedModule)));
-      CHECK(modules_);
-      n_modules_ = GetListOfModules(modules_, kMaxNumberOfModuleContexts,
-                                    /* filter */ 0);
-      // FIXME: Return this check when GetListOfModules is implemented on Mac.
-      // CHECK_GT(n_modules_, 0);
-      CHECK_LT(n_modules_, kMaxNumberOfModuleContexts);
-      modules_fresh_ = true;
-      modules_were_reloaded = true;
-    }
-    for (uptr i = 0; i < n_modules_; i++) {
-      if (modules_[i].containsAddress(address)) {
-        return &modules_[i];
-      }
-    }
-    // Reload the modules and look up again, if we haven't tried it yet.
-    if (!modules_were_reloaded) {
-      // FIXME: set modules_fresh_ from dlopen()/dlclose() interceptors.
-      // It's too aggressive to reload the list of modules each time we fail
-      // to find a module for a given address.
-      modules_fresh_ = false;
-      return FindModuleForAddress(address);
-    }
-    return 0;
-  }
-
-  void ReportExternalSymbolizerError(const char *msg) {
-    // Don't use atomics here for now, as SymbolizeCode can't be called
-    // from multiple threads anyway.
-    static bool reported;
-    if (!reported) {
-      Report(msg);
-      reported = true;
-    }
-  }
-
-  // 16K loaded modules should be enough for everyone.
-  static const uptr kMaxNumberOfModuleContexts = 1 << 14;
-  LoadedModule *modules_;  // Array of module descriptions is leaked.
-  uptr n_modules_;
-  // If stale, need to reload the modules before looking up addresses.
-  bool modules_fresh_;
-
-  ExternalSymbolizer *external_symbolizer_;  // Leaked.
-  InternalSymbolizer *internal_symbolizer_;  // Leaked.
-};
-
-static Symbolizer symbolizer;  // Linker initialized.
-
-uptr SymbolizeCode(uptr address, AddressInfo *frames, uptr max_frames) {
-  return symbolizer.SymbolizeCode(address, frames, max_frames);
-}
-
-bool SymbolizeData(uptr address, DataInfo *info) {
-  return symbolizer.SymbolizeData(address, info);
-}
-
-bool InitializeExternalSymbolizer(const char *path_to_symbolizer) {
-  return symbolizer.InitializeExternalSymbolizer(path_to_symbolizer);
-}
-
-bool IsSymbolizerAvailable() {
-  return symbolizer.IsSymbolizerAvailable();
-}
-
-void FlushSymbolizer() {
-  symbolizer.Flush();
-}
-
-}  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=182372&r1=182371&r2=182372&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Tue May 21 07:08:37 2013
@@ -66,7 +66,8 @@ struct DataInfo {
 // for a given address (in all inlined functions). Returns the number
 // of descriptions actually filled.
 // This function should NOT be called from two threads simultaneously.
-uptr SymbolizeCode(uptr address, AddressInfo *frames, uptr max_frames);
+uptr SymbolizeCode(uptr address, AddressInfo *frames, uptr max_frames)
+    SANITIZER_WEAK_ATTRIBUTE;
 bool SymbolizeData(uptr address, DataInfo *info);
 
 bool IsSymbolizerAvailable();

Copied: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc (from r182369, compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc?p2=compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc&p1=compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc&r1=182369&r2=182372&rev=182372&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc Tue May 21 07:08:37 2013
@@ -1,4 +1,4 @@
-//===-- sanitizer_symbolizer.cc -------------------------------------------===//
+//===-- sanitizer_symbolizer_libcdep.cc -----------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //

Removed: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc?rev=182371&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc (removed)
@@ -1,199 +0,0 @@
-//===-- sanitizer_symbolizer_linux.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.
-// Linux-specific implementation of symbolizer parts.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_platform.h"
-#if SANITIZER_LINUX
-#include "sanitizer_common.h"
-#include "sanitizer_internal_defs.h"
-#include "sanitizer_libc.h"
-#include "sanitizer_placement_new.h"
-#include "sanitizer_symbolizer.h"
-
-// Android NDK r8e elf.h depends on stdint.h without including the latter.
-#include <stdint.h>
-
-#include <elf.h>
-#include <errno.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#if !SANITIZER_ANDROID
-#include <link.h>
-#endif
-
-namespace __sanitizer {
-
-static const int kSymbolizerStartupTimeMillis = 10;
-
-bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
-                               int *input_fd, int *output_fd) {
-  if (!FileExists(path_to_symbolizer)) {
-    Report("WARNING: invalid path to external symbolizer!\n");
-    return false;
-  }
-
-  int *infd = NULL;
-  int *outfd = NULL;
-  // The client program may close its stdin and/or stdout and/or stderr
-  // thus allowing socketpair to reuse file descriptors 0, 1 or 2.
-  // In this case the communication between the forked processes may be
-  // broken if either the parent or the child tries to close or duplicate
-  // these descriptors. The loop below produces two pairs of file
-  // descriptors, each greater than 2 (stderr).
-  int sock_pair[5][2];
-  for (int i = 0; i < 5; i++) {
-    if (pipe(sock_pair[i]) == -1) {
-      for (int j = 0; j < i; j++) {
-        internal_close(sock_pair[j][0]);
-        internal_close(sock_pair[j][1]);
-      }
-      Report("WARNING: Can't create a socket pair to start "
-             "external symbolizer (errno: %d)\n", errno);
-      return false;
-    } else if (sock_pair[i][0] > 2 && sock_pair[i][1] > 2) {
-      if (infd == NULL) {
-        infd = sock_pair[i];
-      } else {
-        outfd = sock_pair[i];
-        for (int j = 0; j < i; j++) {
-          if (sock_pair[j] == infd) continue;
-          internal_close(sock_pair[j][0]);
-          internal_close(sock_pair[j][1]);
-        }
-        break;
-      }
-    }
-  }
-  CHECK(infd);
-  CHECK(outfd);
-
-  int pid = fork();
-  if (pid == -1) {
-    // Fork() failed.
-    internal_close(infd[0]);
-    internal_close(infd[1]);
-    internal_close(outfd[0]);
-    internal_close(outfd[1]);
-    Report("WARNING: failed to fork external symbolizer "
-           " (errno: %d)\n", errno);
-    return false;
-  } else if (pid == 0) {
-    // Child subprocess.
-    internal_close(STDOUT_FILENO);
-    internal_close(STDIN_FILENO);
-    internal_dup2(outfd[0], STDIN_FILENO);
-    internal_dup2(infd[1], STDOUT_FILENO);
-    internal_close(outfd[0]);
-    internal_close(outfd[1]);
-    internal_close(infd[0]);
-    internal_close(infd[1]);
-    for (int fd = getdtablesize(); fd > 2; fd--)
-      internal_close(fd);
-    execl(path_to_symbolizer, path_to_symbolizer, (char*)0);
-    internal__exit(1);
-  }
-
-  // Continue execution in parent process.
-  internal_close(outfd[0]);
-  internal_close(infd[1]);
-  *input_fd = infd[0];
-  *output_fd = outfd[1];
-
-  // Check that symbolizer subprocess started successfully.
-  int pid_status;
-  SleepForMillis(kSymbolizerStartupTimeMillis);
-  int exited_pid = waitpid(pid, &pid_status, WNOHANG);
-  if (exited_pid != 0) {
-    // Either waitpid failed, or child has already exited.
-    Report("WARNING: external symbolizer didn't start up correctly!\n");
-    return false;
-  }
-
-  return true;
-}
-
-#if SANITIZER_ANDROID
-uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
-                      string_predicate_t filter) {
-  return 0;
-}
-#else  // SANITIZER_ANDROID
-typedef ElfW(Phdr) Elf_Phdr;
-
-struct DlIteratePhdrData {
-  LoadedModule *modules;
-  uptr current_n;
-  bool first;
-  uptr max_n;
-  string_predicate_t filter;
-};
-
-static const uptr kMaxPathLength = 512;
-
-static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
-  DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
-  if (data->current_n == data->max_n)
-    return 0;
-  InternalScopedBuffer<char> module_name(kMaxPathLength);
-  module_name.data()[0] = '\0';
-  if (data->first) {
-    data->first = false;
-    // First module is the binary itself.
-    uptr module_name_len = internal_readlink(
-        "/proc/self/exe", module_name.data(), module_name.size());
-    if (internal_iserror(module_name_len)) {
-      // We can't read /proc/self/exe for some reason, assume the name of the
-      // binary is unknown.
-      module_name_len = internal_snprintf(module_name.data(),
-                                          module_name.size(), "/proc/self/exe");
-    }
-    CHECK_LT(module_name_len, module_name.size());
-    module_name[module_name_len] = '\0';
-  } else if (info->dlpi_name) {
-    internal_strncpy(module_name.data(), info->dlpi_name, module_name.size());
-  }
-  if (module_name.data()[0] == '\0')
-    return 0;
-  if (data->filter && !data->filter(module_name.data()))
-    return 0;
-  void *mem = &data->modules[data->current_n];
-  LoadedModule *cur_module = new(mem) LoadedModule(module_name.data(),
-                                                   info->dlpi_addr);
-  data->current_n++;
-  for (int i = 0; i < info->dlpi_phnum; i++) {
-    const Elf_Phdr *phdr = &info->dlpi_phdr[i];
-    if (phdr->p_type == PT_LOAD) {
-      uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;
-      uptr cur_end = cur_beg + phdr->p_memsz;
-      cur_module->addAddressRange(cur_beg, cur_end);
-    }
-  }
-  return 0;
-}
-
-uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
-                      string_predicate_t filter) {
-  CHECK(modules);
-  DlIteratePhdrData data = {modules, 0, true, max_modules, filter};
-  dl_iterate_phdr(dl_iterate_phdr_cb, &data);
-  return data.current_n;
-}
-#endif  // SANITIZER_ANDROID
-
-}  // namespace __sanitizer
-
-#endif  // SANITIZER_LINUX

Copied: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc (from r182369, compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc?p2=compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc&p1=compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc&r1=182369&r2=182372&rev=182372&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc Tue May 21 07:08:37 2013
@@ -1,4 +1,4 @@
-//===-- sanitizer_symbolizer_linux.cc -------------------------------------===//
+//===-- sanitizer_symbolizer_linux_libcdep.cc -----------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //





More information about the llvm-commits mailing list