mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
Add MinidumpExceptionWriter::InitializeFromSnapshot() and test.
TEST=minidump_test MinidumpExceptionWriter.InitializeFromSnapshot R=rsesek@chromium.org Review URL: https://codereview.chromium.org/698673002
This commit is contained in:
parent
8248c030e2
commit
62b0976290
@ -18,6 +18,7 @@
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "minidump/minidump_context_writer.h"
|
||||
#include "snapshot/exception_snapshot.h"
|
||||
#include "util/file/file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -29,6 +30,26 @@ MinidumpExceptionWriter::MinidumpExceptionWriter()
|
||||
MinidumpExceptionWriter::~MinidumpExceptionWriter() {
|
||||
}
|
||||
|
||||
void MinidumpExceptionWriter::InitializeFromSnapshot(
|
||||
const ExceptionSnapshot* exception_snapshot,
|
||||
const MinidumpThreadIDMap* thread_id_map) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(!context_);
|
||||
|
||||
auto thread_id_it = thread_id_map->find(exception_snapshot->ThreadID());
|
||||
DCHECK(thread_id_it != thread_id_map->end());
|
||||
SetThreadID(thread_id_it->second);
|
||||
|
||||
SetExceptionCode(exception_snapshot->Exception());
|
||||
SetExceptionFlags(exception_snapshot->ExceptionInfo());
|
||||
SetExceptionAddress(exception_snapshot->ExceptionAddress());
|
||||
SetExceptionInformation(exception_snapshot->Codes());
|
||||
|
||||
scoped_ptr<MinidumpContextWriter> context =
|
||||
MinidumpContextWriter::CreateFromSnapshot(exception_snapshot->Context());
|
||||
SetContext(context.Pass());
|
||||
}
|
||||
|
||||
void MinidumpExceptionWriter::SetContext(
|
||||
scoped_ptr<MinidumpContextWriter> context) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
@ -23,9 +23,11 @@
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "minidump/minidump_stream_writer.h"
|
||||
#include "minidump/minidump_thread_id_map.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
class ExceptionSnapshot;
|
||||
class MinidumpContextWriter;
|
||||
|
||||
//! \brief The writer for a MINIDUMP_EXCEPTION_STREAM stream in a minidump file.
|
||||
@ -34,6 +36,21 @@ class MinidumpExceptionWriter final : public internal::MinidumpStreamWriter {
|
||||
MinidumpExceptionWriter();
|
||||
~MinidumpExceptionWriter() override;
|
||||
|
||||
//! \brief Initializes the MINIDUMP_EXCEPTION_STREAM based on \a
|
||||
//! exception_snapshot.
|
||||
//!
|
||||
//! \param[in] exception_snapshot The exception snapshot to use as source
|
||||
//! data.
|
||||
//! \param[in] thread_id_map A MinidumpThreadIDMap to be consulted to
|
||||
//! determine the 32-bit minidump thread ID to use for the thread
|
||||
//! identified by \a exception_snapshot.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable. No mutator methods may be called before
|
||||
//! this method, and it is not normally necessary to call any mutator
|
||||
//! methods after this method.
|
||||
void InitializeFromSnapshot(const ExceptionSnapshot* exception_snapshot,
|
||||
const MinidumpThreadIDMap* thread_id_map);
|
||||
|
||||
//! \brief Arranges for MINIDUMP_EXCEPTION_STREAM::ThreadContext to point to
|
||||
//! the CPU context to be written by \a context.
|
||||
//!
|
||||
|
@ -26,9 +26,12 @@
|
||||
#include "minidump/minidump_context_writer.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "minidump/minidump_thread_id_map.h"
|
||||
#include "minidump/test/minidump_context_test_util.h"
|
||||
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
#include "snapshot/test/test_cpu_context.h"
|
||||
#include "snapshot/test/test_exception_snapshot.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -194,6 +197,62 @@ TEST(MinidumpExceptionWriter, Standard) {
|
||||
ExpectMinidumpContextX86(kSeed, observed_context, false));
|
||||
}
|
||||
|
||||
TEST(MinidumpExceptionWriter, InitializeFromSnapshot) {
|
||||
std::vector<uint64_t> exception_codes;
|
||||
exception_codes.push_back(0x1000000000000000);
|
||||
exception_codes.push_back(0x5555555555555555);
|
||||
|
||||
MINIDUMP_EXCEPTION_STREAM expect_exception = {};
|
||||
|
||||
expect_exception.ThreadId = 123;
|
||||
expect_exception.ExceptionRecord.ExceptionCode = 100;
|
||||
expect_exception.ExceptionRecord.ExceptionFlags = 1;
|
||||
expect_exception.ExceptionRecord.ExceptionAddress = 0xfedcba9876543210;
|
||||
expect_exception.ExceptionRecord.NumberParameters = exception_codes.size();
|
||||
for (size_t index = 0; index < exception_codes.size(); ++index) {
|
||||
expect_exception.ExceptionRecord.ExceptionInformation[index] =
|
||||
exception_codes[index];
|
||||
}
|
||||
const uint64_t kThreadID = 0xaaaaaaaaaaaaaaaa;
|
||||
const uint32_t kSeed = 65;
|
||||
|
||||
TestExceptionSnapshot exception_snapshot;
|
||||
exception_snapshot.SetThreadID(kThreadID);
|
||||
exception_snapshot.SetException(
|
||||
expect_exception.ExceptionRecord.ExceptionCode);
|
||||
exception_snapshot.SetExceptionInfo(
|
||||
expect_exception.ExceptionRecord.ExceptionFlags);
|
||||
exception_snapshot.SetExceptionAddress(
|
||||
expect_exception.ExceptionRecord.ExceptionAddress);
|
||||
exception_snapshot.SetCodes(exception_codes);
|
||||
|
||||
InitializeCPUContextX86(exception_snapshot.MutableContext(), kSeed);
|
||||
|
||||
MinidumpThreadIDMap thread_id_map;
|
||||
thread_id_map[kThreadID] = expect_exception.ThreadId;
|
||||
|
||||
auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter());
|
||||
exception_writer->InitializeFromSnapshot(&exception_snapshot, &thread_id_map);
|
||||
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
minidump_file_writer.AddStream(exception_writer.Pass());
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MINIDUMP_EXCEPTION_STREAM* exception;
|
||||
ASSERT_NO_FATAL_FAILURE(GetExceptionStream(file_writer.string(), &exception));
|
||||
|
||||
const MinidumpContextX86* observed_context;
|
||||
ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expect_exception,
|
||||
exception,
|
||||
file_writer.string(),
|
||||
&observed_context));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
ExpectMinidumpContextX86(kSeed, observed_context, true));
|
||||
}
|
||||
|
||||
TEST(MinidumpExceptionWriterDeathTest, NoContext) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter());
|
||||
|
@ -88,6 +88,8 @@
|
||||
'sources': [
|
||||
'test/test_cpu_context.cc',
|
||||
'test/test_cpu_context.h',
|
||||
'test/test_exception_snapshot.cc',
|
||||
'test/test_exception_snapshot.h',
|
||||
'test/test_memory_snapshot.cc',
|
||||
'test/test_memory_snapshot.h',
|
||||
'test/test_module_snapshot.cc',
|
||||
|
59
snapshot/test/test_exception_snapshot.cc
Normal file
59
snapshot/test/test_exception_snapshot.cc
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2014 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/test/test_exception_snapshot.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
TestExceptionSnapshot::TestExceptionSnapshot()
|
||||
: context_union_(),
|
||||
context_(),
|
||||
thread_id_(0),
|
||||
exception_(0),
|
||||
exception_info_(0),
|
||||
exception_address_(0),
|
||||
codes_() {
|
||||
context_.x86 = &context_union_.x86;
|
||||
}
|
||||
|
||||
TestExceptionSnapshot::~TestExceptionSnapshot() {
|
||||
}
|
||||
|
||||
const CPUContext* TestExceptionSnapshot::Context() const {
|
||||
return &context_;
|
||||
}
|
||||
|
||||
uint64_t TestExceptionSnapshot::ThreadID() const {
|
||||
return thread_id_;
|
||||
}
|
||||
|
||||
uint32_t TestExceptionSnapshot::Exception() const {
|
||||
return exception_;
|
||||
}
|
||||
|
||||
uint32_t TestExceptionSnapshot::ExceptionInfo() const {
|
||||
return exception_info_;
|
||||
}
|
||||
|
||||
uint64_t TestExceptionSnapshot::ExceptionAddress() const {
|
||||
return exception_address_;
|
||||
}
|
||||
|
||||
const std::vector<uint64_t>& TestExceptionSnapshot::Codes() const {
|
||||
return codes_;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
88
snapshot/test/test_exception_snapshot.h
Normal file
88
snapshot/test/test_exception_snapshot.h
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2014 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_TEST_TEST_EXCEPTION_SNAPSHOT_H_
|
||||
#define CRASHPAD_SNAPSHOT_TEST_TEST_EXCEPTION_SNAPSHOT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "snapshot/cpu_context.h"
|
||||
#include "snapshot/exception_snapshot.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
//! \brief A test ExceptionSnapshot that can carry arbitrary data for testing
|
||||
//! purposes.
|
||||
class TestExceptionSnapshot final : public ExceptionSnapshot {
|
||||
public:
|
||||
TestExceptionSnapshot();
|
||||
~TestExceptionSnapshot();
|
||||
|
||||
//! \brief Obtains a pointer to the underlying mutable CPUContext structure.
|
||||
//!
|
||||
//! This method is intended to be used by callers to populate the CPUContext
|
||||
//! structure.
|
||||
//!
|
||||
//! \return The same pointer that Context() does, while treating the data as
|
||||
//! mutable.
|
||||
//!
|
||||
//! \attention This returns a non-`const` pointer to this object’s private
|
||||
//! data so that a caller can populate the context structure directly.
|
||||
//! This is done because providing setter interfaces to each field in the
|
||||
//! context structure would be unwieldy and cumbersome. Care must be taken
|
||||
//! to populate the context structure correctly.
|
||||
CPUContext* MutableContext() { return &context_; }
|
||||
|
||||
void SetThreadID(uint64_t thread_id) { thread_id_ = thread_id; }
|
||||
void SetException(uint32_t exception) { exception_ = exception; }
|
||||
void SetExceptionInfo(uint32_t exception_info) {
|
||||
exception_info_ = exception_info;
|
||||
}
|
||||
void SetExceptionAddress(uint64_t exception_address) {
|
||||
exception_address_ = exception_address;
|
||||
}
|
||||
void SetCodes(const std::vector<uint64_t>& codes) { codes_ = codes; }
|
||||
|
||||
// ExceptionSnapshot:
|
||||
|
||||
const CPUContext* Context() const override;
|
||||
uint64_t ThreadID() const override;
|
||||
uint32_t Exception() const override;
|
||||
uint32_t ExceptionInfo() const override;
|
||||
uint64_t ExceptionAddress() const override;
|
||||
const std::vector<uint64_t>& Codes() const override;
|
||||
|
||||
private:
|
||||
union {
|
||||
CPUContextX86 x86;
|
||||
CPUContextX86_64 x86_64;
|
||||
} context_union_;
|
||||
CPUContext context_;
|
||||
uint64_t thread_id_;
|
||||
uint32_t exception_;
|
||||
uint32_t exception_info_;
|
||||
uint64_t exception_address_;
|
||||
std::vector<uint64_t> codes_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TestExceptionSnapshot);
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_TEST_TEST_EXCEPTION_SNAPSHOT_H_
|
Loading…
x
Reference in New Issue
Block a user