Using traceprinter and interpreting the output

Updated: October 26, 2022

The simplest way to turn the tracing data into a form that you can analyze is to pass the .kev file through traceprinter. For details, see its entry in the Utilities Reference.

Let's take a look at an example of the output from traceprinter. This is the output from Gathering all events from all classes in the Tutorials chapter.

The output starts with some information about how you ran the trace:

TRACEPRINTER version 1.02
TRACEPARSER LIBRARY version 1.02
 -- HEADER FILE INFORMATION -- 
       TRACE_FILE_NAME:: all_classes.kev
            TRACE_DATE:: Wed Jun 24 10:52:58 2009
       TRACE_VER_MAJOR:: 1
       TRACE_VER_MINOR:: 01
   TRACE_LITTLE_ENDIAN:: TRUE
        TRACE_ENCODING:: 16 byte events
       TRACE_BOOT_DATE:: Tue Jun 23 11:47:46 2009
  TRACE_CYCLES_PER_SEC:: 736629000
         TRACE_CPU_NUM:: 1
         TRACE_SYSNAME:: QNX
        TRACE_NODENAME:: localhost
     TRACE_SYS_RELEASE:: 6.4.1
     TRACE_SYS_VERSION:: 2009/05/20-17:35:56EDT
         TRACE_MACHINE:: x86pc
     TRACE_SYSPAGE_LEN:: 2264
TRACE_TRACELOGGER_ARGS:: tracelogger -d1 -n 3 -f all_classes.kev

The next section includes information about all the processes in existence when the trace started:

 -- KERNEL EVENTS -- 
t:0x4f81e320 CPU:00 CONTROL: BUFFER sequence = 33, num_events = 714
t:0x4f81e320 CPU:00 CONTROL :TIME msb:0x000037b0 lsb(offset):0x4f81e014
t:0x4f82017a CPU:00 PROCESS :PROCCREATE_NAME
                      ppid:0
                       pid:1
                      name:proc/boot/procnto-smp-instr
t:0x4f820f9a CPU:00 THREAD  :THCREATE      pid:1 tid:1
t:0x4f821358 CPU:00 THREAD  :THREADY       pid:1 tid:1 
t:0x4f821698 CPU:00 THREAD  :THCREATE      pid:1 tid:2
t:0x4f821787 CPU:00 THREAD  :THRECEIVE     pid:1 tid:2 
t:0x4f8219ca CPU:00 THREAD  :THCREATE      pid:1 tid:3
t:0x4f821ac6 CPU:00 THREAD  :THRECEIVE     pid:1 tid:3 
t:0x4f821c94 CPU:00 THREAD  :THCREATE      pid:1 tid:4
t:0x4f821d90 CPU:00 THREAD  :THRECEIVE     pid:1 tid:4 
t:0x4f821f6c CPU:00 THREAD  :THCREATE      pid:1 tid:5
t:0x4f82205b CPU:00 THREAD  :THRECEIVE     pid:1 tid:5 
t:0x4f8222aa CPU:00 THREAD  :THCREATE      pid:1 tid:7
t:0x4f822399 CPU:00 THREAD  :THRECEIVE     pid:1 tid:7 
t:0x4f8225bd CPU:00 THREAD  :THCREATE      pid:1 tid:8
t:0x4f8226ac CPU:00 THREAD  :THRECEIVE     pid:1 tid:8 
t:0x4f8228ca CPU:00 THREAD  :THCREATE      pid:1 tid:10
t:0x4f8229b9 CPU:00 THREAD  :THRECEIVE     pid:1 tid:10 
t:0x4f822b7d CPU:00 THREAD  :THCREATE      pid:1 tid:11
t:0x4f822c6c CPU:00 THREAD  :THRECEIVE     pid:1 tid:11 
t:0x4f822dd7 CPU:00 THREAD  :THCREATE      pid:1 tid:12
t:0x4f822ec6 CPU:00 THREAD  :THRECEIVE     pid:1 tid:12 
t:0x4f8230ac CPU:00 THREAD  :THCREATE      pid:1 tid:15
t:0x4f82319b CPU:00 THREAD  :THRECEIVE     pid:1 tid:15 
t:0x4f8233ca CPU:00 THREAD  :THCREATE      pid:1 tid:20
t:0x4f8234b9 CPU:00 THREAD  :THRECEIVE     pid:1 tid:20 
t:0x4f823ad0 CPU:00 PROCESS :PROCCREATE_NAME
                      ppid:1
                       pid:2
                      name:sbin/tinit
