VirtualBox

Changeset 34431 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Nov 27, 2010 9:56:47 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
68203
Message:

AsyncCompletion: Proper debugger command for error injection

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMAsyncCompletionFile.cpp

    r34344 r34431  
    2727#include <VBox/err.h>
    2828#include <VBox/log.h>
     29#include <VBox/dbg.h>
     30#include <VBox/uvm.h>
    2931
    3032#include <iprt/asm.h>
     
    4648
    4749#include "PDMAsyncCompletionFileInternal.h"
     50
     51
     52/*******************************************************************************
     53*   Internal Functions                                                         *
     54*******************************************************************************/
     55#ifdef VBOX_WITH_DEBUGGER
     56static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs, PDBGCVAR pResult);
     57#endif
     58
     59/*******************************************************************************
     60*   Global Variables                                                           *
     61*******************************************************************************/
     62#ifdef VBOX_WITH_DEBUGGER
     63static const DBGCVARDESC g_aInjectErrorArgs[] =
     64{
     65    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     66    {  1,           1,          DBGCVAR_CAT_STRING,     0,                              "direction",    "write/read." },
     67    {  1,           1,          DBGCVAR_CAT_STRING,     0,                              "filename",     "Filename." },
     68    {  1,           1,          DBGCVAR_CAT_STRING,     0,                              "errcode",      "IPRT error code." },
     69};
     70
     71/** Command descriptors. */
     72static const DBGCCMD g_aCmds[] =
     73{
     74    /* pszCmd,       cArgsMin, cArgsMax, paArgDesc,                cArgDescs,    pResultDesc,        fFlags,     pfnHandler          pszSyntax,          ....pszDescription */
     75    { "injecterror",        3, 3,        &g_aInjectErrorArgs[0],           3,           NULL,             0,     pdmacEpFileErrorInject,        "",   "Inject error into I/O subsystem." },
     76};
     77#endif
    4878
    4979/**
     
    598628}
    599629
    600 #ifdef DEBUG
     630#ifdef VBOX_WITH_DEBUGGER
    601631/**
    602632 * Error inject callback.
    603  *
    604  * The argument parsing is quite ugly but it is only a development tool
    605  * not compiled into a release build. Will improve some day.
    606633 */
    607 static DECLCALLBACK(void) pdmacEpFileErrorInject(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs)
     634static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs, PDBGCVAR pResult)
    608635{
    609636    bool fWrite;
    610     int rcToInject = VINF_SUCCESS;
    611     char *pszFilename = NULL;
    612     PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pvUser;
     637    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
     638
     639    /*
     640     * Validate input.
     641     */
     642    if (!pVM)
     643        return DBGCCmdHlpPrintf(pCmdHlp, "error: The command requires a VM to be selected.\n");
     644    if (    cArgs != 3
     645        ||  pArgs[0].enmType != DBGCVAR_TYPE_STRING
     646        ||  pArgs[1].enmType != DBGCVAR_TYPE_STRING
     647        ||  pArgs[2].enmType != DBGCVAR_TYPE_STRING)
     648        return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: parser error, invalid arguments.\n");
     649
     650    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];
    613651
    614652    /* Syntax is "read|write <filename> <status code>" */
    615     if (!RTStrNCmp(pszArgs, "read", 4))
     653    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
    616654        fWrite = false;
    617     else if (!RTStrNCmp(pszArgs, "write", 5))
     655    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
    618656        fWrite = true;
    619657    else
    620         return;
    621 
    622     pszArgs += fWrite ? 5 : 4;
    623 
    624     /* Skip white space. */
    625     while (   *pszArgs == ' '
    626            && *pszArgs != '\0')
    627         pszArgs++;
    628 
    629     if (pszArgs != '\0')
    630     {
    631         /* Extract the filename */
    632         const char *pszPos = pszArgs;
    633 
    634         /* ASSUMPTION: No white space in the filename. */
    635         while (   *pszArgs != ' '
    636                && *pszArgs != '\0')
    637             pszArgs++;
    638 
    639         if (*pszArgs != '\0')
    640         {
    641             size_t cchFilename = pszArgs - pszPos;
    642             pszFilename = RTStrDupN(pszPos, cchFilename);
    643             if (pszFilename)
    644             {
    645                 /* Skip white space. */
    646                 while (   *pszArgs == ' '
    647                        && *pszArgs != '\0')
    648                     pszArgs++;
    649 
    650                 if (*pszArgs != '\0')
    651                 {
    652                     /* Extract error number. */
    653                     rcToInject = RTStrToInt32(pszArgs);
    654                     if (rcToInject != 0)
    655                     {
    656                         /* Search for the matching endpoint. */
    657                         RTCritSectEnter(&pEpClassFile->Core.CritSect);
    658                         PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
    659 
    660                         while (pEpFile)
    661                         {
    662                             if (!RTStrCmp(pszFilename, RTPathFilename(pEpFile->Core.pszUri)))
    663                                 break;
    664                             pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    665                         }
    666 
    667                         if (pEpFile)
    668                         {
    669                             if (fWrite)
    670                                 ASMAtomicXchgS32(&pEpFile->rcReqWrite, rcToInject);
    671                             else
    672                                 ASMAtomicXchgS32(&pEpFile->rcReqRead, rcToInject);
    673 
    674                             pHlp->pfnPrintf(pHlp, "Injected %Rrc into '%s' for %s\n",
    675                                             rcToInject, pszFilename, fWrite ? "write" : "read");
    676                         }
    677                         else
    678                             pHlp->pfnPrintf(pHlp, "No file with name '%s' found\n", pszFilename);
    679 
    680                         RTCritSectLeave(&pEpClassFile->Core.CritSect);
    681                         RTStrFree(pszFilename);
    682                         return;
    683                     }
    684                 }
    685                 RTStrFree(pszFilename);
    686             }
    687         }
    688     }
    689     pHlp->pfnPrintf(pHlp, "Error parsing command line\n");
     658    {
     659        DBGCCmdHlpPrintf(pCmdHlp, "error: invalid transefr direction '%s'.\n", pArgs[0].u.pszString);
     660        return VINF_SUCCESS;
     661    }
     662
     663    /* Search for the matching endpoint. */
     664    RTCritSectEnter(&pEpClassFile->Core.CritSect);
     665    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
     666
     667    while (pEpFile)
     668    {
     669        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
     670            break;
     671        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
     672    }
     673
     674    if (pEpFile)
     675    {
     676        int rcToInject = RTStrToInt32(pArgs[2].u.pszString);
     677
     678        if (fWrite)
     679            ASMAtomicXchgS32(&pEpFile->rcReqWrite, rcToInject);
     680        else
     681            ASMAtomicXchgS32(&pEpFile->rcReqRead, rcToInject);
     682
     683            DBGCCmdHlpPrintf(pCmdHlp, "Injected %Rrc into '%s' for %s\n",
     684                             rcToInject, pArgs[1].u.pszString, pArgs[0].u.pszString);
     685    }
     686    else
     687        DBGCCmdHlpPrintf(pCmdHlp, "No file with name '%s' found\n", NULL, pArgs[1].u.pszString);
     688
     689    RTCritSectLeave(&pEpClassFile->Core.CritSect);
     690    return VINF_SUCCESS;
    690691}
    691692#endif
     
    779780    }
    780781
    781 #ifdef DEBUG
     782#ifdef VBOX_WITH_DEBUGGER
    782783    /* Install the error injection handler. */
    783784    if (RT_SUCCESS(rc))
    784785    {
    785         rc = DBGFR3InfoRegisterExternal(pClassGlobals->pVM, "injecterror",
    786                                         "Inject an error into the async file I/O handling",
    787                                         pdmacEpFileErrorInject, pEpClassFile);
     786        rc = DBGCRegisterCommands(&g_aCmds[0], 1);
    788787        AssertRC(rc);
    789788    }
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