/** * Ends a stack walk process. * * This *must* be called after a successful first call to any of the stack * walker functions. If not called we will leak memory or other resources. * * @param pFirstFrame The frame returned by one of the begin functions. */ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame) { if ( !pFirstFrame || !pFirstFrame->pFirstInternal) return; PDBGFSTACKFRAME pFrame = (PDBGFSTACKFRAME)pFirstFrame->pFirstInternal; while (pFrame) { PDBGFSTACKFRAME pCur = pFrame; pFrame = (PDBGFSTACKFRAME)pCur->pNextInternal; if (pFrame) { if (pCur->pSymReturnPC == pFrame->pSymPC) pFrame->pSymPC = NULL; if (pCur->pSymReturnPC == pFrame->pSymReturnPC) pFrame->pSymReturnPC = NULL; if (pCur->pSymPC == pFrame->pSymPC) pFrame->pSymPC = NULL; if (pCur->pSymPC == pFrame->pSymReturnPC) pFrame->pSymReturnPC = NULL; if (pCur->pLineReturnPC == pFrame->pLinePC) pFrame->pLinePC = NULL; if (pCur->pLineReturnPC == pFrame->pLineReturnPC) pFrame->pLineReturnPC = NULL; if (pCur->pLinePC == pFrame->pLinePC) pFrame->pLinePC = NULL; if (pCur->pLinePC == pFrame->pLineReturnPC) pFrame->pLineReturnPC = NULL; } RTDbgSymbolFree(pCur->pSymPC); RTDbgSymbolFree(pCur->pSymReturnPC); RTDbgLineFree(pCur->pLinePC); RTDbgLineFree(pCur->pLineReturnPC); pCur->pNextInternal = NULL; pCur->pFirstInternal = NULL; pCur->fFlags = 0; MMR3HeapFree(pCur); } }
/** * Queries line number information by address. * * The returned line number is what the debug info interpreter considers the * one most applicable to the specified address. This usually means a line * number with an address equal or lower than the requested. * * @returns IPRT status code. * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers. * @retval VERR_DBG_LINE_NOT_FOUND if no suitable line number was found. * @retval VERR_INVALID_HANDLE if hDbgMod is invalid. * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and * it's not inside any of the segments defined by the module. * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid. * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the * end of the segment. * @retval VERR_NO_MEMORY if RTDbgLineAlloc fails. * * @param hDbgMod The module handle. * @param iSeg The segment number. * @param off The offset into the segment. * @param poffDisp Where to store the distance between the * specified address and the returned symbol. * Optional. * @param ppLineInfo Where to store the pointer to the returned line * number information. Always set. Free with * RTDbgLineFree. */ RTDECL(int) RTDbgModLineByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE *ppLineInfo) { AssertPtr(ppLineInfo); *ppLineInfo = NULL; PRTDBGLINE pLineInfo = RTDbgLineAlloc(); if (!pLineInfo) return VERR_NO_MEMORY; int rc = RTDbgModLineByAddr(hDbgMod, iSeg, off, poffDisp, pLineInfo); if (RT_SUCCESS(rc)) *ppLineInfo = pLineInfo; else RTDbgLineFree(pLineInfo); return rc; }
/** * Queries line number information by ordinal number. * * This can be used to enumerate the line numbers for the module. Use * RTDbgModLineCount() to figure the end of the ordinals. * * @returns IPRT status code. * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers. * @retval VERR_DBG_LINE_NOT_FOUND if there is no line number with that * ordinal. * @retval VERR_INVALID_HANDLE if hDbgMod is invalid. * @retval VERR_NO_MEMORY if RTDbgLineAlloc fails. * * @param hDbgMod The module handle. * @param iOrdinal The line number ordinal number. * @param ppLineInfo Where to store the pointer to the returned line * number information. Always set. Free with * RTDbgLineFree. */ RTDECL(int) RTDbgModLineByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE *ppLineInfo) { AssertPtr(ppLineInfo); *ppLineInfo = NULL; PRTDBGLINE pLineInfo = RTDbgLineAlloc(); if (!pLineInfo) return VERR_NO_MEMORY; int rc = RTDbgModLineByOrdinal(hDbgMod, iOrdinal, pLineInfo); if (RT_SUCCESS(rc)) *ppLineInfo = pLineInfo; else RTDbgLineFree(pLineInfo); return rc; }