t:0x4f823f38 CPU:00 THREAD  :THCREATE      pid:2 tid:1
t:0x4f82402e CPU:00 THREAD  :THREPLY       pid:2 tid:1 
t:0x4f82447d CPU:00 PROCESS :PROCCREATE_NAME
                      ppid:2
                       pid:4099
                      name:proc/boot/pci-server
t:0x4f824957 CPU:00 THREAD  :THCREATE      pid:4099 tid:1
t:0x4f824a4d CPU:00 THREAD  :THRECEIVE     pid:4099 tid:1 
t:0x4f824ff8 CPU:00 PROCESS :PROCCREATE_NAME
                      ppid:2
                       pid:4100
                      name:proc/boot/slogger2

You can suppress this initial information by passing the _NTO_TRACE_STARTNOSTATE command to TraceEvent(), but you'll likely need the information (including process IDs and thread IDs) to make sense out of the actual trace data.

The sample above shows the creation and naming of the instrumented kernel procnto-smp-instr (process ID 1) and its threads (thread ID 1 is the idle thread), followed by tinit (process ID 2), pci-server, and slogger2. Some of these are the processes that were launched when you booted your system.

This continues for a while, culminating in the creation of the tracelogger process and our own program, all_classes (process ID 1511472):

t:0x4f852aa8 CPU:00 PROCESS :PROCCREATE_NAME
                      ppid:426015
                       pid:1507375
                      name:usr/sbin/tracelogger
t:0x4f853360 CPU:00 THREAD  :THCREATE      pid:1507375 tid:1
t:0x4f853579 CPU:00 THREAD  :THRECEIVE     pid:1507375 tid:1 
t:0x4f85392a CPU:00 THREAD  :THCREATE      pid:1507375 tid:2
t:0x4f853a19 CPU:00 THREAD  :THSIGWAITINFO pid:1507375 tid:2 
t:0x4f853d96 CPU:00 PROCESS :PROCCREATE_NAME
                      ppid:426022
                       pid:1511472
                      name:./all_classes
t:0x4f854048 CPU:00 THREAD  :THCREATE      pid:1511472 tid:1
t:0x4f854140 CPU:00 THREAD  :THRUNNING     pid:1511472 tid:1 

Next is the exit from our program's call to TraceEvent():

t:0x4f854910 CPU:00 KER_EXIT:TRACE_EVENT/01 ret_val:0x00000000 empty:0x00000000

Why doesn't the trace doesn't include the entry to TraceEvent()? Well, tracelogger didn't log anything until our program told it to—by calling TraceEvent()!

So far, so good, but now things get more complicated:

t:0x4f856aac CPU:00 KER_CALL:THREAD_DESTROY/47 tid:-1 status_p:0
t:0x4f857dca CPU:00 KER_EXIT:THREAD_DESTROY/47 ret_val:0x00000030 empty:0x00000000
t:0x4f8588d3 CPU:00 KER_CALL:THREAD_DESTROYALL/48 empty:0x00000000 empty:0x00000000
t:0x4f858ed7 CPU:00 THREAD  :THDESTROY     pid:1511472 tid:1
t:0x4f8598b9 CPU:00 THREAD  :THDEAD        pid:1511472 tid:1 
t:0x4f859c4c CPU:00 THREAD  :THRUNNING     pid:1 tid:1 

You can see that a thread is being destroyed, but which one? The tid of -1 refers to the current thread, but which process does it belong to? As mentioned earlier, most of the events don't indicate what caused the event to occur; you have to infer from a previous thread-running event. In this case, it's our own program (process ID 1511472) that's ending; it starts the tracing, and then exits. Thread 1 of procnto-smp-instr (the idle thread) runs.

The trace continues like this:

