VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp@ 35273

Last change on this file since 35273 was 35242, checked in by vboxsync, 13 years ago

IMachineDebugger: Stubbed a few, new methods that may come in handy in the 4.0 product cycle. Adjusted the dumpGuestCore method so that it can later be amended with any stream compression method we like.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: VBoxManageDebugVM.cpp 35242 2010-12-20 13:33:23Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of the debugvm command.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <VBox/com/com.h>
23#include <VBox/com/string.h>
24#include <VBox/com/Guid.h>
25#include <VBox/com/array.h>
26#include <VBox/com/ErrorInfo.h>
27#include <VBox/com/errorprint.h>
28#include <VBox/com/EventQueue.h>
29
30#include <VBox/com/VirtualBox.h>
31
32#include <iprt/ctype.h>
33#include <VBox/err.h>
34#include <iprt/getopt.h>
35#include <iprt/path.h>
36#include <iprt/param.h>
37#include <iprt/stream.h>
38#include <iprt/string.h>
39#include <iprt/uuid.h>
40#include <VBox/log.h>
41
42#include "VBoxManage.h"
43
44
45/**
46 * Handles the inject sub-command.
47 *
48 * @returns Suitable exit code.
49 * @param a The handler arguments.
50 * @param pDebugger Pointer to the debugger interface.
51 */
52static RTEXITCODE handleDebugVM_InjectNMI(HandlerArg *a, IMachineDebugger *pDebugger)
53{
54 if (a->argc != 2)
55 return errorSyntax(USAGE_DEBUGVM, "The inject sub-command does not take any arguments");
56 CHECK_ERROR2_RET(pDebugger, InjectNMI(), RTEXITCODE_FAILURE);
57 return RTEXITCODE_SUCCESS;
58}
59
60/**
61 * Handles the inject sub-command.
62 *
63 * @returns Suitable exit code.
64 * @param pArgs The handler arguments.
65 * @param pDebugger Pointer to the debugger interface.
66 */
67static RTEXITCODE handleDebugVM_DumpVMCore(HandlerArg *pArgs, IMachineDebugger *pDebugger)
68{
69 /*
70 * Parse arguments.
71 */
72 const char *pszFilename = NULL;
73 const char *pszCompression = NULL;
74
75 RTGETOPTSTATE GetState;
76 RTGETOPTUNION ValueUnion;
77 static const RTGETOPTDEF s_aOptions[] =
78 {
79 { "--filename", 'f', RTGETOPT_REQ_STRING },
80 { "--compression", 'c', RTGETOPT_REQ_STRING }
81 };
82 int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
83 AssertRCReturn(rc, RTEXITCODE_FAILURE);
84
85 while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0)
86 {
87 switch (rc)
88 {
89 case 'c':
90 if (pszCompression)
91 return errorSyntax(USAGE_DEBUGVM, "The --compression option has already been given");
92 pszCompression = ValueUnion.psz;
93 break;
94 case 'f':
95 if (pszFilename)
96 return errorSyntax(USAGE_DEBUGVM, "The --filename option has already been given");
97 pszFilename = ValueUnion.psz;
98 break;
99 default:
100 return errorGetOpt(USAGE_DEBUGVM, rc, &ValueUnion);
101 }
102 }
103
104 if (!pszFilename)
105 return errorSyntax(USAGE_DEBUGVM, "The --filename option is required");
106
107 /*
108 * Make the filename absolute before handing it on to the API.
109 */
110 char szAbsFilename[RTPATH_MAX];
111 rc = RTPathAbs(pszFilename, szAbsFilename, sizeof(szAbsFilename));
112 if (RT_FAILURE(rc))
113 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAbs failed on '%s': %Rrc", pszFilename, rc);
114
115 com::Bstr bstrFilename(szAbsFilename);
116 com::Bstr bstrCompression(pszCompression);
117 CHECK_ERROR2_RET(pDebugger, DumpGuestCore(bstrFilename.raw(), bstrCompression.raw()), RTEXITCODE_FAILURE);
118 return RTEXITCODE_SUCCESS;
119}
120
121/**
122 * Handles the statistics sub-command.
123 *
124 * @returns Suitable exit code.
125 * @param pArgs The handler arguments.
126 * @param pDebugger Pointer to the debugger interface.
127 */
128static RTEXITCODE handleDebugVM_Statistics(HandlerArg *pArgs, IMachineDebugger *pDebugger)
129{
130 /*
131 * Parse arguments.
132 */
133 bool fWithDescriptions = false;
134 const char *pszPattern = NULL; /* all */
135 bool fReset = false;
136
137 RTGETOPTSTATE GetState;
138 RTGETOPTUNION ValueUnion;
139 static const RTGETOPTDEF s_aOptions[] =
140 {
141 { "--descriptions", 'd', RTGETOPT_REQ_NOTHING },
142 { "--pattern", 'p', RTGETOPT_REQ_STRING },
143 { "--reset", 'r', RTGETOPT_REQ_NOTHING },
144 };
145 int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
146 AssertRCReturn(rc, RTEXITCODE_FAILURE);
147
148 while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0)
149 {
150 switch (rc)
151 {
152 case 'd':
153 fWithDescriptions = true;
154 break;
155
156 case 'p':
157 if (pszPattern)
158 return errorSyntax(USAGE_DEBUGVM, "Multiple --pattern options are not permitted");
159 pszPattern = ValueUnion.psz;
160 break;
161
162 case 'r':
163 fReset = true;
164 break;
165
166 default:
167 return errorGetOpt(USAGE_DEBUGVM, rc, &ValueUnion);
168 }
169 }
170
171 if (fReset && fWithDescriptions)
172 return errorSyntax(USAGE_DEBUGVM, "The --reset and --descriptions options does not mix");
173
174 /*
175 * Execute the order.
176 */
177 com::Bstr bstrPattern(pszPattern);
178 if (fReset)
179 CHECK_ERROR2_RET(pDebugger, ResetStats(bstrPattern.raw()), RTEXITCODE_FAILURE);
180 else
181 {
182 com::Bstr bstrStats;
183 CHECK_ERROR2_RET(pDebugger, GetStats(bstrPattern.raw(), fWithDescriptions, bstrStats.asOutParam()),
184 RTEXITCODE_FAILURE);
185 /* if (fFormatted)
186 { big mess }
187 else
188 */
189 RTPrintf("%ls\n", bstrStats.raw());
190 }
191
192 return RTEXITCODE_SUCCESS;
193}
194
195int handleDebugVM(HandlerArg *pArgs)
196{
197 RTEXITCODE rcExit = RTEXITCODE_FAILURE;
198
199 /*
200 * The first argument is the VM name or UUID. Open a session to it.
201 */
202 if (pArgs->argc < 2)
203 return errorSyntax(USAGE_DEBUGVM, "Too few parameters");
204 ComPtr<IMachine> ptrMachine;
205 CHECK_ERROR2_RET(pArgs->virtualBox, FindMachine(com::Bstr(pArgs->argv[0]).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
206 CHECK_ERROR2_RET(ptrMachine, LockMachine(pArgs->session, LockType_Shared), RTEXITCODE_FAILURE);
207
208 /*
209 * Get the associated console and machine debugger.
210 */
211 HRESULT rc;
212 ComPtr<IConsole> ptrConsole;
213 CHECK_ERROR(pArgs->session, COMGETTER(Console)(ptrConsole.asOutParam()));
214 if (SUCCEEDED(rc))
215 {
216 ComPtr<IMachineDebugger> ptrDebugger;
217 CHECK_ERROR(ptrConsole, COMGETTER(Debugger)(ptrDebugger.asOutParam()));
218 if (SUCCEEDED(rc))
219 {
220 /*
221 * String switch on the sub-command.
222 */
223 const char *pszSubCmd = pArgs->argv[1];
224 if (!strcmp(pszSubCmd, "dumpguestcore"))
225 rcExit = handleDebugVM_DumpVMCore(pArgs, ptrDebugger);
226 else if (!strcmp(pszSubCmd, "injectnmi"))
227 rcExit = handleDebugVM_InjectNMI(pArgs, ptrDebugger);
228 else if (!strcmp(pszSubCmd, "statistics"))
229 rcExit = handleDebugVM_Statistics(pArgs, ptrDebugger);
230 else
231 errorSyntax(USAGE_DEBUGVM, "Invalid parameter '%s'", pArgs->argv[1]);
232 }
233 }
234
235 pArgs->session->UnlockMachine();
236
237 return rcExit;
238}
239
240
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use