1*061da546Spatrick //===-- SingleStepCheck.h ------------------------------------- -*- C++ -*-===// 2*061da546Spatrick // 3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*061da546Spatrick // 7*061da546Spatrick //===----------------------------------------------------------------------===// 8*061da546Spatrick 9*061da546Spatrick #ifndef liblldb_SingleStepCheck_H_ 10*061da546Spatrick #define liblldb_SingleStepCheck_H_ 11*061da546Spatrick 12*061da546Spatrick #include <memory> 13*061da546Spatrick #include <sched.h> 14*061da546Spatrick #include <sys/types.h> 15*061da546Spatrick 16*061da546Spatrick namespace lldb_private { 17*061da546Spatrick namespace process_linux { 18*061da546Spatrick 19*061da546Spatrick // arm64 linux had a bug which prevented single-stepping and watchpoints from 20*061da546Spatrick // working on non-boot cpus, due to them being incorrectly initialized after 21*061da546Spatrick // coming out of suspend. This issue is particularly affecting android M, which 22*061da546Spatrick // uses suspend ("doze mode") quite aggressively. This code detects that 23*061da546Spatrick // situation and makes single-stepping work by doing all the step operations on 24*061da546Spatrick // the boot cpu. 25*061da546Spatrick // 26*061da546Spatrick // The underlying issue has been fixed in android N and linux 4.4. This code can 27*061da546Spatrick // be removed once these systems become obsolete. 28*061da546Spatrick 29*061da546Spatrick #if defined(__arm64__) || defined(__aarch64__) 30*061da546Spatrick class SingleStepWorkaround { 31*061da546Spatrick ::pid_t m_tid; 32*061da546Spatrick cpu_set_t m_original_set; 33*061da546Spatrick 34*061da546Spatrick SingleStepWorkaround(const SingleStepWorkaround &) = delete; 35*061da546Spatrick void operator=(const SingleStepWorkaround &) = delete; 36*061da546Spatrick 37*061da546Spatrick public: SingleStepWorkaround(::pid_t tid,cpu_set_t original_set)38*061da546Spatrick SingleStepWorkaround(::pid_t tid, cpu_set_t original_set) 39*061da546Spatrick : m_tid(tid), m_original_set(original_set) {} 40*061da546Spatrick ~SingleStepWorkaround(); 41*061da546Spatrick 42*061da546Spatrick static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid); 43*061da546Spatrick }; 44*061da546Spatrick #else 45*061da546Spatrick class SingleStepWorkaround { 46*061da546Spatrick public: 47*061da546Spatrick static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid) { 48*061da546Spatrick return nullptr; 49*061da546Spatrick } 50*061da546Spatrick }; 51*061da546Spatrick #endif 52*061da546Spatrick 53*061da546Spatrick } // end namespace process_linux 54*061da546Spatrick } // end namespace lldb_private 55*061da546Spatrick 56*061da546Spatrick #endif // #ifndef liblldb_SingleStepCheck_H_ 57