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

Side by Side Diff: kernel_collector.cc

Issue 6599022: Add ARM support (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crash-reporter.git@master
Patch Set: Removed 3 tests from ARM as they don't really test anything new Created 9 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « kernel_collector.h ('k') | kernel_collector_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "crash-reporter/kernel_collector.h" 5 #include "crash-reporter/kernel_collector.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 10
11 const char KernelCollector::kClearingSequence[] = " "; 11 const char KernelCollector::kClearingSequence[] = " ";
12 static const char kDefaultKernelStackSignature[] = 12 static const char kDefaultKernelStackSignature[] =
13 "kernel-UnspecifiedStackSignature"; 13 "kernel-UnspecifiedStackSignature";
14 static const char kKernelExecName[] = "kernel"; 14 static const char kKernelExecName[] = "kernel";
15 const pid_t kKernelPid = 0; 15 const pid_t kKernelPid = 0;
16 static const char kKernelSignatureKey[] = "sig"; 16 static const char kKernelSignatureKey[] = "sig";
17 // Byte length of maximum human readable portion of a kernel crash signature. 17 // Byte length of maximum human readable portion of a kernel crash signature.
18 static const int kMaxHumanStringLength = 40; 18 static const int kMaxHumanStringLength = 40;
19 static const char kPreservedDumpPath[] = "/sys/kernel/debug/preserved/kcrash"; 19 static const char kPreservedDumpPath[] = "/sys/kernel/debug/preserved/kcrash";
20 const uid_t kRootUid = 0; 20 const uid_t kRootUid = 0;
21 // Time in seconds from the final kernel log message for a call stack 21 // Time in seconds from the final kernel log message for a call stack
22 // to count towards the signature of the kcrash. 22 // to count towards the signature of the kcrash.
23 static const int kSignatureTimestampWindow = 2; 23 static const int kSignatureTimestampWindow = 2;
24 // Kernel log timestamp regular expression. 24 // Kernel log timestamp regular expression.
25 static const std::string kTimestampRegex("^<.*>\\[\\s*(\\d+\\.\\d+)\\]"); 25 static const std::string kTimestampRegex("^<.*>\\[\\s*(\\d+\\.\\d+)\\]");
26 26
27 /*
28 * These regular expressions enable to us capture the PC in a backtrace.
29 * The backtrace is obtained through dmesg or the kernel's preserved/kcrashmem
30 * feature.
31 *
32 * For ARM we see:
33 * "<5>[ 39.458982] PC is at write_breakme+0xd0/0x1b4"
34 * For x86:
35 * "<0>[ 37.474699] EIP: [<790ed488>] write_breakme+0x80/0x108 \
36 * SS:ESP 0068:e9dd3efc
37 */
38 static const char *s_pc_regex[] = {
39 0,
40 " PC is at ([^\\+ ]+).*",
41 " EIP: \\[<.*>\\] ([^\\+ ]+).*", // X86 uses EIP for the program counter
42 };
43
44 COMPILE_ASSERT(arraysize(s_pc_regex) == KernelCollector::archCount,
45 missing_arch_pc_regexp);
46
27 KernelCollector::KernelCollector() 47 KernelCollector::KernelCollector()
28 : is_enabled_(false), 48 : is_enabled_(false),
29 preserved_dump_path_(kPreservedDumpPath) { 49 preserved_dump_path_(kPreservedDumpPath) {
50 // We expect crash dumps in the format of the architecture we are built for.
51 arch_ = GetCompilerArch();
30 } 52 }
31 53
32 KernelCollector::~KernelCollector() { 54 KernelCollector::~KernelCollector() {
33 } 55 }
34 56
35 void KernelCollector::OverridePreservedDumpPath(const FilePath &file_path) { 57 void KernelCollector::OverridePreservedDumpPath(const FilePath &file_path) {
36 preserved_dump_path_ = file_path; 58 preserved_dump_path_ = file_path;
37 } 59 }
38 60
39 bool KernelCollector::LoadPreservedDump(std::string *contents) { 61 bool KernelCollector::LoadPreservedDump(std::string *contents) {
40 // clear contents since ReadFileToString actually appends to the string. 62 // clear contents since ReadFileToString actually appends to the string.
41 contents->clear(); 63 contents->clear();
42 if (!file_util::ReadFileToString(preserved_dump_path_, contents)) { 64 if (!file_util::ReadFileToString(preserved_dump_path_, contents)) {
43 LOG(ERROR) << "Unable to read " << preserved_dump_path_.value(); 65 LOG(ERROR) << "Unable to read " << preserved_dump_path_.value();
44 return false; 66 return false;
45 } 67 }
46 return true; 68 return true;
47 } 69 }
48 70
49 bool KernelCollector::Enable() { 71 bool KernelCollector::Enable() {
50 if (!file_util::PathExists(preserved_dump_path_)) { 72 if (arch_ == archUnknown || arch_ >= archCount ||
73 s_pc_regex[arch_] == NULL) {
74 LOG(WARNING) << "KernelCollector does not understand this architecture";
75 return false;
76 }
77 else if (!file_util::PathExists(preserved_dump_path_)) {
51 LOG(WARNING) << "Kernel does not support crash dumping"; 78 LOG(WARNING) << "Kernel does not support crash dumping";
52 return false; 79 return false;
53 } 80 }
54 81
55 // To enable crashes, we will eventually need to set 82 // To enable crashes, we will eventually need to set
56 // the chnv bit in BIOS, but it does not yet work. 83 // the chnv bit in BIOS, but it does not yet work.
57 LOG(INFO) << "Enabling kernel crash handling"; 84 LOG(INFO) << "Enabling kernel crash handling";
58 is_enabled_ = true; 85 is_enabled_ = true;
59 return true; 86 return true;
60 } 87 }
(...skipping 22 matching lines...) Expand all
83 hash = hash * 16127 + input[i]; 110 hash = hash * 16127 + input[i];
84 return hash; 111 return hash;
85 } 112 }
86 113
87 void KernelCollector::ProcessStackTrace( 114 void KernelCollector::ProcessStackTrace(
88 pcrecpp::StringPiece kernel_dump, 115 pcrecpp::StringPiece kernel_dump,
89 bool print_diagnostics, 116 bool print_diagnostics,
90 unsigned *hash, 117 unsigned *hash,
91 float *last_stack_timestamp) { 118 float *last_stack_timestamp) {
92 pcrecpp::RE line_re("(.+)", pcrecpp::MULTILINE()); 119 pcrecpp::RE line_re("(.+)", pcrecpp::MULTILINE());
93 pcrecpp::RE stack_trace_start_re(kTimestampRegex + " Call Trace:$"); 120 pcrecpp::RE stack_trace_start_re(kTimestampRegex +
121 " (Call Trace|Backtrace):$");
122
123 // For ARM:
124 // <4>[ 3498.731164] [<c0057220>] (__bug+0x20/0x2c) from [<c018062c>]
125 // (write_breakme+0xdc/0x1bc)
126 //
127 // For X86:
94 // Match lines such as the following and grab out "error_code". 128 // Match lines such as the following and grab out "error_code".
95 // <4>[ 6066.849504] [<7937bcee>] error_code+0x66/0x6c 129 // <4>[ 6066.849504] [<7937bcee>] ? error_code+0x66/0x6c
130 // The ? may or may not be present
96 pcrecpp::RE stack_entry_re(kTimestampRegex + 131 pcrecpp::RE stack_entry_re(kTimestampRegex +
97 " \\[<.*>\\]([\\s\\?]+)([^\\+ ]+)"); 132 "\\s+\\[<[[:xdigit:]]+>\\]" // Matches " [<7937bcee>]"
133 "([\\s\\?(]+)" // Matches " ? (" (ARM) or " ? " (X86)
134 "([^\\+ )]+)"); // Matches until delimiter reached
98 std::string line; 135 std::string line;
99 std::string hashable; 136 std::string hashable;
100 137
101 *hash = 0; 138 *hash = 0;
102 *last_stack_timestamp = 0; 139 *last_stack_timestamp = 0;
103 140
104 while (line_re.FindAndConsume(&kernel_dump, &line)) { 141 while (line_re.FindAndConsume(&kernel_dump, &line)) {
105 std::string certainty; 142 std::string certainty;
106 std::string function_name; 143 std::string function_name;
107 if (stack_trace_start_re.PartialMatch(line, last_stack_timestamp)) { 144 if (stack_trace_start_re.PartialMatch(line, last_stack_timestamp)) {
(...skipping 22 matching lines...) Expand all
130 } 167 }
131 168
132 *hash = HashString(hashable); 169 *hash = HashString(hashable);
133 170
134 if (print_diagnostics) { 171 if (print_diagnostics) {
135 printf("Hash based on stack trace: \"%s\" at %f.\n", 172 printf("Hash based on stack trace: \"%s\" at %f.\n",
136 hashable.c_str(), *last_stack_timestamp); 173 hashable.c_str(), *last_stack_timestamp);
137 } 174 }
138 } 175 }
139 176
177 enum KernelCollector::ArchKind KernelCollector::GetCompilerArch(void)
178 {
179 #if defined(COMPILER_GCC) && defined(ARCH_CPU_ARM_FAMILY)
180 return archArm;
181 #elif defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY)
182 return archX86;
183 #else
184 return archUnknown;
185 #endif
186 }
187
188 void KernelCollector::SetArch(enum ArchKind arch)
189 {
190 arch_ = arch;
191 }
192
140 bool KernelCollector::FindCrashingFunction( 193 bool KernelCollector::FindCrashingFunction(
141 pcrecpp::StringPiece kernel_dump, 194 pcrecpp::StringPiece kernel_dump,
142 bool print_diagnostics, 195 bool print_diagnostics,
143 float stack_trace_timestamp, 196 float stack_trace_timestamp,
144 std::string *crashing_function) { 197 std::string *crashing_function) {
145 pcrecpp::RE eip_re(kTimestampRegex + " EIP: \\[<.*>\\] ([^\\+ ]+).*", 198 float timestamp = 0;
199
200 // Use the correct regex for this architecture.
201 pcrecpp::RE eip_re(kTimestampRegex + s_pc_regex[arch_],
146 pcrecpp::MULTILINE()); 202 pcrecpp::MULTILINE());
147 float timestamp = 0; 203
148 while (eip_re.FindAndConsume(&kernel_dump, &timestamp, crashing_function)) { 204 while (eip_re.FindAndConsume(&kernel_dump, &timestamp, crashing_function)) {
149 if (print_diagnostics) { 205 if (print_diagnostics) {
150 printf("@%f: found crashing function %s\n", 206 printf("@%f: found crashing function %s\n",
151 timestamp, 207 timestamp,
152 crashing_function->c_str()); 208 crashing_function->c_str());
153 } 209 }
154 } 210 }
155 if (timestamp == 0) { 211 if (timestamp == 0) {
156 if (print_diagnostics) { 212 if (print_diagnostics) {
157 printf("Found no crashing function.\n"); 213 printf("Found no crashing function.\n");
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 kernel_crash_path.value()); 350 kernel_crash_path.value());
295 351
296 LOG(INFO) << "Stored kcrash to " << kernel_crash_path.value(); 352 LOG(INFO) << "Stored kcrash to " << kernel_crash_path.value();
297 } 353 }
298 if (!ClearPreservedDump()) { 354 if (!ClearPreservedDump()) {
299 return false; 355 return false;
300 } 356 }
301 357
302 return true; 358 return true;
303 } 359 }
OLDNEW
« no previous file with comments | « kernel_collector.h ('k') | kernel_collector_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698