|
3 | 3 | #include <cstdint> |
4 | 4 | #include <exception> |
5 | 5 | #include <ostream> |
| 6 | +#include <utility> |
6 | 7 | #include <vector> |
7 | 8 | #ifdef _WIN32 |
8 | 9 | #include <windows.h> |
@@ -70,7 +71,6 @@ struct PidTidEncoder { |
70 | 71 | // A span into the main buffer |
71 | 72 | struct Record { |
72 | 73 | const uint64_t *p; |
73 | | - ; |
74 | 74 | uint16_t len_word; |
75 | 75 | uint64_t header; |
76 | 76 | }; |
@@ -171,13 +171,26 @@ std::vector<uint8_t> read_input(const char *input) { |
171 | 171 | return buf; |
172 | 172 | } |
173 | 173 |
|
174 | | -// read next record starting at `offset` |
175 | | -Record read_next_record(std::vector<uint8_t> const &input, size_t &offset) { |
| 174 | +// read next record starting at `offset`. Returns |
| 175 | +// either `(ok, r)` for an in-bound record, or `(false, …)` otherwise. |
| 176 | +std::pair<bool, Record> read_next_record(std::vector<uint8_t> const &input, size_t &offset) { |
| 177 | + |
| 178 | + // bound check |
| 179 | +#define CHECK_BOUND(n) if ((n) > input.size()) { \ |
| 180 | + fprintf(stderr, "warning: invalid record at offset %" PRIu64 "\n", offset); \ |
| 181 | + return std::make_pair(false,Record{}); \ |
| 182 | +} |
| 183 | + |
| 184 | + CHECK_BOUND(offset+8); |
| 185 | + |
176 | 186 | uint64_t header = *((uint64_t *)&input[offset]); |
177 | 187 | uint16_t len_word = (header >> 4) & 0xfff; |
178 | | - Record sp{(uint64_t *)&input[offset], len_word, header}; |
| 188 | + |
| 189 | + CHECK_BOUND(offset + 8*len_word); |
| 190 | + |
| 191 | + Record r{(uint64_t *)&input[offset], len_word, header}; |
179 | 192 | offset += 8 * len_word; |
180 | | - return sp; |
| 193 | + return std::make_pair(true, r); |
181 | 194 | } |
182 | 195 |
|
183 | 196 | // there might be multiple processes so we allocate a pseudo-tid |
@@ -398,7 +411,8 @@ int main(int argc, char **argv) { |
398 | 411 | #define CHECK_INIT() if (!initialized) throw TraceNotInitialized{} |
399 | 412 |
|
400 | 413 | while (offset < buf.size()) { |
401 | | - Record r = read_next_record(buf, offset); |
| 414 | + auto [ok, r] = read_next_record(buf, offset); |
| 415 | + if (!ok) break; |
402 | 416 | n_records++; |
403 | 417 |
|
404 | 418 | uint8_t ty = r.header & 0xf; |
|
0 commit comments