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 <string> | |
12 #include <vector> | |
13 | |
14 #include "base/files/file.h" | |
15 #include "base/macros.h" | |
16 #include "base/strings/string_piece.h" | |
17 #include "components/browser_watcher/stability_report.pb.h" | |
18 #include "third_party/crashpad/crashpad/minidump/minidump_extensions.h" | |
19 #include "third_party/crashpad/crashpad/util/misc/uuid.h" | |
20 | |
21 namespace browser_watcher { | |
22 | |
23 // A class with functionality for writing minimal minidump containers to wrap | |
24 // postmortem stability reports. | |
25 // TODO(manzagop): remove this class once CrashPad takes over writing postmortem | |
26 // minidumps. | |
27 // TODO(manzagop): revisit where the module information should be transported, | |
28 // in the protocol buffer or in a module stream. | |
29 class PostmortemMinidumpWriter { | |
30 public: | |
31 // Position is an offset within a minidump file. Note: using this type to | |
32 // avoid including windows.h and relying on the RVA type. | |
33 using Position = uint32_t; | |
Sigurður Ásgeirsson
2016/09/09 14:21:00
nit: maybe FilePosition? Also, it doesn't look lik
manzagop (departed)
2016/09/09 20:34:40
Done.
| |
34 | |
35 // Note: the caller owns |minidump_file| and is responsible for keeping it | |
36 // valid for this object's lifetime. |minidump_file| is expected to be empty | |
37 // and a binary stream. | |
38 explicit PostmortemMinidumpWriter(base::PlatformFile minidump_file); | |
39 ~PostmortemMinidumpWriter() = default; | |
40 | |
41 // Write to |minidump_file| a minimal minidump that wraps |report|. Returns | |
42 // true on success, false otherwise. | |
43 bool WriteDump(const StabilityReport& report, | |
44 const crashpad::UUID& client_id, | |
45 const crashpad::UUID& report_id, | |
46 const std::string& product_name, | |
47 const std::string& version_number); | |
48 | |
49 private: | |
50 // The minidump header is always located at the head. | |
51 static const Position kHeaderPos = 0U; | |
52 | |
53 bool AppendCrashpadInfo(const crashpad::UUID& client_id, | |
54 const crashpad::UUID& report_id, | |
55 const std::map<std::string, std::string>& crash_keys); | |
56 | |
57 bool AppendCrashpadDictionaryEntry( | |
58 const std::string& key, | |
59 const std::string& value, | |
60 std::vector<crashpad::MinidumpSimpleStringDictionaryEntry>* entries); | |
61 | |
62 // Allocate |size_bytes| within the minidump. On success, |pos| contains the | |
63 // location of the allocation. Returns true on success, false otherwise. | |
64 bool Allocate(size_t size_bytes, Position* pos); | |
65 | |
66 // Seeks |cursor_|. The seek operation is kept separate from the write in | |
67 // order to make the call explicit. Seek operations can be costly and should | |
68 // be avoided. | |
69 bool SeekCursor(Position destination); | |
70 | |
71 // Write to pre-allocated space. | |
72 // Note: |pos| must match |cursor_|. | |
73 template <class DataType> | |
74 bool Write(Position pos, const DataType& data); | |
75 bool WriteBytes(Position pos, size_t size_bytes, const void* data); | |
76 | |
77 // Allocate space for and write the contents of |data|. On success, |pos| | |
78 // contains the location of the write. Returns true on success, false | |
79 // otherwise. | |
80 template <class DataType> | |
81 bool Append(const DataType& data, Position* pos); | |
82 template <class DataType> | |
83 bool AppendVec(const std::vector<DataType>& data, Position* pos); | |
84 bool AppendUtf8String(base::StringPiece data, Position* pos); | |
85 bool AppendBytes(base::StringPiece data, Position* pos); | |
86 | |
87 void RegisterDirectoryEntry(uint32_t stream_type, | |
88 Position pos, | |
89 uint32_t size); | |
90 | |
91 // The next allocatable position. | |
92 Position next_available_byte_; | |
93 | |
94 // The position of the cursor used to write. | |
95 Position cursor_; | |
Sigurður Ásgeirsson
2016/09/09 14:21:00
is this synonymous with the position of minidump_f
manzagop (departed)
2016/09/09 20:34:40
It is. Its only use was to DCHECK-validate there's
| |
96 | |
97 // Storage for the directory during writes. | |
98 std::vector<MINIDUMP_DIRECTORY> directory_; | |
99 | |
100 // The file to write to. | |
101 base::PlatformFile minidump_file_; // Not owned. | |
Sigurður Ásgeirsson
2016/09/09 14:21:00
why not use a base::File or File*? This provides t
manzagop (departed)
2016/09/09 20:34:40
As discussed, switched to File but needed to dupli
| |
102 | |
103 DISALLOW_COPY_AND_ASSIGN(PostmortemMinidumpWriter); | |
104 }; | |
105 | |
106 template <class DataType> | |
107 bool PostmortemMinidumpWriter::Write(Position pos, const DataType& data) { | |
108 return WriteBytes(pos, sizeof(data), &data); | |
Sigurður Ásgeirsson
2016/09/09 14:21:00
TIL: you can static_assert(std::is_pod<DataType>::
manzagop (departed)
2016/09/09 20:34:40
Oh cool!
Hm, looks like I can't use that because
| |
109 } | |
110 | |
111 template <class DataType> | |
112 bool PostmortemMinidumpWriter::Append(const DataType& data, Position* pos) { | |
113 DCHECK(pos); | |
114 if (!Allocate(sizeof(data), pos)) | |
115 return false; | |
116 return Write(*pos, data); | |
117 } | |
118 | |
119 template <class DataType> | |
120 bool PostmortemMinidumpWriter::AppendVec(const std::vector<DataType>& data, | |
121 Position* pos) { | |
122 DCHECK(!data.empty()); | |
123 DCHECK(pos); | |
124 | |
125 size_t size_bytes = sizeof(DataType) * data.size(); | |
126 if (!Allocate(size_bytes, pos)) | |
127 return false; | |
128 return WriteBytes(*pos, size_bytes, &data.at(0)); | |
129 } | |
130 | |
131 } // namespace browser_watcher | |
132 | |
133 #endif // COMPONENTS_BROWSER_WATCHER_POSTMORTEM_MINIDUMP_WRITER_H_ | |
OLD | NEW |