1605b51b8SPavel Labath //===-- SingleStepCheck.h ------------------------------------- -*- C++ -*-===// 2605b51b8SPavel Labath // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6605b51b8SPavel Labath // 7605b51b8SPavel Labath //===----------------------------------------------------------------------===// 8605b51b8SPavel Labath 9605b51b8SPavel Labath #ifndef liblldb_SingleStepCheck_H_ 10605b51b8SPavel Labath #define liblldb_SingleStepCheck_H_ 11605b51b8SPavel Labath 127278496cSPavel Labath #include <memory> 137278496cSPavel Labath #include <sched.h> 148abd34f0SPavel Labath #include <sys/types.h> 158abd34f0SPavel Labath 16b9c1b51eSKate Stone namespace lldb_private { 17b9c1b51eSKate Stone namespace process_linux { 18605b51b8SPavel Labath 19b9c1b51eSKate Stone // arm64 linux had a bug which prevented single-stepping and watchpoints from 208abd34f0SPavel Labath // working on non-boot cpus, due to them being incorrectly initialized after 218abd34f0SPavel Labath // coming out of suspend. This issue is particularly affecting android M, which 228abd34f0SPavel Labath // uses suspend ("doze mode") quite aggressively. This code detects that 238abd34f0SPavel Labath // situation and makes single-stepping work by doing all the step operations on 24605b51b8SPavel Labath // the boot cpu. 25605b51b8SPavel Labath // 26b9c1b51eSKate Stone // The underlying issue has been fixed in android N and linux 4.4. This code can 278abd34f0SPavel Labath // be removed once these systems become obsolete. 288abd34f0SPavel Labath 298abd34f0SPavel Labath #if defined(__arm64__) || defined(__aarch64__) 308abd34f0SPavel Labath class SingleStepWorkaround { 318abd34f0SPavel Labath ::pid_t m_tid; 328abd34f0SPavel Labath cpu_set_t m_original_set; 338abd34f0SPavel Labath 347278496cSPavel Labath SingleStepWorkaround(const SingleStepWorkaround &) = delete; 357278496cSPavel Labath void operator=(const SingleStepWorkaround &) = delete; 367278496cSPavel Labath 378abd34f0SPavel Labath public: SingleStepWorkaround(::pid_t tid,cpu_set_t original_set)388abd34f0SPavel Labath SingleStepWorkaround(::pid_t tid, cpu_set_t original_set) 398abd34f0SPavel Labath : m_tid(tid), m_original_set(original_set) {} 408abd34f0SPavel Labath ~SingleStepWorkaround(); 418abd34f0SPavel Labath 427278496cSPavel Labath static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid); 438abd34f0SPavel Labath }; 448abd34f0SPavel Labath #else 458abd34f0SPavel Labath class SingleStepWorkaround { 468abd34f0SPavel Labath public: 477278496cSPavel Labath static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid) { 487278496cSPavel Labath return nullptr; 49605b51b8SPavel Labath } 508abd34f0SPavel Labath }; 518abd34f0SPavel Labath #endif 528abd34f0SPavel Labath 53605b51b8SPavel Labath } // end namespace process_linux 54605b51b8SPavel Labath } // end namespace lldb_private 55605b51b8SPavel Labath 56605b51b8SPavel Labath #endif // #ifndef liblldb_SingleStepCheck_H_ 57