SWTRACE is a software tracing mechanism that runs on Windows and Linux. swtrace is the PI command which provides command-line control of the SWTRACE facility.
Essentially SWTRACE manages trace buffers, one per processor, to which hooks (records) are written. SWTRACE allows for allocating and initializing the trace buffers, selecting which types of hooks are written, enabling and disabling writing of trace hooks to the buffer, writing trace hooks, and retrieving the contents of the trace buffers once tracing is completed.
The basic SWTRACE unit is the hook. Hooks are just records. Only hooks whose major code is enabled are written to the trace buffer. When written to disk, the contents of the trace buffers is written, in binary form, to an NRM2 file. The NRM2 file access API allows for querying trace file information and for reading trace hooks.
Properties of trace hooks:
Reserved Major Codes:
Steps required to use the SWTRACE facility are:
Allocates the SWTRACE buffer(s) and initializes the Trace facility. All major event codes are disabled.
|
Sets the additional metrics, in addition to cycles, to be used as additional timestamps in trace hooks. Cycles is always maintained as a metric and is metric number 1.
|
Sets the trace mode to be normal, continuous, or wrap-around.
|
Sets the name of raw trace file for continuous and wrap-around tracing modes (full file name).
|
Gets (reads) the name of raw trace file, as set by TraceSetName().
|
Sets size of per-cpu MTE buffer(s).
|
Specifies granularity of file writes with continuous and wraparound modes - whenever a section size bytes are written to a trace buffer, they are copied to the trace file.
|
Enables (turns on) the requested major event code. Only hooks whose major codes are enabled are written to the trace buffer.
|
Disables (turns off) the requested major event code. Only hooks whose major codes are enabled are written to the trace buffer.
|
Allows multiple metrics, if any, to be traced along with the specified major code.
|
Disallows multiple metrics, if any, from being traced along with the specified major code.
|
Enables (turns on) tracing. If the Trace facility is not currently initialized TraceOn will initialize it with a default buffer size of 3MB per processor.
|
Disables (turns off) tracing.
|
Temporarily suspends tracing. Current Trace facility controls (enabled major codes, trace buffer size, etc.) are not changed.
|
Resumes tracing if tracing is on and there are enabled major codes. Current Trace facility controls (enabled major codes, trace buffer size, etc.) are not changed.
|
Deallocates all trace buffers, disables all major codes and terminates the Trace facility. The Trace facility is no longer usable.
|
Discards the contents of all trace buffers. Tracing continues with an empty trace buffer.
|
Returns the state (enabled or disabled) of the given major event code.
|
Writes the contents of the trace buffer to file.
|
Returns the maximum number of additional metrics that can be traced/collected.
|
Returns a value indicating the number of times SWTRAACE has been turned on. The interval Id is also stored in the trace buffer.
|
TraceDisable disables (turns off) the requested major event code. Only hooks whose major codes are enabled are written to the trace buffer.
Returns whether or not tracing is currently on.
|
Returns whether or not tracing is currently active (not paused).
|
Returns whether or not trace mode is set to "continuos".
|
Returns whether or not trace mode is set to "wrap-around".
|
Sets the TPROF tick/sampling rate.
|
Sets the TPROF event and event count when profiling using events.
|
Writes a user hook to the trace buffer. Only hooks whose major codes are enabled are written to the trace buffer.
|
... UINT32 maj = 0x35, min = 0x99; // Major and minor codes UINT32 u1 = 99, u2 = 100; // 2 UINT32s int l1, l2; // 2 BUFFERs char *p1 = "This is buffer #1"; // Buffer 1 char *p2 = "This is buffer #2"; // Buffer 2 ... l1 = strlen(p1); l2 = strlen(p2); ... TraceHook(maj, min, 0, 0); // No data TraceHook(maj, min, 1, 0, u1); // 1 UINT32 TraceHook(maj, min, 2, 0, u1, u2); // 2 UINT32s TraceHook(maj, min, 0, 1, l1, p1); // 1 Buffer TraceHook(maj, min, 0, 2, l1, p1, l2, p2); // 2 Buffers TraceHook(maj, min, 1, 1, u1, l1, p1); // 1 UINT32 and 1 Buffer TraceHook(maj, min, 2, 2, u1, u2, l1, p1, l2, p2); // 2 UINT32s and 2 Buffers ...
Writes a user hook to the trace buffer. An address hook records a virtual address. Major and extended minor codes are specified by the caller.
|
This is a simple example of using the SWTRACE measurement facility. It is written for Windows but it can be easily modified to be compiled and run on Linux. You need to check return codes and handle errors appropriately!
#include <windows.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdarg.h> #include "perfutil.h" int main(int argc, char * argv[]) { char * str1 = "abcdefghijklmnopqrstuvwxyz"; char * str2 = "0123456789"; char * str3 = "*#*#*#*#*#*#*#*#*#*"; int len1 = strlen(str1); int len2 = strlen(str2); int len3 = strlen(str3); char msg[256]; int rc; // Reset trace facility to put in known state rc = TraceReset(); // Initialize trace facility. Take default on trace buffer size (3MB) rc = TraceInit(0); // Enable major code 119 (0x77). Can be anything. // Stay away from the reserved major codes. rc = TraceEnable(0x77); // Start tracing rc = TraceOn(); // Write hooks 77/8x: 0 - 3 DWORDs strcpy(msg, "** 77/80 - 77/84 0-4 DWORDs"); printf_so("%s\n", msg); TraceHook(0x77, 0xffff, 0, 1, strlen(msg), msg); // Set marker hook TraceHook(0x77, 0x80, 0, 0); TraceHook(0x77, 0x81, 1, 0, 0x80000001); TraceHook(0x77, 0x82, 2, 0, 0x80000001, 0x80000002); TraceHook(0x77, 0x83, 3, 0, 0x80000001, 0x80000002, 0x80000003); TraceHook(0x77, 0x84, 4, 0, 0x80000001, 0x80000002, 0x80000003, 0x80000004); // Write hooks 77/9x: 0 - 3 buffers strcpy(msg, "** 77/90 - 77/93 0-3 BUFFERs"); printf_so("%s\n", msg); TraceHook(0x77, 0xffff, 0, 1, strlen(msg), msg); // Set marker hook TraceHook(0x77, 0x90, 0, 0); TraceHook(0x77, 0x91, 0, 1, len1, str1); TraceHook(0x77, 0x92, 0, 2, len1, str1, len2, str2); TraceHook(0x77, 0x93, 0, 3, len1, str1, len2, str2, len3, str3); // Write B0/Ax: 0 - 3 DWORDs, 0 - 3 buffers strcpy(msg, "** 77/A0 - 77/AD 0-3 DWORDs, 0-3 BUFFERs"); printf_so("%s\n", msg); TraceHook(0x77, 0xffff, 0, 1, strlen(msg), msg); // Set marker hook // All buffers TraceHook(0x77, 0xA0, 0, 0); TraceHook(0x77, 0xA1, 0, 1, len1, str1); TraceHook(0x77, 0xA2, 0, 2, len1, str1, len2, str2); TraceHook(0x77, 0xA3, 0, 3, len1, str1, len2, str2, len3, str3); // All 32-bit values TraceHook(0x77, 0xA4, 1, 0, len1); TraceHook(0x77, 0xA5, 2, 0, len1, len2); TraceHook(0x77, 0xA6, 3, 0, len1, len2, len3); // Mixed TraceHook(0x77, 0xA7, 1, 1, 0x80000001, len1, str1); TraceHook(0x77, 0xA8, 1, 2, 0x80000001, len1, str1, len2, str2); TraceHook(0x77, 0xA9, 1, 3, 0x80000001, len1, str1, len2, str2, len3, str3); TraceHook(0x77, 0xAA, 2, 1, 0x80000001, 0x80000002, len1, str1); TraceHook(0x77, 0xAB, 3, 1, 0x80000001, 0x80000002, 0x80000003, len1, str1); TraceHook(0x77, 0xAC, 2, 2, 0x80000001, 0x80000002, len1, str1, len2, str2); TraceHook(0x77, 0xAD, 3, 3, 0x80000001, 0x80000002, 0x80000003, len1, str1, len2, str2, len3, str3); // Stop tracing rc = TraceOff(); // Write trace buffer to disk. remove("test.nrm2"); // Get rid of old trace file rc = TraceWriteBufferToFile("test.nrm2"); printf_so("\n** To post-process the trace file do the following:\n"); printf_so(" - \"post -r test.nrm2 -showx\" to convert binary trace file to ASCII.\n"); printf_so(" - \"write post.show\" to view the ASCII trace.\n"); // Deallocate trace buffers and reset trace facility TraceReset(); return(0); }