mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Add ProcessSnapshotMinidump, the beginning of the minidump variant of
the Snapshot family. For the time being, only ProcessSnapshotMinidump::AnnotationsSimpleMap() is implemented. In order to complete the initial uploader for Crashpad, ModuleSnapshotMinidump::AnnotationsSimpleMap() is also needed, to be accessed by ProcessSnapshotMinidump::Modules(). TEST=snapshot_test ProcessSnapshotMinidump.* R=rsesek@chromium.org Review URL: https://codereview.chromium.org/932153003
This commit is contained in:
parent
583314184a
commit
40b931bd8e
@ -107,6 +107,7 @@ void ProcessSnapshotMac::ProcessCPUTimes(timeval* user_time,
|
||||
|
||||
const std::map<std::string, std::string>&
|
||||
ProcessSnapshotMac::AnnotationsSimpleMap() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
return annotations_simple_map_;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,89 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/minidump/minidump_simple_string_dictionary_reader.h"
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "snapshot/minidump/minidump_string_reader.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace internal {
|
||||
|
||||
bool ReadMinidumpSimpleStringDictionary(
|
||||
FileReaderInterface* file_reader,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location,
|
||||
std::map<std::string, std::string>* dictionary) {
|
||||
if (location.Rva == 0) {
|
||||
dictionary->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (location.DataSize < sizeof(MinidumpSimpleStringDictionary)) {
|
||||
LOG(ERROR) << "simple_string_dictionary size mismatch";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_reader->SeekSet(location.Rva)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t entry_count;
|
||||
if (!file_reader->ReadExactly(&entry_count, sizeof(entry_count))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (location.DataSize !=
|
||||
entry_count * sizeof(MinidumpSimpleStringDictionaryEntry)) {
|
||||
LOG(ERROR) << "simple_string_dictionary size mismatch";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<MinidumpSimpleStringDictionaryEntry> entries(entry_count);
|
||||
if (!file_reader->ReadExactly(&entries[0],
|
||||
entry_count * sizeof(entries[0]))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> local_dictionary;
|
||||
for (const MinidumpSimpleStringDictionaryEntry& entry : entries) {
|
||||
std::string key;
|
||||
if (!ReadMinidumpUTF8String(file_reader, entry.key, &key)) {
|
||||
// Not a hard error, keep trying.
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string value;
|
||||
if (!ReadMinidumpUTF8String(file_reader, entry.value, &value)) {
|
||||
// Not a hard error, keep trying.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (local_dictionary.find(key) != local_dictionary.end()) {
|
||||
LOG(WARNING) << "duplicate key " << key << ", discarding value " << value;
|
||||
continue;
|
||||
}
|
||||
|
||||
local_dictionary.insert(std::make_pair(key, value));
|
||||
}
|
||||
|
||||
dictionary->swap(local_dictionary);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
44
snapshot/minidump/minidump_simple_string_dictionary_reader.h
Normal file
44
snapshot/minidump/minidump_simple_string_dictionary_reader.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_MINIDUMP_MINIDUMP_SIMPLE_STRING_DICTIONARY_READER_H_
|
||||
#define CRASHPAD_SNAPSHOT_MINIDUMP_MINIDUMP_SIMPLE_STRING_DICTIONARY_READER_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "util/file/file_reader.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace internal {
|
||||
|
||||
//! \brief Reads a MinidumpSimpleStringDictionary from a minidump file \a
|
||||
//! location in \a file_reader, and returns it in \a dictionary.
|
||||
//!
|
||||
//! \return `true` on success, with \a dictionary set by replacing its contents.
|
||||
//! `false` on failure, with a message logged. If any individual strings
|
||||
//! cannot be read, or if any duplicate keys are found, it is not considered
|
||||
//! an error, although a message will be logged.
|
||||
bool ReadMinidumpSimpleStringDictionary(
|
||||
FileReaderInterface* file_reader,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location,
|
||||
std::map<std::string, std::string>* dictionary);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_MINIDUMP_MINIDUMP_SIMPLE_STRING_DICTIONARY_READER_H_
|
50
snapshot/minidump/minidump_string_reader.cc
Normal file
50
snapshot/minidump/minidump_string_reader.cc
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/minidump/minidump_string_reader.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace internal {
|
||||
|
||||
bool ReadMinidumpUTF8String(FileReaderInterface* file_reader,
|
||||
RVA rva,
|
||||
std::string* string) {
|
||||
if (rva == 0) {
|
||||
string->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!file_reader->SeekSet(rva)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t string_size;
|
||||
if (!file_reader->ReadExactly(&string_size, sizeof(string_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string local_string(string_size, '\0');
|
||||
if (!file_reader->ReadExactly(&local_string[0], string_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string->swap(local_string);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
40
snapshot/minidump/minidump_string_reader.h
Normal file
40
snapshot/minidump/minidump_string_reader.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_MINIDUMP_MINIDUMP_STRING_READER_H_
|
||||
#define CRASHPAD_SNAPSHOT_MINIDUMP_MINIDUMP_STRING_READER_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "util/file/file_reader.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace internal {
|
||||
|
||||
//! \brief Reads a MinidumpUTF8String from a minidump file at offset \a rva in
|
||||
//! \a file_reader, and returns it in \a string.
|
||||
//!
|
||||
//! \return `true` on success, with \a string set. `false` on failure, with a
|
||||
//! message logged.
|
||||
bool ReadMinidumpUTF8String(FileReaderInterface* file_reader,
|
||||
RVA rva,
|
||||
std::string* string);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_MINIDUMP_MINIDUMP_STRING_READER_H_
|
189
snapshot/minidump/process_snapshot_minidump.cc
Normal file
189
snapshot/minidump/process_snapshot_minidump.cc
Normal file
@ -0,0 +1,189 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/minidump/process_snapshot_minidump.h"
|
||||
|
||||
#include "util/file/file_io.h"
|
||||
#include "snapshot/minidump/minidump_simple_string_dictionary_reader.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
ProcessSnapshotMinidump::ProcessSnapshotMinidump()
|
||||
: ProcessSnapshot(),
|
||||
header_(),
|
||||
stream_directory_(),
|
||||
stream_map_(),
|
||||
crashpad_info_(),
|
||||
annotations_simple_map_(),
|
||||
file_reader_(nullptr),
|
||||
initialized_() {
|
||||
}
|
||||
|
||||
ProcessSnapshotMinidump::~ProcessSnapshotMinidump() {
|
||||
}
|
||||
|
||||
bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) {
|
||||
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
||||
|
||||
file_reader_ = file_reader;
|
||||
|
||||
if (!file_reader_->SeekSet(0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_reader_->ReadExactly(&header_, sizeof(header_))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header_.Signature != MINIDUMP_SIGNATURE) {
|
||||
LOG(ERROR) << "minidump signature mismatch";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header_.Version != MINIDUMP_VERSION) {
|
||||
LOG(ERROR) << "minidump version mismatch";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_reader->SeekSet(header_.StreamDirectoryRva)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stream_directory_.resize(header_.NumberOfStreams);
|
||||
if (!file_reader_->ReadExactly(
|
||||
&stream_directory_[0],
|
||||
header_.NumberOfStreams * sizeof(stream_directory_[0]))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const MINIDUMP_DIRECTORY& directory : stream_directory_) {
|
||||
const MinidumpStreamType stream_type =
|
||||
static_cast<MinidumpStreamType>(directory.StreamType);
|
||||
if (stream_map_.find(stream_type) != stream_map_.end()) {
|
||||
LOG(ERROR) << "duplicate streams for type " << directory.StreamType;
|
||||
return false;
|
||||
}
|
||||
|
||||
stream_map_[stream_type] = &directory.Location;
|
||||
}
|
||||
|
||||
INITIALIZATION_STATE_SET_VALID(initialized_);
|
||||
|
||||
InitializeCrashpadInfo();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pid_t ProcessSnapshotMinidump::ProcessID() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t ProcessSnapshotMinidump::ParentProcessID() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ProcessSnapshotMinidump::SnapshotTime(timeval* snapshot_time) const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
snapshot_time->tv_sec = 0;
|
||||
snapshot_time->tv_usec = 0;
|
||||
}
|
||||
|
||||
void ProcessSnapshotMinidump::ProcessStartTime(timeval* start_time) const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
start_time->tv_sec = 0;
|
||||
start_time->tv_usec = 0;
|
||||
}
|
||||
|
||||
void ProcessSnapshotMinidump::ProcessCPUTimes(timeval* user_time,
|
||||
timeval* system_time) const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
user_time->tv_sec = 0;
|
||||
user_time->tv_usec = 0;
|
||||
system_time->tv_sec = 0;
|
||||
system_time->tv_usec = 0;
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string>&
|
||||
ProcessSnapshotMinidump::AnnotationsSimpleMap() const {
|
||||
// TODO(mark): This method should not be const, although the interface
|
||||
// currently imposes this requirement. Making it non-const would allow
|
||||
// annotations_simple_map_ to be lazily constructed: InitializeCrashpadInfo()
|
||||
// could be called here, and from other locations that require it, rather than
|
||||
// calling it from Initialize().
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
return annotations_simple_map_;
|
||||
}
|
||||
|
||||
const SystemSnapshot* ProcessSnapshotMinidump::System() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
return std::vector<const ThreadSnapshot*>();
|
||||
}
|
||||
|
||||
std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
return std::vector<const ModuleSnapshot*>();
|
||||
}
|
||||
|
||||
const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ProcessSnapshotMinidump::InitializeCrashpadInfo() {
|
||||
const auto& it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo);
|
||||
if (it == stream_map_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (it->second->DataSize < sizeof(crashpad_info_)) {
|
||||
LOG(ERROR) << "crashpad_info size mismatch";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file_reader_->SeekSet(it->second->Rva)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) {
|
||||
LOG(ERROR) << "crashpad_info version mismatch";
|
||||
return;
|
||||
}
|
||||
|
||||
internal::ReadMinidumpSimpleStringDictionary(
|
||||
file_reader_,
|
||||
crashpad_info_.simple_annotations,
|
||||
&annotations_simple_map_);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
85
snapshot/minidump/process_snapshot_minidump.h
Normal file
85
snapshot/minidump/process_snapshot_minidump.h
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_MINIDUMP_PROCESS_SNAPSHOT_MINIDUMP_H_
|
||||
#define CRASHPAD_SNAPSHOT_MINIDUMP_PROCESS_SNAPSHOT_MINIDUMP_H_
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "snapshot/exception_snapshot.h"
|
||||
#include "snapshot/module_snapshot.h"
|
||||
#include "snapshot/process_snapshot.h"
|
||||
#include "snapshot/system_snapshot.h"
|
||||
#include "snapshot/thread_snapshot.h"
|
||||
#include "util/file/file_reader.h"
|
||||
#include "util/misc/initialization_state_dcheck.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief A ProcessSnapshot based on a minidump file.
|
||||
class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
||||
public:
|
||||
ProcessSnapshotMinidump();
|
||||
~ProcessSnapshotMinidump() override;
|
||||
|
||||
//! \brief Initializes the object.
|
||||
//!
|
||||
//! \param[in] file_reader A file reader corresponding to a minidump file.
|
||||
//! The file reader must support seeking.
|
||||
//!
|
||||
//! \return `true` if the snapshot could be created, `false` otherwise with
|
||||
//! an appropriate message logged.
|
||||
bool Initialize(FileReaderInterface* file_reader);
|
||||
|
||||
// ProcessSnapshot:
|
||||
|
||||
pid_t ProcessID() const override;
|
||||
pid_t ParentProcessID() const override;
|
||||
void SnapshotTime(timeval* snapshot_time) const override;
|
||||
void ProcessStartTime(timeval* start_time) const override;
|
||||
void ProcessCPUTimes(timeval* user_time, timeval* system_time) const override;
|
||||
const std::map<std::string, std::string>& AnnotationsSimpleMap()
|
||||
const override;
|
||||
const SystemSnapshot* System() const override;
|
||||
std::vector<const ThreadSnapshot*> Threads() const override;
|
||||
std::vector<const ModuleSnapshot*> Modules() const override;
|
||||
const ExceptionSnapshot* Exception() const override;
|
||||
|
||||
private:
|
||||
// Initializes data carried in a MinidumpCrashpadInfo stream on behalf of
|
||||
// Initialize().
|
||||
void InitializeCrashpadInfo();
|
||||
|
||||
MINIDUMP_HEADER header_;
|
||||
std::vector<MINIDUMP_DIRECTORY> stream_directory_;
|
||||
std::map<MinidumpStreamType, const MINIDUMP_LOCATION_DESCRIPTOR*> stream_map_;
|
||||
MinidumpCrashpadInfo crashpad_info_;
|
||||
std::map<std::string, std::string> annotations_simple_map_;
|
||||
FileReaderInterface* file_reader_; // weak
|
||||
InitializationStateDcheck initialized_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ProcessSnapshotMinidump);
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_MINIDUMP_PROCESS_SNAPSHOT_MINIDUMP_H_
|
140
snapshot/minidump/process_snapshot_minidump_test.cc
Normal file
140
snapshot/minidump/process_snapshot_minidump_test.cc
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/minidump/process_snapshot_minidump.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "util/file/string_file.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
TEST(ProcessSnapshotMinidump, EmptyFile) {
|
||||
StringFile string_file;
|
||||
ProcessSnapshotMinidump process_snapshot;
|
||||
|
||||
EXPECT_FALSE(process_snapshot.Initialize(&string_file));
|
||||
}
|
||||
|
||||
TEST(ProcessSnapshotMinidump, InvalidSignatureAndVersion) {
|
||||
StringFile string_file;
|
||||
|
||||
MINIDUMP_HEADER header = {};
|
||||
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
ProcessSnapshotMinidump process_snapshot;
|
||||
EXPECT_FALSE(process_snapshot.Initialize(&string_file));
|
||||
}
|
||||
|
||||
TEST(ProcessSnapshotMinidump, Empty) {
|
||||
StringFile string_file;
|
||||
|
||||
MINIDUMP_HEADER header = {};
|
||||
header.Signature = MINIDUMP_SIGNATURE;
|
||||
header.Version = MINIDUMP_VERSION;
|
||||
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
ProcessSnapshotMinidump process_snapshot;
|
||||
EXPECT_TRUE(process_snapshot.Initialize(&string_file));
|
||||
}
|
||||
|
||||
TEST(ProcessSnapshotMinidump, AnnotationsSimpleMap) {
|
||||
StringFile string_file;
|
||||
|
||||
MINIDUMP_HEADER header = {};
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
MinidumpSimpleStringDictionaryEntry entry0 = {};
|
||||
entry0.key = static_cast<RVA>(string_file.SeekGet());
|
||||
const char kKey0[] = "the first key";
|
||||
uint32_t string_size = strlen(kKey0);
|
||||
EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
|
||||
EXPECT_TRUE(string_file.Write(kKey0, sizeof(kKey0)));
|
||||
|
||||
entry0.value = static_cast<RVA>(string_file.SeekGet());
|
||||
const char kValue0[] = "THE FIRST VALUE EVER!";
|
||||
string_size = strlen(kValue0);
|
||||
EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
|
||||
EXPECT_TRUE(string_file.Write(kValue0, sizeof(kValue0)));
|
||||
|
||||
MinidumpSimpleStringDictionaryEntry entry1 = {};
|
||||
entry1.key = static_cast<RVA>(string_file.SeekGet());
|
||||
const char kKey1[] = "2key";
|
||||
string_size = strlen(kKey1);
|
||||
EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
|
||||
EXPECT_TRUE(string_file.Write(kKey1, sizeof(kKey1)));
|
||||
|
||||
entry1.value = static_cast<RVA>(string_file.SeekGet());
|
||||
const char kValue1[] = "a lowly second value";
|
||||
string_size = strlen(kValue1);
|
||||
EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
|
||||
EXPECT_TRUE(string_file.Write(kValue1, sizeof(kValue1)));
|
||||
|
||||
MinidumpCrashpadInfo crashpad_info = {};
|
||||
crashpad_info.version = MinidumpCrashpadInfo::kVersion;
|
||||
|
||||
crashpad_info.simple_annotations.Rva =
|
||||
static_cast<RVA>(string_file.SeekGet());
|
||||
uint32_t simple_string_dictionary_entries = 2;
|
||||
EXPECT_TRUE(string_file.Write(&simple_string_dictionary_entries,
|
||||
sizeof(simple_string_dictionary_entries)));
|
||||
EXPECT_TRUE(string_file.Write(&entry0, sizeof(entry0)));
|
||||
EXPECT_TRUE(string_file.Write(&entry1, sizeof(entry1)));
|
||||
crashpad_info.simple_annotations.DataSize =
|
||||
simple_string_dictionary_entries *
|
||||
sizeof(MinidumpSimpleStringDictionaryEntry);
|
||||
|
||||
MINIDUMP_DIRECTORY crashpad_info_directory = {};
|
||||
crashpad_info_directory.StreamType = kMinidumpStreamTypeCrashpadInfo;
|
||||
crashpad_info_directory.Location.Rva =
|
||||
static_cast<RVA>(string_file.SeekGet());
|
||||
EXPECT_TRUE(string_file.Write(&crashpad_info, sizeof(crashpad_info)));
|
||||
crashpad_info_directory.Location.DataSize = sizeof(crashpad_info);
|
||||
|
||||
header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet());
|
||||
EXPECT_TRUE(string_file.Write(&crashpad_info_directory,
|
||||
sizeof(crashpad_info_directory)));
|
||||
|
||||
header.Signature = MINIDUMP_SIGNATURE;
|
||||
header.Version = MINIDUMP_VERSION;
|
||||
header.NumberOfStreams = 1;
|
||||
EXPECT_TRUE(string_file.SeekSet(0));
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
ProcessSnapshotMinidump process_snapshot;
|
||||
EXPECT_TRUE(process_snapshot.Initialize(&string_file));
|
||||
|
||||
const auto annotations_simple_map = process_snapshot.AnnotationsSimpleMap();
|
||||
EXPECT_EQ(2u, annotations_simple_map.size());
|
||||
|
||||
auto it = annotations_simple_map.find(kKey0);
|
||||
ASSERT_NE(it, annotations_simple_map.end());
|
||||
EXPECT_EQ(kValue0, it->second);
|
||||
|
||||
it = annotations_simple_map.find(kKey1);
|
||||
ASSERT_NE(it, annotations_simple_map.end());
|
||||
EXPECT_EQ(kValue1, it->second);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -67,6 +67,12 @@
|
||||
'mac/system_snapshot_mac.h',
|
||||
'mac/thread_snapshot_mac.cc',
|
||||
'mac/thread_snapshot_mac.h',
|
||||
'minidump/minidump_simple_string_dictionary_reader.cc',
|
||||
'minidump/minidump_simple_string_dictionary_reader.h',
|
||||
'minidump/minidump_string_reader.cc',
|
||||
'minidump/minidump_string_reader.h',
|
||||
'minidump/process_snapshot_minidump.cc',
|
||||
'minidump/process_snapshot_minidump.h',
|
||||
'memory_snapshot.h',
|
||||
'module_snapshot.h',
|
||||
'process_snapshot.h',
|
||||
@ -128,6 +134,7 @@
|
||||
'mac/process_reader_test.cc',
|
||||
'mac/process_types_test.cc',
|
||||
'mac/system_snapshot_mac_test.cc',
|
||||
'minidump/process_snapshot_minidump_test.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user