mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
Add MinidumpCrashpadInfoWriter and its test.
TEST=minidump_test MinidumpCrashpadInfoWriter.* R=rsesek@chromium.org Review URL: https://codereview.chromium.org/654573003
This commit is contained in:
parent
b9db7543a3
commit
b8a2f41156
@ -32,6 +32,8 @@
|
||||
'minidump_context.h',
|
||||
'minidump_context_writer.cc',
|
||||
'minidump_context_writer.h',
|
||||
'minidump_crashpad_info_writer.cc',
|
||||
'minidump_crashpad_info_writer.h',
|
||||
'minidump_exception_writer.cc',
|
||||
'minidump_exception_writer.h',
|
||||
'minidump_extensions.cc',
|
||||
@ -76,6 +78,7 @@
|
||||
'minidump_context_test_util.cc',
|
||||
'minidump_context_test_util.h',
|
||||
'minidump_context_writer_test.cc',
|
||||
'minidump_crashpad_info_writer_test.cc',
|
||||
'minidump_exception_writer_test.cc',
|
||||
'minidump_file_writer_test.cc',
|
||||
'minidump_file_writer_test_util.cc',
|
||||
@ -87,6 +90,8 @@
|
||||
'minidump_module_writer_test.cc',
|
||||
'minidump_simple_string_dictionary_writer_test.cc',
|
||||
'minidump_string_writer_test.cc',
|
||||
'minidump_string_writer_test_util.cc',
|
||||
'minidump_string_writer_test_util.h',
|
||||
'minidump_system_info_writer_test.cc',
|
||||
'minidump_thread_writer_test.cc',
|
||||
'minidump_writable_test.cc',
|
||||
|
80
minidump/minidump_crashpad_info_writer.cc
Normal file
80
minidump/minidump_crashpad_info_writer.cc
Normal file
@ -0,0 +1,80 @@
|
||||
// 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 "minidump/minidump_crashpad_info_writer.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
MinidumpCrashpadInfoWriter::MinidumpCrashpadInfoWriter()
|
||||
: MinidumpStreamWriter(), crashpad_info_(), simple_annotations_() {
|
||||
crashpad_info_.size = sizeof(crashpad_info_);
|
||||
crashpad_info_.version = 1;
|
||||
}
|
||||
|
||||
MinidumpCrashpadInfoWriter::~MinidumpCrashpadInfoWriter() {
|
||||
}
|
||||
|
||||
void MinidumpCrashpadInfoWriter::SetSimpleAnnotations(
|
||||
MinidumpSimpleStringDictionaryWriter* simple_annotations) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
simple_annotations_ = simple_annotations;
|
||||
}
|
||||
|
||||
bool MinidumpCrashpadInfoWriter::Freeze() {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
if (!MinidumpStreamWriter::Freeze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (simple_annotations_) {
|
||||
simple_annotations_->RegisterLocationDescriptor(
|
||||
&crashpad_info_.simple_annotations);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t MinidumpCrashpadInfoWriter::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
return sizeof(crashpad_info_);
|
||||
}
|
||||
|
||||
std::vector<internal::MinidumpWritable*>
|
||||
MinidumpCrashpadInfoWriter::Children() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
std::vector<MinidumpWritable*> children;
|
||||
if (simple_annotations_) {
|
||||
children.push_back(simple_annotations_);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
bool MinidumpCrashpadInfoWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||
DCHECK_EQ(state(), kStateWritable);
|
||||
|
||||
return file_writer->Write(&crashpad_info_, sizeof(crashpad_info_));
|
||||
}
|
||||
|
||||
MinidumpStreamType MinidumpCrashpadInfoWriter::StreamType() const {
|
||||
return kMinidumpStreamTypeCrashpadInfo;
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
69
minidump/minidump_crashpad_info_writer.h
Normal file
69
minidump/minidump_crashpad_info_writer.h
Normal file
@ -0,0 +1,69 @@
|
||||
// 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_MINIDUMP_MINIDUMP_CRASHPAD_INFO_WRITER_H_
|
||||
#define CRASHPAD_MINIDUMP_MINIDUMP_CRASHPAD_INFO_WRITER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_simple_string_dictionary_writer.h"
|
||||
#include "minidump/minidump_stream_writer.h"
|
||||
#include "minidump/minidump_writable.h"
|
||||
#include "util/file/file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief The writer for a MinidumpCrashpadInfo stream in a minidump file.
|
||||
class MinidumpCrashpadInfoWriter final : public internal::MinidumpStreamWriter {
|
||||
public:
|
||||
MinidumpCrashpadInfoWriter();
|
||||
~MinidumpCrashpadInfoWriter();
|
||||
|
||||
//! \brief Arranges for MinidumpCrashpadInfo::simple_annotations to point to
|
||||
//! the MinidumpSimpleStringDictionaryWriter object to be written by \a
|
||||
//! simple_annotations.
|
||||
//!
|
||||
//! \a simple_annotations will become a child of this object in the overall
|
||||
//! tree of internal::MinidumpWritable objects.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable.
|
||||
void SetSimpleAnnotations(
|
||||
MinidumpSimpleStringDictionaryWriter* simple_annotations);
|
||||
|
||||
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:
|
||||
MinidumpCrashpadInfo crashpad_info_;
|
||||
MinidumpSimpleStringDictionaryWriter* simple_annotations_; // weak
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpCrashpadInfoWriter);
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_MINIDUMP_CRASHPAD_INFO_WRITER_H_
|
155
minidump/minidump_crashpad_info_writer_test.cc
Normal file
155
minidump/minidump_crashpad_info_writer_test.cc
Normal file
@ -0,0 +1,155 @@
|
||||
// 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 "minidump/minidump_crashpad_info_writer.h"
|
||||
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "minidump/minidump_file_writer_test_util.h"
|
||||
#include "minidump/minidump_simple_string_dictionary_writer.h"
|
||||
#include "minidump/minidump_string_writer_test_util.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
void GetCrashpadInfoStream(
|
||||
const std::string& file_contents,
|
||||
const MinidumpCrashpadInfo** crashpad_info,
|
||||
const MinidumpSimpleStringDictionary** simple_annotations) {
|
||||
const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
|
||||
const size_t kCrashpadInfoStreamOffset =
|
||||
kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
|
||||
size_t end = kCrashpadInfoStreamOffset + sizeof(MinidumpCrashpadInfo);
|
||||
const size_t kSimpleAnnotationsOffset = simple_annotations ? end : 0;
|
||||
if (simple_annotations) {
|
||||
end += sizeof(MinidumpSimpleStringDictionary);
|
||||
}
|
||||
const size_t kFileSize = end;
|
||||
|
||||
if (!simple_annotations) {
|
||||
ASSERT_EQ(kFileSize, file_contents.size());
|
||||
} else {
|
||||
EXPECT_GE(file_contents.size(), kFileSize);
|
||||
}
|
||||
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeCrashpadInfo, directory->StreamType);
|
||||
ASSERT_EQ(sizeof(MinidumpCrashpadInfo), directory->Location.DataSize);
|
||||
ASSERT_EQ(kCrashpadInfoStreamOffset, directory->Location.Rva);
|
||||
|
||||
*crashpad_info = reinterpret_cast<const MinidumpCrashpadInfo*>(
|
||||
&file_contents[kCrashpadInfoStreamOffset]);
|
||||
|
||||
if (simple_annotations) {
|
||||
ASSERT_GE((*crashpad_info)->simple_annotations.DataSize,
|
||||
sizeof(MinidumpSimpleStringDictionary));
|
||||
ASSERT_EQ(kSimpleAnnotationsOffset,
|
||||
(*crashpad_info)->simple_annotations.Rva);
|
||||
*simple_annotations =
|
||||
reinterpret_cast<const MinidumpSimpleStringDictionary*>(
|
||||
&file_contents[kSimpleAnnotationsOffset]);
|
||||
} else {
|
||||
ASSERT_EQ(0u, (*crashpad_info)->simple_annotations.DataSize);
|
||||
ASSERT_EQ(0u, (*crashpad_info)->simple_annotations.Rva);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MinidumpCrashpadInfoWriter, Empty) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpCrashpadInfoWriter crashpad_info_writer;
|
||||
|
||||
minidump_file_writer.AddStream(&crashpad_info_writer);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MinidumpCrashpadInfo* crashpad_info;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
GetCrashpadInfoStream(file_writer.string(), &crashpad_info, nullptr));
|
||||
|
||||
EXPECT_EQ(sizeof(*crashpad_info), crashpad_info->size);
|
||||
EXPECT_EQ(1u, crashpad_info->version);
|
||||
EXPECT_EQ(0u, crashpad_info->simple_annotations.DataSize);
|
||||
EXPECT_EQ(0u, crashpad_info->simple_annotations.Rva);
|
||||
}
|
||||
|
||||
TEST(MinidumpCrashpadInfoWriter, SimpleAnnotations) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
MinidumpCrashpadInfoWriter crashpad_info_writer;
|
||||
|
||||
minidump_file_writer.AddStream(&crashpad_info_writer);
|
||||
|
||||
MinidumpSimpleStringDictionaryWriter simple_annotations_writer;
|
||||
|
||||
// Set a key and value before adding the simple_annotations_writer to
|
||||
// crashpad_info_writer, and another one after.
|
||||
const char kKey0[] = "k0";
|
||||
const char kValue0[] = "v";
|
||||
const char kKey1[] = "KEY1";
|
||||
const char kValue1[] = "";
|
||||
MinidumpSimpleStringDictionaryEntryWriter entry_0;
|
||||
entry_0.SetKeyValue(kKey0, kValue0);
|
||||
simple_annotations_writer.AddEntry(&entry_0);
|
||||
|
||||
crashpad_info_writer.SetSimpleAnnotations(&simple_annotations_writer);
|
||||
|
||||
MinidumpSimpleStringDictionaryEntryWriter entry_1;
|
||||
entry_1.SetKeyValue(kKey1, kValue1);
|
||||
simple_annotations_writer.AddEntry(&entry_1);
|
||||
|
||||
StringFileWriter file_writer;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
|
||||
|
||||
const MinidumpCrashpadInfo* crashpad_info;
|
||||
const MinidumpSimpleStringDictionary* simple_annotations;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream(
|
||||
file_writer.string(), &crashpad_info, &simple_annotations));
|
||||
|
||||
EXPECT_EQ(sizeof(*crashpad_info), crashpad_info->size);
|
||||
EXPECT_EQ(1u, crashpad_info->version);
|
||||
|
||||
ASSERT_EQ(2u, simple_annotations->count);
|
||||
|
||||
EXPECT_EQ(
|
||||
kKey1,
|
||||
MinidumpUTF8StringAtRVA(file_writer, simple_annotations->entries[0].key));
|
||||
EXPECT_EQ(kValue1,
|
||||
MinidumpUTF8StringAtRVA(file_writer,
|
||||
simple_annotations->entries[0].value));
|
||||
EXPECT_EQ(
|
||||
kKey0,
|
||||
MinidumpUTF8StringAtRVA(file_writer, simple_annotations->entries[1].key));
|
||||
EXPECT_EQ(kValue0,
|
||||
MinidumpUTF8StringAtRVA(file_writer,
|
||||
simple_annotations->entries[1].value));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_string_writer_test_util.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -44,38 +45,6 @@ TEST(MinidumpSimpleStringDictionaryWriter, EmptySimpleStringDictionary) {
|
||||
EXPECT_EQ(0u, dictionary->count);
|
||||
}
|
||||
|
||||
std::string MinidumpUTF8StringAtRVA(const StringFileWriter& file_writer,
|
||||
RVA rva) {
|
||||
const std::string& contents = file_writer.string();
|
||||
if (rva == 0) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (rva + sizeof(MinidumpUTF8String) > contents.size()) {
|
||||
ADD_FAILURE()
|
||||
<< "rva " << rva << " too large for contents " << contents.size();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const MinidumpUTF8String* minidump_string =
|
||||
reinterpret_cast<const MinidumpUTF8String*>(&contents[rva]);
|
||||
|
||||
// Verify that the file has enough data for the string’s stated length plus
|
||||
// its required NUL terminator.
|
||||
if (rva + sizeof(MinidumpUTF8String) + minidump_string->Length + 1 >
|
||||
contents.size()) {
|
||||
ADD_FAILURE()
|
||||
<< "rva " << rva << ", length " << minidump_string->Length
|
||||
<< " too large for contents " << contents.size();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string minidump_string_data(
|
||||
reinterpret_cast<const char*>(&minidump_string->Buffer[0]),
|
||||
minidump_string->Length);
|
||||
return minidump_string_data;
|
||||
}
|
||||
|
||||
TEST(MinidumpSimpleStringDictionaryWriter, EmptyKeyValue) {
|
||||
StringFileWriter file_writer;
|
||||
|
||||
|
56
minidump/minidump_string_writer_test_util.cc
Normal file
56
minidump/minidump_string_writer_test_util.cc
Normal file
@ -0,0 +1,56 @@
|
||||
// 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 "minidump/minidump_string_writer_test_util.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
std::string MinidumpUTF8StringAtRVA(const StringFileWriter& file_writer,
|
||||
RVA rva) {
|
||||
const std::string& contents = file_writer.string();
|
||||
if (rva == 0) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (rva + sizeof(MinidumpUTF8String) > contents.size()) {
|
||||
ADD_FAILURE()
|
||||
<< "rva " << rva << " too large for contents " << contents.size();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const MinidumpUTF8String* minidump_string =
|
||||
reinterpret_cast<const MinidumpUTF8String*>(&contents[rva]);
|
||||
|
||||
// Verify that the file has enough data for the string’s stated length plus
|
||||
// its required NUL terminator.
|
||||
if (rva + sizeof(MinidumpUTF8String) + minidump_string->Length + 1 >
|
||||
contents.size()) {
|
||||
ADD_FAILURE()
|
||||
<< "rva " << rva << ", length " << minidump_string->Length
|
||||
<< " too large for contents " << contents.size();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string minidump_string_data(
|
||||
reinterpret_cast<const char*>(&minidump_string->Buffer[0]),
|
||||
minidump_string->Length);
|
||||
return minidump_string_data;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
42
minidump/minidump_string_writer_test_util.h
Normal file
42
minidump/minidump_string_writer_test_util.h
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 <dbghelp.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
//! \brief Returns the contents of a MinidumpUTF8String.
|
||||
//!
|
||||
//! If \a rva points outside of the range of \a file_writer, or if any of the
|
||||
//! string data would lie outside of the range of \a file_writer, this function
|
||||
//! will fail.
|
||||
//!
|
||||
//! \param[in] file_writer A StringFileWriter into which MinidumpWritable
|
||||
//! objects have been written.
|
||||
//! \param[in] rva An offset in \a file_writer at which to find the desired
|
||||
//! string.
|
||||
//!
|
||||
//! \return On success, the string read from \a file_writer at offset \a rva. On
|
||||
//! failure, returns an empty string, with a nonfatal assertion logged to
|
||||
//! gtest.
|
||||
std::string MinidumpUTF8StringAtRVA(const StringFileWriter& file_writer,
|
||||
RVA rva);
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
Loading…
x
Reference in New Issue
Block a user