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