mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
Write MINIDUMP_HANDLE_DATA_STREAM to minidump
R=mark@chromium.org BUG=crashpad:21, crashpad:52 Review URL: https://codereview.chromium.org/1419623003 .
This commit is contained in:
parent
3ac40a54d0
commit
3261edd997
@ -157,6 +157,9 @@ enum MINIDUMP_STREAM_TYPE {
|
|||||||
//! \brief The stream type for MINIDUMP_SYSTEM_INFO.
|
//! \brief The stream type for MINIDUMP_SYSTEM_INFO.
|
||||||
SystemInfoStream = 7,
|
SystemInfoStream = 7,
|
||||||
|
|
||||||
|
//! \brief The stream contains information about active `HANDLE`s.
|
||||||
|
HandleDataStream = 12,
|
||||||
|
|
||||||
//! \brief The stream type for MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
|
//! \brief The stream type for MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
|
||||||
//! MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4.
|
//! MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4.
|
||||||
//!
|
//!
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
'minidump_extensions.h',
|
'minidump_extensions.h',
|
||||||
'minidump_file_writer.cc',
|
'minidump_file_writer.cc',
|
||||||
'minidump_file_writer.h',
|
'minidump_file_writer.h',
|
||||||
|
'minidump_handle_writer.cc',
|
||||||
|
'minidump_handle_writer.h',
|
||||||
'minidump_memory_info_writer.cc',
|
'minidump_memory_info_writer.cc',
|
||||||
'minidump_memory_info_writer.h',
|
'minidump_memory_info_writer.h',
|
||||||
'minidump_memory_writer.cc',
|
'minidump_memory_writer.cc',
|
||||||
|
@ -71,6 +71,11 @@ enum MinidumpStreamType : uint32_t {
|
|||||||
//! \sa SystemInfoStream
|
//! \sa SystemInfoStream
|
||||||
kMinidumpStreamTypeSystemInfo = SystemInfoStream,
|
kMinidumpStreamTypeSystemInfo = SystemInfoStream,
|
||||||
|
|
||||||
|
//! \brief The stream type for MINIDUMP_HANDLE_DATA_STREAM.
|
||||||
|
//!
|
||||||
|
//! \sa HandleDataStream
|
||||||
|
kMinidumpStreamTypeHandleData = HandleDataStream,
|
||||||
|
|
||||||
//! \brief The stream type for MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
|
//! \brief The stream type for MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
|
||||||
//! MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4.
|
//! MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4.
|
||||||
//!
|
//!
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "minidump/minidump_crashpad_info_writer.h"
|
#include "minidump/minidump_crashpad_info_writer.h"
|
||||||
#include "minidump/minidump_exception_writer.h"
|
#include "minidump/minidump_exception_writer.h"
|
||||||
|
#include "minidump/minidump_handle_writer.h"
|
||||||
#include "minidump/minidump_memory_info_writer.h"
|
#include "minidump/minidump_memory_info_writer.h"
|
||||||
#include "minidump/minidump_memory_writer.h"
|
#include "minidump/minidump_memory_writer.h"
|
||||||
#include "minidump/minidump_misc_info_writer.h"
|
#include "minidump/minidump_misc_info_writer.h"
|
||||||
@ -108,6 +109,13 @@ void MinidumpFileWriter::InitializeFromSnapshot(
|
|||||||
AddStream(memory_info_list.Pass());
|
AddStream(memory_info_list.Pass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<HandleSnapshot> handles_snapshot = process_snapshot->Handles();
|
||||||
|
if (!handles_snapshot.empty()) {
|
||||||
|
auto handle_data_writer = make_scoped_ptr(new MinidumpHandleDataWriter());
|
||||||
|
handle_data_writer->InitializeFromSnapshot(handles_snapshot);
|
||||||
|
AddStream(handle_data_writer.Pass());
|
||||||
|
}
|
||||||
|
|
||||||
memory_list->AddFromSnapshot(process_snapshot->ExtraMemory());
|
memory_list->AddFromSnapshot(process_snapshot->ExtraMemory());
|
||||||
|
|
||||||
AddStream(memory_list.Pass());
|
AddStream(memory_list.Pass());
|
||||||
|
115
minidump/minidump_handle_writer.cc
Normal file
115
minidump/minidump_handle_writer.cc
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// 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 "minidump/minidump_handle_writer.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "minidump/minidump_extensions.h"
|
||||||
|
#include "util/file/file_writer.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
MinidumpHandleDataWriter::MinidumpHandleDataWriter()
|
||||||
|
: handle_data_stream_base_(), handle_descriptors_(), strings_() {
|
||||||
|
}
|
||||||
|
|
||||||
|
MinidumpHandleDataWriter::~MinidumpHandleDataWriter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MinidumpHandleDataWriter::InitializeFromSnapshot(
|
||||||
|
const std::vector<HandleSnapshot>& handle_snapshots) {
|
||||||
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
|
DCHECK(handle_descriptors_.empty());
|
||||||
|
// Because we RegisterRVA() on the string writer below, we preallocate and
|
||||||
|
// never resize the handle_descriptors_ vector.
|
||||||
|
handle_descriptors_.resize(handle_snapshots.size());
|
||||||
|
strings_.reserve(handle_snapshots.size());
|
||||||
|
for (size_t i = 0; i < handle_snapshots.size(); ++i) {
|
||||||
|
const HandleSnapshot& handle_snapshot = handle_snapshots[i];
|
||||||
|
MINIDUMP_HANDLE_DESCRIPTOR& descriptor = handle_descriptors_[i];
|
||||||
|
|
||||||
|
descriptor.Handle = handle_snapshot.handle;
|
||||||
|
|
||||||
|
if (handle_snapshot.type_name.empty()) {
|
||||||
|
descriptor.TypeNameRva = 0;
|
||||||
|
} else {
|
||||||
|
// TODO(scottmg): There is often a number of repeated type names here, the
|
||||||
|
// strings ought to be pooled.
|
||||||
|
strings_.push_back(new internal::MinidumpUTF16StringWriter());
|
||||||
|
strings_.back()->SetUTF16(handle_snapshot.type_name);
|
||||||
|
strings_.back()->RegisterRVA(&descriptor.TypeNameRva);
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor.ObjectNameRva = 0;
|
||||||
|
descriptor.Attributes = handle_snapshot.attributes;
|
||||||
|
descriptor.GrantedAccess = handle_snapshot.granted_access;
|
||||||
|
descriptor.HandleCount = handle_snapshot.handle_count;
|
||||||
|
descriptor.PointerCount = handle_snapshot.pointer_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MinidumpHandleDataWriter::Freeze() {
|
||||||
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
|
if (!MinidumpStreamWriter::Freeze())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
handle_data_stream_base_.SizeOfHeader = sizeof(handle_data_stream_base_);
|
||||||
|
handle_data_stream_base_.SizeOfDescriptor = sizeof(handle_descriptors_[0]);
|
||||||
|
handle_data_stream_base_.NumberOfDescriptors = handle_descriptors_.size();
|
||||||
|
handle_data_stream_base_.Reserved = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MinidumpHandleDataWriter::SizeOfObject() {
|
||||||
|
DCHECK_GE(state(), kStateFrozen);
|
||||||
|
return sizeof(handle_data_stream_base_) +
|
||||||
|
sizeof(handle_descriptors_[0]) * handle_descriptors_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<internal::MinidumpWritable*> MinidumpHandleDataWriter::Children() {
|
||||||
|
DCHECK_GE(state(), kStateFrozen);
|
||||||
|
|
||||||
|
std::vector<MinidumpWritable*> children;
|
||||||
|
for (auto* string : strings_)
|
||||||
|
children.push_back(string);
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MinidumpHandleDataWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||||
|
DCHECK_EQ(state(), kStateWritable);
|
||||||
|
|
||||||
|
WritableIoVec iov;
|
||||||
|
iov.iov_base = &handle_data_stream_base_;
|
||||||
|
iov.iov_len = sizeof(handle_data_stream_base_);
|
||||||
|
std::vector<WritableIoVec> iovecs(1, iov);
|
||||||
|
|
||||||
|
for (const auto& descriptor : handle_descriptors_) {
|
||||||
|
iov.iov_base = &descriptor;
|
||||||
|
iov.iov_len = sizeof(descriptor);
|
||||||
|
iovecs.push_back(iov);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_writer->WriteIoVec(&iovecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
MinidumpStreamType MinidumpHandleDataWriter::StreamType() const {
|
||||||
|
return kMinidumpStreamTypeHandleData;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crashpad
|
75
minidump/minidump_handle_writer.h
Normal file
75
minidump/minidump_handle_writer.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// 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_MINIDUMP_MINIDUMP_HANDLE_WRITER_H_
|
||||||
|
#define CRASHPAD_MINIDUMP_MINIDUMP_HANDLE_WRITER_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <dbghelp.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "minidump/minidump_stream_writer.h"
|
||||||
|
#include "minidump/minidump_string_writer.h"
|
||||||
|
#include "minidump/minidump_writable.h"
|
||||||
|
#include "snapshot/handle_snapshot.h"
|
||||||
|
#include "util/stdlib/pointer_container.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
//! \brief The writer for a MINIDUMP_HANDLE_DATA_STREAM stream in a minidump
|
||||||
|
//! and its contained MINIDUMP_HANDLE_DESCRIPTOR s.
|
||||||
|
//!
|
||||||
|
//! As we currently do not track any data beyond what MINIDUMP_HANDLE_DESCRIPTOR
|
||||||
|
//! supports, we only write that type of record rather than the newer
|
||||||
|
//! MINIDUMP_HANDLE_DESCRIPTOR_2.
|
||||||
|
//!
|
||||||
|
//! Note that this writer writes both the header (MINIDUMP_HANDLE_DATA_STREAM)
|
||||||
|
//! and the list of objects (MINIDUMP_HANDLE_DESCRIPTOR), which is different
|
||||||
|
//! from some of the other list writers.
|
||||||
|
class MinidumpHandleDataWriter final : public internal::MinidumpStreamWriter {
|
||||||
|
public:
|
||||||
|
MinidumpHandleDataWriter();
|
||||||
|
~MinidumpHandleDataWriter() override;
|
||||||
|
|
||||||
|
//! \brief Adds a MINIDUMP_HANDLE_DESCRIPTOR for each handle in \a
|
||||||
|
//! handle_snapshot to the MINIDUMP_HANDLE_DATA_STREAM.
|
||||||
|
//!
|
||||||
|
//! \param[in] handle_snapshots The handle snapshots to use as source data.
|
||||||
|
//!
|
||||||
|
//! \note Valid in #kStateMutable.
|
||||||
|
void InitializeFromSnapshot(
|
||||||
|
const std::vector<HandleSnapshot>& handle_snapshots);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// MinidumpWritable:
|
||||||
|
bool Freeze() override;
|
||||||
|
size_t SizeOfObject() override;
|
||||||
|
std::vector<MinidumpWritable*> Children() override;
|
||||||
|
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||||
|
|
||||||
|
// MinidumpStreamWriter:
|
||||||
|
MinidumpStreamType StreamType() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MINIDUMP_HANDLE_DATA_STREAM handle_data_stream_base_;
|
||||||
|
std::vector<MINIDUMP_HANDLE_DESCRIPTOR> handle_descriptors_;
|
||||||
|
PointerVector<internal::MinidumpUTF16StringWriter> strings_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(MinidumpHandleDataWriter);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
#endif // CRASHPAD_MINIDUMP_MINIDUMP_HANDLE_WRITER_H_
|
127
minidump/minidump_handle_writer_test.cc
Normal file
127
minidump/minidump_handle_writer_test.cc
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// 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 "minidump/minidump_handle_writer.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "minidump/minidump_file_writer.h"
|
||||||
|
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||||
|
#include "minidump/test/minidump_string_writer_test_util.h"
|
||||||
|
#include "minidump/test/minidump_writable_test_util.h"
|
||||||
|
#include "util/file/string_file.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace test {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// The handle data stream is expected to be the only stream.
|
||||||
|
void GetHandleDataStream(
|
||||||
|
const std::string& file_contents,
|
||||||
|
const MINIDUMP_HANDLE_DATA_STREAM** handle_data_stream) {
|
||||||
|
const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
|
||||||
|
const size_t kHandleDataStreamOffset =
|
||||||
|
kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
|
||||||
|
|
||||||
|
const MINIDUMP_DIRECTORY* directory;
|
||||||
|
const MINIDUMP_HEADER* header =
|
||||||
|
MinidumpHeaderAtStart(file_contents, &directory);
|
||||||
|
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||||
|
ASSERT_TRUE(directory);
|
||||||
|
|
||||||
|
const size_t kDirectoryIndex = 0;
|
||||||
|
|
||||||
|
ASSERT_EQ(kMinidumpStreamTypeHandleData,
|
||||||
|
directory[kDirectoryIndex].StreamType);
|
||||||
|
EXPECT_EQ(kHandleDataStreamOffset, directory[kDirectoryIndex].Location.Rva);
|
||||||
|
|
||||||
|
*handle_data_stream =
|
||||||
|
MinidumpWritableAtLocationDescriptor<MINIDUMP_HANDLE_DATA_STREAM>(
|
||||||
|
file_contents, directory[kDirectoryIndex].Location);
|
||||||
|
ASSERT_TRUE(*handle_data_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MinidumpHandleDataWriter, Empty) {
|
||||||
|
MinidumpFileWriter minidump_file_writer;
|
||||||
|
auto handle_data_writer = make_scoped_ptr(new MinidumpHandleDataWriter());
|
||||||
|
minidump_file_writer.AddStream(handle_data_writer.Pass());
|
||||||
|
|
||||||
|
StringFile string_file;
|
||||||
|
ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));
|
||||||
|
|
||||||
|
ASSERT_EQ(sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
|
||||||
|
sizeof(MINIDUMP_HANDLE_DATA_STREAM),
|
||||||
|
string_file.string().size());
|
||||||
|
|
||||||
|
const MINIDUMP_HANDLE_DATA_STREAM* handle_data_stream = nullptr;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
|
GetHandleDataStream(string_file.string(), &handle_data_stream));
|
||||||
|
|
||||||
|
EXPECT_EQ(0u, handle_data_stream->NumberOfDescriptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MinidumpHandleDataWriter, OneHandle) {
|
||||||
|
MinidumpFileWriter minidump_file_writer;
|
||||||
|
auto handle_data_writer = make_scoped_ptr(new MinidumpHandleDataWriter());
|
||||||
|
|
||||||
|
HandleSnapshot handle_snapshot;
|
||||||
|
handle_snapshot.handle = 0x1234;
|
||||||
|
handle_snapshot.type_name = L"Something";
|
||||||
|
handle_snapshot.attributes = 0x12345678;
|
||||||
|
handle_snapshot.granted_access = 0x9abcdef0;
|
||||||
|
handle_snapshot.pointer_count = 4567;
|
||||||
|
handle_snapshot.handle_count = 9876;
|
||||||
|
|
||||||
|
std::vector<HandleSnapshot> snapshot;
|
||||||
|
snapshot.push_back(handle_snapshot);
|
||||||
|
|
||||||
|
handle_data_writer->InitializeFromSnapshot(snapshot);
|
||||||
|
|
||||||
|
minidump_file_writer.AddStream(handle_data_writer.Pass());
|
||||||
|
|
||||||
|
StringFile string_file;
|
||||||
|
ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));
|
||||||
|
|
||||||
|
const size_t kTypeNameStringDataLength =
|
||||||
|
(handle_snapshot.type_name.size() + 1) *
|
||||||
|
sizeof(handle_snapshot.type_name[0]);
|
||||||
|
ASSERT_EQ(sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
|
||||||
|
sizeof(MINIDUMP_HANDLE_DATA_STREAM) +
|
||||||
|
sizeof(MINIDUMP_HANDLE_DESCRIPTOR) + sizeof(MINIDUMP_STRING) +
|
||||||
|
kTypeNameStringDataLength,
|
||||||
|
string_file.string().size());
|
||||||
|
|
||||||
|
const MINIDUMP_HANDLE_DATA_STREAM* handle_data_stream = nullptr;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
|
GetHandleDataStream(string_file.string(), &handle_data_stream));
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, handle_data_stream->NumberOfDescriptors);
|
||||||
|
const MINIDUMP_HANDLE_DESCRIPTOR* handle_descriptor =
|
||||||
|
reinterpret_cast<const MINIDUMP_HANDLE_DESCRIPTOR*>(
|
||||||
|
&handle_data_stream[1]);
|
||||||
|
EXPECT_EQ(handle_snapshot.handle, handle_descriptor->Handle);
|
||||||
|
EXPECT_EQ(handle_snapshot.type_name,
|
||||||
|
MinidumpStringAtRVAAsString(string_file.string(),
|
||||||
|
handle_descriptor->TypeNameRva));
|
||||||
|
EXPECT_EQ(0u, handle_descriptor->ObjectNameRva);
|
||||||
|
EXPECT_EQ(handle_snapshot.attributes, handle_descriptor->Attributes);
|
||||||
|
EXPECT_EQ(handle_snapshot.granted_access, handle_descriptor->GrantedAccess);
|
||||||
|
EXPECT_EQ(handle_snapshot.handle_count, handle_descriptor->HandleCount);
|
||||||
|
EXPECT_EQ(handle_snapshot.pointer_count, handle_descriptor->PointerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace test
|
||||||
|
} // namespace crashpad
|
@ -51,7 +51,7 @@ void GetMemoryInfoListStream(
|
|||||||
*memory_info_list =
|
*memory_info_list =
|
||||||
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_INFO_LIST>(
|
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_INFO_LIST>(
|
||||||
file_contents, directory[kDirectoryIndex].Location);
|
file_contents, directory[kDirectoryIndex].Location);
|
||||||
ASSERT_TRUE(memory_info_list);
|
ASSERT_TRUE(*memory_info_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MinidumpMemoryInfoWriter, Empty) {
|
TEST(MinidumpMemoryInfoWriter, Empty) {
|
||||||
|
@ -99,6 +99,13 @@ class MinidumpUTF16StringWriter final
|
|||||||
//! \note Valid in #kStateMutable.
|
//! \note Valid in #kStateMutable.
|
||||||
void SetUTF8(const std::string& string_utf8);
|
void SetUTF8(const std::string& string_utf8);
|
||||||
|
|
||||||
|
//! \brief Sets the given UTF-16 string as the string to be written.
|
||||||
|
//!
|
||||||
|
//! \note Valid in #kStateMutable.
|
||||||
|
void SetUTF16(const base::string16& string_utf16) {
|
||||||
|
set_string(string_utf16);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(MinidumpUTF16StringWriter);
|
DISALLOW_COPY_AND_ASSIGN(MinidumpUTF16StringWriter);
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,23 @@ TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) {
|
|||||||
MinidumpStringAtRVAAsString(string_file.string(), 0));
|
MinidumpStringAtRVAAsString(string_file.string(), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("no conversion");
|
||||||
|
string_file.Reset();
|
||||||
|
crashpad::internal::MinidumpUTF16StringWriter string_writer;
|
||||||
|
const base::string16 kString(L"oóöőo");
|
||||||
|
string_writer.SetUTF16(kString);
|
||||||
|
EXPECT_TRUE(string_writer.WriteEverything(&string_file));
|
||||||
|
ASSERT_EQ(
|
||||||
|
sizeof(MINIDUMP_STRING) + (kString.size() + 1) * sizeof(kString[0]),
|
||||||
|
string_file.string().size());
|
||||||
|
|
||||||
|
const MINIDUMP_STRING* minidump_string =
|
||||||
|
MinidumpStringAtRVA(string_file.string(), 0);
|
||||||
|
EXPECT_TRUE(minidump_string);
|
||||||
|
EXPECT_EQ(kString, MinidumpStringAtRVAAsString(string_file.string(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
const struct {
|
const struct {
|
||||||
size_t input_length;
|
size_t input_length;
|
||||||
const char* input_string;
|
const char* input_string;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
'minidump_context_writer_test.cc',
|
'minidump_context_writer_test.cc',
|
||||||
'minidump_crashpad_info_writer_test.cc',
|
'minidump_crashpad_info_writer_test.cc',
|
||||||
'minidump_exception_writer_test.cc',
|
'minidump_exception_writer_test.cc',
|
||||||
|
'minidump_handle_writer_test.cc',
|
||||||
'minidump_file_writer_test.cc',
|
'minidump_file_writer_test.cc',
|
||||||
'minidump_memory_info_writer_test.cc',
|
'minidump_memory_info_writer_test.cc',
|
||||||
'minidump_memory_writer_test.cc',
|
'minidump_memory_writer_test.cc',
|
||||||
|
@ -181,6 +181,14 @@ struct MinidumpThreadListTraits {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MinidumpHandleDataStreamTraits {
|
||||||
|
using ListType = MINIDUMP_HANDLE_DATA_STREAM;
|
||||||
|
enum : size_t { kElementSize = sizeof(MINIDUMP_HANDLE_DESCRIPTOR) };
|
||||||
|
static size_t ElementCount(const ListType* list) {
|
||||||
|
return static_cast<size_t>(list->NumberOfDescriptors);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct MinidumpMemoryInfoListTraits {
|
struct MinidumpMemoryInfoListTraits {
|
||||||
using ListType = MINIDUMP_MEMORY_INFO_LIST;
|
using ListType = MINIDUMP_MEMORY_INFO_LIST;
|
||||||
enum : size_t { kElementSize = sizeof(MINIDUMP_MEMORY_INFO) };
|
enum : size_t { kElementSize = sizeof(MINIDUMP_MEMORY_INFO) };
|
||||||
@ -252,6 +260,14 @@ const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
|
|||||||
file_contents, location);
|
file_contents, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
const MINIDUMP_HANDLE_DATA_STREAM* MinidumpWritableAtLocationDescriptor<
|
||||||
|
MINIDUMP_HANDLE_DATA_STREAM>(const std::string& file_contents,
|
||||||
|
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
||||||
|
return MinidumpListAtLocationDescriptor<MinidumpHandleDataStreamTraits>(
|
||||||
|
file_contents, location);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const MINIDUMP_MEMORY_INFO_LIST* MinidumpWritableAtLocationDescriptor<
|
const MINIDUMP_MEMORY_INFO_LIST* MinidumpWritableAtLocationDescriptor<
|
||||||
MINIDUMP_MEMORY_INFO_LIST>(const std::string& file_contents,
|
MINIDUMP_MEMORY_INFO_LIST>(const std::string& file_contents,
|
||||||
|
@ -90,6 +90,7 @@ MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_DIRECTORY);
|
|||||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_LIST);
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_LIST);
|
||||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MODULE_LIST);
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MODULE_LIST);
|
||||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_THREAD_LIST);
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_THREAD_LIST);
|
||||||
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_HANDLE_DATA_STREAM);
|
||||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_INFO_LIST);
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_INFO_LIST);
|
||||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpModuleCrashpadInfoList);
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpModuleCrashpadInfoList);
|
||||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpRVAList);
|
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpRVAList);
|
||||||
@ -190,6 +191,11 @@ const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
|
|||||||
MINIDUMP_THREAD_LIST>(const std::string& file_contents,
|
MINIDUMP_THREAD_LIST>(const std::string& file_contents,
|
||||||
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
const MINIDUMP_HANDLE_DATA_STREAM* MinidumpWritableAtLocationDescriptor<
|
||||||
|
MINIDUMP_HANDLE_DATA_STREAM>(const std::string& file_contents,
|
||||||
|
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const MINIDUMP_MEMORY_INFO_LIST* MinidumpWritableAtLocationDescriptor<
|
const MINIDUMP_MEMORY_INFO_LIST* MinidumpWritableAtLocationDescriptor<
|
||||||
MINIDUMP_MEMORY_INFO_LIST>(const std::string& file_contents,
|
MINIDUMP_MEMORY_INFO_LIST>(const std::string& file_contents,
|
||||||
|
@ -183,10 +183,14 @@ def RunTests(cdb_path, dump_path, pipe_name):
|
|||||||
out = CdbRun(cdb_path, dump_path, '!locks')
|
out = CdbRun(cdb_path, dump_path, '!locks')
|
||||||
out.Check(r'CritSec crashy_program!crashpad::`anonymous namespace\'::'
|
out.Check(r'CritSec crashy_program!crashpad::`anonymous namespace\'::'
|
||||||
r'g_test_critical_section', 'lock was captured')
|
r'g_test_critical_section', 'lock was captured')
|
||||||
if float(platform.win32_ver()[0]) != 7:
|
if platform.win32_ver()[0] != '7':
|
||||||
# We can't allocate CRITICAL_SECTIONs with .DebugInfo on Win 7.
|
# We can't allocate CRITICAL_SECTIONs with .DebugInfo on Win 7.
|
||||||
out.Check(r'\*\*\* Locked', 'lock debug info was captured, and is locked')
|
out.Check(r'\*\*\* Locked', 'lock debug info was captured, and is locked')
|
||||||
|
|
||||||
|
out = CdbRun(cdb_path, dump_path, '!handle')
|
||||||
|
out.Check(r'\d+ Handles', 'captured handles')
|
||||||
|
out.Check(r'Event\s+\d+', 'capture some event handles')
|
||||||
|
out.Check(r'File\s+\d+', 'capture some file handles')
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
try:
|
try:
|
||||||
@ -202,8 +206,10 @@ def main(args):
|
|||||||
# Make sure we can download Windows symbols.
|
# Make sure we can download Windows symbols.
|
||||||
if not os.environ.get('_NT_SYMBOL_PATH'):
|
if not os.environ.get('_NT_SYMBOL_PATH'):
|
||||||
symbol_dir = MakeTempDir()
|
symbol_dir = MakeTempDir()
|
||||||
|
protocol = 'https' if platform.win32_ver()[0] != 'XP' else 'http'
|
||||||
os.environ['_NT_SYMBOL_PATH'] = (
|
os.environ['_NT_SYMBOL_PATH'] = (
|
||||||
'SRV*' + symbol_dir + '*https://msdl.microsoft.com/download/symbols')
|
'SRV*' + symbol_dir + '*' +
|
||||||
|
protocol + '://msdl.microsoft.com/download/symbols')
|
||||||
|
|
||||||
pipe_name = r'\\.\pipe\end-to-end_%s_%s' % (
|
pipe_name = r'\\.\pipe\end-to-end_%s_%s' % (
|
||||||
os.getpid(), str(random.getrandbits(64)))
|
os.getpid(), str(random.getrandbits(64)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user