Snapshot Event logging manager for logging blocks of memory, strings in memory
and names of dynamically created objects
The following configuration script shows the simplest way
to configure an application to use log snapshot events:
The second line causes the LogSnapshot .xs script to run during the configuration
process when building the application. The script detects that a logger has
not been assigned to the LogSnapshot module, so it checks if
a logger has been configured for either the Main module or the Defaults module.
Since there is a logger for the Main module, the script configures the LogSnapshot
module to log events to the same logger instance.
In some situations, the amount of data logged by the LogSnapshot
APIs may exceed the ability of the target to move the event data out of the
Main module's logger's circular buffer and up to the host. One way of
ensuring that the other events that are logged are not dropped due to this
type of situation is to configure the LogSnapshot module to write events
to a separate lower priority logger.
The following is an example of the configuration script used
to configure the default mask for modules to have Analysis events such as
the UIASnapshot events always on.
struct LogSnapshot_EventRec |
|
The target representation of a recorded event
typedef struct LogSnapshot_EventRec {
// time event was written
Bits32 serial;
// serial number of event
// target encoding of an Event
Int snapshotId;
IArg fmt;
Ptr pData;
UInt16 lengthInMAUs;
// arguments passed via Log_write/print
} LogSnapshot_EventRec;
DETAILS
This structure defines how events are recorded on the target.
config LogSnapshot_injectIntoTraceFxn // module-wide |
|
Callback function that handles injection of info such as serial numbers
of sync point events, context change events or snapshot events into a
hardware trace stream. (e.g. GEM CPU Trace, System Trace, etc.)
DETAILS
Users can provide their own custom injectIntoTraceFxn to log whatever
additional information they wish to record when the hook function is called.
For example, event serial numbers can be injected into the CPU
trace stream and / or STM trace stream in order to enable correlation
of information logged in these streams with UIA software events.
EXAMPLES
Example 1: Correlating events with C64X+ and C66 CPU Trace
The following is an example of the configuration script used
to inject serial numbers of sync point events or context change events or
snapshot Ids associated with snapshot events.
Note that the GemTraceSync module's .xs script takes care of finding
all modules that implement the IUIATraceSyncClient and assigning the
GemTraceSync_injectIntoTrace function pointer to those modules'
injectIntoTraceFxn config option.
//The following 3 modules all implement the IUIATraceSyncClient interface
var LogSnapshot = xdc.useModule('ti.uia.runtime.LogSnapshot');
var LogCtxChg = xdc.useModule('ti.uia.runtime.LogCtxChg');
var LogSync = xdc.useModule('ti.uia.runtime.LogSync');
//For C66 devices, replace the following line with
// var GemTraceSync = xdc.useModule('ti.uia.family.c66.GemTraceSync');
var GemTraceSync = xdc.useModule('ti.uia.family.c64p.GemTraceSync');
Example 2: How to create a custom hook function
and assign it to the LogSnapshot module
The following is an example of a 'C' code program that implements
a hook function that prints out the snapshot ID that is passed in
as the serialNumber
#include <xdc/std.h>
#include <xdc/runtime/Gate.h>
#include <ti/uia/runtime/IUIATraceSyncProvider.h>
#include <ti/uia/runtime/LogSnapshot.h>
#include <stdio.h>
#include <string.h>
extern Void myHookFxn(UInt32 serialNumber, IUIATraceSyncProvider_ContextType ctxType);
Void Test();
char name[32]={"Bob"};
UInt32 newAppId = 0;
Void myHookFxn(UInt32 serialNumber, IUIATraceSyncProvider_ContextType ctxType){
volatile UInt32 syncWord;
IArg key = Gate_enterSystem();
printf("newAppId written with serialNumber %d and ctxType = %d\n",serialNumber,ctxType);
Gate_leaveSystem(key);
}
Void Test(){
// note that the hook function is triggered by calling LogSnapshot_getSnapshotId()
// since that is where the unique snapshot ID that is passed to the
// hook function is generated.
Int snapshotId = LogSnapshot_getSnapshotId();
LogSnapshot_writeString(snapshotId,"User-defined name=%s.",name, strlen(name));
}
Void main(){
while(TRUE){ Test(); }
}
In order to have the above user-defined function called by the LogSnapshot
module whenever it writes an event, the following configuration script
is needed:
var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
var LogSnapshot = xdc.useModule('ti.uia.runtime.LogSnapshot');
var IUIATraceSyncClient = xdc.useModule('ti.uia.runtime.IUIATraceSyncClient');
LogSnapshot.injectIntoTraceFxn = $externFxn('myHookFxn');
SEE
config LogSnapshot_isTimestampEnabled // module-wide |
|
used to enable or disable logging the 64b local CPU timestamp
at the start of each event
extern const Bool LogSnapshot_isTimestampEnabled;
config LogSnapshot_loggerObj // module-wide |
|
handle of the logger that is to be used to log snapshot events
extern const Ptr LogSnapshot_loggerObj;
config LogSnapshot_maxLengthInMAUs // module-wide |
|
Maximum number of MAUs (miniumum addressable units, e.g. bytes)
supported by LogSnapshot events
extern const Int LogSnapshot_maxLengthInMAUs;
DETAILS
Attempting to write more than the maximum length results in the
multiple events being logged. The maxLengthInMAUs must be
lower than the size of the buffer that the events are being logged to.
Must be less than 1400 in order to support streaming of event
data over UDP.
LogSnapshot_doPrint() // module-wide |
|
Render an event as text via System_printf
ARGUMENTS
evRec
a nonNULL pointer to an initialized
LogSnapshot_EventRecstructure to be formated via
System_printf`.
DETAILS
This method is not currently implemented.
LogSnapshot_getSnapshotId() // module-wide |
|
returns a unique ID to use to group a set of snapshot event logs together
UInt32 LogSnapshot_getSnapshotId();
DETAILS
Allows tooling to treat a set of consecutive event logs as a unit and
display all of the relevent data together as a set
EXAMPLE
The following C code shows how to log two snapshot events that capture
the target state of two different data structures, using a common unique
non-zero snapshot ID provided by the getSnapshotId to inform the host-side
tooling that the events represent the target state at the same point in time
#include <ti/uia/runtime/LogSnapshot.h>
...
MyStruct1 myStruct1;
MyStruct2 myStruct2;
UInt32 snapshotId;
...
snapshotId = LogSnapshot_getSnapshotId();
LogSnapshot_writeMemoryBlock(snapshotId,"myStruct1 ptr=0x%x, numBytes=%d",(UInt32)&myStruct1,sizeof(MyStruct1));
LogSnapshot_writeMemoryBlock(snapshotId,"myStruct2 ptr=0x%x, numBytes=%d",(UInt32)&myStruct2,sizeof(MyStruct2));
...
RETURN
a unique non-zero snapshot ID to pass in as a parameter to the
LogSnapshot APIs
LogSnapshot_putMemoryRange() // module-wide |
|
Unconditionally put the specified Types event.
Supports both writeMemoryRange and writeString
macro Void LogSnapshot_putMemoryRange(
Types_Event evt,
Types_ModuleId mid,
IArg fileName,
IArg lineNum,
UInt32 snapshotID,
IArg fmt,
IArg startAdrs,
IArg lengthInMAUs);
ARGUMENTS
evt
the Types event to put into the log
mid
the module ID of the caller
snapshotId
unique ID that binds together a series of events used to
log a large memory range. Upper 16b hold the ID Tag (0 for UIA)
fileName
the name of the file that the event was logged from
lineNum
the line number that the event was logged from
fmt
a user-specified print format string
startAdrs
the start address of the memory range to log
lengthInMAUs
the number of minimum addressable units (e.g. bytes) to log
DETAILS
This method unconditionally puts the specified memoryRange
Types.Event
evt into the log. This type of event is created either implicitly
(and passed to an
ISnapshotLogger implementation) or explicitly
via
Types.makeEvent().
RETURN
value to use as snapshotId parameter for subsequent events
LogSnapshot_writeMemoryBlock() // module-wide |
|
Generate a LogSnapshot event for a block of memory
macro Void LogSnapshot_writeMemoryBlock(UInt32 snapshotID, IArg fmt, Ptr pMemoryRange, UInt16 lengthInMAUs);
ARGUMENTS
snapshotID
ID used to identify snapshot events taken at the same
time. Set to 0 for first in series, set rest to return
value of LogSnapshot API. see getSnapshotId()
fmt
a constant string that provides a user-readable description
of what information the event is capturing
pMemoryRange
the start address of the range of memory
lengthInMAUs
the number of MAUs of data payload for the
multi-event data record
EXAMPLES
Example: The following C code shows how to log a snapshot event to
capture a block of memory.
#include <ti/uia/runtime/LogSnapshot.h>
...
UInt32* pIntArray = (UInt32 *)malloc(sizeof(UInt32) * 200);
...
LogSnapshot_writeMemoryBlock(0,"pIntArray ptr=0x%x, numBytes=%d",(UInt32)pIntArray,200);
...
The following text will be displayed for the event, if it was logged
from file demo.c at line 1234 and all 200 bytes were logged in the
same event.
Memory Snapshot at [demo.c:1234] [snapshotID=0,adrs=0x80002000,
numMAUsDataInEvent=200,numMAUsDataInRecord=200] ptr=0x80002000, numBytes=200
If the 200 bytes were spread across multiple events,
the numMAUsDataInRecord would indicate how many bytes were in the
memory block, and numMAUsDataInEvent would indicate how many bytes
were stored in that particular event.
LogSnapshot_writeMemoryBlockWithIdTag() // module-wide |
|
Generate a LogSnapshot event for a block of memory
macro Void LogSnapshot_writeMemoryBlockWithIdTag(UInt16 idTag, UInt32 snapshotID, IArg fmt, Ptr pMemoryRange, UInt16 lengthInMAUs);
ARGUMENTS
idTag
ID used to identify who logged the event. Set to 0 for a
standard UIA event. Can be used to filter snapshot events on host.
snapshotID
ID used to identify snapshot events taken at the same
time. Set to 0 for first in series, set rest to return
value of LogSnapshot API. see getSnapshotId()
fmt
a constant string that provides a user-readable description
of what information the event is capturing
pMemoryRange
the start address of the range of memory
lengthInMAUs
the number of MAUs of data payload for the
multi-event data record
EXAMPLES
Example: The following C code shows how to log a snapshot event to
capture a block of memory.
#include <ti/uia/runtime/LogSnapshot.h>
...
UInt32* pIntArray = (UInt32 *)malloc(sizeof(UInt32) * 200);
...
UInt16 myCustomIdTag = 1;
LogSnapshot_writeMemoryBlockWithIdTag(myCustomIdTag,0,"pIntArray ptr=0x%x, numBytes=%d",(UInt32)pIntArray,200);
...
The following text will be displayed for the event, if it was logged
from file demo.c at line 1234 and all 200 bytes were logged in the
same event.
Memory Snapshot at [demo.c:1234] [snapshotID=0,adrs=0x80002000,
numMAUsDataInEvent=200,numMAUsDataInRecord=200] ptr=0x80002000, numBytes=200
If the 200 bytes were spread across multiple events,
the numMAUsDataInRecord would indicate how many bytes were in the
memory block, and numMAUsDataInEvent would indicate how many bytes
were stored in that particular event.
LogSnapshot_writeNameOfReference() // module-wide |
|
Used to log the contents of a dynamic string on the heap so that host-side
tooling can display this string as the name of handle / reference ID
macro Void LogSnapshot_writeNameOfReference(UInt32 refID, IArg fmt, Ptr pString, UInt16 lengthInMAUs);
ARGUMENTS
refID
reference ID (e.g. task handle) that the name is
associated with
pString
the start address of the string on the heap
lengthInMAUs
the number of MAUs to log (e.g. strlen(pString))
fmt
a constant string that provides format specifiers
describing the string
EXAMPLE
The following C code shows how to log a task name for use by task
execution graphs etc.
#include <ti/uia/runtime/LogSnapshot.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
...
// Task create hook function that logs the task name.
// Notes: Task name is not trequired when creating a BIOS task. Please \
// make sure a name is provided in order for the host side analysis tool
// to work properly.
Void tskCreateHook(Task_Handle hTask, Error_Block *eb) {
String name;
name = Task_Handle_name(hTask);
LogSnapshot_writeNameOfReference(hTask,"Task_create: name=%s",
name,strlen(name)+1);
}
This event prints the Log call site (%$F) and a format string (%$S)
which describes what information the event is logging.
The following text will be displayed for the event:
nameOfReference at [demo.c:line 1234] [refID=0x80002000,adrs=0x80001234,40,40] Task_create: name=10msThread.
LogSnapshot_writeString() // module-wide |
|
Generate a LogSnapshot event for a string in memory
macro Void LogSnapshot_writeString(UInt32 snapshotID, IArg fmt, Ptr pString, UInt16 lengthInMAUs);
ARGUMENTS
snapshotID
ID used to identify snapshot events taken at the same
time. Set to 0 for first in series, set rest to return
value of LogSnapshot API. see getSnapshotId()
fmt
a constant string that provides a user-readable description
of what information the event is capturing
pString
the start address of the string in memory
lengthInMAUs
the number of MAUs to log (e.g. strlen(pString))
EXAMPLE
The following C code shows how to log a snapshot event to log the
contents of a string in memory.
#include <ti/uia/runtime/LogSnapshot.h>
...
Void myFunc(String name){
...
LogSnapshot_writeString(0,"User-defined name=%s.",name, strlen(name));
}
The following text will be displayed for the event, if it was logged
from file demo.c at line 1234 and all bytes in the 40 character string
was logged in the same event.
String Snapshot at [../demo.c:1234] [snapshotID=0,adrs=0x80001234,40,40] User-defined name=ValueOfParm.
LogSnapshot_writeStringWithIdTag() // module-wide |
|
Generate a LogSnapshot event for a string in memory
macro Void LogSnapshot_writeStringWithIdTag(UInt16 idTag, UInt32 snapshotID, IArg fmt, Ptr pString, UInt16 lengthInMAUs);
ARGUMENTS
idTag
ID used to identify who logged the event. Set to 0 for a
standard UIA event. Can be used to filter snapshot events on host.
snapshotID
ID used to identify snapshot events taken at the same
time. Set to 0 for first in series, set rest to return
value of LogSnapshot API. see getSnapshotId()
fmt
a constant string that provides a user-readable description
of what information the event is capturing
pString
the start address of the string in memory
lengthInMAUs
the number of MAUs to log (e.g. strlen(pString))
EXAMPLE
The following C code shows how to log a snapshot event to log the
contents of a string in memory.
#include <ti/uia/runtime/LogSnapshot.h>
...
Void myFunc(String name){
...
UInt16 myCustomIdTag = 1;
LogSnapshot_writeStringWithIdTag(myCustomIdTag,0,"User-defined name=%s.",name, strlen(name));
}
The following text will be displayed for the event, if it was logged
from file demo.c at line 1234 and all bytes in the 40 character string
was logged in the same event.
String Snapshot at [../demo.c:1234] [snapshotID=0,adrs=0x80001234,40,40] User-defined name=ValueOfParm.
Module-Wide Built-Ins |
|
// Get this module's unique id
Bool LogSnapshot_Module_startupDone();
// Test if this module has completed startup
// The heap from which this module allocates memory
Bool LogSnapshot_Module_hasMask();
// Test whether this module has a diagnostics mask
Bits16 LogSnapshot_Module_getMask();
// Returns the diagnostics mask for this module
Void LogSnapshot_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
struct LogSnapshot.EventRec |
|
The target representation of a recorded event
var obj = new LogSnapshot.EventRec;
// time event was written
obj.serial = Bits32 ...
// serial number of event
obj.evt = Bits32 ...
// target encoding of an Event
obj.snapshotId = Int ...
obj.fmt = IArg ...
obj.pData = Ptr ...
obj.lengthInMAUs = UInt16 ...
// arguments passed via Log_write/print
DETAILS
This structure defines how events are recorded on the target.
C SYNOPSIS
config LogSnapshot.injectIntoTraceFxn // module-wide |
|
Callback function that handles injection of info such as serial numbers
of sync point events, context change events or snapshot events into a
hardware trace stream. (e.g. GEM CPU Trace, System Trace, etc.)
DETAILS
Users can provide their own custom injectIntoTraceFxn to log whatever
additional information they wish to record when the hook function is called.
For example, event serial numbers can be injected into the CPU
trace stream and / or STM trace stream in order to enable correlation
of information logged in these streams with UIA software events.
EXAMPLES
Example 1: Correlating events with C64X+ and C66 CPU Trace
The following is an example of the configuration script used
to inject serial numbers of sync point events or context change events or
snapshot Ids associated with snapshot events.
Note that the GemTraceSync module's .xs script takes care of finding
all modules that implement the IUIATraceSyncClient and assigning the
GemTraceSync_injectIntoTrace function pointer to those modules'
injectIntoTraceFxn config option.
//The following 3 modules all implement the IUIATraceSyncClient interface
var LogSnapshot = xdc.useModule('ti.uia.runtime.LogSnapshot');
var LogCtxChg = xdc.useModule('ti.uia.runtime.LogCtxChg');
var LogSync = xdc.useModule('ti.uia.runtime.LogSync');
//For C66 devices, replace the following line with
// var GemTraceSync = xdc.useModule('ti.uia.family.c66.GemTraceSync');
var GemTraceSync = xdc.useModule('ti.uia.family.c64p.GemTraceSync');
Example 2: How to create a custom hook function
and assign it to the LogSnapshot module
The following is an example of a 'C' code program that implements
a hook function that prints out the snapshot ID that is passed in
as the serialNumber
#include <xdc/std.h>
#include <xdc/runtime/Gate.h>
#include <ti/uia/runtime/IUIATraceSyncProvider.h>
#include <ti/uia/runtime/LogSnapshot.h>
#include <stdio.h>
#include <string.h>
extern Void myHookFxn(UInt32 serialNumber, IUIATraceSyncProvider_ContextType ctxType);
Void Test();
char name[32]={"Bob"};
UInt32 newAppId = 0;
Void myHookFxn(UInt32 serialNumber, IUIATraceSyncProvider_ContextType ctxType){
volatile UInt32 syncWord;
IArg key = Gate_enterSystem();
printf("newAppId written with serialNumber %d and ctxType = %d\n",serialNumber,ctxType);
Gate_leaveSystem(key);
}
Void Test(){
// note that the hook function is triggered by calling LogSnapshot_getSnapshotId()
// since that is where the unique snapshot ID that is passed to the
// hook function is generated.
Int snapshotId = LogSnapshot_getSnapshotId();
LogSnapshot_writeString(snapshotId,"User-defined name=%s.",name, strlen(name));
}
Void main(){
while(TRUE){ Test(); }
}
In order to have the above user-defined function called by the LogSnapshot
module whenever it writes an event, the following configuration script
is needed:
var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
var LogSnapshot = xdc.useModule('ti.uia.runtime.LogSnapshot');
var IUIATraceSyncClient = xdc.useModule('ti.uia.runtime.IUIATraceSyncClient');
LogSnapshot.injectIntoTraceFxn = $externFxn('myHookFxn');
SEE
C SYNOPSIS
config LogSnapshot.isTimestampEnabled // module-wide |
|
used to enable or disable logging the 64b local CPU timestamp
at the start of each event
LogSnapshot.isTimestampEnabled = Bool true;
C SYNOPSIS
config LogSnapshot.loggerObj // module-wide |
|
handle of the logger that is to be used to log snapshot events
LogSnapshot.loggerObj = Ptr null;
C SYNOPSIS
config LogSnapshot.maxLengthInMAUs // module-wide |
|
Maximum number of MAUs (miniumum addressable units, e.g. bytes)
supported by LogSnapshot events
LogSnapshot.maxLengthInMAUs = Int 512;
DETAILS
Attempting to write more than the maximum length results in the
multiple events being logged. The maxLengthInMAUs must be
lower than the size of the buffer that the events are being logged to.
Must be less than 1400 in order to support streaming of event
data over UDP.
C SYNOPSIS
metaonly config LogSnapshot.common$ // module-wide |
|
Common module configuration parameters
DETAILS
All modules have this configuration parameter. Its name
contains the '$' character to ensure it does not conflict with
configuration parameters declared by the module. This allows
new configuration parameters to be added in the future without
any chance of breaking existing modules.
metaonly config LogSnapshot.idToInfo // module-wide |
|
LogSnapshot.idToInfo = String[string] [ ];
metaonly config LogSnapshot.isInjectIntoTraceEnabled // module-wide |
|
set false to turn off injection of sync point info into trace even
if a module that implements IUIATraceSyncProvider is configured
LogSnapshot.isInjectIntoTraceEnabled = Bool true;
DETAILS
The XDCScript associated with a module that implements IUIATraceSyncProvider
is responsible for checking this config option for all IUIATraceSyncClient
modules before automatically configuring the client callback function.
This allows users to control which features have sync points injected
into the trace stream. For example, a user may wish to configure
LogSync.isInjectIntoTraceEnabled = true and
LogCtxChg.isInjectIntoTraceEnabled = false in order to reduce the number
of sync point events injected into the trace stream.