Treat the process stack as the top of memory for free space histograms.

Because we can't determine the top of userspace mappable memory
directly, we rely on the fact that the process stack is allocated at the
top of the address space (minus some randomization). Anything after that
should not count as free space.

BUG=695382

Change-Id: I68453aac9732c2bd4b87236b234518068dec6640
Reviewed-on: https://chromium-review.googlesource.com/446100
Reviewed-by: Primiano Tucci <primiano@chromium.org>
This commit is contained in:
Tobias Sargeant 2017-03-29 11:41:05 +01:00 committed by Tobias Sargeant
parent 219d0b15c4
commit 846b6335c5
2 changed files with 22 additions and 1 deletions

View file

@ -483,6 +483,12 @@ class MicrodumpWriter {
#if !defined(__LP64__)
void DumpFreeSpace() {
const MappingInfo* stack_mapping = nullptr;
ThreadInfo info;
if (dumper_->GetThreadInfoByIndex(dumper_->GetMainThreadIndex(), &info)) {
stack_mapping = dumper_->FindMappingNoBias(info.stack_pointer);
}
const google_breakpad::wasteful_vector<MappingInfo*>& mappings =
dumper_->mappings();
if (mappings.size() == 0) return;
@ -515,6 +521,14 @@ class MicrodumpWriter {
++curr;
}
if (mappings[curr] == stack_mapping) {
// Because we can't determine the top of userspace mappable
// memory we treat the start of the process stack as the top
// of the allocatable address space. Once we reach
// |stack_mapping| we are done scanning for free space regions.
break;
}
size_t next = NextOrderedMapping(mappings, curr);
if (next == std::numeric_limits<size_t>::max())
break;
@ -602,7 +616,7 @@ class MicrodumpWriter {
// crashed process. |stack_lower_bound_| <= |stack_pointer_|
uintptr_t stack_lower_bound_;
// The stack pointer in the crashed process.
// The stack pointer of the crashed thread.
uintptr_t stack_pointer_;
};
} // namespace

View file

@ -99,6 +99,13 @@ class LinuxDumper {
// Returns true on success. One must have called |ThreadsSuspend| first.
virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info) = 0;
size_t GetMainThreadIndex() const {
for (size_t i = 0; i < threads_.size(); ++i) {
if (threads_[i] == pid_) return i;
}
return -1u;
}
// These are only valid after a call to |Init|.
const wasteful_vector<pid_t> &threads() { return threads_; }
const wasteful_vector<MappingInfo*> &mappings() { return mappings_; }