VirtualBox

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

Last change on this file since 25414 was 25310, checked in by vboxsync, 15 years ago

Main: lock validator, first batch: implement per-thread stack to trace locking (disabled by default, use VBOX_WITH_LOCK_VALIDATOR, but that WILL FAIL presently)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.3 KB
RevLine 
[14627]1/* $Id: MachineDebuggerImpl.cpp 25310 2009-12-10 17:06:44Z vboxsync $ */
2
[1]3/** @file
4 *
5 * VirtualBox COM class implementation
6 */
7
8/*
[14627]9 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
[1]10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
[5999]14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
[8155]18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
[1]22 */
23
24#include "MachineDebuggerImpl.h"
[15762]25
26#include "Global.h"
[1]27#include "ConsoleImpl.h"
28#include "Logging.h"
29
30#include <VBox/em.h>
31#include <VBox/patm.h>
32#include <VBox/csam.h>
33#include <VBox/vm.h>
[444]34#include <VBox/tm.h>
[1]35#include <VBox/err.h>
36#include <VBox/hwaccm.h>
37
38// defines
[14627]39/////////////////////////////////////////////////////////////////////////////
[1]40
41
42// globals
[14627]43/////////////////////////////////////////////////////////////////////////////
[1]44
45
46// constructor / destructor
[14627]47/////////////////////////////////////////////////////////////////////////////
[1]48
[14627]49DEFINE_EMPTY_CTOR_DTOR (MachineDebugger)
50
[1]51HRESULT MachineDebugger::FinalConstruct()
52{
[21878]53 unconst(mParent) = NULL;
[1]54 return S_OK;
55}
56
57void MachineDebugger::FinalRelease()
58{
[14627]59 uninit();
[1]60}
61
[14627]62// public initializer/uninitializer for internal purposes only
63/////////////////////////////////////////////////////////////////////////////
[1]64
65/**
66 * Initializes the machine debugger object.
67 *
68 * @returns COM result indicator
[14627]69 * @param aParent handle of our parent object
[1]70 */
[14627]71HRESULT MachineDebugger::init (Console *aParent)
[1]72{
[21878]73 LogFlowThisFunc(("aParent=%p\n", aParent));
[1]74
[14627]75 ComAssertRet (aParent, E_INVALIDARG);
[1]76
[14627]77 /* Enclose the state transition NotReady->InInit->Ready */
[21878]78 AutoInitSpan autoInitSpan(this);
79 AssertReturn(autoInitSpan.isOk(), E_FAIL);
[1]80
[21878]81 unconst(mParent) = aParent;
[14627]82
83 mSinglestepQueued = ~0;
84 mRecompileUserQueued = ~0;
85 mRecompileSupervisorQueued = ~0;
86 mPatmEnabledQueued = ~0;
87 mCsamEnabledQueued = ~0;
[1]88 mLogEnabledQueued = ~0;
[444]89 mVirtualTimeRateQueued = ~0;
[14627]90 mFlushMode = false;
91
92 /* Confirm a successful initialization */
93 autoInitSpan.setSucceeded();
94
[1]95 return S_OK;
96}
97
98/**
99 * Uninitializes the instance and sets the ready flag to FALSE.
100 * Called either from FinalRelease() or by the parent when it gets destroyed.
101 */
102void MachineDebugger::uninit()
103{
[21878]104 LogFlowThisFunc(("\n"));
[1]105
[14627]106 /* Enclose the state transition Ready->InUninit->NotReady */
[21878]107 AutoUninitSpan autoUninitSpan(this);
[14627]108 if (autoUninitSpan.uninitDone())
109 return;
[1]110
[21878]111 unconst(mParent).setNull();
[14627]112 mFlushMode = false;
[1]113}
114
[14627]115// IMachineDebugger properties
116/////////////////////////////////////////////////////////////////////////////
117
[1]118/**
119 * Returns the current singlestepping flag.
120 *
121 * @returns COM status code
[14627]122 * @param aEnabled address of result variable
[1]123 */
[14627]124STDMETHODIMP MachineDebugger::COMGETTER(Singlestep) (BOOL *aEnabled)
[1]125{
[14972]126 CheckComArgOutPointerValid(aEnabled);
[14627]127
[21878]128 AutoCaller autoCaller(this);
[25149]129 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]130
[1]131 /** @todo */
[14715]132 ReturnComNotImplemented();
[1]133}
134
135/**
136 * Sets the singlestepping flag.
137 *
138 * @returns COM status code
[14627]139 * @param aEnable new singlestepping flag
[1]140 */
[14627]141STDMETHODIMP MachineDebugger::COMSETTER(Singlestep) (BOOL aEnable)
[1]142{
[21878]143 AutoCaller autoCaller(this);
[25149]144 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]145
[1]146 /** @todo */
[14715]147 ReturnComNotImplemented();
[1]148}
149
150/**
[14627]151 * Returns the current recompile user mode code flag.
[1]152 *
[14627]153 * @returns COM status code
154 * @param aEnabled address of result variable
[1]155 */
[14627]156STDMETHODIMP MachineDebugger::COMGETTER(RecompileUser) (BOOL *aEnabled)
[1]157{
[14972]158 CheckComArgOutPointerValid(aEnabled);
[1]159
[21878]160 AutoCaller autoCaller(this);
[25149]161 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[1]162
[25310]163 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]164
[5190]165 Console::SafeVMPtrQuiet pVM (mParent);
166
[1]167 if (pVM.isOk())
[14627]168 *aEnabled = !EMIsRawRing3Enabled (pVM.raw());
[1]169 else
[14627]170 *aEnabled = false;
171
[1]172 return S_OK;
173}
174
175/**
176 * Sets the recompile user mode code flag.
177 *
178 * @returns COM status
[14627]179 * @param aEnable new user mode code recompile flag.
[1]180 */
[14627]181STDMETHODIMP MachineDebugger::COMSETTER(RecompileUser) (BOOL aEnable)
[1]182{
[21878]183 LogFlowThisFunc(("enable=%d\n", aEnable));
[1]184
[21878]185 AutoCaller autoCaller(this);
[25149]186 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]187
[25310]188 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[1]189
[14627]190 if (queueSettings())
[1]191 {
[14627]192 // queue the request
193 mRecompileUserQueued = aEnable;
194 return S_OK;
[1]195 }
196
197 Console::SafeVMPtr pVM (mParent);
[25149]198 if (FAILED(pVM.rc())) return pVM.rc();
[1]199
[14627]200 EMRAWMODE rawModeFlag = aEnable ? EMRAW_RING3_DISABLE : EMRAW_RING3_ENABLE;
[23012]201 int rcVBox = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)EMR3RawSetMode, 2, pVM.raw(), rawModeFlag);
[21878]202 if (RT_SUCCESS(rcVBox))
[1]203 return S_OK;
204
[14627]205 AssertMsgFailed (("Could not set raw mode flags to %d, rcVBox = %Rrc\n",
206 rawModeFlag, rcVBox));
[1]207 return E_FAIL;
208}
209
210/**
211 * Returns the current recompile supervisor code flag.
212 *
213 * @returns COM status code
[14627]214 * @param aEnabled address of result variable
[1]215 */
[14627]216STDMETHODIMP MachineDebugger::COMGETTER(RecompileSupervisor) (BOOL *aEnabled)
[1]217{
[14972]218 CheckComArgOutPointerValid(aEnabled);
[14627]219
[21878]220 AutoCaller autoCaller(this);
[25149]221 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]222
[25310]223 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]224
[1]225 Console::SafeVMPtrQuiet pVM (mParent);
[14627]226
[1]227 if (pVM.isOk())
[14627]228 *aEnabled = !EMIsRawRing0Enabled (pVM.raw());
[1]229 else
[14627]230 *aEnabled = false;
231
[1]232 return S_OK;
233}
234
235/**
236 * Sets the new recompile supervisor code flag.
237 *
238 * @returns COM status code
[14627]239 * @param aEnable new recompile supervisor code flag
[1]240 */
[14627]241STDMETHODIMP MachineDebugger::COMSETTER(RecompileSupervisor) (BOOL aEnable)
[1]242{
[21878]243 LogFlowThisFunc(("enable=%d\n", aEnable));
[1]244
[21878]245 AutoCaller autoCaller(this);
[25149]246 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]247
[25310]248 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[1]249
[14627]250 if (queueSettings())
[1]251 {
[14627]252 // queue the request
253 mRecompileSupervisorQueued = aEnable;
254 return S_OK;
[1]255 }
256
257 Console::SafeVMPtr pVM (mParent);
[25149]258 if (FAILED(pVM.rc())) return pVM.rc();
[1]259
[14627]260 EMRAWMODE rawModeFlag = aEnable ? EMRAW_RING0_DISABLE : EMRAW_RING0_ENABLE;
[23012]261 int rcVBox = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)EMR3RawSetMode, 2, pVM.raw(), rawModeFlag);
[21878]262 if (RT_SUCCESS(rcVBox))
[1]263 return S_OK;
264
[14627]265 AssertMsgFailed (("Could not set raw mode flags to %d, rcVBox = %Rrc\n",
266 rawModeFlag, rcVBox));
[1]267 return E_FAIL;
268}
269
270/**
271 * Returns the current patch manager enabled flag.
272 *
273 * @returns COM status code
[14627]274 * @param aEnabled address of result variable
[1]275 */
[14627]276STDMETHODIMP MachineDebugger::COMGETTER(PATMEnabled) (BOOL *aEnabled)
[1]277{
[14972]278 CheckComArgOutPointerValid(aEnabled);
[14627]279
[21878]280 AutoCaller autoCaller(this);
[25149]281 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]282
[25310]283 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]284
[1]285 Console::SafeVMPtrQuiet pVM (mParent);
[14627]286
[1]287 if (pVM.isOk())
[14627]288 *aEnabled = PATMIsEnabled (pVM.raw());
[1]289 else
[14627]290 *aEnabled = false;
291
[1]292 return S_OK;
293}
294
295/**
296 * Set the new patch manager enabled flag.
297 *
298 * @returns COM status code
[14627]299 * @param aEnable new patch manager enabled flag
[1]300 */
[14627]301STDMETHODIMP MachineDebugger::COMSETTER(PATMEnabled) (BOOL aEnable)
[1]302{
[21878]303 LogFlowThisFunc(("enable=%d\n", aEnable));
[14627]304
[21878]305 AutoCaller autoCaller(this);
[25149]306 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]307
[25310]308 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[1]309
[14627]310 if (queueSettings())
[1]311 {
[14627]312 // queue the request
313 mPatmEnabledQueued = aEnable;
314 return S_OK;
[1]315 }
316
[25149]317 Console::SafeVMPtr pVM(mParent);
318 if (FAILED(pVM.rc())) return pVM.rc();
[1]319
[14627]320 PATMR3AllowPatching (pVM, aEnable);
321
[14107]322 return S_OK;
[1]323}
324
325/**
326 * Returns the current code scanner enabled flag.
327 *
328 * @returns COM status code
[14627]329 * @param aEnabled address of result variable
[1]330 */
[14627]331STDMETHODIMP MachineDebugger::COMGETTER(CSAMEnabled) (BOOL *aEnabled)
[1]332{
[14972]333 CheckComArgOutPointerValid(aEnabled);
[14627]334
[21878]335 AutoCaller autoCaller(this);
[25149]336 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]337
[25310]338 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]339
[1]340 Console::SafeVMPtrQuiet pVM (mParent);
[14627]341
[1]342 if (pVM.isOk())
[14627]343 *aEnabled = CSAMIsEnabled (pVM.raw());
[1]344 else
[14627]345 *aEnabled = false;
346
[1]347 return S_OK;
348}
349
350/**
351 * Sets the new code scanner enabled flag.
352 *
353 * @returns COM status code
[14627]354 * @param aEnable new code scanner enabled flag
[1]355 */
[14627]356STDMETHODIMP MachineDebugger::COMSETTER(CSAMEnabled) (BOOL aEnable)
[1]357{
[21878]358 LogFlowThisFunc(("enable=%d\n", aEnable));
[14627]359
[21878]360 AutoCaller autoCaller(this);
[25149]361 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]362
[25310]363 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[1]364
[14627]365 if (queueSettings())
[1]366 {
[14627]367 // queue the request
368 mCsamEnabledQueued = aEnable;
369 return S_OK;
[1]370 }
371
[25149]372 Console::SafeVMPtr pVM(mParent);
373 if (FAILED(pVM.rc())) return pVM.rc();
[1]374
375 int vrc;
[14627]376 if (aEnable)
377 vrc = CSAMEnableScanning (pVM);
[1]378 else
[14627]379 vrc = CSAMDisableScanning (pVM);
380
[21878]381 if (RT_FAILURE(vrc))
[1]382 {
383 /** @todo handle error case */
384 }
[14627]385
[1]386 return S_OK;
387}
388
389/**
390 * Returns the log enabled / disabled status.
391 *
392 * @returns COM status code
393 * @param aEnabled address of result variable
394 */
[14627]395STDMETHODIMP MachineDebugger::COMGETTER(LogEnabled) (BOOL *aEnabled)
[1]396{
[14972]397 CheckComArgOutPointerValid(aEnabled);
[14627]398
[21878]399 AutoCaller autoCaller(this);
[25149]400 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]401
[9242]402#ifdef LOG_ENABLED
[25310]403 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]404
405 const PRTLOGGER pLogInstance = RTLogDefaultInstance();
[1]406 *aEnabled = pLogInstance && !(pLogInstance->fFlags & RTLOGFLAGS_DISABLED);
[9242]407#else
408 *aEnabled = false;
409#endif
[14627]410
[1]411 return S_OK;
412}
413
414/**
415 * Enables or disables logging.
416 *
417 * @returns COM status code
418 * @param aEnabled The new code log state.
419 */
[14627]420STDMETHODIMP MachineDebugger::COMSETTER(LogEnabled) (BOOL aEnabled)
[1]421{
[21878]422 LogFlowThisFunc(("aEnabled=%d\n", aEnabled));
[1]423
[21878]424 AutoCaller autoCaller(this);
[25149]425 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]426
[25310]427 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]428
429 if (queueSettings())
[1]430 {
[14627]431 // queue the request
432 mLogEnabledQueued = aEnabled;
433 return S_OK;
[1]434 }
435
[25149]436 Console::SafeVMPtr pVM(mParent);
437 if (FAILED(pVM.rc())) return pVM.rc();
[1]438
[9242]439#ifdef LOG_ENABLED
[14627]440 int vrc = DBGFR3LogModifyFlags (pVM, aEnabled ? "enabled" : "disabled");
[21878]441 if (RT_FAILURE(vrc))
[1]442 {
443 /** @todo handle error code. */
444 }
[9242]445#endif
[14627]446
[1]447 return S_OK;
448}
449
450/**
451 * Returns the current hardware virtualization flag.
452 *
453 * @returns COM status code
[14627]454 * @param aEnabled address of result variable
[1]455 */
[14627]456STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExEnabled) (BOOL *aEnabled)
[1]457{
[14972]458 CheckComArgOutPointerValid(aEnabled);
[1]459
[21878]460 AutoCaller autoCaller(this);
[25149]461 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[1]462
[25310]463 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]464
[1]465 Console::SafeVMPtrQuiet pVM (mParent);
[14627]466
[1]467 if (pVM.isOk())
[14627]468 *aEnabled = HWACCMIsEnabled (pVM.raw());
[1]469 else
[14627]470 *aEnabled = false;
471
[1]472 return S_OK;
473}
474
475/**
[10695]476 * Returns the current nested paging flag.
477 *
478 * @returns COM status code
[14627]479 * @param aEnabled address of result variable
[10695]480 */
[14627]481STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExNestedPagingEnabled) (BOOL *aEnabled)
[10695]482{
[14972]483 CheckComArgOutPointerValid(aEnabled);
[10695]484
[21878]485 AutoCaller autoCaller(this);
[25149]486 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10695]487
[25310]488 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]489
[10695]490 Console::SafeVMPtrQuiet pVM (mParent);
[14627]491
[10695]492 if (pVM.isOk())
[14627]493 *aEnabled = HWACCMR3IsNestedPagingActive (pVM.raw());
[10695]494 else
[14627]495 *aEnabled = false;
496
[10695]497 return S_OK;
498}
499
500/**
[13221]501 * Returns the current VPID flag.
502 *
503 * @returns COM status code
[14627]504 * @param aEnabled address of result variable
[13221]505 */
[14627]506STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExVPIDEnabled) (BOOL *aEnabled)
[13221]507{
[14972]508 CheckComArgOutPointerValid(aEnabled);
[13221]509
[21878]510 AutoCaller autoCaller(this);
[25149]511 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[13221]512
[25310]513 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]514
[13221]515 Console::SafeVMPtrQuiet pVM (mParent);
[14627]516
[13221]517 if (pVM.isOk())
[14627]518 *aEnabled = HWACCMR3IsVPIDActive (pVM.raw());
[13221]519 else
[14627]520 *aEnabled = false;
521
[13221]522 return S_OK;
523}
524
525/**
[7990]526 * Returns the current PAE flag.
527 *
528 * @returns COM status code
[14627]529 * @param aEnabled address of result variable
[7990]530 */
[14627]531STDMETHODIMP MachineDebugger::COMGETTER(PAEEnabled) (BOOL *aEnabled)
[7990]532{
[14972]533 CheckComArgOutPointerValid(aEnabled);
[7990]534
[21878]535 AutoCaller autoCaller(this);
[25149]536 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[7990]537
[25310]538 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]539
[7990]540 Console::SafeVMPtrQuiet pVM (mParent);
[14627]541
[7990]542 if (pVM.isOk())
543 {
[18927]544 uint64_t cr4 = CPUMGetGuestCR4 (VMMGetCpu0(pVM.raw()));
[14627]545 *aEnabled = !!(cr4 & X86_CR4_PAE);
[7990]546 }
547 else
[14627]548 *aEnabled = false;
549
[7990]550 return S_OK;
551}
552
553/**
[444]554 * Returns the current virtual time rate.
[5190]555 *
[444]556 * @returns COM status code.
[14627]557 * @param aPct Where to store the rate.
[444]558 */
[14627]559STDMETHODIMP MachineDebugger::COMGETTER(VirtualTimeRate) (ULONG *aPct)
[444]560{
[14972]561 CheckComArgOutPointerValid(aPct);
[444]562
[21878]563 AutoCaller autoCaller(this);
[25149]564 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[444]565
[25310]566 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]567
[444]568 Console::SafeVMPtrQuiet pVM (mParent);
[14627]569
[444]570 if (pVM.isOk())
[19500]571 *aPct = TMGetWarpDrive (pVM);
[444]572 else
[14627]573 *aPct = 100;
574
[444]575 return S_OK;
576}
577
578/**
579 * Returns the current virtual time rate.
[5190]580 *
[444]581 * @returns COM status code.
[14627]582 * @param aPct Where to store the rate.
[444]583 */
[14627]584STDMETHODIMP MachineDebugger::COMSETTER(VirtualTimeRate) (ULONG aPct)
[444]585{
[14627]586 if (aPct < 2 || aPct > 20000)
[444]587 return E_INVALIDARG;
588
[21878]589 AutoCaller autoCaller(this);
[25149]590 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[14627]591
[25310]592 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[444]593
[14627]594 if (queueSettings())
[444]595 {
[14627]596 // queue the request
597 mVirtualTimeRateQueued = aPct;
598 return S_OK;
[444]599 }
600
[25149]601 Console::SafeVMPtr pVM(mParent);
602 if (FAILED(pVM.rc())) return pVM.rc();
[444]603
[19500]604 int vrc = TMR3SetWarpDrive (pVM, aPct);
[21878]605 if (RT_FAILURE(vrc))
[444]606 {
607 /** @todo handle error code. */
608 }
[14627]609
[444]610 return S_OK;
611}
612
613/**
[1]614 * Hack for getting the VM handle.
615 * This is only temporary (promise) while prototyping the debugger.
616 *
617 * @returns COM status code
[14627]618 * @param aVm Where to store the vm handle.
[1]619 * Since there is no uintptr_t in COM, we're using the max integer.
620 * (No, ULONG is not pointer sized!)
621 */
[14627]622STDMETHODIMP MachineDebugger::COMGETTER(VM) (ULONG64 *aVm)
[1]623{
[14972]624 CheckComArgOutPointerValid(aVm);
[1]625
[21878]626 AutoCaller autoCaller(this);
[25149]627 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[1]628
[25310]629 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[14627]630
[25149]631 Console::SafeVMPtr pVM(mParent);
632 if (FAILED(pVM.rc())) return pVM.rc();
[1]633
[14627]634 *aVm = (uintptr_t)pVM.raw();
[1]635
636 /*
637 * Note: pVM protection provided by SafeVMPtr is no more effective
638 * after we return from this method.
639 */
640
641 return S_OK;
642}
643
[14627]644// IMachineDebugger methods
645/////////////////////////////////////////////////////////////////////////////
646
647/**
648 * Resets VM statistics.
649 *
650 * @returns COM status code.
651 * @param aPattern The selection pattern. A bit similar to filename globbing.
652 */
[15051]653STDMETHODIMP MachineDebugger::ResetStats (IN_BSTR aPattern)
[14627]654{
655 Console::SafeVMPtrQuiet pVM (mParent);
656
[15827]657 if (!pVM.isOk())
658 return E_FAIL;
[14627]659
[15827]660 STAMR3Reset (pVM, Utf8Str (aPattern).raw());
661
[14627]662 return S_OK;
663}
664
665/**
666 * Dumps VM statistics to the log.
667 *
668 * @returns COM status code.
669 * @param aPattern The selection pattern. A bit similar to filename globbing.
670 */
[15051]671STDMETHODIMP MachineDebugger::DumpStats (IN_BSTR aPattern)
[14627]672{
673 Console::SafeVMPtrQuiet pVM (mParent);
674
[15827]675 if (!pVM.isOk())
676 return E_FAIL;
[14627]677
[15827]678 STAMR3Dump (pVM, Utf8Str (aPattern).raw());
679
[14627]680 return S_OK;
681}
682
683/**
684 * Get the VM statistics in an XML format.
685 *
686 * @returns COM status code.
687 * @param aPattern The selection pattern. A bit similar to filename globbing.
688 * @param aWithDescriptions Whether to include the descriptions.
689 * @param aStats The XML document containing the statistics.
690 */
[15051]691STDMETHODIMP MachineDebugger::GetStats (IN_BSTR aPattern, BOOL aWithDescriptions, BSTR *aStats)
[14627]692{
693 Console::SafeVMPtrQuiet pVM (mParent);
694
695 if (!pVM.isOk())
696 return E_FAIL;
697
698 char *pszSnapshot;
699 int vrc = STAMR3Snapshot (pVM, Utf8Str (aPattern).raw(), &pszSnapshot, NULL,
700 !!aWithDescriptions);
[21878]701 if (RT_FAILURE(vrc))
[14627]702 return vrc == VERR_NO_MEMORY ? E_OUTOFMEMORY : E_FAIL;
703
704 /** @todo this is horribly inefficient! And it's kinda difficult to tell whether it failed...
705 * Must use UTF-8 or ASCII here and completely avoid these two extra copy operations.
706 * Until that's done, this method is kind of useless for debugger statistics GUI because
707 * of the amount statistics in a debug build. */
[21878]708 Bstr (pszSnapshot).cloneTo(aStats);
[14627]709
710 return S_OK;
711}
712
[15827]713/**
714 * Set the new patch manager enabled flag.
715 *
716 * @returns COM status code
717 * @param new patch manager enabled flag
718 */
719STDMETHODIMP MachineDebugger::InjectNMI()
720{
[23392]721 LogFlowThisFunc(("\n"));
[14627]722
[21878]723 AutoCaller autoCaller(this);
[25149]724 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[15827]725
[25310]726 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[15827]727
[25149]728 Console::SafeVMPtr pVM(mParent);
729 if (FAILED(pVM.rc())) return pVM.rc();
[15827]730
731 HWACCMR3InjectNMI(pVM);
732
733 return S_OK;
734}
735
736
[14627]737// public methods only for internal purposes
738/////////////////////////////////////////////////////////////////////////////
739
[1]740void MachineDebugger::flushQueuedSettings()
741{
[14627]742 mFlushMode = true;
743 if (mSinglestepQueued != ~0)
[1]744 {
[14627]745 COMSETTER(Singlestep) (mSinglestepQueued);
746 mSinglestepQueued = ~0;
[1]747 }
[14627]748 if (mRecompileUserQueued != ~0)
[1]749 {
[14627]750 COMSETTER(RecompileUser) (mRecompileUserQueued);
751 mRecompileUserQueued = ~0;
[1]752 }
[14627]753 if (mRecompileSupervisorQueued != ~0)
[1]754 {
[14627]755 COMSETTER(RecompileSupervisor) (mRecompileSupervisorQueued);
756 mRecompileSupervisorQueued = ~0;
[1]757 }
[14627]758 if (mPatmEnabledQueued != ~0)
[1]759 {
[14627]760 COMSETTER(PATMEnabled) (mPatmEnabledQueued);
761 mPatmEnabledQueued = ~0;
[1]762 }
[14627]763 if (mCsamEnabledQueued != ~0)
[1]764 {
[14627]765 COMSETTER(CSAMEnabled) (mCsamEnabledQueued);
766 mCsamEnabledQueued = ~0;
[1]767 }
768 if (mLogEnabledQueued != ~0)
769 {
[14627]770 COMSETTER(LogEnabled) (mLogEnabledQueued);
[1]771 mLogEnabledQueued = ~0;
772 }
[776]773 if (mVirtualTimeRateQueued != ~(uint32_t)0)
[444]774 {
[14627]775 COMSETTER(VirtualTimeRate) (mVirtualTimeRateQueued);
[444]776 mVirtualTimeRateQueued = ~0;
777 }
[14627]778 mFlushMode = false;
[1]779}
780
781// private methods
[14627]782/////////////////////////////////////////////////////////////////////////////
783
784bool MachineDebugger::queueSettings() const
785{
786 if (!mFlushMode)
787 {
788 // check if the machine is running
789 MachineState_T machineState;
790 mParent->COMGETTER(State) (&machineState);
[24301]791 switch (machineState)
792 {
[14627]793 // queue the request
[24301]794 default:
795 return true;
796
797 case MachineState_Running:
798 case MachineState_Paused:
799 case MachineState_Stuck:
800 case MachineState_LiveSnapshotting:
801 case MachineState_Teleporting:
802 break;
803 }
[14627]804 }
805 return false;
806}
[14772]807/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use