VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGCCmdWorkers.cpp@ 74882

Last change on this file since 74882 was 73097, checked in by vboxsync, 6 years ago

*: Made RT_UOFFSETOF, RT_OFFSETOF, RT_UOFFSETOF_ADD and RT_OFFSETOF_ADD work like builtin_offsetof() and require compile time resolvable requests, adding RT_UOFFSETOF_DYN for the dynamic questions that can only be answered at runtime.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: DBGCCmdWorkers.cpp 73097 2018-07-12 21:06:33Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, Command Worker Routines.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DBGC
23#include <VBox/dbg.h>
24#include <VBox/vmm/dbgf.h>
25#include <VBox/param.h>
26#include <VBox/err.h>
27#include <VBox/log.h>
28
29#include <iprt/alloc.h>
30#include <iprt/string.h>
31#include <iprt/assert.h>
32
33#include "DBGCInternal.h"
34
35
36
37
38//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
39//
40//
41// B r e a k p o i n t M a n a g e m e n t
42//
43//
44//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
45
46
47/**
48 * Adds a breakpoint to the DBGC breakpoint list.
49 */
50int dbgcBpAdd(PDBGC pDbgc, RTUINT iBp, const char *pszCmd)
51{
52 /*
53 * Check if it already exists.
54 */
55 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
56 if (pBp)
57 return VERR_DBGC_BP_EXISTS;
58
59 /*
60 * Add the breakpoint.
61 */
62 if (pszCmd)
63 pszCmd = RTStrStripL(pszCmd);
64 size_t cchCmd = pszCmd ? strlen(pszCmd) : 0;
65 pBp = (PDBGCBP)RTMemAlloc(RT_UOFFSETOF_DYN(DBGCBP, szCmd[cchCmd + 1]));
66 if (!pBp)
67 return VERR_NO_MEMORY;
68 if (cchCmd)
69 memcpy(pBp->szCmd, pszCmd, cchCmd + 1);
70 else
71 pBp->szCmd[0] = '\0';
72 pBp->cchCmd = cchCmd;
73 pBp->iBp = iBp;
74 pBp->pNext = pDbgc->pFirstBp;
75 pDbgc->pFirstBp = pBp;
76
77 return VINF_SUCCESS;
78}
79
80/**
81 * Updates the a breakpoint.
82 *
83 * @returns VBox status code.
84 * @param pDbgc The DBGC instance.
85 * @param iBp The breakpoint to update.
86 * @param pszCmd The new command.
87 */
88int dbgcBpUpdate(PDBGC pDbgc, RTUINT iBp, const char *pszCmd)
89{
90 /*
91 * Find the breakpoint.
92 */
93 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
94 if (!pBp)
95 return VERR_DBGC_BP_NOT_FOUND;
96
97 /*
98 * Do we need to reallocate?
99 */
100 if (pszCmd)
101 pszCmd = RTStrStripL(pszCmd);
102 if (!pszCmd || !*pszCmd)
103 pBp->szCmd[0] = '\0';
104 else
105 {
106 size_t cchCmd = strlen(pszCmd);
107 if (strlen(pBp->szCmd) >= cchCmd)
108 {
109 memcpy(pBp->szCmd, pszCmd, cchCmd + 1);
110 pBp->cchCmd = cchCmd;
111 }
112 else
113 {
114 /*
115 * Yes, let's do it the simple way...
116 */
117 int rc = dbgcBpDelete(pDbgc, iBp);
118 AssertRC(rc);
119 return dbgcBpAdd(pDbgc, iBp, pszCmd);
120 }
121 }
122 return VINF_SUCCESS;
123}
124
125
126/**
127 * Deletes a breakpoint.
128 *
129 * @returns VBox status code.
130 * @param pDbgc The DBGC instance.
131 * @param iBp The breakpoint to delete.
132 */
133int dbgcBpDelete(PDBGC pDbgc, RTUINT iBp)
134{
135 /*
136 * Search thru the list, when found unlink and free it.
137 */
138 PDBGCBP pBpPrev = NULL;
139 PDBGCBP pBp = pDbgc->pFirstBp;
140 for (; pBp; pBp = pBp->pNext)
141 {
142 if (pBp->iBp == iBp)
143 {
144 if (pBpPrev)
145 pBpPrev->pNext = pBp->pNext;
146 else
147 pDbgc->pFirstBp = pBp->pNext;
148 RTMemFree(pBp);
149 return VINF_SUCCESS;
150 }
151 pBpPrev = pBp;
152 }
153
154 return VERR_DBGC_BP_NOT_FOUND;
155}
156
157
158/**
159 * Get a breakpoint.
160 *
161 * @returns Pointer to the breakpoint.
162 * @returns NULL if the breakpoint wasn't found.
163 * @param pDbgc The DBGC instance.
164 * @param iBp The breakpoint to get.
165 */
166PDBGCBP dbgcBpGet(PDBGC pDbgc, RTUINT iBp)
167{
168 /*
169 * Enumerate the list.
170 */
171 PDBGCBP pBp = pDbgc->pFirstBp;
172 for (; pBp; pBp = pBp->pNext)
173 if (pBp->iBp == iBp)
174 return pBp;
175 return NULL;
176}
177
178
179/**
180 * Executes the command of a breakpoint.
181 *
182 * @returns VINF_DBGC_BP_NO_COMMAND if there is no command associated with the breakpoint.
183 * @returns VERR_DBGC_BP_NOT_FOUND if the breakpoint wasn't found.
184 * @returns VERR_BUFFER_OVERFLOW if the is not enough space in the scratch buffer for the command.
185 * @returns VBox status code from dbgcEvalCommand() otherwise.
186 * @param pDbgc The DBGC instance.
187 * @param iBp The breakpoint to execute.
188 */
189int dbgcBpExec(PDBGC pDbgc, RTUINT iBp)
190{
191 /*
192 * Find the breakpoint.
193 */
194 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
195 if (!pBp)
196 return VERR_DBGC_BP_NOT_FOUND;
197
198 /*
199 * Anything to do?
200 */
201 if (!pBp->cchCmd)
202 return VINF_DBGC_BP_NO_COMMAND;
203
204 /*
205 * Execute the command.
206 * This means copying it to the scratch buffer and process it as if it
207 * were user input. We must save and restore the state of the scratch buffer.
208 */
209 /* Save the scratch state. */
210 char *pszScratch = pDbgc->pszScratch;
211 unsigned iArg = pDbgc->iArg;
212
213 /* Copy the command to the scratch buffer. */
214 size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
215 if (pBp->cchCmd >= cbScratch)
216 return VERR_BUFFER_OVERFLOW;
217 memcpy(pDbgc->pszScratch, pBp->szCmd, pBp->cchCmd + 1);
218
219 /* Execute the command. */
220 pDbgc->pszScratch = pDbgc->pszScratch + pBp->cchCmd + 1;
221 int rc = dbgcEvalCommand(pDbgc, pszScratch, pBp->cchCmd, false /* fNoExecute */);
222
223 /* Restore the scratch state. */
224 pDbgc->iArg = iArg;
225 pDbgc->pszScratch = pszScratch;
226
227 return rc;
228}
229
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