/* ******************************************************************************
 * Copyright (c) 2010-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.
 */

/**
 ****************************************************************************
\page page_debug_memtrace DrCacheSim Offline Trace Debugging

This page contains tips for troubleshooting issues when using the
[DrCacheSim](@ref page_drcachesim) tool's
[offline memory address traces](@ref sec_drcachesim_offline).

# Thread Interleaving Granularity

Each thread has a 32K buffer and when it fills up, or when a system call is about to be executed, the buffer is written out to a per-thread file with a header attached which has a timestamp and cpu identifier.  Thus the thread interleaving and cpu scheduling can be reconstructed with a granularity of these buffers.

# Viewing binary trace files

## Viewing raw, pre-processed files

Each offline_entry_t struct is 8 bytes, so it's easy to view the records as 8-byte entries:

```
$ od -t x8 -A x drmemtrace.simple_app.09291.0000.dir/raw/drmemtrace.simple_app.09291.0000.raw  | tail
06ed10 200080080007c170 00007fd5a8a49700
06ed20 00007fd5a8a496a8 2000e0080007c187
06ed30 00007ffdee8cd0f8 00007ffdee8cd100
06ed40 00007ffdee8cd108 00007ffdee8cd110
06ed50 00007ffdee8cd118 200060080003c15b
06ed60 200040080003c164 00007ffdee8cd118
06ed70 2000a008000c1180 00007fd5a8a47e68
06ed80 20006008000c11b1 802e9f9036480c5d
06ed90 c100000000000000
06ed98
```

Of course, if the raw file is compressed, it must first be uncompressed.  Use `unlz4` for lz4-compressed raw files.

Cheat sheet:

- c040000000000004 is a header (offline version 4; type 0x40==OFFLINE_FILE_TYPE_ARCH_X86_64)
- c100000000000000 is a footer
- 8* is a timestamp
- 6* is a pid
- 4* is a tid
- 2* are PC entries
- a* is an arm iflush
- c2* is a marker
- c203* is a cpu id
- c20a* is the cache line size
- c212* is the page size
- c200* is kernel event; c201* is kernel xfer

## Viewing post-processed files

trace_entry_t is 12 bytes and is turned into memref_t by reader_t and its subclasses.
To view the 12-byte entries I use `od` or `hexdump` to split into 6 2-byte entries and then combine the final 4 into an 8-byte little-endian field using `awk`:

```
$ zcat drmemtrace.tool.drcacheoff.burst_malloc.211917.2237.dir/trace/drmemtrace.tool.drcacheoff.burst_malloc.211917.8542.trace.gz | od -A x -t x2 -w12 | awk '{printf "%s | %s %s %s%s%s%s\n", $1, $2, $3, $7, $6, $5, $4}' | head
000000 | 0019 0000 0000000000000001
00000c | 0016 0004 0000000000033bcd
000018 | 0018 0004 0000000000033bcd
000024 | 001c 0002 002eff22e15562f3
000030 | 001c 0003 0000000000000000
00003c | 000a 0003 0000555ec5db2e40
000048 | 0000 0004 00007ffed4b546ac
```

The printed columns are "offset | type size addr".
Type cheat sheet (from trace_type_t enum):
- 0x19 header
- 0x16 thread
- 0x18 pid
- 0x1c marker: 2=timestamp; 3=cpuid; 0xc=version; 9=filetype
- 0x0a instr (non-cti)
- 0x0e direct call
- 0x00 load
- 0x01 store
- 0x1d non-fetched instr
- 0x1a footer
- 0x2f instr encoding

type_is_instr: 0xa-0x10 + 0x1e

For .zip files, the data is split into the component files within the archive, in order.
Each component repeats enough information (the final timestamp + cpu from the prior
chunk, instruction encodings, etc.) to avoid having to examing prior chunks.
Extract each component file in turn to view the data.  For example:
```
$ unzip -p drmemtrace.app.194439.1516.dir/trace/drmemtrace.app.194439.7393.trace.zip chunk.0000 | hexdump -v -e '"%010_ax | " 6/2 "%04x " "\n"' | awk '{printf "%s %s %s %s %s%s%s%s\n", $1, $2, $3, $4, $8, $7, $6, $5}' | head -3
0000000000 | 0019 0000 0000000000000004
000000000c | 001c 000c 0000000000000004
0000000018 | 001c 0009 0000000000000040
```

## Viewing instruction disassembly

You can use the `view` analysis tool with `skip_refs` and `sim_refs` parameters to select a window, or for small traces you can re-post-process with `drraw2trace` with high verbosity (`-verbose 4` is good).

 ****************************************************************************
 */