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

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

Issue 1796803003: Add statistics about free space to microdump format. (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Created 4 years, 9 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 | « no previous file | 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 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 // 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
Primiano Tucci (use gerrit) 2016/04/07 18:07:39 in general in breakpad client we don't allow anyth
Tobias Sargeant 2016/05/03 13:43:19 Acknowledged.
35 #include <algorithm>
35 #include <sys/utsname.h> 36 #include <sys/utsname.h>
36 37
37 #include "client/linux/dump_writer_common/thread_info.h" 38 #include "client/linux/dump_writer_common/thread_info.h"
38 #include "client/linux/dump_writer_common/ucontext_reader.h" 39 #include "client/linux/dump_writer_common/ucontext_reader.h"
39 #include "client/linux/handler/exception_handler.h" 40 #include "client/linux/handler/exception_handler.h"
40 #include "client/linux/handler/microdump_extra_info.h" 41 #include "client/linux/handler/microdump_extra_info.h"
41 #include "client/linux/log/log.h" 42 #include "client/linux/log/log.h"
42 #include "client/linux/minidump_writer/linux_ptrace_dumper.h" 43 #include "client/linux/minidump_writer/linux_ptrace_dumper.h"
43 #include "common/linux/linux_libc_support.h" 44 #include "common/linux/linux_libc_support.h"
45 #include "common/memory.h"
44 46
45 namespace { 47 namespace {
46 48
47 using google_breakpad::ExceptionHandler; 49 using google_breakpad::ExceptionHandler;
48 using google_breakpad::LinuxDumper; 50 using google_breakpad::LinuxDumper;
49 using google_breakpad::LinuxPtraceDumper; 51 using google_breakpad::LinuxPtraceDumper;
50 using google_breakpad::MappingInfo; 52 using google_breakpad::MappingInfo;
51 using google_breakpad::MappingList; 53 using google_breakpad::MappingList;
52 using google_breakpad::MicrodumpExtraInfo; 54 using google_breakpad::MicrodumpExtraInfo;
53 using google_breakpad::RawContextCPU; 55 using google_breakpad::RawContextCPU;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 return false; 88 return false;
87 return dumper_->ThreadsSuspend() && dumper_->LateInit(); 89 return dumper_->ThreadsSuspend() && dumper_->LateInit();
88 } 90 }
89 91
90 bool Dump() { 92 bool Dump() {
91 bool success; 93 bool success;
92 LogLine("-----BEGIN BREAKPAD MICRODUMP-----"); 94 LogLine("-----BEGIN BREAKPAD MICRODUMP-----");
93 DumpProductInformation(); 95 DumpProductInformation();
94 DumpOSInformation(); 96 DumpOSInformation();
95 DumpGPUInformation(); 97 DumpGPUInformation();
98 DumpFreeSpace();
96 success = DumpCrashingThread(); 99 success = DumpCrashingThread();
97 if (success) 100 if (success)
98 success = DumpMappings(); 101 success = DumpMappings();
99 LogLine("-----END BREAKPAD MICRODUMP-----"); 102 LogLine("-----END BREAKPAD MICRODUMP-----");
100 dumper_->ThreadsResume(); 103 dumper_->ThreadsResume();
101 return success; 104 return success;
102 } 105 }
103 106
104 private: 107 private:
105 // Writes one line to the system log. 108 // Writes one line to the system log.
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 LogAppend(module_identifier.data4[3]); 372 LogAppend(module_identifier.data4[3]);
370 LogAppend(module_identifier.data4[4]); 373 LogAppend(module_identifier.data4[4]);
371 LogAppend(module_identifier.data4[5]); 374 LogAppend(module_identifier.data4[5]);
372 LogAppend(module_identifier.data4[6]); 375 LogAppend(module_identifier.data4[6]);
373 LogAppend(module_identifier.data4[7]); 376 LogAppend(module_identifier.data4[7]);
374 LogAppend("0 "); // Age is always 0 on Linux. 377 LogAppend("0 "); // Age is always 0 on Linux.
375 LogAppend(file_name); 378 LogAppend(file_name);
376 LogCommitLine(); 379 LogCommitLine();
377 } 380 }
378 381
382 static bool MappingsAreAdjacent(const MappingInfo *a, const MappingInfo *b) {
Primiano Tucci (use gerrit) 2016/04/07 18:07:39 should these static functions just be anonymous na
Primiano Tucci (use gerrit) 2016/04/07 18:07:39 nit: * should be close to the type, i.e. MappingIn
383 // Because of load biasing, we can end up with a situation where two
384 // mappings actually overlap. So we will define adjacency to also include a
385 // b start address that lies within a's address range (including starting
386 // immediately after a).
387 // Because load biasing only ever moves the start address backwards, the end
388 // address should still increase.
389 return a->start_addr <= b->start_addr &&
390 a->start_addr + a->size >= b->start_addr;
391 }
392
393 static bool StartAddrLessThan(const MappingInfo *a, const MappingInfo *b) {
394 return a->start_addr < b->start_addr;
395 }
396
397 static size_t NextOrderedMapping(
398 const google_breakpad::wasteful_vector<MappingInfo*>& mappings,
399 size_t curr) {
400 size_t best = mappings.size();
401 for (size_t next = 0; next < mappings.size(); ++next) {
402 if (StartAddrLessThan(mappings[curr], mappings[next])) {
403 if (best == mappings.size() ||
404 StartAddrLessThan(mappings[next], mappings[best]))
405 best = next;
406 }
407 }
408 return best;
409 }
410
411 bool DumpFreeSpace() {
412 const google_breakpad::wasteful_vector<MappingInfo*>& mappings =
413 dumper_->mappings();
414 if (mappings.size() == 0) return false;
415
416 // This is complicated by the fact that mappings is not in order. It should
417 // be mostly in order, however the mapping that contains the entry point for
418 // the process is always at the front of the vector.
419
420 static const int HBITS = sizeof(size_t)*8;
Primiano Tucci (use gerrit) 2016/04/07 18:07:39 nit: space between ) * 8
Tobias Sargeant 2016/05/03 13:43:19 Done.
421 int hole_hist[HBITS];
422 std::fill(hole_hist, hole_hist + HBITS, 0);
Primiano Tucci (use gerrit) 2016/04/07 18:07:39 nope, in breakpad we cannot rely on any std lib fu
Tobias Sargeant 2016/05/03 13:43:19 Done.
423
424 // Find the lowest address mapping.
425 size_t curr =
426 std::min_element(mappings.begin(), mappings.end(), StartAddrLessThan) -
427 mappings.begin();
428
429 uintptr_t lo_addr = mappings[curr]->start_addr;
430
431 int hole_cnt = 0;
432 size_t hole_max = 0;
433 size_t hole_tot = 0;
434
435 while (true) {
436 // Skip to the end of an adjacent run of mappings. This is an optimization
437 // for the fact that mappings is mostly sorted.
438 while (curr != mappings.size() - 1 &&
439 MappingsAreAdjacent(mappings[curr], mappings[curr + 1]))
440 ++curr;
441
442 size_t next = NextOrderedMapping(mappings, curr);
443 if (next == mappings.size())
444 break;
445
446 uintptr_t hole_lo = mappings[curr]->start_addr + mappings[curr]->size;
447 uintptr_t hole_hi = mappings[next]->start_addr;
448
449 if (hole_hi > hole_lo) {
450 size_t hole_sz = hole_hi - hole_lo;
451 hole_tot += hole_sz;
452 hole_max = std::max(hole_sz, hole_max);
453 ++hole_cnt;
454 size_t h = 0;
455 while (hole_sz) {
456 ++h;
457 hole_sz >>= 1;
458 }
459 ++hole_hist[h];
460 }
461 curr = next;
462 }
463
464 uintptr_t hi_addr = mappings[curr]->start_addr + mappings[curr]->size;
465
466 LogAppend("H ");
467 LogAppend(lo_addr);
468 LogAppend(" ");
469 LogAppend(hi_addr);
470
471 char buf[32];
472 snprintf(buf, 32, " %d %0zX %0zX", hole_cnt, hole_max, hole_tot);
Primiano Tucci (use gerrit) 2016/04/07 18:07:39 no snprintf for same reason. Please use the LogApp
Tobias Sargeant 2016/05/03 13:43:19 Done.
473 LogAppend(buf);
474 for (int i = 0; i < HBITS; ++i) {
475 if (!hole_hist[i]) continue;
476 snprintf(buf, 32, " %d:%d", i, hole_hist[i]);
477 LogAppend(buf);
478 }
479 LogCommitLine();
480 return true;
481 }
482
379 // Write information about the mappings in effect. 483 // Write information about the mappings in effect.
380 bool DumpMappings() { 484 bool DumpMappings() {
381 // First write all the mappings from the dumper 485 // First write all the mappings from the dumper
382 for (unsigned i = 0; i < dumper_->mappings().size(); ++i) { 486 for (unsigned i = 0; i < dumper_->mappings().size(); ++i) {
383 const MappingInfo& mapping = *dumper_->mappings()[i]; 487 const MappingInfo& mapping = *dumper_->mappings()[i];
384 if (mapping.name[0] == 0 || // only want modules with filenames. 488 if (mapping.name[0] == 0 || // only want modules with filenames.
385 !mapping.exec || // only want executable mappings. 489 !mapping.exec || // only want executable mappings.
386 mapping.size < 4096 || // too small to get a signature for. 490 mapping.size < 4096 || // too small to get a signature for.
387 HaveMappingInfo(mapping)) { 491 HaveMappingInfo(mapping)) {
388 continue; 492 continue;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 dumper.set_crash_signal(context->siginfo.si_signo); 534 dumper.set_crash_signal(context->siginfo.si_signo);
431 dumper.set_crash_thread(context->tid); 535 dumper.set_crash_thread(context->tid);
432 } 536 }
433 MicrodumpWriter writer(context, mappings, microdump_extra_info, &dumper); 537 MicrodumpWriter writer(context, mappings, microdump_extra_info, &dumper);
434 if (!writer.Init()) 538 if (!writer.Init())
435 return false; 539 return false;
436 return writer.Dump(); 540 return writer.Dump();
437 } 541 }
438 542
439 } // namespace google_breakpad 543 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698