VBoxManageDebugVM.cpp revision 0985803eef55885cfdc007d1bc664ca286585d52
/* $Id$ */
/** @file
* VBoxManage - Implementation of the debugvm command.
*/
/*
* Copyright (C) 2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "VBoxManage.h"
/**
* Handles the getregisters sub-command.
*
* @returns Suitable exit code.
* @param pArgs The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
/*
* We take a list of register names (case insensitive). If 'all' is
* encountered we'll dump all registers.
*/
unsigned cRegisters = 0;
static const RTGETOPTDEF s_aOptions[] =
{
};
int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
{
switch (rc)
{
case 'c':
break;
case VINF_GETOPT_NOT_OPTION:
{
CHECK_ERROR2_RET(pDebugger, GetRegisters(idCpu, ComSafeArrayAsOutParam(aBstrNames), ComSafeArrayAsOutParam(aBstrValues)),
{
if (cchName > cchMaxName)
}
}
else
{
CHECK_ERROR2_RET(pDebugger, GetRegister(idCpu, bstrName.raw(), bstrValue.asOutParam()), RTEXITCODE_FAILURE);
}
cRegisters++;
break;
default:
}
}
if (!cRegisters)
return RTEXITCODE_SUCCESS;
}
/**
* Handles the info sub-command.
*
* @returns Suitable exit code.
* @param a The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
CHECK_ERROR2_RET(pDebugger, Info(bstrName.raw(), bstrArgs.raw(), bstrInfo.asOutParam()), RTEXITCODE_FAILURE);
return RTEXITCODE_SUCCESS;
}
/**
* Handles the inject sub-command.
*
* @returns Suitable exit code.
* @param a The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
if (a->argc != 2)
return RTEXITCODE_SUCCESS;
}
/**
* Handles the log sub-command.
*
* @returns Suitable exit code.
* @param pArgs The handler arguments.
* @param pDebugger Pointer to the debugger interface.
* @param pszSubCmd The sub command.
*/
static RTEXITCODE handleDebugVM_LogXXXX(HandlerArg *pArgs, IMachineDebugger *pDebugger, const char *pszSubCmd)
{
/*
* Parse arguments.
*/
bool fRelease = false;
/** @todo Put short options into enum / defines! */
static const RTGETOPTDEF s_aOptions[] =
{
};
int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
{
switch (rc)
{
case 'r':
fRelease = true;
break;
case 'd':
fRelease = false;
break;
/* Because log strings can start with "-" (like "-all+dev_foo")
* we have to take everything we got as a setting and apply it.
* IPRT will take care of the validation afterwards. */
default:
if (strSettings.length() == 0)
else
{
}
break;
}
}
if (fRelease)
{
strSettings = "release: ";
}
else
return RTEXITCODE_SUCCESS;
}
/**
* Handles the inject sub-command.
*
* @returns Suitable exit code.
* @param pArgs The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
/*
* Parse arguments.
*/
const char *pszFilename = NULL;
const char *pszCompression = NULL;
static const RTGETOPTDEF s_aOptions[] =
{
};
int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
{
switch (rc)
{
case 'c':
if (pszCompression)
break;
case 'f':
if (pszFilename)
break;
default:
}
}
if (!pszFilename)
/*
* Make the filename absolute before handing it on to the API.
*/
char szAbsFilename[RTPATH_MAX];
if (RT_FAILURE(rc))
CHECK_ERROR2_RET(pDebugger, DumpGuestCore(bstrFilename.raw(), bstrCompression.raw()), RTEXITCODE_FAILURE);
return RTEXITCODE_SUCCESS;
}
/**
* Handles the os sub-command.
*
* @returns Suitable exit code.
* @param a The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
if (a->argc != 2)
return RTEXITCODE_SUCCESS;
}
/**
* Handles the os sub-command.
*
* @returns Suitable exit code.
* @param a The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
if (a->argc != 2)
return RTEXITCODE_SUCCESS;
}
/**
* Handles the setregisters sub-command.
*
* @returns Suitable exit code.
* @param pArgs The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
/*
* We take a list of register assignments, that is register=value.
*/
static const RTGETOPTDEF s_aOptions[] =
{
};
int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
{
switch (rc)
{
case 'c':
break;
case VINF_GETOPT_NOT_OPTION:
{
if (!pszEqual)
return errorSyntax(USAGE_DEBUGVM, "setregisters expects input on the form 'register=value' got '%s'", ValueUnion.psz);
try
{
}
{
RTMsgError("Out of memory\n");
return RTEXITCODE_FAILURE;
}
break;
}
default:
}
}
if (!aBstrNames.size())
/*
* If it is only one register, use the single register method just so
* we expose it and can test it from the command line.
*/
{
}
else
{
CHECK_ERROR2_RET(pDebugger, SetRegisters(idCpu, ComSafeArrayAsInParam(aBstrNames), ComSafeArrayAsInParam(aBstrValues)), RTEXITCODE_FAILURE);
}
return RTEXITCODE_SUCCESS;
}
/** @name debugvm show flags
* @{ */
/** @} */
/**
* Prints a variable according to the @a fFlags.
*
* @param pszVar The variable name.
* @param pbstrValue The variable value.
* @param fFlags The debugvm show flags.
*/
static void handleDebugVM_Show_PrintVar(const char *pszVar, com::Bstr const *pbstrValue, uint32_t fFlags)
{
switch (fFlags & DEBUGVM_SHOW_FLAGS_FMT_MASK)
{
default: AssertFailed();
}
}
/**
* Handles logdbg-settings.
*
* @returns Exit code.
* @param pDebugger The debugger interface.
* @param fFlags The debugvm show flags.
*/
{
RTPrintf("Debug logger settings:\n");
return RTEXITCODE_SUCCESS;
}
/**
* Handles logrel-settings.
*
* @returns Exit code.
* @param pDebugger The debugger interface.
* @param fFlags The debugvm show flags.
*/
{
RTPrintf("Release logger settings:\n");
return RTEXITCODE_SUCCESS;
}
/**
* Handles the show sub-command.
*
* @returns Suitable exit code.
* @param pArgs The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
/*
* Parse arguments and what to show. Order dependent.
*/
static const RTGETOPTDEF s_aOptions[] =
{
};
int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
{
switch (rc)
{
case 'H':
break;
case 'e':
break;
case 'E':
break;
case 's':
break;
case VINF_GETOPT_NOT_OPTION:
{
{
if (rcExit == RTEXITCODE_SUCCESS)
}
else
rcExit = errorSyntax(USAGE_DEBUGVM, "The show sub-command has no idea what '%s' might be", ValueUnion.psz);
if (rcExit != RTEXITCODE_SUCCESS)
return rcExit;
break;
}
default:
}
}
return RTEXITCODE_SUCCESS;
}
/**
* Handles the statistics sub-command.
*
* @returns Suitable exit code.
* @param pArgs The handler arguments.
* @param pDebugger Pointer to the debugger interface.
*/
{
/*
* Parse arguments.
*/
bool fWithDescriptions = false;
bool fReset = false;
static const RTGETOPTDEF s_aOptions[] =
{
};
int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
{
switch (rc)
{
case 'd':
fWithDescriptions = true;
break;
case 'p':
if (pszPattern)
break;
case 'r':
fReset = true;
break;
default:
}
}
if (fReset && fWithDescriptions)
/*
* Execute the order.
*/
if (fReset)
else
{
/* if (fFormatted)
{ big mess }
else
*/
}
return RTEXITCODE_SUCCESS;
}
{
/*
* The first argument is the VM name or UUID. Open a session to it.
*/
CHECK_ERROR2_RET(pArgs->virtualBox, FindMachine(com::Bstr(pArgs->argv[0]).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
/*
* Get the associated console and machine debugger.
*/
{
{
/*
* String switch on the sub-command.
*/
else
}
}
return rcExit;
}