mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
win: Resolve zero-length array errors on MSVC
In some cases, it's sufficient to move the zero-length array to the end of the structure. When the struct is used inside a class that is derived from however, this fails. In that case, switch to holding the object in a scoped_ptr. Longer winded version: https://groups.google.com/a/chromium.org/d/msg/crashpad-dev/NGZ6LwRMORM/nKcXKQ7inIEJ R=mark@chromium.org BUG=crashpad:1 Review URL: https://codereview.chromium.org/896663006
This commit is contained in:
parent
429a3368d4
commit
74a34e9c4b
@ -24,6 +24,16 @@
|
||||
#include "build/build_config.h"
|
||||
#include "util/misc/uuid.h"
|
||||
|
||||
#if defined(COMPILER_MSVC)
|
||||
// C4200 is "nonstandard extension used : zero-sized array in struct/union".
|
||||
// We would like to globally disable this warning, but unfortunately, the
|
||||
// compiler is buggy and only supports disabling it with a pragma, so we can't
|
||||
// disable it with other silly warnings in build/common.gypi. See:
|
||||
// https://connect.microsoft.com/VisualStudio/feedback/details/1114440
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
#endif // COMPILER_MSVC
|
||||
|
||||
#if defined(COMPILER_MSVC)
|
||||
#define PACKED
|
||||
#pragma pack(push, 1)
|
||||
@ -460,6 +470,10 @@ struct ALIGNAS(4) PACKED MinidumpCrashpadInfo {
|
||||
#endif // COMPILER_MSVC
|
||||
#undef PACKED
|
||||
|
||||
#if defined(COMPILER_MSVC)
|
||||
#pragma warning(pop) // C4200
|
||||
#endif // COMPILER_MSVC
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_
|
||||
|
@ -23,7 +23,7 @@ namespace internal {
|
||||
|
||||
MinidumpLocationDescriptorListWriter::MinidumpLocationDescriptorListWriter()
|
||||
: MinidumpWritable(),
|
||||
location_descriptor_list_base_(),
|
||||
location_descriptor_list_base_(new MinidumpLocationDescriptorList()),
|
||||
children_(),
|
||||
child_location_descriptors_() {
|
||||
}
|
||||
@ -47,7 +47,8 @@ bool MinidumpLocationDescriptorListWriter::Freeze() {
|
||||
}
|
||||
|
||||
size_t child_count = children_.size();
|
||||
if (!AssignIfInRange(&location_descriptor_list_base_.count, child_count)) {
|
||||
if (!AssignIfInRange(&location_descriptor_list_base_->count,
|
||||
child_count)) {
|
||||
LOG(ERROR) << "child_count " << child_count << " out of range";
|
||||
return false;
|
||||
}
|
||||
@ -64,7 +65,7 @@ bool MinidumpLocationDescriptorListWriter::Freeze() {
|
||||
size_t MinidumpLocationDescriptorListWriter::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
return sizeof(location_descriptor_list_base_) +
|
||||
return sizeof(*location_descriptor_list_base_) +
|
||||
children_.size() * sizeof(MINIDUMP_LOCATION_DESCRIPTOR);
|
||||
}
|
||||
|
||||
@ -86,8 +87,8 @@ bool MinidumpLocationDescriptorListWriter::WriteObject(
|
||||
DCHECK_EQ(children_.size(), child_location_descriptors_.size());
|
||||
|
||||
WritableIoVec iov;
|
||||
iov.iov_base = &location_descriptor_list_base_;
|
||||
iov.iov_len = sizeof(location_descriptor_list_base_);
|
||||
iov.iov_base = location_descriptor_list_base_.get();
|
||||
iov.iov_len = sizeof(*location_descriptor_list_base_);
|
||||
std::vector<WritableIoVec> iovecs(1, iov);
|
||||
|
||||
if (!child_location_descriptors_.empty()) {
|
||||
|
@ -70,7 +70,7 @@ class MinidumpLocationDescriptorListWriter : public MinidumpWritable {
|
||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
private:
|
||||
MinidumpLocationDescriptorList location_descriptor_list_base_;
|
||||
scoped_ptr<MinidumpLocationDescriptorList> location_descriptor_list_base_;
|
||||
PointerVector<MinidumpWritable> children_;
|
||||
std::vector<MINIDUMP_LOCATION_DESCRIPTOR> child_location_descriptors_;
|
||||
|
||||
|
@ -162,9 +162,9 @@ internal::MinidumpWritable::Phase MinidumpMemoryWriter::WritePhase() {
|
||||
|
||||
MinidumpMemoryListWriter::MinidumpMemoryListWriter()
|
||||
: MinidumpStreamWriter(),
|
||||
memory_list_base_(),
|
||||
memory_writers_(),
|
||||
children_() {
|
||||
children_(),
|
||||
memory_list_base_() {
|
||||
}
|
||||
|
||||
MinidumpMemoryListWriter::~MinidumpMemoryListWriter() {
|
||||
|
@ -180,9 +180,9 @@ class MinidumpMemoryListWriter final : public internal::MinidumpStreamWriter {
|
||||
MinidumpStreamType StreamType() const override;
|
||||
|
||||
private:
|
||||
MINIDUMP_MEMORY_LIST memory_list_base_;
|
||||
std::vector<MinidumpMemoryWriter*> memory_writers_; // weak
|
||||
PointerVector<MinidumpMemoryWriter> children_;
|
||||
MINIDUMP_MEMORY_LIST memory_list_base_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryListWriter);
|
||||
};
|
||||
|
@ -375,7 +375,7 @@ bool MinidumpModuleWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||
}
|
||||
|
||||
MinidumpModuleListWriter::MinidumpModuleListWriter()
|
||||
: MinidumpStreamWriter(), module_list_base_(), modules_() {
|
||||
: MinidumpStreamWriter(), modules_(), module_list_base_() {
|
||||
}
|
||||
|
||||
MinidumpModuleListWriter::~MinidumpModuleListWriter() {
|
||||
|
@ -346,8 +346,8 @@ class MinidumpModuleListWriter final : public internal::MinidumpStreamWriter {
|
||||
MinidumpStreamType StreamType() const override;
|
||||
|
||||
private:
|
||||
MINIDUMP_MODULE_LIST module_list_base_;
|
||||
PointerVector<MinidumpModuleWriter> modules_;
|
||||
MINIDUMP_MODULE_LIST module_list_base_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpModuleListWriter);
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ namespace internal {
|
||||
|
||||
MinidumpRVAListWriter::MinidumpRVAListWriter()
|
||||
: MinidumpWritable(),
|
||||
rva_list_base_(),
|
||||
rva_list_base_(new MinidumpRVAList()),
|
||||
children_(),
|
||||
child_rvas_() {
|
||||
}
|
||||
@ -46,7 +46,7 @@ bool MinidumpRVAListWriter::Freeze() {
|
||||
}
|
||||
|
||||
size_t child_count = children_.size();
|
||||
if (!AssignIfInRange(&rva_list_base_.count, child_count)) {
|
||||
if (!AssignIfInRange(&rva_list_base_->count, child_count)) {
|
||||
LOG(ERROR) << "child_count " << child_count << " out of range";
|
||||
return false;
|
||||
}
|
||||
@ -62,7 +62,7 @@ bool MinidumpRVAListWriter::Freeze() {
|
||||
size_t MinidumpRVAListWriter::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
return sizeof(rva_list_base_) + children_.size() * sizeof(RVA);
|
||||
return sizeof(*rva_list_base_) + children_.size() * sizeof(RVA);
|
||||
}
|
||||
|
||||
std::vector<MinidumpWritable*> MinidumpRVAListWriter::Children() {
|
||||
@ -81,8 +81,8 @@ bool MinidumpRVAListWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||
DCHECK_EQ(children_.size(), child_rvas_.size());
|
||||
|
||||
WritableIoVec iov;
|
||||
iov.iov_base = &rva_list_base_;
|
||||
iov.iov_len = sizeof(rva_list_base_);
|
||||
iov.iov_base = rva_list_base_.get();
|
||||
iov.iov_len = sizeof(*rva_list_base_);
|
||||
std::vector<WritableIoVec> iovecs(1, iov);
|
||||
|
||||
if (!child_rvas_.empty()) {
|
||||
|
@ -66,7 +66,7 @@ class MinidumpRVAListWriter : public MinidumpWritable {
|
||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
private:
|
||||
MinidumpRVAList rva_list_base_;
|
||||
scoped_ptr<MinidumpRVAList> rva_list_base_;
|
||||
PointerVector<MinidumpWritable> children_;
|
||||
std::vector<RVA> child_rvas_;
|
||||
|
||||
|
@ -91,7 +91,7 @@ bool MinidumpSimpleStringDictionaryEntryWriter::WriteObject(
|
||||
}
|
||||
|
||||
MinidumpSimpleStringDictionaryWriter::MinidumpSimpleStringDictionaryWriter()
|
||||
: MinidumpWritable(), simple_string_dictionary_base_(), entries_() {
|
||||
: MinidumpWritable(), entries_(), simple_string_dictionary_base_() {
|
||||
}
|
||||
|
||||
MinidumpSimpleStringDictionaryWriter::~MinidumpSimpleStringDictionaryWriter() {
|
||||
|
@ -132,11 +132,11 @@ class MinidumpSimpleStringDictionaryWriter final
|
||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
private:
|
||||
MinidumpSimpleStringDictionary simple_string_dictionary_base_;
|
||||
|
||||
// This object owns the MinidumpSimpleStringDictionaryEntryWriter objects.
|
||||
std::map<std::string, MinidumpSimpleStringDictionaryEntryWriter*> entries_;
|
||||
|
||||
MinidumpSimpleStringDictionary simple_string_dictionary_base_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpSimpleStringDictionaryWriter);
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace internal {
|
||||
|
||||
template <typename Traits>
|
||||
MinidumpStringWriter<Traits>::MinidumpStringWriter()
|
||||
: MinidumpWritable(), string_base_(), string_() {
|
||||
: MinidumpWritable(), string_base_(new MinidumpStringType()), string_() {
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
@ -42,7 +42,7 @@ bool MinidumpStringWriter<Traits>::Freeze() {
|
||||
}
|
||||
|
||||
size_t string_bytes = string_.size() * sizeof(string_[0]);
|
||||
if (!AssignIfInRange(&string_base_.Length, string_bytes)) {
|
||||
if (!AssignIfInRange(&string_base_->Length, string_bytes)) {
|
||||
LOG(ERROR) << "string_bytes " << string_bytes << " out of range";
|
||||
return false;
|
||||
}
|
||||
@ -55,7 +55,7 @@ size_t MinidumpStringWriter<Traits>::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
// Include the NUL terminator.
|
||||
return sizeof(string_base_) + (string_.size() + 1) * sizeof(string_[0]);
|
||||
return sizeof(*string_base_) + (string_.size() + 1) * sizeof(string_[0]);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
@ -66,8 +66,8 @@ bool MinidumpStringWriter<Traits>::WriteObject(
|
||||
// The string’s length is stored in string_base_, and its data is stored in
|
||||
// string_. Write them both.
|
||||
WritableIoVec iov;
|
||||
iov.iov_base = &string_base_;
|
||||
iov.iov_len = sizeof(string_base_);
|
||||
iov.iov_base = string_base_.get();
|
||||
iov.iov_len = sizeof(*string_base_);
|
||||
std::vector<WritableIoVec> iovecs(1, iov);
|
||||
|
||||
// Include the NUL terminator.
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_rva_list_writer.h"
|
||||
@ -75,7 +76,7 @@ class MinidumpStringWriter : public MinidumpWritable {
|
||||
const StringType& string() const { return string_; }
|
||||
|
||||
private:
|
||||
MinidumpStringType string_base_;
|
||||
scoped_ptr<MinidumpStringType> string_base_;
|
||||
StringType string_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpStringWriter);
|
||||
|
@ -129,9 +129,9 @@ bool MinidumpThreadWriter::WriteObject(FileWriterInterface* file_writer) {
|
||||
|
||||
MinidumpThreadListWriter::MinidumpThreadListWriter()
|
||||
: MinidumpStreamWriter(),
|
||||
thread_list_base_(),
|
||||
threads_(),
|
||||
memory_list_writer_(nullptr) {
|
||||
memory_list_writer_(nullptr),
|
||||
thread_list_base_() {
|
||||
}
|
||||
|
||||
MinidumpThreadListWriter::~MinidumpThreadListWriter() {
|
||||
|
@ -202,9 +202,9 @@ class MinidumpThreadListWriter final : public internal::MinidumpStreamWriter {
|
||||
MinidumpStreamType StreamType() const override;
|
||||
|
||||
private:
|
||||
MINIDUMP_THREAD_LIST thread_list_base_;
|
||||
PointerVector<MinidumpThreadWriter> threads_;
|
||||
MinidumpMemoryListWriter* memory_list_writer_; // weak
|
||||
MINIDUMP_THREAD_LIST thread_list_base_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpThreadListWriter);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user