aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/linux')
-rw-r--r--src/client/linux/microdump_writer/microdump_writer.cc16
-rw-r--r--src/client/linux/minidump_writer/linux_dumper.h7
2 files changed, 22 insertions, 1 deletions
diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc
index 065ca0b7..3764eec2 100644
--- a/src/client/linux/microdump_writer/microdump_writer.cc
+++ b/src/client/linux/microdump_writer/microdump_writer.cc
@@ -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
diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h
index 23c78e08..3a9a2e8b 100644
--- a/src/client/linux/minidump_writer/linux_dumper.h
+++ b/src/client/linux/minidump_writer/linux_dumper.h
@@ -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_; }