OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_ | |
6 #define COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <map> | |
11 #include <memory> | |
12 #include <string> | |
13 #include <vector> | |
14 | |
15 #include "base/files/file.h" | |
16 #include "base/macros.h" | |
17 #include "base/strings/string_piece.h" | |
18 #include "components/browser_watcher/stability_report.pb.h" | |
19 #include "third_party/crashpad/crashpad/minidump/minidump_extensions.h" | |
20 #include "third_party/crashpad/crashpad/util/misc/uuid.h" | |
21 | |
22 namespace browser_watcher { | |
23 | |
24 // A class with functionality for writing minimal minidump containers to wrap | |
25 // postmortem stability reports. | |
26 // TODO(manzagop): remove this class once CrashPad takes over writing postmortem | |
27 // minidumps. | |
28 // TODO(manzagop): revisit where the module information should be transported, | |
29 // in the protocol buffer or in a module stream. | |
30 class PostmortemMinidumpWriter { | |
31 public: | |
32 struct ReportInfo; | |
33 | |
34 PostmortemMinidumpWriter() = default; | |
35 ~PostmortemMinidumpWriter() = default; | |
36 | |
37 // Write to |minidump_file| a minimal minidump that wraps |report|. Returns | |
38 // true on success, false otherwise. | |
39 // Note: the caller owns |minidump_file| and is responsible for keeping it | |
40 // valid for this object's lifetime. |minidump_file| is expected to be empty | |
41 // and a binary stream. | |
42 bool WriteDump(base::PlatformFile minidump_file, | |
43 const StabilityReport& report, | |
44 const ReportInfo& report_info); | |
45 | |
46 private: | |
47 // An offset within a minidump file. Note: using this type to avoid including | |
48 // windows.h and relying on the RVA type. | |
49 using FilePosition = uint32_t; | |
50 | |
51 // The minidump header is always located at the head. | |
52 static const FilePosition kHeaderPos = 0U; | |
53 | |
54 void Initialize(); | |
55 | |
56 bool AppendCrashpadInfo(const crashpad::UUID& client_id, | |
57 const crashpad::UUID& report_id, | |
58 const std::map<std::string, std::string>& crash_keys); | |
59 | |
60 bool AppendCrashpadDictionaryEntry( | |
61 const std::string& key, | |
62 const std::string& value, | |
63 std::vector<crashpad::MinidumpSimpleStringDictionaryEntry>* entries); | |
64 | |
65 // Allocate |size_bytes| within the minidump. On success, |pos| contains the | |
66 // location of the allocation. Returns true on success, false otherwise. | |
67 bool Allocate(size_t size_bytes, FilePosition* pos); | |
68 | |
69 // Seeks |cursor_|. The seek operation is kept separate from the write in | |
70 // order to make the call explicit. Seek operations can be costly and should | |
71 // be avoided. | |
72 bool SeekCursor(FilePosition destination); | |
73 | |
74 // Write to pre-allocated space. | |
75 // Note: |pos| must match |cursor_|. | |
76 template <class DataType> | |
77 bool Write(FilePosition pos, const DataType& data); | |
78 bool WriteBytes(FilePosition pos, size_t size_bytes, const char* data); | |
79 | |
80 // Allocate space for and write the contents of |data|. On success, |pos| | |
81 // contains the location of the write. Returns true on success, false | |
82 // otherwise. | |
83 template <class DataType> | |
84 bool Append(const DataType& data, FilePosition* pos); | |
85 template <class DataType> | |
86 bool AppendVec(const std::vector<DataType>& data, FilePosition* pos); | |
87 bool AppendUtf8String(base::StringPiece data, FilePosition* pos); | |
88 bool AppendBytes(base::StringPiece data, FilePosition* pos); | |
89 | |
90 void RegisterDirectoryEntry(uint32_t stream_type, | |
91 FilePosition pos, | |
92 uint32_t size); | |
93 | |
94 // The next allocatable FilePosition. | |
95 FilePosition next_available_byte_; | |
96 | |
97 // Storage for the directory during writes. | |
98 std::vector<MINIDUMP_DIRECTORY> directory_; | |
99 | |
100 // The file to write to. | |
101 std::unique_ptr<base::File> minidump_file_; | |
Sigurður Ásgeirsson
2016/09/13 14:57:09
IMHO simpler to use a base::File* here, and scope
manzagop (departed)
2016/09/13 16:22:44
Done.
| |
102 | |
103 DISALLOW_COPY_AND_ASSIGN(PostmortemMinidumpWriter); | |
104 }; | |
105 | |
106 struct PostmortemMinidumpWriter::ReportInfo { | |
107 crashpad::UUID client_id; | |
Sigurður Ásgeirsson
2016/09/13 14:57:09
nit: maybe a little bit of documentation?
manzagop (departed)
2016/09/13 16:22:44
Done.
| |
108 crashpad::UUID report_id; | |
109 std::string product_name; | |
110 std::string version_number; | |
111 }; | |
112 | |
113 template <class DataType> | |
114 bool PostmortemMinidumpWriter::Write(FilePosition pos, const DataType& data) { | |
115 // Note: we cannot static_assert that std::is_pod<DataType>::value, because | |
116 // MinidumpCrashpadInfo is in fact non-POD. | |
117 return WriteBytes(pos, sizeof(data), reinterpret_cast<const char*>(&data)); | |
118 } | |
119 | |
120 template <class DataType> | |
121 bool PostmortemMinidumpWriter::Append(const DataType& data, FilePosition* pos) { | |
122 // Note: we cannot static_assert that std::is_pod<DataType>::value, because | |
Sigurður Ásgeirsson
2016/09/13 14:57:09
No need for the note, if we can't do it, we can't
manzagop (departed)
2016/09/13 16:22:44
Found is_trivially_copyable. Done.
| |
123 // MinidumpCrashpadInfo is in fact non-POD. | |
124 DCHECK(pos); | |
125 if (!Allocate(sizeof(data), pos)) | |
126 return false; | |
127 return Write(*pos, data); | |
128 } | |
129 | |
130 template <class DataType> | |
131 bool PostmortemMinidumpWriter::AppendVec(const std::vector<DataType>& data, | |
132 FilePosition* pos) { | |
133 static_assert(std::is_pod<DataType>::value, "restricted to POD"); | |
134 DCHECK(!data.empty()); | |
135 DCHECK(pos); | |
136 | |
137 size_t size_bytes = sizeof(DataType) * data.size(); | |
138 if (!Allocate(size_bytes, pos)) | |
139 return false; | |
140 return WriteBytes(*pos, size_bytes, | |
141 reinterpret_cast<const char*>(&data.at(0))); | |
142 } | |
143 | |
144 } // namespace browser_watcher | |
145 | |
146 #endif // COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_ | |
OLD | NEW |