VirtualBox

source: vbox/trunk/src/VBox/Debugger/VBoxDbgConsole.h@ 86327

Last change on this file since 86327 was 86327, checked in by vboxsync, 4 years ago

Debugger: Allow for different I/O providers instead of only TCP

So far TCP was the only option to communicate remotely with the internal debugger, the other option
was to use the console from the GUI directly. This commit reworks basic I/O to allow for different
providers where TCP is just one option. The second one being introduced is an IPC provider using a local
socket or named pipe depending on the platform. This allows for Windows kernel debugging over a pipe
using the KD stub in VirtualBox and WinDbg running on the host (not tested yet).

Furthermore this commit allows multiple stubs to be listening for connections at the same time, so
one can have a GDB stub listening on one TCP port and the native VBox debugger listening on another one
or even using a different I/O provider. Only one session can be active at a time though, because sharing
debugger states is impossible. To configure this the following CFGM keys need to be set for each listener:

"DBGC/<Some unique ID>/Provider" "tcp|ipc"
"DBGC/<Some unique ID>/StubType" "native|gdb|kd"
"DBGC/<Some unique ID>/Address" "<ip>|<local named pipe or socket path>"
"DBGC/<Some unique ID>/Port" "<port>" (for TCP only)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1/* $Id: VBoxDbgConsole.h 86327 2020-09-28 16:20:50Z vboxsync $ */
2/** @file
3 * VBox Debugger GUI - Console.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef DEBUGGER_INCLUDED_SRC_VBoxDbgConsole_h
19#define DEBUGGER_INCLUDED_SRC_VBoxDbgConsole_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include "VBoxDbgBase.h"
25
26#include <QTextEdit>
27#include <QComboBox>
28#include <QTimer>
29#include <QEvent>
30#include <QActionGroup>
31
32#include <iprt/critsect.h>
33#include <iprt/semaphore.h>
34#include <iprt/thread.h>
35
36// VirtualBox COM interfaces declarations (generated header)
37#ifdef VBOX_WITH_XPCOM
38# include <VirtualBox_XPCOM.h>
39#else
40# include <VirtualBox.h>
41#endif
42
43
44class VBoxDbgConsoleOutput : public QTextEdit
45{
46 Q_OBJECT
47
48public:
49 /**
50 * Constructor.
51 *
52 * @param pParent Parent Widget.
53 * @param pVirtualBox VirtualBox object for storing extra data.
54 * @param pszName Widget name.
55 */
56 VBoxDbgConsoleOutput(QWidget *pParent = NULL, IVirtualBox *pVirtualBox = NULL, const char *pszName = NULL);
57
58 /**
59 * Destructor
60 */
61 virtual ~VBoxDbgConsoleOutput();
62
63 /**
64 * Appends text.
65 * This differs from QTextEdit::append() in that it won't start on a new paragraph
66 * unless the previous char was a newline ('\n').
67 *
68 * @param rStr The text string to append.
69 * @param fClearSelection Whether to clear selected text before appending.
70 * If @c false the selection and window position
71 * are preserved.
72 */
73 virtual void appendText(const QString &rStr, bool fClearSelection);
74
75 /** The action to switch to black-on-white color scheme. */
76 QAction *m_pBlackOnWhiteAction;
77 /** The action to switch to green-on-black color scheme. */
78 QAction *m_pGreenOnBlackAction;
79
80 /** The action to switch to Courier font. */
81 QAction *m_pCourierFontAction;
82 /** The action to switch to Monospace font. */
83 QAction *m_pMonospaceFontAction;
84
85protected:
86 typedef enum { kGreenOnBlack, kBlackOnWhite } VBoxDbgConsoleColor;
87 typedef enum { kFontType_Monospace, kFontType_Courier } VBoxDbgConsoleFontType;
88
89 /**
90 * Context menu event.
91 * This adds custom menu items for the output view.
92 *
93 * @param pEvent Pointer to the event.
94 */
95 virtual void contextMenuEvent(QContextMenuEvent *pEvent);
96
97 /**
98 * Sets the color scheme.
99 *
100 * @param enmScheme The new color scheme.
101 * @param fSaveIt Whether to save it.
102 */
103 void setColorScheme(VBoxDbgConsoleColor enmScheme, bool fSaveIt);
104
105 /**
106 * Sets the font type / family.
107 *
108 * @param enmFontType The font type.
109 * @param fSaveIt Whether to save it.
110 */
111 void setFontType(VBoxDbgConsoleFontType enmFontType, bool fSaveIt);
112
113 /**
114 * Sets the font size.
115 *
116 * @param uFontSize The new font size in points.
117 * @param fSaveIt Whether to save it.
118 */
119 void setFontSize(uint32_t uFontSize, bool fSaveIt);
120
121
122 /** The current line (paragraph) number. */
123 unsigned m_uCurLine;
124 /** The position in the current line. */
125 unsigned m_uCurPos;
126 /** The handle to the GUI thread. */
127 RTNATIVETHREAD m_hGUIThread;
128 /** The current color scheme (foreground on background). */
129 VBoxDbgConsoleColor m_enmColorScheme;
130 /** The IVirtualBox object */
131 IVirtualBox *m_pVirtualBox;
132
133 /** Array of font size actions 6..22pt. */
134 QAction *m_apFontSizeActions[22 - 6 + 1];
135 /** Action group for m_apFontSizeActions. */
136 QActionGroup *m_pActionFontSizeGroup;
137
138 /** The minimum font size. */
139 static const uint32_t s_uMinFontSize;
140
141private slots:
142 /**
143 * Selects color scheme
144 */
145 void sltSelectColorScheme();
146
147 /**
148 * Selects font type.
149 */
150 void sltSelectFontType();
151
152 /**
153 * Selects font size.
154 */
155 void sltSelectFontSize();
156};
157
158
159/**
160 * The Debugger Console Input widget.
161 *
162 * This is a combobox which only responds to \<return\>.
163 */
164class VBoxDbgConsoleInput : public QComboBox
165{
166 Q_OBJECT
167
168public:
169 /**
170 * Constructor.
171 *
172 * @param pParent Parent Widget.
173 * @param pszName Widget name.
174 */
175 VBoxDbgConsoleInput(QWidget *pParent = NULL, const char *pszName = NULL);
176
177 /**
178 * Destructor
179 */
180 virtual ~VBoxDbgConsoleInput();
181
182 /**
183 * We overload this method to get signaled upon returnPressed().
184 *
185 * See QComboBox::setLineEdit for full description.
186 * @param pEdit The new line edit widget.
187 * @remark This won't be called during the constructor.
188 */
189 virtual void setLineEdit(QLineEdit *pEdit);
190
191signals:
192 /**
193 * New command submitted.
194 */
195 void commandSubmitted(const QString &rCommand);
196
197private slots:
198 /**
199 * Returned was pressed.
200 *
201 * Will emit commandSubmitted().
202 */
203 void returnPressed();
204
205protected:
206 /** The handle to the GUI thread. */
207 RTNATIVETHREAD m_hGUIThread;
208};
209
210
211/**
212 * The Debugger Console.
213 */
214class VBoxDbgConsole : public VBoxDbgBaseWindow
215{
216 Q_OBJECT
217
218public:
219 /**
220 * Constructor.
221 *
222 * @param a_pDbgGui Pointer to the debugger gui object.
223 * @param a_pParent Parent Widget.
224 * @param a_pVirtualBox VirtualBox object for storing extra data.
225 */
226 VBoxDbgConsole(VBoxDbgGui *a_pDbgGui, QWidget *a_pParent = NULL, IVirtualBox *a_pVirtualBox = NULL);
227
228 /**
229 * Destructor
230 */
231 virtual ~VBoxDbgConsole();
232
233protected slots:
234 /**
235 * Handler called when a command is submitted.
236 * (Enter or return pressed in the combo box.)
237 *
238 * @param rCommand The submitted command.
239 */
240 void commandSubmitted(const QString &rCommand);
241
242 /**
243 * Updates the output with what's currently in the output buffer.
244 * This is called by a timer or a User event posted by the debugger thread.
245 */
246 void updateOutput();
247
248 /**
249 * Changes the focus to the input field.
250 */
251 void actFocusToInput();
252
253 /**
254 * Changes the focus to the output viewer widget.
255 */
256 void actFocusToOutput();
257
258protected:
259 /**
260 * Override the closeEvent so we can choose delete the window when
261 * it is closed.
262 *
263 * @param a_pCloseEvt The close event.
264 */
265 virtual void closeEvent(QCloseEvent *a_pCloseEvt);
266
267 /**
268 * Lock the object.
269 */
270 void lock();
271
272 /**
273 * Unlocks the object.
274 */
275 void unlock();
276
277protected:
278 /** @name Debug Console Backend.
279 * @{
280 */
281
282
283 /**
284 * Checks if there is input.
285 *
286 * @returns true if there is input ready.
287 * @returns false if there not input ready.
288 * @param pBack Pointer to VBoxDbgConsole::m_Back.
289 * @param cMillies Number of milliseconds to wait on input data.
290 */
291 static DECLCALLBACK(bool) backInput(PCDBGCIO pIo, uint32_t cMillies);
292
293 /**
294 * Read input.
295 *
296 * @returns VBox status code.
297 * @param pBack Pointer to VBoxDbgConsole::m_Back.
298 * @param pvBuf Where to put the bytes we read.
299 * @param cbBuf Maximum nymber of bytes to read.
300 * @param pcbRead Where to store the number of bytes actually read.
301 * If NULL the entire buffer must be filled for a
302 * successful return.
303 */
304 static DECLCALLBACK(int) backRead(PCDBGCIO pIo, void *pvBuf, size_t cbBuf, size_t *pcbRead);
305
306 /**
307 * Write (output).
308 *
309 * @returns VBox status code.
310 * @param pBack Pointer to VBoxDbgConsole::m_Back.
311 * @param pvBuf What to write.
312 * @param cbBuf Number of bytes to write.
313 * @param pcbWritten Where to store the number of bytes actually written.
314 * If NULL the entire buffer must be successfully written.
315 */
316 static DECLCALLBACK(int) backWrite(PCDBGCIO pIo, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
317
318 /**
319 * @copydoc DBGCIO::PfnSetReady
320 */
321 static DECLCALLBACK(void) backSetReady(PCDBGCIO pIo, bool fReady);
322
323 /**
324 * The Debugger Console Thread
325 *
326 * @returns VBox status code (ignored).
327 * @param Thread The thread handle.
328 * @param pvUser Pointer to the VBoxDbgConsole object.s
329 */
330 static DECLCALLBACK(int) backThread(RTTHREAD Thread, void *pvUser);
331
332 /** @} */
333
334protected:
335 /**
336 * Processes GUI command posted by the console thread.
337 *
338 * Qt3 isn't thread safe on any platform, meaning there is no locking, so, as
339 * a result we have to be very careful. All operations on objects which we share
340 * with the main thread has to be posted to it so it can perform it.
341 */
342 bool event(QEvent *pEvent);
343
344 /**
345 * For implementing keyboard shortcuts.
346 *
347 * @param pEvent The key event.
348 */
349 void keyReleaseEvent(QKeyEvent *pEvent);
350
351protected:
352 /** The output widget. */
353 VBoxDbgConsoleOutput *m_pOutput;
354 /** The input widget. */
355 VBoxDbgConsoleInput *m_pInput;
356 /** A hack to restore focus to the combobox after a command execution. */
357 bool m_fInputRestoreFocus;
358 /** The input buffer. */
359 char *m_pszInputBuf;
360 /** The amount of input in the buffer. */
361 size_t m_cbInputBuf;
362 /** The allocated size of the buffer. */
363 size_t m_cbInputBufAlloc;
364
365 /** The output buffer. */
366 char *m_pszOutputBuf;
367 /** The amount of output in the buffer. */
368 size_t m_cbOutputBuf;
369 /** The allocated size of the buffer. */
370 size_t m_cbOutputBufAlloc;
371 /** The timer object used to process output in a delayed fashion. */
372 QTimer *m_pTimer;
373 /** Set when an output update is pending. */
374 bool volatile m_fUpdatePending;
375
376 /** The debugger console thread. */
377 RTTHREAD m_Thread;
378 /** The event semaphore used to signal the debug console thread about input. */
379 RTSEMEVENT m_EventSem;
380 /** The critical section used to lock the object. */
381 RTCRITSECT m_Lock;
382 /** When set the thread will cause the debug console thread to terminate. */
383 bool volatile m_fTerminate;
384 /** Has the thread terminated?
385 * Used to do the right thing in closeEvent; the console is dead if the
386 * thread has terminated. */
387 bool volatile m_fThreadTerminated;
388
389 /** The debug console backend structure.
390 * Use VBOXDBGCONSOLE_FROM_DBGCIO to convert the DBGCIO pointer to a object pointer. */
391 struct VBoxDbgConsoleBack
392 {
393 DBGCIO Core;
394 VBoxDbgConsole *pSelf;
395 } m_Back;
396
397 /**
398 * Converts a pointer to VBoxDbgConsole::m_Back to VBoxDbgConsole pointer.
399 * @todo find a better way because offsetof is undefined on objects and g++ gets very noisy because of that.
400 */
401# define VBOXDBGCONSOLE_FROM_DBGCIO(pIo) ( ((struct VBoxDbgConsoleBack *)(pBack))->pSelf )
402
403 /** Change focus to the input field. */
404 QAction *m_pFocusToInput;
405 /** Change focus to the output viewer widget. */
406 QAction *m_pFocusToOutput;
407};
408
409
410/**
411 * Simple event class for push certain operations over
412 * onto the GUI thread.
413 */
414class VBoxDbgConsoleEvent : public QEvent
415{
416public:
417 typedef enum { kUpdate, kInputEnable, kTerminatedUser, kTerminatedOther } VBoxDbgConsoleEventType;
418 enum { kEventNumber = QEvent::User + 42 };
419
420 VBoxDbgConsoleEvent(VBoxDbgConsoleEventType enmCommand)
421 : QEvent((QEvent::Type)kEventNumber), m_enmCommand(enmCommand)
422 {
423 }
424
425 VBoxDbgConsoleEventType command() const
426 {
427 return m_enmCommand;
428 }
429
430private:
431 VBoxDbgConsoleEventType m_enmCommand;
432};
433
434
435#endif /* !DEBUGGER_INCLUDED_SRC_VBoxDbgConsole_h */
436
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