| 1019 | } |
| 1020 | |
| 1021 | void Debugger::RuleActionPreHook(RuleActionNode * action) |
| 1022 | { |
| 1023 | if (globals_.TypedValueVMT == nullptr |
| 1024 | && action->Arguments != nullptr |
| 1025 | && action->Arguments->Args().Size > 0) { |
| 1026 | globals_.TypedValueVMT = action->Arguments->Args().Head->Next->Item->VMT; |
| 1027 | } |
| 1028 | |
| 1029 | // Avoid action mapping errors during merge |
| 1030 | if (debuggingDisabled_) { |
| 1031 | return; |
| 1032 | } |
| 1033 | |
| 1034 | ServerThreadReentry(); |
| 1035 | auto const * mapping = actionMappings_.FindActionMapping(action); |
| 1036 | if (mapping == nullptr) { |
| 1037 | return; |
| 1038 | } |
| 1039 | |
| 1040 | BreakpointReason reason; |
| 1041 | BreakpointType bpType; |
| 1042 | GlobalBreakpointType globalBpType; |
| 1043 | uint64_t breakpointId; |
| 1044 | if (mapping->rule != nullptr) { |
| 1045 | reason = BreakpointReason::RuleActionCall; |
| 1046 | bpType = BreakpointType::BreakOnRuleAction; |
| 1047 | globalBpType = GlobalBreakpointType::GlobalBreakOnRuleAction; |
| 1048 | breakpointId = BreakpointManager::MakeRuleActionBreakpointId(mapping->rule->Id, mapping->actionIndex); |
| 1049 | #if defined(DUMP_TRACEPOINTS) |
| 1050 | Debug("RuleAction(Rule %d, Action %d)", mapping->rule->Id, mapping->actionIndex); |
| 1051 | #endif |
| 1052 | } else if (mapping->isInit) { |
| 1053 | reason = BreakpointReason::GoalInitCall; |
| 1054 | bpType = BreakpointType::BreakOnInitCall; |
| 1055 | globalBpType = GlobalBreakpointType::GlobalBreakOnInitCall; |
| 1056 | breakpointId = BreakpointManager::MakeGoalInitBreakpointId(mapping->goal->Id, mapping->actionIndex); |
| 1057 | #if defined(DUMP_TRACEPOINTS) |
| 1058 | Debug("GoalInit(Goal %d, Action %d)", mapping->goal->Id, mapping->actionIndex); |
| 1059 | #endif |
| 1060 | } else { |
| 1061 | reason = BreakpointReason::GoalExitCall; |
| 1062 | bpType = BreakpointType::BreakOnExitCall; |
| 1063 | globalBpType = GlobalBreakpointType::GlobalBreakOnExitCall; |
| 1064 | breakpointId = BreakpointManager::MakeGoalExitBreakpointId(mapping->goal->Id, mapping->actionIndex); |
| 1065 | #if defined(DUMP_TRACEPOINTS) |
| 1066 | Debug("GoalExit(Goal %d, Action %d)", mapping->goal->Id, mapping->actionIndex); |
| 1067 | #endif |
| 1068 | } |
| 1069 | |
| 1070 | PushFrame({ reason, mapping->rule, mapping->goal, mapping->actionIndex, nullptr, nullptr }); |
| 1071 | |
| 1072 | ConditionalBreakpointInServerThread(nullptr, breakpointId, bpType, globalBpType); |
| 1073 | |
| 1074 | // Capture debug output from the DebugBreak() Osiris call and forward it to the dbg frontend |
| 1075 | |
| 1076 | if (action->FunctionName != nullptr |
| 1077 | && action->Arguments != nullptr |
| 1078 | && action->Arguments->Args().Size == 1 |
no test coverage detected