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 "sched.h"
14 #include "llvm/ADT/Optional.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 public:
36   SingleStepWorkaround(::pid_t tid, cpu_set_t original_set)
37       : m_tid(tid), m_original_set(original_set) {}
38   ~SingleStepWorkaround();
39 
40   static llvm::Optional<SingleStepWorkaround> Get(::pid_t tid);
41 };
42 #else
43 class SingleStepWorkaround {
44 public:
45   static llvm::Optional<SingleStepWorkaround> Get(::pid_t tid) {
46     return llvm::None;
47   }
48 };
49 #endif
50 
51 } // end namespace process_linux
52 } // end namespace lldb_private
53 
54 #endif // #ifndef liblldb_SingleStepCheck_H_
55