Changeset 84653 in vbox for trunk/src/VBox/Debugger
- Timestamp:
- Jun 3, 2020 9:22:18 AM (5 years ago)
- Location:
- trunk/src/VBox/Debugger
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGCCmdHlp.cpp
r82968 r84653 219 219 if (cbChars) 220 220 { 221 int rc = pDbgc->p Back->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL);221 int rc = pDbgc->pfnOutput(pDbgc->pvOutputUser, pachChars, cbChars); 222 222 if (RT_SUCCESS(rc)) 223 223 pDbgc->chLastOutput = pachChars[cbChars - 1]; -
trunk/src/VBox/Debugger/DBGCGdbRemoteStub.cpp
r84630 r84653 126 126 /** Flag whether the stub is in extended mode. */ 127 127 bool fExtendedMode; 128 /** Flag whether was something was output using the 'O' packet since it was reset last. */ 129 bool fOutput; 128 130 } GDBSTUBCTX; 129 131 /** Pointer to the GDB stub context data. */ … … 356 358 * @param cbSrc Number of bytes to encode. 357 359 */ 358 DECLINLINE(int) dbgcGdbStubCtxEncodeBinaryAsHex(uint8_t *pbDst, size_t cbDst, void *pvSrc, size_t cbSrc)360 DECLINLINE(int) dbgcGdbStubCtxEncodeBinaryAsHex(uint8_t *pbDst, size_t cbDst, const void *pvSrc, size_t cbSrc) 359 361 { 360 362 return RTStrPrintHexBytes((char *)pbDst, cbDst, pvSrc, cbSrc, RTSTRPRINTHEXBYTES_F_UPPER); … … 1089 1091 1090 1092 1091 #if 01092 /**1093 * Calls the given command handler and processes the reply.1094 *1095 * @returns Status code.1096 * @param pThis The GDB stub context.1097 * @param pCmd The command to call - NULL if using the generic monitor command received callback in the1098 * interface callback table.1099 * @param pszArgs Argument string to call the command with.1100 */1101 static int gdbStubCtxCmdProcess(PGDBSTUBCTXINT pThis, PCGDBSTUBCMD pCmd, const char *pszArgs)1102 {1103 int rc = gdbStubCtxReplySendBegin(pThis);1104 if (rc == GDBSTUB_INF_SUCCESS)1105 {1106 gdbStubOutCtxReset(&pThis->OutCtx);1107 int rcCmd = GDBSTUB_INF_SUCCESS;1108 if (pCmd)1109 rcCmd = pCmd->pfnCmd(pThis, &pThis->OutCtx.Hlp, pszArgs, pThis->pvUser);1110 else1111 rcCmd = pThis->pIf->pfnMonCmd(pThis, &pThis->OutCtx.Hlp, pszArgs, pThis->pvUser);1112 if (rcCmd == GDBSTUB_INF_SUCCESS)1113 {1114 if (!pThis->OutCtx.offScratch) /* No output, just send OK reply. */1115 rc = gdbStubCtxReplySendOkData(pThis);1116 else1117 rc = gdbStubCtxReplySendData(pThis, &pThis->OutCtx.abScratch[0], pThis->OutCtx.offScratch);1118 1119 /* Try to finish the reply in case of an error anyway (but we might be completely screwed at this point anyway). */1120 gdbStubCtxReplySendEnd(pThis);1121 }1122 else1123 rc = gdbStubCtxReplySendErrStsData(pThis, rcCmd);1124 }1125 1126 return rc;1127 }1128 1129 1130 1093 /** 1131 1094 * Processes the 'Rcmd' query. … … 1136 1099 * @param cbArgs Size of arguments in bytes. 1137 1100 */ 1138 static int gdbStubCtxPktProcessQueryRcmd(PGDBSTUBCTXINT pThis, const uint8_t *pbArgs, size_t cbArgs) 1139 { 1140 int rc = GDBSTUB_INF_SUCCESS; 1141 1101 static int dbgcGdbStubCtxPktProcessQueryRcmd(PGDBSTUBCTX pThis, const uint8_t *pbArgs, size_t cbArgs) 1102 { 1142 1103 /* Skip the , following the qRcmd start. */ 1143 1104 if ( cbArgs < 1 1144 1105 || pbArgs[0] != ',') 1145 return GDBSTUB_ERR_PROTOCOL_VIOLATION; 1146 1147 if (!pThis->pIf->paCmds) 1148 return GDBSTUB_ERR_NOT_FOUND; 1106 return VERR_NET_PROTOCOL_ERROR; 1149 1107 1150 1108 cbArgs--; … … 1153 1111 /* Decode the command. */ 1154 1112 /** @todo Make this dynamic. */ 1155 char szCmd[4096]; 1113 char szCmd[_4K]; 1114 RT_ZERO(szCmd); 1115 1156 1116 if (cbArgs / 2 >= sizeof(szCmd)) 1157 return GDBSTUB_ERR_BUFFER_OVERFLOW;1117 return VERR_NET_PROTOCOL_ERROR; 1158 1118 1159 1119 size_t cbDecoded = 0; 1160 rc = gdbStubCtxParseHexStringAsByteBuf(pbArgs, cbArgs - 1, &szCmd[0], sizeof(szCmd), &cbDecoded);1161 if (rc == GDBSTUB_INF_SUCCESS)1162 {1163 const char *pszArgs = NULL;1164 1165 cbDecoded /= 2;1120 int rc = RTStrConvertHexBytesEx((const char *)pbArgs, &szCmd[0], sizeof(szCmd), 0 /*fFlags*/, 1121 NULL /* ppszNext */, &cbDecoded); 1122 if (rc == VWRN_TRAILING_CHARS) 1123 rc = VINF_SUCCESS; 1124 if (RT_SUCCESS(rc)) 1125 { 1166 1126 szCmd[cbDecoded] = '\0'; /* Ensure zero termination. */ 1167 1127 1168 /** @todo Sanitize string. */ 1169 1170 /* Look for the first space and take that as the separator between command identifier. */ 1171 uint8_t *pbDelim = gdbStubCtxMemchr(&szCmd[0], ' ', cbDecoded); 1172 if (pbDelim) 1173 { 1174 *pbDelim = '\0'; 1175 pszArgs = pbDelim + 1; 1176 } 1177 1178 /* Search for the command. */ 1179 PCGDBSTUBCMD pCmd = &pThis->pIf->paCmds[0]; 1180 rc = GDBSTUB_ERR_NOT_FOUND; 1181 while (pCmd->pszCmd) 1182 { 1183 if (!gdbStubStrcmp(pCmd->pszCmd, &szCmd[0])) 1184 { 1185 rc = gdbStubCtxCmdProcess(pThis, pCmd, pszArgs); 1186 break; 1187 } 1188 pCmd++; 1189 } 1190 1191 if ( rc == GDBSTUB_ERR_NOT_FOUND 1192 && pThis->pIf->pfnMonCmd) 1193 { 1194 /* Restore delimiter. */ 1195 if (pbDelim) 1196 *pbDelim = ' '; 1197 rc = gdbStubCtxCmdProcess(pThis, NULL, &szCmd[0]); 1198 } 1199 else 1200 rc = gdbStubCtxReplySendErrSts(pThis, rc); /** @todo Send string. */ 1128 pThis->fOutput = false; 1129 rc = dbgcEvalCommand(&pThis->Dbgc, &szCmd[0], cbDecoded, false /*fNoExecute*/); 1130 dbgcGdbStubCtxReplySendOk(pThis); 1131 if ( rc != VERR_DBGC_QUIT 1132 && rc != VWRN_DBGC_CMD_PENDING) 1133 rc = VINF_SUCCESS; /* ignore other statuses */ 1201 1134 } 1202 1135 1203 1136 return rc; 1204 1137 } 1205 #endif1206 1138 1207 1139 … … 1215 1147 GDBSTUBQPKTPROC_INIT("Supported", dbgcGdbStubCtxPktProcessQuerySupported), 1216 1148 GDBSTUBQPKTPROC_INIT("Xfer:features:read", dbgcGdbStubCtxPktProcessQueryXferFeatRead), 1217 //GDBSTUBQPKTPROC_INIT("Rcmd", dbgcGdbStubCtxPktProcessQueryRcmd),1149 GDBSTUBQPKTPROC_INIT("Rcmd", dbgcGdbStubCtxPktProcessQueryRcmd), 1218 1150 #undef GDBSTUBQPKTPROC_INIT 1219 1151 }; … … 1981 1913 * Process the event. 1982 1914 */ 1915 PDBGC pDbgc = &pThis->Dbgc; 1983 1916 pThis->Dbgc.pszScratch = &pThis->Dbgc.achInput[0]; 1984 1917 pThis->Dbgc.iArg = 0; … … 1996 1929 1997 1930 1998 #if 01999 1931 /* 2000 1932 * The second part is events which can occur at any time. … … 2008 1940 break; 2009 1941 } 2010 #endif2011 1942 2012 1943 case DBGFEVENT_BREAKPOINT: … … 2026 1957 } 2027 1958 2028 #if 02029 1959 case DBGFEVENT_ASSERTION_HYPER: 2030 1960 { … … 2069 1999 break; 2070 2000 } 2071 #endif2072 2001 2073 2002 case DBGFEVENT_POWERING_OFF: … … 2236 2165 2237 2166 /** 2167 * @copdoc{DBGC,pfnOutput} 2168 */ 2169 static DECLCALLBACK(int) dbgcOutputGdb(void *pvUser, const char *pachChars, size_t cbChars) 2170 { 2171 PGDBSTUBCTX pThis = (PGDBSTUBCTX)pvUser; 2172 2173 pThis->fOutput = true; 2174 int rc = dbgcGdbStubCtxReplySendBegin(pThis); 2175 if (RT_SUCCESS(rc)) 2176 { 2177 uint8_t chConOut = 'O'; 2178 rc = dbgcGdbStubCtxReplySendData(pThis, &chConOut, sizeof(chConOut)); 2179 if (RT_SUCCESS(rc)) 2180 { 2181 /* Convert the characters to hex. */ 2182 const char *pachCur = pachChars; 2183 2184 while ( cbChars 2185 && RT_SUCCESS(rc)) 2186 { 2187 uint8_t achHex[512 + 1]; 2188 size_t cbThisSend = RT_MIN((sizeof(achHex) - 1) / 2, cbChars); /* Each character needs two bytes. */ 2189 2190 rc = dbgcGdbStubCtxEncodeBinaryAsHex(&achHex[0], cbThisSend * 2 + 1, pachCur, cbThisSend); 2191 if (RT_SUCCESS(rc)) 2192 rc = dbgcGdbStubCtxReplySendData(pThis, &achHex[0], cbThisSend * 2); 2193 2194 pachCur += cbThisSend; 2195 cbChars -= cbThisSend; 2196 } 2197 } 2198 2199 dbgcGdbStubCtxReplySendEnd(pThis); 2200 } 2201 2202 return rc; 2203 } 2204 2205 2206 /** 2238 2207 * Creates a GDB stub context instance with the given backend. 2239 2208 * … … 2264 2233 */ 2265 2234 pThis->Dbgc.pBack = pBack; 2235 pThis->Dbgc.pfnOutput = dbgcOutputGdb; 2236 pThis->Dbgc.pvOutputUser = pThis; 2266 2237 pThis->Dbgc.pVM = NULL; 2267 2238 pThis->Dbgc.pUVM = NULL; … … 2317 2288 pThis->cbTgtXmlDesc = 0; 2318 2289 pThis->fExtendedMode = false; 2290 pThis->fOutput = false; 2319 2291 dbgcGdbStubCtxReset(pThis); 2320 2292 … … 2385 2357 pThis->Dbgc.pUVM = pUVM; 2386 2358 pThis->Dbgc.idCpu = 0; 2359 rc = pThis->Dbgc.CmdHlp.pfnPrintf(&pThis->Dbgc.CmdHlp, NULL, 2360 "Current VM is %08x, CPU #%u\n" /** @todo get and print the VM name! */ 2361 , pThis->Dbgc.pVM, pThis->Dbgc.idCpu); 2387 2362 } 2388 2363 else -
trunk/src/VBox/Debugger/DBGCInternal.h
r84627 r84653 116 116 /** Pointer to backend callback structure. */ 117 117 PDBGCBACK pBack; 118 119 /** 120 * Output a bunch of characters. 121 * 122 * @returns VBox status code. 123 * @param pvUser Opaque user data from DBGC::pvOutputUser. 124 * @param pachChars Pointer to an array of utf-8 characters. 125 * @param cbChars Number of bytes in the character array pointed to by pachChars. 126 */ 127 DECLR3CALLBACKMEMBER(int, pfnOutput, (void *pvUser, const char *pachChars, size_t cbChars)); 128 /** Opqaue user data passed to DBGC::pfnOutput. */ 129 void *pvOutputUser; 118 130 119 131 /** Pointer to the current VM. */ … … 587 599 void dbgcDestroy(PDBGC pDbgc); 588 600 601 const char *dbgcGetEventCtx(DBGFEVENTCTX enmCtx); 589 602 590 603 DECLHIDDEN(int) dbgcGdbStubCreate(PUVM pUVM, PDBGCBACK pBack, unsigned fFlags); -
trunk/src/VBox/Debugger/DBGConsole.cpp
r84627 r84653 588 588 * @param enmCtx The context. 589 589 */ 590 staticconst char *dbgcGetEventCtx(DBGFEVENTCTX enmCtx)590 const char *dbgcGetEventCtx(DBGFEVENTCTX enmCtx) 591 591 { 592 592 switch (enmCtx) … … 1089 1089 1090 1090 1091 /** 1092 * @copdoc{DBGC,pfnOutput} 1093 */ 1094 static DECLCALLBACK(int) dbgcOutputNative(void *pvUser, const char *pachChars, size_t cbChars) 1095 { 1096 PDBGC pDbgc = (PDBGC)pvUser; 1097 return pDbgc->pBack->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL /*pcbWritten*/); 1098 } 1099 1091 1100 1092 1101 /** … … 1115 1124 dbgcInitCmdHlp(pDbgc); 1116 1125 pDbgc->pBack = pBack; 1126 pDbgc->pfnOutput = dbgcOutputNative; 1127 pDbgc->pvOutputUser = pDbgc; 1117 1128 pDbgc->pVM = NULL; 1118 1129 pDbgc->pUVM = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.