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

Side by Side Diff: src/client/windows/unittests/dump_analysis.cc

Issue 1994015: Moved exception_handler_test to the more aptly named exception_handler_death_... (Closed) Base URL: http://google-breakpad.googlecode.com/svn/trunk/
Patch Set: '' Created 10 years, 7 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
OLDNEW
1 // Copyright (c) 2010, Google Inc. 1 // Copyright (c) 2010, 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 13 matching lines...) Expand all
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 #include <windows.h> 30 #include <windows.h>
31 #include <objbase.h> 31 #include <objbase.h>
32 #include <dbghelp.h> 32 #include <dbghelp.h>
33 33
34 #include "dump_analysis.h" // NOLINT
34 #include "gtest/gtest.h" 35 #include "gtest/gtest.h"
35 36
36 namespace { 37 DumpAnalysis::~DumpAnalysis() {
37 38 if (dump_file_view_ != NULL) {
38 // Convenience to get to the PEB pointer in a TEB. 39 EXPECT_TRUE(::UnmapViewOfFile(dump_file_view_));
39 struct FakeTEB { 40 ::CloseHandle(dump_file_mapping_);
40 char dummy[0x30]; 41 dump_file_mapping_ = NULL;
41 void* peb;
42 };
43
44 // Minidump with stacks, PEB, TEB, and unloaded module list.
45 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>(
46 MiniDumpWithProcessThreadData | // Get PEB and TEB.
47 MiniDumpWithUnloadedModules); // Get unloaded modules when available.
48
49 // Minidump with all of the above, plus memory referenced from stack.
50 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
51 MiniDumpWithProcessThreadData | // Get PEB and TEB.
52 MiniDumpWithUnloadedModules | // Get unloaded modules when available.
53 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack.
54
55 // Large dump with all process memory.
56 const MINIDUMP_TYPE kFullDumpType = static_cast<MINIDUMP_TYPE>(
57 MiniDumpWithFullMemory | // Full memory from process.
58 MiniDumpWithProcessThreadData | // Get PEB and TEB.
59 MiniDumpWithHandleData | // Get all handle information.
60 MiniDumpWithUnloadedModules); // Get unloaded modules when available.
61
62 class MinidumpTest: public testing::Test {
63 public:
64 MinidumpTest() : dump_file_view_(NULL), dump_file_handle_(NULL),
65 dump_file_mapping_(NULL) {
66 } 42 }
67 43
68 virtual void SetUp() { 44 if (dump_file_handle_ != NULL) {
69 // Make sure URLMon isn't loaded into our process. 45 ::CloseHandle(dump_file_handle_);
70 ASSERT_EQ(NULL, ::GetModuleHandle(L"urlmon.dll")); 46 dump_file_handle_ = NULL;
47 }
48 }
71 49
72 // Then load and unload it to ensure we have something to 50 void DumpAnalysis::EnsureDumpMapped() {
73 // stock the unloaded module list with. 51 if (dump_file_view_ == NULL) {
74 HMODULE urlmon = ::LoadLibrary(L"urlmon.dll"); 52 dump_file_handle_ = ::CreateFile(dump_file_.c_str(),
75 ASSERT_TRUE(urlmon != NULL); 53 GENERIC_READ,
76 ASSERT_TRUE(::FreeLibrary(urlmon)); 54 0,
55 NULL,
56 OPEN_EXISTING,
57 0,
58 NULL);
59 ASSERT_TRUE(dump_file_handle_ != NULL);
60 ASSERT_TRUE(dump_file_mapping_ == NULL);
77 61
78 wchar_t temp_dir_path[ MAX_PATH ] = {0}; 62 dump_file_mapping_ = ::CreateFileMapping(dump_file_handle_,
79 wchar_t dump_file_name[ MAX_PATH ] = {0}; 63 NULL,
80 ::GetTempPath(MAX_PATH, temp_dir_path); 64 PAGE_READONLY,
81 ::GetTempFileName(temp_dir_path, L"tst", 0, dump_file_name); 65 0,
82 dump_file_ = dump_file_name; 66 0,
83 dump_file_handle_ = ::CreateFile(dump_file_.c_str(), 67 NULL);
84 GENERIC_WRITE | GENERIC_READ, 68 ASSERT_TRUE(dump_file_mapping_ != NULL);
85 0, 69
86 NULL, 70 dump_file_view_ = ::MapViewOfFile(dump_file_mapping_,
87 OPEN_EXISTING, 71 FILE_MAP_READ,
88 0, 72 0,
89 NULL); 73 0,
90 ASSERT_TRUE(dump_file_handle_ != NULL); 74 0);
75 ASSERT_TRUE(dump_file_view_ != NULL);
76 }
77 }
78
79 bool DumpAnalysis::HasTebs() const {
80 MINIDUMP_THREAD_LIST* thread_list = NULL;
81 size_t thread_list_size = GetStream(ThreadListStream, &thread_list);
82
83 if (thread_list_size > 0 && thread_list != NULL) {
84 for (ULONG i = 0; i < thread_list->NumberOfThreads; ++i) {
85 if (!HasMemory(thread_list->Threads[i].Teb))
86 return false;
87 }
88
89 return true;
91 } 90 }
92 91
93 virtual void TearDown() { 92 // No thread list, no TEB info.
94 if (dump_file_view_ != NULL) { 93 return false;
95 EXPECT_TRUE(::UnmapViewOfFile(dump_file_view_)); 94 }
96 ::CloseHandle(dump_file_mapping_);
97 dump_file_mapping_ = NULL;
98 }
99 95
100 ::CloseHandle(dump_file_handle_); 96 bool DumpAnalysis::HasPeb() const {
101 dump_file_handle_ = NULL; 97 MINIDUMP_THREAD_LIST* thread_list = NULL;
98 size_t thread_list_size = GetStream(ThreadListStream, &thread_list);
102 99
103 EXPECT_TRUE(::DeleteFile(dump_file_.c_str())); 100 if (thread_list_size > 0 && thread_list != NULL &&
101 thread_list->NumberOfThreads > 0) {
102 FakeTEB* teb = NULL;
103 if (!HasMemory(thread_list->Threads[0].Teb, &teb))
104 return false;
105
106 return HasMemory(teb->peb);
104 } 107 }
105 108
106 void EnsureDumpMapped() { 109 return false;
107 ASSERT_TRUE(dump_file_handle_ != NULL); 110 }
108 if (dump_file_view_ == NULL) {
109 ASSERT_TRUE(dump_file_mapping_ == NULL);
110 111
111 dump_file_mapping_ = ::CreateFileMapping(dump_file_handle_, 112 bool DumpAnalysis::HasStream(ULONG stream_number) const {
112 NULL, 113 void* stream = NULL;
113 PAGE_READONLY, 114 size_t stream_size = GetStreamImpl(stream_number, &stream);
114 0, 115 return stream_size > 0 && stream != NULL;
115 0, 116 }
116 NULL);
117 ASSERT_TRUE(dump_file_mapping_ != NULL);
118 117
119 dump_file_view_ = ::MapViewOfFile(dump_file_mapping_, 118 size_t DumpAnalysis::GetStreamImpl(ULONG stream_number, void** stream) const {
120 FILE_MAP_READ, 119 MINIDUMP_DIRECTORY* directory = NULL;
121 0, 120 ULONG memory_list_size = 0;
122 0, 121 BOOL ret = ::MiniDumpReadDumpStream(dump_file_view_,
123 0); 122 stream_number,
124 ASSERT_TRUE(dump_file_view_ != NULL); 123 &directory,
124 stream,
125 &memory_list_size);
126
127 return ret ? memory_list_size : 0;
128 }
129
130 bool DumpAnalysis::HasMemoryImpl(const void *addr_in, size_t structuresize,
131 void **structure) const {
132 uintptr_t address = reinterpret_cast<uintptr_t>(addr_in);
133 MINIDUMP_MEMORY_LIST* memory_list = NULL;
134 size_t memory_list_size = GetStream(MemoryListStream, &memory_list);
135 if (memory_list_size > 0 && memory_list != NULL) {
136 for (ULONG i = 0; i < memory_list->NumberOfMemoryRanges; ++i) {
137 MINIDUMP_MEMORY_DESCRIPTOR& descr = memory_list->MemoryRanges[i];
138 const uintptr_t range_start =
139 static_cast<uintptr_t>(descr.StartOfMemoryRange);
140 uintptr_t range_end = range_start + descr.Memory.DataSize;
141
142 if (address >= range_start &&
143 address + structuresize < range_end) {
144 // The start address falls in the range, and the end address is
145 // in bounds, return a pointer to the structure if requested.
146 if (structure != NULL)
147 *structure = RVA_TO_ADDR(dump_file_view_, descr.Memory.Rva);
148
149 return true;
150 }
125 } 151 }
126 } 152 }
127 153
128 bool WriteDump(ULONG flags) { 154 // We didn't find the range in a MINIDUMP_MEMORY_LIST, so maybe this
129 // Fake exception is access violation on write to this. 155 // is a full dump using MINIDUMP_MEMORY64_LIST with all the memory at the
130 EXCEPTION_RECORD ex_record = { 156 // end of the dump file.
131 STATUS_ACCESS_VIOLATION, // ExceptionCode 157 MINIDUMP_MEMORY64_LIST* memory64_list = NULL;
132 0, // ExceptionFlags 158 memory_list_size = GetStream(Memory64ListStream, &memory64_list);
133 NULL, // ExceptionRecord; 159 if (memory_list_size > 0 && memory64_list != NULL) {
134 reinterpret_cast<void*>(0xCAFEBABE), // ExceptionAddress; 160 // Keep track of where the current descriptor maps to.
135 2, // NumberParameters; 161 RVA64 curr_rva = memory64_list->BaseRva;
136 { EXCEPTION_WRITE_FAULT, reinterpret_cast<ULONG_PTR>(this) } 162 for (ULONG i = 0; i < memory64_list->NumberOfMemoryRanges; ++i) {
137 }; 163 MINIDUMP_MEMORY_DESCRIPTOR64& descr = memory64_list->MemoryRanges[i];
138 CONTEXT ctx_record = {}; 164 uintptr_t range_start =
139 EXCEPTION_POINTERS ex_ptrs = { 165 static_cast<uintptr_t>(descr.StartOfMemoryRange);
140 &ex_record, 166 uintptr_t range_end = range_start + static_cast<size_t>(descr.DataSize);
141 &ctx_record,
142 };
143 MINIDUMP_EXCEPTION_INFORMATION ex_info = {
144 ::GetCurrentThreadId(),
145 &ex_ptrs,
146 FALSE,
147 };
148 167
149 // Capture our register context. 168 if (address >= range_start &&
150 ::RtlCaptureContext(&ctx_record); 169 address + structuresize < range_end) {
170 // The start address falls in the range, and the end address is
171 // in bounds, return a pointer to the structure if requested.
172 if (structure != NULL)
173 *structure = RVA_TO_ADDR(dump_file_view_, curr_rva);
151 174
152 // And write a dump 175 return true;
153 BOOL result = ::MiniDumpWriteDump(::GetCurrentProcess(), 176 }
154 ::GetCurrentProcessId(), 177
155 dump_file_handle_, 178 // Advance the current RVA.
156 static_cast<MINIDUMP_TYPE>(flags), 179 curr_rva += descr.DataSize;
157 &ex_info, 180 }
158 NULL,
159 NULL);
160 return result == TRUE;
161 } 181 }
162 182
163 bool DumpHasStream(ULONG stream_number) { 183 return false;
164 EnsureDumpMapped();
165
166 MINIDUMP_DIRECTORY* directory = NULL;
167 void* stream = NULL;
168 ULONG stream_size = 0;
169 BOOL ret = ::MiniDumpReadDumpStream(dump_file_view_,
170 stream_number,
171 &directory,
172 &stream,
173 &stream_size);
174
175 return ret != FALSE && stream != NULL && stream_size > 0;
176 }
177
178 template <class StreamType>
179 size_t GetStream(ULONG stream_number, StreamType** stream) {
180 EnsureDumpMapped();
181 MINIDUMP_DIRECTORY* directory = NULL;
182 ULONG memory_list_size = 0;
183 BOOL ret = ::MiniDumpReadDumpStream(dump_file_view_,
184 stream_number,
185 &directory,
186 reinterpret_cast<void**>(stream),
187 &memory_list_size);
188
189 return ret ? memory_list_size : 0;
190 }
191
192 bool DumpHasTebs() {
193 MINIDUMP_THREAD_LIST* thread_list = NULL;
194 size_t thread_list_size = GetStream(ThreadListStream, &thread_list);
195
196 if (thread_list_size > 0 && thread_list != NULL) {
197 for (ULONG i = 0; i < thread_list->NumberOfThreads; ++i) {
198 if (!DumpHasMemory(thread_list->Threads[i].Teb))
199 return false;
200 }
201
202 return true;
203 }
204
205 // No thread list, no TEB info.
206 return false;
207 }
208
209 bool DumpHasPeb() {
210 MINIDUMP_THREAD_LIST* thread_list = NULL;
211 size_t thread_list_size = GetStream(ThreadListStream, &thread_list);
212
213 if (thread_list_size > 0 && thread_list != NULL &&
214 thread_list->NumberOfThreads > 0) {
215 FakeTEB* teb = NULL;
216 if (!DumpHasMemory(thread_list->Threads[0].Teb, &teb))
217 return false;
218
219 return DumpHasMemory(teb->peb);
220 }
221
222 return false;
223 }
224
225 bool DumpHasMemory(ULONG64 address) {
226 return DumpHasMemory<BYTE>(address, NULL);
227 }
228
229 bool DumpHasMemory(const void* address) {
230 return DumpHasMemory<BYTE>(address, NULL);
231 }
232
233 template <class StructureType>
234 bool DumpHasMemory(ULONG64 address, StructureType** structure = NULL) {
235 // We can't cope with 64 bit addresses for now.
236 if (address > 0xFFFFFFFFUL)
237 return false;
238
239 return DumpHasMemory(reinterpret_cast<void*>(address), structure);
240 }
241
242 template <class StructureType>
243 bool DumpHasMemory(const void* addr_in, StructureType** structure = NULL) {
244 uintptr_t address = reinterpret_cast<uintptr_t>(addr_in);
245 MINIDUMP_MEMORY_LIST* memory_list = NULL;
246 size_t memory_list_size = GetStream(MemoryListStream, &memory_list);
247 if (memory_list_size > 0 && memory_list != NULL) {
248 for (ULONG i = 0; i < memory_list->NumberOfMemoryRanges; ++i) {
249 MINIDUMP_MEMORY_DESCRIPTOR& descr = memory_list->MemoryRanges[i];
250 const uintptr_t range_start =
251 static_cast<uintptr_t>(descr.StartOfMemoryRange);
252 uintptr_t range_end = range_start + descr.Memory.DataSize;
253
254 if (address >= range_start &&
255 address + sizeof(StructureType) < range_end) {
256 // The start address falls in the range, and the end address is
257 // in bounds, return a pointer to the structure if requested.
258 if (structure != NULL)
259 *structure = reinterpret_cast<StructureType*>(
260 RVA_TO_ADDR(dump_file_view_, descr.Memory.Rva));
261
262 return true;
263 }
264 }
265 }
266
267 // We didn't find the range in a MINIDUMP_MEMORY_LIST, so maybe this
268 // is a full dump using MINIDUMP_MEMORY64_LIST with all the memory at the
269 // end of the dump file.
270 MINIDUMP_MEMORY64_LIST* memory64_list = NULL;
271 memory_list_size = GetStream(Memory64ListStream, &memory64_list);
272 if (memory_list_size > 0 && memory64_list != NULL) {
273 // Keep track of where the current descriptor maps to.
274 RVA64 curr_rva = memory64_list->BaseRva;
275 for (ULONG i = 0; i < memory64_list->NumberOfMemoryRanges; ++i) {
276 MINIDUMP_MEMORY_DESCRIPTOR64& descr = memory64_list->MemoryRanges[i];
277 uintptr_t range_start =
278 static_cast<uintptr_t>(descr.StartOfMemoryRange);
279 uintptr_t range_end = range_start + static_cast<size_t>(descr.DataSize);
280
281 if (address >= range_start &&
282 address + sizeof(StructureType) < range_end) {
283 // The start address falls in the range, and the end address is
284 // in bounds, return a pointer to the structure if requested.
285 if (structure != NULL)
286 *structure = reinterpret_cast<StructureType*>(
287 RVA_TO_ADDR(dump_file_view_, curr_rva));
288
289 return true;
290 }
291
292 // Advance the current RVA.
293 curr_rva += descr.DataSize;
294 }
295 }
296
297
298
299 return false;
300 }
301
302 protected:
303 HANDLE dump_file_handle_;
304 HANDLE dump_file_mapping_;
305 void* dump_file_view_;
306
307 std::wstring dump_file_;
308 };
309
310 // We need to be able to get file information from Windows
311 bool HasFileInfo(const std::wstring& file_path) {
312 DWORD dummy;
313 const wchar_t* path = file_path.c_str();
314 DWORD length = ::GetFileVersionInfoSize(path, &dummy);
315 if (length == 0)
316 return NULL;
317
318 void* data = calloc(length, 1);
319 if (!data)
320 return false;
321
322 if (!::GetFileVersionInfo(path, dummy, length, data)) {
323 free(data);
324 return false;
325 }
326
327 void* translate = NULL;
328 UINT page_count;
329 BOOL query_result = VerQueryValue(
330 data,
331 L"\\VarFileInfo\\Translation",
332 static_cast<void**>(&translate),
333 &page_count);
334
335 free(data);
336 if (query_result && translate) {
337 return true;
338 } else {
339 return false;
340 }
341 } 184 }
342
343 TEST_F(MinidumpTest, Version) {
344 API_VERSION* version = ::ImagehlpApiVersion();
345
346 HMODULE dbg_help = ::GetModuleHandle(L"dbghelp.dll");
347 ASSERT_TRUE(dbg_help != NULL);
348
349 wchar_t dbg_help_file[1024] = {};
350 ASSERT_TRUE(::GetModuleFileName(dbg_help,
351 dbg_help_file,
352 sizeof(dbg_help_file) /
353 sizeof(*dbg_help_file)));
354 ASSERT_TRUE(HasFileInfo(std::wstring(dbg_help_file)) != NULL);
355
356 // LOG(INFO) << "DbgHelp.dll version: " << file_info->file_version();
357 }
358
359 TEST_F(MinidumpTest, Normal) {
360 EXPECT_TRUE(WriteDump(MiniDumpNormal));
361
362 // We expect threads, modules and some memory.
363 EXPECT_TRUE(DumpHasStream(ThreadListStream));
364 EXPECT_TRUE(DumpHasStream(ModuleListStream));
365 EXPECT_TRUE(DumpHasStream(MemoryListStream));
366 EXPECT_TRUE(DumpHasStream(ExceptionStream));
367 EXPECT_TRUE(DumpHasStream(SystemInfoStream));
368 EXPECT_TRUE(DumpHasStream(MiscInfoStream));
369
370 EXPECT_FALSE(DumpHasStream(ThreadExListStream));
371 EXPECT_FALSE(DumpHasStream(Memory64ListStream));
372 EXPECT_FALSE(DumpHasStream(CommentStreamA));
373 EXPECT_FALSE(DumpHasStream(CommentStreamW));
374 EXPECT_FALSE(DumpHasStream(HandleDataStream));
375 EXPECT_FALSE(DumpHasStream(FunctionTableStream));
376 EXPECT_FALSE(DumpHasStream(UnloadedModuleListStream));
377 EXPECT_FALSE(DumpHasStream(MemoryInfoListStream));
378 EXPECT_FALSE(DumpHasStream(ThreadInfoListStream));
379 EXPECT_FALSE(DumpHasStream(HandleOperationListStream));
380 EXPECT_FALSE(DumpHasStream(TokenStream));
381
382 // We expect no PEB nor TEBs in this dump.
383 EXPECT_FALSE(DumpHasTebs());
384 EXPECT_FALSE(DumpHasPeb());
385
386 // We expect no off-stack memory in this dump.
387 EXPECT_FALSE(DumpHasMemory(this));
388 }
389
390 TEST_F(MinidumpTest, SmallDump) {
391 ASSERT_TRUE(WriteDump(kSmallDumpType));
392
393 EXPECT_TRUE(DumpHasStream(ThreadListStream));
394 EXPECT_TRUE(DumpHasStream(ModuleListStream));
395 EXPECT_TRUE(DumpHasStream(MemoryListStream));
396 EXPECT_TRUE(DumpHasStream(ExceptionStream));
397 EXPECT_TRUE(DumpHasStream(SystemInfoStream));
398 EXPECT_TRUE(DumpHasStream(UnloadedModuleListStream));
399 EXPECT_TRUE(DumpHasStream(MiscInfoStream));
400
401 // We expect PEB and TEBs in this dump.
402 EXPECT_TRUE(DumpHasTebs());
403 EXPECT_TRUE(DumpHasPeb());
404
405 EXPECT_FALSE(DumpHasStream(ThreadExListStream));
406 EXPECT_FALSE(DumpHasStream(Memory64ListStream));
407 EXPECT_FALSE(DumpHasStream(CommentStreamA));
408 EXPECT_FALSE(DumpHasStream(CommentStreamW));
409 EXPECT_FALSE(DumpHasStream(HandleDataStream));
410 EXPECT_FALSE(DumpHasStream(FunctionTableStream));
411 EXPECT_FALSE(DumpHasStream(MemoryInfoListStream));
412 EXPECT_FALSE(DumpHasStream(ThreadInfoListStream));
413 EXPECT_FALSE(DumpHasStream(HandleOperationListStream));
414 EXPECT_FALSE(DumpHasStream(TokenStream));
415
416 // We expect no off-stack memory in this dump.
417 EXPECT_FALSE(DumpHasMemory(this));
418 }
419
420 TEST_F(MinidumpTest, LargerDump) {
421 ASSERT_TRUE(WriteDump(kLargerDumpType));
422
423 // The dump should have all of these streams.
424 EXPECT_TRUE(DumpHasStream(ThreadListStream));
425 EXPECT_TRUE(DumpHasStream(ModuleListStream));
426 EXPECT_TRUE(DumpHasStream(MemoryListStream));
427 EXPECT_TRUE(DumpHasStream(ExceptionStream));
428 EXPECT_TRUE(DumpHasStream(SystemInfoStream));
429 EXPECT_TRUE(DumpHasStream(UnloadedModuleListStream));
430 EXPECT_TRUE(DumpHasStream(MiscInfoStream));
431
432 // We expect memory referenced by stack in this dump.
433 EXPECT_TRUE(DumpHasMemory(this));
434
435 // We expect PEB and TEBs in this dump.
436 EXPECT_TRUE(DumpHasTebs());
437 EXPECT_TRUE(DumpHasPeb());
438
439 EXPECT_FALSE(DumpHasStream(ThreadExListStream));
440 EXPECT_FALSE(DumpHasStream(Memory64ListStream));
441 EXPECT_FALSE(DumpHasStream(CommentStreamA));
442 EXPECT_FALSE(DumpHasStream(CommentStreamW));
443 EXPECT_FALSE(DumpHasStream(HandleDataStream));
444 EXPECT_FALSE(DumpHasStream(FunctionTableStream));
445 EXPECT_FALSE(DumpHasStream(MemoryInfoListStream));
446 EXPECT_FALSE(DumpHasStream(ThreadInfoListStream));
447 EXPECT_FALSE(DumpHasStream(HandleOperationListStream));
448 EXPECT_FALSE(DumpHasStream(TokenStream));
449 }
450
451 TEST_F(MinidumpTest, FullDump) {
452 ASSERT_TRUE(WriteDump(kFullDumpType));
453
454 // The dump should have all of these streams.
455 EXPECT_TRUE(DumpHasStream(ThreadListStream));
456 EXPECT_TRUE(DumpHasStream(ModuleListStream));
457 EXPECT_TRUE(DumpHasStream(Memory64ListStream));
458 EXPECT_TRUE(DumpHasStream(ExceptionStream));
459 EXPECT_TRUE(DumpHasStream(SystemInfoStream));
460 EXPECT_TRUE(DumpHasStream(UnloadedModuleListStream));
461 EXPECT_TRUE(DumpHasStream(MiscInfoStream));
462 EXPECT_TRUE(DumpHasStream(HandleDataStream));
463
464 // We expect memory referenced by stack in this dump.
465 EXPECT_TRUE(DumpHasMemory(this));
466
467 // We expect PEB and TEBs in this dump.
468 EXPECT_TRUE(DumpHasTebs());
469 EXPECT_TRUE(DumpHasPeb());
470
471 EXPECT_FALSE(DumpHasStream(ThreadExListStream));
472 EXPECT_FALSE(DumpHasStream(MemoryListStream));
473 EXPECT_FALSE(DumpHasStream(CommentStreamA));
474 EXPECT_FALSE(DumpHasStream(CommentStreamW));
475 EXPECT_FALSE(DumpHasStream(FunctionTableStream));
476 EXPECT_FALSE(DumpHasStream(MemoryInfoListStream));
477 EXPECT_FALSE(DumpHasStream(ThreadInfoListStream));
478 EXPECT_FALSE(DumpHasStream(HandleOperationListStream));
479 EXPECT_FALSE(DumpHasStream(TokenStream));
480 }
481
482 } // namespace
OLDNEW
« no previous file with comments | « src/client/windows/unittests/dump_analysis.h ('k') | src/client/windows/unittests/exception_handler_death_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698