Index: lib/sanitizer_common/sanitizer_stoptheworld_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_stoptheworld_mac.cc +++ lib/sanitizer_common/sanitizer_stoptheworld_mac.cc @@ -49,11 +49,30 @@ } #if defined(__x86_64__) +typedef x86_thread_state64_t regs_struct; +#define THREAD_STATE x86_THREAD_STATE64 #define THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT + +#define SP_REG __rsp + #elif defined(__aarch64__) +typedef arm_thread_state64_t regs_struct; +#define THREAD_STATE ARM_THREAD_STATE64 #define THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT + +#if __DARWIN_UNIX03 +#define SP_REG __sp +#else +#define SP_REG sp +#endif + #elif defined(__i386) +typedef x86_thread_state32_t regs_struct; +#define THREAD_STATE x86_THREAD_STATE32 #define THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT + +#define SP_REG __esp + #else #error "Unsupported architecture" #endif @@ -93,8 +112,26 @@ PtraceRegistersStatus SuspendedThreadsListMac::GetRegistersAndSP( uptr index, uptr *buffer, uptr *sp) const { - CHECK(0 && "unimplemented"); - return REGISTERS_UNAVAILABLE_FATAL; + thread_t thread = GetThread(index); + regs_struct regs; + int err; + mach_msg_type_number_t reg_count = THREAD_STATE_COUNT; + err = + thread_get_state(thread, THREAD_STATE, (thread_state_t)®s, ®_count); + if (err != KERN_SUCCESS) { + VReport(1, "Error - unable to get registers for a thread\n"); + // KERN_INVALID_ARGUMENT indicates that either the flavor is invalid, + // or the thread does not exist. The other possible error case, + // MIG_ARRAY_TOO_LARGE, means that the state is too large, but it's + // still safe to proceed. + return err == KERN_INVALID_ARGUMENT ? REGISTERS_UNAVAILABLE_FATAL + : REGISTERS_UNAVAILABLE; + } + + internal_memcpy(buffer, ®s, sizeof(regs)); + *sp = regs.SP_REG; + + return REGISTERS_AVAILABLE; } uptr SuspendedThreadsListMac::RegisterCount() const {