| 4963 | } |
| 4964 | |
| 4965 | void WinDebugger::CheckNonDebuggerBreak() |
| 4966 | { |
| 4967 | enum MessageType |
| 4968 | { |
| 4969 | MessageType_None = 0, |
| 4970 | MessageType_Error = 1, |
| 4971 | MessageType_ProfilerCmd = 2 |
| 4972 | }; |
| 4973 | |
| 4974 | CPURegisters registers; |
| 4975 | PopulateRegisters(®isters); |
| 4976 | addr_target pcAddress = registers.GetPC(); |
| 4977 | |
| 4978 | addr_target debugMessageDataAddr = (addr_target)-1; |
| 4979 | if (mDebugTarget->mTargetBinary != NULL) |
| 4980 | { |
| 4981 | mDebugTarget->mTargetBinary->ParseSymbolData(); |
| 4982 | debugMessageDataAddr = mDebugTarget->FindSymbolAddr("gBfDebugMessageData"); |
| 4983 | } |
| 4984 | if (debugMessageDataAddr != (addr_target)-1) |
| 4985 | { |
| 4986 | struct BfDebugMessageData |
| 4987 | { |
| 4988 | int mMessageType; // 0 = none, 1 = error |
| 4989 | int mStackWindbackCount; |
| 4990 | int mBufParamLen; |
| 4991 | addr_target mBufParam; |
| 4992 | addr_target mPCOverride; |
| 4993 | }; |
| 4994 | BfDebugMessageData messageData = ReadMemory<BfDebugMessageData>(debugMessageDataAddr); |
| 4995 | WriteMemory<int>(debugMessageDataAddr, 0); // Zero out type so we won't trigger again |
| 4996 | if (messageData.mMessageType != 0) |
| 4997 | { |
| 4998 | llvm::SmallVector<char, 4096> strBuf; |
| 4999 | int strLen = messageData.mBufParamLen; |
| 5000 | strBuf.resize(strLen + 1); |
| 5001 | |
| 5002 | char* str = &strBuf[0]; |
| 5003 | str[strLen] = 0; |
| 5004 | if (ReadMemory(messageData.mBufParam, strLen, str)) |
| 5005 | { |
| 5006 | if (messageData.mMessageType == MessageType_Error) |
| 5007 | { |
| 5008 | mRequestedStackFrameIdx = messageData.mStackWindbackCount; |
| 5009 | if (messageData.mPCOverride != 0) |
| 5010 | { |
| 5011 | mShowPCOverride = messageData.mPCOverride; |
| 5012 | mRequestedStackFrameIdx = -2; |
| 5013 | } |
| 5014 | mDebugManager->mOutMessages.push_back(StrFormat("error %s", str)); |
| 5015 | } |
| 5016 | else if (messageData.mMessageType == MessageType_ProfilerCmd) |
| 5017 | { |
| 5018 | // It's important to set this here, because we unlock the critSect during StopSampling and we can't have the |
| 5019 | // IDE thinking that we're actually paused when it checks the mRunState |
| 5020 | mRunState = RunState_Running; |
| 5021 | |
| 5022 | char* cmd = strtok(str, "\t"); |
nothing calls this directly
no test coverage detected