Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i#6751 trace_entry_t: pretty printer #6771

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions clients/drcachesim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ add_exported_library(drmemtrace_opcode_mix STATIC tools/opcode_mix.cpp)
add_exported_library(drmemtrace_syscall_mix STATIC tools/syscall_mix.cpp)
edeiana marked this conversation as resolved.
Show resolved Hide resolved
edeiana marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To test the correctness of the printed values we compare them with the raw data using:
zcat path/to/trace.zip | od -A x -t x2 -w12 | awk '{printf "%s | %s %s %s%s%s%s\n", $1, $2, $3, $7, $6, $5, $4}'
as described here: https://dynamorio.org/page_debug_memtrace.html#autotoc_md136.

That page should be updated to point at this new tool, but please leave the od commands: as noted below some on-disk-format debugging needs to be at the real file level and not the trace_entry_t-stream level.

add_exported_library(drmemtrace_view STATIC tools/view.cpp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a unit test similar to clients/drcachesim/tests/view_test.cpp.

Also some test that verifies the output for some checked in raw trace (e.g. clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw) like clients/drcachesim/tests/offline-view.templatex.

Copy link
Contributor Author

@edeiana edeiana Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's in the TODO (see PR description).
However, before working on that, I'd like to come to a consensus on the pretty printed output of internal_record_view (<--- new tool name), as that is what I will test against.

Here's what it prints now (a short "representative" snippet, note that I OMITTED a few things because I wasn't sure I could share them here... the actual output has those values):

The internal_record_view tool is a pretty printer for trace_entry_t records.
The trace_entry_t internal record format is not a public interface and is subject to change without notice.
This tool is meant for debugging only, please do not rely on the details here.
<header, trace_version: 6 == frequent_timestamps>
<marker: version 6 frequent_timestamps>
<marker: filetype 0xe40 x86_64>
<thread, tid: 259013>
<pid, pid: 259013>
<marker: cache line size OMITTED>
<marker: chunk instruction count 10000000>
<marker: page size OMITTED>
<marker: timestamp 13352585958813850>
<marker: cpu id 3>
<encoding, num_encoding_bytes: 8, encoding_bytes: OMITTED>
<instr, length: 8, pc: 0x7f6fdd3ec360>
<encoding, num_encoding_bytes: 8, encoding_bytes: OMITTED>
<direct_call, length: 8, pc: 0x7f6fdd3ec368>
<write, memref_size: 8, memref_addr: 0x7fffa4ef43c8>
<encoding, num_encoding_bytes: 8, encoding_bytes: OMITTED>
<instr, length: 8, pc: 0x7f6fdd3ec370>
<write, memref_size: 8, memref_addr: 0x7fffa4ef43c0>
...

Is it acceptable? Do we need "--------" dividers? A header at the top? Do we want to number each line? Tabs?
I'm fine with how it looks now, just wondering.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's worth spending any more time on this (esp for things like dividers and ordinals that the main view tool already has): this PR is just adding an internal tool that honestly will likely be rarely used, as evidenced by it not being needed in the past. Even now there likely is no use case where you wouldn't also go run the final view tool afterward, since that's the real view seen by tools. E.g., for your own ISA transform and filtering, you can't just go by the output of this record view tool: you have to make sure it works at the memref_t layer, so you have to use the real view tool plus invariant checks anyway. This internal tool is only a limited-use debugging step pretty much always followed up by using the "real" pretty printer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more about when I've looked at the on-disk view with od: the most recent was debugging record_filter zip chunking support. There I had to look just before and after the 10M-instr chunk boundaries. Running od on one particular zipfile subfile at a time made this very easy. Looking at the output above with no ordinals, and having to pass in the whole trace file/dir at once: how would I focus on chunk boundaries? I might end up going back to od! I guess -skip_instructions is technically implemented for record_reader_t? But it's slow: the fast chunk skips are not implemented. Plus if the record_filter being debugged got the chunk boundary wrong I would have to go search for the chunk ord marker; if that's missing or wrong: would have to fall back to od.

