VirtualBox

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

Last change on this file since 35305 was 35250, checked in by vboxsync, 14 years ago

IMachineDebugger: More methods and attribute stubs that may come in useful.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.9 KB
Line 
1/* $Id: MachineDebuggerImpl.cpp 35250 2010-12-20 16:10:30Z 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.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
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
456STDMETHODIMP MachineDebugger::COMGETTER(LogFlags)(BSTR *a_pbstrSettings)
457{
458 ReturnComNotImplemented();
459}
460
461STDMETHODIMP MachineDebugger::COMGETTER(LogGroups)(BSTR *a_pbstrSettings)
462{
463 ReturnComNotImplemented();
464}
465
466STDMETHODIMP MachineDebugger::COMGETTER(LogDestinations)(BSTR *a_pbstrSettings)
467{
468 ReturnComNotImplemented();
469}
470
471/**
472 * Returns the current hardware virtualization flag.
473 *
474 * @returns COM status code
475 * @param aEnabled address of result variable
476 */
477STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExEnabled) (BOOL *aEnabled)
478{
479 CheckComArgOutPointerValid(aEnabled);
480
481 AutoCaller autoCaller(this);
482 if (FAILED(autoCaller.rc())) return autoCaller.rc();
483
484 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
485
486 Console::SafeVMPtrQuiet pVM (mParent);
487
488 if (pVM.isOk())
489 *aEnabled = HWACCMIsEnabled (pVM.raw());
490 else
491 *aEnabled = false;
492
493 return S_OK;
494}
495
496/**
497 * Returns the current nested paging flag.
498 *
499 * @returns COM status code
500 * @param aEnabled address of result variable
501 */
502STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExNestedPagingEnabled) (BOOL *aEnabled)
503{
504 CheckComArgOutPointerValid(aEnabled);
505
506 AutoCaller autoCaller(this);
507 if (FAILED(autoCaller.rc())) return autoCaller.rc();
508
509 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
510
511 Console::SafeVMPtrQuiet pVM (mParent);
512
513 if (pVM.isOk())
514 *aEnabled = HWACCMR3IsNestedPagingActive (pVM.raw());
515 else
516 *aEnabled = false;
517
518 return S_OK;
519}
520
521/**
522 * Returns the current VPID flag.
523 *
524 * @returns COM status code
525 * @param aEnabled address of result variable
526 */
527STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExVPIDEnabled) (BOOL *aEnabled)
528{
529 CheckComArgOutPointerValid(aEnabled);
530
531 AutoCaller autoCaller(this);
532 if (FAILED(autoCaller.rc())) return autoCaller.rc();
533
534 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
535
536 Console::SafeVMPtrQuiet pVM (mParent);
537
538 if (pVM.isOk())
539 *aEnabled = HWACCMR3IsVPIDActive (pVM.raw());
540 else
541 *aEnabled = false;
542
543 return S_OK;
544}
545
546STDMETHODIMP MachineDebugger::COMGETTER(OSName)(BSTR *a_pbstrName)
547{
548 ReturnComNotImplemented();
549}
550
551STDMETHODIMP MachineDebugger::COMGETTER(OSVersion)(BSTR *a_pbstrVersion)
552{
553 ReturnComNotImplemented();
554}
555
556/**
557 * Returns the current PAE flag.
558 *
559 * @returns COM status code
560 * @param aEnabled address of result variable
561 */
562STDMETHODIMP MachineDebugger::COMGETTER(PAEEnabled) (BOOL *aEnabled)
563{
564 CheckComArgOutPointerValid(aEnabled);
565
566 AutoCaller autoCaller(this);
567 if (FAILED(autoCaller.rc())) return autoCaller.rc();
568
569 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
570
571 Console::SafeVMPtrQuiet pVM (mParent);
572
573 if (pVM.isOk())
574 {
575 uint64_t cr4 = CPUMGetGuestCR4 (VMMGetCpu0(pVM.raw()));
576 *aEnabled = !!(cr4 & X86_CR4_PAE);
577 }
578 else
579 *aEnabled = false;
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::COMGETTER(VirtualTimeRate) (ULONG *aPct)
591{
592 CheckComArgOutPointerValid(aPct);
593
594 AutoCaller autoCaller(this);
595 if (FAILED(autoCaller.rc())) return autoCaller.rc();
596
597 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
598
599 Console::SafeVMPtrQuiet pVM (mParent);
600
601 if (pVM.isOk())
602 *aPct = TMGetWarpDrive (pVM);
603 else
604 *aPct = 100;
605
606 return S_OK;
607}
608
609/**
610 * Returns the current virtual time rate.
611 *
612 * @returns COM status code.
613 * @param aPct Where to store the rate.
614 */
615STDMETHODIMP MachineDebugger::COMSETTER(VirtualTimeRate) (ULONG aPct)
616{
617 if (aPct < 2 || aPct > 20000)
618 return E_INVALIDARG;
619
620 AutoCaller autoCaller(this);
621 if (FAILED(autoCaller.rc())) return autoCaller.rc();
622
623 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
624
625 if (queueSettings())
626 {
627 // queue the request
628 mVirtualTimeRateQueued = aPct;
629 return S_OK;
630 }
631
632 Console::SafeVMPtr pVM(mParent);
633 if (FAILED(pVM.rc())) return pVM.rc();
634
635 int vrc = TMR3SetWarpDrive (pVM, aPct);
636 if (RT_FAILURE(vrc))
637 {
638 /** @todo handle error code. */
639 }
640
641 return S_OK;
642}
643
644/**
645 * Hack for getting the VM handle.
646 * This is only temporary (promise) while prototyping the debugger.
647 *
648 * @returns COM status code
649 * @param aVm Where to store the vm handle.
650 * Since there is no uintptr_t in COM, we're using the max integer.
651 * (No, ULONG is not pointer sized!)
652 */
653STDMETHODIMP MachineDebugger::COMGETTER(VM) (LONG64 *aVm)
654{
655 CheckComArgOutPointerValid(aVm);
656
657 AutoCaller autoCaller(this);
658 if (FAILED(autoCaller.rc())) return autoCaller.rc();
659
660 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
661
662 Console::SafeVMPtr pVM(mParent);
663 if (FAILED(pVM.rc())) return pVM.rc();
664
665 *aVm = (intptr_t)pVM.raw();
666
667 /*
668 * Note: pVM protection provided by SafeVMPtr is no more effective
669 * after we return from this method.
670 */
671
672 return S_OK;
673}
674
675// IMachineDebugger methods
676/////////////////////////////////////////////////////////////////////////////
677
678STDMETHODIMP MachineDebugger::DumpGuestCore(IN_BSTR a_bstrFilename, IN_BSTR a_bstrCompression)
679{
680 CheckComArgStrNotEmptyOrNull(a_bstrFilename);
681 Utf8Str strFilename(a_bstrFilename);
682 if (a_bstrCompression && *a_bstrCompression)
683 return setError(E_INVALIDARG, tr("The compression parameter must be empty"));
684
685 AutoCaller autoCaller(this);
686 HRESULT hrc = autoCaller.rc();
687 if (SUCCEEDED(hrc))
688 {
689 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
690 Console::SafeVMPtr ptrVM(mParent);
691 hrc = ptrVM.rc();
692 if (SUCCEEDED(hrc))
693 {
694 int vrc = DBGFR3CoreWrite(ptrVM, strFilename.c_str(), false /*fReplaceFile*/);
695 if (RT_SUCCESS(vrc))
696 hrc = S_OK;
697 else
698 hrc = setError(E_FAIL, tr("DBGFR3CoreWrite failed with %Rrc"), vrc);
699 }
700 }
701
702 return hrc;
703}
704
705STDMETHODIMP MachineDebugger::DumpHostProcessCore(IN_BSTR a_bstrFilename, IN_BSTR a_bstrCompression)
706{
707 ReturnComNotImplemented();
708}
709
710STDMETHODIMP MachineDebugger::Info(IN_BSTR a_bstrName, IN_BSTR a_bstrArgs, BSTR *a_pbstrInfo)
711{
712 ReturnComNotImplemented();
713}
714
715STDMETHODIMP MachineDebugger::InjectNMI()
716{
717 LogFlowThisFunc(("\n"));
718
719 AutoCaller autoCaller(this);
720 HRESULT hrc = autoCaller.rc();
721 if (SUCCEEDED(hrc))
722 {
723 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
724 Console::SafeVMPtr ptrVM(mParent);
725 hrc = ptrVM.rc();
726 if (SUCCEEDED(hrc))
727 {
728 int vrc = HWACCMR3InjectNMI(ptrVM);
729 if (RT_SUCCESS(vrc))
730 hrc = S_OK;
731 else
732 hrc = setError(E_FAIL, tr("HWACCMR3InjectNMI failed with %Rrc"), vrc);
733 }
734 }
735 return hrc;
736}
737
738STDMETHODIMP MachineDebugger::ModifyLogFlags(IN_BSTR a_bstrSettings)
739{
740 ReturnComNotImplemented();
741}
742
743STDMETHODIMP MachineDebugger::ModifyLogGroups(IN_BSTR a_bstrSettings)
744{
745 ReturnComNotImplemented();
746}
747
748STDMETHODIMP MachineDebugger::ModifyLogDestinations(IN_BSTR a_bstrSettings)
749{
750 ReturnComNotImplemented();
751}
752
753STDMETHODIMP MachineDebugger::ReadPhysicalMemory(LONG64 a_Address, ULONG a_cbRead, ComSafeArrayOut(BYTE, a_abData))
754{
755 ReturnComNotImplemented();
756}
757
758STDMETHODIMP MachineDebugger::WritePhysicalMemory(LONG64 a_Address, ULONG a_cbRead, ComSafeArrayIn(BYTE, a_abData))
759{
760 ReturnComNotImplemented();
761}
762
763STDMETHODIMP MachineDebugger::ReadVirtualMemory(ULONG a_idCpu, LONG64 a_Address, ULONG a_cbRead, ComSafeArrayOut(BYTE, a_abData))
764{
765 ReturnComNotImplemented();
766}
767
768STDMETHODIMP MachineDebugger::WriteVirtualMemory(ULONG a_idCpu, LONG64 a_Address, ULONG a_cbRead, ComSafeArrayIn(BYTE, a_abData))
769{
770 ReturnComNotImplemented();
771}
772
773STDMETHODIMP MachineDebugger::DetectOS(BSTR *a_pbstrName)
774{
775 ReturnComNotImplemented();
776}
777
778STDMETHODIMP MachineDebugger::GetRegister(ULONG a_idCpu, IN_BSTR a_bstrName, BSTR *a_pbstrValue)
779{
780 ReturnComNotImplemented();
781}
782
783STDMETHODIMP MachineDebugger::GetRegisters(ULONG a_idCpu, ComSafeArrayOut(BSTR, a_bstrNames), ComSafeArrayOut(BSTR, a_bstrValues))
784{
785 ReturnComNotImplemented();
786}
787
788STDMETHODIMP MachineDebugger::SetRegister(ULONG a_idCpu, IN_BSTR a_bstrName, IN_BSTR a_bstrValue)
789{
790 ReturnComNotImplemented();
791}
792
793STDMETHODIMP MachineDebugger::SetRegisters(ULONG a_idCpu, ComSafeArrayIn(IN_BSTR, a_bstrNames), ComSafeArrayIn(IN_BSTR, a_bstrValues))
794{
795 ReturnComNotImplemented();
796}
797
798STDMETHODIMP MachineDebugger::DumpGuestStack(ULONG a_idCpu, BSTR *a_pbstrStack)
799{
800 ReturnComNotImplemented();
801}
802
803/**
804 * Resets VM statistics.
805 *
806 * @returns COM status code.
807 * @param aPattern The selection pattern. A bit similar to filename globbing.
808 */
809STDMETHODIMP MachineDebugger::ResetStats(IN_BSTR aPattern)
810{
811 Console::SafeVMPtrQuiet pVM (mParent);
812
813 if (!pVM.isOk())
814 return setError(VBOX_E_INVALID_VM_STATE, "Machine is not running");
815
816 STAMR3Reset(pVM, Utf8Str(aPattern).c_str());
817
818 return S_OK;
819}
820
821/**
822 * Dumps VM statistics to the log.
823 *
824 * @returns COM status code.
825 * @param aPattern The selection pattern. A bit similar to filename globbing.
826 */
827STDMETHODIMP MachineDebugger::DumpStats (IN_BSTR aPattern)
828{
829 Console::SafeVMPtrQuiet pVM (mParent);
830
831 if (!pVM.isOk())
832 return setError(VBOX_E_INVALID_VM_STATE, "Machine is not running");
833
834 STAMR3Dump(pVM, Utf8Str(aPattern).c_str());
835
836 return S_OK;
837}
838
839/**
840 * Get the VM statistics in an XML format.
841 *
842 * @returns COM status code.
843 * @param aPattern The selection pattern. A bit similar to filename globbing.
844 * @param aWithDescriptions Whether to include the descriptions.
845 * @param aStats The XML document containing the statistics.
846 */
847STDMETHODIMP MachineDebugger::GetStats (IN_BSTR aPattern, BOOL aWithDescriptions, BSTR *aStats)
848{
849 Console::SafeVMPtrQuiet pVM (mParent);
850
851 if (!pVM.isOk())
852 return setError(VBOX_E_INVALID_VM_STATE, "Machine is not running");
853
854 char *pszSnapshot;
855 int vrc = STAMR3Snapshot(pVM, Utf8Str(aPattern).c_str(), &pszSnapshot, NULL,
856 !!aWithDescriptions);
857 if (RT_FAILURE(vrc))
858 return vrc == VERR_NO_MEMORY ? E_OUTOFMEMORY : E_FAIL;
859
860 /** @todo this is horribly inefficient! And it's kinda difficult to tell whether it failed...
861 * Must use UTF-8 or ASCII here and completely avoid these two extra copy operations.
862 * Until that's done, this method is kind of useless for debugger statistics GUI because
863 * of the amount statistics in a debug build. */
864 Bstr(pszSnapshot).detachTo(aStats);
865
866 return S_OK;
867}
868
869
870// public methods only for internal purposes
871/////////////////////////////////////////////////////////////////////////////
872
873void MachineDebugger::flushQueuedSettings()
874{
875 mFlushMode = true;
876 if (mSinglestepQueued != ~0)
877 {
878 COMSETTER(Singlestep) (mSinglestepQueued);
879 mSinglestepQueued = ~0;
880 }
881 if (mRecompileUserQueued != ~0)
882 {
883 COMSETTER(RecompileUser) (mRecompileUserQueued);
884 mRecompileUserQueued = ~0;
885 }
886 if (mRecompileSupervisorQueued != ~0)
887 {
888 COMSETTER(RecompileSupervisor) (mRecompileSupervisorQueued);
889 mRecompileSupervisorQueued = ~0;
890 }
891 if (mPatmEnabledQueued != ~0)
892 {
893 COMSETTER(PATMEnabled) (mPatmEnabledQueued);
894 mPatmEnabledQueued = ~0;
895 }
896 if (mCsamEnabledQueued != ~0)
897 {
898 COMSETTER(CSAMEnabled) (mCsamEnabledQueued);
899 mCsamEnabledQueued = ~0;
900 }
901 if (mLogEnabledQueued != ~0)
902 {
903 COMSETTER(LogEnabled) (mLogEnabledQueued);
904 mLogEnabledQueued = ~0;
905 }
906 if (mVirtualTimeRateQueued != ~(uint32_t)0)
907 {
908 COMSETTER(VirtualTimeRate) (mVirtualTimeRateQueued);
909 mVirtualTimeRateQueued = ~0;
910 }
911 mFlushMode = false;
912}
913
914// private methods
915/////////////////////////////////////////////////////////////////////////////
916
917bool MachineDebugger::queueSettings() const
918{
919 if (!mFlushMode)
920 {
921 // check if the machine is running
922 MachineState_T machineState;
923 mParent->COMGETTER(State) (&machineState);
924 switch (machineState)
925 {
926 // queue the request
927 default:
928 return true;
929
930 case MachineState_Running:
931 case MachineState_Paused:
932 case MachineState_Stuck:
933 case MachineState_LiveSnapshotting:
934 case MachineState_Teleporting:
935 break;
936 }
937 }
938 return false;
939}
940/* 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