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

Unified Diff: src/processor/minidump.cc

Issue 1251593007: Add support for Linux memory mapping stream and remove ELF header usage (Closed) Base URL: http://google-breakpad.googlecode.com/svn/trunk/
Patch Set: Created 5 years, 5 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 | « src/processor/exploitability_unittest.cc ('k') | src/processor/proc_maps_linux.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/processor/minidump.cc
===================================================================
--- src/processor/minidump.cc (revision 1474)
+++ src/processor/minidump.cc (working copy)
@@ -55,6 +55,7 @@
#include <iostream>
#include <limits>
#include <map>
+#include <sstream>
#include <vector>
#include "processor/range_map-inl.h"
@@ -71,6 +72,7 @@
using std::istream;
using std::ifstream;
using std::numeric_limits;
+using std::stringstream;
using std::vector;
// Returns true iff |context_size| matches exactly one of the sizes of the
@@ -3972,8 +3974,144 @@
}
}
+//
+// MinidumpLinuxMaps
+//
+MinidumpLinuxMaps::MinidumpLinuxMaps(Minidump *minidump)
+ : MinidumpObject(minidump) {
+}
+
+void MinidumpLinuxMaps::Print() {
+ if (!valid_) {
+ BPLOG(ERROR) << "MinidumpLinuxMaps cannot print invalid data";
+ return;
+ }
+ std::cout << GetPathname() << std::endl;
+}
+
//
+// MinidumpLinuxMapsList
+//
+
+MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump *minidump)
+ : MinidumpStream(minidump),
+ maps_(NULL),
+ maps_count_(0) {
+}
+
+MinidumpLinuxMapsList::~MinidumpLinuxMapsList() {
+ for (unsigned int i = 0; i < maps_->size(); i++) {
+ delete (*maps_)[i];
+ }
+ delete maps_;
+}
+
+const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsForAddress(
+ uint64_t address) const {
+ if (!valid_) {
+ BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsForAddress";
+ return NULL;
+ }
+
+ // Search every memory mapping.
+ for (unsigned int index = 0; index < maps_count_; index++) {
+ // Check if address is within bounds of the current memory region.
+ if ((*maps_)[index]->GetBase() <= address &&
+ (*maps_)[index]->GetBase() + (*maps_)[index]->GetSize() > address) {
+ return (*maps_)[index];
+ }
+ }
+
+ // No mapping encloses the memory address.
+ BPLOG(ERROR) << "MinidumpLinuxMapsList has no mapping at "
+ << HexString(address);
+ return NULL;
+}
+
+const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsAtIndex(
+ unsigned int index) const {
+ if (!valid_) {
+ BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsAtIndex";
+ return NULL;
+ }
+
+ // Index out of bounds.
+ if (index >= maps_count_) {
+ BPLOG(ERROR) << "MinidumpLinuxMapsList index of out range: "
+ << index
+ << "/"
+ << maps_count_;
+ return NULL;
+ }
+ return (*maps_)[index];
+}
+
+bool MinidumpLinuxMapsList::Read(uint32_t expected_size) {
+ // Invalidate cached data.
+ delete maps_;
+ maps_ = NULL;
+ maps_count_ = 0;
+
+ valid_ = false;
+
+ // Load and check expected stream length.
+ uint32_t length = 0;
+ if (!minidump_->SeekToStreamType(MD_LINUX_MAPS, &length)) {
+ BPLOG(ERROR) << "MinidumpLinuxMapsList stream type not found";
+ return false;
+ }
+ if (expected_size != length) {
+ BPLOG(ERROR) << "MinidumpLinuxMapsList size mismatch: "
+ << expected_size
+ << " != "
+ << length;
+ return false;
+ }
+
+ // Create a vector to read stream data. The vector needs to have
+ // at least enough capacity to read all the data.
+ vector<char> mapping_bytes(length);
+ if (!minidump_->ReadBytes(&mapping_bytes[0], length)) {
+ BPLOG(ERROR) << "MinidumpLinuxMapsList failed to read bytes";
+ return false;
+ }
+ string map_string(mapping_bytes.begin(), mapping_bytes.end());
+ vector<MappedMemoryRegion> all_regions;
+
+ // Parse string into mapping data.
+ if (!ParseProcMaps(map_string, &all_regions)) {
+ return false;
+ }
+
+ scoped_ptr<MinidumpLinuxMappings> maps(new MinidumpLinuxMappings());
+
+ // Push mapping data into wrapper classes.
+ for (size_t i = 0; i < all_regions.size(); i++) {
+ scoped_ptr<MinidumpLinuxMaps> ele(new MinidumpLinuxMaps(minidump_));
+ ele->region_ = all_regions[i];
+ ele->valid_ = true;
+ maps->push_back(ele.release());
+ }
+
+ // Set instance variables.
+ maps_ = maps.release();
+ maps_count_ = maps_->size();
+ valid_ = true;
+ return true;
+}
+
+void MinidumpLinuxMapsList::Print() {
+ if (!valid_) {
+ BPLOG(ERROR) << "MinidumpLinuxMapsList cannot print valid data";
+ return;
+ }
+ for (size_t i = 0; i < maps_->size(); i++) {
+ (*maps_)[i]->Print();
+ }
+}
+
+//
// Minidump
//
@@ -4292,6 +4430,11 @@
return GetStream(&memory_info_list);
}
+MinidumpLinuxMapsList *Minidump::GetLinuxMapsList() {
+ MinidumpLinuxMapsList *linux_maps_list;
+ return GetStream(&linux_maps_list);
+}
+
static const char* get_stream_name(uint32_t stream_type) {
switch (stream_type) {
case MD_UNUSED_STREAM:
« no previous file with comments | « src/processor/exploitability_unittest.cc ('k') | src/processor/proc_maps_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698