VirtualBox

Changeset 104920 in vbox


Ignore:
Timestamp:
Jun 14, 2024 12:02:03 PM (3 months ago)
Author:
vboxsync
Message:

Runtime/tools/RTTraceLogTool,Devices/VBoxTraceLogDecoders.cpp: Allow attaching a state for a decoder to enable analysis spanning multiple events, bugref:10701

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/tracelog-decoder-plugin.h

    r104892 r104920  
    11/** @file
    2  * VD: Plugin support API.
     2 * IPRT: Tracelog decoder plugin API for RTTraceLogTool.
    33 */
    44
     
    4343#include <iprt/tracelog.h>
    4444#include <iprt/types.h>
     45
     46
     47/** Pointer to helper functions for decoders. */
     48typedef struct RTTRACELOGDECODERHLP *PRTTRACELOGDECODERHLP;
     49
     50
     51/**
     52 * Decoder state free callback.
     53 *
     54 * @param   pHlp        Pointer to the callback structure.
     55 * @param   pvState     Pointer to the decoder state.
     56 */
     57typedef DECLCALLBACKTYPE(void, FNTRACELOGDECODERSTATEFREE,(PRTTRACELOGDECODERHLP pHlp, void *pvState));
     58/** Pointer to an event decode callback. */
     59typedef FNTRACELOGDECODERSTATEFREE *PFNTRACELOGDECODERSTATEFREE;
     60
     61
     62/**
     63 * Helper functions for decoders.
     64 */
     65typedef struct RTTRACELOGDECODERHLP
     66{
     67    /** Magic value (RTTRACELOGDECODERHLP_MAGIC). */
     68    uint32_t                u32Magic;
     69
     70    /**
     71     * Helper for writing formatted text to the output.
     72     *
     73     * @returns IPRT status.
     74     * @param   pHlp        Pointer to the callback structure.
     75     * @param   pszFormat   The format string.  This may use all IPRT extensions as
     76     *                      well as the debugger ones.
     77     * @param   ...         Arguments specified in the format string.
     78     */
     79    DECLCALLBACKMEMBER(int, pfnPrintf, (PRTTRACELOGDECODERHLP pHlp, const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(3, 4);
     80
     81
     82    /**
     83     * Helper for writing formatted error message to the output.
     84     *
     85     * @returns IPRT status.
     86     * @param   pHlp        Pointer to the callback structure.
     87     * @param   pszFormat   The format string.  This may use all IPRT extensions as
     88     *                      well as the debugger ones.
     89     * @param   ...         Arguments specified in the format string.
     90     */
     91    DECLCALLBACKMEMBER(int, pfnErrorMsg, (PRTTRACELOGDECODERHLP pHlp, const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(3, 4);
     92
     93
     94    /**
     95     * Creates a new decoder state and associates it with the given helper structure.
     96     *
     97     * @returns IPRT status.
     98     * @param   pHlp        Pointer to the callback structure.
     99     * @param   cbState     Size of the state in bytes.
     100     * @param   pfnFree     Callback which is called before the decoder state is freed to give the decoder
     101     *                      a chance to do some necessary cleanup, optional.
     102     * @param   ppvState    Where to return the pointer to the state on success.
     103     *
     104     * @note This will destroy and free any previously created decoder state as there can be only one currently for
     105     *       a decoder.
     106     */
     107    DECLCALLBACKMEMBER(int, pfnDecoderStateCreate, (PRTTRACELOGDECODERHLP pHlp, size_t cbState, PFNTRACELOGDECODERSTATEFREE pfnFree,
     108                                                    void **ppvState));
     109
     110
     111    /**
     112     * Destroys any currently attached decoder state.
     113     *
     114     * @param   pHlp        Pointer to the callback structure.
     115     */
     116    DECLCALLBACKMEMBER(void, pfnDecoderStateDestroy, (PRTTRACELOGDECODERHLP pHlp));
     117
     118
     119    /**
     120     * Returns any decoder state created previously with RTTRACELOGDECODERHLP::pfnDecoderStateCreate().
     121     *
     122     * @returns Pointer to the decoder state or NULL if none was created yet.
     123     * @param   pHlp        Pointer to the callback structure.
     124     */
     125    DECLCALLBACKMEMBER(void*, pfnDecoderStateGet, (PRTTRACELOGDECODERHLP pHlp));
     126
     127
     128    /** End marker (DBGCCMDHLP_MAGIC). */
     129    uint32_t                u32EndMarker;
     130} RTTRACELOGDECODERHLP;
     131
     132/** Magic value for RTTRACELOGDECODERHLP::u32Magic and RTTRACELOGDECODERHLP::u32EndMarker. (Bernhard-Viktor Christoph-Carl von Buelow) */
     133#define DBGCCMDHLP_MAGIC    UINT32_C(0x19231112)
    45134
    46135
     
    82171 *
    83172 * @returns IPRT status code.
     173 * @param   pHlp                The decoder helper callback table.
     174 * @param   idDecodeEvt         Event decoder ID given in RTTRACELOGDECODEEVT::idDecodeEvt for the particular event ID.
    84175 * @param   hTraceLogEvt        The tracelog event handle called for decoding.
    85176 * @param   pEvtDesc            The event descriptor.
     
    87178 * @param   cVals               Number of values in the array.
    88179 */
    89 typedef DECLCALLBACKTYPE(int, FNTRACELOGDECODEREVENTDECODE,(RTTRACELOGRDREVT hTraceLogEvt, PCRTTRACELOGEVTDESC pEvtDesc,
     180typedef DECLCALLBACKTYPE(int, FNTRACELOGDECODEREVENTDECODE,(PRTTRACELOGDECODERHLP pHlp, uint32_t idDecodeEvt,
     181                                                            RTTRACELOGRDREVT hTraceLogEvt, PCRTTRACELOGEVTDESC pEvtDesc,
    90182                                                            PRTTRACELOGEVTVAL paVals, uint32_t cVals));
    91183/** Pointer to an event decode callback. */
     
    93185
    94186
    95 typedef struct RTTRACELOGDECODERDECODEEVENT
    96 {
    97     /** The event ID to register the decoder for. */
    98     const char                    *pszId;
     187/**
     188 * Event decoder entry.
     189 */
     190typedef struct RTTRACELOGDECODEEVT
     191{
     192    /** The event ID name. */
     193    const char *pszEvtId;
     194    /** The decoder event ID ordinal to pass to in the decode callback for
     195     * faster lookup. */
     196    uint32_t   idDecodeEvt;
     197} RTTRACELOGDECODEEVT;
     198/** Pointer to an event decoder entry. */
     199typedef RTTRACELOGDECODEEVT *PRTTRACELOGDECODEEVT;
     200/** Pointer to a const event decoder entry. */
     201typedef const RTTRACELOGDECODEEVT *PCRTTRACELOGDECODEEVT;
     202
     203
     204/**
     205 * A decoder registration structure.
     206 */
     207typedef struct RTTRACELOGDECODERREG
     208{
     209    /** Decoder name. */
     210    const char                    *pszName;
     211    /** Decoder description. */
     212    const char                    *pszDesc;
     213    /** The event IDs to register the decoder for. */
     214    PCRTTRACELOGDECODEEVT         paEvtIds;
    99215    /** The decode callback. */
    100216    PFNTRACELOGDECODEREVENTDECODE pfnDecode;
    101 } RTTRACELOGDECODERDECODEEVENT;
    102 typedef RTTRACELOGDECODERDECODEEVENT *PRTTRACELOGDECODERDECODEEVENT;
    103 typedef const RTTRACELOGDECODERDECODEEVENT *PCRTTRACELOGDECODERDECODEEVENT;
     217} RTTRACELOGDECODERREG;
     218/** Pointer to a decoder registration structure. */
     219typedef RTTRACELOGDECODERREG *PRTTRACELOGDECODERREG;
     220/** Pointer to a const decoder registration structure. */
     221typedef const RTTRACELOGDECODERREG *PCRTTRACELOGDECODERREG;
    104222
    105223
     
    121239     * @param   cDecoders   Number of entries in the array.
    122240     */
    123     DECLR3CALLBACKMEMBER(int, pfnRegisterDecoders, (void *pvUser, PCRTTRACELOGDECODERDECODEEVENT paDecoders, uint32_t cDecoders));
     241    DECLR3CALLBACKMEMBER(int, pfnRegisterDecoders, (void *pvUser, PCRTTRACELOGDECODERREG paDecoders, uint32_t cDecoders));
    124242
    125243} RTTRACELOGDECODERREGISTER;
  • trunk/src/VBox/Devices/Trace/VBoxTraceLogDecoders.cpp

    r104919 r104920  
    4646/**
    4747 */
    48 typedef DECLCALLBACKTYPE(void, FNDECODETPM2CC, (PCTPMREQHDR pHdr, size_t cb));
     48typedef DECLCALLBACKTYPE(void, FNDECODETPM2CC, (PRTTRACELOGDECODERHLP pHlp, PCTPMREQHDR pHdr, size_t cb));
    4949/** Pointer to an event decode callback. */
    5050typedef FNDECODETPM2CC *PFNFNDECODETPM2CC;
     
    6060*********************************************************************************************************************************/
    6161
    62 static DECLCALLBACK(void) vboxTraceLogDecodeEvtTpmDecodeStartupShutdown(PCTPMREQHDR pHdr, size_t cb)
     62static DECLCALLBACK(void) vboxTraceLogDecodeEvtTpmDecodeStartupShutdown(PRTTRACELOGDECODERHLP pHlp, PCTPMREQHDR pHdr, size_t cb)
    6363{
    6464    if (cb >= sizeof(uint16_t))
     
    7474    }
    7575
    76     RTMsgError("Malformed TPM2_CC_STARTUP/TPM2_CC_SHUTDOWN command, not enough room for TPM_SU constant\n");
     76    pHlp->pfnErrorMsg(pHlp, "Malformed TPM2_CC_STARTUP/TPM2_CC_SHUTDOWN command, not enough room for TPM_SU constant\n");
    7777}
    7878
     
    9797};
    9898
    99 static DECLCALLBACK(void) vboxTraceLogDecodeEvtTpmDecodeGetCapability(PCTPMREQHDR pHdr, size_t cb)
     99static DECLCALLBACK(void) vboxTraceLogDecodeEvtTpmDecodeGetCapability(PRTTRACELOGDECODERHLP pHlp, PCTPMREQHDR pHdr, size_t cb)
    100100{
    101101    if (cb >= sizeof(TPM2REQGETCAPABILITY))
     
    118118    }
    119119
    120     RTMsgError("Malformed TPM2_CC_GET_CAPABILITY command, not enough room for the input\n");
    121 }
    122 
    123 
    124 static DECLCALLBACK(void) vboxTraceLogDecodeEvtTpmDecodeReadPublic(PCTPMREQHDR pHdr, size_t cb)
     120    pHlp->pfnErrorMsg(pHlp, "Malformed TPM2_CC_GET_CAPABILITY command, not enough room for the input\n");
     121}
     122
     123
     124static DECLCALLBACK(void) vboxTraceLogDecodeEvtTpmDecodeReadPublic(PRTTRACELOGDECODERHLP pHlp, PCTPMREQHDR pHdr, size_t cb)
    125125{
    126126    if (cb >= sizeof(TPM2REQREADPUBLIC))
     
    132132    }
    133133
    134     RTMsgError("Malformed TPM2_CC_READ_PUBLIC command, not enough room for the input\n");
     134    pHlp->pfnErrorMsg(pHlp, "Malformed TPM2_CC_READ_PUBLIC command, not enough room for the input\n");
    135135}
    136136
     
    271271};
    272272
    273 static void vboxTraceLogDecodeEvtTpmDecodeCmdBuffer(const uint8_t *pbCmd, size_t cbCmd)
     273static void vboxTraceLogDecodeEvtTpmDecodeCmdBuffer(PRTTRACELOGDECODERHLP pHlp, const uint8_t *pbCmd, size_t cbCmd)
    274274{
    275275    PCTPMREQHDR pHdr = (PCTPMREQHDR)pbCmd;
     
    283283                RTMsgInfo("    %s:\n", s_aTpmCmdCodes[i].pszCmdCode);
    284284                if (s_aTpmCmdCodes[i].pfnDecode)
    285                     s_aTpmCmdCodes[i].pfnDecode(pHdr, RT_BE2H_U32(pHdr->cbReq));
     285                    s_aTpmCmdCodes[i].pfnDecode(pHlp, pHdr, RT_BE2H_U32(pHdr->cbReq));
    286286                return;
    287287            }
     
    294294
    295295
    296 static void vboxTraceLogDecodeEvtTpmDecodeRespBuffer(const uint8_t *pbResp, size_t cbResp)
    297 {
     296static void vboxTraceLogDecodeEvtTpmDecodeRespBuffer(PRTTRACELOGDECODERHLP pHlp, const uint8_t *pbResp, size_t cbResp)
     297{
     298    RT_NOREF(pHlp);
     299
    298300    PCTPMRESPHDR pHdr = (PCTPMRESPHDR)pbResp;
    299301    if (cbResp >= sizeof(*pHdr))
     
    306308
    307309
    308 static DECLCALLBACK(int) vboxTraceLogDecodeEvtTpmCmdExecReq(RTTRACELOGRDREVT hTraceLogEvt, PCRTTRACELOGEVTDESC pEvtDesc,
    309                                                             PRTTRACELOGEVTVAL paVals, uint32_t cVals)
     310static DECLCALLBACK(int) vboxTraceLogDecodeEvtTpm(PRTTRACELOGDECODERHLP pHlp, uint32_t idDecodeEvt, RTTRACELOGRDREVT hTraceLogEvt,
     311                                                  PCRTTRACELOGEVTDESC pEvtDesc, PRTTRACELOGEVTVAL paVals, uint32_t cVals)
    310312{
    311313    RT_NOREF(hTraceLogEvt, pEvtDesc);
    312     for (uint32_t i = 0; i < cVals; i++)
    313     {
    314         /* Look for the pvCmd item which stores the command buffer. */
    315         if (   !strcmp(paVals[i].pItemDesc->pszName, "pvCmd")
    316             && paVals[i].pItemDesc->enmType == RTTRACELOGTYPE_RAWDATA)
     314    if (idDecodeEvt == 0)
     315    {
     316        for (uint32_t i = 0; i < cVals; i++)
    317317        {
    318             vboxTraceLogDecodeEvtTpmDecodeCmdBuffer(paVals[i].u.RawData.pb, paVals[i].u.RawData.cb);
    319             return VINF_SUCCESS;
     318            /* Look for the pvCmd item which stores the command buffer. */
     319            if (   !strcmp(paVals[i].pItemDesc->pszName, "pvCmd")
     320                && paVals[i].pItemDesc->enmType == RTTRACELOGTYPE_RAWDATA)
     321            {
     322                vboxTraceLogDecodeEvtTpmDecodeCmdBuffer(pHlp, paVals[i].u.RawData.pb, paVals[i].u.RawData.cb);
     323                return VINF_SUCCESS;
     324            }
    320325        }
    321     }
    322     RTMsgError("Failed to find the TPM command data buffer for the given event\n");
     326
     327        pHlp->pfnErrorMsg(pHlp, "Failed to find the TPM command data buffer for the given event\n");
     328    }
     329    else if (idDecodeEvt == 1)
     330    {
     331        for (uint32_t i = 0; i < cVals; i++)
     332        {
     333            /* Look for the pvCmd item which stores the response buffer. */
     334            if (   !strcmp(paVals[i].pItemDesc->pszName, "pvResp")
     335                && paVals[i].pItemDesc->enmType == RTTRACELOGTYPE_RAWDATA)
     336            {
     337                vboxTraceLogDecodeEvtTpmDecodeRespBuffer(pHlp, paVals[i].u.RawData.pb, paVals[i].u.RawData.cb);
     338                return VINF_SUCCESS;
     339            }
     340        }
     341        pHlp->pfnErrorMsg(pHlp, "Failed to find the TPM command response buffer for the given event\n");
     342    }
     343
     344    pHlp->pfnErrorMsg(pHlp, "Decode event ID %u is not known to this decoder\n", idDecodeEvt);
    323345    return VERR_NOT_FOUND;
    324346}
    325347
    326348
    327 static DECLCALLBACK(int) vboxTraceLogDecodeEvtTpmCmdExecResp(RTTRACELOGRDREVT hTraceLogEvt, PCRTTRACELOGEVTDESC pEvtDesc,
    328                                                              PRTTRACELOGEVTVAL paVals, uint32_t cVals)
    329 {
    330     RT_NOREF(hTraceLogEvt, pEvtDesc);
    331     for (uint32_t i = 0; i < cVals; i++)
    332     {
    333         /* Look for the pvCmd item which stores the response buffer. */
    334         if (   !strcmp(paVals[i].pItemDesc->pszName, "pvResp")
    335             && paVals[i].pItemDesc->enmType == RTTRACELOGTYPE_RAWDATA)
    336         {
    337             vboxTraceLogDecodeEvtTpmDecodeRespBuffer(paVals[i].u.RawData.pb, paVals[i].u.RawData.cb);
    338             return VINF_SUCCESS;
    339         }
    340     }
    341     RTMsgError("Failed to find the TPM command data buffer for the given event\n");
    342     return VERR_NOT_FOUND;
    343 }
    344 
    345 
    346349/**
    347  * Filter plugin interface.
    348  */
    349 const RTTRACELOGDECODERDECODEEVENT g_aTraceLogDecode[] =
    350 {
    351     { "ITpmConnector.CmdExecReq",  vboxTraceLogDecodeEvtTpmCmdExecReq  },
    352     { "ITpmConnector.CmdExecResp", vboxTraceLogDecodeEvtTpmCmdExecResp },
     350 * TPM decoder event IDs.
     351 */
     352static const RTTRACELOGDECODEEVT s_aDecodeEvtTpm[] =
     353{
     354    { "ITpmConnector.CmdExecReq",  0          },
     355    { "ITpmConnector.CmdExecResp", 1          },
     356    { NULL,                        UINT32_MAX }
     357};
     358
     359
     360/**
     361 * Decoder plugin interface.
     362 */
     363static const RTTRACELOGDECODERREG g_TraceLogDecoderTpm =
     364{
     365    /** pszName */
     366    "TPM",
     367    /** pszDesc */
     368    "Decodes events from the ITpmConnector interface generated with the IfTrace driver.",
     369    /** paEvtIds */
     370    s_aDecodeEvtTpm,
     371    /** pfnDecode */
     372    vboxTraceLogDecodeEvtTpm,
    353373};
    354374
     
    364384                          VERR_VERSION_MISMATCH);
    365385
    366     return pRegisterCallbacks->pfnRegisterDecoders(pvUser, &g_aTraceLogDecode[0], RT_ELEMENTS(g_aTraceLogDecode));
    367 }
    368 
     386    return pRegisterCallbacks->pfnRegisterDecoders(pvUser, &g_TraceLogDecoderTpm, 1);
     387}
     388
  • trunk/src/VBox/Runtime/tools/RTTraceLogTool.cpp

    r104892 r104920  
    5555
    5656
     57typedef struct RTTRACELOGDECODER
     58{
     59    /** The tracelog decoder registration structure. */
     60    PCRTTRACELOGDECODERREG      pReg;
     61    /** The helper structure for this decoder. */
     62    RTTRACELOGDECODERHLP        Hlp;
     63    /** The decoder state if created. */
     64    void                        *pvDecoderState;
     65    /** The free callback of any attached decoder state. */
     66    PFNTRACELOGDECODERSTATEFREE pfnDecoderStateFree;
     67} RTTRACELOGDECODER;
     68typedef RTTRACELOGDECODER *PRTTRACELOGDECODER;
     69typedef const RTTRACELOGDECODER *PCRTTRACELOGDECODER;
     70
     71
    5772/**
    5873 * Loaded tracelog decoders.
    5974 */
    60 typedef struct RTTRACELOGDECODERS
     75typedef struct RTTRACELOGDECODERSTATE
    6176{
    6277    /** Pointer to the array of registered decoders. */
    63     PRTTRACELOGDECODERDECODEEVENT paDecodeEvts;
     78    PRTTRACELOGDECODER            paDecoders;
    6479    /** Number of entries in the decoder array. */
    6580    uint32_t                      cDecoders;
    6681    /** Allocation size of the decoder array. */
    6782    uint32_t                      cDecodersAlloc;
    68 } RTTRACELOGDECODERS;
    69 typedef RTTRACELOGDECODERS *PRTTRACELOGDECODERS;
     83} RTTRACELOGDECODERSTATE;
     84typedef RTTRACELOGDECODERSTATE *PRTTRACELOGDECODERSTATE;
    7085
    7186
     
    191206
    192207
    193 static DECLCALLBACK(int) rtTraceLogToolRegisterDecoders(void *pvUser, PCRTTRACELOGDECODERDECODEEVENT paDecoders, uint32_t cDecoders)
    194 {
    195     PRTTRACELOGDECODERS pDecoderState = (PRTTRACELOGDECODERS)pvUser;
     208static DECLCALLBACK(int) rtTraceLogToolDecoderHlpPrintf(PRTTRACELOGDECODERHLP pHlp, const char *pszFormat, ...)
     209                                                       RT_IPRT_FORMAT_ATTR(3, 4)
     210{
     211    RT_NOREF(pHlp);
     212    va_list Args;
     213    va_start(Args, pszFormat);
     214    int rc = RTMsgInfoV(pszFormat, Args);
     215    va_end(Args);
     216    return rc;
     217}
     218
     219
     220static DECLCALLBACK(int) rtTraceLogToolDecoderHlpErrorMsg(PRTTRACELOGDECODERHLP pHlp, const char *pszFormat, ...)
     221                                                         RT_IPRT_FORMAT_ATTR(3, 4)
     222{
     223    RT_NOREF(pHlp);
     224    va_list Args;
     225    va_start(Args, pszFormat);
     226    int rc = RTMsgErrorV(pszFormat, Args);
     227    va_end(Args);
     228    return rc;
     229}
     230
     231
     232static DECLCALLBACK(int) rtTraceLogToolDecoderHlpStateCreate(PRTTRACELOGDECODERHLP pHlp, size_t cbState, PFNTRACELOGDECODERSTATEFREE pfnFree,
     233                                                          void **ppvState)
     234{
     235    PRTTRACELOGDECODER pDecoder = RT_FROM_MEMBER(pHlp, RTTRACELOGDECODER, Hlp);
     236
     237    if (pDecoder->pvDecoderState)
     238    {
     239        if (pDecoder->pfnDecoderStateFree)
     240            pDecoder->pfnDecoderStateFree(pHlp, pDecoder->pvDecoderState);
     241        RTMemFree(pDecoder->pvDecoderState);
     242        pDecoder->pvDecoderState      = NULL;
     243        pDecoder->pfnDecoderStateFree = NULL;
     244    }
     245
     246    pDecoder->pvDecoderState = RTMemAllocZ(cbState);
     247    if (pDecoder->pvDecoderState)
     248    {
     249        pDecoder->pfnDecoderStateFree = pfnFree;
     250        *ppvState = pDecoder->pvDecoderState;
     251        return VINF_SUCCESS;
     252    }
     253
     254    return VERR_NO_MEMORY;
     255}
     256
     257
     258static DECLCALLBACK(void) rtTraceLogToolDecoderHlpStateDestroy(PRTTRACELOGDECODERHLP pHlp)
     259{
     260    PRTTRACELOGDECODER pDecoder = RT_FROM_MEMBER(pHlp, RTTRACELOGDECODER, Hlp);
     261
     262    if (pDecoder->pvDecoderState)
     263    {
     264        if (pDecoder->pfnDecoderStateFree)
     265            pDecoder->pfnDecoderStateFree(pHlp, pDecoder->pvDecoderState);
     266        RTMemFree(pDecoder->pvDecoderState);
     267        pDecoder->pvDecoderState      = NULL;
     268        pDecoder->pfnDecoderStateFree = NULL;
     269    }
     270}
     271
     272
     273static DECLCALLBACK(void*) rtTraceLogToolDecoderHlpStateGet(PRTTRACELOGDECODERHLP pHlp)
     274{
     275    PRTTRACELOGDECODER pDecoder = RT_FROM_MEMBER(pHlp, RTTRACELOGDECODER, Hlp);
     276
     277    return pDecoder->pvDecoderState;
     278}
     279
     280
     281static DECLCALLBACK(int) rtTraceLogToolRegisterDecoders(void *pvUser, PCRTTRACELOGDECODERREG paDecoders, uint32_t cDecoders)
     282{
     283    PRTTRACELOGDECODERSTATE pDecoderState = (PRTTRACELOGDECODERSTATE)pvUser;
    196284
    197285    if (pDecoderState->cDecodersAlloc - pDecoderState->cDecoders <= cDecoders)
    198286    {
    199         PRTTRACELOGDECODERDECODEEVENT paNew = (PRTTRACELOGDECODERDECODEEVENT)RTMemRealloc(pDecoderState->paDecodeEvts,
    200                                                                                           (pDecoderState->cDecodersAlloc + cDecoders) * sizeof(*paDecoders));
     287        PRTTRACELOGDECODER paNew = (PRTTRACELOGDECODER)RTMemRealloc(pDecoderState->paDecoders,
     288                                                                    (pDecoderState->cDecodersAlloc + cDecoders) * sizeof(*paNew));
    201289        if (!paNew)
    202290            return VERR_NO_MEMORY;
    203291
    204         pDecoderState->paDecodeEvts    = paNew;
     292        pDecoderState->paDecoders      = paNew;
    205293        pDecoderState->cDecodersAlloc += cDecoders;
    206294    }
    207295
    208     memcpy(&pDecoderState->paDecodeEvts[pDecoderState->cDecoders], paDecoders, cDecoders * sizeof(*paDecoders));
     296    for (uint32_t i = 0; i < cDecoders; i++)
     297    {
     298        PRTTRACELOGDECODER pDecoder = &pDecoderState->paDecoders[i];
     299
     300        pDecoder->pReg                       = &paDecoders[i];
     301        pDecoder->pvDecoderState             = NULL;
     302        pDecoder->pfnDecoderStateFree        = NULL;
     303        pDecoder->Hlp.pfnPrintf              = rtTraceLogToolDecoderHlpPrintf;
     304        pDecoder->Hlp.pfnErrorMsg            = rtTraceLogToolDecoderHlpErrorMsg;
     305        pDecoder->Hlp.pfnDecoderStateCreate  = rtTraceLogToolDecoderHlpStateCreate;
     306        pDecoder->Hlp.pfnDecoderStateDestroy = rtTraceLogToolDecoderHlpStateDestroy;
     307        pDecoder->Hlp.pfnDecoderStateGet     = rtTraceLogToolDecoderHlpStateGet;
     308    }
     309
    209310    pDecoderState->cDecoders += cDecoders;
    210311    return VINF_SUCCESS;
     
    230331    };
    231332
    232     RTEXITCODE          rcExit   = RTEXITCODE_SUCCESS;
    233     const char         *pszInput = NULL;
    234     const char         *pszSave  = NULL;
    235     RTTRACELOGDECODERS  Decoders; RT_ZERO(Decoders);
     333    RTEXITCODE              rcExit   = RTEXITCODE_SUCCESS;
     334    const char             *pszInput = NULL;
     335    const char             *pszSave  = NULL;
     336    RTTRACELOGDECODERSTATE  DecoderState; RT_ZERO(DecoderState);
    236337
    237338    RTGETOPTUNION   ValueUnion;
     
    283384                        RegCb.pfnRegisterDecoders = rtTraceLogToolRegisterDecoders;
    284385
    285                         rc = pfnLoad(&Decoders, &RegCb);
     386                        rc = pfnLoad(&DecoderState, &RegCb);
    286387                        if (RT_FAILURE(rc))
    287388                            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to register decoders %Rrc\n", rc);
     
    342443                             * If there is no decoder registered just dump the raw values.
    343444                             */
    344                             PCRTTRACELOGDECODERDECODEEVENT pDecodeEvt = NULL;
    345                             for (uint32_t i = 0; i < Decoders.cDecoders; i++)
    346                                 if (!strcmp(Decoders.paDecodeEvts[i].pszId, pEvtDesc->pszId))
     445                            PRTTRACELOGDECODER    pDecoder = NULL;
     446                            PCRTTRACELOGDECODEEVT pDecodeEvt  = NULL;
     447                            for (uint32_t i = 0; (i < DecoderState.cDecoders) && !pDecoder; i++)
     448                            {
     449                                PCRTTRACELOGDECODEEVT pTmp = DecoderState.paDecoders[i].pReg->paEvtIds;
     450                                while (pTmp->pszEvtId)
    347451                                {
    348                                     pDecodeEvt = &Decoders.paDecodeEvts[i];
    349                                     break;
     452                                    if (!strcmp(pTmp->pszEvtId, pEvtDesc->pszId))
     453                                    {
     454                                        pDecoder   = &DecoderState.paDecoders[i];
     455                                        pDecodeEvt = pTmp;
     456                                        break;
     457                                    }
     458                                    pTmp++;
    350459                                }
    351 
    352                             if (pDecodeEvt)
     460                            }
     461
     462                            if (pDecoder)
    353463                            {
     464                                Assert(pDecodeEvt);
     465
    354466                                /** @todo Dynamic value allocation (too lazy right now). */
    355467                                RTTRACELOGEVTVAL aVals[32];
     
    360472                                    || cVals != pEvtDesc->cEvtItems)
    361473                                {
    362                                     rc = pDecodeEvt->pfnDecode(hTraceLogEvt, pEvtDesc, &aVals[0], cVals);
     474                                    rc = pDecoder->pReg->pfnDecode(&pDecoder->Hlp, pDecodeEvt->idDecodeEvt, hTraceLogEvt,
     475                                                                   pEvtDesc, &aVals[0], cVals);
    363476                                    if (RT_FAILURE(rc))
    364477                                        RTMsgError("Failed to decode event with ID '%s' -> %Rrc\n", pEvtDesc->pszId, rc);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette