VirtualBox

Changeset 77693 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 13, 2019 9:24:29 PM (6 years ago)
Author:
vboxsync
Message:

Runtime/fuzz: Some more statistics, add possibility to configure the environment of the target process through the job config, add possibility to read SanitizerCoverage generated reports to scan for changes in executed paths for inputs to evaluate which mutations are interesting for further use

Location:
trunk/src/VBox/Runtime/common/fuzz
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fuzz/fuzz-observer.cpp

    r77544 r77693  
    112112    /** The binary to run. */
    113113    char                       *pszBinary;
     114    /** The filename path of the binary. */
     115    const char                 *pszBinaryFilename;
    114116    /** Arguments to run the binary with, terminated by a NULL entry. */
    115117    char                      **papszArgs;
     118    /** The environment to use for the target. */
     119    RTENV                       hEnv;
     120    /** Any configured sanitizers. */
     121    uint32_t                    fSanitizers;
     122    /** Sanitizer related options set in the environment block. */
     123    char                       *pszSanitizerOpts;
    116124    /** Number of arguments. */
    117125    uint32_t                    cArgs;
     
    167175    /** The pollset to monitor. */
    168176    RTPOLLSET                   hPollSet;
     177    /** The environment block to use. */
     178    RTENV                       hEnv;
    169179    /** The process to monitor. */
    170180    RTPROCESS                   hProc;
     
    335345        pExecCtx->msExec           = 0;
    336346
    337         rc = RTFuzzTgtRecorderCreateNewState(pThis->hTgtRec, &pExecCtx->hTgtState);
     347        rc = RTEnvClone(&pExecCtx->hEnv, pThis->hEnv);
    338348        if (RT_SUCCESS(rc))
    339349        {
    340             rc = RTPollSetCreate(&pExecCtx->hPollSet);
     350            rc = RTFuzzTgtRecorderCreateNewState(pThis->hTgtRec, &pExecCtx->hTgtState);
    341351            if (RT_SUCCESS(rc))
    342352            {
    343                 rc = RTPipeCreate(&pExecCtx->hPipeStdoutR, &pExecCtx->hPipeStdoutW, RTPIPE_C_INHERIT_WRITE);
     353                rc = RTPollSetCreate(&pExecCtx->hPollSet);
    344354                if (RT_SUCCESS(rc))
    345355                {
    346                     RTHANDLE Handle;
    347                     Handle.enmType = RTHANDLETYPE_PIPE;
    348                     Handle.u.hPipe = pExecCtx->hPipeStdoutR;
    349                     rc = RTPollSetAdd(pExecCtx->hPollSet, &Handle, RTPOLL_EVT_READ, RTFUZZOBS_EXEC_CTX_POLL_ID_STDOUT);
    350                     AssertRC(rc);
    351 
    352                     rc = RTPipeCreate(&pExecCtx->hPipeStderrR, &pExecCtx->hPipeStderrW, RTPIPE_C_INHERIT_WRITE);
     356                    rc = RTPipeCreate(&pExecCtx->hPipeStdoutR, &pExecCtx->hPipeStdoutW, RTPIPE_C_INHERIT_WRITE);
    353357                    if (RT_SUCCESS(rc))
    354358                    {
    355                         Handle.u.hPipe = pExecCtx->hPipeStderrR;
    356                         rc = RTPollSetAdd(pExecCtx->hPollSet, &Handle, RTPOLL_EVT_READ, RTFUZZOBS_EXEC_CTX_POLL_ID_STDERR);
     359                        RTHANDLE Handle;
     360                        Handle.enmType = RTHANDLETYPE_PIPE;
     361                        Handle.u.hPipe = pExecCtx->hPipeStdoutR;
     362                        rc = RTPollSetAdd(pExecCtx->hPollSet, &Handle, RTPOLL_EVT_READ, RTFUZZOBS_EXEC_CTX_POLL_ID_STDOUT);
    357363                        AssertRC(rc);
    358364
    359                         /* Create the stdin pipe handles if not a file input. */
    360                         if (pThis->enmInputChan == RTFUZZOBSINPUTCHAN_STDIN || pThis->enmInputChan == RTFUZZOBSINPUTCHAN_FUZZING_AWARE_CLIENT)
     365                        rc = RTPipeCreate(&pExecCtx->hPipeStderrR, &pExecCtx->hPipeStderrW, RTPIPE_C_INHERIT_WRITE);
     366                        if (RT_SUCCESS(rc))
    361367                        {
    362                             rc = RTPipeCreate(&pExecCtx->hPipeStdinR, &pExecCtx->hPipeStdinW, RTPIPE_C_INHERIT_READ);
     368                            Handle.u.hPipe = pExecCtx->hPipeStderrR;
     369                            rc = RTPollSetAdd(pExecCtx->hPollSet, &Handle, RTPOLL_EVT_READ, RTFUZZOBS_EXEC_CTX_POLL_ID_STDERR);
     370                            AssertRC(rc);
     371
     372                            /* Create the stdin pipe handles if not a file input. */
     373                            if (pThis->enmInputChan == RTFUZZOBSINPUTCHAN_STDIN || pThis->enmInputChan == RTFUZZOBSINPUTCHAN_FUZZING_AWARE_CLIENT)
     374                            {
     375                                rc = RTPipeCreate(&pExecCtx->hPipeStdinR, &pExecCtx->hPipeStdinW, RTPIPE_C_INHERIT_READ);
     376                                if (RT_SUCCESS(rc))
     377                                {
     378                                    pExecCtx->StdinHandle.enmType = RTHANDLETYPE_PIPE;
     379                                    pExecCtx->StdinHandle.u.hPipe = pExecCtx->hPipeStdinR;
     380
     381                                    Handle.u.hPipe = pExecCtx->hPipeStdinW;
     382                                    rc = RTPollSetAdd(pExecCtx->hPollSet, &Handle, RTPOLL_EVT_WRITE, RTFUZZOBS_EXEC_CTX_POLL_ID_STDIN);
     383                                    AssertRC(rc);
     384                                }
     385                            }
     386                            else
     387                            {
     388                                pExecCtx->StdinHandle.enmType = RTHANDLETYPE_PIPE;
     389                                pExecCtx->StdinHandle.u.hPipe = NIL_RTPIPE;
     390                            }
     391
    363392                            if (RT_SUCCESS(rc))
    364393                            {
    365                                 pExecCtx->StdinHandle.enmType = RTHANDLETYPE_PIPE;
    366                                 pExecCtx->StdinHandle.u.hPipe = pExecCtx->hPipeStdinR;
    367 
    368                                 Handle.u.hPipe = pExecCtx->hPipeStdinW;
    369                                 rc = RTPollSetAdd(pExecCtx->hPollSet, &Handle, RTPOLL_EVT_WRITE, RTFUZZOBS_EXEC_CTX_POLL_ID_STDIN);
    370                                 AssertRC(rc);
     394                                pExecCtx->StdoutHandle.enmType = RTHANDLETYPE_PIPE;
     395                                pExecCtx->StdoutHandle.u.hPipe = pExecCtx->hPipeStdoutW;
     396                                pExecCtx->StderrHandle.enmType = RTHANDLETYPE_PIPE;
     397                                pExecCtx->StderrHandle.u.hPipe = pExecCtx->hPipeStderrW;
     398                                *ppExecCtx = pExecCtx;
     399                                return VINF_SUCCESS;
    371400                            }
     401
     402                            RTPipeClose(pExecCtx->hPipeStderrR);
     403                            RTPipeClose(pExecCtx->hPipeStderrW);
    372404                        }
    373                         else
    374                         {
    375                             pExecCtx->StdinHandle.enmType = RTHANDLETYPE_PIPE;
    376                             pExecCtx->StdinHandle.u.hPipe = NIL_RTPIPE;
    377                         }
    378 
    379                         if (RT_SUCCESS(rc))
    380                         {
    381                             pExecCtx->StdoutHandle.enmType = RTHANDLETYPE_PIPE;
    382                             pExecCtx->StdoutHandle.u.hPipe = pExecCtx->hPipeStdoutW;
    383                             pExecCtx->StderrHandle.enmType = RTHANDLETYPE_PIPE;
    384                             pExecCtx->StderrHandle.u.hPipe = pExecCtx->hPipeStderrW;
    385                             *ppExecCtx = pExecCtx;
    386                             return VINF_SUCCESS;
    387                         }
    388 
    389                         RTPipeClose(pExecCtx->hPipeStderrR);
    390                         RTPipeClose(pExecCtx->hPipeStderrW);
     405
     406                        RTPipeClose(pExecCtx->hPipeStdoutR);
     407                        RTPipeClose(pExecCtx->hPipeStdoutW);
    391408                    }
    392409
    393                     RTPipeClose(pExecCtx->hPipeStdoutR);
    394                     RTPipeClose(pExecCtx->hPipeStdoutW);
     410                    RTPollSetDestroy(pExecCtx->hPollSet);
    395411                }
    396412
    397                 RTPollSetDestroy(pExecCtx->hPollSet);
    398             }
    399 
    400             RTFuzzTgtStateRelease(pExecCtx->hTgtState);
     413                RTFuzzTgtStateRelease(pExecCtx->hTgtState);
     414            }
     415
     416            RTEnvDestroy(pExecCtx->hEnv);
    401417        }
    402418
     
    441457    if (pExecCtx->hTgtState != NIL_RTFUZZTGTSTATE)
    442458        RTFuzzTgtStateRelease(pExecCtx->hTgtState);
     459    RTEnvDestroy(pExecCtx->hEnv);
    443460    RTMemFree(pExecCtx);
    444461}
     
    456473static int rtFuzzObsExecCtxClientRun(PRTFUZZOBSINT pThis, PRTFUZZOBSEXECCTX pExecCtx, PRTPROCSTATUS pProcStat)
    457474{
    458     int rc = RTProcCreateEx(pThis->pszBinary, &pExecCtx->apszArgs[0], RTENV_DEFAULT, 0 /*fFlags*/, &pExecCtx->StdinHandle,
     475    int rc = RTProcCreateEx(pThis->pszBinary, &pExecCtx->apszArgs[0], pExecCtx->hEnv, 0 /*fFlags*/, &pExecCtx->StdinHandle,
    459476                            &pExecCtx->StdoutHandle, &pExecCtx->StderrHandle, NULL, NULL, &pExecCtx->hProc);
    460477    if (RT_SUCCESS(rc))
     
    472489                {
    473490                    Assert(fEvtsRecv & RTPOLL_EVT_READ);
    474                     rc = RTFuzzTgtStateAppendStdoutFromPipe(pExecCtx->hTgtState, pExecCtx->hPipeStdoutR);
    475                     AssertRC(rc);
     491                    //rc = RTFuzzTgtStateAppendStdoutFromPipe(pExecCtx->hTgtState, pExecCtx->hPipeStdoutR);
     492                    //AssertRC(rc);
    476493                }
    477494                else if (idEvt == RTFUZZOBS_EXEC_CTX_POLL_ID_STDERR)
    478495                {
    479496                    Assert(fEvtsRecv & RTPOLL_EVT_READ);
    480                     rc = RTFuzzTgtStateAppendStderrFromPipe(pExecCtx->hTgtState, pExecCtx->hPipeStderrR);
    481                     AssertRC(rc);
     497
     498                    /*
     499                     * Can't add the stderr buffer with sancov enabled as it dumps the resulting report file path
     500                     * (which includes the always changing pid) to stderr...
     501                     */
     502                    if (!(pThis->fSanitizers & RTFUZZOBS_SANITIZER_F_SANCOV))
     503                    {
     504                        rc = RTFuzzTgtStateAppendStderrFromPipe(pExecCtx->hTgtState, pExecCtx->hPipeStderrR);
     505                        AssertRC(rc);
     506                    }
     507                    else
     508                    {
     509                        /* Dump to /dev/null. */
     510                        char abBitBucket[_4K];
     511                        size_t cbRead = 0;
     512                        do
     513                        {
     514                            rc = RTPipeRead(pExecCtx->hPipeStderrR, &abBitBucket[0], sizeof(abBitBucket), &cbRead);
     515                        } while (   RT_SUCCESS(rc)
     516                                 && cbRead == sizeof(abBitBucket));
     517                    }
    482518                }
    483519                else if (idEvt == RTFUZZOBS_EXEC_CTX_POLL_ID_STDIN)
     
    508544            rc = RTProcWait(pExecCtx->hProc, RTPROCWAIT_FLAGS_NOBLOCK, pProcStat);
    509545            if (RT_SUCCESS(rc))
     546            {
     547                /* Add the coverage report to the sanitizer if enabled. */
     548                if (pThis->fSanitizers & RTFUZZOBS_SANITIZER_F_SANCOV)
     549                {
     550                    char szSanCovReport[RTPATH_MAX];
     551                    ssize_t cch = RTStrPrintf2(&szSanCovReport[0], sizeof(szSanCovReport),
     552                                               "%s%c%s.%u.sancov",
     553                                               pThis->pszTmpDir, RTPATH_SLASH,
     554                                               pThis->pszBinaryFilename, pExecCtx->hProc);
     555                    Assert(cch > 0); RT_NOREF(cch);
     556                    rc = RTFuzzTgtStateAddSanCovReportFromFile(pExecCtx->hTgtState, &szSanCovReport[0]);
     557                    RTFileDelete(&szSanCovReport[0]);
     558                }
    510559                break;
     560            }
    511561            else
    512562            {
     
    544594static int rtFuzzObsExecCtxClientRunFuzzingAware(PRTFUZZOBSINT pThis, PRTFUZZOBSEXECCTX pExecCtx, PRTPROCSTATUS pProcStat)
    545595{
    546     int rc = RTProcCreateEx(pThis->pszBinary, &pExecCtx->apszArgs[0], RTENV_DEFAULT, 0 /*fFlags*/, &pExecCtx->StdinHandle,
     596    int rc = RTProcCreateEx(pThis->pszBinary, &pExecCtx->apszArgs[0], pExecCtx->hEnv, 0 /*fFlags*/, &pExecCtx->StdinHandle,
    547597                            &pExecCtx->StdoutHandle, &pExecCtx->StderrHandle, NULL, NULL, &pExecCtx->hProc);
    548598    if (RT_SUCCESS(rc))
     
    10011051
    10021052
     1053/**
     1054 * Sets up any configured sanitizers to cooperate with the observer.
     1055 *
     1056 * @returns IPRT status code.
     1057 * @param   pThis               The internal fuzzing observer state.
     1058 */
     1059static int rtFuzzObsSetupSanitizerCfg(PRTFUZZOBSINT pThis)
     1060{
     1061    int rc = VINF_SUCCESS;
     1062    bool fSep = false;
     1063
     1064    if (pThis->fSanitizers & RTFUZZOBS_SANITIZER_F_ASAN)
     1065    {
     1066        /*
     1067         * Need to set abort_on_error=1 in ASAN_OPTIONS or
     1068         * the sanitizer will call exit() instead of abort() and we
     1069         * don't catch invalid memory accesses.
     1070         */
     1071        rc = RTStrAAppend(&pThis->pszSanitizerOpts, "abort_on_error=1");
     1072        fSep = true;
     1073    }
     1074
     1075    if (   RT_SUCCESS(rc)
     1076        && (pThis->fSanitizers & RTFUZZOBS_SANITIZER_F_SANCOV))
     1077    {
     1078        /*
     1079         * The coverage sanitizer will dump coverage information into a file
     1080         * on process exit. Need to configure the directory where to dump it.
     1081         */
     1082        char aszSanCovCfg[_4K];
     1083        ssize_t cch = RTStrPrintf2(&aszSanCovCfg[0], sizeof(aszSanCovCfg),
     1084                                   "%scoverage=1:coverage_dir=%s",
     1085                                   fSep ? ":" : "", pThis->pszTmpDir);
     1086        if (cch > 0)
     1087            rc = RTStrAAppend(&pThis->pszSanitizerOpts, &aszSanCovCfg[0]);
     1088        else
     1089            rc = VERR_BUFFER_OVERFLOW;
     1090        fSep = true;
     1091    }
     1092
     1093    if (   RT_SUCCESS(rc)
     1094        && pThis->pszSanitizerOpts)
     1095    {
     1096        /* Add it to the environment. */
     1097        if (pThis->hEnv == RTENV_DEFAULT)
     1098        {
     1099            /* Clone the environment to keep the default one untouched. */
     1100            rc = RTEnvClone(&pThis->hEnv, RTENV_DEFAULT);
     1101        }
     1102        if (RT_SUCCESS(rc))
     1103            rc = RTEnvSetEx(pThis->hEnv, "ASAN_OPTIONS", pThis->pszSanitizerOpts);
     1104    }
     1105
     1106    return rc;
     1107}
     1108
     1109
    10031110RTDECL(int) RTFuzzObsCreate(PRTFUZZOBS phFuzzObs, RTFUZZCTXTYPE enmType)
    10041111{
     
    10091116    if (RT_LIKELY(pThis))
    10101117    {
    1011         pThis->pszBinary     = NULL;
    1012         pThis->papszArgs     = NULL;
    1013         pThis->msWaitMax     = 1000;
    1014         pThis->hThreadGlobal = NIL_RTTHREAD;
    1015         pThis->hEvtGlobal    = NIL_RTSEMEVENT;
    1016         pThis->bmEvt         = 0;
    1017         pThis->cThreads      = 0;
    1018         pThis->paObsThreads  = NULL;
    1019         pThis->tsLastStats   = RTTimeMilliTS();
     1118        pThis->pszBinary         = NULL;
     1119        pThis->pszBinaryFilename = NULL;
     1120        pThis->papszArgs         = NULL;
     1121        pThis->hEnv              = RTENV_DEFAULT;
     1122        pThis->msWaitMax         = 1000;
     1123        pThis->hThreadGlobal     = NIL_RTTHREAD;
     1124        pThis->hEvtGlobal        = NIL_RTSEMEVENT;
     1125        pThis->bmEvt             = 0;
     1126        pThis->cThreads          = 0;
     1127        pThis->paObsThreads      = NULL;
     1128        pThis->tsLastStats       = RTTimeMilliTS();
    10201129        pThis->Stats.cFuzzedInputsPerSec = 0;
    10211130        pThis->Stats.cFuzzedInputs       = 0;
     
    10651174    if (pThis->pszBinary)
    10661175        RTStrFree(pThis->pszBinary);
     1176    if (pThis->pszSanitizerOpts)
     1177        RTStrFree(pThis->pszSanitizerOpts);
     1178    if (pThis->hEnv != RTENV_DEFAULT)
     1179    {
     1180        RTEnvDestroy(pThis->hEnv);
     1181        pThis->hEnv = RTENV_DEFAULT;
     1182    }
    10671183    RTFuzzTgtRecorderRelease(pThis->hTgtRec);
    10681184    RTFuzzCtxRelease(pThis->hFuzzCtx);
     
    11481264    if (RT_UNLIKELY(!pThis->pszBinary))
    11491265        rc = VERR_NO_STR_MEMORY;
     1266    else
     1267        pThis->pszBinaryFilename = RTPathFilename(pThis->pszBinary);
    11501268    return rc;
    11511269}
     
    12091327
    12101328
     1329RTDECL(int) RTFuzzObsSetTestBinaryEnv(RTFUZZOBS hFuzzObs, RTENV hEnv)
     1330{
     1331    PRTFUZZOBSINT pThis = hFuzzObs;
     1332    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1333
     1334    pThis->hEnv = hEnv;
     1335    return VINF_SUCCESS;
     1336}
     1337
     1338
     1339RTDECL(int) RTFuzzObsSetTestBinarySanitizers(RTFUZZOBS hFuzzObs, uint32_t fSanitizers)
     1340{
     1341    PRTFUZZOBSINT pThis = hFuzzObs;
     1342    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1343
     1344    pThis->fSanitizers = fSanitizers;
     1345    return VINF_SUCCESS;
     1346}
     1347
     1348
     1349RTDECL(int) RTFuzzObsSetTestBinaryTimeout(RTFUZZOBS hFuzzObs, RTMSINTERVAL msTimeoutMax)
     1350{
     1351    PRTFUZZOBSINT pThis = hFuzzObs;
     1352    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1353
     1354    pThis->msWaitMax = msTimeoutMax;
     1355    return VINF_SUCCESS;
     1356}
     1357
     1358
    12111359RTDECL(int) RTFuzzObsExecStart(RTFUZZOBS hFuzzObs, uint32_t cProcs)
    12121360{
     
    12221370        cProcs = RT_MIN(RTMpGetPresentCoreCount(), sizeof(uint64_t) * 8);
    12231371
    1224     /* Spin up the worker threads first. */
    1225     rc = rtFuzzObsWorkersCreate(pThis, cProcs);
     1372    rc = rtFuzzObsSetupSanitizerCfg(pThis);
    12261373    if (RT_SUCCESS(rc))
    12271374    {
    1228         /* Spin up the global thread. */
    1229         rc = rtFuzzObsMasterCreate(pThis);
     1375        /* Spin up the worker threads first. */
     1376        rc = rtFuzzObsWorkersCreate(pThis, cProcs);
     1377        if (RT_SUCCESS(rc))
     1378        {
     1379            /* Spin up the global thread. */
     1380            rc = rtFuzzObsMasterCreate(pThis);
     1381        }
    12301382    }
    12311383
  • trunk/src/VBox/Runtime/common/fuzz/fuzz-target-recorder.cpp

    r77547 r77693  
    3535#include <iprt/assert.h>
    3636#include <iprt/avl.h>
     37#include <iprt/crc.h>
    3738#include <iprt/ctype.h>
    3839#include <iprt/err.h>
     
    7677    /** Node for the list of states. */
    7778    RTLISTNODE                  NdStates;
     79    /** Checksum for the state. */
     80    uint64_t                    uChkSum;
    7881    /** Magic identifying the structure. */
    7982    uint32_t                    u32Magic;
     
    9093    /** The stderr data buffer. */
    9194    RTFUZZTGTSTDOUTERRBUF       StdErrBuf;
     95    /** Coverage report buffer. */
     96    void                        *pvCovReport;
     97    /** Size of the coverage report in bytes. */
     98    size_t                      cbCovReport;
     99    /** Number of traced edges. */
     100    size_t                      cEdges;
    92101} RTFUZZTGTSTATEINT;
    93102/** Pointer to an internal fuzzed target state. */
     
    100109typedef struct RTFUZZTGTRECNODE
    101110{
    102     /** The AVL tree core (keyed by stdout/stderr buffer sizes). */
     111    /** The AVL tree core (keyed by checksum). */
    103112    AVLU64NODECORE              Core;
    104113    /** The list anchor for the individual states. */
     
    107116/** Pointer to a recorder states node. */
    108117typedef RTFUZZTGTRECNODE *PRTFUZZTGTRECNODE;
     118
     119
     120/**
     121 * Edge information node.
     122 */
     123typedef struct RTFUZZTGTEDGE
     124{
     125    /** The AVL tree core (keyed by offset). */
     126    AVLU64NODECORE              Core;
     127    /** Number of times the edge was hit. */
     128    volatile uint64_t           cHits;
     129} RTFUZZTGTEDGE;
     130/** Pointer to a edge information node. */
     131typedef RTFUZZTGTEDGE *PRTFUZZTGTEDGE;
    109132
    110133
     
    122145    /** The AVL tree for indexing the recorded state (keyed by stdout/stderr buffer size). */
    123146    AVLU64TREE                  TreeStates;
     147    /** Semaphore protecting the edges tree. */
     148    RTSEMRW                     hSemRwEdges;
     149    /** The AVL tree for discovered edges when coverage reports are collected. */
     150    AVLU64TREE                  TreeEdges;
     151    /** Number of edges discovered so far. */
     152    volatile uint64_t           cEdges;
     153    /** The discovered offset width. */
     154    volatile uint32_t           cbCovOff;
    124155} RTFUZZTGTRECINT;
     156
     157
     158/** SanCov magic for 64bit offsets. */
     159#define SANCOV_MAGIC_64         UINT64_C(0xc0bfffffffffff64)
     160/** SanCov magic for 32bit offsets. */
     161#define SANCOV_MAGIC_32         UINT64_C(0xc0bfffffffffff32)
    125162
    126163
     
    200237
    201238/**
     239 * Scans the given target state for newly discovered edges in the coverage report.
     240 *
     241 * @returns IPRT status code.
     242 * @param   pThis               The fuzzer target recorder instance.
     243 * @param   pTgtState           The target state to check.
     244 */
     245static int rtFuzzTgtRecScanStateForNewEdges(PRTFUZZTGTRECINT pThis, PRTFUZZTGTSTATEINT pTgtState)
     246{
     247    int rc = VINF_SUCCESS;
     248
     249    if (pTgtState->pvCovReport)
     250    {
     251        rc = RTSemRWRequestRead(pThis->hSemRwEdges, RT_INDEFINITE_WAIT); AssertRC(rc);
     252
     253        uint32_t cbCovOff = ASMAtomicReadU32(&pThis->cbCovOff);
     254        Assert(cbCovOff != 0);
     255
     256        uint8_t *pbCovCur = (uint8_t *)pTgtState->pvCovReport;
     257        size_t cEdgesLeft = pTgtState->cbCovReport / cbCovOff;
     258        while (cEdgesLeft)
     259        {
     260            uint64_t offCur =   cbCovOff == sizeof(uint64_t)
     261                              ? *(uint64_t *)pbCovCur
     262                              : *(uint32_t *)pbCovCur;
     263
     264            PRTFUZZTGTEDGE pEdge = (PRTFUZZTGTEDGE)RTAvlU64Get(&pThis->TreeEdges, offCur);
     265            if (!pEdge)
     266            {
     267                /* New edge discovered, allocate and add. */
     268                rc = RTSemRWReleaseRead(pThis->hSemRwEdges); AssertRC(rc);
     269
     270                pEdge = (PRTFUZZTGTEDGE)RTMemAllocZ(sizeof(RTFUZZTGTEDGE));
     271                if (RT_LIKELY(pEdge))
     272                {
     273                    pEdge->Core.Key = offCur;
     274                    pEdge->cHits    = 1;
     275                    rc = RTSemRWRequestWrite(pThis->hSemRwEdges, RT_INDEFINITE_WAIT); AssertRC(rc);
     276
     277                    bool fIns = RTAvlU64Insert(&pThis->TreeEdges, &pEdge->Core);
     278                    if (!fIns)
     279                    {
     280                        /* Someone raced us, free and query again. */
     281                        RTMemFree(pEdge);
     282                        pEdge = (PRTFUZZTGTEDGE)RTAvlU64Get(&pThis->TreeEdges, offCur);
     283                        AssertPtr(pEdge);
     284
     285                        ASMAtomicIncU64(&pEdge->cHits);
     286                    }
     287                    else
     288                        ASMAtomicIncU64(&pThis->cEdges);
     289
     290                    rc = RTSemRWReleaseWrite(pThis->hSemRwEdges); AssertRC(rc);
     291                    rc = RTSemRWRequestRead(pThis->hSemRwEdges, RT_INDEFINITE_WAIT); AssertRC(rc);
     292                }
     293                else
     294                {
     295                    rc = RTSemRWRequestRead(pThis->hSemRwEdges, RT_INDEFINITE_WAIT);
     296                    AssertRC(rc);
     297
     298                    rc = VERR_NO_MEMORY;
     299                    break;
     300                }
     301            }
     302            else
     303                ASMAtomicIncU64(&pEdge->cHits);
     304
     305            pbCovCur += cbCovOff;
     306            cEdgesLeft--;
     307        }
     308
     309        rc = RTSemRWReleaseRead(pThis->hSemRwEdges); AssertRC(rc);
     310    }
     311
     312    return rc;
     313}
     314
     315
     316/**
    202317 * Destorys the given fuzzer target recorder freeing all allocated resources.
    203318 *
     
    212327
    213328/**
    214  * Destorys the given fuzzer target recorder freeing all allocated resources.
     329 * Destroys the given fuzzer target state freeing all allocated resources.
    215330 *
    216331 * @returns nothing.
     
    235350        pThis->cRefs            = 1;
    236351        pThis->TreeStates       = NULL;
     352        pThis->TreeEdges        = NULL;
     353        pThis->cbCovOff         = 0;
    237354
    238355        rc = RTSemRWCreate(&pThis->hSemRwStates);
    239356        if (RT_SUCCESS(rc))
    240357        {
    241             *phFuzzTgtRec = pThis;
    242             return VINF_SUCCESS;
     358            rc = RTSemRWCreate(&pThis->hSemRwEdges);
     359            if (RT_SUCCESS(rc))
     360            {
     361                *phFuzzTgtRec = pThis;
     362                return VINF_SUCCESS;
     363            }
     364
     365            RTSemRWDestroy(pThis->hSemRwStates);
    243366        }
    244367
     
    339462    pThis->StdOutBuf.cbBuf = 0;
    340463    pThis->StdErrBuf.cbBuf = 0;
     464    if (pThis->pvCovReport)
     465        RTMemFree(pThis->pvCovReport);
     466    pThis->pvCovReport     = NULL;
    341467    pThis->fFinalized      = false;
    342468    return VINF_SUCCESS;
     
    349475    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    350476
    351     /*
    352      * As we key both the stdout and stderr sizes in one 64bit
    353      * AVL tree core we only have 32bit for each and refuse buffers
    354      * exceeding this size (very unlikely for now).
    355      */
    356     if (RT_UNLIKELY(   pThis->StdOutBuf.cbBuf > UINT32_MAX
    357                     || pThis->StdErrBuf.cbBuf > UINT32_MAX))
    358         return VERR_BUFFER_OVERFLOW;
    359 
     477    /* Create the checksum. */
     478    uint64_t uChkSum = RTCrc64Start();
     479    if (pThis->StdOutBuf.cbBuf)
     480        uChkSum = RTCrc64Process(uChkSum, pThis->StdOutBuf.pbBase, pThis->StdOutBuf.cbBuf);
     481    if (pThis->StdErrBuf.cbBuf)
     482        uChkSum = RTCrc64Process(uChkSum, pThis->StdErrBuf.pbBase, pThis->StdErrBuf.cbBuf);
     483    if (pThis->pvCovReport)
     484        uChkSum = RTCrc64Process(uChkSum, pThis->pvCovReport, pThis->cbCovReport);
     485
     486    pThis->uChkSum = RTCrc64Finish(uChkSum);
    360487    pThis->fFinalized = true;
    361488    return VINF_SUCCESS;
     
    376503
    377504    PRTFUZZTGTRECINT pTgtRec = pThis->pTgtRec;
    378     uint64_t uKey = ((uint64_t)pThis->StdOutBuf.cbBuf << 32) | pThis->StdErrBuf.cbBuf;
    379505
    380506    /* Try to find a node matching the stdout and sterr sizes first. */
    381507    int rc = RTSemRWRequestRead(pTgtRec->hSemRwStates, RT_INDEFINITE_WAIT); AssertRC(rc);
    382     PRTFUZZTGTRECNODE pNode = (PRTFUZZTGTRECNODE)RTAvlU64Get(&pTgtRec->TreeStates, uKey);
     508    PRTFUZZTGTRECNODE pNode = (PRTFUZZTGTRECNODE)RTAvlU64Get(&pTgtRec->TreeStates, pThis->uChkSum);
    383509    if (pNode)
    384510    {
     
    393519                    || !memcmp(pThis->StdOutBuf.pbBase, pIt->StdOutBuf.pbBase, pThis->StdOutBuf.cbBuf))
    394520                && (   !pThis->StdErrBuf.cbBuf
    395                     || !memcmp(pThis->StdErrBuf.pbBase, pIt->StdErrBuf.pbBase, pThis->StdErrBuf.cbBuf)))
     521                    || !memcmp(pThis->StdErrBuf.pbBase, pIt->StdErrBuf.pbBase, pThis->StdErrBuf.cbBuf))
     522                && (   pThis->cbCovReport != pIt->cbCovReport
     523                    || (   pThis->cbCovReport > 0
     524                        && !memcmp(pThis->pvCovReport, pIt->pvCovReport, pThis->cbCovReport))))
    396525            {
    397526                fMatchFound = true;
     
    419548        if (RT_LIKELY(pNode))
    420549        {
    421             pNode->Core.Key = uKey;
     550            pNode->Core.Key = pThis->uChkSum;
    422551            RTListInit(&pNode->LstStates);
    423552            RTListAppend(&pNode->LstStates, &pThis->NdStates);
     
    428557                /* Someone raced us, get the new node and append there. */
    429558                RTMemFree(pNode);
    430                 pNode = (PRTFUZZTGTRECNODE)RTAvlU64Get(&pTgtRec->TreeStates, uKey);
     559                pNode = (PRTFUZZTGTRECNODE)RTAvlU64Get(&pTgtRec->TreeStates, pThis->uChkSum);
    431560                AssertPtr(pNode);
    432561                RTListAppend(&pNode->LstStates, &pThis->NdStates);
     
    439568    }
    440569
     570    if (   RT_SUCCESS(rc)
     571        && pThis->fInRecSet)
     572        rc = rtFuzzTgtRecScanStateForNewEdges(pTgtRec, pThis);
     573
    441574    return rc;
    442575}
     
    484617}
    485618
     619
     620RTDECL(int) RTFuzzTgtStateAddSanCovReportFromFile(RTFUZZTGTSTATE hFuzzTgtState, const char *pszFilename)
     621{
     622    PRTFUZZTGTSTATEINT pThis = hFuzzTgtState;
     623    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     624    AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
     625    AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER);
     626
     627    uint8_t *pbSanCov = NULL;
     628    size_t cbSanCov = 0;
     629    int rc = RTFileReadAll(pszFilename, (void **)&pbSanCov, &cbSanCov);
     630    if (RT_SUCCESS(rc))
     631    {
     632        /* Check for the magic identifying whether the offsets are 32bit or 64bit. */
     633        if (   cbSanCov >= sizeof(uint64_t)
     634            && (   *(uint64_t *)pbSanCov == SANCOV_MAGIC_64
     635                || *(uint64_t *)pbSanCov == SANCOV_MAGIC_32))
     636        {
     637            uint32_t cbCovOff = sizeof(uint32_t);
     638            if (*(uint64_t *)pbSanCov == SANCOV_MAGIC_64)
     639                cbCovOff = sizeof(uint64_t);
     640
     641            uint32_t cbCovDet = ASMAtomicReadU32(&pThis->pTgtRec->cbCovOff);
     642            if (!cbCovDet)
     643            {
     644                /* Set the detected offset width. */
     645                if (!ASMAtomicCmpXchgU32(&pThis->pTgtRec->cbCovOff, cbCovOff, 0))
     646                {
     647                    /* Someone raced us, check again. */
     648                    cbCovDet = ASMAtomicReadU32(&pThis->pTgtRec->cbCovOff);
     649                    Assert(cbCovDet != 0);
     650                }
     651                else
     652                    cbCovDet = cbCovOff;
     653            }
     654
     655            if (cbCovDet == cbCovOff)
     656            {
     657                /*
     658                 * Just copy the offsets into the state for now. Now further analysis
     659                 * is happening right now, just checking whether the content changed for
     660                 * the states.to spot newly discovered edges.
     661                 */
     662                pThis->cbCovReport = cbSanCov - sizeof(uint64_t);
     663                pThis->pvCovReport = RTMemDup(pbSanCov + sizeof(uint64_t), pThis->cbCovReport);
     664                if (!pThis->pvCovReport)
     665                {
     666                    pThis->cbCovReport = 0;
     667                    rc = VERR_NO_MEMORY;
     668                }
     669            }
     670            else
     671                rc = VERR_INVALID_STATE; /* Mixing 32bit and 64bit offsets shouldn't happen, is not supported. */
     672        }
     673        else
     674            rc = VERR_INVALID_STATE;
     675        RTFileReadAllFree(pbSanCov, cbSanCov);
     676    }
     677    return rc;
     678}
     679
  • trunk/src/VBox/Runtime/common/fuzz/fuzz.cpp

    r77658 r77693  
    11211121{
    11221122    int rc = VINF_SUCCESS;
    1123     if (pMutationParent->cbInput > offStart)
     1123    if (   pMutationParent->cbInput > offStart
     1124        && pMutationParent->cbInput > 1)
    11241125    {
    11251126        size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, offStart, pMutationParent->cbInput - 1);
     
    19921993        uint64_t offStart = 0;
    19931994        if (!(pMutator->fFlags & RTFUZZMUTATOR_F_END_OF_BUF))
    1994             offStart = RTRandAdvU64Ex(pThis->hRand, 0, pMutationParent->cbInput);
     1995            offStart = RTRandAdvU64Ex(pThis->hRand, 0, pMutationParent->cbInput - 1);
    19951996        else
    19961997            offStart = pMutationParent->cbInput;
  • trunk/src/VBox/Runtime/common/fuzz/fuzzmastercmd.cpp

    r77659 r77693  
    3737#include <iprt/buildconfig.h>
    3838#include <iprt/ctype.h>
     39#include <iprt/env.h>
    3940#include <iprt/err.h>
    4041#include <iprt/file.h>
     
    5051#include <iprt/tcp.h>
    5152#include <iprt/thread.h>
     53#include <iprt/time.h>
    5254#include <iprt/vfs.h>
    5355#include <iprt/zip.h>
     
    6971    /** Flag whether fuzzing was started. */
    7072    bool                        fStarted;
     73    /** Time when this run was created. */
     74    RTTIME                      TimeCreated;
     75    /** Millisecond timestamp when the run was created. */
     76    uint64_t                    tsCreatedMs;
    7177} RTFUZZRUN;
    7278/** Pointer to a running fuzzer state. */
     
    407413        RTJsonValueRelease(hJsonValArgArray);
    408414    }
     415
     416    return rc;
     417}
     418
     419
     420/**
     421 * Processes process environment related configs for the given fuzzing run.
     422 *
     423 * @returns IPRT status code.
     424 * @param   pFuzzRun            The fuzzing run.
     425 * @param   hJsonRoot           The root node of the JSON request.
     426 * @param   pErrInfo            Where to store the error information on failure, optional.
     427 */
     428static int rtFuzzCmdMasterFuzzRunProcessEnvironment(PRTFUZZRUN pFuzzRun, RTJSONVAL hJsonRoot, PRTERRINFO pErrInfo)
     429{
     430    RTJSONVAL hJsonValEnv;
     431    int rc = RTJsonValueQueryByName(hJsonRoot, "Env", &hJsonValEnv);
     432    if (RT_SUCCESS(rc))
     433    {
     434        bool fReplaceEnv = false; /* false means to append everything to the default block. */
     435
     436        rc = RTJsonValueQueryBooleanByName(hJsonRoot, "EnvReplace", &fReplaceEnv);
     437        if (   RT_SUCCESS(rc)
     438            || rc == VERR_NOT_FOUND)
     439        {
     440            RTJSONIT hEnvIt;
     441            RTENV hEnv = NULL;
     442
     443            if (fReplaceEnv)
     444                rc = RTEnvCreate(&hEnv);
     445            else
     446                rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
     447
     448            if (RT_SUCCESS(rc))
     449            {
     450                rc = RTJsonIteratorBeginArray(hJsonValEnv, &hEnvIt);
     451                if (RT_SUCCESS(rc))
     452                {
     453                    do
     454                    {
     455                        RTJSONVAL hVal;
     456                        rc = RTJsonIteratorQueryValue(hEnvIt, &hVal, NULL);
     457                        if (RT_SUCCESS(rc))
     458                        {
     459                            const char *pszVar = RTJsonValueGetString(hVal);
     460                            if (RT_LIKELY(pszVar))
     461                                rc = RTEnvPutEx(hEnv, pszVar);
     462                            RTJsonValueRelease(hVal);
     463                        }
     464                        rc = RTJsonIteratorNext(hEnvIt);
     465                    } while (RT_SUCCESS(rc));
     466
     467                    if (   rc == VERR_JSON_IS_EMPTY
     468                        || rc == VERR_JSON_ITERATOR_END)
     469                        rc = VINF_SUCCESS;
     470                    else
     471                        rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: Failed to parse environment");
     472
     473                    RTJsonIteratorFree(hEnvIt);
     474                }
     475                else if (rc == VERR_JSON_IS_EMPTY)
     476                    rc = VINF_SUCCESS;
     477                else
     478                    rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: \"Environment\" is not an array");
     479
     480                if (RT_SUCCESS(rc))
     481                {
     482                    rc = RTFuzzObsSetTestBinaryEnv(pFuzzRun->hFuzzObs, hEnv);
     483                    AssertRC(rc);
     484                }
     485                else if (hEnv)
     486                    RTEnvDestroy(hEnv);
     487            }
     488            else
     489                rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: Failed to create environment block");
     490        }
     491        else
     492            rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: Failed to query \"EnvReplace\"");
     493
     494        RTJsonValueRelease(hJsonValEnv);
     495    }
     496    else if (rc == VERR_NOT_FOUND)
     497        rc = VINF_SUCCESS; /* Just keep using the default environment. */
     498    else
     499        rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: Failed to query the \"Environment\"");
     500
     501    return rc;
     502}
     503
     504
     505/**
     506 * Processes process environment related configs for the given fuzzing run.
     507 *
     508 * @returns IPRT status code.
     509 * @param   pFuzzRun            The fuzzing run.
     510 * @param   hJsonRoot           The root node of the JSON request.
     511 * @param   pErrInfo            Where to store the error information on failure, optional.
     512 */
     513static int rtFuzzCmdMasterFuzzRunProcessSanitizers(PRTFUZZRUN pFuzzRun, RTJSONVAL hJsonRoot, PRTERRINFO pErrInfo)
     514{
     515    RTJSONVAL hJsonValSan;
     516    int rc = RTJsonValueQueryByName(hJsonRoot, "Sanitizers", &hJsonValSan);
     517    if (RT_SUCCESS(rc))
     518    {
     519        uint32_t fSanitizers = 0;
     520        RTJSONIT hSanIt;
     521        rc = RTJsonIteratorBeginArray(hJsonValSan, &hSanIt);
     522        if (RT_SUCCESS(rc))
     523        {
     524            do
     525            {
     526                RTJSONVAL hVal;
     527                rc = RTJsonIteratorQueryValue(hSanIt, &hVal, NULL);
     528                if (RT_SUCCESS(rc))
     529                {
     530                    const char *pszSan = RTJsonValueGetString(hVal);
     531                    if (!RTStrICmp(pszSan, "Asan"))
     532                        fSanitizers |= RTFUZZOBS_SANITIZER_F_ASAN;
     533                    else if (!RTStrICmp(pszSan, "SanCov"))
     534                        fSanitizers |= RTFUZZOBS_SANITIZER_F_SANCOV;
     535                    else
     536                        rc = rtFuzzCmdMasterErrorRc(pErrInfo, VERR_NOT_FOUND, "JSON request malformed: The sanitizer '%s' is not known", pszSan);
     537                    RTJsonValueRelease(hVal);
     538                }
     539                rc = RTJsonIteratorNext(hSanIt);
     540            } while (RT_SUCCESS(rc));
     541
     542            if (   rc == VERR_JSON_IS_EMPTY
     543                || rc == VERR_JSON_ITERATOR_END)
     544                rc = VINF_SUCCESS;
     545            else
     546                rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: Failed to parse sanitizers");
     547
     548            RTJsonIteratorFree(hSanIt);
     549        }
     550        else if (rc == VERR_JSON_IS_EMPTY)
     551            rc = VINF_SUCCESS;
     552        else
     553            rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: \"Sanitizers\" is not an array");
     554
     555        if (RT_SUCCESS(rc))
     556        {
     557            rc = RTFuzzObsSetTestBinarySanitizers(pFuzzRun->hFuzzObs, fSanitizers);
     558            AssertRC(rc);
     559        }
     560
     561        RTJsonValueRelease(hJsonValSan);
     562    }
     563    else if (rc == VERR_NOT_FOUND)
     564        rc = VINF_SUCCESS; /* Just keep using the defaults. */
     565    else
     566        rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "JSON request malformed: Failed to query the \"Sanitizers\"");
    409567
    410568    return rc;
     
    614772    if (RT_SUCCESS(rc))
    615773        rc = rtFuzzCmdMasterFuzzRunProcessCfgU32Def(&pFuzzRun->cProcs, "FuzzingProcs", hJsonRoot, 0, pErrInfo);
     774    if (RT_SUCCESS(rc))
     775    {
     776        uint32_t msTimeoutMax = 0;
     777        rc = rtFuzzCmdMasterFuzzRunProcessCfgU32Def(&msTimeoutMax, "TimeoutMax", hJsonRoot, 1000, pErrInfo);
     778        if (RT_SUCCESS(rc))
     779            rc = RTFuzzObsSetTestBinaryTimeout(pFuzzRun->hFuzzObs, msTimeoutMax);
     780    }
    616781
    617782    return rc;
     
    694859                    rc = rtFuzzCmdMasterFuzzRunProcessArgCfg(pFuzzRun, hJsonRoot, pErrInfo);
    695860                if (RT_SUCCESS(rc))
     861                    rc = rtFuzzCmdMasterFuzzRunProcessEnvironment(pFuzzRun, hJsonRoot, pErrInfo);
     862                if (RT_SUCCESS(rc))
    696863                    rc = rtFuzzCmdMasterFuzzRunProcessInputSeeds(pFuzzRun, hJsonRoot, pErrInfo);
    697864                if (RT_SUCCESS(rc))
    698865                    rc = rtFuzzCmdMasterFuzzRunProcessMiscCfg(pFuzzRun, hJsonRoot, pErrInfo);
     866                if (RT_SUCCESS(rc))
     867                    rc = rtFuzzCmdMasterFuzzRunProcessSanitizers(pFuzzRun, hJsonRoot, pErrInfo);
    699868                if (RT_SUCCESS(rc))
    700869                    rc = rtFuzzCmdMasterFuzzRunSetupDirectories(pThis, pFuzzRun, pErrInfo);
     
    706875                    rc = RTFuzzObsExecStart(pFuzzRun->hFuzzObs, pFuzzRun->cProcs);
    707876                    if (RT_SUCCESS(rc))
     877                    {
     878                        RTTIMESPEC TimeSpec;
     879                        RTTimeNow(&TimeSpec);
     880                        RTTimeLocalExplode(&pFuzzRun->TimeCreated, &TimeSpec);
     881                        pFuzzRun->tsCreatedMs = RTTimeMilliTS();
    708882                        pFuzzRun->fStarted = true;
     883                    }
    709884                    else
    710885                        rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "Request error: Failed to start fuzzing with %Rrc", rc);
     
    9961171    {
    9971172        const char s_szStatsFmt[] = "%s{ \n"
    998                                     "%s    \"Id\":                 %s\n"
     1173                                    "%s    \"Id\":                 \"%s\"\n"
     1174                                    "%s    \"TimeCreated\":        \"%s\"\n"
     1175                                    "%s    \"UptimeSec\":          %llu\n"
    9991176                                    "%s    \"FuzzedInputsPerSec\": %u\n"
    10001177                                    "%s    \"FuzzedInputs\":       %u\n"
     
    10041181                                    "%s    \"CorpusSize\":         %llu\n"
    10051182                                    "%s}%s\n";
    1006         char achStats[_4K]; RT_ZERO(achStats);
    1007         ssize_t cchStats = RTStrPrintf2(&achStats[0], sizeof(achStats),
    1008                                         s_szStatsFmt, pszIndent,
    1009                                         pszIndent, pFuzzRun->pszId,
    1010                                         pszIndent, ObsStats.cFuzzedInputsPerSec,
    1011                                         pszIndent, ObsStats.cFuzzedInputs,
    1012                                         pszIndent, ObsStats.cFuzzedInputsHang,
    1013                                         pszIndent, ObsStats.cFuzzedInputsCrash,
    1014                                         pszIndent, CtxStats.cbMemory,
    1015                                         pszIndent, CtxStats.cMutations,
    1016                                         pszIndent, fLast ? "" : ",");
    1017         if (RT_LIKELY(cchStats > 0))
    1018         {
    1019             rc = RTStrAAppend(&pThis->pszResponse, &achStats[0]);
    1020             if (RT_FAILURE(rc))
    1021                 rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "Request error: Failed to build statistics response", rc);
     1183        char aszTime[_1K]; RT_ZERO(aszTime);
     1184        char aszStats[_4K]; RT_ZERO(aszStats);
     1185
     1186        if (RTTimeToString(&pFuzzRun->TimeCreated, aszTime, sizeof(aszTime)))
     1187        {
     1188            ssize_t cchStats = RTStrPrintf2(&aszStats[0], sizeof(aszStats),
     1189                                            s_szStatsFmt, pszIndent,
     1190                                            pszIndent, pFuzzRun->pszId,
     1191                                            pszIndent, aszTime,
     1192                                            pszIndent, (RTTimeMilliTS() - pFuzzRun->tsCreatedMs) / RT_MS_1SEC_64,
     1193                                            pszIndent, ObsStats.cFuzzedInputsPerSec,
     1194                                            pszIndent, ObsStats.cFuzzedInputs,
     1195                                            pszIndent, ObsStats.cFuzzedInputsHang,
     1196                                            pszIndent, ObsStats.cFuzzedInputsCrash,
     1197                                            pszIndent, CtxStats.cbMemory,
     1198                                            pszIndent, CtxStats.cMutations,
     1199                                            pszIndent, fLast ? "" : ",");
     1200            if (RT_LIKELY(cchStats > 0))
     1201            {
     1202                rc = RTStrAAppend(&pThis->pszResponse, &aszStats[0]);
     1203                if (RT_FAILURE(rc))
     1204                    rc = rtFuzzCmdMasterErrorRc(pErrInfo, rc, "Request error: Failed to build statistics response", rc);
     1205            }
     1206            else
     1207                rc = rtFuzzCmdMasterErrorRc(pErrInfo, VERR_BUFFER_OVERFLOW, "Request error: Response data buffer overflow");
    10221208        }
    10231209        else
    1024             rc = rtFuzzCmdMasterErrorRc(pErrInfo, VERR_BUFFER_OVERFLOW, "Request error: Response data buffer overflow", rc);
     1210            rc = rtFuzzCmdMasterErrorRc(pErrInfo, VERR_BUFFER_OVERFLOW, "Request error: Buffer overflow conerting time to string");
    10251211    }
    10261212    else
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