VirtualBox

Changeset 5679 in vbox


Ignore:
Timestamp:
Nov 11, 2007 9:07:18 AM (17 years ago)
Author:
vboxsync
Message:

Updated the @page.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGConsole.cpp

    r5677 r5679  
    1919/** @page pg_dbgc                       DBGC - The Debug Console
    2020 *
    21  * The debugger console is a first attempt to make some interactive
    22  * debugging facilities for the VirtualBox backend (i.e. the VM). At a later
    23  * stage we'll make a fancy gui around this, but for the present a telnet (or
    24  * serial terminal) will have to suffice.
    25  *
    26  * The debugger is only built into the VM with debug builds or when
    27  * VBOX_WITH_DEBUGGER is defined. There might be need for \#ifdef'ing on this
    28  * define to enable special debugger hooks, but the general approach is to
    29  * make generic interfaces. The individual components also can register
    30  * external commands, and such code must be within \#ifdef.
     21 * The debugger console is an early attempt to make some interactive
     22 * debugging facilities for the VirtualBox VMM. It was initially only
     23 * accessible thru a telnet session on debug builds. Later it was hastily
     24 * built into the VBoxDbg module with a very simple Qt wrapper around it.
     25 *
     26 * The debugger is optional and presently not built into release builds
     27 * of VirtualBox. It is therefore necessary to enclose code related to it
     28 * in \#ifdef VBOX_WITH_DEBUGGER blocks. This is mandatory for components
     29 * that register extenral commands.
    3130 *
    3231 *
     
    4746 *      - '0y' - binary.
    4847 *
     48 * Some of the prefixes are a bit uncommon, the reason for this that
     49 * the typical binary prefix '0b' can also be a hexadecimal value since
     50 * no prefix or suffix is required for such values. Ditto for '0d' and
     51 * '0' for decimal and octal.
     52 *
    4953 *
    5054 * @subsection sec_dbg_op_address       Addressing modes
     
    5559 *      - The default target for the addressing is the guest context, the '#'
    5660 *        will override this and set it to the host.
     61 *        Note that several operations won't work on host addresses.
     62 *
     63 * The '%', '%%' and '#' prefixes is implemented as unary operators, while ':'
     64 * is a binary operator. Operator precedence takes care of evaluation order.
    5765 *
    5866 *
    5967 * @subsection sec_dbg_op_evalution     Evaluation
    6068 *
    61  * As time permits support will be implemented support for a subset of the C
    62  * binary operators, starting with '+', '-', '*' and '/'. Support for variables
    63  * are provided thru commands 'set' and 'unset' and the unary operator '$'. The
    64  * unary '@' operator will indicate function calls. The debugger needs a set of
    65  * memory read functions, but we might later extend this to allow registration of
    66  * external functions too.
    67  *
    68  * A special command '?' will then be added which evalutates a given expression
    69  * and prints it in all the different formats.
     69 * Most unary and binary C operators are supported, check the help text for
     70 * details. However, some of these are not yet implemented because this is
     71 * tiresome and annoying work. So, if something is missing and you need it
     72 * you implement it or complain to bird. (Ditto for missing functions.)
     73 *
     74 * Simple variable support is provided thru the 'set' and 'unset' commands and
     75 * the unary '$' operator.
     76 *
     77 * The unary '@' operator will indicate function calls. Commands and functions
     78 * are the same thing, except that functions has a return type.
    7079 *
    7180 *
     
    7786 * prefix the register names with '.'.
    7887 *
    79  *
    80  * @subsection sec_dbg_op_commands      Commands
    81  *
    82  * The commands are all lowercase, case sensitive, and starting with a letter. We will
    83  * later add some special commands ('?' for evaulation) and perhaps command classes ('.', '!')
    84  *
    85  *
    86  * @section sec_dbg_tasks               Tasks
    87  *
    88  * To implement DBGT and instrument VMM for basic state inspection and log
    89  * viewing, the follwing task must be executed:
    90  *
    91  *      -# Basic threading layer in RT.
    92  *      -# Basic tcpip server abstration in RT.
    93  *      -# Write DBGC.
    94  *      -# Write DBCTCP.
    95  *      -# Integrate with VMM and the rest.
    96  *      -# Start writing DBGF (VMM).
     88 * The registers are implemented as built-in symbols. For making gdb guys more at
     89 * home it is possible to access them with the '$' operator, i.e. as a variable.
     90 *
     91 *
     92 * @subsection sec_dbg_op_commands      Commands and Functions
     93 *
     94 * Commands and functions are the same thing, except that functions may return a
     95 * value. So, functions may be used as commands. The command/function handlers
     96 * can detect whether they are invoked as a command or function by checking whether
     97 * there is a return variable or not.
     98 *
     99 * The command/function names are all lowercase, case sensitive, and starting
     100 * with a letter. Operator characters are not permitted in the names of course.
     101 * Space is allowed, but must be flagged so the parser can check for multiple
     102 * spaces and tabs. (This feature is for 'dump xyz' and for emulating the
     103 * gdb 'info abc'.)
     104 *
     105 * The '.' prefix indicates the set of external commands. External commands are
     106 * command registered by VMM components.
     107 *
     108 *
     109 * @section sec_dbgc_logging            Logging
     110 *
     111 * The idea is to be able to pass thru debug and release logs to the console
     112 * if the user so wishes. This feature requires some kind of hook into the
     113 * logger instance and while this was sketched it hasn't yet been implemented
     114 * (dbgcProcessLog and DBGC::fLog).
     115 *
     116 *
     117 *
     118 * @section sec_dbgc_linking            Linking and API
     119 *
     120 * The DBGC code is linked into the VBoxVMM module. (At present it is also
     121 * linked into VBoxDbg, but this is obviously very wrong.)
     122 *
     123 * A COM object will be created for the DBGC so it can be operated remotely
     124 * without using TCP. VBoxDbg is the intended audience for this usage. Some
     125 * questions about callbacks (for output) and security (you may wish to
     126 * restrict users from debugging a VM) needs to be answered first though.
    97127 */
    98 
    99 
    100128
    101129
     
    135163
    136164
     165/*******************************************************************************
     166*   Internal Functions                                                         *
     167*******************************************************************************/
     168static int dbgcProcessLog(PDBGC pDbgc);
     169
     170
    137171
    138172/**
     
    157191    return ASMBitTest(&g_bmOperatorChars[0], (uint8_t)ch);
    158192}
    159 
    160 
    161 /**
    162  * Prints any log lines from the log buffer.
    163  *
    164  * The caller must not call function this unless pDbgc->fLog is set.
    165  *
    166  * @returns VBox status. (output related)
    167  * @param   pDbgc   Debugger console instance data.
    168  */
    169 static int dbgcProcessLog(PDBGC pDbgc)
    170 {
    171     /** @todo */
    172     NOREF(pDbgc);
    173     return 0;
    174 }
    175 
    176 
    177 
    178 /**
    179  * Handle input buffer overflow.
    180  *
    181  * Will read any available input looking for a '\n' to reset the buffer on.
    182  *
    183  * @returns VBox status.
    184  * @param   pDbgc   Debugger console instance data.
    185  */
    186 static int dbgcInputOverflow(PDBGC pDbgc)
    187 {
    188     /*
    189      * Assert overflow status and reset the input buffer.
    190      */
    191     if (!pDbgc->fInputOverflow)
    192     {
    193         pDbgc->fInputOverflow = true;
    194         pDbgc->iRead = pDbgc->iWrite = 0;
    195         pDbgc->cInputLines = 0;
    196         pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "Input overflow!!\n");
    197     }
    198 
    199     /*
    200      * Eat input till no more or there is a '\n'.
    201      * When finding a '\n' we'll continue normal processing.
    202      */
    203     while (pDbgc->pBack->pfnInput(pDbgc->pBack, 0))
    204     {
    205         size_t cbRead;
    206         int rc = pDbgc->pBack->pfnRead(pDbgc->pBack, &pDbgc->achInput[0], sizeof(pDbgc->achInput) - 1, &cbRead);
    207         if (VBOX_FAILURE(rc))
    208             return rc;
    209         char *psz = (char *)memchr(&pDbgc->achInput[0], '\n', cbRead);
    210         if (psz)
    211         {
    212             pDbgc->fInputOverflow = false;
    213             pDbgc->iRead = psz - &pDbgc->achInput[0] + 1;
    214             pDbgc->iWrite = (unsigned)cbRead;
    215             pDbgc->cInputLines = 0;
    216             break;
    217         }
    218     }
    219 
    220     return 0;
    221 }
    222 
    223 
    224 
    225 /**
    226  * Read input and do some preprocessing.
    227  *
    228  * @returns VBox status.
    229  *          In addition to the iWrite and achInput, cInputLines is maintained.
    230  *          In case of an input overflow the fInputOverflow flag will be set.
    231  * @param   pDbgc   Debugger console instance data.
    232  */
    233 static int dbgcInputRead(PDBGC pDbgc)
    234 {
    235     /*
    236      * We have ready input.
    237      * Read it till we don't have any or we have a full input buffer.
    238      */
    239     int     rc = 0;
    240     do
    241     {
    242         /*
    243          * More available buffer space?
    244          */
    245         size_t cbLeft;
    246         if (pDbgc->iWrite > pDbgc->iRead)
    247             cbLeft = sizeof(pDbgc->achInput) - pDbgc->iWrite - (pDbgc->iRead == 0);
    248         else
    249             cbLeft = pDbgc->iRead - pDbgc->iWrite - 1;
    250         if (!cbLeft)
    251         {
    252             /* overflow? */
    253             if (!pDbgc->cInputLines)
    254                 rc = dbgcInputOverflow(pDbgc);
    255             break;
    256         }
    257 
    258         /*
    259          * Read one char and interpret it.
    260          */
    261         char    achRead[128];
    262         size_t  cbRead;
    263         rc = pDbgc->pBack->pfnRead(pDbgc->pBack, &achRead[0], RT_MIN(cbLeft, sizeof(achRead)), &cbRead);
    264         if (VBOX_FAILURE(rc))
    265             return rc;
    266         char *psz = &achRead[0];
    267         while (cbRead-- > 0)
    268         {
    269             char ch = *psz++;
    270             switch (ch)
    271             {
    272                 /*
    273                  * Ignore.
    274                  */
    275                 case '\0':
    276                 case '\r':
    277                 case '\a':
    278                     break;
    279 
    280                 /*
    281                  * Backspace.
    282                  */
    283                 case '\b':
    284                     Log2(("DBGC: backspace\n"));
    285                     if (pDbgc->iRead != pDbgc->iWrite)
    286                     {
    287                         unsigned iWriteUndo = pDbgc->iWrite;
    288                         if (pDbgc->iWrite)
    289                             pDbgc->iWrite--;
    290                         else
    291                             pDbgc->iWrite = sizeof(pDbgc->achInput) - 1;
    292 
    293                         if (pDbgc->achInput[pDbgc->iWrite] == '\n')
    294                             pDbgc->iWrite = iWriteUndo;
    295                     }
    296                     break;
    297 
    298                 /*
    299                  * Add char to buffer.
    300                  */
    301                 case '\t':
    302                 case '\n':
    303                 case ';':
    304                     switch (ch)
    305                     {
    306                         case '\t': ch = ' '; break;
    307                         case '\n': pDbgc->cInputLines++; break;
    308                     }
    309                 default:
    310                     Log2(("DBGC: ch=%02x\n", (unsigned char)ch));
    311                     pDbgc->achInput[pDbgc->iWrite] = ch;
    312                     if (++pDbgc->iWrite >= sizeof(pDbgc->achInput))
    313                         pDbgc->iWrite = 0;
    314                     break;
    315             }
    316         }
    317 
    318         /* Terminate it to make it easier to read in the debugger. */
    319         pDbgc->achInput[pDbgc->iWrite] = '\0';
    320     } while (pDbgc->pBack->pfnInput(pDbgc->pBack, 0));
    321 
    322     return rc;
    323 }
    324 
    325193
    326194
     
    14861354
    14871355/**
    1488  * Process all commands current in the buffer.
     1356 * Process all commands currently in the buffer.
    14891357 *
    14901358 * @returns VBox status code. Any error indicates the termination of the console session.
     
    15511419            break;
    15521420    }
     1421
     1422    return rc;
     1423}
     1424
     1425
     1426/**
     1427 * Handle input buffer overflow.
     1428 *
     1429 * Will read any available input looking for a '\n' to reset the buffer on.
     1430 *
     1431 * @returns VBox status.
     1432 * @param   pDbgc   Debugger console instance data.
     1433 */
     1434static int dbgcInputOverflow(PDBGC pDbgc)
     1435{
     1436    /*
     1437     * Assert overflow status and reset the input buffer.
     1438     */
     1439    if (!pDbgc->fInputOverflow)
     1440    {
     1441        pDbgc->fInputOverflow = true;
     1442        pDbgc->iRead = pDbgc->iWrite = 0;
     1443        pDbgc->cInputLines = 0;
     1444        pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "Input overflow!!\n");
     1445    }
     1446
     1447    /*
     1448     * Eat input till no more or there is a '\n'.
     1449     * When finding a '\n' we'll continue normal processing.
     1450     */
     1451    while (pDbgc->pBack->pfnInput(pDbgc->pBack, 0))
     1452    {
     1453        size_t cbRead;
     1454        int rc = pDbgc->pBack->pfnRead(pDbgc->pBack, &pDbgc->achInput[0], sizeof(pDbgc->achInput) - 1, &cbRead);
     1455        if (VBOX_FAILURE(rc))
     1456            return rc;
     1457        char *psz = (char *)memchr(&pDbgc->achInput[0], '\n', cbRead);
     1458        if (psz)
     1459        {
     1460            pDbgc->fInputOverflow = false;
     1461            pDbgc->iRead = psz - &pDbgc->achInput[0] + 1;
     1462            pDbgc->iWrite = (unsigned)cbRead;
     1463            pDbgc->cInputLines = 0;
     1464            break;
     1465        }
     1466    }
     1467
     1468    return 0;
     1469}
     1470
     1471
     1472/**
     1473 * Read input and do some preprocessing.
     1474 *
     1475 * @returns VBox status.
     1476 *          In addition to the iWrite and achInput, cInputLines is maintained.
     1477 *          In case of an input overflow the fInputOverflow flag will be set.
     1478 * @param   pDbgc   Debugger console instance data.
     1479 */
     1480static int dbgcInputRead(PDBGC pDbgc)
     1481{
     1482    /*
     1483     * We have ready input.
     1484     * Read it till we don't have any or we have a full input buffer.
     1485     */
     1486    int     rc = 0;
     1487    do
     1488    {
     1489        /*
     1490         * More available buffer space?
     1491         */
     1492        size_t cbLeft;
     1493        if (pDbgc->iWrite > pDbgc->iRead)
     1494            cbLeft = sizeof(pDbgc->achInput) - pDbgc->iWrite - (pDbgc->iRead == 0);
     1495        else
     1496            cbLeft = pDbgc->iRead - pDbgc->iWrite - 1;
     1497        if (!cbLeft)
     1498        {
     1499            /* overflow? */
     1500            if (!pDbgc->cInputLines)
     1501                rc = dbgcInputOverflow(pDbgc);
     1502            break;
     1503        }
     1504
     1505        /*
     1506         * Read one char and interpret it.
     1507         */
     1508        char    achRead[128];
     1509        size_t  cbRead;
     1510        rc = pDbgc->pBack->pfnRead(pDbgc->pBack, &achRead[0], RT_MIN(cbLeft, sizeof(achRead)), &cbRead);
     1511        if (VBOX_FAILURE(rc))
     1512            return rc;
     1513        char *psz = &achRead[0];
     1514        while (cbRead-- > 0)
     1515        {
     1516            char ch = *psz++;
     1517            switch (ch)
     1518            {
     1519                /*
     1520                 * Ignore.
     1521                 */
     1522                case '\0':
     1523                case '\r':
     1524                case '\a':
     1525                    break;
     1526
     1527                /*
     1528                 * Backspace.
     1529                 */
     1530                case '\b':
     1531                    Log2(("DBGC: backspace\n"));
     1532                    if (pDbgc->iRead != pDbgc->iWrite)
     1533                    {
     1534                        unsigned iWriteUndo = pDbgc->iWrite;
     1535                        if (pDbgc->iWrite)
     1536                            pDbgc->iWrite--;
     1537                        else
     1538                            pDbgc->iWrite = sizeof(pDbgc->achInput) - 1;
     1539
     1540                        if (pDbgc->achInput[pDbgc->iWrite] == '\n')
     1541                            pDbgc->iWrite = iWriteUndo;
     1542                    }
     1543                    break;
     1544
     1545                /*
     1546                 * Add char to buffer.
     1547                 */
     1548                case '\t':
     1549                case '\n':
     1550                case ';':
     1551                    switch (ch)
     1552                    {
     1553                        case '\t': ch = ' '; break;
     1554                        case '\n': pDbgc->cInputLines++; break;
     1555                    }
     1556                default:
     1557                    Log2(("DBGC: ch=%02x\n", (unsigned char)ch));
     1558                    pDbgc->achInput[pDbgc->iWrite] = ch;
     1559                    if (++pDbgc->iWrite >= sizeof(pDbgc->achInput))
     1560                        pDbgc->iWrite = 0;
     1561                    break;
     1562            }
     1563        }
     1564
     1565        /* Terminate it to make it easier to read in the debugger. */
     1566        pDbgc->achInput[pDbgc->iWrite] = '\0';
     1567    } while (pDbgc->pBack->pfnInput(pDbgc->pBack, 0));
    15531568
    15541569    return rc;
     
    17451760            if (VBOX_SUCCESS(rc) && pEvent->u.Src.pszMessage && *pEvent->u.Src.pszMessage)
    17461761                rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
    1747                                          "Message:  %s\n",
     1762                                             "Message:  %s\n",
    17481763                                             pEvent->u.Src.pszMessage);
    17491764            if (VBOX_SUCCESS(rc))
     
    17881803
    17891804
    1790 
     1805/**
     1806 * Prints any log lines from the log buffer.
     1807 *
     1808 * The caller must not call function this unless pDbgc->fLog is set.
     1809 *
     1810 * @returns VBox status. (output related)
     1811 * @param   pDbgc   Debugger console instance data.
     1812 */
     1813static int dbgcProcessLog(PDBGC pDbgc)
     1814{
     1815    /** @todo */
     1816    NOREF(pDbgc);
     1817    return 0;
     1818}
    17911819
    17921820
     
    18071835 *          callbacks to return fatal failures.
    18081836 */
    1809 DBGDECL(int)    DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags)
     1837DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags)
    18101838{
    18111839    /*
Note: See TracChangeset for help on using the changeset viewer.

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