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