t:0x4f85c6e3 CPU:00 COMM    :SND_PULSE_EXE scoid:0x40000002 pid:1
t:0x4f85cecd CPU:00 THREAD  :THRUNNING     pid:1 tid:12 
t:0x4f85d5ad CPU:00 THREAD  :THREADY       pid:1 tid:1 
t:0x4f85e5b3 CPU:00 COMM    :REC_PULSE     scoid:0x40000002 pid:1
t:0x4f860ee2 CPU:00 KER_CALL:THREAD_CREATE/46 func_p:f0023170 arg_p:eff6e000
t:0x4f8624c7 CPU:00 THREAD  :THCREATE      pid:1511472 tid:1
t:0x4f8625ff CPU:00 THREAD  :THWAITTHREAD  pid:1 tid:12 
t:0x4f8627b4 CPU:00 THREAD  :THRUNNING     pid:1511472 tid:1 
t:0x4f8636fd CPU:00 THREAD  :THREADY       pid:1 tid:12 
t:0x4f865c34 CPU:00 KER_CALL:CONNECT_SERVER_INFO/41 pid:0 coid:0x00000000
t:0x4f866836 CPU:00 KER_EXIT:CONNECT_SERVER_INFO/41 coid:0x00000000 info->nd:0
t:0x4f86735e CPU:00 KER_CALL:TIMER_TIMEOUT/75 timeout_flags:0x00000050 ntime(sec):30
t:0x4f868445 CPU:00 KER_EXIT:TIMER_TIMEOUT/75 prev_timeout_flags:0x00000000 otime(sec):0
t:0x4f8697d3 CPU:00 INT_ENTR:0x00000000 (0)       IP:0xf008433e
t:0x4f86a276 CPU:00 INT_HANDLER_ENTR:0x00000000 (0)       PID:126997 IP:0x080b7334 AREA:0x0812a060
t:0x4f86afa7 CPU:00 INT_HANDLER_EXIT:0x00000000 (0) SIGEVENT:NONE
t:0x4f86b304 CPU:00 INT_HANDLER_ENTR:0x00000000 (0)       PID:1 IP:0xf0056570 AREA:0x00000000
t:0x4f86ca12 CPU:00 INT_HANDLER_EXIT:0x00000000 (0) SIGEVENT:NONE
t:0x4f86cff6 CPU:00 INT_EXIT:0x00000000 (0) inkernel:0x00000f01
t:0x4f86e276 CPU:00 KER_CALL:MSG_SENDV/11 coid:0x00000000 msg:"" (0x00040116)
t:0x4f86e756 CPU:00 COMM    :SND_MESSAGE   rcvid:0x0000004f pid:159762
t:0x4f86f84a CPU:00 THREAD  :THREPLY       pid:1511472 tid:1 
t:0x4f8705dd CPU:00 THREAD  :THREADY       pid:159762 tid:1 
t:0x4f8707d4 CPU:00 THREAD  :THRUNNING     pid:159762 tid:1 
t:0x4f870bff CPU:00 COMM    :REC_MESSAGE   rcvid:0x0000004f pid:159762
t:0x4f878b6c CPU:00 KER_CALL:MSG_REPLYV/15 rcvid:0x0000004f status:0x00000000
t:0x4f878f4b CPU:00 COMM    :REPLY_MESSAGE tid:1 pid:1511472
t:0x4f8798d2 CPU:00 THREAD  :THREADY       pid:1511472 tid:1 

The SND_PULSE_EXE event indicates that a SIGEV_PULSE was sent to the server connection ID 0x40000002 of procnto-smp-instr, but what is it, and who sent it? Thread 12 of the kernel receives it, and then surprisingly creates a new thread 1 in our process (ID 1511472), and starts chatting with it. What we're seeing here is the teardown of our process. It delivers a death pulse to the kernel, and then one of the kernel's threads receives the pulse and creates a thread in the process to clean up.

In the midst of this teardown, an interrupt occurs, its handler runs, and a message is sent to the process with ID 159762. By looking at the initial system information, we can determine that process ID 159762 is devc-pty.

Farther down in the trace is the actual death of our all_classes process:

t:0x4f8faa68 CPU:00 THREAD  :THRUNNING     pid:1 tid:20 
t:0x4f8fb09f CPU:00 COMM    :REC_PULSE     scoid:0x40000002 pid:1
t:0x4f8ff1a5 CPU:00 PROCESS :PROCDESTROY   ppid:426022 pid:1511472

As you can tell from a very short look at this trace, wading through a trace can be time-consuming, but can give you a great understanding of what exactly is happening in your system.

You can simplify your task by terminating any processes that you don't want to include in the trace, or by filtering the trace data.