CE CHECK

From Texas Instruments Embedded Processors Wiki

Jump to: navigation, search


  • Image:Google-16x16.png Search for an article here:


Contents

Introduction

The CE_CHECK feature lets the user set one simple environment variable and enable extra parameter validation between the application and algorithms. This will catch malformed structures, fields, etc., and can be a useful debugging technique.

As newer releases are made available more checking may be enabled to help catch other common mistakes.

Note - this CE_CHECK environment variable feature is available in CE 2.20 and later. Prior to that, CE 1.20 and later do support this 'checking' feature, but enabling it must be done at config time - which unfortunately requires a reconfig/rebuild. The .cfg script snippet for enabling checked builds in those releases is here:

xdc.useModule('ti.sdo.ce.Settings').checked = true;

Usage

Setting CE_CHECK=1 before running the Codec Engine-based application, without any other preparation in the build or the code, sets a flag in the system that VISA APIs (and custom APIs, if so instrumented) can leverage to do additional parameter checking. Any errors identified are printed on standard output.

Note - prior to CE 2.25, the user also had to enable "error tracing" (level 7) to see these errors. This is typically done by also setting CE_DEBUG to '1'. In CE 2.25 and later, setting CE_CHECK=1 will also enable the error trace level.

Instrumenting your Custom APIs

If you have a custom API, you can add 'checking' support to your libraries as well, by calling VISA_isChecked() function. It returns TRUE if checking is enabled.

Example Implementation

As an example, the implementation of IMGENC1_process() is included here.

Note that the VISA classes further utilize some CE-internal XDM-specific utility services (i.e. XdmUtils_ APIs) to do common tests. The sources for these utility classes are distributed with the Codec Engine releases if you want to explore them further. Further note that these XdmUtils_ APIs are considered internal APIs and therefore subject to change without notice.

/*
 *  ======== IMGENC1_process ========
 *  This method must be the same for both local and remote invocation;
 *  each call site in the client might be calling different implementations
 *  (one that marshalls & sends and one that simply calls).  This API
 *  abstracts *all* image encoders (both high and low complexity
 *  encoders are invoked using this method).
 */
XDAS_Int32 IMGENC1_process(IMGENC1_Handle handle, XDM1_BufDesc *inBufs,
    XDM1_BufDesc *outBufs, IIMGENC1_InArgs *inArgs, IIMGENC1_OutArgs *outArgs)
{
    XDAS_Int32 retVal = IMGENC1_EFAIL;
 
    IMGENC1_InArgs refInArgs;
 
    /*
     * Note, we assign "VISA_isChecked()" results to a local variable
     * rather than repeatedly query it throughout this fxn because
     * someday we may allow dynamically changing the global
     * 'VISA_isChecked()' value on the fly.  If we allow that, we need
     * to ensure the value stays consistent in the context of this
     * call.
     */
    Bool checked = VISA_isChecked();
 
    if (checked) {
        /* Ensure inArgs and outArgs are non-NULL, per the xDM spec */
 
        if ((!(XdmUtils_validateExtendedStruct(inArgs, sizeof(inArgs),
                "inArgs"))) || (!(XdmUtils_validateExtendedStruct(outArgs,
                sizeof(outArgs), "outArgs")))) {
            /* for safety, return here before dereferencing and crashing */
            return (retVal);
        }
    }
 
    GT_5trace(CURTRACE, GT_ENTER, "IMGENC1_process> "
        "Enter (handle=0x%x, inBufs=0x%x, outBufs=0x%x, inArgs=0x%x, "
        "outArgs=0x%x)\n", handle, inBufs, outBufs, inArgs, outArgs);
 
    if (handle) {
        IIMGENC1_Fxns *fxns =
            (IIMGENC1_Fxns *)VISA_getAlgFxns((VISA_Handle)handle);
        IIMGENC1_Handle alg = VISA_getAlgHandle((VISA_Handle)handle);
 
        if (fxns && (alg != NULL)) {
            Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"IMGENC1:process",
                (Arg)handle, (Arg)0);
 
            if (checked) {
 
                /*
                 * Validate inBufs and outBufs.
                 */
                XdmUtils_validateSparseBufDesc1(inBufs, "inBufs");
                XdmUtils_validateSparseBufDesc1(outBufs, "outBufs");
 
                /*
                 * Zero out the outArgs struct (except for .size field);
                 * it's write-only to the codec, so the app shouldn't pass
                 * values through it, nor should the codec expect to
                 * receive values through it.
                 */
                memset((void *)((XDAS_Int32)(outArgs) + sizeof(outArgs->size)),
                    0, (sizeof(*outArgs) - sizeof(outArgs->size)));
 
                /*
                 * Make a reference copy of inArgs so we can check that
                 * the codec didn't modify them during process().
                 */
                refInArgs = *inArgs;
            }
 
            VISA_enter((VISA_Handle)handle);
            retVal = fxns->process(alg, inBufs, outBufs, inArgs, outArgs);
            VISA_exit((VISA_Handle)handle);
 
            if (checked) {
                /* ensure the codec didn't modify the read-only inArgs */
                if (memcmp(&refInArgs, inArgs, sizeof(*inArgs)) != 0) {
                    GT_1trace(CURTRACE, GT_7CLASS,
                        "ERROR> codec (0x%x) modified read-only inArgs "
                        "struct!\n", handle);
                }
            }
 
        }
    }
 
    GT_2trace(CURTRACE, GT_ENTER, "IMGENC1_process> "
        "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal);
 
    return (retVal);
}


Sample log

TBD (Volunteers willing to post their log file - ideally with tracing displaying any errors caught - are welcome!)

See Also


For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article CE CHECK here.
Leave a Comment

Comments

Re Note that the VISA classes further utilize some CE-internal XDM-specific utility services (i.e. XdmUtils_ APIs) to do common tests. The sources for these utility classes are distributed with the Codec Engine releases if you want to explore them further. Further note that these XdmUtils_ APIs are considered internal APIs and therefore subject to change without notice...

How can non-VISA skeletons/codecs use checked builds in such a case? i.e. how could a codec extending e.g. IUNIVERSAL add checked builds code?

non-VISA classes (that does not include IUNIVERSAL codecs) provide their own APIs/stubs/skels, and can call VISA_isChecked() to determine whether the user enabled checking. They can then add whatever checking makes sense for their class of algorithm. For example, in the CE example scale extension API, it could check that the buffers are "correctly formed" (perhaps re-using XdmUtils_ APIs).
As far as IUNIVERSAL algs, those are loosely a "VISA class" as the interface is defined by XDM and supported by Codec Engine. In that particular case, IUNIVERSAL doesn't know what's 'correct' or not, so alg-specific checking is not supported. As with other VISA APIs, the system integrator can plug in their own stubs/skels that include checking, but it's not provided out of the box.
If this is a common customer request, CE could perhaps add something like a "configurable checked callback" fxn that could be configured and called... but there hasn't been significant customer interest in this to date.
ChrisRing 15:03, 9 February 2009 (MST)
Personal tools