| 2072 | } |
| 2073 | |
| 2074 | bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outReturnAddressLoc, bool isStackStart) |
| 2075 | { |
| 2076 | if (outReturnAddressLoc != NULL) |
| 2077 | *outReturnAddressLoc = 0; |
| 2078 | |
| 2079 | CPUInst inst; |
| 2080 | if (DecodeInstruction(registers->GetPC(), &inst)) |
| 2081 | { |
| 2082 | if (inst.IsReturn()) |
| 2083 | { |
| 2084 | // If we are literally just a return then often the frame descriptor is wrong, |
| 2085 | // but we know this is ACTUALLY just a simple rollback |
| 2086 | return RollBackStackFrame_SimpleRet(registers); |
| 2087 | } |
| 2088 | } |
| 2089 | |
| 2090 | #ifdef BF_DBG_32 |
| 2091 | if (RollBackStackFrame_DwFrameDescriptor(registers, outReturnAddressLoc)) |
| 2092 | return true; |
| 2093 | if (RollBackStackFrame_COFFFrameDescriptor(registers, outReturnAddressLoc, isStackStart)) |
| 2094 | return true; |
| 2095 | auto pc = registers->GetPC(); |
| 2096 | DbgSubprogram* dbgSubprogram = FindSubProgram(pc); |
| 2097 | if (dbgSubprogram != NULL) |
| 2098 | { |
| 2099 | if (pc == dbgSubprogram->mBlock.mLowPC) |
| 2100 | return RollBackStackFrame_SimpleRet(registers); |
| 2101 | |
| 2102 | auto dbgModule = dbgSubprogram->mCompileUnit->mDbgModule; |
| 2103 | if ((dbgModule != NULL) && (!dbgModule->mParsedFrameDescriptors)) |
| 2104 | { |
| 2105 | dbgModule->ParseFrameDescriptors(); |
| 2106 | if (RollBackStackFrame_COFFFrameDescriptor(registers, outReturnAddressLoc, isStackStart)) |
| 2107 | return true; |
| 2108 | } |
| 2109 | } |
| 2110 | else |
| 2111 | { |
| 2112 | return RollBackStackFrame_SimpleRet(registers); |
| 2113 | } |
| 2114 | #endif |
| 2115 | |
| 2116 | // Fall through after this, we need to process a 'return' |
| 2117 | bool alreadyRolledBackPC = false; |
| 2118 | bool success = RollBackStackFrame_ExceptionDirectory(registers, outReturnAddressLoc, alreadyRolledBackPC); |
| 2119 | |
| 2120 | ///TODO: Why did we break when there was a minidump? This breaks default-rollback of just a 'ret' |
| 2121 | // if (!success) |
| 2122 | // { |
| 2123 | // if (mDebugger->IsMiniDumpDebugger()) |
| 2124 | // { |
| 2125 | // return false; |
| 2126 | // } |
| 2127 | // } |
| 2128 | if (alreadyRolledBackPC) |
| 2129 | return true; |
| 2130 | |
| 2131 | #ifdef BF_DBG_32 |
nothing calls this directly
no test coverage detected