VirtualBox

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

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

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