@@ -40,12 +40,17 @@ bool SimpleDebugger::startDebugging() {
4040 return false ;
4141 }
4242
43- if (task_set_exception_ports (mach_task_self (),
44- EXC_MASK_BREAKPOINT,
45- exceptionPort,
46- EXCEPTION_DEFAULT,
47- ARM_THREAD_STATE64) != KERN_SUCCESS) {
48- return false ;
43+ if (task_set_exception_ports (
44+ mach_task_self (),
45+ // Register for EXC_MASK_BAD_ACCESS to catch cases where a thread
46+ // is trying to access a page that we are in the middle of changing.
47+ // It temporarily has execute permissions removed so could trigger this.
48+ // When it is triggered we should ignore it and retry the original instruction.
49+ EXC_MASK_BREAKPOINT | EXC_MASK_BAD_ACCESS,
50+ exceptionPort,
51+ EXCEPTION_DEFAULT,
52+ ARM_THREAD_STATE64) != KERN_SUCCESS) {
53+ return false ;
4954 }
5055
5156 m.lock ();
@@ -159,14 +164,11 @@ void SimpleDebugger::continueFromBreak(MachExceptionMessage exceptionMessage, ar
159164 if (originalInstruction.contains (state.__pc )) {
160165 uint32_t orig = originalInstruction.at (state.__pc );
161166 setInstruction (state.__pc , orig);
167+ originalInstruction.erase (state.__pc );
162168 } else {
163- // Address was not tracked, increment the pc and continue
164- state.__pc += 4 ;
165-
166- kern_return_t kr = thread_set_state (exceptionMessage.thread .name , ARM_THREAD_STATE64, (thread_state_t )&state, state_count);
167- if (kr != KERN_SUCCESS) {
168- printf (" Error setting thread state: %s\n " , mach_error_string (kr));
169- }
169+ // Address was not tracked, do nothing. Maybe this was a thread that hit the breakpoint
170+ // at the same time another thread cleared it.
171+ printf (" Unexpected not tracked address\n " );
170172 }
171173
172174 MachReplyMessage replyMessage = {{0 }};
0 commit comments