//===-- SingleStepCheck.h ------------------------------------- -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef liblldb_SingleStepCheck_H_ #define liblldb_SingleStepCheck_H_ #include #include #include namespace lldb_private { namespace process_linux { // arm64 linux had a bug which prevented single-stepping and watchpoints from // working on non-boot cpus, due to them being incorrectly initialized after // coming out of suspend. This issue is particularly affecting android M, which // uses suspend ("doze mode") quite aggressively. This code detects that // situation and makes single-stepping work by doing all the step operations on // the boot cpu. // // The underlying issue has been fixed in android N and linux 4.4. This code can // be removed once these systems become obsolete. #if defined(__arm64__) || defined(__aarch64__) class SingleStepWorkaround { ::pid_t m_tid; cpu_set_t m_original_set; SingleStepWorkaround(const SingleStepWorkaround &) = delete; void operator=(const SingleStepWorkaround &) = delete; public: SingleStepWorkaround(::pid_t tid, cpu_set_t original_set) : m_tid(tid), m_original_set(original_set) {} ~SingleStepWorkaround(); static std::unique_ptr Get(::pid_t tid); }; #else class SingleStepWorkaround { public: static std::unique_ptr Get(::pid_t tid) { return nullptr; } }; #endif } // end namespace process_linux } // end namespace lldb_private #endif // #ifndef liblldb_SingleStepCheck_H_