1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : // A utility class for reading minidumps.
16 :
17 : #ifndef SYZYGY_MINIDUMP_MINIDUMP_H_
18 : #define SYZYGY_MINIDUMP_MINIDUMP_H_
19 :
20 : #include <windows.h> // NOLINT
21 : #include <dbghelp.h>
22 :
23 : #include <string>
24 : #include <vector>
25 :
26 : #include "base/macros.h"
27 : #include "base/files/file_path.h"
28 : #include "base/files/scoped_file.h"
29 :
30 : namespace minidump {
31 :
32 : // fwd.
33 : class Minidump;
34 :
35 : class Minidump {
36 : public:
37 : static const size_t kNoStreamId = static_cast<size_t>(-1);
38 :
39 : class Stream;
40 :
41 : Minidump();
42 : ~Minidump();
43 :
44 : // Opens the minidump file at @p path and verifies its header structure.
45 : // @param path the minidump file to open.
46 : // @return true on success, false on failure.
47 : bool Open(const base::FilePath& path);
48 :
49 : // Returns a stream for @p location.
50 : // @param location defines the offset and length of the returned stream.
51 : Stream GetStreamFor(const MINIDUMP_LOCATION_DESCRIPTOR& location) const;
52 :
53 : // Returns a stream for the file's @p stream_id.
54 : // @param stream_id the stream id to return, must be a valid stream id.
55 : Stream GetStream(size_t stream_id) const;
56 :
57 : // Find the next stream of type @p stream_type.
58 : // @param prev the previous stream of this type or nullptr.
59 : // @param stream_type the stream type to look for.
60 : // @returns a valid stream if one can be found, otherwise an invalid stream.
61 : Stream FindNextStream(const Stream* prev, size_t stream_type) const;
62 :
63 : // Accessors.
64 E : const std::vector<MINIDUMP_DIRECTORY>& directory() const {
65 E : return directory_;
66 E : }
67 :
68 : private:
69 : friend class Stream;
70 :
71 : // @name Data accessors.
72 : // Reads file contents.
73 : // @param offset the file offset to read from.
74 : // @param data_size the amount of data to read.
75 : // @param data where to write the data, must be of size @p data_data size or
76 : // larger.
77 : // @returns true on success, false on failure, including a short read.
78 : bool ReadBytes(size_t offset, size_t data_size, void* data) const;
79 :
80 : base::ScopedFILE file_;
81 : std::vector<MINIDUMP_DIRECTORY> directory_;
82 :
83 : DISALLOW_COPY_AND_ASSIGN(Minidump);
84 : };
85 :
86 : // A forward-only reading class that bounds reads to streams that make it safe
87 : // and easy to parse minidump streams.
88 : class Minidump::Stream {
89 : public:
90 : Stream();
91 : Stream(const Minidump* minidump, size_t offset, size_t length,
92 : size_t stream_id);
93 :
94 E : bool IsValid() const { return minidump_ != nullptr; }
95 : bool ReadBytes(size_t data_len, void* data);
96 : bool ReadBytes(size_t data_len, std::string* data);
97 :
98 : template <class DataType>
99 : bool ReadElement(DataType* element);
100 :
101 : bool ReadString(std::wstring* data);
102 :
103 E : size_t GetRemainingBytes() const { return remaining_length_; }
104 E : size_t stream_id() const { return stream_id_; }
105 :
106 : private:
107 : const Minidump* minidump_;
108 :
109 : size_t current_offset_;
110 : size_t remaining_length_;
111 : size_t stream_id_;
112 : };
113 :
114 : template <typename DataType>
115 E : bool Minidump::Stream::ReadElement(DataType* element) {
116 E : return ReadBytes(sizeof(DataType), element);
117 E : }
118 :
119 : } // namespace minidump
120 :
121 : #endif // SYZYGY_MINIDUMP_MINIDUMP_H_
|