Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: src/client/linux/microdump_writer/microdump_writer.cc

Issue 1334473003: Add GPU fingerprint information to breakpad microdumps. (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Final nits. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, Google Inc. 1 // Copyright (c) 2014, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 19 matching lines...) Expand all
30 // This translation unit generates microdumps into the console (logcat on 30 // This translation unit generates microdumps into the console (logcat on
31 // Android). See crbug.com/410294 for more info and design docs. 31 // Android). See crbug.com/410294 for more info and design docs.
32 32
33 #include "client/linux/microdump_writer/microdump_writer.h" 33 #include "client/linux/microdump_writer/microdump_writer.h"
34 34
35 #include <sys/utsname.h> 35 #include <sys/utsname.h>
36 36
37 #include "client/linux/dump_writer_common/thread_info.h" 37 #include "client/linux/dump_writer_common/thread_info.h"
38 #include "client/linux/dump_writer_common/ucontext_reader.h" 38 #include "client/linux/dump_writer_common/ucontext_reader.h"
39 #include "client/linux/handler/exception_handler.h" 39 #include "client/linux/handler/exception_handler.h"
40 #include "client/linux/handler/microdump_extra_info.h"
40 #include "client/linux/log/log.h" 41 #include "client/linux/log/log.h"
41 #include "client/linux/minidump_writer/linux_ptrace_dumper.h" 42 #include "client/linux/minidump_writer/linux_ptrace_dumper.h"
42 #include "common/linux/linux_libc_support.h" 43 #include "common/linux/linux_libc_support.h"
43 44
44 namespace { 45 namespace {
45 46
46 using google_breakpad::ExceptionHandler; 47 using google_breakpad::ExceptionHandler;
47 using google_breakpad::LinuxDumper; 48 using google_breakpad::LinuxDumper;
48 using google_breakpad::LinuxPtraceDumper; 49 using google_breakpad::LinuxPtraceDumper;
49 using google_breakpad::MappingInfo; 50 using google_breakpad::MappingInfo;
50 using google_breakpad::MappingList; 51 using google_breakpad::MappingList;
52 using google_breakpad::MicrodumpExtraInfo;
51 using google_breakpad::RawContextCPU; 53 using google_breakpad::RawContextCPU;
52 using google_breakpad::ThreadInfo; 54 using google_breakpad::ThreadInfo;
53 using google_breakpad::UContextReader; 55 using google_breakpad::UContextReader;
54 56
55 const size_t kLineBufferSize = 2048; 57 const size_t kLineBufferSize = 2048;
56 58
57 class MicrodumpWriter { 59 class MicrodumpWriter {
58 public: 60 public:
59 MicrodumpWriter(const ExceptionHandler::CrashContext* context, 61 MicrodumpWriter(const ExceptionHandler::CrashContext* context,
60 const MappingList& mappings, 62 const MappingList& mappings,
61 const char* build_fingerprint, 63 const MicrodumpExtraInfo& microdump_extra_info,
62 const char* product_info,
63 LinuxDumper* dumper) 64 LinuxDumper* dumper)
64 : ucontext_(context ? &context->context : NULL), 65 : ucontext_(context ? &context->context : NULL),
65 #if !defined(__ARM_EABI__) && !defined(__mips__) 66 #if !defined(__ARM_EABI__) && !defined(__mips__)
66 float_state_(context ? &context->float_state : NULL), 67 float_state_(context ? &context->float_state : NULL),
67 #endif 68 #endif
68 dumper_(dumper), 69 dumper_(dumper),
69 mapping_list_(mappings), 70 mapping_list_(mappings),
70 build_fingerprint_(build_fingerprint), 71 microdump_extra_info_(microdump_extra_info),
71 product_info_(product_info),
72 log_line_(NULL) { 72 log_line_(NULL) {
73 log_line_ = reinterpret_cast<char*>(Alloc(kLineBufferSize)); 73 log_line_ = reinterpret_cast<char*>(Alloc(kLineBufferSize));
74 if (log_line_) 74 if (log_line_)
75 log_line_[0] = '\0'; // Clear out the log line buffer. 75 log_line_[0] = '\0'; // Clear out the log line buffer.
76 } 76 }
77 77
78 ~MicrodumpWriter() { dumper_->ThreadsResume(); } 78 ~MicrodumpWriter() { dumper_->ThreadsResume(); }
79 79
80 bool Init() { 80 bool Init() {
81 // In the exceptional case where the system was out of memory and there 81 // In the exceptional case where the system was out of memory and there
82 // wasn't even room to allocate the line buffer, bail out. There is nothing 82 // wasn't even room to allocate the line buffer, bail out. There is nothing
83 // useful we can possibly achieve without the ability to Log. At least let's 83 // useful we can possibly achieve without the ability to Log. At least let's
84 // try to not crash. 84 // try to not crash.
85 if (!dumper_->Init() || !log_line_) 85 if (!dumper_->Init() || !log_line_)
86 return false; 86 return false;
87 return dumper_->ThreadsSuspend() && dumper_->LateInit(); 87 return dumper_->ThreadsSuspend() && dumper_->LateInit();
88 } 88 }
89 89
90 bool Dump() { 90 bool Dump() {
91 bool success; 91 bool success;
92 LogLine("-----BEGIN BREAKPAD MICRODUMP-----"); 92 LogLine("-----BEGIN BREAKPAD MICRODUMP-----");
93 DumpProductInformation(); 93 DumpProductInformation();
94 DumpOSInformation(); 94 DumpOSInformation();
95 DumpGPUInformation();
95 success = DumpCrashingThread(); 96 success = DumpCrashingThread();
96 if (success) 97 if (success)
97 success = DumpMappings(); 98 success = DumpMappings();
98 LogLine("-----END BREAKPAD MICRODUMP-----"); 99 LogLine("-----END BREAKPAD MICRODUMP-----");
99 dumper_->ThreadsResume(); 100 dumper_->ThreadsResume();
100 return success; 101 return success;
101 } 102 }
102 103
103 private: 104 private:
104 // Writes one line to the system log. 105 // Writes one line to the system log.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 143 }
143 144
144 // Writes out the current line buffer on the system log. 145 // Writes out the current line buffer on the system log.
145 void LogCommitLine() { 146 void LogCommitLine() {
146 LogLine(log_line_); 147 LogLine(log_line_);
147 my_strlcpy(log_line_, "", kLineBufferSize); 148 my_strlcpy(log_line_, "", kLineBufferSize);
148 } 149 }
149 150
150 void DumpProductInformation() { 151 void DumpProductInformation() {
151 LogAppend("V "); 152 LogAppend("V ");
152 if (product_info_) { 153 if (microdump_extra_info_.product_info) {
153 LogAppend(product_info_); 154 LogAppend(microdump_extra_info_.product_info);
154 } else { 155 } else {
155 LogAppend("UNKNOWN:0.0.0.0"); 156 LogAppend("UNKNOWN:0.0.0.0");
156 } 157 }
157 LogCommitLine(); 158 LogCommitLine();
158 } 159 }
159 160
160 void DumpOSInformation() { 161 void DumpOSInformation() {
161 const uint8_t n_cpus = static_cast<uint8_t>(sysconf(_SC_NPROCESSORS_CONF)); 162 const uint8_t n_cpus = static_cast<uint8_t>(sysconf(_SC_NPROCESSORS_CONF));
162 163
163 #if defined(__ANDROID__) 164 #if defined(__ANDROID__)
(...skipping 29 matching lines...) Expand all
193 194
194 // Dump the HW architecture (e.g., armv7l, aarch64). 195 // Dump the HW architecture (e.g., armv7l, aarch64).
195 struct utsname uts; 196 struct utsname uts;
196 const bool has_uts_info = (uname(&uts) == 0); 197 const bool has_uts_info = (uname(&uts) == 0);
197 const char* hwArch = has_uts_info ? uts.machine : "unknown_hw_arch"; 198 const char* hwArch = has_uts_info ? uts.machine : "unknown_hw_arch";
198 LogAppend(hwArch); 199 LogAppend(hwArch);
199 LogAppend(" "); 200 LogAppend(" ");
200 201
201 // If the client has attached a build fingerprint to the MinidumpDescriptor 202 // If the client has attached a build fingerprint to the MinidumpDescriptor
202 // use that one. Otherwise try to get some basic info from uname(). 203 // use that one. Otherwise try to get some basic info from uname().
203 if (build_fingerprint_) { 204 if (microdump_extra_info_.build_fingerprint) {
204 LogAppend(build_fingerprint_); 205 LogAppend(microdump_extra_info_.build_fingerprint);
205 } else if (has_uts_info) { 206 } else if (has_uts_info) {
206 LogAppend(uts.release); 207 LogAppend(uts.release);
207 LogAppend(" "); 208 LogAppend(" ");
208 LogAppend(uts.version); 209 LogAppend(uts.version);
209 } else { 210 } else {
210 LogAppend("no build fingerprint available"); 211 LogAppend("no build fingerprint available");
211 } 212 }
212 LogCommitLine(); 213 LogCommitLine();
213 } 214 }
214 215
216 void DumpGPUInformation() {
217 LogAppend("G ");
218 if (microdump_extra_info_.gpu_fingerprint) {
219 LogAppend(microdump_extra_info_.gpu_fingerprint);
220 } else {
221 LogAppend("UNKNOWN");
222 }
223 LogCommitLine();
224 }
225
215 bool DumpThreadStack(uint32_t thread_id, 226 bool DumpThreadStack(uint32_t thread_id,
216 uintptr_t stack_pointer, 227 uintptr_t stack_pointer,
217 int max_stack_len, 228 int max_stack_len,
218 uint8_t** stack_copy) { 229 uint8_t** stack_copy) {
219 *stack_copy = NULL; 230 *stack_copy = NULL;
220 const void* stack; 231 const void* stack;
221 size_t stack_len; 232 size_t stack_len;
222 233
223 if (!dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) { 234 if (!dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) {
224 // The stack pointer might not be available. In this case we don't hard 235 // The stack pointer might not be available. In this case we don't hard
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 394 }
384 395
385 void* Alloc(unsigned bytes) { return dumper_->allocator()->Alloc(bytes); } 396 void* Alloc(unsigned bytes) { return dumper_->allocator()->Alloc(bytes); }
386 397
387 const struct ucontext* const ucontext_; 398 const struct ucontext* const ucontext_;
388 #if !defined(__ARM_EABI__) && !defined(__mips__) 399 #if !defined(__ARM_EABI__) && !defined(__mips__)
389 const google_breakpad::fpstate_t* const float_state_; 400 const google_breakpad::fpstate_t* const float_state_;
390 #endif 401 #endif
391 LinuxDumper* dumper_; 402 LinuxDumper* dumper_;
392 const MappingList& mapping_list_; 403 const MappingList& mapping_list_;
393 const char* const build_fingerprint_; 404 const MicrodumpExtraInfo microdump_extra_info_;
394 const char* const product_info_;
395 char* log_line_; 405 char* log_line_;
396 }; 406 };
397 } // namespace 407 } // namespace
398 408
399 namespace google_breakpad { 409 namespace google_breakpad {
400 410
401 bool WriteMicrodump(pid_t crashing_process, 411 bool WriteMicrodump(pid_t crashing_process,
402 const void* blob, 412 const void* blob,
403 size_t blob_size, 413 size_t blob_size,
404 const MappingList& mappings, 414 const MappingList& mappings,
405 const char* build_fingerprint, 415 const MicrodumpExtraInfo& microdump_extra_info) {
406 const char* product_info) {
407 LinuxPtraceDumper dumper(crashing_process); 416 LinuxPtraceDumper dumper(crashing_process);
408 const ExceptionHandler::CrashContext* context = NULL; 417 const ExceptionHandler::CrashContext* context = NULL;
409 if (blob) { 418 if (blob) {
410 if (blob_size != sizeof(ExceptionHandler::CrashContext)) 419 if (blob_size != sizeof(ExceptionHandler::CrashContext))
411 return false; 420 return false;
412 context = reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); 421 context = reinterpret_cast<const ExceptionHandler::CrashContext*>(blob);
413 dumper.set_crash_address( 422 dumper.set_crash_address(
414 reinterpret_cast<uintptr_t>(context->siginfo.si_addr)); 423 reinterpret_cast<uintptr_t>(context->siginfo.si_addr));
415 dumper.set_crash_signal(context->siginfo.si_signo); 424 dumper.set_crash_signal(context->siginfo.si_signo);
416 dumper.set_crash_thread(context->tid); 425 dumper.set_crash_thread(context->tid);
417 } 426 }
418 MicrodumpWriter writer(context, mappings, build_fingerprint, product_info, 427 MicrodumpWriter writer(context, mappings, microdump_extra_info, &dumper);
419 &dumper);
420 if (!writer.Init()) 428 if (!writer.Init())
421 return false; 429 return false;
422 return writer.Dump(); 430 return writer.Dump();
423 } 431 }
424 432
425 } // namespace google_breakpad 433 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « src/client/linux/microdump_writer/microdump_writer.h ('k') | src/client/linux/microdump_writer/microdump_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698