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