Changeset 46161 in vbox for trunk/src/VBox/Runtime/common/dbg
- Timestamp:
- May 19, 2013 1:31:13 PM (12 years ago)
- Location:
- trunk/src/VBox/Runtime/common/dbg
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgcfg.cpp
r46108 r46161 33 33 #include "internal/iprt.h" 34 34 35 #include <iprt/alloca.h> 35 36 #include <iprt/asm.h> 36 37 #include <iprt/assert.h> … … 626 627 if (pThis->fFlags & RTDBGCFG_FLAGS_NO_SYM_SRV) 627 628 return VWRN_NOT_FOUND; 629 if (!pszCacheSubDir || !*pszCacheSubDir) 630 return VWRN_NOT_FOUND; 628 631 629 632 /* … … 749 752 const char *pszCacheSubDir, PRTPATHSPLIT pSplitFn) 750 753 { 754 if (!pszCacheSubDir || !*pszCacheSubDir) 755 return VINF_SUCCESS; 756 751 757 /** @todo copy to cache */ 752 758 return VINF_SUCCESS; … … 1002 1008 if (RT_FAILURE(rc2)) 1003 1009 return rc2; 1010 AssertReturnStmt(pSplitFn->fProps & RTPATH_PROP_FILENAME, RTPathSplitFree(pSplitFn), VERR_IS_A_DIRECTORY); 1004 1011 1005 1012 /* … … 1014 1021 RTPathChangeToUnixSlashes(szPath, false); 1015 1022 rtDbgCfgLog1(pThis, "Trying '%s'...\n", szPath); 1016 rc2 = pfnCallback(pThis, pszFilename, pvUser1, pvUser2);1023 rc2 = pfnCallback(pThis, szPath, pvUser1, pvUser2); 1017 1024 if (rc2 == VINF_CALLBACK_RETURN) 1018 1025 rtDbgCfgLog1(pThis, "Found '%s'.\n", szPath); … … 1168 1175 pfnCallback, pvUser1, pvUser2); 1169 1176 } 1177 1178 1179 1180 /* 1181 * 1182 * D a r w i n . d S Y M b u n d l e s 1183 * D a r w i n . d S Y M b u n d l e s 1184 * D a r w i n . d S Y M b u n d l e s 1185 * 1186 */ 1187 1188 /** 1189 * Very similar to rtDbgCfgTryOpenDir. 1190 */ 1191 static int rtDbgCfgTryOpenDsymBundleInDir(PRTDBGCFGINT pThis, char *pszPath, PRTPATHSPLIT pSplitFn, const char *pszDsymName, 1192 uint32_t fFlags, PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 1193 { 1194 int rcRet = VWRN_NOT_FOUND; 1195 int rc2; 1196 1197 /* If the directory doesn't exist, just quit immediately. 1198 Note! Our case insensitivity doesn't extend to the search dirs themselfs, 1199 only to the bits under neath them. */ 1200 if (!RTDirExists(pszPath)) 1201 { 1202 rtDbgCfgLog2(pThis, "Dir does not exist: '%s'\n", pszPath); 1203 return rcRet; 1204 } 1205 1206 /* Figure out whether we have to do a case sensitive search or not. 1207 Note! As a simplification, we don't ask for case settings in each 1208 directory under the user specified path, we assume the file 1209 systems that mounted there have compatible settings. Faster 1210 that way. */ 1211 bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE) 1212 && !rtDbgCfgIsFsCaseInsensitive(pszPath); 1213 1214 size_t const cchPath = strlen(pszPath); 1215 1216 /* 1217 * Look for the file with less and less of the original path given. 1218 */ 1219 for (unsigned i = RTPATH_PROP_HAS_ROOT_SPEC(pSplitFn->fProps); i < pSplitFn->cComps; i++) 1220 { 1221 pszPath[cchPath] = '\0'; 1222 1223 rc2 = VINF_SUCCESS; 1224 for (unsigned j = i; j < pSplitFn->cComps - 1U && RT_SUCCESS(rc2); j++) 1225 if (!rtDbgCfgIsDirAndFixCase(pszPath, pSplitFn->apszComps[i], fCaseInsensitive)) 1226 rc2 = VERR_FILE_NOT_FOUND; 1227 if ( RT_SUCCESS(rc2) 1228 && !rtDbgCfgIsDirAndFixCase(pszPath, pszDsymName, fCaseInsensitive) 1229 && !rtDbgCfgIsDirAndFixCase(pszPath, "Contents", fCaseInsensitive) 1230 && !rtDbgCfgIsDirAndFixCase(pszPath, "Resources", fCaseInsensitive) 1231 && !rtDbgCfgIsDirAndFixCase(pszPath, "DWARF", fCaseInsensitive)) 1232 { 1233 if (rtDbgCfgIsFileAndFixCase(pszPath, pSplitFn->apszComps[pSplitFn->cComps - 1], fCaseInsensitive, false, NULL)) 1234 { 1235 rtDbgCfgLog1(pThis, "Trying '%s'...\n", pszPath); 1236 rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2); 1237 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 1238 { 1239 if (rc2 == VINF_CALLBACK_RETURN) 1240 rtDbgCfgLog1(pThis, "Found '%s'.\n", pszPath); 1241 else 1242 rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath); 1243 return rc2; 1244 } 1245 rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath); 1246 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 1247 rcRet = rc2; 1248 } 1249 } 1250 rc2 = VERR_FILE_NOT_FOUND; 1251 } 1252 1253 /* 1254 * Do a recursive search if requested. 1255 */ 1256 if ( (fFlags & RTDBGCFG_O_RECURSIVE) 1257 && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH) ) 1258 { 1259 /** @todo Recursive searching will be done later. */ 1260 } 1261 1262 return rcRet; 1263 } 1264 1265 1266 /** 1267 * Very similar to rtDbgCfgTryOpenList. 1268 */ 1269 static int rtDbgCfgTryOpenDsumBundleInList(PRTDBGCFGINT pThis, PRTLISTANCHOR pList, PRTPATHSPLIT pSplitFn, 1270 const char *pszDsymName, const char *pszCacheSubDir, uint32_t fFlags, char *pszPath, 1271 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 1272 { 1273 int rcRet = VWRN_NOT_FOUND; 1274 int rc2; 1275 1276 const char *pchCache = NULL; 1277 size_t cchCache = 0; 1278 int rcCache = VWRN_NOT_FOUND; 1279 1280 PRTDBGCFGSTR pCur; 1281 RTListForEach(pList, pCur, RTDBGCFGSTR, ListEntry) 1282 { 1283 size_t cchDir = pCur->cch; 1284 const char *pszDir = pCur->sz; 1285 rtDbgCfgLog2(pThis, "Path list entry: '%s'\n", pszDir); 1286 1287 /* This is very simplistic, but we have a unreasonably large path 1288 buffer, so it'll work just fine and simplify things greatly below. */ 1289 if (cchDir >= RTPATH_MAX - 8U) 1290 { 1291 if (RT_SUCCESS_NP(rcRet)) 1292 rcRet = VERR_FILENAME_TOO_LONG; 1293 continue; 1294 } 1295 1296 /* 1297 * Process the path according to it's type. 1298 */ 1299 if (!strncmp(pszDir, RT_STR_TUPLE("srv*"))) 1300 { 1301 /* 1302 * Symbol server. 1303 */ 1304 pszDir += sizeof("srv*") - 1; 1305 cchDir -= sizeof("srv*") - 1; 1306 bool fSearchCache = false; 1307 const char *pszServer = (const char *)memchr(pszDir, '*', cchDir); 1308 if (!pszServer) 1309 pszServer = pszDir; 1310 else if (pszServer == pszDir) 1311 continue; 1312 { 1313 fSearchCache = true; 1314 pchCache = pszDir; 1315 cchCache = pszServer - pszDir; 1316 pszServer++; 1317 } 1318 1319 /* We don't have any default cache directory, so skip if the cache is missing. */ 1320 if (cchCache == 0) 1321 continue; 1322 1323 /* Search the cache first (if we haven't already done so). */ 1324 if (fSearchCache) 1325 { 1326 memcpy(pszPath, pchCache, cchCache); 1327 pszPath[cchCache] = '\0'; 1328 RTPathChangeToUnixSlashes(pszPath, false); 1329 1330 rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags, 1331 pfnCallback, pvUser1, pvUser2); 1332 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 1333 return rc2; 1334 } 1335 1336 /* Try downloading the file. */ 1337 if (rcCache == VWRN_NOT_FOUND) 1338 { 1339 memcpy(pszPath, pchCache, cchCache); 1340 pszPath[cchCache] = '\0'; 1341 RTPathChangeToUnixSlashes(pszPath, false); 1342 1343 rc2 = rtDbgCfgTryDownloadAndOpen(pThis, pszServer, pszPath, pszCacheSubDir, pSplitFn, fFlags, 1344 pfnCallback, pvUser1, pvUser2); 1345 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 1346 return rc2; 1347 } 1348 } 1349 else if (!strncmp(pszDir, RT_STR_TUPLE("cache*"))) 1350 { 1351 /* 1352 * Cache directory. 1353 */ 1354 pszDir += sizeof("cache*") - 1; 1355 cchDir -= sizeof("cache*") - 1; 1356 if (!cchDir) 1357 continue; 1358 pchCache = pszDir; 1359 cchCache = cchDir; 1360 1361 memcpy(pszPath, pchCache, cchCache); 1362 pszPath[cchCache] = '\0'; 1363 RTPathChangeToUnixSlashes(pszPath, false); 1364 1365 rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags, 1366 pfnCallback, pvUser1, pvUser2); 1367 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 1368 return rc2; 1369 } 1370 else 1371 { 1372 /* 1373 * Normal directory. Check for our own 'rec*' and 'norec*' prefix 1374 * flags governing recursive searching. 1375 */ 1376 uint32_t fFlagsDir = fFlags; 1377 if (!strncmp(pszDir, RT_STR_TUPLE("rec*"))) 1378 { 1379 pszDir += sizeof("rec*") - 1; 1380 cchDir -= sizeof("rec*") - 1; 1381 fFlagsDir |= RTDBGCFG_O_RECURSIVE; 1382 } 1383 else if (!strncmp(pszDir, RT_STR_TUPLE("norec*"))) 1384 { 1385 pszDir += sizeof("norec*") - 1; 1386 cchDir -= sizeof("norec*") - 1; 1387 fFlagsDir &= ~RTDBGCFG_O_RECURSIVE; 1388 } 1389 1390 /* Copy the path into the buffer and do the searching. */ 1391 memcpy(pszPath, pszDir, cchDir); 1392 pszPath[cchDir] = '\0'; 1393 RTPathChangeToUnixSlashes(pszPath, false); 1394 1395 rc2 = rtDbgCfgTryOpenDsymBundleInDir(pThis, pszPath, pSplitFn, pszDsymName, fFlagsDir, 1396 pfnCallback, pvUser1, pvUser2); 1397 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 1398 { 1399 if ( rc2 == VINF_CALLBACK_RETURN 1400 && cchCache > 0) 1401 rtDbgCfgCopyFileToCache(pThis, pszPath, pchCache, cchCache, pszCacheSubDir, pSplitFn); 1402 return rc2; 1403 } 1404 } 1405 1406 /* Propagate errors. */ 1407 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 1408 rcRet = rc2; 1409 } 1410 1411 return rcRet; 1412 } 1413 1414 1415 RTDECL(int) RTDbgCfgOpenDsymBundle(RTDBGCFG hDbgCfg, const char *pszImage, PCRTUUID pUuid, 1416 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 1417 { 1418 /* 1419 * Bundles are directories, means we can forget about sharing code much 1420 * with the other RTDbgCfgOpenXXX methods. Thus we're duplicating a lot of 1421 * code from rtDbgCfgOpenWithSubDir with .dSYM related adjustments, so, a bug 1422 * found here or there probably means the other version needs updating. 1423 */ 1424 int rcRet = VINF_SUCCESS; 1425 int rc2; 1426 1427 //RTStrPrintf(szFile, sizeof(szFile), "%s.dSYM/Contents/Resources/DWARF/%s", pszFilename, pszFilename); 1428 1429 /* 1430 * Do a little validating first. 1431 */ 1432 PRTDBGCFGINT pThis = hDbgCfg; 1433 if (pThis != NIL_RTDBGCFG) 1434 RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE); 1435 else 1436 pThis = NULL; 1437 AssertPtrReturn(pszImage, VERR_INVALID_POINTER); 1438 AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER); 1439 1440 /* 1441 * Set up rtDbgCfgOpenWithSubDir parameters. 1442 */ 1443 uint32_t fFlags = RTDBGCFG_O_EXT_DEBUG_FILE | RT_OPSYS_DARWIN; 1444 const char *pszCacheSubDir = NULL; 1445 char szCacheSubDir[RTUUID_STR_LENGTH]; 1446 if (pUuid) 1447 { 1448 RTUuidToStr(pUuid, szCacheSubDir, sizeof(szCacheSubDir)); 1449 pszCacheSubDir = szCacheSubDir; 1450 } 1451 1452 /* 1453 * Do some guessing as to the way we should parse the filename and whether 1454 * it's case exact or not. 1455 */ 1456 bool fDosPath = strchr(pszImage, ':') != NULL 1457 || strchr(pszImage, '\\') != NULL 1458 || RT_OPSYS_USES_DOS_PATHS(fFlags & RTDBGCFG_O_OPSYS_MASK) 1459 || (fFlags & RTDBGCFG_O_CASE_INSENSITIVE); 1460 if (fDosPath) 1461 fFlags |= RTDBGCFG_O_CASE_INSENSITIVE; 1462 1463 rtDbgCfgLog2(pThis, "Looking for '%s' with %#x flags...\n", pszImage, fFlags); 1464 1465 PRTPATHSPLIT pSplitFn; 1466 rc2 = RTPathSplitA(pszImage, &pSplitFn, fDosPath ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX); 1467 if (RT_FAILURE(rc2)) 1468 return rc2; 1469 AssertReturnStmt(pSplitFn->fProps & RTPATH_PROP_FILENAME, RTPathSplitFree(pSplitFn), VERR_IS_A_DIRECTORY); 1470 1471 /* 1472 * Try the image directory first. 1473 */ 1474 char szPath[RTPATH_MAX]; 1475 if (pSplitFn->cComps > 0) 1476 { 1477 rc2 = RTPathSplitReassemble(pSplitFn, RTPATH_STR_F_STYLE_HOST, szPath, sizeof(szPath)); 1478 if (RT_SUCCESS(rc2)) 1479 rc2 = RTStrCat(szPath, sizeof(szPath), 1480 ".dSYM" RTPATH_SLASH_STR "Contents" RTPATH_SLASH_STR "Resources" RTPATH_SLASH_STR "DWARF"); 1481 if (RT_SUCCESS(rc2)) 1482 rc2 = RTPathAppend(szPath, sizeof(szPath), pSplitFn->apszComps[pSplitFn->cComps - 1]); 1483 if (RT_SUCCESS(rc2)) 1484 { 1485 RTPathChangeToUnixSlashes(szPath, false); 1486 rtDbgCfgLog1(pThis, "Trying '%s'...\n", szPath); 1487 rc2 = pfnCallback(pThis, szPath, pvUser1, pvUser2); 1488 if (rc2 == VINF_CALLBACK_RETURN) 1489 rtDbgCfgLog1(pThis, "Found '%s'.\n", szPath); 1490 else if (rc2 == VERR_CALLBACK_RETURN) 1491 rtDbgCfgLog1(pThis, "Error opening '%s'.\n", szPath); 1492 else 1493 rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, szPath); 1494 } 1495 } 1496 if ( rc2 != VINF_CALLBACK_RETURN 1497 && rc2 != VERR_CALLBACK_RETURN) 1498 { 1499 char *pszDsymName = (char *)alloca(strlen(pSplitFn->apszComps[pSplitFn->cComps - 1]) + sizeof(".dSYM")); 1500 strcat(strcpy(pszDsymName, pSplitFn->apszComps[pSplitFn->cComps - 1]), ".dSYM"); 1501 1502 /* 1503 * Try the current directory (will take cover relative paths 1504 * skipped above). 1505 */ 1506 rc2 = RTPathGetCurrent(szPath, sizeof(szPath)); 1507 if (RT_FAILURE(rc2)) 1508 strcpy(szPath, "."); 1509 RTPathChangeToUnixSlashes(szPath, false); 1510 1511 rc2 = rtDbgCfgTryOpenDsymBundleInDir(pThis, szPath, pSplitFn, pszDsymName, fFlags, pfnCallback, pvUser1, pvUser2); 1512 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 1513 rcRet = rc2; 1514 1515 if ( rc2 != VINF_CALLBACK_RETURN 1516 && rc2 != VERR_CALLBACK_RETURN 1517 && pThis) 1518 { 1519 rc2 = RTCritSectRwEnterShared(&pThis->CritSect); 1520 if (RT_SUCCESS(rc2)) 1521 { 1522 /* 1523 * Run the applicable lists. 1524 */ 1525 rc2 = rtDbgCfgTryOpenDsumBundleInList(pThis, &pThis->PathList, pSplitFn, pszDsymName, 1526 pszCacheSubDir, fFlags, szPath, 1527 pfnCallback, pvUser1, pvUser2); 1528 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 1529 rcRet = rc2; 1530 1531 RTCritSectRwLeaveShared(&pThis->CritSect); 1532 } 1533 else if (RT_SUCCESS(rcRet)) 1534 rcRet = rc2; 1535 } 1536 } 1537 1538 RTPathSplitFree(pSplitFn); 1539 if ( rc2 == VINF_CALLBACK_RETURN 1540 || rc2 == VERR_CALLBACK_RETURN) 1541 rcRet = rc2; 1542 else if (RT_SUCCESS(rcRet)) 1543 rcRet = VERR_NOT_FOUND; 1544 return rcRet; 1545 1546 1547 } 1548 1170 1549 1171 1550 -
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r46134 r46161 123 123 124 124 125 126 125 127 /** 126 128 * Cleanup debug info interpreter globals. … … 359 361 } 360 362 RT_EXPORT_SYMBOL(RTDbgModCreate); 361 362 363 RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTDBGCFG hDbgCfg)364 {365 /*366 * Input validation and lazy initialization.367 */368 AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER);369 *phDbgMod = NIL_RTDBGMOD;370 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);371 AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);372 AssertPtrNullReturn(pszName, VERR_INVALID_POINTER);373 374 int rc = rtDbgModLazyInit();375 if (RT_FAILURE(rc))376 return rc;377 378 if (!pszName)379 pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS);380 381 /*382 * Allocate a new module instance.383 */384 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));385 if (!pDbgMod)386 return VERR_NO_MEMORY;387 pDbgMod->u32Magic = RTDBGMOD_MAGIC;388 pDbgMod->cRefs = 1;389 rc = RTCritSectInit(&pDbgMod->CritSect);390 if (RT_SUCCESS(rc))391 {392 pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);393 if (pDbgMod->pszName)394 {395 pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);396 if (pDbgMod->pszImgFile)397 {398 RTStrCacheRetain(pDbgMod->pszImgFile);399 pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;400 401 /*402 * Find an image reader which groks the file.403 */404 rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);405 if (RT_SUCCESS(rc))406 {407 rc = VERR_DBG_NO_MATCHING_INTERPRETER;408 PRTDBGMODREGIMG pImg;409 for (pImg = g_pImgHead; pImg; pImg = pImg->pNext)410 {411 pDbgMod->pImgVt = pImg->pVt;412 pDbgMod->pvImgPriv = NULL;413 rc = pImg->pVt->pfnTryOpen(pDbgMod);414 if (RT_SUCCESS(rc))415 {416 /*417 * Find a debug info interpreter.418 */419 rc = VERR_DBG_NO_MATCHING_INTERPRETER;420 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)421 {422 pDbgMod->pDbgVt = pDbg->pVt;423 pDbgMod->pvDbgPriv = NULL;424 rc = pDbg->pVt->pfnTryOpen(pDbgMod);425 if (RT_SUCCESS(rc))426 {427 /*428 * That's it!429 */430 ASMAtomicIncU32(&pDbg->cUsers);431 ASMAtomicIncU32(&pImg->cUsers);432 RTSemRWReleaseRead(g_hDbgModRWSem);433 434 *phDbgMod = pDbgMod;435 return rc;436 }437 }438 439 /*440 * Image detected, but found no debug info we were441 * able to understand.442 */443 /** @todo Fall back on exported symbols! */444 pDbgMod->pImgVt->pfnClose(pDbgMod);445 break;446 }447 }448 449 /*450 * Could it be a file containing raw debug info?451 */452 if (!pImg)453 {454 pDbgMod->pImgVt = NULL;455 pDbgMod->pvImgPriv = NULL;456 pDbgMod->pszDbgFile = pDbgMod->pszImgFile;457 pDbgMod->pszImgFile = NULL;458 459 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)460 {461 pDbgMod->pDbgVt = pDbg->pVt;462 pDbgMod->pvDbgPriv = NULL;463 rc = pDbg->pVt->pfnTryOpen(pDbgMod);464 if (RT_SUCCESS(rc))465 {466 /*467 * That's it!468 */469 ASMAtomicIncU32(&pDbg->cUsers);470 RTSemRWReleaseRead(g_hDbgModRWSem);471 472 *phDbgMod = pDbgMod;473 return rc;474 }475 }476 477 pDbgMod->pszImgFile = pDbgMod->pszDbgFile;478 pDbgMod->pszDbgFile = NULL;479 }480 481 /* bail out */482 RTSemRWReleaseRead(g_hDbgModRWSem);483 }484 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);485 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);486 }487 else488 rc = VERR_NO_STR_MEMORY;489 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);490 }491 else492 rc = VERR_NO_STR_MEMORY;493 RTCritSectDelete(&pDbgMod->CritSect);494 }495 496 RTMemFree(pDbgMod);497 return rc;498 }499 RT_EXPORT_SYMBOL(RTDbgModCreateFromImage);500 501 363 502 364 … … 584 446 585 447 586 587 448 /* 588 449 * 589 * P E I M A G E590 * P E I M A G E591 * P E I M A G E450 * E x e c u t a b l e I m a g e F i l e s 451 * E x e c u t a b l e I m a g e F i l e s 452 * E x e c u t a b l e I m a g e F i l e s 592 453 * 593 454 */ … … 804 665 805 666 667 /** @callback_method_impl{FNRTDBGCFGOPEN} */ 668 static DECLCALLBACK(int) rtDbgModExtDbgInfoOpenCallback2(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2) 669 { 670 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser1; 671 NOREF(pvUser2); /** @todo image matching string or smth. */ 672 673 Assert(!pDbgMod->pDbgVt); 674 Assert(!pDbgMod->pvDbgPriv); 675 Assert(!pDbgMod->pszDbgFile); 676 677 /* 678 * Set the debug file name and try possible interpreters. 679 */ 680 pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); 681 682 int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); 683 if (RT_SUCCESS(rc)) 684 { 685 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext) 686 { 687 pDbgMod->pDbgVt = pDbg->pVt; 688 pDbgMod->pvDbgPriv = NULL; 689 rc = pDbg->pVt->pfnTryOpen(pDbgMod); 690 if (RT_SUCCESS(rc)) 691 { 692 /* 693 * Got it! 694 */ 695 ASMAtomicIncU32(&pDbg->cUsers); 696 RTSemRWReleaseRead(g_hDbgModRWSem); 697 return VINF_CALLBACK_RETURN; 698 } 699 pDbgMod->pDbgVt = NULL; 700 Assert(pDbgMod->pvDbgPriv == NULL); 701 } 702 } 703 704 /* No joy. */ 705 RTSemRWReleaseRead(g_hDbgModRWSem); 706 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); 707 pDbgMod->pszDbgFile = NULL; 708 return rc; 709 } 710 711 712 /** 713 * Opens external debug info that is not listed in the image. 714 * 715 * @returns IPRT status code 716 * @param pDbgMod The debug module. 717 * @param hDbgCfg The debug config. Can be NIL. 718 */ 719 static int rtDbgModOpenDebugInfoExternalToImage2(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg) 720 { 721 int rc; 722 Assert(!pDbgMod->pDbgVt); 723 Assert(pDbgMod->pImgVt); 724 725 /* 726 * Figure out what to search for based on the image format. 727 */ 728 const char *pszzExts = NULL; 729 RTLDRFMT enmFmt = pDbgMod->pImgVt->pfnGetFormat(pDbgMod); 730 switch (enmFmt) 731 { 732 case RTLDRFMT_MACHO: 733 { 734 rc = RTDbgCfgOpenDsymBundle(hDbgCfg, pDbgMod->pszImgFile, NULL /**@todo pUuid*/, 735 rtDbgModExtDbgInfoOpenCallback2, pDbgMod, NULL /*pvUser2*/); 736 if (RT_SUCCESS(rc)) 737 return VINF_SUCCESS; 738 break; 739 } 740 741 #if 0 /* Will be links in the image if these apply. .map readers for PE or ELF we don't have. */ 742 case RTLDRFMT_ELF: 743 pszzExts = ".debug\0.dwo\0"; 744 break; 745 case RTLDRFMT_PE: 746 pszzExts = ".map\0"; 747 break; 748 #endif 749 #if 0 /* Haven't implemented .sym or .map file readers for OS/2 yet. */ 750 case RTLDRFMT_LX: 751 pszzExts = ".sym\0.map\0"; 752 break; 753 #endif 754 default: 755 break; 756 } 757 758 NOREF(pszzExts); 759 #if 0 /* Later */ 760 if (pszzExts) 761 { 762 763 } 764 #endif 765 766 LogFlow(("rtDbgModOpenDebugInfoExternalToImage2: rc=%Rrc\n", rc)); 767 return VERR_NOT_FOUND; 768 } 769 770 771 RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, 772 RTLDRARCH enmArch, RTDBGCFG hDbgCfg) 773 { 774 /* 775 * Input validation and lazy initialization. 776 */ 777 AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER); 778 *phDbgMod = NIL_RTDBGMOD; 779 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 780 AssertReturn(*pszFilename, VERR_INVALID_PARAMETER); 781 AssertPtrNullReturn(pszName, VERR_INVALID_POINTER); 782 AssertReturn(enmArch > RTLDRARCH_INVALID && enmArch < RTLDRARCH_END, VERR_INVALID_PARAMETER); 783 784 int rc = rtDbgModLazyInit(); 785 if (RT_FAILURE(rc)) 786 return rc; 787 788 if (!pszName) 789 pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS); 790 791 /* 792 * Allocate a new module instance. 793 */ 794 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod)); 795 if (!pDbgMod) 796 return VERR_NO_MEMORY; 797 pDbgMod->u32Magic = RTDBGMOD_MAGIC; 798 pDbgMod->cRefs = 1; 799 rc = RTCritSectInit(&pDbgMod->CritSect); 800 if (RT_SUCCESS(rc)) 801 { 802 pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName); 803 if (pDbgMod->pszName) 804 { 805 pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); 806 if (pDbgMod->pszImgFile) 807 { 808 RTStrCacheRetain(pDbgMod->pszImgFile); 809 pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile; 810 811 /* 812 * Find an image reader which groks the file. 813 */ 814 rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); 815 if (RT_SUCCESS(rc)) 816 { 817 rc = VERR_DBG_NO_MATCHING_INTERPRETER; 818 PRTDBGMODREGIMG pImg; 819 for (pImg = g_pImgHead; pImg; pImg = pImg->pNext) 820 { 821 pDbgMod->pImgVt = pImg->pVt; 822 pDbgMod->pvImgPriv = NULL; 823 /** @todo need to specify some arch stuff here. */ 824 rc = pImg->pVt->pfnTryOpen(pDbgMod, enmArch); 825 if (RT_SUCCESS(rc)) 826 { 827 /* 828 * Image detected, but found no debug info we were 829 * able to understand. 830 */ 831 /** @todo some generic way of matching image and debug info, flexible signature 832 * of some kind. Apple uses UUIDs, microsoft uses a UUID+age or a 833 * size+timestamp, and GNU a CRC32 (last time I checked). */ 834 rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, hDbgCfg); 835 if (RT_FAILURE(rc)) 836 rc = rtDbgModOpenDebugInfoInsideImage(pDbgMod); 837 if (RT_FAILURE(rc)) 838 rc = rtDbgModOpenDebugInfoExternalToImage2(pDbgMod, hDbgCfg); 839 if (RT_FAILURE(rc)) 840 rc = rtDbgModCreateForExports(pDbgMod); 841 if (RT_SUCCESS(rc)) 842 { 843 *phDbgMod = pDbgMod; 844 return VINF_SUCCESS; 845 } 846 847 /* Failed, close up the shop. */ 848 pDbgMod->pImgVt->pfnClose(pDbgMod); 849 pDbgMod->pImgVt = NULL; 850 pDbgMod->pvImgPriv = NULL; 851 break; 852 } 853 } 854 855 /* 856 * Could it be a file containing raw debug info? 857 */ 858 if (!pImg) 859 { 860 pDbgMod->pImgVt = NULL; 861 pDbgMod->pvImgPriv = NULL; 862 pDbgMod->pszDbgFile = pDbgMod->pszImgFile; 863 pDbgMod->pszImgFile = NULL; 864 865 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext) 866 { 867 pDbgMod->pDbgVt = pDbg->pVt; 868 pDbgMod->pvDbgPriv = NULL; 869 rc = pDbg->pVt->pfnTryOpen(pDbgMod); 870 if (RT_SUCCESS(rc)) 871 { 872 /* 873 * That's it! 874 */ 875 ASMAtomicIncU32(&pDbg->cUsers); 876 RTSemRWReleaseRead(g_hDbgModRWSem); 877 878 *phDbgMod = pDbgMod; 879 return rc; 880 } 881 } 882 883 pDbgMod->pszImgFile = pDbgMod->pszDbgFile; 884 pDbgMod->pszDbgFile = NULL; 885 } 886 887 /* bail out */ 888 RTSemRWReleaseRead(g_hDbgModRWSem); 889 } 890 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified); 891 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 892 } 893 else 894 rc = VERR_NO_STR_MEMORY; 895 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 896 } 897 else 898 rc = VERR_NO_STR_MEMORY; 899 RTCritSectDelete(&pDbgMod->CritSect); 900 } 901 902 RTMemFree(pDbgMod); 903 return rc; 904 } 905 RT_EXPORT_SYMBOL(RTDbgModCreateFromImage); 906 907 908 909 910 911 /* 912 * 913 * P E I M A G E 914 * P E I M A G E 915 * P E I M A G E 916 * 917 */ 918 919 806 920 807 921 /** @callback_method_impl{FNRTDBGCFGOPEN} */ … … 838 952 pDbgMod->pImgVt = pImg->pVt; 839 953 pDbgMod->pvImgPriv = NULL; 840 rc = pImg->pVt->pfnTryOpen(pDbgMod );954 rc = pImg->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER); 841 955 if (RT_SUCCESS(rc)) 842 956 break; … … 1040 1154 return rc; 1041 1155 } 1042 RT_EXPORT_SYMBOL(RTDbgModCreateFrom Image);1156 RT_EXPORT_SYMBOL(RTDbgModCreateFromPeImage); 1043 1157 1044 1158 -
trunk/src/VBox/Runtime/common/dbg/dbgmoddeferred.cpp
r46149 r46161 440 440 441 441 442 /** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */ 443 static DECLCALLBACK(RTLDRFMT) rtDbgModDeferredImg_GetFormat(PRTDBGMODINT pMod) 444 { 445 RTLDRFMT enmFmt; 446 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/); 447 if (RT_SUCCESS(rc)) 448 enmFmt = pMod->pImgVt->pfnGetFormat(pMod); 449 else 450 enmFmt = RTLDRFMT_INVALID; 451 return enmFmt; 452 } 453 454 442 455 /** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */ 443 456 static DECLCALLBACK(int) rtDbgModDeferredImg_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap) … … 530 543 531 544 /** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */ 532 static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod) 533 { 545 static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch) 546 { 547 NOREF(enmArch); 534 548 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/); 535 549 } … … 552 566 /*.pfnMapPart = */ rtDbgModDeferredImg_MapPart, 553 567 /*.pfnUnmapPart = */ rtDbgModDeferredImg_UnmapPart, 568 /*.pfnGetFormat = */ rtDbgModDeferredImg_GetFormat, 554 569 555 570 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC -
trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp
r46149 r46161 60 60 61 61 62 63 /** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */ 64 static DECLCALLBACK(RTLDRFMT) rtDbgModLdr_GetFormat(PRTDBGMODINT pMod) 65 { 66 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv; 67 return RTLdrGetFormat(pThis->hLdrMod); 68 } 69 70 62 71 /** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */ 63 72 static DECLCALLBACK(int) rtDbgModLdr_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap) … … 158 167 159 168 /** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */ 160 static DECLCALLBACK(int) rtDbgModLdr_TryOpen(PRTDBGMODINT pMod )169 static DECLCALLBACK(int) rtDbgModLdr_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch) 161 170 { 162 171 RTLDRMOD hLdrMod; 163 int rc = RTLdrOpen(pMod->pszImgFile, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, &hLdrMod);172 int rc = RTLdrOpen(pMod->pszImgFile, RTLDR_O_FOR_DEBUG, enmArch, &hLdrMod); 164 173 if (RT_SUCCESS(rc)) 165 174 { … … 188 197 /*.pfnMapPart = */ rtDbgModLdr_MapPart, 189 198 /*.pfnUnmapPart = */ rtDbgModLdr_UnmapPart, 199 /*.pfnGetFormat = */ rtDbgModLdr_GetFormat, 190 200 191 201 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC
Note:
See TracChangeset
for help on using the changeset viewer.