VirtualBox

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

Last change on this file since 4849 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.8 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "MachineDebuggerImpl.h"
19#include "ConsoleImpl.h"
20#include "Logging.h"
21
22#include <VBox/em.h>
23#include <VBox/patm.h>
24#include <VBox/csam.h>
25#include <VBox/vm.h>
26#include <VBox/tm.h>
27#include <VBox/err.h>
28#include <VBox/hwaccm.h>
29
30//
31// defines
32//
33
34
35//
36// globals
37//
38
39
40//
41// constructor / destructor
42//
43
44HRESULT MachineDebugger::FinalConstruct()
45{
46 mParent = NULL;
47 return S_OK;
48}
49
50void MachineDebugger::FinalRelease()
51{
52 if (isReady())
53 uninit();
54}
55
56//
57// public methods
58//
59
60/**
61 * Initializes the machine debugger object.
62 *
63 * @returns COM result indicator
64 * @param parent handle of our parent object
65 */
66HRESULT MachineDebugger::init(Console *parent)
67{
68 LogFlow(("MachineDebugger::init(): isReady=%d\n", isReady()));
69
70 ComAssertRet (parent, E_INVALIDARG);
71
72 AutoLock lock(this);
73 ComAssertRet (!isReady(), E_UNEXPECTED);
74
75 mParent = parent;
76 singlestepQueued = ~0;
77 recompileUserQueued = ~0;
78 recompileSupervisorQueued = ~0;
79 patmEnabledQueued = ~0;
80 csamEnabledQueued = ~0;
81 mLogEnabledQueued = ~0;
82 mVirtualTimeRateQueued = ~0;
83 fFlushMode = false;
84 setReady(true);
85 return S_OK;
86}
87
88/**
89 * Uninitializes the instance and sets the ready flag to FALSE.
90 * Called either from FinalRelease() or by the parent when it gets destroyed.
91 */
92void MachineDebugger::uninit()
93{
94 LogFlow(("MachineDebugger::uninit(): isReady=%d\n", isReady()));
95
96 AutoLock lock(this);
97 AssertReturn (isReady(), (void) 0);
98
99 setReady (false);
100}
101
102/**
103 * Returns the current singlestepping flag.
104 *
105 * @returns COM status code
106 * @param enabled address of result variable
107 */
108STDMETHODIMP MachineDebugger::COMGETTER(Singlestep)(BOOL *enabled)
109{
110 if (!enabled)
111 return E_POINTER;
112 AutoLock lock(this);
113 CHECK_READY();
114 /** @todo */
115 return E_NOTIMPL;
116}
117
118/**
119 * Sets the singlestepping flag.
120 *
121 * @returns COM status code
122 * @param enable new singlestepping flag
123 */
124STDMETHODIMP MachineDebugger::COMSETTER(Singlestep)(BOOL enable)
125{
126 AutoLock lock(this);
127 CHECK_READY();
128 /** @todo */
129 return E_NOTIMPL;
130}
131
132/**
133 * Resets VM statistics
134 *
135 * @returns COM status code
136 */
137STDMETHODIMP MachineDebugger::ResetStats()
138{
139 Console::SafeVMPtrQuiet pVM (mParent);
140 if (pVM.isOk())
141 STAMR3Reset(pVM, NULL);
142 return S_OK;
143}
144
145/**
146 * Dumps VM statistics to the log
147 *
148 * @returns COM status code
149 */
150STDMETHODIMP MachineDebugger::DumpStats()
151{
152 Console::SafeVMPtrQuiet pVM (mParent);
153 if (pVM.isOk())
154 STAMR3Dump(pVM, NULL);
155 return S_OK;
156}
157
158/**
159 * Returns the current recompile user mode code flag.
160 *
161 * @returns COM status code
162 * @param enabled address of result variable
163 */
164STDMETHODIMP MachineDebugger::COMGETTER(RecompileUser)(BOOL *enabled)
165{
166 if (!enabled)
167 return E_POINTER;
168 AutoLock lock(this);
169 CHECK_READY();
170 Console::SafeVMPtrQuiet pVM (mParent);
171 if (pVM.isOk())
172 *enabled = !EMIsRawRing3Enabled(pVM.raw());
173 else
174 *enabled = false;
175 return S_OK;
176}
177
178/**
179 * Sets the recompile user mode code flag.
180 *
181 * @returns COM status
182 * @param enable new user mode code recompile flag.
183 */
184STDMETHODIMP MachineDebugger::COMSETTER(RecompileUser)(BOOL enable)
185{
186 LogFlowThisFunc (("enable=%d\n", enable));
187
188 AutoLock lock(this);
189 CHECK_READY();
190
191 if (!fFlushMode)
192 {
193 // check if the machine is running
194 MachineState_T machineState;
195 mParent->COMGETTER(State)(&machineState);
196 if (machineState != MachineState_Running)
197 {
198 // queue the request
199 recompileUserQueued = enable;
200 return S_OK;
201 }
202 }
203
204 Console::SafeVMPtr pVM (mParent);
205 CheckComRCReturnRC (pVM.rc());
206
207 PVMREQ pReq;
208 EMRAWMODE rawModeFlag = enable ? EMRAW_RING3_DISABLE : EMRAW_RING3_ENABLE;
209 int rcVBox = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT,
210 (PFNRT)EMR3RawSetMode, 2, pVM.raw(), rawModeFlag);
211 if (VBOX_SUCCESS(rcVBox))
212 {
213 rcVBox = pReq->iStatus;
214 VMR3ReqFree(pReq);
215 }
216
217 if (VBOX_SUCCESS(rcVBox))
218 return S_OK;
219
220 AssertMsgFailed(("Could not set raw mode flags to %d, rcVBox = %Vrc\n",
221 rawModeFlag, rcVBox));
222 return E_FAIL;
223}
224
225/**
226 * Returns the current recompile supervisor code flag.
227 *
228 * @returns COM status code
229 * @param enabled address of result variable
230 */
231STDMETHODIMP MachineDebugger::COMGETTER(RecompileSupervisor)(BOOL *enabled)
232{
233 if (!enabled)
234 return E_POINTER;
235 AutoLock lock(this);
236 CHECK_READY();
237 Console::SafeVMPtrQuiet pVM (mParent);
238 if (pVM.isOk())
239 *enabled = !EMIsRawRing0Enabled(pVM.raw());
240 else
241 *enabled = false;
242 return S_OK;
243}
244
245/**
246 * Sets the new recompile supervisor code flag.
247 *
248 * @returns COM status code
249 * @param enable new recompile supervisor code flag
250 */
251STDMETHODIMP MachineDebugger::COMSETTER(RecompileSupervisor)(BOOL enable)
252{
253 LogFlowThisFunc (("enable=%d\n", enable));
254
255 AutoLock lock(this);
256 CHECK_READY();
257
258 if (!fFlushMode)
259 {
260 // check if the machine is running
261 MachineState_T machineState;
262 mParent->COMGETTER(State)(&machineState);
263 if (machineState != MachineState_Running)
264 {
265 // queue the request
266 recompileSupervisorQueued = enable;
267 return S_OK;
268 }
269 }
270
271 Console::SafeVMPtr pVM (mParent);
272 CheckComRCReturnRC (pVM.rc());
273
274 PVMREQ pReq;
275 EMRAWMODE rawModeFlag = enable ? EMRAW_RING0_DISABLE : EMRAW_RING0_ENABLE;
276 int rcVBox = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT,
277 (PFNRT)EMR3RawSetMode, 2, pVM.raw(), rawModeFlag);
278 if (VBOX_SUCCESS(rcVBox))
279 {
280 rcVBox = pReq->iStatus;
281 VMR3ReqFree(pReq);
282 }
283
284 if (VBOX_SUCCESS(rcVBox))
285 return S_OK;
286
287 AssertMsgFailed(("Could not set raw mode flags to %d, rcVBox = %Vrc\n",
288 rawModeFlag, rcVBox));
289 return E_FAIL;
290}
291
292/**
293 * Returns the current patch manager enabled flag.
294 *
295 * @returns COM status code
296 * @param enabled address of result variable
297 */
298STDMETHODIMP MachineDebugger::COMGETTER(PATMEnabled)(BOOL *enabled)
299{
300 if (!enabled)
301 return E_POINTER;
302 AutoLock lock(this);
303 CHECK_READY();
304 Console::SafeVMPtrQuiet pVM (mParent);
305 if (pVM.isOk())
306 *enabled = PATMIsEnabled(pVM.raw());
307 else
308 *enabled = false;
309 return S_OK;
310}
311
312/**
313 * Set the new patch manager enabled flag.
314 *
315 * @returns COM status code
316 * @param new patch manager enabled flag
317 */
318STDMETHODIMP MachineDebugger::COMSETTER(PATMEnabled)(BOOL enable)
319{
320 AutoLock lock(this);
321 CHECK_READY();
322 LogFlowThisFunc (("enable=%d\n", enable));
323
324 if (!fFlushMode)
325 {
326 // check if the machine is running
327 MachineState_T machineState;
328 mParent->COMGETTER(State)(&machineState);
329 if (machineState != MachineState_Running)
330 {
331 // queue the request
332 patmEnabledQueued = enable;
333 return S_OK;
334 }
335 }
336
337 Console::SafeVMPtr pVM (mParent);
338 CheckComRCReturnRC (pVM.rc());
339
340 PATMR3AllowPatching(pVM, enable);
341 return E_NOTIMPL;
342}
343
344/**
345 * Returns the current code scanner enabled flag.
346 *
347 * @returns COM status code
348 * @param enabled address of result variable
349 */
350STDMETHODIMP MachineDebugger::COMGETTER(CSAMEnabled)(BOOL *enabled)
351{
352 if (!enabled)
353 return E_POINTER;
354 AutoLock lock(this);
355 CHECK_READY();
356 Console::SafeVMPtrQuiet pVM (mParent);
357 if (pVM.isOk())
358 *enabled = CSAMIsEnabled(pVM.raw());
359 else
360 *enabled = false;
361 return S_OK;
362}
363
364/**
365 * Sets the new code scanner enabled flag.
366 *
367 * @returns COM status code
368 * @param enable new code scanner enabled flag
369 */
370STDMETHODIMP MachineDebugger::COMSETTER(CSAMEnabled)(BOOL enable)
371{
372 AutoLock lock(this);
373 CHECK_READY();
374 LogFlowThisFunc (("enable=%d\n", enable));
375
376 if (!fFlushMode)
377 {
378 // check if the machine is running
379 MachineState_T machineState;
380 mParent->COMGETTER(State)(&machineState);
381 if (machineState != MachineState_Running)
382 {
383 // queue the request
384 csamEnabledQueued = enable;
385 return S_OK;
386 }
387 }
388
389 Console::SafeVMPtr pVM (mParent);
390 CheckComRCReturnRC (pVM.rc());
391
392 int vrc;
393 if (enable)
394 vrc = CSAMEnableScanning(pVM);
395 else
396 vrc = CSAMDisableScanning(pVM);
397 if (VBOX_FAILURE(vrc))
398 {
399 /** @todo handle error case */
400 }
401 return S_OK;
402}
403
404/**
405 * Returns the log enabled / disabled status.
406 *
407 * @returns COM status code
408 * @param aEnabled address of result variable
409 */
410STDMETHODIMP MachineDebugger::COMGETTER(LogEnabled)(BOOL *aEnabled)
411{
412 if (!aEnabled)
413 return E_POINTER;
414 AutoLock alock(this);
415 CHECK_READY();
416 PRTLOGGER pLogInstance = RTLogDefaultInstance();
417 *aEnabled = pLogInstance && !(pLogInstance->fFlags & RTLOGFLAGS_DISABLED);
418 return S_OK;
419}
420
421/**
422 * Enables or disables logging.
423 *
424 * @returns COM status code
425 * @param aEnabled The new code log state.
426 */
427STDMETHODIMP MachineDebugger::COMSETTER(LogEnabled)(BOOL aEnabled)
428{
429 AutoLock alock(this);
430
431 CHECK_READY();
432 LogFlowThisFunc (("aEnabled=%d\n", aEnabled));
433
434 if (!fFlushMode)
435 {
436 // check if the machine is running
437 MachineState_T machineState;
438 mParent->COMGETTER(State)(&machineState);
439 if (machineState != MachineState_Running)
440 {
441 // queue the request
442 mLogEnabledQueued = aEnabled;
443 return S_OK;
444 }
445 }
446
447 Console::SafeVMPtr pVM (mParent);
448 CheckComRCReturnRC (pVM.rc());
449
450 int vrc = DBGFR3LogModifyFlags(pVM, aEnabled ? "enabled" : "disabled");
451 if (VBOX_FAILURE(vrc))
452 {
453 /** @todo handle error code. */
454 }
455 return S_OK;
456}
457
458/**
459 * Returns the current hardware virtualization flag.
460 *
461 * @returns COM status code
462 * @param enabled address of result variable
463 */
464STDMETHODIMP MachineDebugger::COMGETTER(HWVirtExEnabled)(BOOL *enabled)
465{
466 if (!enabled)
467 return E_POINTER;
468
469 AutoLock lock(this);
470 CHECK_READY();
471
472 Console::SafeVMPtrQuiet pVM (mParent);
473 if (pVM.isOk())
474 *enabled = HWACCMIsEnabled(pVM.raw());
475 else
476 *enabled = false;
477 return S_OK;
478}
479
480/**
481 * Returns the current virtual time rate.
482 *
483 * @returns COM status code.
484 * @param pct Where to store the rate.
485 */
486STDMETHODIMP MachineDebugger::COMGETTER(VirtualTimeRate)(ULONG *pct)
487{
488 if (!pct)
489 return E_POINTER;
490
491 AutoLock lock(this);
492 CHECK_READY();
493
494 Console::SafeVMPtrQuiet pVM (mParent);
495 if (pVM.isOk())
496 *pct = TMVirtualGetWarpDrive(pVM);
497 else
498 *pct = 100;
499 return S_OK;
500}
501
502/**
503 * Returns the current virtual time rate.
504 *
505 * @returns COM status code.
506 * @param pct Where to store the rate.
507 */
508STDMETHODIMP MachineDebugger::COMSETTER(VirtualTimeRate)(ULONG pct)
509{
510 if (pct < 2 || pct > 20000)
511 return E_INVALIDARG;
512
513 AutoLock lock(this);
514 CHECK_READY();
515
516 if (!fFlushMode)
517 {
518 // check if the machine is running
519 MachineState_T machineState;
520 mParent->COMGETTER(State)(&machineState);
521 if (machineState != MachineState_Running)
522 {
523 // queue the request
524 mVirtualTimeRateQueued = pct;
525 return S_OK;
526 }
527 }
528
529 Console::SafeVMPtr pVM (mParent);
530 CheckComRCReturnRC (pVM.rc());
531
532 int vrc = TMVirtualSetWarpDrive(pVM, pct);
533 if (VBOX_FAILURE(vrc))
534 {
535 /** @todo handle error code. */
536 }
537 return S_OK;
538}
539
540/**
541 * Hack for getting the VM handle.
542 * This is only temporary (promise) while prototyping the debugger.
543 *
544 * @returns COM status code
545 * @param vm Where to store the vm handle.
546 * Since there is no uintptr_t in COM, we're using the max integer.
547 * (No, ULONG is not pointer sized!)
548 */
549STDMETHODIMP MachineDebugger::COMGETTER(VM)(ULONG64 *vm)
550{
551 if (!vm)
552 return E_POINTER;
553
554 AutoLock lock(this);
555 CHECK_READY();
556
557 Console::SafeVMPtr pVM (mParent);
558 CheckComRCReturnRC (pVM.rc());
559
560 *vm = (uintptr_t)pVM.raw();
561
562 /*
563 * Note: pVM protection provided by SafeVMPtr is no more effective
564 * after we return from this method.
565 */
566
567 return S_OK;
568}
569
570//
571// "public-private" methods
572//
573void MachineDebugger::flushQueuedSettings()
574{
575 fFlushMode = true;
576 if (singlestepQueued != ~0)
577 {
578 COMSETTER(Singlestep)(singlestepQueued);
579 singlestepQueued = ~0;
580 }
581 if (recompileUserQueued != ~0)
582 {
583 COMSETTER(RecompileUser)(recompileUserQueued);
584 recompileUserQueued = ~0;
585 }
586 if (recompileSupervisorQueued != ~0)
587 {
588 COMSETTER(RecompileSupervisor)(recompileSupervisorQueued);
589 recompileSupervisorQueued = ~0;
590 }
591 if (patmEnabledQueued != ~0)
592 {
593 COMSETTER(PATMEnabled)(patmEnabledQueued);
594 patmEnabledQueued = ~0;
595 }
596 if (csamEnabledQueued != ~0)
597 {
598 COMSETTER(CSAMEnabled)(csamEnabledQueued);
599 csamEnabledQueued = ~0;
600 }
601 if (mLogEnabledQueued != ~0)
602 {
603 COMSETTER(LogEnabled)(mLogEnabledQueued);
604 mLogEnabledQueued = ~0;
605 }
606 if (mVirtualTimeRateQueued != ~(uint32_t)0)
607 {
608 COMSETTER(VirtualTimeRate)(mVirtualTimeRateQueued);
609 mVirtualTimeRateQueued = ~0;
610 }
611 fFlushMode = false;
612}
613
614//
615// private methods
616//
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