LLDB  mainline
TargetThreadWindows.cpp
Go to the documentation of this file.
1 //===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Utility/Log.h"
15 #include "lldb/Utility/Logging.h"
16 #include "lldb/Utility/State.h"
17 
19 #include "ProcessWindows.h"
20 #include "ProcessWindowsLog.h"
21 #include "TargetThreadWindows.h"
22 
23 #if defined(_WIN64)
25 #else
27 #endif
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
33  const HostThread &thread)
34  : Thread(process, thread.GetNativeThread().GetThreadId()),
35  m_thread_reg_ctx_sp(), m_host_thread(thread) {}
36 
38 
40  ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
42  GetRegisterContext()->InvalidateIfNeeded(false);
43 }
44 
46 
48 
50  if (!m_reg_context_sp)
52 
53  return m_reg_context_sp;
54 }
55 
56 RegisterContextSP
58  RegisterContextSP reg_ctx_sp;
59  uint32_t concrete_frame_idx = 0;
61 
62  if (frame)
63  concrete_frame_idx = frame->GetConcreteFrameIndex();
64 
65  if (concrete_frame_idx == 0) {
66  if (!m_thread_reg_ctx_sp) {
67  ArchSpec arch = HostInfo::GetArchitecture();
68  switch (arch.GetMachine()) {
69  case llvm::Triple::x86:
70 #if defined(_WIN64)
71  // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
72  LLDB_LOG(log, "This is a Wow64 process, we should create a "
73  "RegisterContextWindows_Wow64, but we don't.");
74 #else
75  m_thread_reg_ctx_sp.reset(
76  new RegisterContextWindows_x86(*this, concrete_frame_idx));
77 #endif
78  break;
79  case llvm::Triple::x86_64:
80 #if defined(_WIN64)
81  m_thread_reg_ctx_sp.reset(
82  new RegisterContextWindows_x64(*this, concrete_frame_idx));
83 #else
84  LLDB_LOG(log, "LLDB is 32-bit, but the target process is 64-bit.");
85 #endif
86  default:
87  break;
88  }
89  }
90  reg_ctx_sp = m_thread_reg_ctx_sp;
91  } else {
92  Unwind *unwinder = GetUnwinder();
93  if (unwinder != nullptr)
94  reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
95  }
96 
97  return reg_ctx_sp;
98 }
99 
102  return true;
103 }
104 
106  // FIXME: Implement an unwinder based on the Windows unwinder exposed through
107  // DIA SDK.
108  if (!m_unwinder_up)
109  m_unwinder_up.reset(new UnwindLLDB(*this));
110  return m_unwinder_up.get();
111 }
112 
114  StateType resume_state = GetTemporaryResumeState();
115  StateType current_state = GetState();
116  if (resume_state == current_state)
117  return Status();
118 
119  if (resume_state == eStateStepping) {
120  uint32_t flags_index =
121  GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
123  uint64_t flags_value =
124  GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
125  flags_value |= 0x100; // Set the trap flag on the CPU
126  GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
127  }
128 
129  if (resume_state == eStateStepping || resume_state == eStateRunning) {
130  DWORD previous_suspend_count = 0;
131  HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
132  do {
133  // ResumeThread returns -1 on error, or the thread's *previous* suspend
134  // count on success. This means that the return value is 1 when the thread
135  // was restarted. Note that DWORD is an unsigned int, so we need to
136  // explicitly compare with -1.
137  previous_suspend_count = ::ResumeThread(thread_handle);
138 
139  if (previous_suspend_count == (DWORD)-1)
140  return Status(::GetLastError(), eErrorTypeWin32);
141 
142  } while (previous_suspend_count > 1);
143  }
144 
145  return Status();
146 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
std::unique_ptr< lldb_private::Unwind > m_unwinder_up
It gets set in Thread::ShouldResume.
Definition: Thread.h:1248
HostNativeThread & GetNativeThread()
Definition: HostThread.cpp:32
void SetState(lldb::StateType state)
Definition: Thread.cpp:587
An architecture specification class.
Definition: ArchSpec.h:32
void WillResume(lldb::StateType resume_state) override
Process or thread is stopped and can be examined.
lldb::StateType GetState() const
Definition: Thread.cpp:581
lldb::RegisterContextSP m_reg_context_sp
The register context for this thread&#39;s current register state.
Definition: Thread.h:1220
#define LLDB_LOG(log,...)
Definition: Log.h:209
Standard Win32 error codes.
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame)
Definition: Unwind.h:55
lldb::StopInfoSP m_stop_info_sp
The private stop reason for this thread.
Definition: Thread.h:1210
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
void SetStopInfo(const lldb::StopInfoSP &stop_info_sp)
Definition: Thread.cpp:477
#define LIBLLDB_LOG_THREAD
Definition: Logging.h:16
virtual void DestroyThread()
Definition: Thread.cpp:278
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
Process or thread is in the process of stepping and can not be examined.
Definition: SBAddress.h:15
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override
lldb::StateType GetTemporaryResumeState() const
Definition: Thread.h:1127
uint32_t GetConcreteFrameIndex() const
Query this frame to find what frame it is in this Thread&#39;s StackFrameList, not counting inlined frame...
Definition: StackFrame.h:389
lldb::RegisterContextSP GetRegisterContext() override
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:726
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
An error handling class.
Definition: Status.h:44
Process or thread is running and can&#39;t be examined.