VirtualBox

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

Last change on this file since 14772 was 14772, checked in by vboxsync, 16 years ago

Added vim modelines to aid following coding guidelines, like no tabs,
similar to what is already in the xidl file.

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