mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Add MinidumpByteArray extension and its Writer.
The MinidumpByteArray can be used to carry arbitrary blob payloads in a minidump file. Bug: crashpad:192 Change-Id: I1a0710b856375213cdd97eafa9247830aa9a9291 Reviewed-on: https://chromium-review.googlesource.com/716462 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
parent
b88fde0b56
commit
38c8f51ae8
@ -33,6 +33,8 @@
|
||||
'..',
|
||||
],
|
||||
'sources': [
|
||||
'minidump_byte_array_writer.cc',
|
||||
'minidump_byte_array_writer.h',
|
||||
'minidump_context.h',
|
||||
'minidump_context_writer.cc',
|
||||
'minidump_context_writer.h',
|
||||
|
73
minidump/minidump_byte_array_writer.cc
Normal file
73
minidump/minidump_byte_array_writer.cc
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2017 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_byte_array_writer.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "util/file/file_writer.h"
|
||||
#include "util/numeric/safe_assignment.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
MinidumpByteArrayWriter::MinidumpByteArrayWriter()
|
||||
: minidump_array_(new MinidumpByteArray()) {}
|
||||
|
||||
MinidumpByteArrayWriter::~MinidumpByteArrayWriter() = default;
|
||||
|
||||
void MinidumpByteArrayWriter::set_data(const uint8_t* data, size_t size) {
|
||||
data_.clear();
|
||||
data_.insert(data_.begin(), data, data + size);
|
||||
}
|
||||
|
||||
bool MinidumpByteArrayWriter::Freeze() {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
if (!MinidumpWritable::Freeze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size = data_.size();
|
||||
if (!AssignIfInRange(&minidump_array_->length, size)) {
|
||||
LOG(ERROR) << "data size " << size << " is out of range";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t MinidumpByteArrayWriter::SizeOfObject() {
|
||||
DCHECK_EQ(state(), kStateFrozen);
|
||||
|
||||
return sizeof(*minidump_array_) + data_.size();
|
||||
}
|
||||
|
||||
bool MinidumpByteArrayWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||
DCHECK_EQ(state(), kStateWritable);
|
||||
|
||||
WritableIoVec iov;
|
||||
iov.iov_base = minidump_array_.get();
|
||||
iov.iov_len = sizeof(*minidump_array_);
|
||||
|
||||
std::vector<WritableIoVec> iovecs(1, iov);
|
||||
|
||||
if (!data_.empty()) {
|
||||
iov.iov_base = data_.data();
|
||||
iov.iov_len = data_.size();
|
||||
iovecs.push_back(iov);
|
||||
}
|
||||
|
||||
return file_writer->WriteIoVec(&iovecs);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
65
minidump/minidump_byte_array_writer.h
Normal file
65
minidump/minidump_byte_array_writer.h
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2017 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_BYTE_ARRAY_WRITER_H_
|
||||
#define CRASHPAD_MINIDUMP_MINIDUMP_BYTE_ARRAY_WRITER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_writable.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief Writes a variable-length byte array for a minidump into a
|
||||
//! \sa MinidumpByteArray.
|
||||
class MinidumpByteArrayWriter final : public internal::MinidumpWritable {
|
||||
public:
|
||||
MinidumpByteArrayWriter();
|
||||
~MinidumpByteArrayWriter() override;
|
||||
|
||||
//! \brief Sets the data to be written.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable.
|
||||
void set_data(const std::vector<uint8_t>& data) { data_ = data; }
|
||||
|
||||
//! \brief Sets the data to be written.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable.
|
||||
void set_data(const uint8_t* data, size_t size);
|
||||
|
||||
//! \brief Gets the data to be written.
|
||||
//!
|
||||
//! \note Valid in any state.
|
||||
const std::vector<uint8_t>& data() const { return data_; }
|
||||
|
||||
protected:
|
||||
// MinidumpWritable:
|
||||
|
||||
bool Freeze() override;
|
||||
size_t SizeOfObject() override;
|
||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<MinidumpByteArray> minidump_array_;
|
||||
std::vector<uint8_t> data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpByteArrayWriter);
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_MINIDUMP_BYTE_ARRAY_WRITER_H_
|
80
minidump/minidump_byte_array_writer_test.cc
Normal file
80
minidump/minidump_byte_array_writer_test.cc
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright 2017 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_byte_array_writer.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/format_macros.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
#include "util/file/string_file.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
TEST(MinidumpByteArrayWriter, Write) {
|
||||
const std::vector<uint8_t> kTests[] = {
|
||||
{'h', 'e', 'l', 'l', 'o'},
|
||||
{0x42, 0x99, 0x00, 0xbe},
|
||||
{0x00},
|
||||
{},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < arraysize(kTests); ++i) {
|
||||
SCOPED_TRACE(base::StringPrintf("index %" PRIuS, i));
|
||||
|
||||
StringFile string_file;
|
||||
|
||||
crashpad::MinidumpByteArrayWriter writer;
|
||||
writer.set_data(kTests[i]);
|
||||
EXPECT_TRUE(writer.WriteEverything(&string_file));
|
||||
|
||||
ASSERT_EQ(string_file.string().size(),
|
||||
sizeof(MinidumpByteArray) + kTests[i].size());
|
||||
|
||||
auto byte_array = std::make_unique<MinidumpByteArray>();
|
||||
EXPECT_EQ(string_file.Seek(0, SEEK_SET), 0);
|
||||
string_file.Read(byte_array.get(), sizeof(*byte_array));
|
||||
|
||||
EXPECT_EQ(byte_array->length, kTests[i].size());
|
||||
|
||||
std::vector<uint8_t> data(byte_array->length);
|
||||
string_file.Read(data.data(), byte_array->length);
|
||||
|
||||
EXPECT_EQ(data, kTests[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MinidumpByteArrayWriter, SetData) {
|
||||
const std::vector<uint8_t> kTests[] = {
|
||||
{1, 2, 3, 4, 5},
|
||||
{0x0},
|
||||
{},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < arraysize(kTests); ++i) {
|
||||
SCOPED_TRACE(base::StringPrintf("index %" PRIuS, i));
|
||||
|
||||
crashpad::MinidumpByteArrayWriter writer;
|
||||
writer.set_data(kTests[i].data(), kTests[i].size());
|
||||
EXPECT_EQ(writer.data(), kTests[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -118,6 +118,17 @@ struct ALIGNAS(4) PACKED MinidumpUTF8String {
|
||||
uint8_t Buffer[0];
|
||||
};
|
||||
|
||||
//! \brief A variable-length array of bytes carried within a minidump file.
|
||||
//! The data have no intrinsic type and should be interpreted according
|
||||
//! to their referencing context.
|
||||
struct ALIGNAS(4) PACKED MinidumpByteArray {
|
||||
//! \brief The length of the #data field.
|
||||
uint32_t length;
|
||||
|
||||
//! \brief The bytes of data.
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
//! \brief CPU type values for MINIDUMP_SYSTEM_INFO::ProcessorArchitecture.
|
||||
//!
|
||||
//! \sa \ref PROCESSOR_ARCHITECTURE_x "PROCESSOR_ARCHITECTURE_*"
|
||||
|
@ -29,6 +29,8 @@
|
||||
'..',
|
||||
],
|
||||
'sources': [
|
||||
'test/minidump_byte_array_writer_test_util.cc',
|
||||
'test/minidump_byte_array_writer_test_util.h',
|
||||
'test/minidump_context_test_util.cc',
|
||||
'test/minidump_context_test_util.h',
|
||||
'test/minidump_file_writer_test_util.cc',
|
||||
@ -62,6 +64,7 @@
|
||||
'..',
|
||||
],
|
||||
'sources': [
|
||||
'minidump_byte_array_writer_test.cc',
|
||||
'minidump_context_writer_test.cc',
|
||||
'minidump_crashpad_info_writer_test.cc',
|
||||
'minidump_exception_writer_test.cc',
|
||||
|
36
minidump/test/minidump_byte_array_writer_test_util.cc
Normal file
36
minidump/test/minidump_byte_array_writer_test_util.cc
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2017 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/test/minidump_byte_array_writer_test_util.h"
|
||||
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
std::vector<uint8_t> MinidumpByteArrayAtRVA(const std::string& file_contents,
|
||||
RVA rva) {
|
||||
auto* minidump_byte_array =
|
||||
MinidumpWritableAtRVA<MinidumpByteArray>(file_contents, rva);
|
||||
if (!minidump_byte_array) {
|
||||
return {};
|
||||
}
|
||||
auto* data = static_cast<const uint8_t*>(minidump_byte_array->data);
|
||||
const uint8_t* data_end = data + minidump_byte_array->length;
|
||||
return std::vector<uint8_t>(data, data_end);
|
||||
}
|
||||
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
43
minidump/test/minidump_byte_array_writer_test_util.h
Normal file
43
minidump/test/minidump_byte_array_writer_test_util.h
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2017 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 MINIDUMP_TEST_MINIDUMP_BYTE_ARRAY_WRITER_TEST_UTIL_H_
|
||||
#define MINIDUMP_TEST_MINIDUMP_BYTE_ARRAY_WRITER_TEST_UTIL_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
//! \brief Returns the bytes referenced by a MinidumpByteArray object located
|
||||
//! in a minidump file at the specified RVA.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset in the minidump file of the MinidumpByteArray.
|
||||
//!
|
||||
//! \return The MinidumpByteArray::data referenced by the \a rva. Note that
|
||||
//! this function does not check that the data are within the bounds of
|
||||
//! the \a file_contents.
|
||||
std::vector<uint8_t> MinidumpByteArrayAtRVA(const std::string& file_contents,
|
||||
RVA rva);
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // MINIDUMP_TEST_MINIDUMP_BYTE_ARRAY_WRITER_TEST_UTIL_H_
|
Loading…
x
Reference in New Issue
Block a user