Changeset 46025 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- May 13, 2013 3:36:27 PM (12 years ago)
- Location:
- trunk/src/VBox/Runtime/common/dbg
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgcfg.cpp
r45998 r46025 29 29 * Header Files * 30 30 *******************************************************************************/ 31 #define LOG_GROUP RTLOGGROUP_DBG 31 32 #include <iprt/dbg.h> 32 33 #include "internal/iprt.h" … … 36 37 #include <iprt/critsect.h> 37 38 #include <iprt/ctype.h> 39 #include <iprt/dir.h> 38 40 #include <iprt/err.h> 39 41 #include <iprt/env.h> 42 #include <iprt/file.h> 40 43 #include <iprt/list.h> 44 #include <iprt/log.h> 41 45 #include <iprt/mem.h> 42 46 #include <iprt/path.h> 43 47 #include <iprt/semaphore.h> 44 48 #include <iprt/string.h> 49 #include <iprt/uuid.h> 45 50 #include "internal/magics.h" 46 51 … … 49 54 * Structures and Typedefs * 50 55 *******************************************************************************/ 51 /** @name Flags for path search strings52 * @{ */53 #define RTDBGCCFG_PATH_SRV UINT16_C(0x0001)54 #define RTDBGCCFG_PATH_CACHE UINT16_C(0x0002)55 /** @}*/56 57 56 /** 58 57 * String list entry. … … 72 71 typedef RTDBGCFGSTR *PRTDBGCFGSTR; 73 72 73 74 /** 75 * Log callback. 76 * 77 * @param hDbgCfg The debug config instance. 78 * @param iLevel The message level. 79 * @param pszMsg The message. 80 * @param pvUser User argument. 81 */ 82 typedef DECLCALLBACK(int) FNRTDBGCFGLOG(RTDBGCFG hDbgCfg, uint32_t iLevel, const char *pszMsg, void *pvUser); 83 /** Pointer to a log callback. */ 84 typedef FNRTDBGCFGLOG *PFNRTDBGCFGLOG; 85 74 86 /** 75 87 * Configuration instance. … … 100 112 #endif 101 113 114 /** Log callback function. */ 115 PFNRTDBGCFGLOG pfnLogCallback; 116 /** User argument to pass to the log callback. */ 117 void *pvLogUser; 118 102 119 /** Critical section protecting the instance data. */ 103 120 RTCRITSECTRW CritSect; 104 121 } *PRTDBGCFGINT; 105 106 122 107 123 /** … … 124 140 125 141 142 /** @name Open flags. 143 * @{ */ 144 /** The operative system mask. The values are RT_OPSYS_XXX. */ 145 #define RTDBGCFG_O_OPSYS_MASK UINT32_C(0x000000ff) 146 /** Whether to make a recursive search. */ 147 #define RTDBGCFG_O_RECURSIVE RT_BIT_32(27) 148 /** We're looking for a separate debug file. */ 149 #define RTDBGCFG_O_EXT_DEBUG_FILE RT_BIT_32(28) 150 /** We're looking for an executable image. */ 151 #define RTDBGCFG_O_EXECUTABLE_IMAGE RT_BIT_32(29) 152 /** The file search should be done in an case insensitive fashion. */ 153 #define RTDBGCFG_O_CASE_INSENSITIVE RT_BIT_32(30) 154 /** Use Windbg style symbol servers when encountered in the path. */ 155 #define RTDBGCFG_O_SYMSRV RT_BIT_32(31) 156 /** @} */ 157 126 158 127 159 /******************************************************************************* … … 158 190 159 191 192 /** 193 * Runtime logging, level 1. 194 * 195 * @param pThis The debug config instance data. 196 * @param pszFormat The message format string. 197 * @param ... Arguments references in the format string. 198 */ 199 static void rtDbgCfgLog1(PRTDBGCFGINT pThis, const char *pszFormat, ...) 200 { 201 if (LogIsEnabled() || (pThis && pThis->pfnLogCallback)) 202 { 203 va_list va; 204 va_start(va, pszFormat); 205 char *pszMsg = RTStrAPrintf2V(pszFormat, va); 206 va_end(va); 207 208 Log(("RTDbgCfg: %s", pszMsg)); 209 if (pThis && pThis->pfnLogCallback) 210 pThis->pfnLogCallback(pThis, 1, pszMsg, pThis->pvLogUser); 211 RTStrFree(pszMsg); 212 } 213 } 214 215 216 /** 217 * Runtime logging, level 2. 218 * 219 * @param pThis The debug config instance data. 220 * @param pszFormat The message format string. 221 * @param ... Arguments references in the format string. 222 */ 223 static void rtDbgCfgLog2(PRTDBGCFGINT pThis, const char *pszFormat, ...) 224 { 225 if (LogIs2Enabled() || (pThis && pThis->pfnLogCallback)) 226 { 227 va_list va; 228 va_start(va, pszFormat); 229 char *pszMsg = RTStrAPrintf2V(pszFormat, va); 230 va_end(va); 231 232 Log(("RTDbgCfg: %s", pszMsg)); 233 if (pThis && pThis->pfnLogCallback) 234 pThis->pfnLogCallback(pThis, 2, pszMsg, pThis->pvLogUser); 235 RTStrFree(pszMsg); 236 } 237 } 238 239 240 /** 241 * Checks if the file system at the given path is case insensitive or not. 242 * 243 * @returns true / false 244 * @param pszPath The path to query about. 245 */ 246 static int rtDbgCfgIsFsCaseInsensitive(const char *pszPath) 247 { 248 RTFSPROPERTIES Props; 249 int rc = RTFsQueryProperties(pszPath, &Props); 250 if (RT_FAILURE(rc)) 251 return RT_OPSYS == RT_OPSYS_DARWIN 252 || RT_OPSYS == RT_OPSYS_DOS 253 || RT_OPSYS == RT_OPSYS_OS2 254 || RT_OPSYS == RT_OPSYS_NT 255 || RT_OPSYS == RT_OPSYS_WINDOWS; 256 return !Props.fCaseSensitive; 257 } 258 259 260 /** 261 * Worker that does case sensitive file/dir searching. 262 * 263 * @returns true / false. 264 * @param pszPath The path buffer containing an existing directory. 265 * RTPATH_MAX in size. On success, this will contain 266 * the combined path with @a pszName case correct. 267 * @param offLastComp The offset of the last component (for chopping it 268 * off). 269 * @param pszName What we're looking for. 270 * @param enmType What kind of thing we're looking for. 271 */ 272 static bool rtDbgCfgIsXxxxAndFixCaseWorker(char *pszPath, size_t offLastComp, const char *pszName, 273 RTDIRENTRYTYPE enmType) 274 { 275 /** @todo IPRT should generalize this so we can use host specific tricks to 276 * speed it up. */ 277 278 /* Return straight away if the name isn't case foldable. */ 279 if (!RTStrIsCaseFoldable(pszName)) 280 return false; 281 282 /* 283 * Open the directory and check each entry in it. 284 */ 285 pszPath[offLastComp] = '\0'; 286 PRTDIR pDir; 287 int rc = RTDirOpen(&pDir, pszPath); 288 if (RT_SUCCESS(rc)) 289 return false; 290 291 for (;;) 292 { 293 /* Read the next entry. */ 294 union 295 { 296 RTDIRENTRY Entry; 297 uint8_t ab[_4K]; 298 } u; 299 size_t cbBuf = sizeof(u); 300 rc = RTDirRead(pDir, &u.Entry, &cbBuf); 301 if (RT_FAILURE(rc)) 302 break; 303 304 if ( !RTStrICmp(pszName, u.Entry.szName) 305 && ( u.Entry.enmType == enmType 306 || u.Entry.enmType == RTDIRENTRYTYPE_UNKNOWN 307 || u.Entry.enmType == RTDIRENTRYTYPE_SYMLINK) ) 308 { 309 pszPath[offLastComp] = '\0'; 310 rc = RTPathAppend(pszPath, RTPATH_MAX, u.Entry.szName); 311 if ( u.Entry.enmType != enmType 312 && RT_SUCCESS(rc)) 313 RTDirQueryUnknownType(pszPath, true /*fFollowSymlinks*/, &u.Entry.enmType); 314 315 if ( u.Entry.enmType == enmType 316 || RT_FAILURE(rc)) 317 { 318 RTDirClose(pDir); 319 if (RT_FAILURE(rc)) 320 { 321 pszPath[offLastComp] = '\0'; 322 return false; 323 } 324 return true; 325 } 326 } 327 } 328 329 RTDirClose(pDir); 330 pszPath[offLastComp] = '\0'; 331 332 return false; 333 } 334 335 336 /** 337 * Appends @a pszSubDir to @a pszPath and check whether it exists and is a 338 * directory. 339 * 340 * If @a fCaseInsensitive is set, we will do a case insensitive search for a 341 * matching sub directory. 342 * 343 * @returns true / false 344 * @param pszPath The path buffer containing an existing 345 * directory. RTPATH_MAX in size. 346 * @param pszSubDir The sub directory to append. 347 * @param fCaseInsensitive Whether case insensitive searching is required. 348 */ 349 static bool rtDbgCfgIsDirAndFixCase(char *pszPath, const char *pszSubDir, bool fCaseInsensitive) 350 { 351 /* Save the length of the input path so we can restore it in the case 352 insensitive branch further down. */ 353 size_t const cchPath = strlen(pszPath); 354 355 /* 356 * Append the sub directory and check if we got a hit. 357 */ 358 int rc = RTPathAppend(pszPath, RTPATH_MAX, pszSubDir); 359 if (RT_FAILURE(rc)) 360 return false; 361 362 if (RTDirExists(pszPath)) 363 return true; 364 365 /* 366 * Do case insensitive lookup if requested. 367 */ 368 if (fCaseInsensitive) 369 return rtDbgCfgIsXxxxAndFixCaseWorker(pszPath, cchPath, pszSubDir, RTDIRENTRYTYPE_DIRECTORY); 370 return false; 371 } 372 373 374 /** 375 * Appends @a pszFilename to @a pszPath and check whether it exists and is a 376 * directory. 377 * 378 * If @a fCaseInsensitive is set, we will do a case insensitive search for a 379 * matching filename. 380 * 381 * @returns true / false 382 * @param pszPath The path buffer containing an existing 383 * directory. RTPATH_MAX in size. 384 * @param pszFilename The file name to append. 385 * @param fCaseInsensitive Whether case insensitive searching is required. 386 */ 387 static bool rtDbgCfgIsFileAndFixCase(char *pszPath, const char *pszFilename, bool fCaseInsensitive) 388 { 389 /* Save the length of the input path so we can restore it in the case 390 insensitive branch further down. */ 391 size_t cchPath = strlen(pszPath); 392 393 /* 394 * Append the filename and check if we got a hit. 395 */ 396 int rc = RTPathAppend(pszPath, RTPATH_MAX, pszFilename); 397 if (RT_FAILURE(rc)) 398 return false; 399 400 if (RTFileExists(pszPath)) 401 return true; 402 403 /* 404 * Do case insensitive lookup if requested. 405 */ 406 if (fCaseInsensitive) 407 return rtDbgCfgIsXxxxAndFixCaseWorker(pszPath, cchPath, pszFilename, RTDIRENTRYTYPE_FILE); 408 return false; 409 } 410 411 412 static int rtDbgCfgTryOpenDir(PRTDBGCFGINT pThis, char *pszPath, PRTPATHSPLIT pSplitFn, uint32_t fFlags, 413 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 414 { 415 int rcRet = VWRN_NOT_FOUND; 416 int rc2; 417 418 /* If the directory doesn't exist, just quit immediately. 419 Note! Our case insensitivity doesn't extend to the search dirs themselfs, 420 only to the bits under neath them. */ 421 if (!RTDirExists(pszPath)) 422 { 423 rtDbgCfgLog2(pThis, "Dir does not exist: '%s'\n", pszPath); 424 return rcRet; 425 } 426 427 /* Figure out whether we have to do a case sensitive search or not. 428 Note! As a simplification, we don't ask for case settings in each 429 directory under the user specified path, we assume the file 430 systems that mounted there have compatible settings. Faster 431 that way. */ 432 bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE) 433 && rtDbgCfgIsFsCaseInsensitive(pszPath); 434 435 size_t const cchPath = strlen(pszPath); 436 437 /* 438 * Look for the file with less and less of the original path given. 439 */ 440 for (unsigned i = RTPATH_PROP_HAS_ROOT_SPEC(pSplitFn->fProps); i < pSplitFn->cComps; i++) 441 { 442 pszPath[cchPath] = '\0'; 443 444 rc2 = VINF_SUCCESS; 445 for (unsigned j = i; j < pSplitFn->cComps - 1U && RT_SUCCESS(rc2); j++) 446 if (!rtDbgCfgIsDirAndFixCase(pszPath, pSplitFn->apszComps[i], fCaseInsensitive)) 447 rc2 = VERR_FILE_NOT_FOUND; 448 449 if (RT_SUCCESS(rc2)) 450 { 451 if (rtDbgCfgIsFileAndFixCase(pszPath, pSplitFn->apszComps[pSplitFn->cComps - 1], fCaseInsensitive)) 452 { 453 rtDbgCfgLog1(pThis, "Trying '%s'...\n", pszPath); 454 rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2); 455 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 456 { 457 if (rc2 == VINF_CALLBACK_RETURN) 458 rtDbgCfgLog1(pThis, "Found '%s'.", pszPath); 459 else 460 rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath); 461 return rc2; 462 } 463 rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath); 464 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 465 rcRet = rc2; 466 } 467 } 468 } 469 470 /* 471 * Do a recursive search if requested. 472 */ 473 if ( (fFlags & RTDBGCFG_O_RECURSIVE) 474 && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH) ) 475 { 476 /** @todo Recursive searching will be done later. */ 477 } 478 479 return rcRet; 480 } 481 482 483 static int rtDbgCfgTryDownloadAndOpen(PRTDBGCFGINT pThis, const char *pszServer, 484 char *pszPath, const char *pszCacheSubDir, PRTPATHSPLIT pSplitFn, 485 uint32_t fFlags, PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 486 { 487 if (pThis->fFlags & RTDBGCFG_FLAGS_NO_SYM_SRV) 488 return VWRN_NOT_FOUND; 489 490 491 return VERR_NOT_IMPLEMENTED; 492 } 493 494 495 static int rtDbgCfgCopyFileToCache(PRTDBGCFGINT pThis, char const *pszSrc, const char *pchCache, size_t cchCache, 496 const char *pszCacheSubDir, PRTPATHSPLIT pSplitFn) 497 { 498 /** @todo copy to cache */ 499 return VINF_SUCCESS; 500 } 501 502 503 static int rtDbgCfgTryOpenCache(PRTDBGCFGINT pThis, char *pszPath, const char *pszCacheSubDir, PRTPATHSPLIT pSplitFn, 504 uint32_t fFlags, PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 505 { 506 /* 507 * If the cache doesn't exist, fail right away. 508 */ 509 if (!pszCacheSubDir || !*pszCacheSubDir) 510 return VWRN_NOT_FOUND; 511 if (!RTDirExists(pszPath)) 512 { 513 rtDbgCfgLog2(pThis, "Cache does not exist: '%s'\n", pszPath); 514 return VWRN_NOT_FOUND; 515 } 516 517 size_t cchPath = strlen(pszPath); 518 519 /* 520 * Carefully construct the cache path with case insensitivity in mind. 521 */ 522 bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE) 523 && rtDbgCfgIsFsCaseInsensitive(pszPath); 524 525 if (!rtDbgCfgIsDirAndFixCase(pszPath, pSplitFn->apszComps[pSplitFn->cComps - 1], fCaseInsensitive)) 526 return VWRN_NOT_FOUND; 527 528 if (!rtDbgCfgIsDirAndFixCase(pszPath, pszCacheSubDir, fCaseInsensitive)) 529 return VWRN_NOT_FOUND; 530 531 if (!rtDbgCfgIsFileAndFixCase(pszPath, pSplitFn->apszComps[pSplitFn->cComps - 1], fCaseInsensitive)) 532 return VWRN_NOT_FOUND; 533 534 rtDbgCfgLog1(pThis, "Trying '%s'...\n", pszPath); 535 int rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2); 536 if (rc2 == VINF_CALLBACK_RETURN) 537 rtDbgCfgLog1(pThis, "Found '%s'.", pszPath); 538 else if (rc2 == VERR_CALLBACK_RETURN) 539 rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath); 540 else 541 rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath); 542 return rc2; 543 } 544 545 546 static int rtDbgCfgTryOpenList(PRTDBGCFGINT pThis, PRTLISTANCHOR pList, PRTPATHSPLIT pSplitFn, const char *pszCacheSubDir, 547 uint32_t fFlags, char *pszPath, PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 548 { 549 int rcRet = VWRN_NOT_FOUND; 550 int rc2; 551 552 const char *pchCache = NULL; 553 size_t cchCache = 0; 554 555 PRTDBGCFGSTR pCur; 556 RTListForEach(pList, pCur, RTDBGCFGSTR, ListEntry) 557 { 558 size_t cchDir = pCur->cch; 559 const char *pszDir = pCur->sz; 560 rtDbgCfgLog2(pThis, "Path list entry: '%s'\n", pszDir); 561 562 /* This is very simplistic, but we have a unreasonably large path 563 buffer, so it'll work just fine and simplify things greatly below. */ 564 if (cchDir >= RTPATH_MAX - 8U) 565 { 566 if (RT_SUCCESS_NP(rcRet)) 567 rcRet = VERR_FILENAME_TOO_LONG; 568 continue; 569 } 570 571 /* 572 * Process the path according to it's type. 573 */ 574 if (!strncmp(pszDir, RT_STR_TUPLE("srv*"))) 575 { 576 /* 577 * Symbol server. 578 */ 579 pszDir += sizeof("srv*") - 1; 580 cchDir -= sizeof("srv*") - 1; 581 bool fSearchCache = false; 582 const char *pszServer = (const char *)memchr(pszDir, '*', cchDir); 583 if (!pszServer) 584 pszServer = pszDir; 585 else if (pszServer == pszDir) 586 continue; 587 { 588 fSearchCache = true; 589 pchCache = pszDir; 590 cchCache = pszServer - pszDir; 591 pszServer++; 592 } 593 594 /* We don't have any default cache directory, so skip if the cache is missing. */ 595 if (cchCache == 0) 596 continue; 597 598 /* Search the cache first (if we haven't already done so). */ 599 if (fSearchCache) 600 { 601 memcpy(pszPath, pchCache, cchCache); 602 pszPath[cchCache] = '\0'; 603 rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags, 604 pfnCallback, pvUser1, pvUser2); 605 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 606 return rc2; 607 } 608 609 /* Try downloading the file. */ 610 memcpy(pszPath, pchCache, cchCache); 611 pszPath[cchCache] = '\0'; 612 rc2 = rtDbgCfgTryDownloadAndOpen(pThis, pszServer, pszPath, pszCacheSubDir, pSplitFn, fFlags, 613 pfnCallback, pvUser1, pvUser2); 614 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 615 return rc2; 616 } 617 else if (!strncmp(pszDir, RT_STR_TUPLE("cache*"))) 618 { 619 /* 620 * Cache directory. 621 */ 622 pszDir += sizeof("cache*") - 1; 623 cchDir -= sizeof("cache*") - 1; 624 if (!cchDir) 625 continue; 626 pchCache = pszDir; 627 cchCache = cchDir; 628 629 memcpy(pszPath, pchCache, cchCache); 630 pszPath[cchCache] = '\0'; 631 rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags, 632 pfnCallback, pvUser1, pvUser2); 633 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 634 return rc2; 635 } 636 else 637 { 638 /* 639 * Normal directory. Check for our own 'rec*' and 'norec*' prefix 640 * flags governing recursive searching. 641 */ 642 uint32_t fFlagsDir = fFlags; 643 if (!strncmp(pszDir, RT_STR_TUPLE("rec*"))) 644 { 645 pszDir += sizeof("rec*") - 1; 646 cchDir -= sizeof("rec*") - 1; 647 fFlagsDir |= RTDBGCFG_O_RECURSIVE; 648 } 649 else if (!strncmp(pszDir, RT_STR_TUPLE("norec*"))) 650 { 651 pszDir += sizeof("norec*") - 1; 652 cchDir -= sizeof("norec*") - 1; 653 fFlagsDir &= ~RTDBGCFG_O_RECURSIVE; 654 } 655 656 /* Copy the path into the buffer and do the searching. */ 657 memcpy(pszPath, pszDir, cchDir); 658 pszPath[cchDir] = '\0'; 659 660 rc2 = rtDbgCfgTryOpenDir(pThis, pszPath, pSplitFn, fFlagsDir, pfnCallback, pvUser1, pvUser2); 661 if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN) 662 { 663 if ( rc2 == VINF_CALLBACK_RETURN 664 && cchCache > 0) 665 rtDbgCfgCopyFileToCache(pThis, pszPath, pchCache, cchCache, pszCacheSubDir, pSplitFn); 666 return rc2; 667 } 668 } 669 } 670 671 return rcRet; 672 } 673 674 675 /** 676 * Common worker routine for Image and debug info opening. 677 * 678 * This will not search using for suffixes. 679 * 680 * @returns IPRT status code. 681 * @param hDbgCfg The debugging configuration handle. NIL_RTDBGCFG is 682 * accepted, but the result is that no paths will be 683 * searched beyond the given and the current directory. 684 * @param pszFilename The filename to search for. This may or may not 685 * include a full or partial path. 686 * @param pszCacheSubDir The cache subdirectory to look in. 687 * @param fFlags Flags and hints. 688 * @param pfnCallback The open callback routine. 689 * @param pvUser1 User parameter 1. 690 * @param pvUser2 User parameter 2. 691 */ 692 static int rtDbgCfgOpenWithSubDir(RTDBGCFG hDbgCfg, const char *pszFilename, const char *pszCacheSubDir, 693 uint32_t fFlags, PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 694 { 695 int rcRet = VINF_SUCCESS; 696 int rc2; 697 698 /* 699 * Do a little validating first. 700 */ 701 PRTDBGCFGINT pThis = hDbgCfg; 702 if (pThis != NIL_RTDBGCFG) 703 RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE); 704 else 705 pThis = NULL; 706 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 707 AssertPtrReturn(pszCacheSubDir, VERR_INVALID_POINTER); 708 AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER); 709 710 /* 711 * Do some guessing as to the way we should parse the filename and whether 712 * it's case exact or not. 713 */ 714 bool fDosPath = strchr(pszFilename, ':') != NULL 715 || strchr(pszFilename, '\\') != NULL 716 || RT_OPSYS_USES_DOS_PATHS(fFlags & RTDBGCFG_O_OPSYS_MASK) 717 || (fFlags & RTDBGCFG_O_CASE_INSENSITIVE); 718 if (fDosPath) 719 fFlags |= RTDBGCFG_O_CASE_INSENSITIVE; 720 721 rtDbgCfgLog2(pThis, "Looking for '%s' w/ cache subdir '%s' and %#x flags\n", pszFilename, pszCacheSubDir, fFlags); 722 723 PRTPATHSPLIT pSplitFn; 724 rc2 = RTPathSplitA(pszFilename, &pSplitFn, fDosPath ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX); 725 if (RT_FAILURE(rc2)) 726 return rc2; 727 728 /* 729 * Try the stored file name first if it has a kind of absolute path. 730 */ 731 char szPath[RTPATH_MAX]; 732 if (RTPATH_PROP_HAS_ROOT_SPEC(pSplitFn->fProps)) 733 { 734 rc2 = RTPathSplitReassemble(pSplitFn, RTPATH_STR_F_STYLE_HOST, szPath, sizeof(szPath)); 735 if (RT_SUCCESS(rc2) && RTFileExists(szPath)) 736 rc2 = pfnCallback(pThis, pszFilename, pvUser1, pvUser2); 737 } 738 if ( rc2 != VINF_CALLBACK_RETURN 739 && rc2 != VERR_CALLBACK_RETURN) 740 { 741 /* 742 * Try the current directory (will take cover relative paths 743 * skipped above). 744 */ 745 rc2 = RTPathGetCurrent(szPath, sizeof(szPath)); 746 if (RT_FAILURE(rc2)) 747 strcpy(szPath, "."); 748 rc2 = rtDbgCfgTryOpenDir(pThis, szPath, pSplitFn, fFlags, pfnCallback, pvUser1, pvUser2); 749 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 750 rcRet = rc2; 751 752 if ( rc2 != VINF_CALLBACK_RETURN 753 && rc2 != VERR_CALLBACK_RETURN 754 && pThis) 755 { 756 rc2 = RTCritSectRwEnterShared(&pThis->CritSect); 757 if (RT_SUCCESS(rc2)) 758 { 759 /* 760 * Run the applicable lists. 761 */ 762 rc2 = rtDbgCfgTryOpenList(pThis, &pThis->PathList, pSplitFn, pszCacheSubDir, fFlags, szPath, 763 pfnCallback, pvUser1, pvUser2); 764 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 765 rcRet = rc2; 766 767 #ifdef RT_OS_WINDOWS 768 if ( rc2 != VINF_CALLBACK_RETURN 769 && rc2 != VERR_CALLBACK_RETURN 770 && (fFlags & RTDBGCFG_O_EXECUTABLE_IMAGE) 771 && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_SYSTEM_PATHS) ) 772 { 773 rc2 = rtDbgCfgTryOpenList(pThis, &pThis->NtExecutablePathList, pSplitFn, pszCacheSubDir, fFlags, szPath, 774 pfnCallback, pvUser1, pvUser2); 775 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 776 rcRet = rc2; 777 } 778 779 if ( rc2 != VINF_CALLBACK_RETURN 780 && rc2 != VERR_CALLBACK_RETURN 781 && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_SYSTEM_PATHS) ) 782 { 783 rc2 = rtDbgCfgTryOpenList(pThis, &pThis->NtSymbolPathList, pSplitFn, pszCacheSubDir, fFlags, szPath, 784 pfnCallback, pvUser1, pvUser2); 785 if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet)) 786 rcRet = rc2; 787 } 788 #endif 789 RTCritSectRwLeaveShared(&pThis->CritSect); 790 } 791 else if (RT_SUCCESS(rcRet)) 792 rcRet = rc2; 793 } 794 } 795 796 RTPathSplitFree(pSplitFn); 797 if ( rc2 == VINF_CALLBACK_RETURN 798 || rc2 == VERR_CALLBACK_RETURN) 799 rcRet = rc2; 800 else if (RT_SUCCESS(rcRet)) 801 rcRet = VERR_NOT_FOUND; 802 return rcRet; 803 } 804 160 805 161 806 RTDECL(int) RTDbgCfgOpenPeImage(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, 162 807 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 163 808 { 164 int rc = pfnCallback(hDbgCfg, pszFilename, pvUser1, pvUser2); 165 if (rc == VINF_CALLBACK_RETURN || rc == VERR_CALLBACK_RETURN) 166 return rc; 167 168 return rc; 169 } 809 char szSubDir[32]; 810 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%X", uTimestamp, cbImage); 811 return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, 812 RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE 813 | RTDBGCFG_O_EXECUTABLE_IMAGE, 814 pfnCallback, pvUser1, pvUser2); 815 } 816 170 817 171 818 RTDECL(int) RTDbgCfgOpenPdb70(RTDBGCFG hDbgCfg, const char *pszFilename, PCRTUUID pUuid, uint32_t uAge, 172 819 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 173 820 { 174 int rc = pfnCallback(hDbgCfg, pszFilename, pvUser1, pvUser2); 175 if (rc == VINF_CALLBACK_RETURN || rc == VERR_CALLBACK_RETURN) 176 return rc; 177 178 return rc; 179 } 821 char szSubDir[64]; 822 if (!pUuid) 823 szSubDir[0] = '\0'; 824 else 825 { 826 /* Stringify the UUID and remove the dashes. */ 827 int rc2 = RTUuidToStr(pUuid, szSubDir, sizeof(szSubDir)); 828 AssertRCReturn(rc2, rc2); 829 830 char *pszSrc = szSubDir; 831 char *pszDst = szSubDir; 832 char ch; 833 while ((ch = *pszSrc++)) 834 if (ch != '-') 835 *pszDst++ = ch; 836 else if (RT_C_IS_LOWER(ch)) 837 *pszDst++ = RT_C_TO_UPPER(ch); 838 839 RTStrPrintf(pszDst, &szSubDir[sizeof(szSubDir)] - pszDst, "%X", uAge); 840 } 841 842 return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, 843 RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE 844 | RTDBGCFG_O_EXT_DEBUG_FILE, 845 pfnCallback, pvUser1, pvUser2); 846 } 847 180 848 181 849 RTDECL(int) RTDbgCfgOpenPdb20(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, uint32_t uAge, 182 850 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 183 851 { 184 return VERR_NOT_IMPLEMENTED; 852 /** @todo test this! */ 853 char szSubDir[32]; 854 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%X", uTimestamp, uAge); 855 return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, 856 RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE 857 | RTDBGCFG_O_EXT_DEBUG_FILE, 858 pfnCallback, pvUser1, pvUser2); 185 859 } 186 860 … … 189 863 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 190 864 { 191 return VERR_NOT_IMPLEMENTED; 865 char szSubDir[32]; 866 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%X", uTimestamp, cbImage); 867 return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, 868 RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE 869 | RTDBGCFG_O_EXT_DEBUG_FILE, 870 pfnCallback, pvUser1, pvUser2); 192 871 } 193 872 … … 196 875 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 197 876 { 198 return VERR_NOT_IMPLEMENTED; 877 char szSubDir[32]; 878 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08x", uCrc32); 879 return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, 880 RT_OPSYS_UNKNOWN | RTDBGCFG_O_EXT_DEBUG_FILE, 881 pfnCallback, pvUser1, pvUser2); 199 882 } 200 883 … … 253 936 return VERR_FILENAME_TOO_LONG; 254 937 255 if (enmOp != RTDBGCFGOP_REMOVE)938 if (enmOp == RTDBGCFGOP_REMOVE) 256 939 { 257 940 /* … … 280 963 pNew->cch = (uint16_t)cchPath; 281 964 pNew->fFlags = 0; 282 if (fPaths)283 {284 if (!strncmp(pchPath, RT_STR_TUPLE("srv*")))285 pNew->fFlags |= RTDBGCCFG_PATH_SRV;286 else if (!strncmp(pchPath, RT_STR_TUPLE("cache*")))287 pNew->fFlags |= RTDBGCCFG_PATH_CACHE;288 }289 965 memcpy(pNew->sz, pchPath, cchPath); 290 966 pNew->sz[cchPath] = '\0'; … … 738 1414 rc = VINF_SUCCESS; 739 1415 } 1416 1417 /* 1418 * Pick up system specific search paths. 1419 */ 1420 if (RT_SUCCESS(rc)) 1421 { 1422 struct 1423 { 1424 PRTLISTANCHOR pList; 1425 const char *pszVar; 1426 char chSep; 1427 } aNativePaths[] = 1428 { 1429 #ifdef RT_OS_WINDOWS 1430 { &pThis->NtExecutablePathList, "_NT_EXECUTABLE_PATH", ';' }, 1431 { &pThis->NtSymbolPathList, "_NT_ALT_SYMBOL_PATH", ';' }, 1432 { &pThis->NtSymbolPathList, "_NT_SYMBOL_PATH", ';' }, 1433 { &pThis->NtSourcePath, "_NT_SOURCE_PATH", ';' }, 1434 #endif 1435 { NULL, NULL, 0 } 1436 }; 1437 for (unsigned i = 0; i < RT_ELEMENTS(aNativePaths) - 1U; i++) 1438 { 1439 Assert(aNativePaths[i].chSep == ';'); /* fix when needed */ 1440 rc = RTEnvGetEx(RTENV_DEFAULT, aNativePaths[i].pszVar, pszEnvVal, cbEnvVal, NULL); 1441 if (RT_SUCCESS(rc)) 1442 { 1443 rc = rtDbgCfgChangeStringList(pThis, RTDBGCFGOP_APPEND, pszEnvVal, true, aNativePaths[i].pList); 1444 if (RT_FAILURE(rc)) 1445 break; 1446 } 1447 else if (rc != VERR_ENV_VAR_NOT_FOUND) 1448 break; 1449 else 1450 rc = VINF_SUCCESS; 1451 } 1452 } 740 1453 RTMemTmpFree(pszEnvVar); 741 1454 } -
trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp
r39327 r46025 151 151 { 152 152 RTLDRMOD hLdrMod; 153 rc = RTLdrOpen(pMod->pszImgFile, 0 /*fFlags*/, RTLDRARCH_WHATEVER, &hLdrMod);153 rc = RTLdrOpen(pMod->pszImgFile, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, &hLdrMod); 154 154 if (RT_SUCCESS(rc)) 155 155 {
Note:
See TracChangeset
for help on using the changeset viewer.