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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/client/linux/microdump_writer/microdump_writer.cc
diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc
index 91697ed840f930635c494764cac29ca6dd55b09a..138a2b0d86463b0ab0262253beda5e2c5d336123 100644
--- a/src/client/linux/microdump_writer/microdump_writer.cc
+++ b/src/client/linux/microdump_writer/microdump_writer.cc
@@ -32,6 +32,7 @@
#include "client/linux/microdump_writer/microdump_writer.h"
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.
+#include <algorithm>
#include <sys/utsname.h>
#include "client/linux/dump_writer_common/thread_info.h"
@@ -41,6 +42,7 @@
#include "client/linux/log/log.h"
#include "client/linux/minidump_writer/linux_ptrace_dumper.h"
#include "common/linux/linux_libc_support.h"
+#include "common/memory.h"
namespace {
@@ -93,6 +95,7 @@ class MicrodumpWriter {
DumpProductInformation();
DumpOSInformation();
DumpGPUInformation();
+ DumpFreeSpace();
success = DumpCrashingThread();
if (success)
success = DumpMappings();
@@ -376,6 +379,107 @@ class MicrodumpWriter {
LogCommitLine();
}
+ 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
+ // Because of load biasing, we can end up with a situation where two
+ // mappings actually overlap. So we will define adjacency to also include a
+ // b start address that lies within a's address range (including starting
+ // immediately after a).
+ // Because load biasing only ever moves the start address backwards, the end
+ // address should still increase.
+ return a->start_addr <= b->start_addr &&
+ a->start_addr + a->size >= b->start_addr;
+ }
+
+ static bool StartAddrLessThan(const MappingInfo *a, const MappingInfo *b) {
+ return a->start_addr < b->start_addr;
+ }
+
+ static size_t NextOrderedMapping(
+ const google_breakpad::wasteful_vector<MappingInfo*>& mappings,
+ size_t curr) {
+ size_t best = mappings.size();
+ for (size_t next = 0; next < mappings.size(); ++next) {
+ if (StartAddrLessThan(mappings[curr], mappings[next])) {
+ if (best == mappings.size() ||
+ StartAddrLessThan(mappings[next], mappings[best]))
+ best = next;
+ }
+ }
+ return best;
+ }
+
+ bool DumpFreeSpace() {
+ const google_breakpad::wasteful_vector<MappingInfo*>& mappings =
+ dumper_->mappings();
+ if (mappings.size() == 0) return false;
+
+ // This is complicated by the fact that mappings is not in order. It should
+ // be mostly in order, however the mapping that contains the entry point for
+ // the process is always at the front of the vector.
+
+ 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.
+ int hole_hist[HBITS];
+ 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.
+
+ // Find the lowest address mapping.
+ size_t curr =
+ std::min_element(mappings.begin(), mappings.end(), StartAddrLessThan) -
+ mappings.begin();
+
+ uintptr_t lo_addr = mappings[curr]->start_addr;
+
+ int hole_cnt = 0;
+ size_t hole_max = 0;
+ size_t hole_tot = 0;
+
+ while (true) {
+ // Skip to the end of an adjacent run of mappings. This is an optimization
+ // for the fact that mappings is mostly sorted.
+ while (curr != mappings.size() - 1 &&
+ MappingsAreAdjacent(mappings[curr], mappings[curr + 1]))
+ ++curr;
+
+ size_t next = NextOrderedMapping(mappings, curr);
+ if (next == mappings.size())
+ break;
+
+ uintptr_t hole_lo = mappings[curr]->start_addr + mappings[curr]->size;
+ uintptr_t hole_hi = mappings[next]->start_addr;
+
+ if (hole_hi > hole_lo) {
+ size_t hole_sz = hole_hi - hole_lo;
+ hole_tot += hole_sz;
+ hole_max = std::max(hole_sz, hole_max);
+ ++hole_cnt;
+ size_t h = 0;
+ while (hole_sz) {
+ ++h;
+ hole_sz >>= 1;
+ }
+ ++hole_hist[h];
+ }
+ curr = next;
+ }
+
+ uintptr_t hi_addr = mappings[curr]->start_addr + mappings[curr]->size;
+
+ LogAppend("H ");
+ LogAppend(lo_addr);
+ LogAppend(" ");
+ LogAppend(hi_addr);
+
+ char buf[32];
+ 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.
+ LogAppend(buf);
+ for (int i = 0; i < HBITS; ++i) {
+ if (!hole_hist[i]) continue;
+ snprintf(buf, 32, " %d:%d", i, hole_hist[i]);
+ LogAppend(buf);
+ }
+ LogCommitLine();
+ return true;
+ }
+
// Write information about the mappings in effect.
bool DumpMappings() {
// First write all the mappings from the dumper
« 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