846 lines
25 KiB
C
846 lines
25 KiB
C
/* evtLogLib.c - event logging library */
|
|
|
|
/*
|
|
* Copyright (c) 1994-2008, 2010-2012 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute, modify or otherwise make use
|
|
* of this software may be licensed only pursuant to the terms
|
|
* of an applicable Wind River license agreement.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
04k,04jul12,wzc WIND00361531 - Remove building warnings.
|
|
04j,29aug11,wzc Updated to support dynamic power management.(WIND00295115)
|
|
04i,27jul11,wzc PPM for SV (WIND00214625)
|
|
04h,29jun10,wzc Line aligned.
|
|
04g,18jun10,wzc Check the string length and avoid too long.(WIND00206550)
|
|
04f,16jun10,vhe Coding conventions
|
|
04e,21jan10,wzc Adapt SV to vxWorks 64bit.
|
|
04d,10sep08,tcr change references to _WRS_VX_SMP
|
|
04c,03sep08,jpb Renamed VSB header file
|
|
04b,16jul08,tcr BLOB macros, fix warnings
|
|
04a,09may08,tcr update funcptrs, remove redundant code
|
|
03z,08apr08,tcr add log routines for perfMon implementation
|
|
03y,18jun08,jpb Renamed _WRS_VX_SMP to _WRS_CONFIG_SMP. Added include path
|
|
for kernel configurations options set in vsb.
|
|
03x,10jul07,tcr more SMP updates
|
|
03w,19dec06,tcr changes for SMP
|
|
fix defect WIND00083624
|
|
03w,07feb07,lei removed "IMPORT Q_HEAD readyQHead", declared in kernelLibP.h;
|
|
changed "" to <> for header files.
|
|
03v,20sep06,tcr fix non-aligned write in wvEvent() (WIND00066146)
|
|
remove i960 code
|
|
03u,22sep04,tcr don't use MEM_ROUND_UP
|
|
03t,21apr04,tcr add parameter to logging function
|
|
03s,05mar04,tcr move evtEdrErrorInject() prototype to header
|
|
03r,04mar04,tcr fix event space allocation for evtEdrErrorInject()
|
|
03q,11feb04,tcr fix build error in evtLogSyscall
|
|
03p,16dec03,syy Added evtLogOBinary()
|
|
03o,04dec03,aim added evtEdrErrorInject
|
|
03r,03nov03,tcr add WindView syscall logging rtn
|
|
add parameter to evtLogString()
|
|
03q,16sep03,tcr allow evtLogString to take variable num of params
|
|
03p,10sep03,tcr update evtLogString to take another parameter
|
|
03o,26aug03,tcr changes for Base6
|
|
03n,08may03,pes PAL conditional compilation cleanup. Phase 2.
|
|
03m,14aug98,cth removed MEM_ROUND_UP from evtLogPoint
|
|
03m,10aug98,pr added i960 function pointers to evtLogFuncBind
|
|
03l,30jul98,cjtc removed logMsg EVTLOG_RESERVE_BUFF_SPACE macros which resulted
|
|
in stack corruption of the calling task (SPR 21993)
|
|
03k,13may98,pr modified logMsg content
|
|
03j,12may98,pr added logMsg and stop windview if buffer is full
|
|
03i,17apr98,cth removed function evtHeaderLog
|
|
03h,15apr98,cth added binding of _func_evtLogReserveTaskName
|
|
03g,10apr98,cjtc architecture port for i960 processors.
|
|
fixed bug in evtLogT0_noInt in which timestamp was written to
|
|
the event buffer before it was read.
|
|
Removed unused local variable "level" from evtLogT0_noInt
|
|
03f,09apr98,pr added evtLogT0_noInt declaration
|
|
03e,08apr98,pr modified evtLogO to be of general use. Added evtLogT0_noInt
|
|
03d,06apr98,nps 68k family nows shares portable code.
|
|
03c,18mar98,nps fixed check for 'thin' mode when creating header.
|
|
03b,17feb98,dvs added events for memory instrumentation in evtLogO and
|
|
pr fixed evtLogO buffer size.
|
|
03a,03feb98,cth changed evtBufferId from static to global
|
|
02z,27jan98,cth added evtObjLogFuncBind, evtLogFuncBind, evtBufferBind and
|
|
evtHeaderLog, updated copyright
|
|
02y,25jan98,pr changed size in evtLogT1_noTS
|
|
02x,22jan98,pr fixed evtsched
|
|
02w,18dec97,cth changed include buffer.h to wvBufferP.h, changed tmpBufId to
|
|
evtBufferId
|
|
02v,16nov97,cth removed evtBuf and rBuff references
|
|
changed buffer writes to use generic WV2.0 buffers
|
|
02u,22oct97,pr fixed EVTLOG_RESERVE_BUFF_SPACE_L for evtLogT1_noTS
|
|
02t,21oct97,nps use modified rBuff API
|
|
02s,18aug97,nps fixed bug in evtLogM1
|
|
02r,20jul97,nps added ring buffer support
|
|
02q,24jun97,pr commented the evtLogTIsOn for evtLogPoint
|
|
02p,08jul96,pr added evtLogT1_noTS for PPC
|
|
02o,06dec94,rdc fixed bogus intlocks that should have been unlocks.
|
|
02n,08nov94,rdc added 960 kernel instrumentation routines.
|
|
02m,02nov94,rdc added argument to evtLogString to support lockCount param
|
|
in EVENT_TASKNAME.
|
|
02l,02nov94,rdc unlocked interrupts before returning because of errors.
|
|
02k,27may94,smb now use alignment macros to store data in buffer.
|
|
02j,23may94,pme removed taskIdLogin for EVENT_WIND_EXIT_NODISPATCH
|
|
made evtsched equivalent to the 68k assembly version
|
|
01i,05may94,smb sparc porting
|
|
01h,16mar94,smb removed EVENT_WIND_EXIT_IDLENOT
|
|
level 1 optimisations.
|
|
01g,22feb94,smb changed typedef EVENT_TYPE to event_t (SPR #3064)
|
|
01f,24jan94,smb fixed return values for eventPoint()
|
|
01e,19jan94,smb event buffer fix SPR #2904
|
|
01d,14jan94,c_s evtLogOInt now handles EVENT_SIGWRAPPER correctly (SPR #2883).
|
|
01c,04jan94,c_s evtLogPoint now validates the user event ID correctly.
|
|
SPR #2724.
|
|
01b,30dec93,c_s evtLogPoint now uses memcpy (), rather than strncpy (), to
|
|
transfer the user's buffer of data for user-defined events
|
|
to the logging area. SPR #2799.
|
|
01a,10dec93,smb created
|
|
*/
|
|
|
|
/*
|
|
DESCRIPTION
|
|
This library provides routines which log events to the buffer for different
|
|
types of events generated by the instrumented code.
|
|
|
|
INCLUDE FILES:
|
|
|
|
SEE ALSO:
|
|
\NOMANUAL
|
|
*/
|
|
|
|
#include <vxWorks.h>
|
|
#include <vsbConfig.h>
|
|
#include <logLib.h>
|
|
#include <wvLib.h>
|
|
#include <string.h>
|
|
#include <taskLib.h>
|
|
#include <sysLib.h>
|
|
|
|
#include <private/taskLibP.h>
|
|
#include <private/eventP.h>
|
|
#include <private/kernelLibP.h>
|
|
#include <private/workQLibP.h>
|
|
#include <private/wvBufferP.h>
|
|
#include <private/evtLogLibP.h>
|
|
#include <private/kernelLibP.h>
|
|
#include <private/syscallLibP.h>
|
|
#include <private/svFuncBindP.h>
|
|
#include <private/wvBufferP.h> /* BUFFER_ID */
|
|
|
|
#ifdef _WRS_CONFIG_SMP
|
|
#include <spinLockLib.h>
|
|
#endif /* _WRS_CONFIG_SMP */
|
|
|
|
/* optimized version no longer used for 680X0 */
|
|
|
|
#define evtLogLib_PORTABLE
|
|
|
|
/* defines */
|
|
|
|
/* 29 bits for payload length, 3 bits for padding length */
|
|
|
|
#define MAX_PAYLOAD_SIZE (0x1fffffff)
|
|
|
|
|
|
#define MAX_WV_TASKS 500 /* should be the same MAX_DSP_TASKS */
|
|
|
|
#define EVTLOG_RESERVE_BUFF_SPACE(EVENT_SIZE) \
|
|
eventBase = (event_t *) evtBufferId->writeRtn (evtBufferId,NULL,EVENT_SIZE); \
|
|
\
|
|
if (!eventBase) \
|
|
{ \
|
|
wvEvtLogStop(); \
|
|
CRIT_REGION_EXIT(); \
|
|
return; \
|
|
}
|
|
|
|
#define EVTLOG_RESERVE_BUFF_SPACE_STAT(EVENT_SIZE) \
|
|
eventBase = (event_t *) evtBufferId->writeRtn (evtBufferId,NULL,EVENT_SIZE); \
|
|
\
|
|
if (!eventBase) \
|
|
{ \
|
|
wvEvtLogStop(); \
|
|
CRIT_REGION_EXIT(); \
|
|
return (ERROR); \
|
|
}
|
|
|
|
#define EVTLOG_RESERVE_BUFF_SPACE_L(EVENT_SIZE) \
|
|
eventBase = (event_t *) evtBufferId->writeRtn (evtBufferId,NULL,EVENT_SIZE); \
|
|
\
|
|
if (!eventBase) \
|
|
{ \
|
|
wvEvtLogStop(); \
|
|
CRIT_REGION_EXIT(); \
|
|
return; \
|
|
}
|
|
|
|
|
|
#define CRIT_REGION_ENTER() evtBufferId->lockRtn(evtBufferId)
|
|
#define CRIT_REGION_EXIT() evtBufferId->unlockRtn(evtBufferId)
|
|
|
|
/*
|
|
* EVENT_CPU_ID is only required for SMP builds
|
|
* This macro inserts an event indicating the current CPU, for SMP
|
|
* systems. On UP systems, it does nothing.
|
|
*/
|
|
|
|
#ifdef _WRS_CONFIG_SMP
|
|
|
|
#define CPU_EVENT_EMIT(cpuId) \
|
|
do { \
|
|
EVT_STORE_UINT16(eventBase,EVENT_CPU_ID); \
|
|
EVT_STORE_UINT16(eventBase,cpuId); \
|
|
} while (0)
|
|
|
|
#define SIZEOF_CPU_ID_EVENT (sizeof (event_t) + sizeof (UINT16))
|
|
|
|
#else /* _WRS_CONFIG_SMP */
|
|
|
|
#define CPU_EVENT_EMIT(cpuId)
|
|
|
|
#define SIZEOF_CPU_ID_EVENT 0
|
|
|
|
#endif /* _WRS_CONFIG_SMP */
|
|
|
|
|
|
#ifdef _WRS_CONFIG_SMP
|
|
|
|
/*
|
|
* Macro which inserts a CPU_ID event if this event came from a
|
|
* different CPU to the last event recorded into the buffer
|
|
*/
|
|
|
|
#define CONDITIONAL_CPU_EMIT(allocator,eventSize) \
|
|
{ \
|
|
int cpuId; \
|
|
cpuId = vxCpuIndexGet (); \
|
|
if (cpuId != currentCpuId) \
|
|
{ \
|
|
allocator(eventSize + SIZEOF_CPU_ID_EVENT); \
|
|
CPU_EVENT_EMIT((UINT16)cpuId); \
|
|
currentCpuId = cpuId; \
|
|
} \
|
|
else \
|
|
allocator(eventSize); \
|
|
}
|
|
#else /* _WRS_CONFIG_SMP */
|
|
#define CONDITIONAL_CPU_EMIT(allocator,eventSize) allocator(eventSize)
|
|
#endif /* _WRS_CONFIG_SMP */
|
|
|
|
/* local */
|
|
|
|
BUFFER_ID evtBufferId; /* event buffer identifier */
|
|
|
|
|
|
/* flag indicating library is initialized */
|
|
|
|
LOCAL int libInitialized = 0;
|
|
|
|
#ifdef _WRS_CONFIG_SMP
|
|
|
|
/* track which CPU is emitting events. Only used while spinlock held */
|
|
|
|
LOCAL int currentCpuId = -1;
|
|
|
|
#endif /* _WRS_CONFIG_SMP */
|
|
|
|
/* forward declarations */
|
|
|
|
void evtLogOBinary (event_t action, int nParam, int arg1, int arg2, int arg3,
|
|
int arg4, int arg5, int arg6, int payloadSize,
|
|
const char *payload);
|
|
void evtLogString (event_t action, int nArgs, int arg1, int arg2, int arg3,
|
|
int arg4, int arg5, int arg6, int arg7, const char *string);
|
|
void evtObjNameBuffAdd (event_t action, int nArgs, int arg1, int arg2, int arg3,
|
|
int arg4, int arg5, const char *string);
|
|
|
|
void evtLogSyscall (unsigned int nParam, const SYSCALL_ENTRY_STATE * pState);
|
|
|
|
#if defined _WRS_EVTLOGT1_NOTS
|
|
|
|
void evtLogT1_noTS (event_t action, int param);
|
|
|
|
#endif /* _WRS_EVTLOGT1_NOTS */
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogLibInit - initialize evtLogLib
|
|
*
|
|
* This function initializes the spinlock for the logging routines
|
|
*
|
|
* RETURNS: OK, or ERROR
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
STATUS evtLogLibInit (void)
|
|
{
|
|
if (!libInitialized)
|
|
{
|
|
libInitialized = 1;
|
|
return (OK);
|
|
}
|
|
else
|
|
return (ERROR);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtObjLogFuncBind - bind object-level logging functions
|
|
*
|
|
* This routine binds the function pointers used to log system-object events
|
|
* to the appropriate functions in this library.
|
|
*
|
|
* RETURNS: N/A
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
void evtObjLogFuncBind (void)
|
|
{
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogFuncBind - bind general event-logging functions
|
|
*
|
|
* This function binds instrumentation function pointers to logging functions
|
|
* in this file. Event logging routines associated with class-1 (object-
|
|
* class) logging must be bound earlier, with a call to evtObjLogFuncBind.
|
|
*
|
|
* RETURNS: N/A
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
void evtLogFuncBind (void)
|
|
{
|
|
_func_evtLogPayload = &evtLogPayload;
|
|
_func_evtLogPayloadString = &evtLogPayloadString;
|
|
|
|
_func_evtLogReserveTaskName = &wvObjNameCurrentBuffAdd;
|
|
|
|
_func_evtLogSyscall = &evtLogSyscall;
|
|
|
|
_func_edrEvt = &evtEdrErrorInject;
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtNewBufferCallback - callback to run when new buffer started in log
|
|
*
|
|
* This function writes initial data into the buffer when a new buffer is started
|
|
* by the buffer library. This is to save context data so that in wrapping
|
|
* mode, even when buffers are dropped, it is possible to interpret events from
|
|
* the beginning of the log correctly.
|
|
*
|
|
* RETURNS: OK, or ERROR
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
LOCAL STATUS evtNewBufferCallback (BUFFER_ID buff)
|
|
{
|
|
#ifdef _WRS_CONFIG_SMP
|
|
|
|
event_t * eventBase;
|
|
|
|
|
|
eventBase = (event_t *) evtBufferId->writeRtn (buff,NULL,4);
|
|
if (eventBase == NULL)
|
|
return (ERROR);
|
|
|
|
EVT_STORE_UINT16(eventBase,EVENT_CPU_ID);
|
|
EVT_STORE_UINT16(eventBase,(UINT16)vxCpuIndexGet ());
|
|
|
|
#endif /* _WRS_CONFIG_SMP */
|
|
|
|
return OK;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtBufferBind - bind logging routines to a specific event buffer
|
|
*
|
|
* This routine associates a specific event buffer with the event-logging
|
|
* routines.
|
|
*
|
|
* RETURNS: N/A
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
void evtBufferBind
|
|
(
|
|
BUFFER_ID bufId /* bind logging functions to this buffer */
|
|
)
|
|
{
|
|
/* lock buffer until connection completed */
|
|
|
|
bufId->lockRtn (bufId);
|
|
evtBufferId = bufId;
|
|
|
|
#ifdef _WRS_CONFIG_SMP
|
|
bufId->newBuffHookAdd (evtBufferId, evtNewBufferCallback);
|
|
#endif /* _WRS_CONFIG_SMP */
|
|
|
|
bufId->unlockRtn (bufId);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogSyscall - record syscall events with up to 8 params
|
|
*
|
|
* This event logging routine stores
|
|
* event id (short )
|
|
* timestamp (int )
|
|
* param[0..7] (int ) - no. of param logged depends on the event id.
|
|
*
|
|
* This routine lock insterrupts
|
|
*
|
|
* It takes a syscall state struct, and the number of parameters. This avoids
|
|
* a WindView dependancy on the syscall component.
|
|
*
|
|
* SEE ALSO:
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
void evtLogSyscall
|
|
(
|
|
unsigned int nParam, /* number of params to record */
|
|
const SYSCALL_ENTRY_STATE * pState /* parameter array, syscall num */
|
|
)
|
|
{
|
|
event_t * eventBase;
|
|
int * intBase;
|
|
long int * longBase;
|
|
int timestamp;
|
|
unsigned int n;
|
|
|
|
/*
|
|
* This max number of params may be #defined somewhere, but in syscallLibP.h
|
|
* it's fixed as 8. If the requested number is wrong, make it safe.
|
|
*/
|
|
|
|
if (nParam > 8)
|
|
nParam = 0;
|
|
|
|
CRIT_REGION_ENTER();
|
|
|
|
/* reserve space for eventid, timestamp, syscallid, and some parameters */
|
|
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE,
|
|
sizeof (UINT16) + sizeof (UINT32) +
|
|
sizeof (UINT16) + (nParam * sizeof (long int)));
|
|
|
|
/* create event id indexed of the first */
|
|
|
|
EVT_STORE_UINT16 (eventBase, (event_t)(EVENT_SYSCALL_0 + nParam));
|
|
intBase = (int *) eventBase;
|
|
|
|
timestamp = (* _func_tmrStamp) ();
|
|
EVT_STORE (intBase, timestamp);
|
|
|
|
eventBase = (event_t *) intBase;
|
|
EVT_STORE_UINT16 (eventBase, (unsigned short)pState -> scn);
|
|
longBase = (long int *) eventBase;
|
|
|
|
for (n = 0; n < nParam; n++)
|
|
{
|
|
EVT_STORE (longBase, (long int)(pState->args [n]));
|
|
}
|
|
|
|
CRIT_REGION_EXIT();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogPoint - logs a user defined event or eventpoint via event () or e ().
|
|
*
|
|
* This event logging routine stores
|
|
* event id (short )
|
|
* timestamp (int)
|
|
* address (int)
|
|
* buffer size (int) - if size is ZERO the buffer does not exist.
|
|
* buffer (char)
|
|
*
|
|
* RETURNS: OK, or ERROR if unable to log event point
|
|
* SEE ALSO:
|
|
* \NOMANUAL
|
|
*
|
|
* INTERNAL
|
|
* When storing payload data, we need to honour the alignment
|
|
* constraints. Currently, all data must be half-word aligned.
|
|
* The host needs to know how much padding is attached to a data item, and we
|
|
* use the top bits of the length item for this information. The
|
|
* remaining bits contain the length requested by the caller. The length
|
|
* stored is the requested length, plus any padding.
|
|
*/
|
|
|
|
STATUS evtLogPoint
|
|
(
|
|
event_t action, /* user event id (0 - 25535) */
|
|
void * addr, /* pc address */
|
|
size_t nbytes, /* buffer size */
|
|
char * buffer /* buffer */
|
|
)
|
|
{
|
|
event_t * eventBase;
|
|
event_t biasedAction;
|
|
int * intBase;
|
|
long int * longBase;
|
|
int timestamp;
|
|
size_t actualBytes;
|
|
size_t padding;
|
|
long iAddr;
|
|
|
|
biasedAction = (event_t)(action + MIN_USER_ID);
|
|
|
|
if (nbytes > MAX_PAYLOAD_SIZE)
|
|
return (ERROR);
|
|
|
|
/* payload must not result in non-aligned write of following event */
|
|
|
|
actualBytes = (nbytes + 1) & (~1);
|
|
padding = actualBytes - nbytes;
|
|
|
|
/* is event id within the range of user event ids? */
|
|
if (biasedAction < MIN_USER_ID || biasedAction > MAX_USER_ID)
|
|
return (ERROR);
|
|
|
|
CRIT_REGION_ENTER();
|
|
|
|
/* Always timestamp and two params. Sometimes a payload, too */
|
|
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE_STAT,
|
|
actualBytes + EVTLOG_TN_SIZE(2));
|
|
|
|
EVT_STORE_UINT16 (eventBase, biasedAction);
|
|
intBase = (int *) eventBase;
|
|
timestamp = (* _func_tmrStamp) ();
|
|
EVT_STORE (intBase, timestamp);
|
|
longBase = (long int *)intBase;
|
|
iAddr = (long)addr;
|
|
EVT_STORE (longBase, iAddr);
|
|
intBase = (int *)longBase;
|
|
|
|
EVT_STORE (intBase, (int)(nbytes + (padding << PADDING_SHIFT_COUNT)));
|
|
|
|
/* copy buffer contents into event buffer */
|
|
|
|
if ((nbytes != 0) && (buffer != NULL))
|
|
{
|
|
memcpy ((char *) intBase, buffer, nbytes);
|
|
}
|
|
|
|
CRIT_REGION_EXIT();
|
|
|
|
return (OK);
|
|
}
|
|
|
|
#if defined _WRS_EVTLOGT1_NOTS
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogT1_noTS - log event id without getting timestamp
|
|
*
|
|
* This event logging routine stores
|
|
* event id (short )
|
|
* time (int )
|
|
*
|
|
* This routines is very similar to the evtLogT1. The main difference
|
|
* is that no timestamp is here. The parameter passed is actually the
|
|
* current timestamp for this event. This routine is called when an
|
|
* interrupt is entered. It is used for PPC architecture. PPC generates
|
|
* only one kind of interrupt. When the interrupt is entered, the timestamp
|
|
* for windview is obtained. No information about the type of interrupt is
|
|
* known at that point. Only when the sysIbcIntHandler routine is called,
|
|
* the interrupt vector handler is obtained and it is passed to this
|
|
* routine, together with the timestamp.
|
|
* When this routine is called, interrupts must be locked already.
|
|
*
|
|
* SEE ALSO:
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
void evtLogT1_noTS
|
|
(
|
|
event_t action, /* event id */
|
|
int param /* timestamp */
|
|
)
|
|
{
|
|
event_t * eventBase;
|
|
|
|
CRIT_REGION_ENTER();
|
|
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE_L,
|
|
EVTLOG_TN_SIZE(0));
|
|
|
|
EVT_STORE_UINT16 (eventBase, action);
|
|
|
|
CRIT_REGION_EXIT();
|
|
}
|
|
|
|
#endif /* _WRS_EVTLOGT1_NOTS */
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtEdrErrorInject - log edrErrorInject event to the log.
|
|
*
|
|
* This event logging routine stores:
|
|
* event id (short)
|
|
* timestamp (int)
|
|
* kind (int)
|
|
* len (fileName) (int)
|
|
* fileName (char)
|
|
* lineNumber (int)
|
|
* address (void *)
|
|
* len(textPayload)(int) - if size is ZERO the string does not exist.
|
|
* textPayload (char)
|
|
*
|
|
* SEE ALSO:
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
void evtEdrErrorInject
|
|
(
|
|
event_t action, /* the event id */
|
|
int kind, /* error-record kind */
|
|
const char * fileName, /* fileName */
|
|
int lineNumber, /* lineNumber from fileName */
|
|
const void * address, /* faulting address */
|
|
const char * textPayload /* error-record summary */
|
|
)
|
|
{
|
|
event_t * eventBase;
|
|
int * intBase;
|
|
long int * longBase;
|
|
size_t len1;
|
|
size_t len2;
|
|
size_t evtSize;
|
|
int timestamp;
|
|
long iAddr;
|
|
if (fileName != NULL)
|
|
len1 = strlen (fileName);
|
|
else
|
|
len1 = 0;
|
|
|
|
/* ensure len + data will be half word aligned. */
|
|
|
|
if (len1 & 0x1)
|
|
len1++;
|
|
|
|
if (textPayload != NULL)
|
|
len2 = strlen (textPayload);
|
|
else
|
|
len2 = 0;
|
|
|
|
if (len2 & 0x1)
|
|
len2++;
|
|
|
|
evtSize = (sizeof (event_t) +
|
|
sizeof (int) + /* timestamp */
|
|
4 * (sizeof (int)) + /* kind, line, len1, len2 */
|
|
sizeof (address) +
|
|
len1 + len2);
|
|
|
|
|
|
CRIT_REGION_ENTER();
|
|
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE,evtSize);
|
|
|
|
EVT_STORE_UINT16 (eventBase, action);
|
|
|
|
intBase = (int *) eventBase;
|
|
timestamp = (* _func_tmrStamp) ();
|
|
|
|
EVT_STORE (intBase, timestamp);
|
|
|
|
EVT_STORE (intBase, kind);
|
|
|
|
EVT_STORE (intBase, (int)len1);
|
|
|
|
if (len1 != 0)
|
|
{
|
|
strncpy ((char *) intBase, fileName, len1);
|
|
intBase = (int *) ((char *) intBase + len1);
|
|
}
|
|
|
|
EVT_STORE (intBase, lineNumber);
|
|
longBase = (long int *)intBase;
|
|
iAddr = (long)address;
|
|
EVT_STORE (longBase, iAddr);
|
|
intBase = (int *)longBase;
|
|
EVT_STORE (intBase, (int)len2);
|
|
|
|
if (len2 != 0)
|
|
{
|
|
strncpy ((char *) intBase, textPayload, len2);
|
|
intBase = (int *) ((char *) intBase + len2);
|
|
}
|
|
|
|
CRIT_REGION_EXIT();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogPayload - logs an event payload from perfMon data collector
|
|
*
|
|
* This event logging routine stores
|
|
* event id (short )
|
|
* timestamp (int)
|
|
* data
|
|
*
|
|
* The length is assumed to be compatible with logging constraints
|
|
* (e.g. alignment)
|
|
*
|
|
* RETURNS: OK, or ERROR if unable to log event
|
|
* SEE ALSO:
|
|
* \NOMANUAL
|
|
*
|
|
*/
|
|
|
|
STATUS evtLogPayload
|
|
(
|
|
event_t action, /* event id */
|
|
int withTimestamp, /* non-zero if timestamp required */
|
|
const void * addr, /* pointer to source args */
|
|
size_t nbytes /* length of source args*/
|
|
)
|
|
{
|
|
event_t * eventBase;
|
|
int * intBase;
|
|
int timestamp;
|
|
|
|
if (nbytes > MAX_PAYLOAD_SIZE)
|
|
return (ERROR);
|
|
|
|
CRIT_REGION_ENTER();
|
|
|
|
if (withTimestamp)
|
|
{
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE_STAT,
|
|
sizeof (timestamp) + sizeof (action) + nbytes);
|
|
}
|
|
else
|
|
{
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE_STAT,
|
|
sizeof (action) + nbytes);
|
|
}
|
|
|
|
EVT_STORE_UINT16 (eventBase, action);
|
|
intBase = (int *) eventBase;
|
|
|
|
if (withTimestamp)
|
|
{
|
|
timestamp = (* _func_tmrStamp) ();
|
|
EVT_STORE (intBase, timestamp);
|
|
}
|
|
|
|
/* copy buffer contents into event buffer */
|
|
|
|
if ((nbytes != 0) && (addr != NULL))
|
|
{
|
|
memcpy ((char *) intBase, addr, nbytes);
|
|
}
|
|
|
|
CRIT_REGION_EXIT();
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* evtLogPayloadString - logs an event payload from perfMon data collector
|
|
*
|
|
* This event logging routine stores
|
|
* event id (short )
|
|
* timestamp (int)
|
|
* data
|
|
*
|
|
* The length is assumed to be compatible with logging constraints
|
|
* (e.g. alignment)
|
|
*
|
|
* RETURNS: OK, or ERROR if unable to log event
|
|
* SEE ALSO:
|
|
* \NOMANUAL
|
|
*
|
|
*/
|
|
|
|
STATUS evtLogPayloadString
|
|
(
|
|
event_t action, /* event id */
|
|
int withTimestamp, /* non-zero if timestamp required */
|
|
const void * addr, /* pointer to source args */
|
|
size_t nbytes, /* length of source args (bytes) */
|
|
const void * stringAddr, /* address of optional string part */
|
|
size_t stringSize /* size of optional string part */
|
|
)
|
|
{
|
|
event_t * eventBase;
|
|
int * intBase;
|
|
int timestamp;
|
|
int eventSize;
|
|
int actualBytes;
|
|
int padding;
|
|
|
|
if ((nbytes > MAX_PAYLOAD_SIZE) || (stringSize > MAX_PAYLOAD_SIZE))
|
|
return (ERROR);
|
|
|
|
actualBytes = (int)((stringSize + 1) & (~1));
|
|
padding = (int)(actualBytes - stringSize);
|
|
|
|
eventSize = (int)(sizeof (action) +
|
|
nbytes + sizeof (actualBytes) + actualBytes);
|
|
|
|
CRIT_REGION_ENTER();
|
|
|
|
if (withTimestamp)
|
|
{
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE_STAT,
|
|
sizeof (timestamp) + eventSize);
|
|
}
|
|
else
|
|
{
|
|
CONDITIONAL_CPU_EMIT(EVTLOG_RESERVE_BUFF_SPACE_STAT,
|
|
eventSize);
|
|
}
|
|
|
|
EVT_STORE_UINT16 (eventBase, action);
|
|
intBase = (int *) eventBase;
|
|
|
|
if (withTimestamp)
|
|
{
|
|
timestamp = (* _func_tmrStamp) ();
|
|
EVT_STORE (intBase, timestamp);
|
|
}
|
|
|
|
/* copy args into event buffer */
|
|
|
|
if ((nbytes != 0) && (addr != NULL))
|
|
{
|
|
memcpy ((char *) intBase, addr, nbytes);
|
|
}
|
|
|
|
/* adjust intBase past args data just written */
|
|
|
|
intBase += nbytes / sizeof (*intBase);
|
|
|
|
/* BLOB length */
|
|
|
|
EVT_STORE (intBase, (int)(stringSize + (padding << PADDING_SHIFT_COUNT)));
|
|
|
|
/* BLOB data */
|
|
|
|
if ((stringSize != 0) && (stringAddr != NULL))
|
|
{
|
|
memcpy ((char *) intBase, stringAddr, stringSize);
|
|
}
|
|
|
|
CRIT_REGION_EXIT();
|
|
|
|
return (OK);
|
|
}
|