-
Notifications
You must be signed in to change notification settings - Fork 566
/
Copy pathfile_reader.h
188 lines (169 loc) · 6.15 KB
/
file_reader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* **********************************************************
* Copyright (c) 2016-2023 Google, Inc. All rights reserved.
* **********************************************************/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Google, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
/* file_reader: obtains memory streams from DR clients running in
* application processes and presents them via an iterator interface
* to the cache simulator.
*/
#ifndef _FILE_READER_H_
#define _FILE_READER_H_ 1
#include <inttypes.h>
#include <stdint.h>
#include <string.h>
#include <fstream>
#include <queue>
#include <string>
#include <vector>
#include "directory_iterator.h"
#include "memref.h"
#include "reader.h"
#include "trace_entry.h"
#include "utils.h"
namespace dynamorio {
namespace drmemtrace {
#ifndef ZHEX64_FORMAT_STRING
/* We avoid dr_defines.h to keep this code separated and simpler for using with
* external code.
*/
# ifdef WINDOWS
# define ZHEX64_FORMAT_STRING "%016I64x"
# else
# define ZHEX64_FORMAT_STRING "%" PRIx64
# endif
#endif
/**
* We templatize on the file type itself for specializing for compression and
* other different types. An alternative would be to require a std::istream
* interface and add gzip_istream_t (paralleling gzip_ostream_t used for
* raw2trace).
*/
template <typename T> class file_reader_t : public reader_t {
public:
file_reader_t();
file_reader_t(const std::string &path, int verbosity = 0)
: reader_t(verbosity, "[file_reader]")
, input_path_(path)
{
online_ = false;
}
virtual ~file_reader_t();
bool
init() override
{
at_eof_ = false;
if (!open_input_file())
return false;
++*this;
return true;
}
std::string
get_stream_name() const override
{
size_t ind = input_path_.find_last_of(DIRSEP);
if (ind == std::string::npos)
return input_path_;
return input_path_.substr(ind + 1);
}
protected:
trace_entry_t *
read_next_entry() override;
virtual bool
open_single_file(const std::string &path);
virtual bool
open_input_file()
{
if (!open_single_file(input_path_)) {
ERRMSG("Failed to open %s\n", input_path_.c_str());
return false;
}
// First read the tid and pid entries which precede any timestamps.
// We hand out the tid to the output on every thread switch, and the pid
// the very first time for the thread.
trace_entry_t *entry;
trace_entry_t header = {}, pid = {}, tid = {};
entry = read_next_entry();
if (entry == nullptr || entry->type != TRACE_TYPE_HEADER) {
ERRMSG("Invalid header\n");
return false;
}
header = *entry;
// We can handle the older version 1 as well which simply omits the
// early marker with the arch tag, and version 2 which only differs wrt
// TRACE_MARKER_TYPE_KERNEL_EVENT.
if (entry->addr > TRACE_ENTRY_VERSION) {
ERRMSG("Cannot handle version #%zu (expect version <= #%u)\n", entry->addr,
TRACE_ENTRY_VERSION);
return false;
}
// Read the meta entries until we hit the pid.
// We want to pass the tid+pid to the reader *before* any markers,
// even though markers can precede the tid+pid in the file, in particular
// for legacy traces.
std::queue<trace_entry_t> marker_queue;
while ((entry = read_next_entry()) != nullptr) {
if (entry->type == TRACE_TYPE_PID) {
// We assume the pid entry is after the tid.
pid = *entry;
break;
} else if (entry->type == TRACE_TYPE_THREAD)
tid = *entry;
else if (entry->type == TRACE_TYPE_MARKER)
marker_queue.push(*entry);
else {
ERRMSG("Unexpected trace sequence\n");
return false;
}
}
VPRINT(this, 2, "Read header: ver=%zu, pid=%zu, tid=%zu\n", header.addr, pid.addr,
tid.addr);
// The reader expects us to own the header and pass the tid as
// the first entry.
queue_.push(tid);
queue_.push(pid);
while (!marker_queue.empty()) {
queue_.push(marker_queue.front());
marker_queue.pop();
}
return true;
}
// Provided so that instantiations can specialize.
reader_t &
skip_instructions(uint64_t instruction_count) override
{
return reader_t::skip_instructions(instruction_count);
}
// Protected for access by mock_file_reader_t.
T input_file_;
private:
std::string input_path_;
};
} // namespace drmemtrace
} // namespace dynamorio
#endif /* _FILE_READER_H_ */