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

Side by Side Diff: src/client/linux/microdump_writer/microdump_writer_unittest.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
« no previous file with comments | « src/client/linux/microdump_writer/microdump_writer.cc ('k') | no next file » | 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) 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 #include <ctype.h> 30 #include <ctype.h>
31 #include <sys/syscall.h> 31 #include <sys/syscall.h>
32 #include <sys/types.h> 32 #include <sys/types.h>
33 #include <unistd.h> 33 #include <unistd.h>
34 34
35 #include <sstream> 35 #include <sstream>
36 #include <string> 36 #include <string>
37 37
38 #include "breakpad_googletest_includes.h" 38 #include "breakpad_googletest_includes.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/microdump_writer/microdump_writer.h" 41 #include "client/linux/microdump_writer/microdump_writer.h"
41 #include "common/linux/eintr_wrapper.h" 42 #include "common/linux/eintr_wrapper.h"
42 #include "common/linux/ignore_ret.h" 43 #include "common/linux/ignore_ret.h"
43 #include "common/scoped_ptr.h" 44 #include "common/scoped_ptr.h"
44 #include "common/tests/auto_tempdir.h" 45 #include "common/tests/auto_tempdir.h"
45 #include "common/using_std_string.h" 46 #include "common/using_std_string.h"
46 47
47 using namespace google_breakpad; 48 using namespace google_breakpad;
48 49
49 namespace { 50 namespace {
50 51
51 typedef testing::Test MicrodumpWriterTest; 52 typedef testing::Test MicrodumpWriterTest;
52 53
54 MicrodumpExtraInfo MakeMicrodumpExtraInfo(
55 const char* build_fingerprint,
56 const char* product_info,
57 const char* gpu_fingerprint) {
58 MicrodumpExtraInfo info;
59 info.build_fingerprint = build_fingerprint;
60 info.product_info = product_info;
61 info.gpu_fingerprint = gpu_fingerprint;
62 return info;
63 }
64
53 void CrashAndGetMicrodump( 65 void CrashAndGetMicrodump(
54 const MappingList& mappings, 66 const MappingList& mappings,
55 const char* build_fingerprint, 67 const MicrodumpExtraInfo& microdump_extra_info,
56 const char* product_info,
57 scoped_array<char>* buf) { 68 scoped_array<char>* buf) {
58 int fds[2]; 69 int fds[2];
59 ASSERT_NE(-1, pipe(fds)); 70 ASSERT_NE(-1, pipe(fds));
60 71
61 AutoTempDir temp_dir; 72 AutoTempDir temp_dir;
62 string stderr_file = temp_dir.path() + "/stderr.log"; 73 string stderr_file = temp_dir.path() + "/stderr.log";
63 int err_fd = open(stderr_file.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); 74 int err_fd = open(stderr_file.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
64 ASSERT_NE(-1, err_fd); 75 ASSERT_NE(-1, err_fd);
65 76
66 const pid_t child = fork(); 77 const pid_t child = fork();
(...skipping 11 matching lines...) Expand all
78 89
79 // Set a non-zero tid to avoid tripping asserts. 90 // Set a non-zero tid to avoid tripping asserts.
80 context.tid = child; 91 context.tid = child;
81 92
82 // Redirect temporarily stderr to the stderr.log file. 93 // Redirect temporarily stderr to the stderr.log file.
83 int save_err = dup(STDERR_FILENO); 94 int save_err = dup(STDERR_FILENO);
84 ASSERT_NE(-1, save_err); 95 ASSERT_NE(-1, save_err);
85 ASSERT_NE(-1, dup2(err_fd, STDERR_FILENO)); 96 ASSERT_NE(-1, dup2(err_fd, STDERR_FILENO));
86 97
87 ASSERT_TRUE(WriteMicrodump(child, &context, sizeof(context), mappings, 98 ASSERT_TRUE(WriteMicrodump(child, &context, sizeof(context), mappings,
88 build_fingerprint, product_info)); 99 microdump_extra_info));
89 100
90 // Revert stderr back to the console. 101 // Revert stderr back to the console.
91 dup2(save_err, STDERR_FILENO); 102 dup2(save_err, STDERR_FILENO);
92 close(save_err); 103 close(save_err);
93 104
94 // Read back the stderr file and check for the microdump marker. 105 // Read back the stderr file and check for the microdump marker.
95 fsync(err_fd); 106 fsync(err_fd);
96 lseek(err_fd, 0, SEEK_SET); 107 lseek(err_fd, 0, SEEK_SET);
97 const size_t kBufSize = 64 * 1024; 108 const size_t kBufSize = 64 * 1024;
98 buf->reset(new char[kBufSize]); 109 buf->reset(new char[kBufSize]);
99 ASSERT_GT(read(err_fd, buf->get(), kBufSize), 0); 110 ASSERT_GT(read(err_fd, buf->get(), kBufSize), 0);
100 111
101 close(err_fd); 112 close(err_fd);
102 close(fds[1]); 113 close(fds[1]);
103 114
104 ASSERT_NE(static_cast<char*>(0), strstr( 115 ASSERT_NE(static_cast<char*>(0), strstr(
105 buf->get(), "-----BEGIN BREAKPAD MICRODUMP-----")); 116 buf->get(), "-----BEGIN BREAKPAD MICRODUMP-----"));
106 ASSERT_NE(static_cast<char*>(0), strstr( 117 ASSERT_NE(static_cast<char*>(0), strstr(
107 buf->get(), "-----END BREAKPAD MICRODUMP-----")); 118 buf->get(), "-----END BREAKPAD MICRODUMP-----"));
108 } 119 }
109 120
110 void CheckMicrodumpContents(const string &microdum_content, 121 void CheckMicrodumpContents(const string& microdump_content,
111 const string &expected_fingerprint, 122 const MicrodumpExtraInfo& expected_info) {
112 const string &expected_product_info) { 123 std::istringstream iss(microdump_content);
113 std::istringstream iss(microdum_content);
114 bool did_find_os_info = false; 124 bool did_find_os_info = false;
115 bool did_find_product_info = false; 125 bool did_find_product_info = false;
126 bool did_find_gpu_info = false;
116 for (string line; std::getline(iss, line);) { 127 for (string line; std::getline(iss, line);) {
117 if (line.find("O ") == 0) { 128 if (line.find("O ") == 0) {
118 std::istringstream os_info_tokens(line); 129 std::istringstream os_info_tokens(line);
119 string token; 130 string token;
120 os_info_tokens.ignore(2); // Ignore the "O " preamble. 131 os_info_tokens.ignore(2); // Ignore the "O " preamble.
121 // Check the OS descriptor char (L=Linux, A=Android). 132 // Check the OS descriptor char (L=Linux, A=Android).
122 os_info_tokens >> token; 133 os_info_tokens >> token;
123 ASSERT_TRUE(token == "L" || token == "A"); 134 ASSERT_TRUE(token == "L" || token == "A");
124 135
125 os_info_tokens >> token; // HW architecture. 136 os_info_tokens >> token; // HW architecture.
126 os_info_tokens >> token; // Number of cpus. 137 os_info_tokens >> token; // Number of cpus.
127 for (size_t i = 0; i < token.size(); ++i) 138 for (size_t i = 0; i < token.size(); ++i)
128 ASSERT_TRUE(isxdigit(token[i])); 139 ASSERT_TRUE(isxdigit(token[i]));
129 os_info_tokens >> token; // SW architecture. 140 os_info_tokens >> token; // SW architecture.
130 141
131 // Check that the build fingerprint is in the right place. 142 // Check that the build fingerprint is in the right place.
132 os_info_tokens >> token; 143 os_info_tokens >> token;
133 ASSERT_EQ(expected_fingerprint, token); 144 if (expected_info.build_fingerprint)
145 ASSERT_EQ(expected_info.build_fingerprint, token);
134 did_find_os_info = true; 146 did_find_os_info = true;
135 } else if (line.find("V ") == 0) { 147 } else if (line.find("V ") == 0) {
136 ASSERT_EQ("V " + expected_product_info, line); 148 if (expected_info.product_info)
149 ASSERT_EQ(string("V ") + expected_info.product_info, line);
137 did_find_product_info = true; 150 did_find_product_info = true;
151 } else if (line.find("G ") == 0) {
152 if (expected_info.gpu_fingerprint)
153 ASSERT_EQ(string("G ") + expected_info.gpu_fingerprint, line);
154 did_find_gpu_info = true;
138 } 155 }
139 } 156 }
140 ASSERT_TRUE(did_find_os_info); 157 ASSERT_TRUE(did_find_os_info);
141 ASSERT_TRUE(did_find_product_info); 158 ASSERT_TRUE(did_find_product_info);
159 ASSERT_TRUE(did_find_gpu_info);
160 }
161
162 void CheckMicrodumpContents(const string& microdump_content,
163 const string& expected_fingerprint,
164 const string& expected_product_info,
165 const string& expected_gpu_fingerprint) {
166 CheckMicrodumpContents(
167 microdump_content,
168 MakeMicrodumpExtraInfo(expected_fingerprint.c_str(),
169 expected_product_info.c_str(),
170 expected_gpu_fingerprint.c_str()));
142 } 171 }
143 172
144 TEST(MicrodumpWriterTest, BasicWithMappings) { 173 TEST(MicrodumpWriterTest, BasicWithMappings) {
145 // Push some extra mapping to check the MappingList logic. 174 // Push some extra mapping to check the MappingList logic.
146 const uint32_t memory_size = sysconf(_SC_PAGESIZE); 175 const uint32_t memory_size = sysconf(_SC_PAGESIZE);
147 const char* kMemoryName = "libfoo.so"; 176 const char* kMemoryName = "libfoo.so";
148 const uint8_t kModuleGUID[sizeof(MDGUID)] = { 177 const uint8_t kModuleGUID[sizeof(MDGUID)] = {
149 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 178 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
150 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF 179 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
151 }; 180 };
152 181
153 MappingInfo info; 182 MappingInfo info;
154 info.start_addr = memory_size; 183 info.start_addr = memory_size;
155 info.size = memory_size; 184 info.size = memory_size;
156 info.offset = 42; 185 info.offset = 42;
157 strcpy(info.name, kMemoryName); 186 strcpy(info.name, kMemoryName);
158 187
159 MappingList mappings; 188 MappingList mappings;
160 MappingEntry mapping; 189 MappingEntry mapping;
161 mapping.first = info; 190 mapping.first = info;
162 memcpy(mapping.second, kModuleGUID, sizeof(MDGUID)); 191 memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
163 mappings.push_back(mapping); 192 mappings.push_back(mapping);
164 193
165 scoped_array<char> buf; 194 scoped_array<char> buf;
166 CrashAndGetMicrodump(mappings, NULL, NULL, &buf); 195 CrashAndGetMicrodump(mappings, MicrodumpExtraInfo(), &buf);
167 196
168 #ifdef __LP64__ 197 #ifdef __LP64__
169 ASSERT_NE(static_cast<char*>(0), strstr( 198 ASSERT_NE(static_cast<char*>(0), strstr(
170 buf.get(), "M 0000000000001000 000000000000002A 0000000000001000 " 199 buf.get(), "M 0000000000001000 000000000000002A 0000000000001000 "
171 "33221100554477668899AABBCCDDEEFF0 libfoo.so")); 200 "33221100554477668899AABBCCDDEEFF0 libfoo.so"));
172 #else 201 #else
173 ASSERT_NE(static_cast<char*>(0), strstr( 202 ASSERT_NE(static_cast<char*>(0), strstr(
174 buf.get(), "M 00001000 0000002A 00001000 " 203 buf.get(), "M 00001000 0000002A 00001000 "
175 "33221100554477668899AABBCCDDEEFF0 libfoo.so")); 204 "33221100554477668899AABBCCDDEEFF0 libfoo.so"));
176 #endif 205 #endif
177 206
178 // In absence of a product info in the minidump, the writer should just write 207 // In absence of a product info in the minidump, the writer should just write
179 // an unknown marker. 208 // an unknown marker.
180 ASSERT_NE(static_cast<char*>(0), strstr( 209 ASSERT_NE(static_cast<char*>(0), strstr(
181 buf.get(), "V UNKNOWN:0.0.0.0")); 210 buf.get(), "V UNKNOWN:0.0.0.0"));
182 } 211 }
183 212
184 // Ensure that the product info and build fingerprint metadata show up in the 213 // Ensure that the product info and build fingerprint metadata show up in the
185 // final microdump if present. 214 // final microdump if present.
186 TEST(MicrodumpWriterTest, BuildFingerprintAndProductInfo) { 215 TEST(MicrodumpWriterTest, BuildFingerprintAndProductInfo) {
187 const char kProductInfo[] = "MockProduct:42.0.2311.99"; 216 const char kProductInfo[] = "MockProduct:42.0.2311.99";
188 const char kBuildFingerprint[] = 217 const char kBuildFingerprint[] =
189 "aosp/occam/mako:5.1.1/LMY47W/12345678:userdegbug/dev-keys"; 218 "aosp/occam/mako:5.1.1/LMY47W/12345678:userdegbug/dev-keys";
219 const char kGPUFingerprint[] =
220 "Qualcomm;Adreno (TM) 330;OpenGL ES 3.0 V@104.0 AU@ (GIT@Id3510ff6dc)";
221 const MicrodumpExtraInfo kMicrodumpExtraInfo(
222 MakeMicrodumpExtraInfo(kBuildFingerprint, kProductInfo, kGPUFingerprint));
190 scoped_array<char> buf; 223 scoped_array<char> buf;
191 MappingList no_mappings; 224 MappingList no_mappings;
192 225
193 CrashAndGetMicrodump(no_mappings, kBuildFingerprint, kProductInfo, &buf); 226 CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfo, &buf);
194 CheckMicrodumpContents(string(buf.get()), kBuildFingerprint, kProductInfo); 227 CheckMicrodumpContents(string(buf.get()), kMicrodumpExtraInfo);
195 } 228 }
196 229
197 TEST(MicrodumpWriterTest, NoProductInfo) { 230 TEST(MicrodumpWriterTest, NoProductInfo) {
198 const char kBuildFingerprint[] = "foobar"; 231 const char kBuildFingerprint[] = "foobar";
232 const char kGPUFingerprint[] = "bazqux";
199 scoped_array<char> buf; 233 scoped_array<char> buf;
200 MappingList no_mappings; 234 MappingList no_mappings;
201 235
202 CrashAndGetMicrodump(no_mappings, kBuildFingerprint, NULL, &buf); 236 const MicrodumpExtraInfo kMicrodumpExtraInfoNoProductInfo(
203 CheckMicrodumpContents(string(buf.get()), kBuildFingerprint, "UNKNOWN:0.0.0.0" ); 237 MakeMicrodumpExtraInfo(kBuildFingerprint, NULL, kGPUFingerprint));
238
239 CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfoNoProductInfo, &buf);
240 CheckMicrodumpContents(string(buf.get()), kBuildFingerprint,
241 "UNKNOWN:0.0.0.0", kGPUFingerprint);
242 }
243
244 TEST(MicrodumpWriterTest, NoGPUInfo) {
245 const char kProductInfo[] = "bazqux";
246 const char kBuildFingerprint[] = "foobar";
247 scoped_array<char> buf;
248 MappingList no_mappings;
249
250 const MicrodumpExtraInfo kMicrodumpExtraInfoNoGPUInfo(
251 MakeMicrodumpExtraInfo(kBuildFingerprint, kProductInfo, NULL));
252
253 CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfoNoGPUInfo, &buf);
254 CheckMicrodumpContents(string(buf.get()), kBuildFingerprint,
255 kProductInfo, "UNKNOWN");
204 } 256 }
205 } // namespace 257 } // namespace
OLDNEW
« no previous file with comments | « src/client/linux/microdump_writer/microdump_writer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698