VirtualBox

source: vbox/trunk/src/VBox/Main/MachineDebuggerImpl.cpp@ 226

Last change on this file since 226 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#include "MachineDebuggerImpl.h"
23#include "ConsoleImpl.h"
24#include "Logging.h"
25
26#include <VBox/em.h>
27#include <VBox/patm.h>
28#include <VBox/csam.h>
29#include <VBox/vm.h>
30#include <VBox/err.h>
31#include <VBox/hwaccm.h>
32
33//
34// defines
35//
36
37
38//
39// globals
40//
41
42
43//
44// constructor / destructor
45//
46
47HRESULT MachineDebugger::FinalConstruct()
48{
49 mParent = NULL;
50 return S_OK;
51}
52
53void MachineDebugger::FinalRelease()
54{
55 if (isReady())
56 uninit();
57}
58
59//
60// public methods
61//
62
63/**
64 * Initializes the machine debugger object.
65 *
66 * @returns COM result indicator
67 * @param parent handle of our parent object
68 */
69HRESULT MachineDebugger::init(Console *parent)
70{
71 LogFlow(("MachineDebugger::init(): isReady=%d\n", isReady()));
72
73 ComAssertRet (parent, E_INVALIDARG);
74
75 AutoLock lock(this);
76 ComAssertRet (!isReady(), E_UNEXPECTED);
77
78 mParent = parent;
79 singlestepQueued = ~0;
80 recompileUserQueued = ~0;
81 recompileSupervisorQueued = ~0;
82 patmEnabledQueued = ~0;
83 csamEnabledQueued = ~0;
84 mLogEnabledQueued = ~0;
85 fFlushMode = false;
86 setReady(true);
87 return S_OK;
88}
89
90/**
91 * Uninitializes the instance and sets the ready flag to FALSE.
92 * Called either from FinalRelease() or by the parent when it gets destroyed.
93 */
94void MachineDebugger::uninit()
95{
96 LogFlow(("MachineDebugger::uninit(): isReady=%d\n", isReady()));
97
98 AutoLock lock(this);
99 AssertReturn (isReady(), (void) 0);
100
101 setReady (false);
102}
103
104/**
105 * Returns the current singlestepping flag.
106 *
107 * @returns COM status code
108 * @param enabled address of result variable
109 */
110STDMETHODIMP MachineDebugger::COMGETTER(Singlestep)(BOOL *enabled)
111{
112 if (!enabled)
113 return E_POINTER;
114 AutoLock lock(this);
115 CHECK_READY();
116 /** @todo */
117 return E_NOTIMPL;
118}
119
120/**
121 * Sets the singlestepping flag.
122 *
123 * @returns COM status code
124 * @param enable new singlestepping flag
125 */
126STDMETHODIMP MachineDebugger::COMSETTER(Singlestep)(BOOL enable)
127{
128 AutoLock lock(this);
129 CHECK_READY();
130 /** @todo */
131 return E_NOTIMPL;
132}
133
134/**
135 * Resets VM statistics
136 *
137 * @returns COM status code
138 */
139STDMETHODIMP MachineDebugger::ResetStats()
140{
141 Console::SafeVMPtrQuiet pVM (mParent);
142 if (pVM.isOk())
143 STAMR3Reset(pVM, NULL);
144 return S_OK;
145}
146
147/**
148 * Dumps VM statistics to the log
149 *
150 * @returns COM status code
151 */
152STDMETHODIMP MachineDebugger::DumpStats()
153{
154 Console::SafeVMPtrQuiet pVM (mParent);
155 if (pVM.isOk())
156 STAMR3Dump(pVM, NULL);
157 return S_OK;
158}
159
160/**
161 * Returns the current recompile user mode code flag.
162 *
163 * @returns COM status code
164 * @param enabled address of result variable
165 */
166STDMETHODIMP MachineDebugger::COMGETTER(RecompileUser)(BOOL *enabled)
167{
168 if (!enabled)
169 return E_POINTER;
170 AutoLock lock(this);
171 CHECK_READY();
172 Console::SafeVMPtrQuiet pVM (mParent);
173 if (pVM.isOk())
174 *enabled = !EMIsRawRing3Enabled(pVM.raw());
175 else
176 *enabled = false;
177 return S_OK;
178}
179
180/**
181 * Sets the recompile user mode code flag.
182 *
183 * @returns COM status
184 * @param enable new user mode code recompile flag.
185 */
186STDMETHODIMP MachineDebugger::COMSETTER(RecompileUser)(BOOL enable)
187{
188 LogFlowThisFunc (("enable=%d\n", enable));
189
190 AutoLock lock(this);
191 CHECK_READY();
192
193 if (!fFlushMode)
194 {
195 // check if the machine is running
196 MachineState_T machineState;
197 mParent->COMGETTER(State)(&machineState);
198 if (machineState != MachineState_Running)
199 {
200 // queue the request
201 recompileUserQueued = enable;
202 return S_OK;
203 }
204 }
205
206 Console::SafeVMPtr pVM (mParent);
207 CheckComRCReturnRC (pVM.rc());
208
209 PVMREQ pReq;
210 EMRAWMODE rawModeFlag = enable ? EMRAW_RING3_DISABLE : EMRAW_RING3_ENABLE;
211 int rcVBox = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT,
212 (PFNRT)EMR3RawSetMode, 2, pVM.raw(), rawModeFlag);
213 if (VBOX_SUCCESS(rcVBox))
214 {
215 rcVBox = pReq->iStatus;
216 VMR3ReqFree(pReq);
217 }
218
219 if (VBOX_SUCCESS(rcVBox))
220 return S_OK;
221
222 AssertMsgFailed(("Could not set raw mode flags to %d, rcVBox = %Vrc\n",
223 rawModeFlag, rcVBox));
224 return E_FAIL;
225}
226
227/**
228 * Returns the current recompile supervisor code flag.
229 *
230 * @returns COM status code
231 * @param enabled address of result variable
232 */
233STDMETHODIMP MachineDebugger::COMGETTER(RecompileSupervisor)(BOOL *enabled)
234{
235 if (!enabled)
236 return E_POINTER;
237 AutoLock lock(this);
238 CHECK_READY();
239 Console::SafeVMPtrQuiet pVM (mParent);
240 if (pVM.isOk())
241 *enabled = !EMIsRawRing0Enabled(pVM.raw());
242 else
243 *enabled = false;
244 return S_OK;
245}
246
247/**
248 * Sets the new recompile supervisor code flag.
249 *
250 * @returns COM status code
251 * @param enable new recompile supervisor code flag
252 */
253STDMETHODIMP MachineDebugger::COMSETTER(RecompileSupervisor)(BOOL enable)
254{
255 LogFlowThisFunc (("enable=%d\n", enable));
256
257 AutoLock lock(this);
258 CHECK_READY();
259
260 if (!fFlushMode)
261 {
262 // check if the machine is running
263 MachineState_T machineState;
264 mParent->COMGETTER(State)(&machineState);
265 if (machineState != MachineState_Running)
266 {
267 // queue the request
268 recompileSupervisorQueued = enable;
269 return S_OK;
270 }
271 }
272
273 Console::SafeVMPtr pVM (mParent);
274 CheckComRCReturnRC (pVM.rc());
275
276 PVMREQ pReq;
277 EMRAWMODE rawModeFlag = enable ? EMRAW_RING0_DISABLE : EMRAW_RING0_ENABLE;
278 int rcVBox = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT,
279 (PFNRT)EMR3RawSetMode, 2, pVM.raw(), rawModeFlag);
280 if (VBOX_SUCCESS(rcVBox))
281 {
282 rcVBox = pReq->iStatus;
283 VMR3ReqFree(pReq);
284 }
285
286 if (VBOX_SUCCESS(rcVBox))
287 return S_OK;
288
289 AssertMsgFailed(("Could not set raw mode flags to %d, rcVBox = %Vrc\n",
290 rawModeFlag, rcVBox));
291 return E_FAIL;
292}
293
294/**
295 * Returns the current patch manager enabled flag.
296 *
297 * @returns COM status code
298 * @param enabled address of result variable
299 */
300STDMETHODIMP MachineDebugger::COMGETTER(PATMEnabled)(BOOL *enabled)
301{
302 if (!enabled)
303 return E_POINTER;
304 AutoLock lock(this);
305 CHECK_READY();
306 Console::SafeVMPtrQuiet pVM (mParent);
307 if (pVM.isOk())
308 *enabled = PATMIsEnabled(pVM.raw());
309 else
310 *enabled = false;
311 return S_OK;
312}
313
314/**
315 * Set the new patch manager enabled flag.
316 *
317 * @returns COM status code
318 * @param new patch manager enabled flag
319 */
320STDMETHODIMP MachineDebugger::COMSETTER(PATMEnabled)(BOOL enable)
321{
322 AutoLock lock(this);
323 CHECK_READY();
324 LogFlowThisFunc (("enable=%d\n", enable));
325
326 if (!fFlushMode)
327 {
328 // check if the machine is running
329 MachineState_T machineState;
330 mParent->COMGETTER(State)(&machineState);
331 if (machineState != MachineState_Running)
332 {
333 // queue the request
334 patmEnabledQueued = enable;
335 return S_OK;
336 }
337 }
338
339 Console::SafeVMPtr pVM (mParent);
340 CheckComRCReturnRC (pVM.rc());
341
342 PATMR3AllowPatching(pVM, enable);
343 return E_NOTIMPL;
344}
345
346/**
347 * Returns the current code scanner enabled flag.
348 *
349 * @returns COM status code
350 * @param enabled address of result variable
351 */
352STDMETHODIMP MachineDebugger::COMGETTER(CSAMEnabled)(BOOL *enabled)
353{
354 if (!enabled)
355 return E_POINTER;
356 AutoLock lock(this);
357 CHECK_READY();
358 Console::SafeVMPtrQuiet pVM (mParent);
359 if (pVM.isOk())
360 *enabled = CSAMIsEnabled(pVM.raw());
361 else
362 *enabled = false;
363 return S_OK;
364}
365
366/**
367 * Sets the new code scanner enabled flag.
368 *
369 * @returns COM status code
370 * @param enable new code scanner enabled flag
371 */
372STDMETHODIMP MachineDebugger::COMSETTER(CSAMEnabled)(BOOL enable)
373{
374 AutoLock lock(this);
375 CHECK_READY();
376 LogFlowThisFunc (("enable=%d\n", enable));
377
378 if (!fFlushMode)
379 {
380 // check if the machine is running
381 MachineState_T machineState;
382 mParent->COMGETTER(State)(&machineState);
383 if (machineState != MachineState_Running)
384 {
385 // queue the request
386 csamEnabledQueued = enable;
387 return S_OK;
388 }
389 }
390
391 Console::SafeVMPtr pVM (mParent);
392 CheckComRCReturnRC (pVM.rc());
393
394 int vrc;
395 if (enable)
396 vrc = CSAMEnableScanning(pVM);
397 else
398 vrc = CSAMDisableScanning(pVM);
399 if (VBOX_FAILURE(vrc))
400 {
401 /** @todo handle error case */
402 }
403 return S_OK;
404}
405
406/**
407 * Returns the log enabled / disabled status.
408 *
409 * @returns COM status code
410 * @param aEnabled address of result variable
411 */
412STDMETHODIMP MachineDebugger::COMGETTER(LogEnabled)(BOOL *aEnabled)
413{
414 if (!aEnabled)
415 return E_POINTER;
416 AutoLock alock(this);
417 CHECK_READY();
418 PRTLOGGER pLogInstance = RTLogDefaultInstance();
419 *aEnabled = pLogInstance && !(pLogInstance->fFlags & RTLOGFLAGS_DISABLED);
420 return S_OK;
421}
422
423/**
424 * Enables or disables logging.
425 *
426 * @returns COM status code
427 * @param aEnabled The new code log state.
428 */
429STDMETHODIMP MachineDebugger::COMSETTER(LogEnabled)(BOOL aEnabled)
430{
431 AutoLock alock(this);
432
433 CHECK_READY();
434 LogFlowThisFunc (("aEnabled=%d\n", aEnabled));
435
436 if (!fFlushMode)
437 {
438 // check if the machine is running
439 MachineState_T machineState;
440 mParent->COMGETTER(State)(&machineState);
441 if (machineState != MachineState_Running)
442 {
443 // queue the request
444 mLogEnabledQueued = aEnabled;
445 return S_OK;
446 }
447 }
448
449 Console::SafeVMPtr pVM (mParent);
450 CheckComRCReturnRC (pVM.rc());
451
452 int vrc = DBGFR3LogModifyFlags(pVM, aEnabled ? "enabled" : "disabled");
453 if (VBOX_FAILURE(vrc))
454 {
455 /** @todo handle error code. */
456 }
457 return S_OK;
458}
459
460/**
461 * Returns the current hardware virtualization flag.
462 *
463 * @returns COM status code
464 * @param enabled address of result variable
465 */
466STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExEnabled)(BOOL *enabled)
467{
468 if (!enabled)
469 return E_POINTER;
470
471 AutoLock lock(this);
472 CHECK_READY();
473
474 Console::SafeVMPtrQuiet pVM (mParent);
475 if (pVM.isOk())
476 *enabled = HWACCMIsEnabled(pVM.raw());
477 else
478 *enabled = false;
479 return S_OK;
480}
481
482/**
483 * Hack for getting the VM handle.
484 * This is only temporary (promise) while prototyping the debugger.
485 *
486 * @returns COM status code
487 * @param vm Where to store the vm handle.
488 * Since there is no uintptr_t in COM, we're using the max integer.
489 * (No, ULONG is not pointer sized!)
490 */
491STDMETHODIMP MachineDebugger::COMGETTER(VM)(ULONG64 *vm)
492{
493 if (!vm)
494 return E_POINTER;
495
496 AutoLock lock(this);
497 CHECK_READY();
498
499 Console::SafeVMPtr pVM (mParent);
500 CheckComRCReturnRC (pVM.rc());
501
502 *vm = (uintptr_t)pVM.raw();
503
504 /*
505 * Note: pVM protection provided by SafeVMPtr is no more effective
506 * after we return from this method.
507 */
508
509 return S_OK;
510}
511
512//
513// "public-private" methods
514//
515void MachineDebugger::flushQueuedSettings()
516{
517 fFlushMode = true;
518 if (singlestepQueued != ~0)
519 {
520 COMSETTER(Singlestep)(singlestepQueued);
521 singlestepQueued = ~0;
522 }
523 if (recompileUserQueued != ~0)
524 {
525 COMSETTER(RecompileUser)(recompileUserQueued);
526 recompileUserQueued = ~0;
527 }
528 if (recompileSupervisorQueued != ~0)
529 {
530 COMSETTER(RecompileSupervisor)(recompileSupervisorQueued);
531 recompileSupervisorQueued = ~0;
532 }
533 if (patmEnabledQueued != ~0)
534 {
535 COMSETTER(PATMEnabled)(patmEnabledQueued);
536 patmEnabledQueued = ~0;
537 }
538 if (csamEnabledQueued != ~0)
539 {
540 COMSETTER(CSAMEnabled)(csamEnabledQueued);
541 csamEnabledQueued = ~0;
542 }
543 if (mLogEnabledQueued != ~0)
544 {
545 COMSETTER(LogEnabled)(mLogEnabledQueued);
546 mLogEnabledQueued = ~0;
547 }
548 fFlushMode = false;
549}
550
551//
552// private methods
553//
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette