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