toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1214 @@
     1.4 +// Copyright (c) 2006, Google Inc.
     1.5 +// All rights reserved.
     1.6 +//
     1.7 +// Redistribution and use in source and binary forms, with or without
     1.8 +// modification, are permitted provided that the following conditions are
     1.9 +// met:
    1.10 +//
    1.11 +//     * Redistributions of source code must retain the above copyright
    1.12 +// notice, this list of conditions and the following disclaimer.
    1.13 +//     * Redistributions in binary form must reproduce the above
    1.14 +// copyright notice, this list of conditions and the following disclaimer
    1.15 +// in the documentation and/or other materials provided with the
    1.16 +// distribution.
    1.17 +//     * Neither the name of Google Inc. nor the names of its
    1.18 +// contributors may be used to endorse or promote products derived from
    1.19 +// this software without specific prior written permission.
    1.20 +//
    1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.32 +
    1.33 +#include "google_breakpad/processor/minidump_processor.h"
    1.34 +
    1.35 +#include <assert.h>
    1.36 +#include <stdio.h>
    1.37 +
    1.38 +#include "common/scoped_ptr.h"
    1.39 +#include "google_breakpad/processor/call_stack.h"
    1.40 +#include "google_breakpad/processor/minidump.h"
    1.41 +#include "google_breakpad/processor/process_state.h"
    1.42 +#include "google_breakpad/processor/exploitability.h"
    1.43 +#include "google_breakpad/processor/stack_frame_symbolizer.h"
    1.44 +#include "processor/logging.h"
    1.45 +#include "processor/stackwalker_x86.h"
    1.46 +
    1.47 +namespace google_breakpad {
    1.48 +
    1.49 +MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier,
    1.50 +                                     SourceLineResolverInterface *resolver)
    1.51 +    : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)),
    1.52 +      own_frame_symbolizer_(true),
    1.53 +      enable_exploitability_(false) {
    1.54 +}
    1.55 +
    1.56 +MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier,
    1.57 +                                     SourceLineResolverInterface *resolver,
    1.58 +                                     bool enable_exploitability)
    1.59 +    : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)),
    1.60 +      own_frame_symbolizer_(true),
    1.61 +      enable_exploitability_(enable_exploitability) {
    1.62 +}
    1.63 +
    1.64 +MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer *frame_symbolizer,
    1.65 +                                     bool enable_exploitability)
    1.66 +    : frame_symbolizer_(frame_symbolizer),
    1.67 +      own_frame_symbolizer_(false),
    1.68 +      enable_exploitability_(enable_exploitability) {
    1.69 +  assert(frame_symbolizer_);
    1.70 +}
    1.71 +
    1.72 +MinidumpProcessor::~MinidumpProcessor() {
    1.73 +  if (own_frame_symbolizer_) delete frame_symbolizer_;
    1.74 +}
    1.75 +
    1.76 +ProcessResult MinidumpProcessor::Process(
    1.77 +    Minidump *dump, ProcessState *process_state) {
    1.78 +  assert(dump);
    1.79 +  assert(process_state);
    1.80 +
    1.81 +  process_state->Clear();
    1.82 +
    1.83 +  const MDRawHeader *header = dump->header();
    1.84 +  if (!header) {
    1.85 +    BPLOG(ERROR) << "Minidump " << dump->path() << " has no header";
    1.86 +    return PROCESS_ERROR_NO_MINIDUMP_HEADER;
    1.87 +  }
    1.88 +  process_state->time_date_stamp_ = header->time_date_stamp;
    1.89 +
    1.90 +  bool has_cpu_info = GetCPUInfo(dump, &process_state->system_info_);
    1.91 +  bool has_os_info = GetOSInfo(dump, &process_state->system_info_);
    1.92 +
    1.93 +  uint32_t dump_thread_id = 0;
    1.94 +  bool has_dump_thread = false;
    1.95 +  uint32_t requesting_thread_id = 0;
    1.96 +  bool has_requesting_thread = false;
    1.97 +
    1.98 +  MinidumpBreakpadInfo *breakpad_info = dump->GetBreakpadInfo();
    1.99 +  if (breakpad_info) {
   1.100 +    has_dump_thread = breakpad_info->GetDumpThreadID(&dump_thread_id);
   1.101 +    has_requesting_thread =
   1.102 +        breakpad_info->GetRequestingThreadID(&requesting_thread_id);
   1.103 +  }
   1.104 +
   1.105 +  MinidumpException *exception = dump->GetException();
   1.106 +  if (exception) {
   1.107 +    process_state->crashed_ = true;
   1.108 +    has_requesting_thread = exception->GetThreadID(&requesting_thread_id);
   1.109 +
   1.110 +    process_state->crash_reason_ = GetCrashReason(
   1.111 +        dump, &process_state->crash_address_);
   1.112 +  }
   1.113 +
   1.114 +  // This will just return an empty string if it doesn't exist.
   1.115 +  process_state->assertion_ = GetAssertion(dump);
   1.116 +
   1.117 +  MinidumpModuleList *module_list = dump->GetModuleList();
   1.118 +
   1.119 +  // Put a copy of the module list into ProcessState object.  This is not
   1.120 +  // necessarily a MinidumpModuleList, but it adheres to the CodeModules
   1.121 +  // interface, which is all that ProcessState needs to expose.
   1.122 +  if (module_list)
   1.123 +    process_state->modules_ = module_list->Copy();
   1.124 +
   1.125 +  MinidumpThreadList *threads = dump->GetThreadList();
   1.126 +  if (!threads) {
   1.127 +    BPLOG(ERROR) << "Minidump " << dump->path() << " has no thread list";
   1.128 +    return PROCESS_ERROR_NO_THREAD_LIST;
   1.129 +  }
   1.130 +
   1.131 +  BPLOG(INFO) << "Minidump " << dump->path() << " has " <<
   1.132 +      (has_cpu_info           ? "" : "no ") << "CPU info, " <<
   1.133 +      (has_os_info            ? "" : "no ") << "OS info, " <<
   1.134 +      (breakpad_info != NULL  ? "" : "no ") << "Breakpad info, " <<
   1.135 +      (exception != NULL      ? "" : "no ") << "exception, " <<
   1.136 +      (module_list != NULL    ? "" : "no ") << "module list, " <<
   1.137 +      (threads != NULL        ? "" : "no ") << "thread list, " <<
   1.138 +      (has_dump_thread        ? "" : "no ") << "dump thread, and " <<
   1.139 +      (has_requesting_thread  ? "" : "no ") << "requesting thread";
   1.140 +
   1.141 +  bool interrupted = false;
   1.142 +  bool found_requesting_thread = false;
   1.143 +  unsigned int thread_count = threads->thread_count();
   1.144 +
   1.145 +  // Reset frame_symbolizer_ at the beginning of stackwalk for each minidump.
   1.146 +  frame_symbolizer_->Reset();
   1.147 +
   1.148 +  for (unsigned int thread_index = 0;
   1.149 +       thread_index < thread_count;
   1.150 +       ++thread_index) {
   1.151 +    char thread_string_buffer[64];
   1.152 +    snprintf(thread_string_buffer, sizeof(thread_string_buffer), "%d/%d",
   1.153 +             thread_index, thread_count);
   1.154 +    string thread_string = dump->path() + ":" + thread_string_buffer;
   1.155 +
   1.156 +    MinidumpThread *thread = threads->GetThreadAtIndex(thread_index);
   1.157 +    if (!thread) {
   1.158 +      BPLOG(ERROR) << "Could not get thread for " << thread_string;
   1.159 +      return PROCESS_ERROR_GETTING_THREAD;
   1.160 +    }
   1.161 +
   1.162 +    uint32_t thread_id;
   1.163 +    if (!thread->GetThreadID(&thread_id)) {
   1.164 +      BPLOG(ERROR) << "Could not get thread ID for " << thread_string;
   1.165 +      return PROCESS_ERROR_GETTING_THREAD_ID;
   1.166 +    }
   1.167 +
   1.168 +    thread_string += " id " + HexString(thread_id);
   1.169 +    BPLOG(INFO) << "Looking at thread " << thread_string;
   1.170 +
   1.171 +    // If this thread is the thread that produced the minidump, don't process
   1.172 +    // it.  Because of the problems associated with a thread producing a
   1.173 +    // dump of itself (when both its context and its stack are in flux),
   1.174 +    // processing that stack wouldn't provide much useful data.
   1.175 +    if (has_dump_thread && thread_id == dump_thread_id) {
   1.176 +      continue;
   1.177 +    }
   1.178 +
   1.179 +    MinidumpContext *context = thread->GetContext();
   1.180 +
   1.181 +    if (has_requesting_thread && thread_id == requesting_thread_id) {
   1.182 +      if (found_requesting_thread) {
   1.183 +        // There can't be more than one requesting thread.
   1.184 +        BPLOG(ERROR) << "Duplicate requesting thread: " << thread_string;
   1.185 +        return PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS;
   1.186 +      }
   1.187 +
   1.188 +      // Use processed_state->threads_.size() instead of thread_index.
   1.189 +      // thread_index points to the thread index in the minidump, which
   1.190 +      // might be greater than the thread index in the threads vector if
   1.191 +      // any of the minidump's threads are skipped and not placed into the
   1.192 +      // processed threads vector.  The thread vector's current size will
   1.193 +      // be the index of the current thread when it's pushed into the
   1.194 +      // vector.
   1.195 +      process_state->requesting_thread_ = process_state->threads_.size();
   1.196 +
   1.197 +      found_requesting_thread = true;
   1.198 +
   1.199 +      if (process_state->crashed_) {
   1.200 +        // Use the exception record's context for the crashed thread, instead
   1.201 +        // of the thread's own context.  For the crashed thread, the thread's
   1.202 +        // own context is the state inside the exception handler.  Using it
   1.203 +        // would not result in the expected stack trace from the time of the
   1.204 +        // crash. If the exception context is invalid, however, we fall back
   1.205 +        // on the thread context.
   1.206 +        MinidumpContext *ctx = exception->GetContext();
   1.207 +        context = ctx ? ctx : thread->GetContext();
   1.208 +      }
   1.209 +    }
   1.210 +
   1.211 +    MinidumpMemoryRegion *thread_memory = thread->GetMemory();
   1.212 +    if (!thread_memory) {
   1.213 +      BPLOG(ERROR) << "No memory region for " << thread_string;
   1.214 +    }
   1.215 +
   1.216 +    // Use process_state->modules_ instead of module_list, because the
   1.217 +    // |modules| argument will be used to populate the |module| fields in
   1.218 +    // the returned StackFrame objects, which will be placed into the
   1.219 +    // returned ProcessState object.  module_list's lifetime is only as
   1.220 +    // long as the Minidump object: it will be deleted when this function
   1.221 +    // returns.  process_state->modules_ is owned by the ProcessState object
   1.222 +    // (just like the StackFrame objects), and is much more suitable for this
   1.223 +    // task.
   1.224 +    scoped_ptr<Stackwalker> stackwalker(
   1.225 +        Stackwalker::StackwalkerForCPU(process_state->system_info(),
   1.226 +                                       context,
   1.227 +                                       thread_memory,
   1.228 +                                       process_state->modules_,
   1.229 +                                       frame_symbolizer_));
   1.230 +
   1.231 +    scoped_ptr<CallStack> stack(new CallStack());
   1.232 +    if (stackwalker.get()) {
   1.233 +      if (!stackwalker->Walk(stack.get(),
   1.234 +                             &process_state->modules_without_symbols_)) {
   1.235 +        BPLOG(INFO) << "Stackwalker interrupt (missing symbols?) at "
   1.236 +                    << thread_string;
   1.237 +        interrupted = true;
   1.238 +      }
   1.239 +    } else {
   1.240 +      // Threads with missing CPU contexts will hit this, but
   1.241 +      // don't abort processing the rest of the dump just for
   1.242 +      // one bad thread.
   1.243 +      BPLOG(ERROR) << "No stackwalker for " << thread_string;
   1.244 +    }
   1.245 +    process_state->threads_.push_back(stack.release());
   1.246 +    process_state->thread_memory_regions_.push_back(thread_memory);
   1.247 +  }
   1.248 +
   1.249 +  if (interrupted) {
   1.250 +    BPLOG(INFO) << "Processing interrupted for " << dump->path();
   1.251 +    return PROCESS_SYMBOL_SUPPLIER_INTERRUPTED;
   1.252 +  }
   1.253 +
   1.254 +  // If a requesting thread was indicated, it must be present.
   1.255 +  if (has_requesting_thread && !found_requesting_thread) {
   1.256 +    // Don't mark as an error, but invalidate the requesting thread
   1.257 +    BPLOG(ERROR) << "Minidump indicated requesting thread " <<
   1.258 +        HexString(requesting_thread_id) << ", not found in " <<
   1.259 +        dump->path();
   1.260 +    process_state->requesting_thread_ = -1;
   1.261 +  }
   1.262 +
   1.263 +  // Exploitability defaults to EXPLOITABILITY_NOT_ANALYZED
   1.264 +  process_state->exploitability_ = EXPLOITABILITY_NOT_ANALYZED;
   1.265 +
   1.266 +  // If an exploitability run was requested we perform the platform specific
   1.267 +  // rating.
   1.268 +  if (enable_exploitability_) {
   1.269 +    scoped_ptr<Exploitability> exploitability(
   1.270 +        Exploitability::ExploitabilityForPlatform(dump, process_state));
   1.271 +    // The engine will be null if the platform is not supported
   1.272 +    if (exploitability != NULL) {
   1.273 +      process_state->exploitability_ = exploitability->CheckExploitability();
   1.274 +    } else {
   1.275 +      process_state->exploitability_ = EXPLOITABILITY_ERR_NOENGINE;
   1.276 +    }
   1.277 +  }
   1.278 +
   1.279 +  BPLOG(INFO) << "Processed " << dump->path();
   1.280 +  return PROCESS_OK;
   1.281 +}
   1.282 +
   1.283 +ProcessResult MinidumpProcessor::Process(
   1.284 +    const string &minidump_file, ProcessState *process_state) {
   1.285 +  BPLOG(INFO) << "Processing minidump in file " << minidump_file;
   1.286 +
   1.287 +  Minidump dump(minidump_file);
   1.288 +  if (!dump.Read()) {
   1.289 +     BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read";
   1.290 +     return PROCESS_ERROR_MINIDUMP_NOT_FOUND;
   1.291 +  }
   1.292 +
   1.293 +  return Process(&dump, process_state);
   1.294 +}
   1.295 +
   1.296 +// Returns the MDRawSystemInfo from a minidump, or NULL if system info is
   1.297 +// not available from the minidump.  If system_info is non-NULL, it is used
   1.298 +// to pass back the MinidumpSystemInfo object.
   1.299 +static const MDRawSystemInfo* GetSystemInfo(Minidump *dump,
   1.300 +                                            MinidumpSystemInfo **system_info) {
   1.301 +  MinidumpSystemInfo *minidump_system_info = dump->GetSystemInfo();
   1.302 +  if (!minidump_system_info)
   1.303 +    return NULL;
   1.304 +
   1.305 +  if (system_info)
   1.306 +    *system_info = minidump_system_info;
   1.307 +
   1.308 +  return minidump_system_info->system_info();
   1.309 +}
   1.310 +
   1.311 +// static
   1.312 +bool MinidumpProcessor::GetCPUInfo(Minidump *dump, SystemInfo *info) {
   1.313 +  assert(dump);
   1.314 +  assert(info);
   1.315 +
   1.316 +  info->cpu.clear();
   1.317 +  info->cpu_info.clear();
   1.318 +
   1.319 +  MinidumpSystemInfo *system_info;
   1.320 +  const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
   1.321 +  if (!raw_system_info)
   1.322 +    return false;
   1.323 +
   1.324 +  switch (raw_system_info->processor_architecture) {
   1.325 +    case MD_CPU_ARCHITECTURE_X86:
   1.326 +    case MD_CPU_ARCHITECTURE_AMD64: {
   1.327 +      if (raw_system_info->processor_architecture ==
   1.328 +          MD_CPU_ARCHITECTURE_X86)
   1.329 +        info->cpu = "x86";
   1.330 +      else
   1.331 +        info->cpu = "amd64";
   1.332 +
   1.333 +      const string *cpu_vendor = system_info->GetCPUVendor();
   1.334 +      if (cpu_vendor) {
   1.335 +        info->cpu_info = *cpu_vendor;
   1.336 +        info->cpu_info.append(" ");
   1.337 +      }
   1.338 +
   1.339 +      char x86_info[36];
   1.340 +      snprintf(x86_info, sizeof(x86_info), "family %u model %u stepping %u",
   1.341 +               raw_system_info->processor_level,
   1.342 +               raw_system_info->processor_revision >> 8,
   1.343 +               raw_system_info->processor_revision & 0xff);
   1.344 +      info->cpu_info.append(x86_info);
   1.345 +      break;
   1.346 +    }
   1.347 +
   1.348 +    case MD_CPU_ARCHITECTURE_PPC: {
   1.349 +      info->cpu = "ppc";
   1.350 +      break;
   1.351 +    }
   1.352 +
   1.353 +    case MD_CPU_ARCHITECTURE_SPARC: {
   1.354 +      info->cpu = "sparc";
   1.355 +      break;
   1.356 +    }
   1.357 +
   1.358 +    case MD_CPU_ARCHITECTURE_ARM: {
   1.359 +      info->cpu = "arm";
   1.360 +      break;
   1.361 +    }
   1.362 +
   1.363 +    default: {
   1.364 +      // Assign the numeric architecture ID into the CPU string.
   1.365 +      char cpu_string[7];
   1.366 +      snprintf(cpu_string, sizeof(cpu_string), "0x%04x",
   1.367 +               raw_system_info->processor_architecture);
   1.368 +      info->cpu = cpu_string;
   1.369 +      break;
   1.370 +    }
   1.371 +  }
   1.372 +
   1.373 +  info->cpu_count = raw_system_info->number_of_processors;
   1.374 +
   1.375 +  return true;
   1.376 +}
   1.377 +
   1.378 +// static
   1.379 +bool MinidumpProcessor::GetOSInfo(Minidump *dump, SystemInfo *info) {
   1.380 +  assert(dump);
   1.381 +  assert(info);
   1.382 +
   1.383 +  info->os.clear();
   1.384 +  info->os_short.clear();
   1.385 +  info->os_version.clear();
   1.386 +
   1.387 +  MinidumpSystemInfo *system_info;
   1.388 +  const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
   1.389 +  if (!raw_system_info)
   1.390 +    return false;
   1.391 +
   1.392 +  info->os_short = system_info->GetOS();
   1.393 +
   1.394 +  switch (raw_system_info->platform_id) {
   1.395 +    case MD_OS_WIN32_NT: {
   1.396 +      info->os = "Windows NT";
   1.397 +      break;
   1.398 +    }
   1.399 +
   1.400 +    case MD_OS_WIN32_WINDOWS: {
   1.401 +      info->os = "Windows";
   1.402 +      break;
   1.403 +    }
   1.404 +
   1.405 +    case MD_OS_MAC_OS_X: {
   1.406 +      info->os = "Mac OS X";
   1.407 +      break;
   1.408 +    }
   1.409 +
   1.410 +    case MD_OS_IOS: {
   1.411 +      info->os = "iOS";
   1.412 +      break;
   1.413 +    }
   1.414 +
   1.415 +    case MD_OS_LINUX: {
   1.416 +      info->os = "Linux";
   1.417 +      break;
   1.418 +    }
   1.419 +
   1.420 +    case MD_OS_SOLARIS: {
   1.421 +      info->os = "Solaris";
   1.422 +      break;
   1.423 +    }
   1.424 +
   1.425 +    case MD_OS_ANDROID: {
   1.426 +      info->os = "Android";
   1.427 +      break;
   1.428 +    }
   1.429 +
   1.430 +    default: {
   1.431 +      // Assign the numeric platform ID into the OS string.
   1.432 +      char os_string[11];
   1.433 +      snprintf(os_string, sizeof(os_string), "0x%08x",
   1.434 +               raw_system_info->platform_id);
   1.435 +      info->os = os_string;
   1.436 +      break;
   1.437 +    }
   1.438 +  }
   1.439 +
   1.440 +  char os_version_string[33];
   1.441 +  snprintf(os_version_string, sizeof(os_version_string), "%u.%u.%u",
   1.442 +           raw_system_info->major_version,
   1.443 +           raw_system_info->minor_version,
   1.444 +           raw_system_info->build_number);
   1.445 +  info->os_version = os_version_string;
   1.446 +
   1.447 +  const string *csd_version = system_info->GetCSDVersion();
   1.448 +  if (csd_version) {
   1.449 +    info->os_version.append(" ");
   1.450 +    info->os_version.append(*csd_version);
   1.451 +  }
   1.452 +
   1.453 +  return true;
   1.454 +}
   1.455 +
   1.456 +// static
   1.457 +string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
   1.458 +  MinidumpException *exception = dump->GetException();
   1.459 +  if (!exception)
   1.460 +    return "";
   1.461 +
   1.462 +  const MDRawExceptionStream *raw_exception = exception->exception();
   1.463 +  if (!raw_exception)
   1.464 +    return "";
   1.465 +
   1.466 +  if (address)
   1.467 +    *address = raw_exception->exception_record.exception_address;
   1.468 +
   1.469 +  // The reason value is OS-specific and possibly CPU-specific.  Set up
   1.470 +  // sensible numeric defaults for the reason string in case we can't
   1.471 +  // map the codes to a string (because there's no system info, or because
   1.472 +  // it's an unrecognized platform, or because it's an unrecognized code.)
   1.473 +  char reason_string[24];
   1.474 +  uint32_t exception_code = raw_exception->exception_record.exception_code;
   1.475 +  uint32_t exception_flags = raw_exception->exception_record.exception_flags;
   1.476 +  snprintf(reason_string, sizeof(reason_string), "0x%08x / 0x%08x",
   1.477 +           exception_code, exception_flags);
   1.478 +  string reason = reason_string;
   1.479 +
   1.480 +  const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, NULL);
   1.481 +  if (!raw_system_info)
   1.482 +    return reason;
   1.483 +
   1.484 +  switch (raw_system_info->platform_id) {
   1.485 +    case MD_OS_MAC_OS_X:
   1.486 +    case MD_OS_IOS: {
   1.487 +      char flags_string[11];
   1.488 +      snprintf(flags_string, sizeof(flags_string), "0x%08x", exception_flags);
   1.489 +      switch (exception_code) {
   1.490 +        case MD_EXCEPTION_MAC_BAD_ACCESS:
   1.491 +          reason = "EXC_BAD_ACCESS / ";
   1.492 +          switch (exception_flags) {
   1.493 +            case MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS:
   1.494 +              reason.append("KERN_INVALID_ADDRESS");
   1.495 +              break;
   1.496 +            case MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE:
   1.497 +              reason.append("KERN_PROTECTION_FAILURE");
   1.498 +              break;
   1.499 +            case MD_EXCEPTION_CODE_MAC_NO_ACCESS:
   1.500 +              reason.append("KERN_NO_ACCESS");
   1.501 +              break;
   1.502 +            case MD_EXCEPTION_CODE_MAC_MEMORY_FAILURE:
   1.503 +              reason.append("KERN_MEMORY_FAILURE");
   1.504 +              break;
   1.505 +            case MD_EXCEPTION_CODE_MAC_MEMORY_ERROR:
   1.506 +              reason.append("KERN_MEMORY_ERROR");
   1.507 +              break;
   1.508 +            default:
   1.509 +              // arm and ppc overlap
   1.510 +              if (raw_system_info->processor_architecture ==
   1.511 +                  MD_CPU_ARCHITECTURE_ARM) {
   1.512 +                switch (exception_flags) {
   1.513 +                  case MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN:
   1.514 +                    reason.append("EXC_ARM_DA_ALIGN");
   1.515 +                    break;
   1.516 +                  case MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG:
   1.517 +                    reason.append("EXC_ARM_DA_DEBUG");
   1.518 +                    break;
   1.519 +                  default:
   1.520 +                    reason.append(flags_string);
   1.521 +                    BPLOG(INFO) << "Unknown exception reason " << reason;
   1.522 +                    break;
   1.523 +                }
   1.524 +              } else if (raw_system_info->processor_architecture ==
   1.525 +                         MD_CPU_ARCHITECTURE_PPC) {
   1.526 +                switch (exception_flags) {
   1.527 +                  case MD_EXCEPTION_CODE_MAC_PPC_VM_PROT_READ:
   1.528 +                    reason.append("EXC_PPC_VM_PROT_READ");
   1.529 +                    break;
   1.530 +                  case MD_EXCEPTION_CODE_MAC_PPC_BADSPACE:
   1.531 +                    reason.append("EXC_PPC_BADSPACE");
   1.532 +                    break;
   1.533 +                  case MD_EXCEPTION_CODE_MAC_PPC_UNALIGNED:
   1.534 +                    reason.append("EXC_PPC_UNALIGNED");
   1.535 +                    break;
   1.536 +                  default:
   1.537 +                    reason.append(flags_string);
   1.538 +                    BPLOG(INFO) << "Unknown exception reason " << reason;
   1.539 +                    break;
   1.540 +                }
   1.541 +              } else {
   1.542 +                reason.append(flags_string);
   1.543 +                BPLOG(INFO) << "Unknown exception reason " << reason;
   1.544 +              }
   1.545 +              break;
   1.546 +          }
   1.547 +          break;
   1.548 +        case MD_EXCEPTION_MAC_BAD_INSTRUCTION:
   1.549 +          reason = "EXC_BAD_INSTRUCTION / ";
   1.550 +          switch (raw_system_info->processor_architecture) {
   1.551 +            case MD_CPU_ARCHITECTURE_ARM: {
   1.552 +              switch (exception_flags) {
   1.553 +                case MD_EXCEPTION_CODE_MAC_ARM_UNDEFINED:
   1.554 +                  reason.append("EXC_ARM_UNDEFINED");
   1.555 +                  break;
   1.556 +                default:
   1.557 +                  reason.append(flags_string);
   1.558 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.559 +                  break;
   1.560 +              }
   1.561 +              break;
   1.562 +            }
   1.563 +            case MD_CPU_ARCHITECTURE_PPC: {
   1.564 +              switch (exception_flags) {
   1.565 +                case MD_EXCEPTION_CODE_MAC_PPC_INVALID_SYSCALL:
   1.566 +                  reason.append("EXC_PPC_INVALID_SYSCALL");
   1.567 +                  break;
   1.568 +                case MD_EXCEPTION_CODE_MAC_PPC_UNIMPLEMENTED_INSTRUCTION:
   1.569 +                  reason.append("EXC_PPC_UNIPL_INST");
   1.570 +                  break;
   1.571 +                case MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_INSTRUCTION:
   1.572 +                  reason.append("EXC_PPC_PRIVINST");
   1.573 +                  break;
   1.574 +                case MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_REGISTER:
   1.575 +                  reason.append("EXC_PPC_PRIVREG");
   1.576 +                  break;
   1.577 +                case MD_EXCEPTION_CODE_MAC_PPC_TRACE:
   1.578 +                  reason.append("EXC_PPC_TRACE");
   1.579 +                  break;
   1.580 +                case MD_EXCEPTION_CODE_MAC_PPC_PERFORMANCE_MONITOR:
   1.581 +                  reason.append("EXC_PPC_PERFMON");
   1.582 +                  break;
   1.583 +                default:
   1.584 +                  reason.append(flags_string);
   1.585 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.586 +                  break;
   1.587 +              }
   1.588 +              break;
   1.589 +            }
   1.590 +            case MD_CPU_ARCHITECTURE_X86: {
   1.591 +              switch (exception_flags) {
   1.592 +                case MD_EXCEPTION_CODE_MAC_X86_INVALID_OPERATION:
   1.593 +                  reason.append("EXC_I386_INVOP");
   1.594 +                  break;
   1.595 +                case MD_EXCEPTION_CODE_MAC_X86_INVALID_TASK_STATE_SEGMENT:
   1.596 +                  reason.append("EXC_INVTSSFLT");
   1.597 +                  break;
   1.598 +                case MD_EXCEPTION_CODE_MAC_X86_SEGMENT_NOT_PRESENT:
   1.599 +                  reason.append("EXC_SEGNPFLT");
   1.600 +                  break;
   1.601 +                case MD_EXCEPTION_CODE_MAC_X86_STACK_FAULT:
   1.602 +                  reason.append("EXC_STKFLT");
   1.603 +                  break;
   1.604 +                case MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT:
   1.605 +                  reason.append("EXC_GPFLT");
   1.606 +                  break;
   1.607 +                case MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT:
   1.608 +                  reason.append("EXC_ALIGNFLT");
   1.609 +                  break;
   1.610 +                default:
   1.611 +                  reason.append(flags_string);
   1.612 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.613 +                  break;
   1.614 +              }
   1.615 +              break;
   1.616 +            }
   1.617 +            default:
   1.618 +              reason.append(flags_string);
   1.619 +              BPLOG(INFO) << "Unknown exception reason " << reason;
   1.620 +              break;
   1.621 +          }
   1.622 +          break;
   1.623 +        case MD_EXCEPTION_MAC_ARITHMETIC:
   1.624 +          reason = "EXC_ARITHMETIC / ";
   1.625 +          switch (raw_system_info->processor_architecture) {
   1.626 +            case MD_CPU_ARCHITECTURE_PPC: {
   1.627 +              switch (exception_flags) {
   1.628 +                case MD_EXCEPTION_CODE_MAC_PPC_OVERFLOW:
   1.629 +                  reason.append("EXC_PPC_OVERFLOW");
   1.630 +                  break;
   1.631 +                case MD_EXCEPTION_CODE_MAC_PPC_ZERO_DIVIDE:
   1.632 +                  reason.append("EXC_PPC_ZERO_DIVIDE");
   1.633 +                  break;
   1.634 +                case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_INEXACT:
   1.635 +                  reason.append("EXC_FLT_INEXACT");
   1.636 +                  break;
   1.637 +                case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_ZERO_DIVIDE:
   1.638 +                  reason.append("EXC_PPC_FLT_ZERO_DIVIDE");
   1.639 +                  break;
   1.640 +                case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_UNDERFLOW:
   1.641 +                  reason.append("EXC_PPC_FLT_UNDERFLOW");
   1.642 +                  break;
   1.643 +                case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_OVERFLOW:
   1.644 +                  reason.append("EXC_PPC_FLT_OVERFLOW");
   1.645 +                  break;
   1.646 +                case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_NOT_A_NUMBER:
   1.647 +                  reason.append("EXC_PPC_FLT_NOT_A_NUMBER");
   1.648 +                  break;
   1.649 +                case MD_EXCEPTION_CODE_MAC_PPC_NO_EMULATION:
   1.650 +                  reason.append("EXC_PPC_NOEMULATION");
   1.651 +                  break;
   1.652 +                case MD_EXCEPTION_CODE_MAC_PPC_ALTIVEC_ASSIST:
   1.653 +                  reason.append("EXC_PPC_ALTIVECASSIST");
   1.654 +                default:
   1.655 +                  reason.append(flags_string);
   1.656 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.657 +                  break;
   1.658 +              }
   1.659 +              break;
   1.660 +            }
   1.661 +            case MD_CPU_ARCHITECTURE_X86: {
   1.662 +              switch (exception_flags) {
   1.663 +                case MD_EXCEPTION_CODE_MAC_X86_DIV:
   1.664 +                  reason.append("EXC_I386_DIV");
   1.665 +                  break;
   1.666 +                case MD_EXCEPTION_CODE_MAC_X86_INTO:
   1.667 +                  reason.append("EXC_I386_INTO");
   1.668 +                  break;
   1.669 +                case MD_EXCEPTION_CODE_MAC_X86_NOEXT:
   1.670 +                  reason.append("EXC_I386_NOEXT");
   1.671 +                  break;
   1.672 +                case MD_EXCEPTION_CODE_MAC_X86_EXTOVR:
   1.673 +                  reason.append("EXC_I386_EXTOVR");
   1.674 +                  break;
   1.675 +                case MD_EXCEPTION_CODE_MAC_X86_EXTERR:
   1.676 +                  reason.append("EXC_I386_EXTERR");
   1.677 +                  break;
   1.678 +                case MD_EXCEPTION_CODE_MAC_X86_EMERR:
   1.679 +                  reason.append("EXC_I386_EMERR");
   1.680 +                  break;
   1.681 +                case MD_EXCEPTION_CODE_MAC_X86_BOUND:
   1.682 +                  reason.append("EXC_I386_BOUND");
   1.683 +                  break;
   1.684 +                case MD_EXCEPTION_CODE_MAC_X86_SSEEXTERR:
   1.685 +                  reason.append("EXC_I386_SSEEXTERR");
   1.686 +                  break;
   1.687 +                default:
   1.688 +                  reason.append(flags_string);
   1.689 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.690 +                  break;
   1.691 +              }
   1.692 +              break;
   1.693 +            }
   1.694 +            default:
   1.695 +              reason.append(flags_string);
   1.696 +              BPLOG(INFO) << "Unknown exception reason " << reason;
   1.697 +              break;
   1.698 +          }
   1.699 +          break;
   1.700 +        case MD_EXCEPTION_MAC_EMULATION:
   1.701 +          reason = "EXC_EMULATION / ";
   1.702 +          reason.append(flags_string);
   1.703 +          break;
   1.704 +        case MD_EXCEPTION_MAC_SOFTWARE:
   1.705 +          reason = "EXC_SOFTWARE / ";
   1.706 +          switch (exception_flags) {
   1.707 +            case MD_EXCEPTION_CODE_MAC_ABORT:
   1.708 +              reason.append("SIGABRT");
   1.709 +              break;
   1.710 +            case MD_EXCEPTION_CODE_MAC_NS_EXCEPTION:
   1.711 +              reason.append("UNCAUGHT_NS_EXCEPTION");
   1.712 +              break;
   1.713 +            // These are ppc only but shouldn't be a problem as they're
   1.714 +            // unused on x86
   1.715 +            case MD_EXCEPTION_CODE_MAC_PPC_TRAP:
   1.716 +              reason.append("EXC_PPC_TRAP");
   1.717 +              break;
   1.718 +            case MD_EXCEPTION_CODE_MAC_PPC_MIGRATE:
   1.719 +              reason.append("EXC_PPC_MIGRATE");
   1.720 +              break;
   1.721 +            default:
   1.722 +              reason.append(flags_string);
   1.723 +              BPLOG(INFO) << "Unknown exception reason " << reason;
   1.724 +              break;
   1.725 +          }
   1.726 +          break;
   1.727 +        case MD_EXCEPTION_MAC_BREAKPOINT:
   1.728 +          reason = "EXC_BREAKPOINT / ";
   1.729 +          switch (raw_system_info->processor_architecture) {
   1.730 +            case MD_CPU_ARCHITECTURE_ARM: {
   1.731 +              switch (exception_flags) {
   1.732 +                case MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN:
   1.733 +                  reason.append("EXC_ARM_DA_ALIGN");
   1.734 +                  break;
   1.735 +                case MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG:
   1.736 +                  reason.append("EXC_ARM_DA_DEBUG");
   1.737 +                  break;
   1.738 +                case MD_EXCEPTION_CODE_MAC_ARM_BREAKPOINT:
   1.739 +                  reason.append("EXC_ARM_BREAKPOINT");
   1.740 +                  break;
   1.741 +                default:
   1.742 +                  reason.append(flags_string);
   1.743 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.744 +                  break;
   1.745 +              }
   1.746 +              break;
   1.747 +            }
   1.748 +            case MD_CPU_ARCHITECTURE_PPC: {
   1.749 +              switch (exception_flags) {
   1.750 +                case MD_EXCEPTION_CODE_MAC_PPC_BREAKPOINT:
   1.751 +                  reason.append("EXC_PPC_BREAKPOINT");
   1.752 +                  break;
   1.753 +                default:
   1.754 +                  reason.append(flags_string);
   1.755 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.756 +                  break;
   1.757 +              }
   1.758 +              break;
   1.759 +            }
   1.760 +            case MD_CPU_ARCHITECTURE_X86: {
   1.761 +              switch (exception_flags) {
   1.762 +                case MD_EXCEPTION_CODE_MAC_X86_SGL:
   1.763 +                  reason.append("EXC_I386_SGL");
   1.764 +                  break;
   1.765 +                case MD_EXCEPTION_CODE_MAC_X86_BPT:
   1.766 +                  reason.append("EXC_I386_BPT");
   1.767 +                  break;
   1.768 +                default:
   1.769 +                  reason.append(flags_string);
   1.770 +                  BPLOG(INFO) << "Unknown exception reason " << reason;
   1.771 +                  break;
   1.772 +              }
   1.773 +              break;
   1.774 +            }
   1.775 +            default:
   1.776 +              reason.append(flags_string);
   1.777 +              BPLOG(INFO) << "Unknown exception reason " << reason;
   1.778 +              break;
   1.779 +          }
   1.780 +          break;
   1.781 +        case MD_EXCEPTION_MAC_SYSCALL:
   1.782 +          reason = "EXC_SYSCALL / ";
   1.783 +          reason.append(flags_string);
   1.784 +          break;
   1.785 +        case MD_EXCEPTION_MAC_MACH_SYSCALL:
   1.786 +          reason = "EXC_MACH_SYSCALL / ";
   1.787 +          reason.append(flags_string);
   1.788 +          break;
   1.789 +        case MD_EXCEPTION_MAC_RPC_ALERT:
   1.790 +          reason = "EXC_RPC_ALERT / ";
   1.791 +          reason.append(flags_string);
   1.792 +          break;
   1.793 +      }
   1.794 +      break;
   1.795 +    }
   1.796 +
   1.797 +    case MD_OS_WIN32_NT:
   1.798 +    case MD_OS_WIN32_WINDOWS: {
   1.799 +      switch (exception_code) {
   1.800 +        case MD_EXCEPTION_CODE_WIN_CONTROL_C:
   1.801 +          reason = "DBG_CONTROL_C";
   1.802 +          break;
   1.803 +        case MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION:
   1.804 +          reason = "EXCEPTION_GUARD_PAGE";
   1.805 +          break;
   1.806 +        case MD_EXCEPTION_CODE_WIN_DATATYPE_MISALIGNMENT:
   1.807 +          reason = "EXCEPTION_DATATYPE_MISALIGNMENT";
   1.808 +          break;
   1.809 +        case MD_EXCEPTION_CODE_WIN_BREAKPOINT:
   1.810 +          reason = "EXCEPTION_BREAKPOINT";
   1.811 +          break;
   1.812 +        case MD_EXCEPTION_CODE_WIN_SINGLE_STEP:
   1.813 +          reason = "EXCEPTION_SINGLE_STEP";
   1.814 +          break;
   1.815 +        case MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION:
   1.816 +          // For EXCEPTION_ACCESS_VIOLATION, Windows puts the address that
   1.817 +          // caused the fault in exception_information[1].
   1.818 +          // exception_information[0] is 0 if the violation was caused by
   1.819 +          // an attempt to read data and 1 if it was an attempt to write
   1.820 +          // data.
   1.821 +          // This information is useful in addition to the code address, which
   1.822 +          // will be present in the crash thread's instruction field anyway.
   1.823 +          if (raw_exception->exception_record.number_parameters >= 1) {
   1.824 +            MDAccessViolationTypeWin av_type =
   1.825 +                static_cast<MDAccessViolationTypeWin>
   1.826 +                (raw_exception->exception_record.exception_information[0]);
   1.827 +            switch (av_type) {
   1.828 +              case MD_ACCESS_VIOLATION_WIN_READ:
   1.829 +                reason = "EXCEPTION_ACCESS_VIOLATION_READ";
   1.830 +                break;
   1.831 +              case MD_ACCESS_VIOLATION_WIN_WRITE:
   1.832 +                reason = "EXCEPTION_ACCESS_VIOLATION_WRITE";
   1.833 +                break;
   1.834 +              case MD_ACCESS_VIOLATION_WIN_EXEC:
   1.835 +                reason = "EXCEPTION_ACCESS_VIOLATION_EXEC";
   1.836 +                break;
   1.837 +              default:
   1.838 +                reason = "EXCEPTION_ACCESS_VIOLATION";
   1.839 +                break;
   1.840 +            }
   1.841 +          } else {
   1.842 +            reason = "EXCEPTION_ACCESS_VIOLATION";
   1.843 +          }
   1.844 +          if (address &&
   1.845 +              raw_exception->exception_record.number_parameters >= 2) {
   1.846 +            *address =
   1.847 +                raw_exception->exception_record.exception_information[1];
   1.848 +          }
   1.849 +          break;
   1.850 +        case MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR:
   1.851 +          reason = "EXCEPTION_IN_PAGE_ERROR";
   1.852 +          break;
   1.853 +        case MD_EXCEPTION_CODE_WIN_INVALID_HANDLE:
   1.854 +          reason = "EXCEPTION_INVALID_HANDLE";
   1.855 +          break;
   1.856 +        case MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION:
   1.857 +          reason = "EXCEPTION_ILLEGAL_INSTRUCTION";
   1.858 +          break;
   1.859 +        case MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION:
   1.860 +          reason = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
   1.861 +          break;
   1.862 +        case MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION:
   1.863 +          reason = "EXCEPTION_INVALID_DISPOSITION";
   1.864 +          break;
   1.865 +        case MD_EXCEPTION_CODE_WIN_ARRAY_BOUNDS_EXCEEDED:
   1.866 +          reason = "EXCEPTION_BOUNDS_EXCEEDED";
   1.867 +          break;
   1.868 +        case MD_EXCEPTION_CODE_WIN_FLOAT_DENORMAL_OPERAND:
   1.869 +          reason = "EXCEPTION_FLT_DENORMAL_OPERAND";
   1.870 +          break;
   1.871 +        case MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO:
   1.872 +          reason = "EXCEPTION_FLT_DIVIDE_BY_ZERO";
   1.873 +          break;
   1.874 +        case MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT:
   1.875 +          reason = "EXCEPTION_FLT_INEXACT_RESULT";
   1.876 +          break;
   1.877 +        case MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION:
   1.878 +          reason = "EXCEPTION_FLT_INVALID_OPERATION";
   1.879 +          break;
   1.880 +        case MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW:
   1.881 +          reason = "EXCEPTION_FLT_OVERFLOW";
   1.882 +          break;
   1.883 +        case MD_EXCEPTION_CODE_WIN_FLOAT_STACK_CHECK:
   1.884 +          reason = "EXCEPTION_FLT_STACK_CHECK";
   1.885 +          break;
   1.886 +        case MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW:
   1.887 +          reason = "EXCEPTION_FLT_UNDERFLOW";
   1.888 +          break;
   1.889 +        case MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO:
   1.890 +          reason = "EXCEPTION_INT_DIVIDE_BY_ZERO";
   1.891 +          break;
   1.892 +        case MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW:
   1.893 +          reason = "EXCEPTION_INT_OVERFLOW";
   1.894 +          break;
   1.895 +        case MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION:
   1.896 +          reason = "EXCEPTION_PRIV_INSTRUCTION";
   1.897 +          break;
   1.898 +        case MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW:
   1.899 +          reason = "EXCEPTION_STACK_OVERFLOW";
   1.900 +          break;
   1.901 +        case MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK:
   1.902 +          reason = "EXCEPTION_POSSIBLE_DEADLOCK";
   1.903 +          break;
   1.904 +        case MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN:
   1.905 +          reason = "EXCEPTION_STACK_BUFFER_OVERRUN";
   1.906 +          break;
   1.907 +        case MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION:
   1.908 +          reason = "EXCEPTION_HEAP_CORRUPTION";
   1.909 +          break;
   1.910 +        case MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION:
   1.911 +          reason = "Unhandled C++ Exception";
   1.912 +          break;
   1.913 +        default:
   1.914 +          BPLOG(INFO) << "Unknown exception reason " << reason;
   1.915 +          break;
   1.916 +      }
   1.917 +      break;
   1.918 +    }
   1.919 +
   1.920 +    case MD_OS_ANDROID:
   1.921 +    case MD_OS_LINUX: {
   1.922 +      switch (exception_code) {
   1.923 +        case MD_EXCEPTION_CODE_LIN_SIGHUP:
   1.924 +          reason = "SIGHUP";
   1.925 +          break;
   1.926 +        case MD_EXCEPTION_CODE_LIN_SIGINT:
   1.927 +          reason = "SIGINT";
   1.928 +          break;
   1.929 +        case MD_EXCEPTION_CODE_LIN_SIGQUIT:
   1.930 +          reason = "SIGQUIT";
   1.931 +          break;
   1.932 +        case MD_EXCEPTION_CODE_LIN_SIGILL:
   1.933 +          reason = "SIGILL";
   1.934 +          break;
   1.935 +        case MD_EXCEPTION_CODE_LIN_SIGTRAP:
   1.936 +          reason = "SIGTRAP";
   1.937 +          break;
   1.938 +        case MD_EXCEPTION_CODE_LIN_SIGABRT:
   1.939 +          reason = "SIGABRT";
   1.940 +          break;
   1.941 +        case MD_EXCEPTION_CODE_LIN_SIGBUS:
   1.942 +          reason = "SIGBUS";
   1.943 +          break;
   1.944 +        case MD_EXCEPTION_CODE_LIN_SIGFPE:
   1.945 +          reason = "SIGFPE";
   1.946 +          break;
   1.947 +        case MD_EXCEPTION_CODE_LIN_SIGKILL:
   1.948 +          reason = "SIGKILL";
   1.949 +          break;
   1.950 +        case MD_EXCEPTION_CODE_LIN_SIGUSR1:
   1.951 +          reason = "SIGUSR1";
   1.952 +          break;
   1.953 +        case MD_EXCEPTION_CODE_LIN_SIGSEGV:
   1.954 +          reason = "SIGSEGV";
   1.955 +          break;
   1.956 +        case MD_EXCEPTION_CODE_LIN_SIGUSR2:
   1.957 +          reason = "SIGUSR2";
   1.958 +          break;
   1.959 +        case MD_EXCEPTION_CODE_LIN_SIGPIPE:
   1.960 +          reason = "SIGPIPE";
   1.961 +          break;
   1.962 +        case MD_EXCEPTION_CODE_LIN_SIGALRM:
   1.963 +          reason = "SIGALRM";
   1.964 +          break;
   1.965 +        case MD_EXCEPTION_CODE_LIN_SIGTERM:
   1.966 +          reason = "SIGTERM";
   1.967 +          break;
   1.968 +        case MD_EXCEPTION_CODE_LIN_SIGSTKFLT:
   1.969 +          reason = "SIGSTKFLT";
   1.970 +          break;
   1.971 +        case MD_EXCEPTION_CODE_LIN_SIGCHLD:
   1.972 +          reason = "SIGCHLD";
   1.973 +          break;
   1.974 +        case MD_EXCEPTION_CODE_LIN_SIGCONT:
   1.975 +          reason = "SIGCONT";
   1.976 +          break;
   1.977 +        case MD_EXCEPTION_CODE_LIN_SIGSTOP:
   1.978 +          reason = "SIGSTOP";
   1.979 +          break;
   1.980 +        case MD_EXCEPTION_CODE_LIN_SIGTSTP:
   1.981 +          reason = "SIGTSTP";
   1.982 +          break;
   1.983 +        case MD_EXCEPTION_CODE_LIN_SIGTTIN:
   1.984 +          reason = "SIGTTIN";
   1.985 +          break;
   1.986 +        case MD_EXCEPTION_CODE_LIN_SIGTTOU:
   1.987 +          reason = "SIGTTOU";
   1.988 +          break;
   1.989 +        case MD_EXCEPTION_CODE_LIN_SIGURG:
   1.990 +          reason = "SIGURG";
   1.991 +          break;
   1.992 +        case MD_EXCEPTION_CODE_LIN_SIGXCPU:
   1.993 +          reason = "SIGXCPU";
   1.994 +          break;
   1.995 +        case MD_EXCEPTION_CODE_LIN_SIGXFSZ:
   1.996 +          reason = "SIGXFSZ";
   1.997 +          break;
   1.998 +        case MD_EXCEPTION_CODE_LIN_SIGVTALRM:
   1.999 +          reason = "SIGVTALRM";
  1.1000 +          break;
  1.1001 +        case MD_EXCEPTION_CODE_LIN_SIGPROF:
  1.1002 +          reason = "SIGPROF";
  1.1003 +          break;
  1.1004 +        case MD_EXCEPTION_CODE_LIN_SIGWINCH:
  1.1005 +          reason = "SIGWINCH";
  1.1006 +          break;
  1.1007 +        case MD_EXCEPTION_CODE_LIN_SIGIO:
  1.1008 +          reason = "SIGIO";
  1.1009 +          break;
  1.1010 +        case MD_EXCEPTION_CODE_LIN_SIGPWR:
  1.1011 +          reason = "SIGPWR";
  1.1012 +          break;
  1.1013 +        case MD_EXCEPTION_CODE_LIN_SIGSYS:
  1.1014 +          reason = "SIGSYS";
  1.1015 +          break;
  1.1016 +      case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED:
  1.1017 +          reason = "DUMP_REQUESTED";
  1.1018 +          break;
  1.1019 +        default:
  1.1020 +          BPLOG(INFO) << "Unknown exception reason " << reason;
  1.1021 +          break;
  1.1022 +      }
  1.1023 +      break;
  1.1024 +    }
  1.1025 +
  1.1026 +    case MD_OS_SOLARIS: {
  1.1027 +      switch (exception_code) {
  1.1028 +        case MD_EXCEPTION_CODE_SOL_SIGHUP:
  1.1029 +          reason = "SIGHUP";
  1.1030 +          break;
  1.1031 +        case MD_EXCEPTION_CODE_SOL_SIGINT:
  1.1032 +          reason = "SIGINT";
  1.1033 +          break;
  1.1034 +        case MD_EXCEPTION_CODE_SOL_SIGQUIT:
  1.1035 +          reason = "SIGQUIT";
  1.1036 +          break;
  1.1037 +        case MD_EXCEPTION_CODE_SOL_SIGILL:
  1.1038 +          reason = "SIGILL";
  1.1039 +          break;
  1.1040 +        case MD_EXCEPTION_CODE_SOL_SIGTRAP:
  1.1041 +          reason = "SIGTRAP";
  1.1042 +          break;
  1.1043 +        case MD_EXCEPTION_CODE_SOL_SIGIOT:
  1.1044 +          reason = "SIGIOT | SIGABRT";
  1.1045 +          break;
  1.1046 +        case MD_EXCEPTION_CODE_SOL_SIGEMT:
  1.1047 +          reason = "SIGEMT";
  1.1048 +          break;
  1.1049 +        case MD_EXCEPTION_CODE_SOL_SIGFPE:
  1.1050 +          reason = "SIGFPE";
  1.1051 +          break;
  1.1052 +        case MD_EXCEPTION_CODE_SOL_SIGKILL:
  1.1053 +          reason = "SIGKILL";
  1.1054 +          break;
  1.1055 +        case MD_EXCEPTION_CODE_SOL_SIGBUS:
  1.1056 +          reason = "SIGBUS";
  1.1057 +          break;
  1.1058 +        case MD_EXCEPTION_CODE_SOL_SIGSEGV:
  1.1059 +          reason = "SIGSEGV";
  1.1060 +          break;
  1.1061 +        case MD_EXCEPTION_CODE_SOL_SIGSYS:
  1.1062 +          reason = "SIGSYS";
  1.1063 +          break;
  1.1064 +        case MD_EXCEPTION_CODE_SOL_SIGPIPE:
  1.1065 +          reason = "SIGPIPE";
  1.1066 +          break;
  1.1067 +        case MD_EXCEPTION_CODE_SOL_SIGALRM:
  1.1068 +          reason = "SIGALRM";
  1.1069 +          break;
  1.1070 +        case MD_EXCEPTION_CODE_SOL_SIGTERM:
  1.1071 +          reason = "SIGTERM";
  1.1072 +          break;
  1.1073 +        case MD_EXCEPTION_CODE_SOL_SIGUSR1:
  1.1074 +          reason = "SIGUSR1";
  1.1075 +          break;
  1.1076 +        case MD_EXCEPTION_CODE_SOL_SIGUSR2:
  1.1077 +          reason = "SIGUSR2";
  1.1078 +          break;
  1.1079 +        case MD_EXCEPTION_CODE_SOL_SIGCLD:
  1.1080 +          reason = "SIGCLD | SIGCHLD";
  1.1081 +          break;
  1.1082 +        case MD_EXCEPTION_CODE_SOL_SIGPWR:
  1.1083 +          reason = "SIGPWR";
  1.1084 +          break;
  1.1085 +        case MD_EXCEPTION_CODE_SOL_SIGWINCH:
  1.1086 +          reason = "SIGWINCH";
  1.1087 +          break;
  1.1088 +        case MD_EXCEPTION_CODE_SOL_SIGURG:
  1.1089 +          reason = "SIGURG";
  1.1090 +          break;
  1.1091 +        case MD_EXCEPTION_CODE_SOL_SIGPOLL:
  1.1092 +          reason = "SIGPOLL | SIGIO";
  1.1093 +          break;
  1.1094 +        case MD_EXCEPTION_CODE_SOL_SIGSTOP:
  1.1095 +          reason = "SIGSTOP";
  1.1096 +          break;
  1.1097 +        case MD_EXCEPTION_CODE_SOL_SIGTSTP:
  1.1098 +          reason = "SIGTSTP";
  1.1099 +          break;
  1.1100 +        case MD_EXCEPTION_CODE_SOL_SIGCONT:
  1.1101 +          reason = "SIGCONT";
  1.1102 +          break;
  1.1103 +        case MD_EXCEPTION_CODE_SOL_SIGTTIN:
  1.1104 +          reason = "SIGTTIN";
  1.1105 +          break;
  1.1106 +        case MD_EXCEPTION_CODE_SOL_SIGTTOU:
  1.1107 +          reason = "SIGTTOU";
  1.1108 +          break;
  1.1109 +        case MD_EXCEPTION_CODE_SOL_SIGVTALRM:
  1.1110 +          reason = "SIGVTALRM";
  1.1111 +          break;
  1.1112 +        case MD_EXCEPTION_CODE_SOL_SIGPROF:
  1.1113 +          reason = "SIGPROF";
  1.1114 +          break;
  1.1115 +        case MD_EXCEPTION_CODE_SOL_SIGXCPU:
  1.1116 +          reason = "SIGXCPU";
  1.1117 +          break;
  1.1118 +        case MD_EXCEPTION_CODE_SOL_SIGXFSZ:
  1.1119 +          reason = "SIGXFSZ";
  1.1120 +          break;
  1.1121 +        case MD_EXCEPTION_CODE_SOL_SIGWAITING:
  1.1122 +          reason = "SIGWAITING";
  1.1123 +          break;
  1.1124 +        case MD_EXCEPTION_CODE_SOL_SIGLWP:
  1.1125 +          reason = "SIGLWP";
  1.1126 +          break;
  1.1127 +        case MD_EXCEPTION_CODE_SOL_SIGFREEZE:
  1.1128 +          reason = "SIGFREEZE";
  1.1129 +          break;
  1.1130 +        case MD_EXCEPTION_CODE_SOL_SIGTHAW:
  1.1131 +          reason = "SIGTHAW";
  1.1132 +          break;
  1.1133 +        case MD_EXCEPTION_CODE_SOL_SIGCANCEL:
  1.1134 +          reason = "SIGCANCEL";
  1.1135 +          break;
  1.1136 +        case MD_EXCEPTION_CODE_SOL_SIGLOST:
  1.1137 +          reason = "SIGLOST";
  1.1138 +          break;
  1.1139 +        case MD_EXCEPTION_CODE_SOL_SIGXRES:
  1.1140 +          reason = "SIGXRES";
  1.1141 +          break;
  1.1142 +        case MD_EXCEPTION_CODE_SOL_SIGJVM1:
  1.1143 +          reason = "SIGJVM1";
  1.1144 +          break;
  1.1145 +        case MD_EXCEPTION_CODE_SOL_SIGJVM2:
  1.1146 +          reason = "SIGJVM2";
  1.1147 +          break;
  1.1148 +        default:
  1.1149 +          BPLOG(INFO) << "Unknown exception reason " << reason;
  1.1150 +          break;
  1.1151 +      }
  1.1152 +      break;
  1.1153 +    }
  1.1154 +
  1.1155 +    default: {
  1.1156 +      BPLOG(INFO) << "Unknown exception reason " << reason;
  1.1157 +      break;
  1.1158 +    }
  1.1159 +  }
  1.1160 +
  1.1161 +  return reason;
  1.1162 +}
  1.1163 +
  1.1164 +// static
  1.1165 +string MinidumpProcessor::GetAssertion(Minidump *dump) {
  1.1166 +  MinidumpAssertion *assertion = dump->GetAssertion();
  1.1167 +  if (!assertion)
  1.1168 +    return "";
  1.1169 +
  1.1170 +  const MDRawAssertionInfo *raw_assertion = assertion->assertion();
  1.1171 +  if (!raw_assertion)
  1.1172 +    return "";
  1.1173 +
  1.1174 +  string assertion_string;
  1.1175 +  switch (raw_assertion->type) {
  1.1176 +  case MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER:
  1.1177 +    assertion_string = "Invalid parameter passed to library function";
  1.1178 +    break;
  1.1179 +  case MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL:
  1.1180 +    assertion_string = "Pure virtual function called";
  1.1181 +    break;
  1.1182 +  default: {
  1.1183 +    char assertion_type[32];
  1.1184 +    snprintf(assertion_type, sizeof(assertion_type),
  1.1185 +             "0x%08x", raw_assertion->type);
  1.1186 +    assertion_string = "Unknown assertion type ";
  1.1187 +    assertion_string += assertion_type;
  1.1188 +    break;
  1.1189 +  }
  1.1190 +  }
  1.1191 +
  1.1192 +  string expression = assertion->expression();
  1.1193 +  if (!expression.empty()) {
  1.1194 +    assertion_string.append(" " + expression);
  1.1195 +  }
  1.1196 +
  1.1197 +  string function = assertion->function();
  1.1198 +  if (!function.empty()) {
  1.1199 +    assertion_string.append(" in function " + function);
  1.1200 +  }
  1.1201 +
  1.1202 +  string file = assertion->file();
  1.1203 +  if (!file.empty()) {
  1.1204 +    assertion_string.append(", in file " + file);
  1.1205 +  }
  1.1206 +
  1.1207 +  if (raw_assertion->line != 0) {
  1.1208 +    char assertion_line[32];
  1.1209 +    snprintf(assertion_line, sizeof(assertion_line), "%u", raw_assertion->line);
  1.1210 +    assertion_string.append(" at line ");
  1.1211 +    assertion_string.append(assertion_line);
  1.1212 +  }
  1.1213 +
  1.1214 +  return assertion_string;
  1.1215 +}
  1.1216 +
  1.1217 +}  // namespace google_breakpad

mercurial