Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc @@ -48,6 +48,29 @@ CHECK(0 && "unimplemented"); } +#if defined(__x86_64__) +typedef x86_thread_state64_t regs_struct; + +#define SP_REG __rsp + +#elif defined(__aarch64__) +typedef arm_thread_state64_t regs_struct; + +# if __DARWIN_UNIX03 +# define SP_REG __sp +# else +# define SP_REG sp +# endif + +#elif defined(__i386) +typedef x86_thread_state32_t regs_struct; + +#define SP_REG __esp + +#else +#error "Unsupported architecture" +#endif + tid_t SuspendedThreadsListMac::GetThreadID(uptr index) const { CHECK_LT(index, threads_.size()); return threads_[index].tid; @@ -83,8 +106,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 = MACHINE_THREAD_STATE_COUNT; + err = thread_get_state(thread, MACHINE_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 {