blob: 160e18d35892b630b20c0b78a8ea60083a52cec7 [file] [log] [blame]
Todd Fialae77fce02016-09-04 00:18:56 +00001//===-- NativeThreadDarwin.h ---------------------------------- -*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Todd Fialae77fce02016-09-04 00:18:56 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef NativeThreadDarwin_H
10#define NativeThreadDarwin_H
11
12// C includes
13#include <mach/mach_types.h>
14#include <sched.h>
15#include <sys/proc_info.h>
16
17// C++ includes
18#include <map>
19#include <memory>
20#include <string>
21
22// LLDB includes
Todd Fialae77fce02016-09-04 00:18:56 +000023#include "lldb/Host/common/NativeThreadProtocol.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "lldb/lldb-private-forward.h"
Todd Fialae77fce02016-09-04 00:18:56 +000025
26#include "MachException.h"
27
28namespace lldb_private {
29namespace process_darwin {
30
31class NativeProcessDarwin;
32using NativeProcessDarwinSP = std::shared_ptr<NativeProcessDarwin>;
33
34class NativeThreadListDarwin;
35
Kate Stoneb9c1b512016-09-06 20:57:50 +000036class NativeThreadDarwin : public NativeThreadProtocol {
37 friend class NativeProcessDarwin;
38 friend class NativeThreadListDarwin;
Todd Fialae77fce02016-09-04 00:18:56 +000039
40public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 static uint64_t
42 GetGloballyUniqueThreadIDForMachPortID(::thread_t mach_port_id);
Todd Fialae77fce02016-09-04 00:18:56 +000043
Kate Stoneb9c1b512016-09-06 20:57:50 +000044 NativeThreadDarwin(NativeProcessDarwin *process, bool is_64_bit,
45 lldb::tid_t unique_thread_id = 0,
46 ::thread_t mach_thread_port = 0);
Todd Fialae77fce02016-09-04 00:18:56 +000047
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 // -----------------------------------------------------------------
49 // NativeThreadProtocol Interface
50 // -----------------------------------------------------------------
51 std::string GetName() override;
Todd Fialae77fce02016-09-04 00:18:56 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 lldb::StateType GetState() override;
Todd Fialae77fce02016-09-04 00:18:56 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 bool GetStopReason(ThreadStopInfo &stop_info,
56 std::string &description) override;
Todd Fialae77fce02016-09-04 00:18:56 +000057
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 NativeRegisterContextSP GetRegisterContext() override;
Todd Fialae77fce02016-09-04 00:18:56 +000059
Zachary Turner97206d52017-05-12 04:51:55 +000060 Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
61 bool hardware) override;
Todd Fialae77fce02016-09-04 00:18:56 +000062
Zachary Turner97206d52017-05-12 04:51:55 +000063 Status RemoveWatchpoint(lldb::addr_t addr) override;
Todd Fialae77fce02016-09-04 00:18:56 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 // -----------------------------------------------------------------
66 // New methods that are fine for others to call.
67 // -----------------------------------------------------------------
68 void Dump(Stream &stream) const;
Todd Fialae77fce02016-09-04 00:18:56 +000069
70private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 // -----------------------------------------------------------------
72 // Interface for friend classes
73 // -----------------------------------------------------------------
Todd Fialae77fce02016-09-04 00:18:56 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 /// Resumes the thread. If @p signo is anything but
76 /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
Zachary Turner97206d52017-05-12 04:51:55 +000077 Status Resume(uint32_t signo);
Todd Fialae77fce02016-09-04 00:18:56 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 /// Single steps the thread. If @p signo is anything but
80 /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
Zachary Turner97206d52017-05-12 04:51:55 +000081 Status SingleStep(uint32_t signo);
Todd Fialae77fce02016-09-04 00:18:56 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 bool NotifyException(MachException::Data &exc);
Todd Fialae77fce02016-09-04 00:18:56 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 bool ShouldStop(bool &step_more) const;
Todd Fialae77fce02016-09-04 00:18:56 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 void ThreadDidStop();
Todd Fialae77fce02016-09-04 00:18:56 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
Todd Fialae77fce02016-09-04 00:18:56 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 /// Return true if the thread is stopped.
92 /// If stopped by a signal, indicate the signo in the signo
93 /// argument. Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
94 bool IsStopped(int *signo);
Todd Fialae77fce02016-09-04 00:18:56 +000095
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 const struct thread_basic_info *GetBasicInfo() const;
Todd Fialae77fce02016-09-04 00:18:56 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 static bool GetBasicInfo(::thread_t thread,
99 struct thread_basic_info *basicInfoPtr);
Todd Fialae77fce02016-09-04 00:18:56 +0000100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 bool IsUserReady() const;
Todd Fialae77fce02016-09-04 00:18:56 +0000102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 void SetStoppedByExec();
Todd Fialae77fce02016-09-04 00:18:56 +0000104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105 void SetStoppedByBreakpoint();
Todd Fialae77fce02016-09-04 00:18:56 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 void SetStoppedByWatchpoint(uint32_t wp_index);
Todd Fialae77fce02016-09-04 00:18:56 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 bool IsStoppedAtBreakpoint();
Todd Fialae77fce02016-09-04 00:18:56 +0000110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 bool IsStoppedAtWatchpoint();
Todd Fialae77fce02016-09-04 00:18:56 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 void SetStoppedByTrace();
Todd Fialae77fce02016-09-04 00:18:56 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 void SetStoppedWithNoReason();
Todd Fialae77fce02016-09-04 00:18:56 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 void SetExited();
Todd Fialae77fce02016-09-04 00:18:56 +0000118
Zachary Turner97206d52017-05-12 04:51:55 +0000119 Status RequestStop();
Todd Fialae77fce02016-09-04 00:18:56 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 // -------------------------------------------------------------------------
122 /// Return the mach thread port number for this thread.
123 ///
124 /// @return
125 /// The mach port number for this thread. Returns NULL_THREAD
126 /// when the thread is invalid.
127 // -------------------------------------------------------------------------
128 thread_t GetMachPortNumber() const { return m_mach_thread_port; }
Todd Fialae77fce02016-09-04 00:18:56 +0000129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 static bool MachPortNumberIsValid(::thread_t thread);
Todd Fialae77fce02016-09-04 00:18:56 +0000131
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 // ---------------------------------------------------------------------
133 // Private interface
134 // ---------------------------------------------------------------------
135 bool GetIdentifierInfo();
Todd Fialae77fce02016-09-04 00:18:56 +0000136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 void MaybeLogStateChange(lldb::StateType new_state);
Todd Fialae77fce02016-09-04 00:18:56 +0000138
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 NativeProcessDarwinSP GetNativeProcessDarwinSP();
Todd Fialae77fce02016-09-04 00:18:56 +0000140
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 void SetStopped();
Todd Fialae77fce02016-09-04 00:18:56 +0000142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 inline void MaybePrepareSingleStepWorkaround();
Todd Fialae77fce02016-09-04 00:18:56 +0000144
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 inline void MaybeCleanupSingleStepWorkaround();
Todd Fialae77fce02016-09-04 00:18:56 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 // -----------------------------------------------------------------
148 // Member Variables
149 // -----------------------------------------------------------------
Todd Fialae77fce02016-09-04 00:18:56 +0000150
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 // The mach thread port for the thread.
152 ::thread_t m_mach_thread_port;
Todd Fialae77fce02016-09-04 00:18:56 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 // The most recently-retrieved thread basic info.
155 mutable ::thread_basic_info m_basic_info;
Todd Fialae77fce02016-09-04 00:18:56 +0000156
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 struct proc_threadinfo m_proc_threadinfo;
Todd Fialae77fce02016-09-04 00:18:56 +0000158
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 thread_identifier_info_data_t m_ident_info;
Todd Fialae77fce02016-09-04 00:18:56 +0000160
161#if 0
162 lldb::StateType m_state;
163 ThreadStopInfo m_stop_info;
164 NativeRegisterContextSP m_reg_context_sp;
165 std::string m_stop_description;
166 using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
167 WatchpointIndexMap m_watchpoint_index_map;
168 // cpu_set_t m_original_cpu_set; // For single-step workaround.
169#endif
170};
171
172typedef std::shared_ptr<NativeThreadDarwin> NativeThreadDarwinSP;
173
174} // namespace process_darwin
175} // namespace lldb_private
176
177#endif // #ifndef NativeThreadDarwin_H