Managing trace buffers

As mentioned above, you can use TraceEvent() to manage the instrumented kernel's buffers, but it's probably easier to run tracelogger in daemon mode and let it look after the buffers. Nevertheless, here's a summary of how to do it with TraceEvent():

Note:
In order to allocate or free the trace buffers, your application must have the PROCMGR_AID_TRACE ability enabled. For more information, see the entry procmgr_ability() in the QNX Neutrino C Library Reference.
  • To allocate the buffers, use the _NTO_TRACE_ALLOCBUFFER command, specifying the number of buffers and a pointer to a location where TraceEvent() can store the physical address of the beginning of the ring of allocated trace buffers:
    TraceEvent(_NTO_TRACE_ALLOCBUFFER, uint bufnum, void** paddr); 
    

    Allocated trace buffers can store 1024 simple trace events.

    Once you've allocated the buffers, you can use mmap() to map the buffers into your process's address space and get their virtual address. For example:

    paddr_t paddr;
    tracebuf_t *kbufs;
    
    ret = TraceEvent(_NTO_TRACE_ALLOCBUFFER, num_buffers, &paddr);
    if( ret == -1 )
    {
      // Handle the error.
    }
    
    kbufs = mmap( 0, num_buffers * sizeof(tracebuf_t), PROT_READ | PROT_WRITE,
                  MAP_PHYS | MAP_SHARED, NOFD, paddr );
    
    if( kbufs == MAP_FAILED )
    {
      // Handle the error.
    }
    

    Then you can use InterruptHookTrace() to register a handler for the _NTO_HOOK_TRACE synthetic interrupt that the instrumented kernel raises as each buffer becomes full.

  • To free the buffers, use the _NTO_TRACE_DEALLOCBUFFER command. It doesn't take any additional arguments:
    TraceEvent(_NTO_TRACE_DEALLOCBUFFER);
    

    All events stored in the trace buffers are lost.

  • To flush the buffer, regardless of the number of trace events it contains, use the _NTO_TRACE_FLUSHBUFFER command:
    TraceEvent(_NTO_TRACE_FLUSHBUFFER);
    
  • To get the number of simple trace events that are currently stored in the trace buffer, use the _NTO_TRACE_QUERYEVENTS command:
    num_events = TraceEvent(_NTO_TRACE_QUERYEVENTS);
    

For examples of some of these commands, see Data-capture program in the Sample Programs appendix.

Page updated: