blob: 232a19ed3e5e3d3d1594c4311febab2944a5751f [file] [log] [blame]
mmentovai7daf2462006-09-20 21:16:16 +00001// Copyright (c) 2006, Google Inc.
2// All rights reserved.
brynerd5e66382006-09-08 02:35:53 +00003//
mmentovai7daf2462006-09-20 21:16:16 +00004// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
brynerd5e66382006-09-08 02:35:53 +00007//
mmentovai7daf2462006-09-20 21:16:16 +00008// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
ivan.penkov@gmail.com8695cc02013-05-11 00:23:41 +000014// * Neither the name of Google Inc. nor the names of its
mmentovai7daf2462006-09-20 21:16:16 +000015// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
brynerd5e66382006-09-08 02:35:53 +000017//
mmentovai7daf2462006-09-20 21:16:16 +000018// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
brynerd5e66382006-09-08 02:35:53 +000029
mmentovaie5dc6082007-02-14 19:51:05 +000030#include "google_breakpad/processor/minidump_processor.h"
ted.mielczareke1930982010-06-25 16:57:07 +000031
32#include <assert.h>
33#include <stdio.h>
34
ivan.penkov@gmail.com8695cc02013-05-11 00:23:41 +000035#include <string>
36
ted.mielczarek@gmail.com63c5d982013-01-17 15:53:56 +000037#include "common/scoped_ptr.h"
ivan.penkov@gmail.com8695cc02013-05-11 00:23:41 +000038#include "common/using_std_string.h"
mmentovaie5dc6082007-02-14 19:51:05 +000039#include "google_breakpad/processor/call_stack.h"
40#include "google_breakpad/processor/minidump.h"
41#include "google_breakpad/processor/process_state.h"
nealsid8d2c5182010-08-24 14:28:10 +000042#include "google_breakpad/processor/exploitability.h"
SiyangXie@gmail.combab77002012-10-10 21:41:52 +000043#include "google_breakpad/processor/stack_frame_symbolizer.h"
mmentovaiaf3c43f2007-05-17 18:34:37 +000044#include "processor/logging.h"
brynerd5e66382006-09-08 02:35:53 +000045#include "processor/stackwalker_x86.h"
46
mmentovaie5dc6082007-02-14 19:51:05 +000047namespace google_breakpad {
brynerd5e66382006-09-08 02:35:53 +000048
brynerfd38d482006-12-11 23:22:54 +000049MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier,
50 SourceLineResolverInterface *resolver)
SiyangXie@gmail.combab77002012-10-10 21:41:52 +000051 : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)),
52 own_frame_symbolizer_(true),
nealsid8d2c5182010-08-24 14:28:10 +000053 enable_exploitability_(false) {
54}
55
56MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier,
57 SourceLineResolverInterface *resolver,
58 bool enable_exploitability)
SiyangXie@gmail.combab77002012-10-10 21:41:52 +000059 : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)),
60 own_frame_symbolizer_(true),
nealsid8d2c5182010-08-24 14:28:10 +000061 enable_exploitability_(enable_exploitability) {
brynerd5e66382006-09-08 02:35:53 +000062}
63
SiyangXie@gmail.combab77002012-10-10 21:41:52 +000064MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer *frame_symbolizer,
65 bool enable_exploitability)
66 : frame_symbolizer_(frame_symbolizer),
67 own_frame_symbolizer_(false),
68 enable_exploitability_(enable_exploitability) {
69 assert(frame_symbolizer_);
70}
71
brynercce34922006-09-19 21:58:41 +000072MinidumpProcessor::~MinidumpProcessor() {
SiyangXie@gmail.combab77002012-10-10 21:41:52 +000073 if (own_frame_symbolizer_) delete frame_symbolizer_;
brynerd5e66382006-09-08 02:35:53 +000074}
75
nealsidb56cfa02009-05-29 00:53:02 +000076ProcessResult MinidumpProcessor::Process(
77 Minidump *dump, ProcessState *process_state) {
78 assert(dump);
79 assert(process_state);
brynerd5e66382006-09-08 02:35:53 +000080
brynerf33b8d22006-12-08 04:13:51 +000081 process_state->Clear();
mmentovaie5468b82006-10-24 19:31:21 +000082
nealsidb56cfa02009-05-29 00:53:02 +000083 const MDRawHeader *header = dump->header();
84 if (!header) {
85 BPLOG(ERROR) << "Minidump " << dump->path() << " has no header";
86 return PROCESS_ERROR_NO_MINIDUMP_HEADER;
87 }
waylonisdaf42112006-12-06 04:58:27 +000088 process_state->time_date_stamp_ = header->time_date_stamp;
89
nealsidb56cfa02009-05-29 00:53:02 +000090 bool has_cpu_info = GetCPUInfo(dump, &process_state->system_info_);
91 bool has_os_info = GetOSInfo(dump, &process_state->system_info_);
mmentovaie5468b82006-10-24 19:31:21 +000092
ted.mielczarek@gmail.comaeffe102013-03-06 14:04:42 +000093 uint32_t dump_thread_id = 0;
mmentovai76f052f2006-11-06 23:00:19 +000094 bool has_dump_thread = false;
ted.mielczarek@gmail.comaeffe102013-03-06 14:04:42 +000095 uint32_t requesting_thread_id = 0;
mmentovai76f052f2006-11-06 23:00:19 +000096 bool has_requesting_thread = false;
97
nealsidb56cfa02009-05-29 00:53:02 +000098 MinidumpBreakpadInfo *breakpad_info = dump->GetBreakpadInfo();
mmentovaie5dc6082007-02-14 19:51:05 +000099 if (breakpad_info) {
100 has_dump_thread = breakpad_info->GetDumpThreadID(&dump_thread_id);
mmentovai76f052f2006-11-06 23:00:19 +0000101 has_requesting_thread =
mmentovaie5dc6082007-02-14 19:51:05 +0000102 breakpad_info->GetRequestingThreadID(&requesting_thread_id);
mmentovai76f052f2006-11-06 23:00:19 +0000103 }
104
nealsidb56cfa02009-05-29 00:53:02 +0000105 MinidumpException *exception = dump->GetException();
mmentovaie5468b82006-10-24 19:31:21 +0000106 if (exception) {
107 process_state->crashed_ = true;
mmentovai76f052f2006-11-06 23:00:19 +0000108 has_requesting_thread = exception->GetThreadID(&requesting_thread_id);
mmentovaie5468b82006-10-24 19:31:21 +0000109
110 process_state->crash_reason_ = GetCrashReason(
nealsidb56cfa02009-05-29 00:53:02 +0000111 dump, &process_state->crash_address_);
brynerd5e66382006-09-08 02:35:53 +0000112 }
113
cdn@chromium.orgcec12872010-09-22 02:37:19 +0000114 // This will just return an empty string if it doesn't exist.
115 process_state->assertion_ = GetAssertion(dump);
ted.mielczarek0314e482009-12-02 17:43:57 +0000116
nealsidb56cfa02009-05-29 00:53:02 +0000117 MinidumpModuleList *module_list = dump->GetModuleList();
mmentovaidb3342a2006-12-05 22:52:28 +0000118
119 // Put a copy of the module list into ProcessState object. This is not
120 // necessarily a MinidumpModuleList, but it adheres to the CodeModules
121 // interface, which is all that ProcessState needs to expose.
122 if (module_list)
123 process_state->modules_ = module_list->Copy();
124
nealsidb56cfa02009-05-29 00:53:02 +0000125 MinidumpThreadList *threads = dump->GetThreadList();
brynerd5e66382006-09-08 02:35:53 +0000126 if (!threads) {
nealsidb56cfa02009-05-29 00:53:02 +0000127 BPLOG(ERROR) << "Minidump " << dump->path() << " has no thread list";
128 return PROCESS_ERROR_NO_THREAD_LIST;
brynerd5e66382006-09-08 02:35:53 +0000129 }
130
nealsidb56cfa02009-05-29 00:53:02 +0000131 BPLOG(INFO) << "Minidump " << dump->path() << " has " <<
132 (has_cpu_info ? "" : "no ") << "CPU info, " <<
133 (has_os_info ? "" : "no ") << "OS info, " <<
134 (breakpad_info != NULL ? "" : "no ") << "Breakpad info, " <<
135 (exception != NULL ? "" : "no ") << "exception, " <<
136 (module_list != NULL ? "" : "no ") << "module list, " <<
137 (threads != NULL ? "" : "no ") << "thread list, " <<
138 (has_dump_thread ? "" : "no ") << "dump thread, and " <<
139 (has_requesting_thread ? "" : "no ") << "requesting thread";
mmentovaiaf3c43f2007-05-17 18:34:37 +0000140
mmentovai6ed453a2007-05-25 19:10:19 +0000141 bool interrupted = false;
mmentovai76f052f2006-11-06 23:00:19 +0000142 bool found_requesting_thread = false;
mmentovaie5468b82006-10-24 19:31:21 +0000143 unsigned int thread_count = threads->thread_count();
SiyangXie@gmail.combab77002012-10-10 21:41:52 +0000144
145 // Reset frame_symbolizer_ at the beginning of stackwalk for each minidump.
146 frame_symbolizer_->Reset();
147
mmentovaie5468b82006-10-24 19:31:21 +0000148 for (unsigned int thread_index = 0;
149 thread_index < thread_count;
150 ++thread_index) {
mmentovaiaf3c43f2007-05-17 18:34:37 +0000151 char thread_string_buffer[64];
152 snprintf(thread_string_buffer, sizeof(thread_string_buffer), "%d/%d",
153 thread_index, thread_count);
nealsidb56cfa02009-05-29 00:53:02 +0000154 string thread_string = dump->path() + ":" + thread_string_buffer;
mmentovaiaf3c43f2007-05-17 18:34:37 +0000155
mmentovaie5468b82006-10-24 19:31:21 +0000156 MinidumpThread *thread = threads->GetThreadAtIndex(thread_index);
157 if (!thread) {
mmentovaiaf3c43f2007-05-17 18:34:37 +0000158 BPLOG(ERROR) << "Could not get thread for " << thread_string;
nealsidb56cfa02009-05-29 00:53:02 +0000159 return PROCESS_ERROR_GETTING_THREAD;
mmentovaie5468b82006-10-24 19:31:21 +0000160 }
161
ted.mielczarek@gmail.comaeffe102013-03-06 14:04:42 +0000162 uint32_t thread_id;
mmentovai76f052f2006-11-06 23:00:19 +0000163 if (!thread->GetThreadID(&thread_id)) {
mmentovaiaf3c43f2007-05-17 18:34:37 +0000164 BPLOG(ERROR) << "Could not get thread ID for " << thread_string;
nealsidb56cfa02009-05-29 00:53:02 +0000165 return PROCESS_ERROR_GETTING_THREAD_ID;
mmentovai76f052f2006-11-06 23:00:19 +0000166 }
167
mmentovaiaf3c43f2007-05-17 18:34:37 +0000168 thread_string += " id " + HexString(thread_id);
169 BPLOG(INFO) << "Looking at thread " << thread_string;
170
mmentovai76f052f2006-11-06 23:00:19 +0000171 // If this thread is the thread that produced the minidump, don't process
172 // it. Because of the problems associated with a thread producing a
173 // dump of itself (when both its context and its stack are in flux),
174 // processing that stack wouldn't provide much useful data.
175 if (has_dump_thread && thread_id == dump_thread_id) {
176 continue;
177 }
178
mmentovaif944ba32006-10-26 23:09:02 +0000179 MinidumpContext *context = thread->GetContext();
180
mmentovai76f052f2006-11-06 23:00:19 +0000181 if (has_requesting_thread && thread_id == requesting_thread_id) {
182 if (found_requesting_thread) {
183 // There can't be more than one requesting thread.
mmentovaiaf3c43f2007-05-17 18:34:37 +0000184 BPLOG(ERROR) << "Duplicate requesting thread: " << thread_string;
nealsidb56cfa02009-05-29 00:53:02 +0000185 return PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS;
mmentovaie5468b82006-10-24 19:31:21 +0000186 }
187
mmentovai76f052f2006-11-06 23:00:19 +0000188 // Use processed_state->threads_.size() instead of thread_index.
189 // thread_index points to the thread index in the minidump, which
190 // might be greater than the thread index in the threads vector if
191 // any of the minidump's threads are skipped and not placed into the
192 // processed threads vector. The thread vector's current size will
193 // be the index of the current thread when it's pushed into the
194 // vector.
195 process_state->requesting_thread_ = process_state->threads_.size();
mmentovaif944ba32006-10-26 23:09:02 +0000196
mmentovai76f052f2006-11-06 23:00:19 +0000197 found_requesting_thread = true;
198
199 if (process_state->crashed_) {
200 // Use the exception record's context for the crashed thread, instead
201 // of the thread's own context. For the crashed thread, the thread's
202 // own context is the state inside the exception handler. Using it
203 // would not result in the expected stack trace from the time of the
jschuh@chromium.org5f4fa552009-10-19 18:10:49 +0000204 // crash. If the exception context is invalid, however, we fall back
205 // on the thread context.
jschuh@chromium.org96c69632009-10-19 18:53:26 +0000206 MinidumpContext *ctx = exception->GetContext();
jschuh@chromium.org5f4fa552009-10-19 18:10:49 +0000207 context = ctx ? ctx : thread->GetContext();
mmentovai76f052f2006-11-06 23:00:19 +0000208 }
mmentovaie5468b82006-10-24 19:31:21 +0000209 }
210
211 MinidumpMemoryRegion *thread_memory = thread->GetMemory();
212 if (!thread_memory) {
mmentovaiaf3c43f2007-05-17 18:34:37 +0000213 BPLOG(ERROR) << "No memory region for " << thread_string;
mmentovaie5468b82006-10-24 19:31:21 +0000214 }
215
mmentovaidb3342a2006-12-05 22:52:28 +0000216 // Use process_state->modules_ instead of module_list, because the
217 // |modules| argument will be used to populate the |module| fields in
218 // the returned StackFrame objects, which will be placed into the
219 // returned ProcessState object. module_list's lifetime is only as
220 // long as the Minidump object: it will be deleted when this function
221 // returns. process_state->modules_ is owned by the ProcessState object
222 // (just like the StackFrame objects), and is much more suitable for this
223 // task.
mmentovaie5468b82006-10-24 19:31:21 +0000224 scoped_ptr<Stackwalker> stackwalker(
mmentovai97d392d2007-01-10 22:47:56 +0000225 Stackwalker::StackwalkerForCPU(process_state->system_info(),
226 context,
mmentovaie5468b82006-10-24 19:31:21 +0000227 thread_memory,
mmentovaidb3342a2006-12-05 22:52:28 +0000228 process_state->modules_,
SiyangXie@gmail.combab77002012-10-10 21:41:52 +0000229 frame_symbolizer_));
mmentovaie5468b82006-10-24 19:31:21 +0000230
brynerf33b8d22006-12-08 04:13:51 +0000231 scoped_ptr<CallStack> stack(new CallStack());
ted.mielczarek@gmail.comfc6f7002012-11-06 16:50:01 +0000232 if (stackwalker.get()) {
ivan.penkov@gmail.com60b5f7c2013-03-06 19:32:13 +0000233 if (!stackwalker->Walk(stack.get(),
234 &process_state->modules_without_symbols_)) {
235 BPLOG(INFO) << "Stackwalker interrupt (missing symbols?) at "
236 << thread_string;
ted.mielczarek@gmail.comfc6f7002012-11-06 16:50:01 +0000237 interrupted = true;
238 }
239 } else {
240 // Threads with missing CPU contexts will hit this, but
241 // don't abort processing the rest of the dump just for
242 // one bad thread.
243 BPLOG(ERROR) << "No stackwalker for " << thread_string;
mmentovaie5468b82006-10-24 19:31:21 +0000244 }
mmentovaie5468b82006-10-24 19:31:21 +0000245 process_state->threads_.push_back(stack.release());
nealsid6e525cb2009-07-02 00:30:44 +0000246 process_state->thread_memory_regions_.push_back(thread_memory);
mmentovaie5468b82006-10-24 19:31:21 +0000247 }
248
mmentovai6ed453a2007-05-25 19:10:19 +0000249 if (interrupted) {
nealsidb56cfa02009-05-29 00:53:02 +0000250 BPLOG(INFO) << "Processing interrupted for " << dump->path();
251 return PROCESS_SYMBOL_SUPPLIER_INTERRUPTED;
mmentovai6ed453a2007-05-25 19:10:19 +0000252 }
253
mmentovai76f052f2006-11-06 23:00:19 +0000254 // If a requesting thread was indicated, it must be present.
255 if (has_requesting_thread && !found_requesting_thread) {
waylonis3a9a38a2007-02-01 23:54:05 +0000256 // Don't mark as an error, but invalidate the requesting thread
mmentovaiaf3c43f2007-05-17 18:34:37 +0000257 BPLOG(ERROR) << "Minidump indicated requesting thread " <<
nealsidb56cfa02009-05-29 00:53:02 +0000258 HexString(requesting_thread_id) << ", not found in " <<
259 dump->path();
waylonis3a9a38a2007-02-01 23:54:05 +0000260 process_state->requesting_thread_ = -1;
brynerd5e66382006-09-08 02:35:53 +0000261 }
262
nealsid8d2c5182010-08-24 14:28:10 +0000263 // Exploitability defaults to EXPLOITABILITY_NOT_ANALYZED
264 process_state->exploitability_ = EXPLOITABILITY_NOT_ANALYZED;
265
266 // If an exploitability run was requested we perform the platform specific
267 // rating.
268 if (enable_exploitability_) {
269 scoped_ptr<Exploitability> exploitability(
270 Exploitability::ExploitabilityForPlatform(dump, process_state));
271 // The engine will be null if the platform is not supported
272 if (exploitability != NULL) {
273 process_state->exploitability_ = exploitability->CheckExploitability();
274 } else {
275 process_state->exploitability_ = EXPLOITABILITY_ERR_NOENGINE;
276 }
277 }
278
nealsidb56cfa02009-05-29 00:53:02 +0000279 BPLOG(INFO) << "Processed " << dump->path();
brynerf33b8d22006-12-08 04:13:51 +0000280 return PROCESS_OK;
mmentovaie5468b82006-10-24 19:31:21 +0000281}
282
nealsidb56cfa02009-05-29 00:53:02 +0000283ProcessResult MinidumpProcessor::Process(
284 const string &minidump_file, ProcessState *process_state) {
285 BPLOG(INFO) << "Processing minidump in file " << minidump_file;
286
287 Minidump dump(minidump_file);
288 if (!dump.Read()) {
289 BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read";
290 return PROCESS_ERROR_MINIDUMP_NOT_FOUND;
cdn@chromium.orgcec12872010-09-22 02:37:19 +0000291 }
nealsidb56cfa02009-05-29 00:53:02 +0000292
293 return Process(&dump, process_state);
294}
295
mmentovaie5468b82006-10-24 19:31:21 +0000296// Returns the MDRawSystemInfo from a minidump, or NULL if system info is
mmentovai80e98392006-10-25 21:25:41 +0000297// not available from the minidump. If system_info is non-NULL, it is used
mmentovaie5468b82006-10-24 19:31:21 +0000298// to pass back the MinidumpSystemInfo object.
299static const MDRawSystemInfo* GetSystemInfo(Minidump *dump,
300 MinidumpSystemInfo **system_info) {
301 MinidumpSystemInfo *minidump_system_info = dump->GetSystemInfo();
302 if (!minidump_system_info)
mmentovaid119a922006-10-23 19:24:58 +0000303 return NULL;
mmentovaie5468b82006-10-24 19:31:21 +0000304
305 if (system_info)
306 *system_info = minidump_system_info;
307
308 return minidump_system_info->system_info();
309}
310
digit@chromium.org593eff42013-04-24 10:06:14 +0000311// Extract CPU info string from ARM-specific MDRawSystemInfo structure.
312// raw_info: pointer to source MDRawSystemInfo.
313// cpu_info: address of target string, cpu info text will be appended to it.
314static void GetARMCpuInfo(const MDRawSystemInfo* raw_info,
ivan.penkov@gmail.com8695cc02013-05-11 00:23:41 +0000315 string* cpu_info) {
digit@chromium.org593eff42013-04-24 10:06:14 +0000316 assert(raw_info != NULL && cpu_info != NULL);
317
318 // Write ARM architecture version.
319 char cpu_string[32];
320 snprintf(cpu_string, sizeof(cpu_string), "ARMv%d",
321 raw_info->processor_level);
322 cpu_info->append(cpu_string);
323
324 // There is no good list of implementer id values, but the following
325 // pages provide some help:
326 // http://comments.gmane.org/gmane.linux.linaro.devel/6903
327 // http://forum.xda-developers.com/archive/index.php/t-480226.html
328 const struct {
329 uint32_t id;
330 const char* name;
331 } vendors[] = {
332 { 0x41, "ARM" },
333 { 0x51, "Qualcomm" },
334 { 0x56, "Marvell" },
335 { 0x69, "Intel/Marvell" },
336 };
337 const struct {
338 uint32_t id;
339 const char* name;
340 } parts[] = {
341 { 0x4100c050, "Cortex-A5" },
342 { 0x4100c080, "Cortex-A8" },
343 { 0x4100c090, "Cortex-A9" },
344 { 0x4100c0f0, "Cortex-A15" },
345 { 0x4100c140, "Cortex-R4" },
346 { 0x4100c150, "Cortex-R5" },
347 { 0x4100b360, "ARM1136" },
348 { 0x4100b560, "ARM1156" },
349 { 0x4100b760, "ARM1176" },
350 { 0x4100b020, "ARM11-MPCore" },
351 { 0x41009260, "ARM926" },
352 { 0x41009460, "ARM946" },
353 { 0x41009660, "ARM966" },
354 { 0x510006f0, "Krait" },
355 { 0x510000f0, "Scorpion" },
356 };
357
358 const struct {
359 uint32_t hwcap;
360 const char* name;
361 } features[] = {
362 { MD_CPU_ARM_ELF_HWCAP_SWP, "swp" },
363 { MD_CPU_ARM_ELF_HWCAP_HALF, "half" },
364 { MD_CPU_ARM_ELF_HWCAP_THUMB, "thumb" },
365 { MD_CPU_ARM_ELF_HWCAP_26BIT, "26bit" },
366 { MD_CPU_ARM_ELF_HWCAP_FAST_MULT, "fastmult" },
367 { MD_CPU_ARM_ELF_HWCAP_FPA, "fpa" },
368 { MD_CPU_ARM_ELF_HWCAP_VFP, "vfpv2" },
369 { MD_CPU_ARM_ELF_HWCAP_EDSP, "edsp" },
370 { MD_CPU_ARM_ELF_HWCAP_JAVA, "java" },
371 { MD_CPU_ARM_ELF_HWCAP_IWMMXT, "iwmmxt" },
372 { MD_CPU_ARM_ELF_HWCAP_CRUNCH, "crunch" },
373 { MD_CPU_ARM_ELF_HWCAP_THUMBEE, "thumbee" },
374 { MD_CPU_ARM_ELF_HWCAP_NEON, "neon" },
375 { MD_CPU_ARM_ELF_HWCAP_VFPv3, "vfpv3" },
376 { MD_CPU_ARM_ELF_HWCAP_VFPv3D16, "vfpv3d16" },
377 { MD_CPU_ARM_ELF_HWCAP_TLS, "tls" },
378 { MD_CPU_ARM_ELF_HWCAP_VFPv4, "vfpv4" },
379 { MD_CPU_ARM_ELF_HWCAP_IDIVA, "idiva" },
380 { MD_CPU_ARM_ELF_HWCAP_IDIVT, "idivt" },
381 };
382
383 uint32_t cpuid = raw_info->cpu.arm_cpu_info.cpuid;
384 if (cpuid != 0) {
385 // Extract vendor name from CPUID
386 const char* vendor = NULL;
387 uint32_t vendor_id = (cpuid >> 24) & 0xff;
388 for (size_t i = 0; i < sizeof(vendors)/sizeof(vendors[0]); ++i) {
389 if (vendors[i].id == vendor_id) {
390 vendor = vendors[i].name;
391 break;
392 }
393 }
394 cpu_info->append(" ");
395 if (vendor) {
396 cpu_info->append(vendor);
397 } else {
398 snprintf(cpu_string, sizeof(cpu_string), "vendor(0x%x)", vendor_id);
399 cpu_info->append(cpu_string);
400 }
401
402 // Extract part name from CPUID
403 uint32_t part_id = (cpuid & 0xff00fff0);
404 const char* part = NULL;
405 for (size_t i = 0; i < sizeof(parts)/sizeof(parts[0]); ++i) {
406 if (parts[i].id == part_id) {
407 part = parts[i].name;
408 break;
409 }
410 }
411 cpu_info->append(" ");
412 if (part != NULL) {
413 cpu_info->append(part);
414 } else {
415 snprintf(cpu_string, sizeof(cpu_string), "part(0x%x)", part_id);
416 cpu_info->append(cpu_string);
417 }
418 }
419 uint32_t elf_hwcaps = raw_info->cpu.arm_cpu_info.elf_hwcaps;
420 if (elf_hwcaps != 0) {
421 cpu_info->append(" features: ");
422 const char* comma = "";
423 for (size_t i = 0; i < sizeof(features)/sizeof(features[0]); ++i) {
424 if (elf_hwcaps & features[i].hwcap) {
425 cpu_info->append(comma);
426 cpu_info->append(features[i].name);
427 comma = ",";
428 }
429 }
430 }
431}
432
mmentovaie5468b82006-10-24 19:31:21 +0000433// static
mmentovaiaf3c43f2007-05-17 18:34:37 +0000434bool MinidumpProcessor::GetCPUInfo(Minidump *dump, SystemInfo *info) {
mmentovai97d392d2007-01-10 22:47:56 +0000435 assert(dump);
436 assert(info);
437
438 info->cpu.clear();
439 info->cpu_info.clear();
mmentovaie5468b82006-10-24 19:31:21 +0000440
441 MinidumpSystemInfo *system_info;
442 const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
443 if (!raw_system_info)
mmentovaiaf3c43f2007-05-17 18:34:37 +0000444 return false;
mmentovaie5468b82006-10-24 19:31:21 +0000445
mmentovaie5468b82006-10-24 19:31:21 +0000446 switch (raw_system_info->processor_architecture) {
ted.mielczarek8eb71112007-10-31 19:20:31 +0000447 case MD_CPU_ARCHITECTURE_X86:
448 case MD_CPU_ARCHITECTURE_AMD64: {
nealsidb56cfa02009-05-29 00:53:02 +0000449 if (raw_system_info->processor_architecture ==
ted.mielczarek8eb71112007-10-31 19:20:31 +0000450 MD_CPU_ARCHITECTURE_X86)
451 info->cpu = "x86";
452 else
453 info->cpu = "amd64";
454
mmentovai97d392d2007-01-10 22:47:56 +0000455 const string *cpu_vendor = system_info->GetCPUVendor();
456 if (cpu_vendor) {
457 info->cpu_info = *cpu_vendor;
458 info->cpu_info.append(" ");
mmentovaie5468b82006-10-24 19:31:21 +0000459 }
mmentovai97d392d2007-01-10 22:47:56 +0000460
461 char x86_info[36];
462 snprintf(x86_info, sizeof(x86_info), "family %u model %u stepping %u",
463 raw_system_info->processor_level,
464 raw_system_info->processor_revision >> 8,
465 raw_system_info->processor_revision & 0xff);
466 info->cpu_info.append(x86_info);
mmentovaie5468b82006-10-24 19:31:21 +0000467 break;
468 }
469
470 case MD_CPU_ARCHITECTURE_PPC: {
mmentovai97d392d2007-01-10 22:47:56 +0000471 info->cpu = "ppc";
mmentovaie5468b82006-10-24 19:31:21 +0000472 break;
473 }
474
thestig@chromium.org0c759c62013-04-12 23:24:02 +0000475 case MD_CPU_ARCHITECTURE_PPC64: {
476 info->cpu = "ppc64";
477 break;
478 }
479
mmentovaiea2bba92007-09-26 18:28:05 +0000480 case MD_CPU_ARCHITECTURE_SPARC: {
481 info->cpu = "sparc";
482 break;
483 }
484
ted.mielczarek9276b0d2009-12-19 21:43:53 +0000485 case MD_CPU_ARCHITECTURE_ARM: {
486 info->cpu = "arm";
digit@chromium.org593eff42013-04-24 10:06:14 +0000487 GetARMCpuInfo(raw_system_info, &info->cpu_info);
ted.mielczarek9276b0d2009-12-19 21:43:53 +0000488 break;
489 }
490
mmentovaie5468b82006-10-24 19:31:21 +0000491 default: {
492 // Assign the numeric architecture ID into the CPU string.
493 char cpu_string[7];
494 snprintf(cpu_string, sizeof(cpu_string), "0x%04x",
495 raw_system_info->processor_architecture);
mmentovai97d392d2007-01-10 22:47:56 +0000496 info->cpu = cpu_string;
mmentovaie5468b82006-10-24 19:31:21 +0000497 break;
498 }
brynerd5e66382006-09-08 02:35:53 +0000499 }
mmentovaiaf3c43f2007-05-17 18:34:37 +0000500
ted.mielczarek90e050e2007-05-30 12:14:09 +0000501 info->cpu_count = raw_system_info->number_of_processors;
502
mmentovaiaf3c43f2007-05-17 18:34:37 +0000503 return true;
mmentovaie5468b82006-10-24 19:31:21 +0000504}
505
506// static
mmentovaiaf3c43f2007-05-17 18:34:37 +0000507bool MinidumpProcessor::GetOSInfo(Minidump *dump, SystemInfo *info) {
mmentovai97d392d2007-01-10 22:47:56 +0000508 assert(dump);
509 assert(info);
510
511 info->os.clear();
512 info->os_short.clear();
513 info->os_version.clear();
mmentovaie5468b82006-10-24 19:31:21 +0000514
515 MinidumpSystemInfo *system_info;
516 const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
517 if (!raw_system_info)
mmentovaiaf3c43f2007-05-17 18:34:37 +0000518 return false;
mmentovaie5468b82006-10-24 19:31:21 +0000519
mmentovai97d392d2007-01-10 22:47:56 +0000520 info->os_short = system_info->GetOS();
521
mmentovaie5468b82006-10-24 19:31:21 +0000522 switch (raw_system_info->platform_id) {
523 case MD_OS_WIN32_NT: {
mmentovai97d392d2007-01-10 22:47:56 +0000524 info->os = "Windows NT";
mmentovaie5468b82006-10-24 19:31:21 +0000525 break;
526 }
527
528 case MD_OS_WIN32_WINDOWS: {
mmentovai97d392d2007-01-10 22:47:56 +0000529 info->os = "Windows";
mmentovaie5468b82006-10-24 19:31:21 +0000530 break;
531 }
532
533 case MD_OS_MAC_OS_X: {
mmentovai97d392d2007-01-10 22:47:56 +0000534 info->os = "Mac OS X";
mmentovaie5468b82006-10-24 19:31:21 +0000535 break;
536 }
537
qsr@chromium.orgb9583792011-10-11 14:17:02 +0000538 case MD_OS_IOS: {
539 info->os = "iOS";
540 break;
541 }
542
mmentovaie5468b82006-10-24 19:31:21 +0000543 case MD_OS_LINUX: {
mmentovai97d392d2007-01-10 22:47:56 +0000544 info->os = "Linux";
mmentovaie5468b82006-10-24 19:31:21 +0000545 break;
546 }
547
mmentovaiea2bba92007-09-26 18:28:05 +0000548 case MD_OS_SOLARIS: {
549 info->os = "Solaris";
550 break;
551 }
552
digit@chromium.org8d967072012-07-04 11:56:26 +0000553 case MD_OS_ANDROID: {
554 info->os = "Android";
555 break;
556 }
557
thestig@chromium.org0bdc7142013-04-25 20:36:31 +0000558 case MD_OS_PS3: {
559 info->os = "PS3";
mseaborn@chromium.org85c35262013-05-06 23:33:02 +0000560 break;
561 }
562
563 case MD_OS_NACL: {
564 info->os = "NaCl";
565 break;
thestig@chromium.org0bdc7142013-04-25 20:36:31 +0000566 }
567
mmentovaie5468b82006-10-24 19:31:21 +0000568 default: {
569 // Assign the numeric platform ID into the OS string.
570 char os_string[11];
571 snprintf(os_string, sizeof(os_string), "0x%08x",
572 raw_system_info->platform_id);
mmentovai97d392d2007-01-10 22:47:56 +0000573 info->os = os_string;
mmentovaie5468b82006-10-24 19:31:21 +0000574 break;
575 }
mmentovai960e5272006-09-25 18:29:48 +0000576 }
577
mmentovai97d392d2007-01-10 22:47:56 +0000578 char os_version_string[33];
579 snprintf(os_version_string, sizeof(os_version_string), "%u.%u.%u",
580 raw_system_info->major_version,
581 raw_system_info->minor_version,
582 raw_system_info->build_number);
583 info->os_version = os_version_string;
mmentovaie5468b82006-10-24 19:31:21 +0000584
mmentovai97d392d2007-01-10 22:47:56 +0000585 const string *csd_version = system_info->GetCSDVersion();
586 if (csd_version) {
587 info->os_version.append(" ");
588 info->os_version.append(*csd_version);
mmentovaie5468b82006-10-24 19:31:21 +0000589 }
mmentovaiaf3c43f2007-05-17 18:34:37 +0000590
591 return true;
mmentovaie5468b82006-10-24 19:31:21 +0000592}
593
594// static
ted.mielczarek@gmail.comaeffe102013-03-06 14:04:42 +0000595string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
mmentovaie5468b82006-10-24 19:31:21 +0000596 MinidumpException *exception = dump->GetException();
597 if (!exception)
598 return "";
599
600 const MDRawExceptionStream *raw_exception = exception->exception();
601 if (!raw_exception)
602 return "";
603
604 if (address)
605 *address = raw_exception->exception_record.exception_address;
606
607 // The reason value is OS-specific and possibly CPU-specific. Set up
608 // sensible numeric defaults for the reason string in case we can't
609 // map the codes to a string (because there's no system info, or because
610 // it's an unrecognized platform, or because it's an unrecognized code.)
611 char reason_string[24];
ted.mielczarek@gmail.comaeffe102013-03-06 14:04:42 +0000612 uint32_t exception_code = raw_exception->exception_record.exception_code;
613 uint32_t exception_flags = raw_exception->exception_record.exception_flags;
mmentovaie5468b82006-10-24 19:31:21 +0000614 snprintf(reason_string, sizeof(reason_string), "0x%08x / 0x%08x",
waylonisdaf42112006-12-06 04:58:27 +0000615 exception_code, exception_flags);
mmentovaie5468b82006-10-24 19:31:21 +0000616 string reason = reason_string;
617
618 const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, NULL);
619 if (!raw_system_info)
620 return reason;
621
mmentovai80e98392006-10-25 21:25:41 +0000622 switch (raw_system_info->platform_id) {
qsr@chromium.orgb9583792011-10-11 14:17:02 +0000623 case MD_OS_MAC_OS_X:
624 case MD_OS_IOS: {
waylonisdaf42112006-12-06 04:58:27 +0000625 char flags_string[11];
626 snprintf(flags_string, sizeof(flags_string), "0x%08x", exception_flags);
627 switch (exception_code) {
628 case MD_EXCEPTION_MAC_BAD_ACCESS:
629 reason = "EXC_BAD_ACCESS / ";
630 switch (exception_flags) {
631 case MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS:
632 reason.append("KERN_INVALID_ADDRESS");
633 break;
634 case MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE:
635 reason.append("KERN_PROTECTION_FAILURE");
636 break;
637 case MD_EXCEPTION_CODE_MAC_NO_ACCESS:
638 reason.append("KERN_NO_ACCESS");
639 break;
640 case MD_EXCEPTION_CODE_MAC_MEMORY_FAILURE:
641 reason.append("KERN_MEMORY_FAILURE");
642 break;
643 case MD_EXCEPTION_CODE_MAC_MEMORY_ERROR:
644 reason.append("KERN_MEMORY_ERROR");
645 break;
waylonisdaf42112006-12-06 04:58:27 +0000646 default:
qsr@chromium.org6446cfc2012-09-25 08:30:48 +0000647 // arm and ppc overlap
648 if (raw_system_info->processor_architecture ==
649 MD_CPU_ARCHITECTURE_ARM) {
650 switch (exception_flags) {
651 case MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN:
652 reason.append("EXC_ARM_DA_ALIGN");
653 break;
654 case MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG:
655 reason.append("EXC_ARM_DA_DEBUG");
656 break;
657 default:
658 reason.append(flags_string);
659 BPLOG(INFO) << "Unknown exception reason " << reason;
660 break;
661 }
662 } else if (raw_system_info->processor_architecture ==
663 MD_CPU_ARCHITECTURE_PPC) {
664 switch (exception_flags) {
665 case MD_EXCEPTION_CODE_MAC_PPC_VM_PROT_READ:
666 reason.append("EXC_PPC_VM_PROT_READ");
667 break;
668 case MD_EXCEPTION_CODE_MAC_PPC_BADSPACE:
669 reason.append("EXC_PPC_BADSPACE");
670 break;
671 case MD_EXCEPTION_CODE_MAC_PPC_UNALIGNED:
672 reason.append("EXC_PPC_UNALIGNED");
673 break;
674 default:
675 reason.append(flags_string);
676 BPLOG(INFO) << "Unknown exception reason " << reason;
677 break;
678 }
679 } else {
680 reason.append(flags_string);
681 BPLOG(INFO) << "Unknown exception reason " << reason;
682 }
waylonisdaf42112006-12-06 04:58:27 +0000683 break;
684 }
685 break;
686 case MD_EXCEPTION_MAC_BAD_INSTRUCTION:
687 reason = "EXC_BAD_INSTRUCTION / ";
688 switch (raw_system_info->processor_architecture) {
qsr@chromium.org6446cfc2012-09-25 08:30:48 +0000689 case MD_CPU_ARCHITECTURE_ARM: {
690 switch (exception_flags) {
691 case MD_EXCEPTION_CODE_MAC_ARM_UNDEFINED:
692 reason.append("EXC_ARM_UNDEFINED");
693 break;
694 default:
695 reason.append(flags_string);
696 BPLOG(INFO) << "Unknown exception reason " << reason;
697 break;
698 }
699 break;
700 }
waylonisdaf42112006-12-06 04:58:27 +0000701 case MD_CPU_ARCHITECTURE_PPC: {
702 switch (exception_flags) {
703 case MD_EXCEPTION_CODE_MAC_PPC_INVALID_SYSCALL:
704 reason.append("EXC_PPC_INVALID_SYSCALL");
705 break;
706 case MD_EXCEPTION_CODE_MAC_PPC_UNIMPLEMENTED_INSTRUCTION:
707 reason.append("EXC_PPC_UNIPL_INST");
708 break;
709 case MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_INSTRUCTION:
710 reason.append("EXC_PPC_PRIVINST");
711 break;
712 case MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_REGISTER:
713 reason.append("EXC_PPC_PRIVREG");
714 break;
715 case MD_EXCEPTION_CODE_MAC_PPC_TRACE:
716 reason.append("EXC_PPC_TRACE");
717 break;
718 case MD_EXCEPTION_CODE_MAC_PPC_PERFORMANCE_MONITOR:
719 reason.append("EXC_PPC_PERFMON");
720 break;
721 default:
722 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000723 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000724 break;
725 }
726 break;
727 }
728 case MD_CPU_ARCHITECTURE_X86: {
729 switch (exception_flags) {
730 case MD_EXCEPTION_CODE_MAC_X86_INVALID_OPERATION:
731 reason.append("EXC_I386_INVOP");
732 break;
733 case MD_EXCEPTION_CODE_MAC_X86_INVALID_TASK_STATE_SEGMENT:
734 reason.append("EXC_INVTSSFLT");
735 break;
736 case MD_EXCEPTION_CODE_MAC_X86_SEGMENT_NOT_PRESENT:
737 reason.append("EXC_SEGNPFLT");
738 break;
739 case MD_EXCEPTION_CODE_MAC_X86_STACK_FAULT:
740 reason.append("EXC_STKFLT");
741 break;
742 case MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT:
743 reason.append("EXC_GPFLT");
744 break;
745 case MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT:
746 reason.append("EXC_ALIGNFLT");
747 break;
748 default:
749 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000750 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000751 break;
752 }
753 break;
754 }
755 default:
756 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000757 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000758 break;
759 }
760 break;
761 case MD_EXCEPTION_MAC_ARITHMETIC:
762 reason = "EXC_ARITHMETIC / ";
763 switch (raw_system_info->processor_architecture) {
764 case MD_CPU_ARCHITECTURE_PPC: {
765 switch (exception_flags) {
766 case MD_EXCEPTION_CODE_MAC_PPC_OVERFLOW:
767 reason.append("EXC_PPC_OVERFLOW");
768 break;
769 case MD_EXCEPTION_CODE_MAC_PPC_ZERO_DIVIDE:
770 reason.append("EXC_PPC_ZERO_DIVIDE");
771 break;
772 case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_INEXACT:
773 reason.append("EXC_FLT_INEXACT");
774 break;
775 case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_ZERO_DIVIDE:
776 reason.append("EXC_PPC_FLT_ZERO_DIVIDE");
777 break;
778 case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_UNDERFLOW:
779 reason.append("EXC_PPC_FLT_UNDERFLOW");
780 break;
781 case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_OVERFLOW:
782 reason.append("EXC_PPC_FLT_OVERFLOW");
783 break;
784 case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_NOT_A_NUMBER:
785 reason.append("EXC_PPC_FLT_NOT_A_NUMBER");
786 break;
787 case MD_EXCEPTION_CODE_MAC_PPC_NO_EMULATION:
788 reason.append("EXC_PPC_NOEMULATION");
789 break;
790 case MD_EXCEPTION_CODE_MAC_PPC_ALTIVEC_ASSIST:
791 reason.append("EXC_PPC_ALTIVECASSIST");
792 default:
793 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000794 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000795 break;
796 }
797 break;
798 }
799 case MD_CPU_ARCHITECTURE_X86: {
800 switch (exception_flags) {
801 case MD_EXCEPTION_CODE_MAC_X86_DIV:
802 reason.append("EXC_I386_DIV");
803 break;
804 case MD_EXCEPTION_CODE_MAC_X86_INTO:
805 reason.append("EXC_I386_INTO");
806 break;
807 case MD_EXCEPTION_CODE_MAC_X86_NOEXT:
808 reason.append("EXC_I386_NOEXT");
809 break;
810 case MD_EXCEPTION_CODE_MAC_X86_EXTOVR:
811 reason.append("EXC_I386_EXTOVR");
812 break;
813 case MD_EXCEPTION_CODE_MAC_X86_EXTERR:
814 reason.append("EXC_I386_EXTERR");
815 break;
816 case MD_EXCEPTION_CODE_MAC_X86_EMERR:
817 reason.append("EXC_I386_EMERR");
818 break;
819 case MD_EXCEPTION_CODE_MAC_X86_BOUND:
820 reason.append("EXC_I386_BOUND");
821 break;
822 case MD_EXCEPTION_CODE_MAC_X86_SSEEXTERR:
823 reason.append("EXC_I386_SSEEXTERR");
824 break;
825 default:
826 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000827 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000828 break;
829 }
830 break;
831 }
832 default:
833 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000834 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000835 break;
836 }
837 break;
838 case MD_EXCEPTION_MAC_EMULATION:
839 reason = "EXC_EMULATION / ";
840 reason.append(flags_string);
841 break;
842 case MD_EXCEPTION_MAC_SOFTWARE:
843 reason = "EXC_SOFTWARE / ";
844 switch (exception_flags) {
qsr@chromium.org1e8d2d52012-03-13 20:02:40 +0000845 case MD_EXCEPTION_CODE_MAC_ABORT:
846 reason.append("SIGABRT");
847 break;
848 case MD_EXCEPTION_CODE_MAC_NS_EXCEPTION:
849 reason.append("UNCAUGHT_NS_EXCEPTION");
850 break;
waylonisdaf42112006-12-06 04:58:27 +0000851 // These are ppc only but shouldn't be a problem as they're
852 // unused on x86
853 case MD_EXCEPTION_CODE_MAC_PPC_TRAP:
854 reason.append("EXC_PPC_TRAP");
855 break;
856 case MD_EXCEPTION_CODE_MAC_PPC_MIGRATE:
857 reason.append("EXC_PPC_MIGRATE");
858 break;
859 default:
860 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000861 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000862 break;
863 }
864 break;
865 case MD_EXCEPTION_MAC_BREAKPOINT:
866 reason = "EXC_BREAKPOINT / ";
867 switch (raw_system_info->processor_architecture) {
qsr@chromium.org6446cfc2012-09-25 08:30:48 +0000868 case MD_CPU_ARCHITECTURE_ARM: {
869 switch (exception_flags) {
870 case MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN:
871 reason.append("EXC_ARM_DA_ALIGN");
872 break;
873 case MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG:
874 reason.append("EXC_ARM_DA_DEBUG");
875 break;
876 case MD_EXCEPTION_CODE_MAC_ARM_BREAKPOINT:
877 reason.append("EXC_ARM_BREAKPOINT");
878 break;
879 default:
880 reason.append(flags_string);
881 BPLOG(INFO) << "Unknown exception reason " << reason;
882 break;
883 }
884 break;
885 }
waylonisdaf42112006-12-06 04:58:27 +0000886 case MD_CPU_ARCHITECTURE_PPC: {
887 switch (exception_flags) {
888 case MD_EXCEPTION_CODE_MAC_PPC_BREAKPOINT:
889 reason.append("EXC_PPC_BREAKPOINT");
890 break;
891 default:
892 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000893 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000894 break;
895 }
896 break;
897 }
898 case MD_CPU_ARCHITECTURE_X86: {
899 switch (exception_flags) {
900 case MD_EXCEPTION_CODE_MAC_X86_SGL:
901 reason.append("EXC_I386_SGL");
902 break;
903 case MD_EXCEPTION_CODE_MAC_X86_BPT:
904 reason.append("EXC_I386_BPT");
905 break;
906 default:
907 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000908 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000909 break;
910 }
911 break;
912 }
913 default:
914 reason.append(flags_string);
mmentovaiaf3c43f2007-05-17 18:34:37 +0000915 BPLOG(INFO) << "Unknown exception reason " << reason;
waylonisdaf42112006-12-06 04:58:27 +0000916 break;
917 }
918 break;
919 case MD_EXCEPTION_MAC_SYSCALL:
920 reason = "EXC_SYSCALL / ";
921 reason.append(flags_string);
922 break;
923 case MD_EXCEPTION_MAC_MACH_SYSCALL:
924 reason = "EXC_MACH_SYSCALL / ";
925 reason.append(flags_string);
926 break;
927 case MD_EXCEPTION_MAC_RPC_ALERT:
928 reason = "EXC_RPC_ALERT / ";
929 reason.append(flags_string);
930 break;
931 }
932 break;
933 }
934
mmentovaie5468b82006-10-24 19:31:21 +0000935 case MD_OS_WIN32_NT:
936 case MD_OS_WIN32_WINDOWS: {
waylonisdaf42112006-12-06 04:58:27 +0000937 switch (exception_code) {
mmentovaie5468b82006-10-24 19:31:21 +0000938 case MD_EXCEPTION_CODE_WIN_CONTROL_C:
939 reason = "DBG_CONTROL_C";
940 break;
941 case MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION:
942 reason = "EXCEPTION_GUARD_PAGE";
943 break;
944 case MD_EXCEPTION_CODE_WIN_DATATYPE_MISALIGNMENT:
945 reason = "EXCEPTION_DATATYPE_MISALIGNMENT";
946 break;
947 case MD_EXCEPTION_CODE_WIN_BREAKPOINT:
948 reason = "EXCEPTION_BREAKPOINT";
949 break;
950 case MD_EXCEPTION_CODE_WIN_SINGLE_STEP:
951 reason = "EXCEPTION_SINGLE_STEP";
952 break;
953 case MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION:
954 // For EXCEPTION_ACCESS_VIOLATION, Windows puts the address that
955 // caused the fault in exception_information[1].
956 // exception_information[0] is 0 if the violation was caused by
957 // an attempt to read data and 1 if it was an attempt to write
958 // data.
959 // This information is useful in addition to the code address, which
960 // will be present in the crash thread's instruction field anyway.
nealsid4f182c72010-06-04 16:59:23 +0000961 if (raw_exception->exception_record.number_parameters >= 1) {
cdn@chromium.orgcec12872010-09-22 02:37:19 +0000962 MDAccessViolationTypeWin av_type =
963 static_cast<MDAccessViolationTypeWin>
964 (raw_exception->exception_record.exception_information[0]);
965 switch (av_type) {
966 case MD_ACCESS_VIOLATION_WIN_READ:
nealsid4f182c72010-06-04 16:59:23 +0000967 reason = "EXCEPTION_ACCESS_VIOLATION_READ";
968 break;
cdn@chromium.orgcec12872010-09-22 02:37:19 +0000969 case MD_ACCESS_VIOLATION_WIN_WRITE:
nealsid4f182c72010-06-04 16:59:23 +0000970 reason = "EXCEPTION_ACCESS_VIOLATION_WRITE";
971 break;
cdn@chromium.orgcec12872010-09-22 02:37:19 +0000972 case MD_ACCESS_VIOLATION_WIN_EXEC:
nealsid4f182c72010-06-04 16:59:23 +0000973 reason = "EXCEPTION_ACCESS_VIOLATION_EXEC";
974 break;
975 default:
976 reason = "EXCEPTION_ACCESS_VIOLATION";
977 break;
978 }
979 } else {
980 reason = "EXCEPTION_ACCESS_VIOLATION";
981 }
mmentovaie5468b82006-10-24 19:31:21 +0000982 if (address &&
983 raw_exception->exception_record.number_parameters >= 2) {
984 *address =
985 raw_exception->exception_record.exception_information[1];
986 }
987 break;
988 case MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR:
989 reason = "EXCEPTION_IN_PAGE_ERROR";
990 break;
991 case MD_EXCEPTION_CODE_WIN_INVALID_HANDLE:
992 reason = "EXCEPTION_INVALID_HANDLE";
993 break;
994 case MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION:
995 reason = "EXCEPTION_ILLEGAL_INSTRUCTION";
996 break;
997 case MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION:
998 reason = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
999 break;
1000 case MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION:
1001 reason = "EXCEPTION_INVALID_DISPOSITION";
1002 break;
1003 case MD_EXCEPTION_CODE_WIN_ARRAY_BOUNDS_EXCEEDED:
1004 reason = "EXCEPTION_BOUNDS_EXCEEDED";
1005 break;
1006 case MD_EXCEPTION_CODE_WIN_FLOAT_DENORMAL_OPERAND:
1007 reason = "EXCEPTION_FLT_DENORMAL_OPERAND";
1008 break;
1009 case MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO:
1010 reason = "EXCEPTION_FLT_DIVIDE_BY_ZERO";
1011 break;
1012 case MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT:
1013 reason = "EXCEPTION_FLT_INEXACT_RESULT";
1014 break;
1015 case MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION:
1016 reason = "EXCEPTION_FLT_INVALID_OPERATION";
1017 break;
1018 case MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW:
1019 reason = "EXCEPTION_FLT_OVERFLOW";
1020 break;
1021 case MD_EXCEPTION_CODE_WIN_FLOAT_STACK_CHECK:
1022 reason = "EXCEPTION_FLT_STACK_CHECK";
1023 break;
1024 case MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW:
1025 reason = "EXCEPTION_FLT_UNDERFLOW";
1026 break;
1027 case MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO:
1028 reason = "EXCEPTION_INT_DIVIDE_BY_ZERO";
1029 break;
1030 case MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW:
1031 reason = "EXCEPTION_INT_OVERFLOW";
1032 break;
1033 case MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION:
1034 reason = "EXCEPTION_PRIV_INSTRUCTION";
1035 break;
1036 case MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW:
1037 reason = "EXCEPTION_STACK_OVERFLOW";
1038 break;
1039 case MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK:
1040 reason = "EXCEPTION_POSSIBLE_DEADLOCK";
1041 break;
nealsid4f182c72010-06-04 16:59:23 +00001042 case MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN:
1043 reason = "EXCEPTION_STACK_BUFFER_OVERRUN";
1044 break;
1045 case MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION:
1046 reason = "EXCEPTION_HEAP_CORRUPTION";
1047 break;
ted.mielczarekb2bc3bc2009-09-04 20:00:33 +00001048 case MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION:
cdn@chromium.orgcec12872010-09-22 02:37:19 +00001049 reason = "Unhandled C++ Exception";
1050 break;
mmentovaiaf3c43f2007-05-17 18:34:37 +00001051 default:
1052 BPLOG(INFO) << "Unknown exception reason " << reason;
1053 break;
mmentovaie5468b82006-10-24 19:31:21 +00001054 }
mmentovaiaf3c43f2007-05-17 18:34:37 +00001055 break;
mmentovai278946c2007-09-26 18:13:38 +00001056 }
ted.mielczarekb5c78cc2007-06-11 17:03:30 +00001057
digit@chromium.org8d967072012-07-04 11:56:26 +00001058 case MD_OS_ANDROID:
mmentovai278946c2007-09-26 18:13:38 +00001059 case MD_OS_LINUX: {
ted.mielczarekb5c78cc2007-06-11 17:03:30 +00001060 switch (exception_code) {
1061 case MD_EXCEPTION_CODE_LIN_SIGHUP:
1062 reason = "SIGHUP";
1063 break;
1064 case MD_EXCEPTION_CODE_LIN_SIGINT:
1065 reason = "SIGINT";
1066 break;
1067 case MD_EXCEPTION_CODE_LIN_SIGQUIT:
1068 reason = "SIGQUIT";
1069 break;
1070 case MD_EXCEPTION_CODE_LIN_SIGILL:
1071 reason = "SIGILL";
1072 break;
1073 case MD_EXCEPTION_CODE_LIN_SIGTRAP:
1074 reason = "SIGTRAP";
1075 break;
1076 case MD_EXCEPTION_CODE_LIN_SIGABRT:
1077 reason = "SIGABRT";
1078 break;
1079 case MD_EXCEPTION_CODE_LIN_SIGBUS:
1080 reason = "SIGBUS";
1081 break;
1082 case MD_EXCEPTION_CODE_LIN_SIGFPE:
1083 reason = "SIGFPE";
1084 break;
1085 case MD_EXCEPTION_CODE_LIN_SIGKILL:
1086 reason = "SIGKILL";
1087 break;
1088 case MD_EXCEPTION_CODE_LIN_SIGUSR1:
1089 reason = "SIGUSR1";
1090 break;
1091 case MD_EXCEPTION_CODE_LIN_SIGSEGV:
1092 reason = "SIGSEGV";
1093 break;
1094 case MD_EXCEPTION_CODE_LIN_SIGUSR2:
1095 reason = "SIGUSR2";
1096 break;
1097 case MD_EXCEPTION_CODE_LIN_SIGPIPE:
1098 reason = "SIGPIPE";
1099 break;
1100 case MD_EXCEPTION_CODE_LIN_SIGALRM:
1101 reason = "SIGALRM";
1102 break;
1103 case MD_EXCEPTION_CODE_LIN_SIGTERM:
1104 reason = "SIGTERM";
1105 break;
1106 case MD_EXCEPTION_CODE_LIN_SIGSTKFLT:
1107 reason = "SIGSTKFLT";
1108 break;
1109 case MD_EXCEPTION_CODE_LIN_SIGCHLD:
1110 reason = "SIGCHLD";
1111 break;
1112 case MD_EXCEPTION_CODE_LIN_SIGCONT:
1113 reason = "SIGCONT";
1114 break;
1115 case MD_EXCEPTION_CODE_LIN_SIGSTOP:
1116 reason = "SIGSTOP";
1117 break;
1118 case MD_EXCEPTION_CODE_LIN_SIGTSTP:
1119 reason = "SIGTSTP";
1120 break;
1121 case MD_EXCEPTION_CODE_LIN_SIGTTIN:
1122 reason = "SIGTTIN";
1123 break;
1124 case MD_EXCEPTION_CODE_LIN_SIGTTOU:
1125 reason = "SIGTTOU";
1126 break;
1127 case MD_EXCEPTION_CODE_LIN_SIGURG:
1128 reason = "SIGURG";
1129 break;
1130 case MD_EXCEPTION_CODE_LIN_SIGXCPU:
1131 reason = "SIGXCPU";
1132 break;
1133 case MD_EXCEPTION_CODE_LIN_SIGXFSZ:
1134 reason = "SIGXFSZ";
1135 break;
1136 case MD_EXCEPTION_CODE_LIN_SIGVTALRM:
1137 reason = "SIGVTALRM";
1138 break;
1139 case MD_EXCEPTION_CODE_LIN_SIGPROF:
1140 reason = "SIGPROF";
1141 break;
1142 case MD_EXCEPTION_CODE_LIN_SIGWINCH:
1143 reason = "SIGWINCH";
1144 break;
1145 case MD_EXCEPTION_CODE_LIN_SIGIO:
1146 reason = "SIGIO";
1147 break;
1148 case MD_EXCEPTION_CODE_LIN_SIGPWR:
1149 reason = "SIGPWR";
1150 break;
1151 case MD_EXCEPTION_CODE_LIN_SIGSYS:
1152 reason = "SIGSYS";
1153 break;
ted.mielczarek@gmail.com67364c12012-09-18 18:51:56 +00001154 case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED:
1155 reason = "DUMP_REQUESTED";
1156 break;
ted.mielczarekb5c78cc2007-06-11 17:03:30 +00001157 default:
1158 BPLOG(INFO) << "Unknown exception reason " << reason;
1159 break;
1160 }
1161 break;
mmentovaiaf3c43f2007-05-17 18:34:37 +00001162 }
1163
mmentovaiea2bba92007-09-26 18:28:05 +00001164 case MD_OS_SOLARIS: {
1165 switch (exception_code) {
1166 case MD_EXCEPTION_CODE_SOL_SIGHUP:
1167 reason = "SIGHUP";
1168 break;
1169 case MD_EXCEPTION_CODE_SOL_SIGINT:
1170 reason = "SIGINT";
1171 break;
1172 case MD_EXCEPTION_CODE_SOL_SIGQUIT:
1173 reason = "SIGQUIT";
nealsidb56cfa02009-05-29 00:53:02 +00001174 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001175 case MD_EXCEPTION_CODE_SOL_SIGILL:
1176 reason = "SIGILL";
nealsidb56cfa02009-05-29 00:53:02 +00001177 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001178 case MD_EXCEPTION_CODE_SOL_SIGTRAP:
1179 reason = "SIGTRAP";
nealsidb56cfa02009-05-29 00:53:02 +00001180 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001181 case MD_EXCEPTION_CODE_SOL_SIGIOT:
1182 reason = "SIGIOT | SIGABRT";
nealsidb56cfa02009-05-29 00:53:02 +00001183 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001184 case MD_EXCEPTION_CODE_SOL_SIGEMT:
1185 reason = "SIGEMT";
nealsidb56cfa02009-05-29 00:53:02 +00001186 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001187 case MD_EXCEPTION_CODE_SOL_SIGFPE:
1188 reason = "SIGFPE";
nealsidb56cfa02009-05-29 00:53:02 +00001189 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001190 case MD_EXCEPTION_CODE_SOL_SIGKILL:
1191 reason = "SIGKILL";
nealsidb56cfa02009-05-29 00:53:02 +00001192 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001193 case MD_EXCEPTION_CODE_SOL_SIGBUS:
1194 reason = "SIGBUS";
nealsidb56cfa02009-05-29 00:53:02 +00001195 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001196 case MD_EXCEPTION_CODE_SOL_SIGSEGV:
1197 reason = "SIGSEGV";
nealsidb56cfa02009-05-29 00:53:02 +00001198 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001199 case MD_EXCEPTION_CODE_SOL_SIGSYS:
1200 reason = "SIGSYS";
nealsidb56cfa02009-05-29 00:53:02 +00001201 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001202 case MD_EXCEPTION_CODE_SOL_SIGPIPE:
1203 reason = "SIGPIPE";
nealsidb56cfa02009-05-29 00:53:02 +00001204 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001205 case MD_EXCEPTION_CODE_SOL_SIGALRM:
1206 reason = "SIGALRM";
nealsidb56cfa02009-05-29 00:53:02 +00001207 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001208 case MD_EXCEPTION_CODE_SOL_SIGTERM:
1209 reason = "SIGTERM";
nealsidb56cfa02009-05-29 00:53:02 +00001210 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001211 case MD_EXCEPTION_CODE_SOL_SIGUSR1:
1212 reason = "SIGUSR1";
nealsidb56cfa02009-05-29 00:53:02 +00001213 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001214 case MD_EXCEPTION_CODE_SOL_SIGUSR2:
1215 reason = "SIGUSR2";
nealsidb56cfa02009-05-29 00:53:02 +00001216 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001217 case MD_EXCEPTION_CODE_SOL_SIGCLD:
1218 reason = "SIGCLD | SIGCHLD";
nealsidb56cfa02009-05-29 00:53:02 +00001219 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001220 case MD_EXCEPTION_CODE_SOL_SIGPWR:
1221 reason = "SIGPWR";
nealsidb56cfa02009-05-29 00:53:02 +00001222 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001223 case MD_EXCEPTION_CODE_SOL_SIGWINCH:
1224 reason = "SIGWINCH";
nealsidb56cfa02009-05-29 00:53:02 +00001225 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001226 case MD_EXCEPTION_CODE_SOL_SIGURG:
1227 reason = "SIGURG";
nealsidb56cfa02009-05-29 00:53:02 +00001228 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001229 case MD_EXCEPTION_CODE_SOL_SIGPOLL:
1230 reason = "SIGPOLL | SIGIO";
nealsidb56cfa02009-05-29 00:53:02 +00001231 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001232 case MD_EXCEPTION_CODE_SOL_SIGSTOP:
1233 reason = "SIGSTOP";
nealsidb56cfa02009-05-29 00:53:02 +00001234 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001235 case MD_EXCEPTION_CODE_SOL_SIGTSTP:
1236 reason = "SIGTSTP";
nealsidb56cfa02009-05-29 00:53:02 +00001237 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001238 case MD_EXCEPTION_CODE_SOL_SIGCONT:
1239 reason = "SIGCONT";
nealsidb56cfa02009-05-29 00:53:02 +00001240 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001241 case MD_EXCEPTION_CODE_SOL_SIGTTIN:
1242 reason = "SIGTTIN";
nealsidb56cfa02009-05-29 00:53:02 +00001243 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001244 case MD_EXCEPTION_CODE_SOL_SIGTTOU:
1245 reason = "SIGTTOU";
nealsidb56cfa02009-05-29 00:53:02 +00001246 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001247 case MD_EXCEPTION_CODE_SOL_SIGVTALRM:
1248 reason = "SIGVTALRM";
nealsidb56cfa02009-05-29 00:53:02 +00001249 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001250 case MD_EXCEPTION_CODE_SOL_SIGPROF:
1251 reason = "SIGPROF";
nealsidb56cfa02009-05-29 00:53:02 +00001252 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001253 case MD_EXCEPTION_CODE_SOL_SIGXCPU:
1254 reason = "SIGXCPU";
nealsidb56cfa02009-05-29 00:53:02 +00001255 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001256 case MD_EXCEPTION_CODE_SOL_SIGXFSZ:
1257 reason = "SIGXFSZ";
nealsidb56cfa02009-05-29 00:53:02 +00001258 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001259 case MD_EXCEPTION_CODE_SOL_SIGWAITING:
1260 reason = "SIGWAITING";
nealsidb56cfa02009-05-29 00:53:02 +00001261 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001262 case MD_EXCEPTION_CODE_SOL_SIGLWP:
1263 reason = "SIGLWP";
nealsidb56cfa02009-05-29 00:53:02 +00001264 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001265 case MD_EXCEPTION_CODE_SOL_SIGFREEZE:
1266 reason = "SIGFREEZE";
nealsidb56cfa02009-05-29 00:53:02 +00001267 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001268 case MD_EXCEPTION_CODE_SOL_SIGTHAW:
1269 reason = "SIGTHAW";
nealsidb56cfa02009-05-29 00:53:02 +00001270 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001271 case MD_EXCEPTION_CODE_SOL_SIGCANCEL:
1272 reason = "SIGCANCEL";
nealsidb56cfa02009-05-29 00:53:02 +00001273 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001274 case MD_EXCEPTION_CODE_SOL_SIGLOST:
1275 reason = "SIGLOST";
nealsidb56cfa02009-05-29 00:53:02 +00001276 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001277 case MD_EXCEPTION_CODE_SOL_SIGXRES:
1278 reason = "SIGXRES";
nealsidb56cfa02009-05-29 00:53:02 +00001279 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001280 case MD_EXCEPTION_CODE_SOL_SIGJVM1:
1281 reason = "SIGJVM1";
nealsidb56cfa02009-05-29 00:53:02 +00001282 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001283 case MD_EXCEPTION_CODE_SOL_SIGJVM2:
1284 reason = "SIGJVM2";
nealsidb56cfa02009-05-29 00:53:02 +00001285 break;
mmentovaiea2bba92007-09-26 18:28:05 +00001286 default:
1287 BPLOG(INFO) << "Unknown exception reason " << reason;
1288 break;
1289 }
1290 break;
1291 }
1292
thestig@chromium.org0bdc7142013-04-25 20:36:31 +00001293 case MD_OS_PS3: {
1294 switch (exception_code) {
1295 case MD_EXCEPTION_CODE_PS3_UNKNOWN:
1296 reason = "UNKNOWN";
1297 break;
1298 case MD_EXCEPTION_CODE_PS3_TRAP_EXCEP:
1299 reason = "TRAP_EXCEP";
1300 break;
1301 case MD_EXCEPTION_CODE_PS3_PRIV_INSTR:
1302 reason = "PRIV_INSTR";
1303 break;
1304 case MD_EXCEPTION_CODE_PS3_ILLEGAL_INSTR:
1305 reason = "ILLEGAL_INSTR";
1306 break;
1307 case MD_EXCEPTION_CODE_PS3_INSTR_STORAGE:
1308 reason = "INSTR_STORAGE";
1309 break;
1310 case MD_EXCEPTION_CODE_PS3_INSTR_SEGMENT:
1311 reason = "INSTR_SEGMENT";
1312 break;
1313 case MD_EXCEPTION_CODE_PS3_DATA_STORAGE:
1314 reason = "DATA_STORAGE";
1315 break;
1316 case MD_EXCEPTION_CODE_PS3_DATA_SEGMENT:
1317 reason = "DATA_SEGMENT";
1318 break;
1319 case MD_EXCEPTION_CODE_PS3_FLOAT_POINT:
1320 reason = "FLOAT_POINT";
1321 break;
1322 case MD_EXCEPTION_CODE_PS3_DABR_MATCH:
1323 reason = "DABR_MATCH";
1324 break;
1325 case MD_EXCEPTION_CODE_PS3_ALIGN_EXCEP:
1326 reason = "ALIGN_EXCEP";
1327 break;
1328 case MD_EXCEPTION_CODE_PS3_MEMORY_ACCESS:
1329 reason = "MEMORY_ACCESS";
1330 break;
1331 case MD_EXCEPTION_CODE_PS3_COPRO_ALIGN:
1332 reason = "COPRO_ALIGN";
1333 break;
1334 case MD_EXCEPTION_CODE_PS3_COPRO_INVALID_COM:
1335 reason = "COPRO_INVALID_COM";
1336 break;
1337 case MD_EXCEPTION_CODE_PS3_COPRO_ERR:
1338 reason = "COPRO_ERR";
1339 break;
1340 case MD_EXCEPTION_CODE_PS3_COPRO_FIR:
1341 reason = "COPRO_FIR";
1342 break;
1343 case MD_EXCEPTION_CODE_PS3_COPRO_DATA_SEGMENT:
1344 reason = "COPRO_DATA_SEGMENT";
1345 break;
1346 case MD_EXCEPTION_CODE_PS3_COPRO_DATA_STORAGE:
1347 reason = "COPRO_DATA_STORAGE";
1348 break;
1349 case MD_EXCEPTION_CODE_PS3_COPRO_STOP_INSTR:
1350 reason = "COPRO_STOP_INSTR";
1351 break;
1352 case MD_EXCEPTION_CODE_PS3_COPRO_HALT_INSTR:
1353 reason = "COPRO_HALT_INSTR";
1354 break;
1355 case MD_EXCEPTION_CODE_PS3_COPRO_HALTINST_UNKNOWN:
1356 reason = "COPRO_HALTINSTR_UNKNOWN";
1357 break;
1358 case MD_EXCEPTION_CODE_PS3_COPRO_MEMORY_ACCESS:
1359 reason = "COPRO_MEMORY_ACCESS";
1360 break;
1361 case MD_EXCEPTION_CODE_PS3_GRAPHIC:
1362 reason = "GRAPHIC";
1363 break;
1364 default:
1365 BPLOG(INFO) << "Unknown exception reason "<< reason;
1366 break;
1367 }
1368 break;
1369 }
1370
mmentovaiaf3c43f2007-05-17 18:34:37 +00001371 default: {
1372 BPLOG(INFO) << "Unknown exception reason " << reason;
1373 break;
mmentovaie5468b82006-10-24 19:31:21 +00001374 }
1375 }
1376
1377 return reason;
brynerd5e66382006-09-08 02:35:53 +00001378}
1379
ted.mielczarek0314e482009-12-02 17:43:57 +00001380// static
cdn@chromium.orgcec12872010-09-22 02:37:19 +00001381string MinidumpProcessor::GetAssertion(Minidump *dump) {
ted.mielczarek0314e482009-12-02 17:43:57 +00001382 MinidumpAssertion *assertion = dump->GetAssertion();
1383 if (!assertion)
1384 return "";
1385
1386 const MDRawAssertionInfo *raw_assertion = assertion->assertion();
1387 if (!raw_assertion)
1388 return "";
1389
1390 string assertion_string;
1391 switch (raw_assertion->type) {
1392 case MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER:
1393 assertion_string = "Invalid parameter passed to library function";
1394 break;
1395 case MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL:
1396 assertion_string = "Pure virtual function called";
1397 break;
1398 default: {
1399 char assertion_type[32];
SiyangXie@gmail.combab77002012-10-10 21:41:52 +00001400 snprintf(assertion_type, sizeof(assertion_type),
1401 "0x%08x", raw_assertion->type);
ted.mielczarek0314e482009-12-02 17:43:57 +00001402 assertion_string = "Unknown assertion type ";
1403 assertion_string += assertion_type;
1404 break;
1405 }
1406 }
1407
1408 string expression = assertion->expression();
1409 if (!expression.empty()) {
1410 assertion_string.append(" " + expression);
1411 }
1412
1413 string function = assertion->function();
1414 if (!function.empty()) {
1415 assertion_string.append(" in function " + function);
1416 }
1417
1418 string file = assertion->file();
1419 if (!file.empty()) {
1420 assertion_string.append(", in file " + file);
1421 }
1422
1423 if (raw_assertion->line != 0) {
1424 char assertion_line[32];
SiyangXie@gmail.combab77002012-10-10 21:41:52 +00001425 snprintf(assertion_line, sizeof(assertion_line), "%u", raw_assertion->line);
ted.mielczarek0314e482009-12-02 17:43:57 +00001426 assertion_string.append(" at line ");
1427 assertion_string.append(assertion_line);
1428 }
1429
1430 return assertion_string;
1431}
1432
mmentovaie5dc6082007-02-14 19:51:05 +00001433} // namespace google_breakpad