1 //===-- NativeThreadLinux.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_NativeThreadLinux_H_
11 #define liblldb_NativeThreadLinux_H_
12 
13 #include "lldb/Host/common/NativeThreadProtocol.h"
14 #include "lldb/lldb-private-forward.h"
15 
16 #include <sched.h>
17 
18 #include <map>
19 #include <memory>
20 #include <string>
21 
22 namespace lldb_private {
23 namespace process_linux {
24 
25 class NativeProcessLinux;
26 
27 class NativeThreadLinux : public NativeThreadProtocol {
28   friend class NativeProcessLinux;
29 
30 public:
31   NativeThreadLinux(NativeProcessLinux *process, lldb::tid_t tid);
32 
33   // ---------------------------------------------------------------------
34   // NativeThreadProtocol Interface
35   // ---------------------------------------------------------------------
36   std::string GetName() override;
37 
38   lldb::StateType GetState() override;
39 
40   bool GetStopReason(ThreadStopInfo &stop_info,
41                      std::string &description) override;
42 
43   NativeRegisterContextSP GetRegisterContext() override;
44 
45   Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
46                       bool hardware) override;
47 
48   Error RemoveWatchpoint(lldb::addr_t addr) override;
49 
50 private:
51   // ---------------------------------------------------------------------
52   // Interface for friend classes
53   // ---------------------------------------------------------------------
54 
55   /// Resumes the thread.  If @p signo is anything but
56   /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
57   Error Resume(uint32_t signo);
58 
59   /// Single steps the thread.  If @p signo is anything but
60   /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
61   Error SingleStep(uint32_t signo);
62 
63   void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
64 
65   /// Return true if the thread is stopped.
66   /// If stopped by a signal, indicate the signo in the signo argument.
67   /// Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
68   bool IsStopped(int *signo);
69 
70   void SetStoppedByExec();
71 
72   void SetStoppedByBreakpoint();
73 
74   void SetStoppedByWatchpoint(uint32_t wp_index);
75 
76   bool IsStoppedAtBreakpoint();
77 
78   bool IsStoppedAtWatchpoint();
79 
80   void SetStoppedByTrace();
81 
82   void SetStoppedWithNoReason();
83 
84   void SetExited();
85 
86   Error RequestStop();
87 
88   // ---------------------------------------------------------------------
89   // Private interface
90   // ---------------------------------------------------------------------
91   void MaybeLogStateChange(lldb::StateType new_state);
92 
93   NativeProcessLinux &GetProcess();
94 
95   void SetStopped();
96 
97   inline void MaybePrepareSingleStepWorkaround();
98 
99   inline void MaybeCleanupSingleStepWorkaround();
100 
101   // ---------------------------------------------------------------------
102   // Member Variables
103   // ---------------------------------------------------------------------
104   lldb::StateType m_state;
105   ThreadStopInfo m_stop_info;
106   NativeRegisterContextSP m_reg_context_sp;
107   std::string m_stop_description;
108   using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
109   WatchpointIndexMap m_watchpoint_index_map;
110   cpu_set_t m_original_cpu_set; // For single-step workaround.
111 };
112 
113 typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
114 } // namespace process_linux
115 } // namespace lldb_private
116 
117 #endif // #ifndef liblldb_NativeThreadLinux_H_
118