| 3954 | } |
| 3955 | |
| 3956 | bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubprogram* dbgSubprogram, addr_target pcAddress) |
| 3957 | { |
| 3958 | // What was this assertion for? |
| 3959 | //BF_ASSERT(mCallStack.size() == 0); |
| 3960 | |
| 3961 | auto headBreakpoint = breakpoint->GetHeadBreakpoint(); |
| 3962 | |
| 3963 | if (headBreakpoint->mThreadId != -1) |
| 3964 | { |
| 3965 | if ((mActiveThread != NULL) && (mActiveThread->mThreadId != headBreakpoint->mThreadId)) |
| 3966 | return false; |
| 3967 | } |
| 3968 | |
| 3969 | auto _SplitExpr = [&](const StringImpl& expr, StringImpl& outExpr, StringImpl& outSubject) |
| 3970 | { |
| 3971 | int crPos = expr.IndexOf('\n'); |
| 3972 | if (crPos != -1) |
| 3973 | { |
| 3974 | outExpr += expr.Substring(0, crPos); |
| 3975 | outSubject += expr.Substring(crPos + 1); |
| 3976 | } |
| 3977 | else |
| 3978 | { |
| 3979 | outExpr += expr; |
| 3980 | } |
| 3981 | }; |
| 3982 | |
| 3983 | if (headBreakpoint->mCondition != NULL) |
| 3984 | { |
| 3985 | ClearCallStack(); |
| 3986 | |
| 3987 | auto conditional = headBreakpoint->mCondition; |
| 3988 | if (conditional->mDbgEvaluationContext == NULL) |
| 3989 | { |
| 3990 | CPURegisters registers; |
| 3991 | PopulateRegisters(®isters); |
| 3992 | auto pcAddress = registers.GetPC(); |
| 3993 | DbgSubprogram* subprogram = mDebugTarget->FindSubProgram(pcAddress); |
| 3994 | if (subprogram == NULL) |
| 3995 | { |
| 3996 | return false; |
| 3997 | } |
| 3998 | |
| 3999 | StringT<256> expr; |
| 4000 | StringT<256> subjectExpr; |
| 4001 | if (breakpoint->mMemoryBreakpointInfo != NULL) |
| 4002 | { |
| 4003 | subjectExpr += "*"; |
| 4004 | } |
| 4005 | |
| 4006 | _SplitExpr(conditional->mExpr, expr, subjectExpr); |
| 4007 | DbgLanguage language = DbgLanguage_Unknown; |
| 4008 | if (expr.StartsWith("@Beef:")) |
| 4009 | { |
| 4010 | expr.Remove(0, 6); |
| 4011 | language = DbgLanguage_Beef; |
| 4012 | } |
| 4013 | else if (expr.StartsWith("@C:")) |
nothing calls this directly
no test coverage detected