Not sure there's an action item here: just an observation that this new tool is not enough to debug all on-disk issues as it abstracts away the file splits and I'm not sure it would have been useful the last time I did that. Adding ordinals would help -- but I don't know it's worth the effort. I would probably go run the regular view tool skipped to the chunk transition and take the closest timestamps and search for that in this tool's output or sthg. But I would again want to be at the real file layer instead of the trace_entry_t stream layer's abstracting away of the file divisions.

add_exported_library(drmemtrace_func_view STATIC tools/func_view.cpp)
add_exported_library(drmemtrace_internal_record_view STATIC tools/internal_record_view.cpp)
add_exported_library(drmemtrace_invariant_checker STATIC tools/invariant_checker.cpp)
add_exported_library(drmemtrace_schedule_stats STATIC tools/schedule_stats.cpp)
add_exported_library(drmemtrace_schedule_file STATIC common/schedule_file.cpp)
Expand All @@ -174,6 +175,7 @@ target_link_libraries(drmemtrace_invariant_checker drdecode drmemtrace_schedule_

configure_DynamoRIO_standalone(drmemtrace_opcode_mix)
configure_DynamoRIO_standalone(drmemtrace_view)
configure_DynamoRIO_standalone(drmemtrace_internal_record_view)
configure_DynamoRIO_standalone(drmemtrace_invariant_checker)

# We combine the cache and TLB simulators as they share code already.
Expand Down Expand Up @@ -286,7 +288,7 @@ configure_DynamoRIO_standalone(drmemtrace_launcher)
target_link_libraries(drmemtrace_launcher drmemtrace_simulator drmemtrace_reuse_distance
drmemtrace_histogram drmemtrace_reuse_time drmemtrace_basic_counts
drmemtrace_opcode_mix drmemtrace_syscall_mix drmemtrace_view drmemtrace_func_view
drmemtrace_raw2trace directory_iterator drmemtrace_invariant_checker
drmemtrace_internal_record_view drmemtrace_raw2trace directory_iterator drmemtrace_invariant_checker
drmemtrace_schedule_stats drmemtrace_record_filter drmemtrace_mutex_dbg_owned)
if (UNIX)
target_link_libraries(drmemtrace_launcher dl)
Expand Down Expand Up @@ -369,6 +371,7 @@ install_client_nonDR_header(drmemtrace simulator/cache_simulator_create.h)
install_client_nonDR_header(drmemtrace simulator/tlb_simulator_create.h)
install_client_nonDR_header(drmemtrace tools/view_create.h)
install_client_nonDR_header(drmemtrace tools/func_view_create.h)
install_client_nonDR_header(drmemtrace tools/internal_record_view_create.h)
install_client_nonDR_header(drmemtrace tools/filter/record_filter_create.h)
install_client_nonDR_header(drmemtrace tools/filter/record_filter.h)
# TODO i#6412: Create a separate directory for non-tracer headers so that
Expand Down Expand Up @@ -596,6 +599,7 @@ restore_nonclient_flags(drmemtrace_opcode_mix)
restore_nonclient_flags(drmemtrace_syscall_mix)
restore_nonclient_flags(drmemtrace_view)
restore_nonclient_flags(drmemtrace_func_view)
restore_nonclient_flags(drmemtrace_internal_record_view)
restore_nonclient_flags(drmemtrace_record_filter)
restore_nonclient_flags(drmemtrace_analyzer)
restore_nonclient_flags(drmemtrace_invariant_checker)
Expand Down Expand Up @@ -669,6 +673,7 @@ add_win32_flags(drmemtrace_opcode_mix)
add_win32_flags(drmemtrace_syscall_mix)
add_win32_flags(drmemtrace_view)
add_win32_flags(drmemtrace_func_view)
add_win32_flags(drmemtrace_internal_record_view)
add_win32_flags(drmemtrace_record_filter)
add_win32_flags(drmemtrace_analyzer)
add_win32_flags(drmemtrace_invariant_checker)
Expand Down Expand Up @@ -861,8 +866,9 @@ if (BUILD_TESTS)
drmemtrace_raw2trace drmemtrace_simulator drmemtrace_reuse_distance
drmemtrace_histogram drmemtrace_reuse_time drmemtrace_basic_counts
drmemtrace_opcode_mix drmemtrace_syscall_mix drmemtrace_view drmemtrace_func_view
drmemtrace_raw2trace directory_iterator drmemtrace_invariant_checker
drmemtrace_schedule_stats drmemtrace_analyzer drmemtrace_record_filter)
drmemtrace_internal_record_view drmemtrace_raw2trace directory_iterator
drmemtrace_invariant_checker drmemtrace_schedule_stats drmemtrace_analyzer
drmemtrace_record_filter)
if (UNIX)
target_link_libraries(tool.drcachesim.core_sharded dl)
endif ()
Expand Down
4 changes: 4 additions & 0 deletions clients/drcachesim/analyzer_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "tools/reuse_distance_create.h"
#include "tools/reuse_time_create.h"
#include "tools/view_create.h"
#include "tools/internal_record_view_create.h"
#include "tools/loader/external_config_file.h"
#include "tools/loader/external_tool_creator.h"
#include "tools/filter/record_filter_create.h"
Expand Down Expand Up @@ -341,6 +342,9 @@ record_analyzer_multi_t::create_analysis_tool_from_options(const std::string &to
op_trim_after_timestamp.get_value(), op_encodings2regdeps.get_value(),
op_filter_func_ids.get_value(), op_modify_marker_value.get_value(),
op_verbose.get_value());
} else if (tool == INTERNAL_RECORD_VIEW) {
return internal_record_view_tool_create(op_skip_refs.get_value(),
op_sim_refs.get_value());
}
ERRMSG("Usage error: unsupported record analyzer type \"%s\". Only " RECORD_FILTER
" is supported.\n",
Expand Down
1 change: 1 addition & 0 deletions clients/drcachesim/common/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#define SYSCALL_MIX "syscall_mix"
#define VIEW "view"
#define FUNC_VIEW "func_view"
#define INTERNAL_RECORD_VIEW "internal_record_view"
#define INVARIANT_CHECKER "invariant_checker"
#define SCHEDULE_STATS "schedule_stats"
#define RECORD_FILTER "record_filter"
Expand Down
115 changes: 115 additions & 0 deletions clients/drcachesim/common/trace_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
namespace dynamorio {
namespace drmemtrace {

/* Keep synched with trace_type_t enum in trace_entry.h.
*/
const char *const trace_type_names[] = {
"read",
"write",
Expand Down Expand Up @@ -88,5 +90,118 @@ const char *const trace_type_names[] = {
"untaken_jump",
};

/* Keep synched with trace_version_t enum in trace_entry.h.
*/
const char *const trace_version_names[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since for trace version the enum value matters, let's add the corresponding enum value too to these strings.

Copy link
Contributor Author

@edeiana edeiana Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in, for example: "trace_entry_version_no_kernel_pc" -> "trace_entry_version_no_kernel_pc_2" ? (2 is the enum value)
Although I'm not quite understanding why the enum value matters in the string representation of TRACE_ENTRY_VERSION_ enum. They have different names after all.
Unless you're referring to trace_version_names[0] (and [1]), which are "unknown"? If so, you mean I should just differentiate those 2?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I'm not quite understanding why the enum value matters in the string representation of TRACE_ENTRY_VERSION_ enum

I'm considering a use case where the user wants to know whether their trace has a version more recent than some other version (some of our tools want a minimum trace version). Having the enum value would be easier, but I guess the user can always look up the enum value themselves using just the enum string. So it's fine either way I guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we print the enum value along side the string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, I didn't understand that the enum value had a meaning (larger == more recent trace version?).
I like @xdje42 suggestion. Now printing it when we print the trace_entry_t record (but not including it in trace_version_names[]).

"<unknown>", "<unknown>", "no_kernel_pc", "kernel_pc",
"encodings", "branch_info", "frequent_timestamps",
};

/* Keep synched with trace_marker_type_t enum in trace_entry.h.
*/
const char *const trace_marker_names[] = {
edeiana marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we want the strings at clients/drcachesim/tools/view.cpp to be replaced by these? Maybe. Add a TODO at view.cpp.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would change all the output recorded in the docs here and in the sample traces repo and in internal docs so would not be taken lightly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reverse might be an easier thing to do. See all the comments about sharing code: eliminate this array and use the existing public pretty-printer's marker printing code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@edeiana edeiana Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reverse might be an easier thing to do. See all the comments about sharing code: eliminate this array and use the existing public pretty-printer's marker printing code.

I modified this array to be consistent with view.cpp (which, now, view.cpp also uses).
I think we still want a simple string representation of a marker type, we don't want to get rid of this array.
What view.cpp does is merging together the string representation of a marker type + a marker value.

Now, trace_marker_names[] contains the string representation of marker types only, and it's used in the new trace_marker_type_value_as_string(), which returns a string representation of marker type + value (and it's, for the most part, in common between view.cpp and record_view.cpp).

"marker: kernel xfer", /* TRACE_MARKER_TYPE_KERNEL_EVENT */
"marker: syscall xfer", /* TRACE_MARKER_TYPE_KERNEL_XFER */
"marker: timestamp", /* TRACE_MARKER_TYPE_TIMESTAMP */
"marker: cpu id", /* TRACE_MARKER_TYPE_CPU_ID */
"marker: function", /* TRACE_MARKER_TYPE_FUNC_ID */
"marker: function return address", /* TRACE_MARKER_TYPE_FUNC_RETADDR */
"marker: function argument", /* TRACE_MARKER_TYPE_FUNC_ARG */
"marker: function return value", /* TRACE_MARKER_TYPE_FUNC_RETVAL */
"marker: split value", /* TRACE_MARKER_TYPE_SPLIT_VALUE */
"marker: filetype", /* TRACE_MARKER_TYPE_FILETYPE */
"marker: cache line size", /* TRACE_MARKER_TYPE_CACHE_LINE_SIZE */
"marker: instruction count", /* TRACE_MARKER_TYPE_INSTRUCTION_COUNT */
"marker: version", /* TRACE_MARKER_TYPE_VERSION */
"marker: rseq abort", /* TRACE_MARKER_TYPE_RSEQ_ABORT */
"marker: window", /* TRACE_MARKER_TYPE_WINDOW_ID */
"marker: physical address", /* TRACE_MARKER_TYPE_PHYSICAL_ADDRESS */
"marker: physical address not available", /* TRACE_MARKER_TYPE_PHYSICAL_ADDRESS_NOT_
AVAILABLE */
"marker: virtual address", /* TRACE_MARKER_TYPE_VIRTUAL_ADDRESS */
"marker: page size", /* TRACE_MARKER_TYPE_PAGE_SIZE */
"marker: system call idx", /* TRACE_MARKER_TYPE_SYSCALL_IDX */
"marker: chunk instruction count", /* TRACE_MARKER_TYPE_CHUNK_INSTR_COUNT */
"marker: chunk footer", /* TRACE_MARKER_TYPE_CHUNK_FOOTER */
"marker: record ordinal", /* TRACE_MARKER_TYPE_RECORD_ORDINAL */
"marker: filter endpoint", /* TRACE_MARKER_TYPE_FILTER_ENDPOINT */
"marker: rseq entry", /* TRACE_MARKER_TYPE_RSEQ_ENTRY */
"marker: system call", /* TRACE_MARKER_TYPE_SYSCALL */
"marker: maybe-blocking system call", /* TRACE_MARKER_TYPE_MAYBE_BLOCKING_SYSCALL */
"marker: trace start for system call", /* TRACE_MARKER_TYPE_SYSCALL_TRACE_START */
"marker: trace end for system call", /* TRACE_MARKER_TYPE_SYSCALL_TRACE_END */
"marker: indirect branch target", /* TRACE_MARKER_TYPE_BRANCH_TARGET */
"marker: system call failed", /* TRACE_MARKER_TYPE_SYSCALL_FAILED */
"marker: direct switch to thread", /* TRACE_MARKER_TYPE_DIRECT_THREAD_SWITCH */
"marker: wait for another core", /* TRACE_MARKER_TYPE_CORE_WAIT */
"marker: core is idle", /* TRACE_MARKER_TYPE_CORE_IDLE */
"marker: trace start for context switch", /* TRACE_MARKER_TYPE_CONTEXT_SWITCH_START */
"marker: trace end for context switch", /* TRACE_MARKER_TYPE_CONTEXT_SWITCH_END */
"marker: vector length", /* TRACE_MARKER_TYPE_VECTOR_LENGTH */
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: unused",
"marker: reserved end", /* TRACE_MARKER_TYPE_RESERVED_END */
};
edeiana marked this conversation as resolved.
Show resolved Hide resolved

} // namespace drmemtrace
} // namespace dynamorio
118 changes: 118 additions & 0 deletions clients/drcachesim/common/trace_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#define _TRACE_ENTRY_H_ 1

#include <memory>
#include <sstream>
#include <string>
#include <stddef.h>
#include <stdint.h>

Expand Down Expand Up @@ -720,6 +722,8 @@ enum class func_trace_t : uint64_t { // VS2019 won't infer 64-bit with "enum {".
};

extern const char *const trace_type_names[];
extern const char *const trace_version_names[];
extern const char *const trace_marker_names[];

/**
* Returns whether the type represents an instruction fetch.
Expand Down Expand Up @@ -1077,6 +1081,120 @@ trace_arch_string(offline_file_type_t type)
return "unspecified";
}

/* Returns a string representation of marker type and corresponding marker value (if any)
* together.
*/
static inline std::string
trace_marker_type_value_as_string(trace_marker_type_t marker_type, uintptr_t marker_value)
{
std::stringstream ss;
const char *marker_name = trace_marker_names[marker_type];
switch (marker_type) {
/* Handle all the cases where marker_value doesn't matter.
*/
case TRACE_MARKER_TYPE_FILTER_ENDPOINT:
case TRACE_MARKER_TYPE_MAYBE_BLOCKING_SYSCALL:
case TRACE_MARKER_TYPE_CORE_WAIT:
case TRACE_MARKER_TYPE_CORE_IDLE: ss << "<" << marker_name << ">\n"; break;
/* Handle all the cases where we simply print <marker_type marker_value>.
*/
case TRACE_MARKER_TYPE_TIMESTAMP:
case TRACE_MARKER_TYPE_CPU_ID:
case TRACE_MARKER_TYPE_INSTRUCTION_COUNT:
case TRACE_MARKER_TYPE_CACHE_LINE_SIZE:
case TRACE_MARKER_TYPE_PAGE_SIZE:
case TRACE_MARKER_TYPE_CHUNK_INSTR_COUNT:
case TRACE_MARKER_TYPE_SYSCALL:
case TRACE_MARKER_TYPE_DIRECT_THREAD_SWITCH:
case TRACE_MARKER_TYPE_WINDOW_ID:
case TRACE_MARKER_TYPE_SYSCALL_IDX:
ss << "<" << marker_name << " " << marker_value << ">\n";
break;
/* Handle all the cases where we simply print <marker_type 0xmarker_value>.
*/
case TRACE_MARKER_TYPE_FUNC_RETADDR:
case TRACE_MARKER_TYPE_FUNC_ARG:
case TRACE_MARKER_TYPE_FUNC_RETVAL:
case TRACE_MARKER_TYPE_RECORD_ORDINAL:
case TRACE_MARKER_TYPE_SPLIT_VALUE:
case TRACE_MARKER_TYPE_BRANCH_TARGET:
ss << "<" << marker_name << " 0x" << std::hex << marker_value << std::dec
<< ">\n";
break;
/* Handle all remaining cases where we want to print a more informative output.
*/
case TRACE_MARKER_TYPE_SYSCALL_TRACE_START:
case TRACE_MARKER_TYPE_SYSCALL_TRACE_END:
ss << "<" << marker_name << " number " << marker_value << ">\n";
break;
case TRACE_MARKER_TYPE_CONTEXT_SWITCH_START:
case TRACE_MARKER_TYPE_CONTEXT_SWITCH_END:
ss << "<" << marker_name << " type " << marker_value << ">\n";
break;
/* We don't have a way to know the trace version here. This might be an offset,
* but we don't make any distinction.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate as a new reader will have no idea what you mean: I only know b/c I remember a legacy version having offset instead of abs addr.

*/
case TRACE_MARKER_TYPE_KERNEL_XFER:
case TRACE_MARKER_TYPE_KERNEL_EVENT:
ss << "<" << marker_name << " from 0x" << std::hex << marker_value << std::dec
<< ">\n";
break;
case TRACE_MARKER_TYPE_VERSION:
ss << "<" << marker_name << " " << static_cast<int>(marker_value) << " "
<< trace_version_names[marker_value] << ">\n";
break;
case TRACE_MARKER_TYPE_FILETYPE:
ss << "<" << marker_name << " 0x" << std::hex
<< static_cast<intptr_t>(marker_value) << std::dec << " "
<< trace_arch_string((offline_file_type_t)marker_value) << ">\n";
break;
case TRACE_MARKER_TYPE_RSEQ_ABORT:
ss << "<" << marker_name << " from 0x" << std::hex << marker_value << std::dec
<< " to handler>\n";
break;
case TRACE_MARKER_TYPE_RSEQ_ENTRY:
ss << "<" << marker_name << " with end at 0x" << std::hex << marker_value
<< std::dec << ">\n";
break;
case TRACE_MARKER_TYPE_CHUNK_FOOTER:
ss << "<" << marker_name << " #" << marker_value << ">\n";
break;
case TRACE_MARKER_TYPE_PHYSICAL_ADDRESS:
ss << "<" << marker_name << " for following virtual: 0x" << std::hex
<< marker_value << std::dec << ">\n";
break;
case TRACE_MARKER_TYPE_VIRTUAL_ADDRESS:
ss << "<" << marker_name << " for prior physical: 0x" << std::hex << marker_value
<< std::dec << ">\n";
break;
case TRACE_MARKER_TYPE_PHYSICAL_ADDRESS_NOT_AVAILABLE:
ss << "<" << marker_name << " for 0x" << std::hex << marker_value << std::dec
<< ">\n";
break;
case TRACE_MARKER_TYPE_FUNC_ID:
if (marker_value >=
static_cast<intptr_t>(func_trace_t::TRACE_FUNC_ID_SYSCALL_BASE)) {
ss << "<" << marker_name << "==syscall #"
<< (marker_value -
static_cast<uintptr_t>(func_trace_t::TRACE_FUNC_ID_SYSCALL_BASE))
<< ">\n";
} else {
ss << "<" << marker_name << " #" << marker_value << ">\n";
}
break;
case TRACE_MARKER_TYPE_SYSCALL_FAILED:
ss << "<" << marker_name << ": " << marker_value << ">\n";
break;
case TRACE_MARKER_TYPE_VECTOR_LENGTH:
ss << "<" << marker_name << " " << marker_value << " bytes>\n";
break;
default:
ss << "<marker: type " << marker_type << "; value " << marker_value << ">\n";
break;
}
return ss.str();
}

/* We have non-client targets including this header that do not include API
* headers defining IF_X86_ELSE, etc. Those don't need this function so we
* simply exclude them.
Expand Down
3 changes: 2 additions & 1 deletion clients/drcachesim/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ _tmain(int argc, const TCHAR *targv[])
FATAL_ERROR("invalid -outdir %s", op_outdir.get_value().c_str());
}
} else {
if (op_tool.get_value() == RECORD_FILTER) {
if (op_tool.get_value() == RECORD_FILTER ||
op_tool.get_value() == INTERNAL_RECORD_VIEW) {
record_analyzer = new record_analyzer_multi_t;
if (!*record_analyzer) {
std::string error_string_ = record_analyzer->get_error_string();
Expand Down
Loading
Loading