| Index: components/browser_watcher/postmortem_minidump_writer.h
|
| diff --git a/components/browser_watcher/postmortem_minidump_writer.h b/components/browser_watcher/postmortem_minidump_writer.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b9cf944733fed665ebe5633c57c0d6dc75bc1c0b
|
| --- /dev/null
|
| +++ b/components/browser_watcher/postmortem_minidump_writer.h
|
| @@ -0,0 +1,133 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_
|
| +#define COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_
|
| +
|
| +#include <stdint.h>
|
| +
|
| +#include <map>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/files/file.h"
|
| +#include "base/macros.h"
|
| +#include "base/strings/string_piece.h"
|
| +#include "components/browser_watcher/stability_report.pb.h"
|
| +#include "third_party/crashpad/crashpad/minidump/minidump_extensions.h"
|
| +#include "third_party/crashpad/crashpad/util/misc/uuid.h"
|
| +
|
| +namespace browser_watcher {
|
| +
|
| +// A class with functionality for writing minimal minidump containers to wrap
|
| +// postmortem stability reports.
|
| +// TODO(manzagop): remove this class once CrashPad takes over writing postmortem
|
| +// minidumps.
|
| +// TODO(manzagop): revisit where the module information should be transported,
|
| +// in the protocol buffer or in a module stream.
|
| +class PostmortemMinidumpWriter {
|
| + public:
|
| + // Position is an offset within a minidump file. Note: using this type to
|
| + // avoid including windows.h and relying on the RVA type.
|
| + using Position = uint32_t;
|
| +
|
| + // Note: the caller owns |minidump_file| and is responsible for keeping it
|
| + // valid for this object's lifetime. |minidump_file| is expected to be empty
|
| + // and a binary stream.
|
| + explicit PostmortemMinidumpWriter(base::PlatformFile minidump_file);
|
| + ~PostmortemMinidumpWriter() = default;
|
| +
|
| + // Write to |minidump_file| a minimal minidump that wraps |report|. Returns
|
| + // true on success, false otherwise.
|
| + bool WriteDump(const StabilityReport& report,
|
| + const crashpad::UUID& client_id,
|
| + const crashpad::UUID& report_id,
|
| + const std::string& product_name,
|
| + const std::string& version_number);
|
| +
|
| + private:
|
| + // The minidump header is always located at the head.
|
| + static const Position kHeaderPos = 0U;
|
| +
|
| + bool AppendCrashpadInfo(const crashpad::UUID& client_id,
|
| + const crashpad::UUID& report_id,
|
| + const std::map<std::string, std::string>& crash_keys);
|
| +
|
| + bool AppendCrashpadDictionaryEntry(
|
| + const std::string& key,
|
| + const std::string& value,
|
| + std::vector<crashpad::MinidumpSimpleStringDictionaryEntry>* entries);
|
| +
|
| + // Allocate |size_bytes| within the minidump. On success, |pos| contains the
|
| + // location of the allocation. Returns true on success, false otherwise.
|
| + bool Allocate(size_t size_bytes, Position* pos);
|
| +
|
| + // Seeks |cursor_|. The seek operation is kept separate from the write in
|
| + // order to make the call explicit. Seek operations can be costly and should
|
| + // be avoided.
|
| + bool SeekCursor(Position destination);
|
| +
|
| + // Write to pre-allocated space.
|
| + // Note: |pos| must match |cursor_|.
|
| + template <class DataType>
|
| + bool Write(Position pos, const DataType& data);
|
| + bool WriteBytes(Position pos, size_t size_bytes, const void* data);
|
| +
|
| + // Allocate space for and write the contents of |data|. On success, |pos|
|
| + // contains the location of the write. Returns true on success, false
|
| + // otherwise.
|
| + template <class DataType>
|
| + bool Append(const DataType& data, Position* pos);
|
| + template <class DataType>
|
| + bool AppendVec(const std::vector<DataType>& data, Position* pos);
|
| + bool AppendUtf8String(base::StringPiece data, Position* pos);
|
| + bool AppendBytes(base::StringPiece data, Position* pos);
|
| +
|
| + void RegisterDirectoryEntry(uint32_t stream_type,
|
| + Position pos,
|
| + uint32_t size);
|
| +
|
| + // The next allocatable position.
|
| + Position next_available_byte_;
|
| +
|
| + // The position of the cursor used to write.
|
| + Position cursor_;
|
| +
|
| + // Storage for the directory during writes.
|
| + std::vector<MINIDUMP_DIRECTORY> directory_;
|
| +
|
| + // The file to write to.
|
| + base::PlatformFile minidump_file_; // Not owned.
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PostmortemMinidumpWriter);
|
| +};
|
| +
|
| +template <class DataType>
|
| +bool PostmortemMinidumpWriter::Write(Position pos, const DataType& data) {
|
| + return WriteBytes(pos, sizeof(data), &data);
|
| +}
|
| +
|
| +template <class DataType>
|
| +bool PostmortemMinidumpWriter::Append(const DataType& data, Position* pos) {
|
| + DCHECK(pos);
|
| + if (!Allocate(sizeof(data), pos))
|
| + return false;
|
| + return Write(*pos, data);
|
| +}
|
| +
|
| +template <class DataType>
|
| +bool PostmortemMinidumpWriter::AppendVec(const std::vector<DataType>& data,
|
| + Position* pos) {
|
| + DCHECK(!data.empty());
|
| + DCHECK(pos);
|
| +
|
| + size_t size_bytes = sizeof(DataType) * data.size();
|
| + if (!Allocate(size_bytes, pos))
|
| + return false;
|
| + return WriteBytes(*pos, size_bytes, &data.at(0));
|
| +}
|
| +
|
| +} // namespace browser_watcher
|
| +
|
| +#endif // COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_
|
|
|