Changeset 64557 in vbox
- Timestamp:
- Nov 4, 2016 10:54:19 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r64552 r64557 2580 2580 VMMR3DECL(int) DBGFR3CfgQueryBbByAddress(DBGFCFG hCfg, PDBGFADDRESS pAddr, PDBGFCFGBB phCfgBb); 2581 2581 VMMR3DECL(uint32_t) DBGFR3CfgGetBbCount(DBGFCFG hCfg); 2582 VMMR3DECL(int) DBGFR3CfgDump(DBGFCFG hCfg, PFNDBGFR3CFGDUMP pfnDump, void *pvUser);2583 2582 VMMR3DECL(uint32_t) DBGFR3CfgBbRetain(DBGFCFGBB hCfgBb); 2584 2583 VMMR3DECL(uint32_t) DBGFR3CfgBbRelease(DBGFCFGBB hCfgBb); -
trunk/src/VBox/VMM/VMMR3/DBGFR3Cfg.cpp
r64552 r64557 911 911 912 912 /** 913 * Returns the buffer starting at the given position.914 *915 * @returns Pointer to the ASCII buffer.916 * @param pScreen The screen.917 * @param uX Horizontal position.918 * @param uY Vertical position.919 */920 static char *dbgfR3CfgDumpScreenGetBufferAtPos(PDBGFCFGDUMPSCREEN pScreen, uint32_t uX, uint32_t uY)921 {922 AssertReturn(uX < pScreen->cchWidth && uY < pScreen->cchHeight, NULL);923 return pScreen->pszScreen + (pScreen->cchWidth + pScreen->cchStride) * uY + uX;924 }925 926 927 /**928 * Draws a single pixel to the screen at the given coordinates.929 *930 * @returns nothing.931 * @param pScreen The screen.932 * @param uX X coordinate.933 * @param uY Y coordinate.934 * @param ch Character to draw.935 */936 DECLINLINE(void) dbgfR3CfgDumpScreenDrawPixel(PDBGFCFGDUMPSCREEN pScreen, uint32_t uX, uint32_t uY, char ch)937 {938 char *psz = dbgfR3CfgDumpScreenGetBufferAtPos(pScreen, uX, uY);939 AssertPtrReturnVoid(psz);940 AssertReturnVoid(*psz != '\0');941 *psz = ch;942 }943 944 945 /**946 * Draws a horizontal line at the given coordinates.947 *948 * @returns nothing.949 * @param pScreen The screen.950 * @param uStartX X position to start drawing.951 * @param uEndX X position to draw the line to (inclusive).952 * @param uY Y position.953 * @param ch The character to use for drawing.954 */955 static void dbgfR3CfgDumpScreenDrawLineHorizontal(PDBGFCFGDUMPSCREEN pScreen, uint32_t uStartX, uint32_t uEndX,956 uint32_t uY, char ch)957 {958 char *psz = dbgfR3CfgDumpScreenGetBufferAtPos(pScreen, uStartX, uY);959 AssertPtrReturnVoid(psz);960 //AssertReturnVoid(psz[uEndX - uStartX + 1] != '\0'); /* Triggers during initialization. */961 962 memset(psz, ch, uEndX - uStartX + 1);963 }964 965 966 /**967 * Draws a vertical line at the given coordinates.968 *969 * @returns nothing.970 * @param pScreen The screen.971 * @param uX X position to draw.972 * @param uStartY Y position to start drawing.973 * @param uEndY Y position to draw to (inclusive).974 * @param ch The character to use for drawing.975 */976 static void dbgfR3CfgDumpScreenDrawLineVertical(PDBGFCFGDUMPSCREEN pScreen, uint32_t uX, uint32_t uStartY,977 uint32_t uEndY, char ch)978 {979 while (uStartY <= uEndY)980 {981 char *psz = dbgfR3CfgDumpScreenGetBufferAtPos(pScreen, uX, uStartY);982 AssertPtrReturnVoid(psz);983 *psz = ch;984 uStartY++;985 }986 }987 988 989 /**990 * Creates a new ASCII screen for layouting.991 *992 * @returns VBox status code.993 * @param ppScreen Where to store the screen instance on success.994 * @param cchWidth Width of the screen in characters.995 * @param cchHeight Height of the screen in characters.996 */997 static int dbgfR3CfgDumpScreenCreate(PDBGFCFGDUMPSCREEN *ppScreen, uint32_t cchWidth, uint32_t cchHeight)998 {999 int rc = VINF_SUCCESS;1000 1001 PDBGFCFGDUMPSCREEN pScreen = (PDBGFCFGDUMPSCREEN)RTMemAllocZ(sizeof(DBGFCFGDUMPSCREEN));1002 if (pScreen)1003 {1004 pScreen->cchWidth = cchWidth;1005 pScreen->cchHeight = cchHeight;1006 pScreen->cchStride = 1; /* Zero terminators after every line. */1007 pScreen->pszScreen = RTStrAlloc((cchWidth + 1) * cchHeight * sizeof(char));1008 if (pScreen->pszScreen)1009 {1010 memset(pScreen->pszScreen, 0, (cchWidth + 1) * cchHeight * sizeof(char));1011 /* Initialize the screen with spaces. */1012 for (uint32_t i = 0; i < cchHeight; i++)1013 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, 0, cchWidth, i, ' ');1014 *ppScreen = pScreen;1015 }1016 else1017 rc = VERR_NO_STR_MEMORY;1018 1019 if (RT_FAILURE(rc))1020 RTMemFree(pScreen);1021 }1022 else1023 rc = VERR_NO_MEMORY;1024 1025 return rc;1026 }1027 1028 1029 /**1030 * Destroys a given ASCII screen.1031 *1032 * @returns nothing.1033 * @param pScreen The screen to destroy.1034 */1035 static void dbgfR3CfgDumpScreenDestroy(PDBGFCFGDUMPSCREEN pScreen)1036 {1037 RTStrFree(pScreen->pszScreen);1038 RTMemFree(pScreen);1039 }1040 1041 1042 /**1043 * Blits the entire screen using the dumper callback.1044 *1045 * @returns VBox status code.1046 * @param pScreen The screen to blit.1047 * @param pfnDump Dumper callback.1048 * @param pvUser Opaque user data to pass to the dumper callback.1049 */1050 static int dbgfR3CfgDumpScreenBlit(PDBGFCFGDUMPSCREEN pScreen, PFNDBGFR3CFGDUMP pfnDump, void *pvUser)1051 {1052 int rc = VINF_SUCCESS;1053 1054 for (uint32_t iY = 0; iY < pScreen->cchHeight && RT_SUCCESS(rc); iY++)1055 {1056 /* Play safe and restore line endings. */1057 char *psz = dbgfR3CfgDumpScreenGetBufferAtPos(pScreen, 0, iY);1058 psz[pScreen->cchWidth] = '\0';1059 rc = pfnDump(psz, pvUser);1060 }1061 1062 return rc;1063 }1064 1065 1066 /**1067 * Calculates the size required for the given basic block including the1068 * border and spacing on the edges.1069 *1070 * @returns nothing.1071 * @param pCfgBb The basic block.1072 * @param pDumpBb The dumper state to fill in for the basic block.1073 */1074 static void dbgfR3CfgDumpBbCalcSizes(PDBGFCFGBBINT pCfgBb, PDBGFCFGDUMPBB pDumpBb)1075 {1076 pDumpBb->pCfgBb = pCfgBb;1077 pDumpBb->cchHeight = pCfgBb->cInstr + 4; /* Include spacing and border top and bottom. */1078 pDumpBb->cchWidth = 0;1079 if ( RT_FAILURE(pCfgBb->rcError)1080 && pCfgBb->pszErr)1081 {1082 pDumpBb->cchHeight++;1083 pDumpBb->cchWidth = RT_MAX(pDumpBb->cchWidth, (uint32_t)strlen(pCfgBb->pszErr));1084 }1085 for (unsigned i = 0; i < pCfgBb->cInstr; i++)1086 pDumpBb->cchWidth = RT_MAX(pDumpBb->cchWidth, (uint32_t)strlen(pCfgBb->aInstr[i].pszInstr));1087 pDumpBb->cchWidth += 4; /* Include spacing and border left and right. */1088 }1089 1090 1091 /**1092 * Dumps a top or bottom boundary line.1093 *1094 * @returns nothing.1095 * @param pScreen The screen to draw to.1096 * @param uStartX Where to start drawing the boundary.1097 * @param uStartY Y coordinate.1098 * @param cchWidth Width of the boundary.1099 */1100 static void dbgfR3CfgDumpBbBoundary(PDBGFCFGDUMPSCREEN pScreen, uint32_t uStartX, uint32_t uStartY, uint32_t cchWidth)1101 {1102 dbgfR3CfgDumpScreenDrawPixel(pScreen, uStartX, uStartY, '+');1103 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, uStartX + 1, uStartX + 1 + cchWidth - 2, uStartY, '-');1104 dbgfR3CfgDumpScreenDrawPixel(pScreen, uStartX + cchWidth - 1, uStartY, '+');1105 }1106 1107 1108 /**1109 * Dumps a spacing line between the top or bottom boundary and the actual disassembly.1110 *1111 * @returns nothing.1112 * @param pScreen The screen to draw to.1113 * @param uStartX Where to start drawing the spacing.1114 * @param uStartY Y coordinate.1115 * @param cchWidth Width of the spacing.1116 */1117 static void dbgfR3CfgDumpBbSpacing(PDBGFCFGDUMPSCREEN pScreen, uint32_t uStartX, uint32_t uStartY, uint32_t cchWidth)1118 {1119 dbgfR3CfgDumpScreenDrawPixel(pScreen, uStartX, uStartY, '|');1120 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, uStartX + 1, uStartX + 1 + cchWidth - 2, uStartY, ' ');1121 dbgfR3CfgDumpScreenDrawPixel(pScreen, uStartX + cchWidth - 1, uStartY, '|');1122 }1123 1124 1125 /**1126 * Writes a given text to the screen.1127 *1128 * @returns nothing.1129 * @returns nothing.1130 * @param pScreen The screen to draw to.1131 * @param uStartX Where to start drawing the line.1132 * @param uStartY Y coordinate.1133 * @param cchWidth Maximum width of the text.1134 * @param pszText The text to write.1135 */1136 static void dbgfR3CfgDumpBbText(PDBGFCFGDUMPSCREEN pScreen, uint32_t uStartX, uint32_t uStartY,1137 uint32_t cchWidth, const char *pszText)1138 {1139 char *psz = dbgfR3CfgDumpScreenGetBufferAtPos(pScreen, uStartX, uStartY);1140 AssertPtrReturnVoid(psz);1141 size_t cch = 0;1142 size_t cchText = strlen(pszText);1143 psz[cch++] = '|';1144 psz[cch++] = ' ';1145 int rc = RTStrCopyEx(&psz[cch], cchWidth, pszText, cchText);1146 AssertRC(rc);1147 1148 /* Fill the rest with spaces. */1149 cch += cchText;1150 while (cch < cchWidth - 1)1151 psz[cch++] = ' ';1152 psz[cch] = '|';1153 }1154 1155 1156 /**1157 * Dumps one basic block using the dumper callback.1158 *1159 * @returns nothing.1160 * @param pDumpBb The basic block dump state to dump.1161 * @param pScreen The screen to dump to.1162 */1163 static void dbgfR3CfgDumpBb(PDBGFCFGDUMPBB pDumpBb, PDBGFCFGDUMPSCREEN pScreen)1164 {1165 uint32_t uStartY = pDumpBb->uStartY;1166 1167 dbgfR3CfgDumpBbBoundary(pScreen, pDumpBb->uStartX, uStartY, pDumpBb->cchWidth);1168 uStartY++;1169 dbgfR3CfgDumpBbSpacing(pScreen, pDumpBb->uStartX, uStartY, pDumpBb->cchWidth);1170 uStartY++;1171 1172 for (unsigned i = 0; i < pDumpBb->pCfgBb->cInstr; i++)1173 dbgfR3CfgDumpBbText(pScreen, pDumpBb->uStartX, uStartY + i,1174 pDumpBb->cchWidth, pDumpBb->pCfgBb->aInstr[i].pszInstr);1175 uStartY += pDumpBb->pCfgBb->cInstr;1176 1177 if (pDumpBb->pCfgBb->pszErr)1178 {1179 dbgfR3CfgDumpBbText(pScreen, pDumpBb->uStartX, uStartY, pDumpBb->cchWidth,1180 pDumpBb->pCfgBb->pszErr);1181 uStartY++;1182 }1183 1184 dbgfR3CfgDumpBbSpacing(pScreen, pDumpBb->uStartX, uStartY, pDumpBb->cchWidth);1185 uStartY++;1186 dbgfR3CfgDumpBbBoundary(pScreen, pDumpBb->uStartX, uStartY, pDumpBb->cchWidth);1187 uStartY++;1188 }1189 1190 1191 /**1192 * @callback_method_impl{FNRTSORTCMP}1193 */1194 static DECLCALLBACK(int) dbgfR3CfgDumpSortCmp(void const *pvElement1, void const *pvElement2, void *pvUser)1195 {1196 RT_NOREF(pvUser);1197 PDBGFCFGDUMPBB pCfgDumpBb1 = (PDBGFCFGDUMPBB)pvElement1;1198 PDBGFCFGDUMPBB pCfgDumpBb2 = (PDBGFCFGDUMPBB)pvElement2;1199 1200 if (dbgfR3CfgBbAddrEqual(&pCfgDumpBb1->pCfgBb->AddrStart, &pCfgDumpBb2->pCfgBb->AddrStart))1201 return 0;1202 else if (dbgfR3CfgBbAddrLower(&pCfgDumpBb1->pCfgBb->AddrStart, &pCfgDumpBb2->pCfgBb->AddrStart))1203 return -1;1204 1205 return 1;1206 }1207 1208 1209 /**1210 * Dumps a given control flow graph as ASCII using the given dumper callback.1211 *1212 * @returns VBox status code.1213 * @param hCfg The control flow graph handle.1214 * @param pfnDump The dumper callback.1215 * @param pvUser Opaque user data to pass to the dumper callback.1216 */1217 VMMR3DECL(int) DBGFR3CfgDump(DBGFCFG hCfg, PFNDBGFR3CFGDUMP pfnDump, void *pvUser)1218 {1219 int rc = VINF_SUCCESS;1220 PDBGFCFGINT pThis = hCfg;1221 AssertPtrReturn(pThis, VERR_INVALID_POINTER);1222 AssertPtrReturn(pfnDump, VERR_INVALID_POINTER);1223 1224 PDBGFCFGDUMPBB paDumpBb = (PDBGFCFGDUMPBB)RTMemTmpAllocZ(pThis->cBbs * sizeof(DBGFCFGDUMPBB));1225 if (paDumpBb)1226 {1227 /* Calculate the sizes of each basic block first. */1228 PDBGFCFGBBINT pCfgBb = NULL;1229 uint32_t idxDumpBb = 0;1230 RTListForEach(&pThis->LstCfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)1231 {1232 dbgfR3CfgDumpBbCalcSizes(pCfgBb, &paDumpBb[idxDumpBb]);1233 idxDumpBb++;1234 }1235 1236 /* Sort the blocks by address. */1237 RTSortShell(paDumpBb, pThis->cBbs, sizeof(DBGFCFGDUMPBB), dbgfR3CfgDumpSortCmp, NULL);1238 1239 /* Calculate the ASCII screen dimensions and create one. */1240 uint32_t cchWidth = 0;1241 uint32_t cchLeftExtra = 5;1242 uint32_t cchRightExtra = 5;1243 uint32_t cchHeight = 0;1244 for (unsigned i = 0; i < pThis->cBbs; i++)1245 {1246 PDBGFCFGDUMPBB pDumpBb = &paDumpBb[i];1247 cchWidth = RT_MAX(cchWidth, pDumpBb->cchWidth);1248 cchHeight += pDumpBb->cchHeight;1249 1250 /* Incomplete blocks don't have a successor. */1251 if (pDumpBb->pCfgBb->fFlags & DBGF_CFG_BB_F_INCOMPLETE_ERR)1252 continue;1253 1254 switch (pDumpBb->pCfgBb->enmEndType)1255 {1256 case DBGFCFGBBENDTYPE_EXIT:1257 case DBGFCFGBBENDTYPE_LAST_DISASSEMBLED:1258 break;1259 case DBGFCFGBBENDTYPE_UNCOND_JMP:1260 if ( dbgfR3CfgBbAddrLower(&pDumpBb->pCfgBb->AddrTarget, &pDumpBb->pCfgBb->AddrStart)1261 || dbgfR3CfgBbAddrEqual(&pDumpBb->pCfgBb->AddrTarget, &pDumpBb->pCfgBb->AddrStart))1262 cchLeftExtra++;1263 else1264 cchRightExtra++;1265 break;1266 case DBGFCFGBBENDTYPE_UNCOND:1267 cchHeight += 2; /* For the arrow down to the next basic block. */1268 break;1269 case DBGFCFGBBENDTYPE_COND:1270 cchHeight += 2; /* For the arrow down to the next basic block. */1271 if ( dbgfR3CfgBbAddrLower(&pDumpBb->pCfgBb->AddrTarget, &pDumpBb->pCfgBb->AddrStart)1272 || dbgfR3CfgBbAddrEqual(&pDumpBb->pCfgBb->AddrTarget, &pDumpBb->pCfgBb->AddrStart))1273 cchLeftExtra++;1274 else1275 cchRightExtra++;1276 break;1277 default:1278 AssertFailed();1279 }1280 }1281 1282 cchWidth += 2;1283 1284 PDBGFCFGDUMPSCREEN pScreen = NULL;1285 rc = dbgfR3CfgDumpScreenCreate(&pScreen, cchWidth + cchLeftExtra + cchRightExtra, cchHeight);1286 if (RT_SUCCESS(rc))1287 {1288 uint32_t uY = 0;1289 1290 /* Dump the basic blocks and connections to the immediate successor. */1291 for (unsigned i = 0; i < pThis->cBbs; i++)1292 {1293 paDumpBb[i].uStartX = cchLeftExtra + (cchWidth - paDumpBb[i].cchWidth) / 2;1294 paDumpBb[i].uStartY = uY;1295 dbgfR3CfgDumpBb(&paDumpBb[i], pScreen);1296 uY += paDumpBb[i].cchHeight;1297 1298 /* Incomplete blocks don't have a successor. */1299 if (paDumpBb[i].pCfgBb->fFlags & DBGF_CFG_BB_F_INCOMPLETE_ERR)1300 continue;1301 1302 switch (paDumpBb[i].pCfgBb->enmEndType)1303 {1304 case DBGFCFGBBENDTYPE_EXIT:1305 case DBGFCFGBBENDTYPE_LAST_DISASSEMBLED:1306 case DBGFCFGBBENDTYPE_UNCOND_JMP:1307 break;1308 case DBGFCFGBBENDTYPE_UNCOND:1309 case DBGFCFGBBENDTYPE_COND:1310 /* Draw the arrow down to the next block. */1311 dbgfR3CfgDumpScreenDrawPixel(pScreen, cchLeftExtra + cchWidth / 2, uY, '|');1312 uY++;1313 dbgfR3CfgDumpScreenDrawPixel(pScreen, cchLeftExtra + cchWidth / 2, uY, 'V');1314 uY++;1315 break;1316 default:1317 AssertFailed();1318 }1319 }1320 1321 /* Last pass, connect all remaining branches. */1322 uint32_t uBackConns = 0;1323 uint32_t uFwdConns = 0;1324 for (unsigned i = 0; i < pThis->cBbs; i++)1325 {1326 PDBGFCFGDUMPBB pDumpBb = &paDumpBb[i];1327 1328 /* Incomplete blocks don't have a successor. */1329 if (pDumpBb->pCfgBb->fFlags & DBGF_CFG_BB_F_INCOMPLETE_ERR)1330 continue;1331 1332 switch (pDumpBb->pCfgBb->enmEndType)1333 {1334 case DBGFCFGBBENDTYPE_EXIT:1335 case DBGFCFGBBENDTYPE_LAST_DISASSEMBLED:1336 case DBGFCFGBBENDTYPE_UNCOND:1337 break;1338 case DBGFCFGBBENDTYPE_COND:1339 case DBGFCFGBBENDTYPE_UNCOND_JMP:1340 {1341 /* Find the target first to get the coordinates. */1342 PDBGFCFGDUMPBB pDumpBbTgt = NULL;1343 for (idxDumpBb = 0; idxDumpBb < pThis->cBbs; idxDumpBb++)1344 {1345 pDumpBbTgt = &paDumpBb[idxDumpBb];1346 if (dbgfR3CfgBbAddrEqual(&pDumpBb->pCfgBb->AddrTarget, &pDumpBbTgt->pCfgBb->AddrStart))1347 break;1348 }1349 1350 /*1351 * Use the right side for targets with higher addresses,1352 * left when jumping backwards.1353 */1354 if ( dbgfR3CfgBbAddrLower(&pDumpBb->pCfgBb->AddrTarget, &pDumpBb->pCfgBb->AddrStart)1355 || dbgfR3CfgBbAddrEqual(&pDumpBb->pCfgBb->AddrTarget, &pDumpBb->pCfgBb->AddrStart))1356 {1357 /* Going backwards. */1358 uint32_t uXVerLine = /*cchLeftExtra - 1 -*/ uBackConns + 1;1359 uint32_t uYHorLine = pDumpBb->uStartY + pDumpBb->cchHeight - 1 - 2;1360 uBackConns++;1361 1362 /* Draw the arrow pointing to the target block. */1363 dbgfR3CfgDumpScreenDrawPixel(pScreen, pDumpBbTgt->uStartX - 1, pDumpBbTgt->uStartY, '>');1364 /* Draw the horizontal line. */1365 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, uXVerLine + 1, pDumpBbTgt->uStartX - 2,1366 pDumpBbTgt->uStartY, '-');1367 dbgfR3CfgDumpScreenDrawPixel(pScreen, uXVerLine, pDumpBbTgt->uStartY, '+');1368 /* Draw the vertical line down to the source block. */1369 dbgfR3CfgDumpScreenDrawLineVertical(pScreen, uXVerLine, pDumpBbTgt->uStartY + 1, uYHorLine - 1, '|');1370 dbgfR3CfgDumpScreenDrawPixel(pScreen, uXVerLine, uYHorLine, '+');1371 /* Draw the horizontal connection between the source block and vertical part. */1372 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, uXVerLine + 1, pDumpBb->uStartX - 1,1373 uYHorLine, '-');1374 1375 }1376 else1377 {1378 /* Going forward. */1379 uint32_t uXVerLine = cchWidth + cchLeftExtra + (cchRightExtra - uFwdConns) - 1;1380 uint32_t uYHorLine = pDumpBb->uStartY + pDumpBb->cchHeight - 1 - 2;1381 uFwdConns++;1382 1383 /* Draw the horizontal line. */1384 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, pDumpBb->uStartX + pDumpBb->cchWidth,1385 uXVerLine - 1, uYHorLine, '-');1386 dbgfR3CfgDumpScreenDrawPixel(pScreen, uXVerLine, uYHorLine, '+');1387 /* Draw the vertical line down to the target block. */1388 dbgfR3CfgDumpScreenDrawLineVertical(pScreen, uXVerLine, uYHorLine + 1, pDumpBbTgt->uStartY - 1, '|');1389 /* Draw the horizontal connection between the target block and vertical part. */1390 dbgfR3CfgDumpScreenDrawLineHorizontal(pScreen, pDumpBbTgt->uStartX + pDumpBbTgt->cchWidth,1391 uXVerLine, pDumpBbTgt->uStartY, '-');1392 dbgfR3CfgDumpScreenDrawPixel(pScreen, uXVerLine, pDumpBbTgt->uStartY, '+');1393 /* Draw the arrow pointing to the target block. */1394 dbgfR3CfgDumpScreenDrawPixel(pScreen, pDumpBbTgt->uStartX + pDumpBbTgt->cchWidth,1395 pDumpBbTgt->uStartY, '<');1396 }1397 break;1398 }1399 default:1400 AssertFailed();1401 }1402 }1403 1404 rc = dbgfR3CfgDumpScreenBlit(pScreen, pfnDump, pvUser);1405 dbgfR3CfgDumpScreenDestroy(pScreen);1406 }1407 1408 RTMemTmpFree(paDumpBb);1409 }1410 else1411 rc = VERR_NO_MEMORY;1412 return rc;1413 }1414 1415 1416 /**1417 913 * Retains the basic block handle. 1418 914 * -
trunk/src/VBox/VMM/VMMR3/VMMR3.def
r64552 r64557 136 136 DBGFR3CfgQueryBbByAddress 137 137 DBGFR3CfgGetBbCount 138 DBGFR3CfgDump139 138 DBGFR3CfgBbRetain 140 139 DBGFR3CfgBbRelease
Note:
See TracChangeset
for help on using the changeset viewer.