Changeset 31914 in vbox for trunk/src/VBox/Runtime/r3/solaris
- Timestamp:
- Aug 24, 2010 12:18:38 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 65124
- Location:
- trunk/src/VBox/Runtime/r3/solaris
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp
r31869 r31914 116 116 * @param cbToRead Size of data to read. 117 117 * 118 * @return VBoxstatus code.118 * @return IPRT status code. 119 119 */ 120 120 static int ReadFileNoIntr(RTFILE hFile, void *pv, size_t cbToRead) … … 139 139 * @param cbToRead Size of data to write. 140 140 * 141 * @return VBoxstatus code.141 * @return IPRT status code. 142 142 */ 143 143 static int WriteFileNoIntr(RTFILE hFile, const void *pcv, size_t cbToRead) … … 220 220 * @param pVBoxCore Pointer to the core object. 221 221 * 222 * @return VBoxstatus code.222 * @return IPRT status code. 223 223 */ 224 224 static int AllocMemoryArea(PVBOXCORE pVBoxCore) … … 339 339 * @param pcb Where to store size of the buffer. 340 340 * 341 * @return VBoxstatus code.341 * @return IPRT status code. 342 342 */ 343 343 static int ProcReadFileInto(PVBOXCORE pVBoxCore, const char *pszProcFileName, void **ppv, size_t *pcb) … … 351 351 if (RT_SUCCESS(rc)) 352 352 { 353 RTFileGetSize(hFile, (uint64_t *)pcb); /** @todo size_t != uint64_t! */ 353 uint64_t u64Size; 354 RTFileGetSize(hFile, &u64Size); 355 *pcb = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0; 354 356 if (*pcb > 0) 355 357 { … … 378 380 * @param pVBoxCore Pointer to the core object. 379 381 * 380 * @return VBoxstatus code.382 * @return IPRT status code. 381 383 */ 382 384 static int ProcReadInfo(PVBOXCORE pVBoxCore) … … 406 408 * @param pVBoxCore Pointer to the core object. 407 409 * 408 * @return VBoxstatus code.410 * @return IPRT status code. 409 411 */ 410 412 static int ProcReadStatus(PVBOXCORE pVBoxCore) … … 437 439 * 438 440 * @remarks Should not be called before successful call to @see AllocMemoryArea() 439 * @return VBoxstatus code.441 * @return IPRT status code. 440 442 */ 441 443 static int ProcReadCred(PVBOXCORE pVBoxCore) … … 454 456 * 455 457 * @remarks Should not be called before successful call to @see AllocMemoryArea() 456 * @return VBoxstatus code.458 * @return IPRT status code. 457 459 */ 458 460 static int ProcReadPriv(PVBOXCORE pVBoxCore) … … 480 482 * 481 483 * @remarks Should not be called before successful call to @see AllocMemoryArea() 482 * @return VBoxstatus code.484 * @return IPRT status code. 483 485 */ 484 486 static int ProcReadLdt(PVBOXCORE pVBoxCore) … … 497 499 * 498 500 * @remarks Should not be called before successful call to @see AllocMemoryArea() 499 * @return VBoxstatus code.501 * @return IPRT status code. 500 502 */ 501 503 static int ProcReadAuxVecs(PVBOXCORE pVBoxCore) … … 514 516 } 515 517 516 size_t cbAuxFile = 0; 517 RTFileGetSize(hFile, (uint64_t *)&cbAuxFile); /** @todo size_t != uint64_t! */ 518 uint64_t u64Size; 519 RTFileGetSize(hFile, &u64Size); 520 size_t cbAuxFile = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0; 518 521 if (cbAuxFile >= sizeof(auxv_t)) 519 522 { … … 585 588 * 586 589 * @remarks Should not be called before successful call to @see AllocMemoryArea() 587 * @return VBoxstatus code.590 * @return IPRT status code. 588 591 */ 589 592 static int ProcReadMappings(PVBOXCORE pVBoxCore) … … 606 609 * Allocate and read all the prmap_t objects from proc. 607 610 */ 608 size_t cbMapFile = 0; 609 RTFileGetSize(hFile, (uint64_t *)&cbMapFile); /** @todo size_t != uint64_t! */ 611 uint64_t u64Size; 612 RTFileGetSize(hFile, &u64Size); 613 size_t cbMapFile = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0; 610 614 if (cbMapFile >= sizeof(prmap_t)) 611 615 { … … 716 720 * 717 721 * @remarks Should not be called before successful call to @see AllocMemoryArea() 718 * @return VBoxstatus code.722 * @return IPRT status code. 719 723 */ 720 724 static int ProcReadThreads(PVBOXCORE pVBoxCore) … … 876 880 * @param pVBoxCore Pointer to the core object. 877 881 * 878 * @return VBoxstatus code.882 * @return IPRT status code. 879 883 */ 880 884 static int ProcReadMiscInfo(PVBOXCORE pVBoxCore) … … 1063 1067 1064 1068 1069 /** 1070 * Callback for rtCoreDumperForEachThread to suspend a thread. 1071 * 1072 * @param pVBoxCore Pointer to the core object. 1073 * @param pvThreadInfo Opaque pointer to thread information. 1074 * 1075 * @return IPRT status code. 1076 */ 1077 static int suspendThread(PVBOXCORE pVBoxCore, void *pvThreadInfo) 1078 { 1079 AssertPtrReturn(pvThreadInfo, VERR_INVALID_POINTER); 1080 NOREF(pVBoxCore); 1081 1082 lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)pvThreadInfo; 1083 CORELOGRELSYS((CORELOG_NAME ":suspendThread %d\n", (lwpid_t)pThreadInfo->pr_lwpid)); 1084 if ((lwpid_t)pThreadInfo->pr_lwpid != pVBoxCore->VBoxProc.hCurThread) 1085 _lwp_suspend(pThreadInfo->pr_lwpid); 1086 return VINF_SUCCESS; 1087 } 1088 1089 1090 /** 1091 * Callback for rtCoreDumperForEachThread to resume a thread. 1092 * 1093 * @param pVBoxCore Pointer to the core object. 1094 * @param pvThreadInfo Opaque pointer to thread information. 1095 * 1096 * @return IPRT status code. 1097 */ 1098 static int resumeThread(PVBOXCORE pVBoxCore, void *pvThreadInfo) 1099 { 1100 AssertPtrReturn(pvThreadInfo, VERR_INVALID_POINTER); 1101 NOREF(pVBoxCore); 1102 1103 lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)pvThreadInfo; 1104 if ((lwpid_t)pThreadInfo->pr_lwpid != (lwpid_t)pVBoxCore->VBoxProc.hCurThread) 1105 _lwp_continue(pThreadInfo->pr_lwpid); 1106 return VINF_SUCCESS; 1107 } 1108 1109 1110 /** 1111 * Calls a thread worker function for all threads in the process as described by /proc 1112 * 1113 * @param pVBoxCore Pointer to the core object. 1114 * @param pcThreads Number of threads read. 1115 * @param pfnWorker Callback function for each thread. 1116 * 1117 * @return IPRT status code. 1118 */ 1119 static int rtCoreDumperForEachThread(PVBOXCORE pVBoxCore, uint64_t *pcThreads, PFNCORETHREADWORKER pfnWorker) 1120 { 1121 AssertPtrReturn(pVBoxCore, VERR_INVALID_POINTER); 1122 1123 PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc; 1124 1125 /* 1126 * Read the information for threads. 1127 * Format: prheader_t + array of lwpsinfo_t's. 1128 */ 1129 char szLpsInfoPath[PATH_MAX]; 1130 RTStrPrintf(szLpsInfoPath, sizeof(szLpsInfoPath), "/proc/%d/lpsinfo", (int)pVBoxProc->Process); 1131 1132 RTFILE hFile = NIL_RTFILE; 1133 int rc = RTFileOpen(&hFile, szLpsInfoPath, RTFILE_O_READ); 1134 if (RT_SUCCESS(rc)) 1135 { 1136 uint64_t u64Size; 1137 RTFileGetSize(hFile, &u64Size); 1138 size_t cbInfoHdrAndData = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0; 1139 void *pvInfoHdr = mmap(NULL, cbInfoHdrAndData, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1 /* fd */, 0 /* offset */); 1140 if (pvInfoHdr) 1141 { 1142 rc = RTFileRead(hFile, pvInfoHdr, cbInfoHdrAndData, NULL); 1143 if (RT_SUCCESS(rc)) 1144 { 1145 prheader_t *pHeader = (prheader_t *)pvInfoHdr; 1146 lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)((uintptr_t)pvInfoHdr + sizeof(prheader_t)); 1147 for (unsigned i = 0; i < pHeader->pr_nent; i++) 1148 { 1149 pfnWorker(pVBoxCore, pThreadInfo); 1150 pThreadInfo = (lwpsinfo_t *)((uintptr_t)pThreadInfo + pHeader->pr_entsize); 1151 } 1152 if (pcThreads) 1153 *pcThreads = pHeader->pr_nent; 1154 } 1155 1156 munmap(pvInfoHdr, cbInfoHdrAndData); 1157 } 1158 else 1159 rc = VERR_NO_MEMORY; 1160 RTFileClose(hFile); 1161 } 1162 1163 return rc; 1164 } 1165 1166 1065 1167 /** 1066 1168 * Resume all threads of this process. 1067 1169 * 1068 * @param pVBoxProc Pointer to the VBox process. 1069 * 1070 * @return VBox error code. 1071 */ 1072 static int rtCoreDumperResumeThreads(PVBOXPROCESS pVBoxProc) 1073 { 1074 AssertReturn(pVBoxProc, VERR_INVALID_POINTER); 1170 * @param pVBoxCore Pointer to the core object. 1171 * 1172 * @return IPRT status code.. 1173 */ 1174 static int rtCoreDumperResumeThreads(PVBOXCORE pVBoxCore) 1175 { 1176 AssertReturn(pVBoxCore, VERR_INVALID_POINTER); 1177 1178 #if 1 1179 uint64_t cThreads; 1180 return rtCoreDumperForEachThread(pVBoxCore, &cThreads, resumeThread); 1181 #else 1182 PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc; 1075 1183 1076 1184 char szCurThread[128]; … … 1111 1219 rc = VERR_READ_ERROR; 1112 1220 } 1113 1114 1221 return rc; 1115 } 1116 1117 1118 /** 1119 * Stop all running threads of this process. Before dumping any 1120 * core we need to make sure the process is quiesced. 1121 * 1122 * @param pVBoxProc Pointer to the VBox process. 1123 * 1124 * @return VBox error code. 1125 */ 1126 static int rtCoreDumperSuspendThreads(PVBOXPROCESS pVBoxProc) 1127 { 1222 #endif 1223 } 1224 1225 1226 /** 1227 * Stop all running threads of this process except the current one. 1228 * 1229 * @param pVBoxCore Pointer to the core object. 1230 * 1231 * @return IPRT status code. 1232 */ 1233 static int rtCoreDumperSuspendThreads(PVBOXCORE pVBoxCore) 1234 { 1235 AssertPtrReturn(pVBoxCore, VERR_INVALID_POINTER); 1236 1237 /* 1238 * This function tries to ensures while we suspend threads, no newly spawned threads 1239 * or a combination of spawning and terminating threads can cause any threads to be left running. 1240 * The assumption here is that threads can only increase not decrease across iterations. 1241 */ 1242 #if 1 1243 uint16_t cTries = 0; 1244 uint64_t aThreads[4]; 1245 RT_ZERO(aThreads); 1246 int rc = VERR_GENERAL_FAILURE; 1247 void *pv = NULL; 1248 size_t cb = 0; 1249 for (cTries = 0; cTries < RT_ELEMENTS(aThreads); cTries++) 1250 { 1251 rc = rtCoreDumperForEachThread(pVBoxCore, &aThreads[cTries], suspendThread); 1252 if (RT_FAILURE(rc)) 1253 break; 1254 } 1255 if ( RT_SUCCESS(rc) 1256 && aThreads[cTries - 1] != aThreads[cTries - 2]) 1257 { 1258 CORELOGRELSYS((CORELOG_NAME "rtCoreDumperSuspendThreads: possible thread bomb!?\n")); 1259 rc = VERR_GENERAL_FAILURE; /* @todo better error code */ 1260 } 1261 return rc; 1262 #else 1263 PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc; 1264 1128 1265 char szCurThread[128]; 1129 1266 char szPath[PATH_MAX]; … … 1180 1317 1181 1318 return rc; 1319 #endif 1182 1320 } 1183 1321 … … 1204 1342 * @param cb Size of the data. 1205 1343 * 1206 * @return VBoxstatus code.1344 * @return IPRT status code. 1207 1345 */ 1208 1346 static int ElfWriteNoteHeader(PVBOXCORE pVBoxCore, uint_t Type, const void *pcv, size_t cb) … … 1328 1466 * @param enmType Type of core file information required. 1329 1467 * 1330 * @return VBoxstatus code.1468 * @return IPRT status code. 1331 1469 */ 1332 1470 static int ElfWriteNoteSection(PVBOXCORE pVBoxCore, VBOXSOLCORETYPE enmType) … … 1471 1609 * @param pVBoxCore Pointer to the core object. 1472 1610 * 1473 * @return VBoxstatus code.1611 * @return IPRT status code. 1474 1612 */ 1475 1613 static int ElfWriteMappings(PVBOXCORE pVBoxCore) … … 1531 1669 * @param pVBoxCore Pointer to the core object. 1532 1670 * 1533 * @return VBoxstatus code.1671 * @return IPRT status code. 1534 1672 */ 1535 1673 static int ElfWriteMappingHeaders(PVBOXCORE pVBoxCore) … … 1746 1884 } 1747 1885 1748 rtCoreDumperResumeThreads(pVBox Proc);1886 rtCoreDumperResumeThreads(pVBoxCore); 1749 1887 return rc; 1750 1888 } … … 1760 1898 * 1761 1899 * @remarks Halts all threads. 1762 * @return VBoxstatus code.1900 * @return IPRT status code. 1763 1901 */ 1764 1902 static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext) … … 1806 1944 * Quiesce the process. 1807 1945 */ 1808 int rc = rtCoreDumperSuspendThreads(pVBox Proc);1946 int rc = rtCoreDumperSuspendThreads(pVBoxCore); 1809 1947 if (RT_SUCCESS(rc)) 1810 1948 { … … 1877 2015 * Resume threads on failure. 1878 2016 */ 1879 rtCoreDumperResumeThreads(pVBox Proc);2017 rtCoreDumperResumeThreads(pVBoxCore); 1880 2018 } 1881 2019 else … … 1891 2029 * @param pVBoxCore Pointer to the core object. 1892 2030 * 1893 * @return VBoxstatus code.2031 * @return IPRT status code. 1894 2032 */ 1895 2033 static int rtCoreDumperDestroyCore(PVBOXCORE pVBoxCore) … … 1910 2048 * 1911 2049 * @param pContext The context of the caller. 1912 * @returns VBoxstatus code.2050 * @returns IPRT status code. 1913 2051 */ 1914 2052 static int rtCoreDumperTakeDump(ucontext_t *pContext) … … 1932 2070 rc = rtCoreDumperWriteCore(&VBoxCore, &WriteFileNoIntr); 1933 2071 if (RT_SUCCESS(rc)) 1934 CORELOGRELSYS((CORELOG_NAME " Success! Core written to%s\n", VBoxCore.szCorePath));2072 CORELOGRELSYS((CORELOG_NAME "Core dumped in %s\n", VBoxCore.szCorePath)); 1935 2073 else 1936 2074 CORELOGRELSYS((CORELOG_NAME "TakeDump: WriteCore failed. szCorePath=%s rc=%Rrc\n", VBoxCore.szCorePath, rc)); -
trunk/src/VBox/Runtime/r3/solaris/coredumper-solaris.h
r31862 r31914 166 166 167 167 typedef int (*PFNCOREACCUMULATOR)(PVBOXCORE pVBoxCore); 168 typedef int (*PFNCORETHREADWORKER)(PVBOXCORE pVBoxCore, void *pvThreadInfo); 168 169
Note:
See TracChangeset
for help on using the changeset viewer.