VirtualBox

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

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

Main: Exmplicit machine state comparisons replaced with bool "IsMetastate"-like methods.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use