diff --git a/clients/drcachesim/CMakeLists.txt b/clients/drcachesim/CMakeLists.txt index 4a484189868..176e1c42ad0 100644 --- a/clients/drcachesim/CMakeLists.txt +++ b/clients/drcachesim/CMakeLists.txt @@ -1,5 +1,5 @@ # ********************************************************** -# Copyright (c) 2015-2022 Google, Inc. All rights reserved. +# Copyright (c) 2015-2023 Google, Inc. All rights reserved. # ********************************************************** # Redistribution and use in source and binary forms, with or without @@ -699,7 +699,7 @@ if (BUILD_TESTS) add_test(NAME tool.drcachesim.invariant_checker_test COMMAND tool.drcachesim.invariant_checker_test) - add_executable(tool.drcacheoff.view_test tests/view_test.cpp) + add_executable(tool.drcacheoff.view_test tests/view_test.cpp reader/file_reader.cpp) configure_DynamoRIO_standalone(tool.drcacheoff.view_test) add_win32_flags(tool.drcacheoff.view_test) target_link_libraries(tool.drcacheoff.view_test drmemtrace_view drmemtrace_raw2trace) diff --git a/clients/drcachesim/reader/file_reader.h b/clients/drcachesim/reader/file_reader.h index 076a0f8d2ff..60d6277ce5e 100644 --- a/clients/drcachesim/reader/file_reader.h +++ b/clients/drcachesim/reader/file_reader.h @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2016-2022 Google, Inc. All rights reserved. + * Copyright (c) 2016-2023 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -361,10 +361,12 @@ template class file_reader_t : public reader_t { return true; } + // Protected for access by mock_file_reader_t. + std::vector input_files_; + private: std::string input_path_; std::vector input_path_list_; - std::vector input_files_; trace_entry_t entry_copy_; // The current thread we're processing is "index". If it's set to input_files_.size() // that means we need to pick a new thread. diff --git a/clients/drcachesim/reader/reader.cpp b/clients/drcachesim/reader/reader.cpp index a8cded4de48..9eba5f577fc 100644 --- a/clients/drcachesim/reader/reader.cpp +++ b/clients/drcachesim/reader/reader.cpp @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2016-2022 Google, Inc. All rights reserved. + * Copyright (c) 2016-2023 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -262,21 +262,19 @@ reader_t::process_input_entry() // and use them to start post-seek iteration. if (chunk_instr_count_ > 0 && cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_TIMESTAMP && - cur_instr_count_ / chunk_instr_count_ != - last_timestamp_instr_count_ / chunk_instr_count_) { + skip_chunk_header_.find(cur_tid_) != skip_chunk_header_.end()) { VPRINT(this, 2, "skipping start-of-chunk dup timestamp\n"); - skip_next_cpu_ = true; - } else if (cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_CPU_ID && - skip_next_cpu_) { + } else if (chunk_instr_count_ > 0 && + cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_CPU_ID && + skip_chunk_header_.find(cur_tid_) != skip_chunk_header_.end()) { VPRINT(this, 2, "skipping start-of-chunk dup cpu\n"); - skip_next_cpu_ = false; + skip_chunk_header_.erase(cur_tid_); } else if (cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_RECORD_ORDINAL) { // Not exposed to tools. } else { have_memref = true; } if (cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_TIMESTAMP) { - last_timestamp_instr_count_ = cur_instr_count_; // Today, a skipped memref is just a duplicate of one that we've // already seen, so this condition is not really needed. But to // be future-proof, we want to avoid looking at timestamps that @@ -295,6 +293,8 @@ reader_t::process_input_entry() page_size_ = cur_ref_.marker.marker_value; else if (cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_CHUNK_INSTR_COUNT) chunk_instr_count_ = cur_ref_.marker.marker_value; + else if (cur_ref_.marker.marker_type == TRACE_MARKER_TYPE_CHUNK_FOOTER) + skip_chunk_header_.insert(cur_tid_); break; default: ERRMSG("Unknown trace entry type %s (%d)\n", trace_type_names[input_entry_->type], @@ -305,7 +305,8 @@ reader_t::process_input_entry() } if (have_memref) { if (suppress_ref_count_ > 0) { - VPRINT(this, 4, "suppressing %" PRIu64 " ref counts\n", suppress_ref_count_); + VPRINT(this, 4, "suppressing %" PRIu64 " ref counts @%" PRIu64 "\n", + suppress_ref_count_, cur_ref_count_); --suppress_ref_count_; } else { if (suppress_ref_count_ == 0) { @@ -313,6 +314,7 @@ reader_t::process_input_entry() suppress_ref_count_ = -1; } ++cur_ref_count_; + VPRINT(this, 5, "ref count is now @%" PRIu64 "\n", cur_ref_count_); } } return have_memref; diff --git a/clients/drcachesim/reader/reader.h b/clients/drcachesim/reader/reader.h index ebdbda23f93..c1a40143dc8 100644 --- a/clients/drcachesim/reader/reader.h +++ b/clients/drcachesim/reader/reader.h @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2015-2022 Google, Inc. All rights reserved. + * Copyright (c) 2015-2023 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -40,6 +40,7 @@ #include #include #include +#include // For exporting we avoid "../common" and rely on -I. #include "memref.h" #include "memtrace_stream.h" @@ -204,7 +205,7 @@ class reader_t : public std::iterator, uint64_t cur_ref_count_ = 0; int64_t suppress_ref_count_ = -1; uint64_t cur_instr_count_ = 0; - uint64_t last_timestamp_instr_count_ = 0; + std::unordered_set skip_chunk_header_; uint64_t last_timestamp_ = 0; trace_entry_t *input_entry_ = nullptr; // Remember top-level headers for the memtrace_stream_t interface. @@ -228,7 +229,6 @@ class reader_t : public std::iterator, addr_t prev_instr_addr_ = 0; int bundle_idx_ = 0; std::unordered_map tid2pid_; - bool skip_next_cpu_ = false; bool expect_no_encodings_ = true; encoding_info_t last_encoding_; std::unordered_map encodings_; diff --git a/clients/drcachesim/reader/zipfile_file_reader.cpp b/clients/drcachesim/reader/zipfile_file_reader.cpp index 5a779f0dc63..315453560e5 100644 --- a/clients/drcachesim/reader/zipfile_file_reader.cpp +++ b/clients/drcachesim/reader/zipfile_file_reader.cpp @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2017-2022 Google, Inc. All rights reserved. + * Copyright (c) 2017-2023 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -187,6 +187,7 @@ file_reader_t::skip_thread_instructions(size_t thread_index, zipfile->cur_buf = zipfile->max_buf; } // We have to linearly walk the last mile. + bool prev_was_record_ord = false; while (cur_instr_count_ < stop_count_) { // End condition is never reached. if (!read_next_thread_entry(thread_index, &entry_copy_, eof)) return false; @@ -197,16 +198,26 @@ file_reader_t::skip_thread_instructions(size_t thread_index, type_is_instr(static_cast(entry_copy_.type))) break; // To examine the produced memrefs we'd have to have the base reader - // expose these hidden entries. It is simpler for use to read the + // expose these hidden entries. It is simpler for us to read the // trace_entry_t directly prior to processing by the base class. if (entry_copy_.type == TRACE_TYPE_MARKER) { - if (entry_copy_.size == TRACE_MARKER_TYPE_RECORD_ORDINAL) + if (entry_copy_.size == TRACE_MARKER_TYPE_RECORD_ORDINAL) { cur_ref_count_ = entry_copy_.addr; - else if (entry_copy_.size == TRACE_MARKER_TYPE_TIMESTAMP) + prev_was_record_ord = true; + VPRINT(this, 4, "Found record ordinal marker: new ord %" PRIu64 "\n", + cur_ref_count_); + } else if (entry_copy_.size == TRACE_MARKER_TYPE_TIMESTAMP) { timestamp = entry_copy_; - else if (entry_copy_.size == TRACE_MARKER_TYPE_CPU_ID) + if (prev_was_record_ord) + --cur_ref_count_; + } else if (entry_copy_.size == TRACE_MARKER_TYPE_CPU_ID) { cpu = entry_copy_; - } + if (prev_was_record_ord) + --cur_ref_count_; + } else + prev_was_record_ord = false; + } else + prev_was_record_ord = false; // Update core state. input_entry_ = &entry_copy_; process_input_entry(); diff --git a/clients/drcachesim/tests/drmemtrace.allasm_x86_64.trace.zip b/clients/drcachesim/tests/drmemtrace.allasm_x86_64.trace.zip index 1e7facfe94e..defafa0588f 100644 Binary files a/clients/drcachesim/tests/drmemtrace.allasm_x86_64.trace.zip and b/clients/drcachesim/tests/drmemtrace.allasm_x86_64.trace.zip differ diff --git a/clients/drcachesim/tests/offline-skip.expect b/clients/drcachesim/tests/offline-skip.expect index cd13d9371b5..d4bb76fb112 100644 --- a/clients/drcachesim/tests/offline-skip.expect +++ b/clients/drcachesim/tests/offline-skip.expect @@ -1,17 +1,17 @@ Output format: : T ------------------------------------------------------------ - 0 63: T1384871 - 0 63: T1384871 - 92 64: T1384871 ifetch 4 byte(s) @ 0x0000000000401028 48 83 eb 01 sub $0x0000000000000001 %rbx -> %rbx - 93 65: T1384871 ifetch 4 byte(s) @ 0x000000000040102c 48 83 fb 00 cmp %rbx $0x0000000000000000 - 94 66: T1384871 ifetch 2 byte(s) @ 0x0000000000401030 75 d9 jnz $0x000000000040100b - 95 67: T1384871 ifetch 7 byte(s) @ 0x000000000040100b 48 c7 c7 01 00 00 00 mov $0x0000000000000001 -> %rdi - 96 68: T1384871 ifetch 8 byte(s) @ 0x0000000000401012 48 8d 34 25 00 20 40 lea 0x00402000 -> %rsi - 96 68: T1384871 00 - 97 69: T1384871 ifetch 7 byte(s) @ 0x000000000040101a 48 c7 c2 0d 00 00 00 mov $0x000000000000000d -> %rdx - 98 70: T1384871 ifetch 5 byte(s) @ 0x0000000000401021 b8 01 00 00 00 mov $0x00000001 -> %eax - 99 71: T1384871 ifetch 2 byte(s) @ 0x0000000000401026 0f 05 syscall -> %rcx %r11 + 0 63: T296231 + 0 63: T296231 + 90 64: T296231 ifetch 4 byte(s) @ 0x0000000000401028 48 83 eb 01 sub $0x0000000000000001 %rbx -> %rbx + 91 65: T296231 ifetch 4 byte(s) @ 0x000000000040102c 48 83 fb 00 cmp %rbx $0x0000000000000000 + 92 66: T296231 ifetch 2 byte(s) @ 0x0000000000401030 75 d9 jnz $0x000000000040100b + 93 67: T296231 ifetch 7 byte(s) @ 0x000000000040100b 48 c7 c7 01 00 00 00 mov $0x0000000000000001 -> %rdi + 94 68: T296231 ifetch 8 byte(s) @ 0x0000000000401012 48 8d 34 25 00 20 40 lea 0x00402000 -> %rsi + 94 68: T296231 00 + 95 69: T296231 ifetch 7 byte(s) @ 0x000000000040101a 48 c7 c2 0d 00 00 00 mov $0x000000000000000d -> %rdx + 96 70: T296231 ifetch 5 byte(s) @ 0x0000000000401021 b8 01 00 00 00 mov $0x00000001 -> %eax + 97 71: T296231 ifetch 2 byte(s) @ 0x0000000000401026 0f 05 syscall -> %rcx %r11 View tool results: 8 : total instructions diff --git a/clients/drcachesim/tests/view_test.cpp b/clients/drcachesim/tests/view_test.cpp index f95ea20aa19..ed544327e61 100644 --- a/clients/drcachesim/tests/view_test.cpp +++ b/clients/drcachesim/tests/view_test.cpp @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2021-2022 Google, LLC All rights reserved. + * Copyright (c) 2021-2023 Google, LLC All rights reserved. * **********************************************************/ /* @@ -34,11 +34,14 @@ #include #include +#include +#include #include #include "../tools/view.h" #include "../common/memref.h" #include "../tracer/raw2trace.h" +#include "../reader/file_reader.h" #include "memref_gen.h" #undef ASSERT @@ -58,6 +61,34 @@ } \ } while (0) +// These are for our mock serial reader and must be in the same namespace +// as file_reader_t's declaration. +template <> file_reader_t>::~file_reader_t() +{ +} + +template <> +bool +file_reader_t>::is_complete() +{ + return false; +} + +template <> +bool +file_reader_t>::open_single_file(const std::string &path) +{ + return true; +} + +template <> +bool +file_reader_t>::read_next_thread_entry( + size_t thread_index, OUT trace_entry_t *entry, OUT bool *eof) +{ + return false; +} + namespace { // Subclasses module_mapper_t and replaces the module loading with a buffer @@ -382,13 +413,243 @@ run_limit_tests(void *drcontext) instrlist_clear_and_destroy(drcontext, ilist); return res; } + +/*************************************************************************** + * Serial reader mock. + */ + +class mock_file_reader_t : public file_reader_t> { +public: + mock_file_reader_t() + { + } + mock_file_reader_t(const std::vector> &entries) + : file_reader_t(std::vector(1, "non-empty")) + { + input_files_ = entries; + pos_.resize(input_files_.size(), 0); + init(); + } + bool + read_next_thread_entry(size_t thread_index, OUT trace_entry_t *entry, + OUT bool *eof) override + { + if (pos_[thread_index] >= input_files_[thread_index].size()) { + *eof = true; + return false; + } + *entry = input_files_[thread_index][pos_[thread_index]]; + ++pos_[thread_index]; + return true; + } + +private: + std::vector pos_; +}; + +std::string +run_serial_test_helper(view_t &view, + const std::vector> &entries) +{ + class local_stream_t : public default_memtrace_stream_t { + public: + local_stream_t(view_t &view, + const std::vector> &entries) + : view_(view) + , entries_(entries) + { + } + + std::string + run() + { + view_.initialize_stream(this); + // Capture cerr. + std::stringstream capture; + std::streambuf *prior = std::cerr.rdbuf(capture.rdbuf()); + // Run the tool. + mock_file_reader_t serial(entries_); + mock_file_reader_t end; + for (; serial != end; ++serial) { + const memref_t memref = *serial; + ++ref_count_; + if (type_is_instr(memref.instr.type)) + ++instr_count_; + if (!view_.process_memref(memref)) + std::cout << "Hit error: " << view_.get_error_string() << "\n"; + } + // Return the result. + std::string res = capture.str(); + std::cerr.rdbuf(prior); + return res; + } + + uint64_t + get_record_ordinal() const override + { + return ref_count_; + } + uint64_t + get_instruction_ordinal() const override + { + return instr_count_; + } + + private: + view_t &view_; + const std::vector> &entries_; + uint64_t ref_count_ = 0; + uint64_t instr_count_ = 0; + }; + + local_stream_t stream(view, entries); + return stream.run(); +} + +/***************************************************************************/ + +bool +run_single_thread_chunk_test(void *drcontext) +{ + const memref_tid_t t1 = 3; + std::vector> entries = { { + { TRACE_TYPE_HEADER, 0, { 0x1 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_VERSION, { 3 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_FILETYPE, { 0 } }, + { TRACE_TYPE_THREAD, 0, { t1 } }, + { TRACE_TYPE_PID, 0, { t1 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CACHE_LINE_SIZE, { 64 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CHUNK_INSTR_COUNT, { 2 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_TIMESTAMP, { 1002 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CPU_ID, { 2 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CHUNK_FOOTER, { 0 } }, + // We're testing that the reader hides this duplicate timestamp + // at the start of a chunk. + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_TIMESTAMP, { 1002 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CPU_ID, { 3 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + } }; + const char *expect = R"DELIM( 1 0: T3 + 2 0: T3 + 3 0: T3 + 4 0: T3 + 5 0: T3 + 6 0: T3 + 7 1: T3 ifetch 4 byte(s) @ 0x0000002a non-branch + 8 2: T3 ifetch 4 byte(s) @ 0x0000002a non-branch + 9 2: T3 + 10 3: T3 ifetch 4 byte(s) @ 0x0000002a non-branch +)DELIM"; + instrlist_t *ilist_unused = nullptr; + view_nomod_test_t view(drcontext, *ilist_unused, 0, 0, 0); + std::string res = run_serial_test_helper(view, entries); + // Make 64-bit match our 32-bit expect string. + res = std::regex_replace(res, std::regex("0x000000000000002a"), "0x0000002a"); + if (res != expect) { + std::cerr << "Output mismatch: got |" << res << "| expected |" << expect << "|\n"; + return false; + } + return true; +} + +bool +run_serial_chunk_test(void *drcontext) +{ + // We ensure headers are not omitted incorrectly, which they were + // in the first implementation of the reader skipping dup headers: + // i#/5538#issuecomment-1407235283 + const memref_tid_t t1 = 3; + const memref_tid_t t2 = 7; + std::vector> entries = { + { + { TRACE_TYPE_HEADER, 0, { 0x1 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_VERSION, { 3 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_FILETYPE, { 0 } }, + { TRACE_TYPE_THREAD, 0, { t1 } }, + { TRACE_TYPE_PID, 0, { t1 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CACHE_LINE_SIZE, { 64 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CHUNK_INSTR_COUNT, { 20 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_TIMESTAMP, { 1001 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CPU_ID, { 2 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_TIMESTAMP, { 1003 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CPU_ID, { 3 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + }, + { + { TRACE_TYPE_HEADER, 0, { 0x1 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_VERSION, { 3 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_FILETYPE, { 0 } }, + { TRACE_TYPE_THREAD, 0, { t2 } }, + { TRACE_TYPE_PID, 0, { t2 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CACHE_LINE_SIZE, { 64 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CHUNK_INSTR_COUNT, { 2 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_TIMESTAMP, { 1002 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CPU_ID, { 2 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_TIMESTAMP, { 1004 } }, + { TRACE_TYPE_MARKER, TRACE_MARKER_TYPE_CPU_ID, { 3 } }, + { TRACE_TYPE_INSTR, 4, { 42 } }, + } + }; + const char *expect = + R"DELIM( 1 0: T3 + 2 0: T3 + 3 0: T3 + 4 0: T3 +------------------------------------------------------------ + 5 0: T7 + 6 0: T7 + 7 0: T7 + 8 0: T7 +------------------------------------------------------------ + 9 0: T3 + 10 0: T3 + 11 1: T3 ifetch 4 byte(s) @ 0x0000002a non-branch + 12 2: T3 ifetch 4 byte(s) @ 0x0000002a non-branch +------------------------------------------------------------ + 13 2: T7 + 14 2: T7 + 15 3: T7 ifetch 4 byte(s) @ 0x0000002a non-branch + 16 4: T7 ifetch 4 byte(s) @ 0x0000002a non-branch +------------------------------------------------------------ + 17 4: T3 + 18 4: T3 + 19 5: T3 ifetch 4 byte(s) @ 0x0000002a non-branch +------------------------------------------------------------ + 20 5: T7 + 21 5: T7 + 22 6: T7 ifetch 4 byte(s) @ 0x0000002a non-branch +)DELIM"; + instrlist_t *ilist_unused = nullptr; + view_nomod_test_t view(drcontext, *ilist_unused, 0, 0, 0); + std::string res = run_serial_test_helper(view, entries); + // Make 64-bit match our 32-bit expect string. + res = std::regex_replace(res, std::regex("0x000000000000002a"), "0x0000002a"); + if (res != expect) { + std::cerr << "Output mismatch: got |" << res << "| expected |" << expect << "|\n"; + return false; + } + return true; +} + +bool +run_chunk_tests(void *drcontext) +{ + return run_single_thread_chunk_test(drcontext) && run_serial_chunk_test(drcontext); +} + } // namespace int main(int argc, const char *argv[]) { void *drcontext = dr_standalone_init(); - if (run_limit_tests(drcontext)) { + if (run_limit_tests(drcontext) && run_chunk_tests(drcontext)) { std::cerr << "view_test passed\n"; return 0; } diff --git a/clients/drcachesim/tools/view.cpp b/clients/drcachesim/tools/view.cpp index c12aeff7e0e..0e0ebad5493 100644 --- a/clients/drcachesim/tools/view.cpp +++ b/clients/drcachesim/tools/view.cpp @@ -187,21 +187,21 @@ view_t::parallel_shard_memref(void *shard_data, const memref_t &memref) // We delay printing until we know the tid. if (trace_version_ == -1) { trace_version_ = static_cast(memref.marker.marker_value); - version_record_ord_ = memstream->get_record_ordinal(); } else if (trace_version_ != static_cast(memref.marker.marker_value)) { error_string_ = std::string("Version mismatch across files"); return false; } + version_record_ord_ = memstream->get_record_ordinal(); return true; // Do not count toward -sim_refs yet b/c we don't have tid. case TRACE_MARKER_TYPE_FILETYPE: // We delay printing until we know the tid. if (filetype_ == -1) { filetype_ = static_cast(memref.marker.marker_value); - filetype_record_ord_ = memstream->get_record_ordinal(); } else if (filetype_ != static_cast(memref.marker.marker_value)) { error_string_ = std::string("Filetype mismatch across files"); return false; } + filetype_record_ord_ = memstream->get_record_ordinal(); if (TESTANY(OFFLINE_FILE_TYPE_ARCH_ALL, memref.marker.marker_value) && !TESTANY(build_target_arch_type(), memref.marker.marker_value)) { error_string_ = std::string("Architecture mismatch: trace recorded on ") + diff --git a/clients/drcachesim/tracer/raw2trace.cpp b/clients/drcachesim/tracer/raw2trace.cpp index b52eb735481..4e0fbe624d6 100644 --- a/clients/drcachesim/tracer/raw2trace.cpp +++ b/clients/drcachesim/tracer/raw2trace.cpp @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2016-2022 Google, Inc. All rights reserved. + * Copyright (c) 2016-2023 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -1179,6 +1179,8 @@ raw2trace_t::emit_new_chunk_header(raw2trace_thread_data_t *tdata) buf += trace_metadata_writer_t::write_marker( buf, TRACE_MARKER_TYPE_RECORD_ORDINAL, static_cast(tdata->cur_chunk_ref_count)); + log(2, "Chunk #" INT64_FORMAT_STRING " ord marker " INT64_FORMAT_STRING "\n", + tdata->chunk_count_, tdata->cur_chunk_ref_count); buf += trace_metadata_writer_t::write_timestamp(buf, (uintptr_t)tdata->last_timestamp_); buf += trace_metadata_writer_t::write_marker(buf, TRACE_MARKER_TYPE_CPU_ID, @@ -1188,8 +1190,8 @@ raw2trace_t::emit_new_chunk_header(raw2trace_thread_data_t *tdata) // need to go into the schedule file. if (!tdata->out_file->write((char *)buf_base, buf - buf_base)) return "Failed to write to output file"; - // These didn't go through tdata->memref_counter so we manually add. - tdata->cur_chunk_ref_count += (buf - buf_base) / sizeof(trace_entry_t); + // These didn't go through tdata->memref_counter but all 3 should be invisible + // so we don't want to increment cur_chunk_ref_count. return ""; }