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