1ac7ddfbfSEd Maste //===-- Process.cpp ---------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
104bb0738eSEd Maste #include <atomic>
114bb0738eSEd Maste #include <mutex>
124bb0738eSEd Maste 
13435933ddSDimitry Andric #include "llvm/Support/ScopedPrinter.h"
14f678e45dSDimitry Andric #include "llvm/Support/Threading.h"
15f678e45dSDimitry Andric 
164bb0738eSEd Maste #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
184bb0738eSEd Maste #include "lldb/Breakpoint/StoppointCallbackContext.h"
19ac7ddfbfSEd Maste #include "lldb/Core/Debugger.h"
20ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
211c3bbb01SEd Maste #include "lldb/Core/ModuleSpec.h"
22ac7ddfbfSEd Maste #include "lldb/Core/PluginManager.h"
2312b93ac6SEd Maste #include "lldb/Core/StreamFile.h"
244bb0738eSEd Maste #include "lldb/Expression/DiagnosticManager.h"
251c3bbb01SEd Maste #include "lldb/Expression/IRDynamicChecks.h"
264bb0738eSEd Maste #include "lldb/Expression/UserExpression.h"
274ba319b5SDimitry Andric #include "lldb/Expression/UtilityFunction.h"
287aa51b79SEd Maste #include "lldb/Host/ConnectionFileDescriptor.h"
299f2f44ceSEd Maste #include "lldb/Host/FileSystem.h"
30ac7ddfbfSEd Maste #include "lldb/Host/Host.h"
317aa51b79SEd Maste #include "lldb/Host/HostInfo.h"
32f678e45dSDimitry Andric #include "lldb/Host/OptionParser.h"
330127ef0fSEd Maste #include "lldb/Host/Pipe.h"
3412b93ac6SEd Maste #include "lldb/Host/Terminal.h"
357aa51b79SEd Maste #include "lldb/Host/ThreadLauncher.h"
367aa51b79SEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
374ba319b5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
381c3bbb01SEd Maste #include "lldb/Interpreter/OptionValueProperties.h"
399f2f44ceSEd Maste #include "lldb/Symbol/Function.h"
407aa51b79SEd Maste #include "lldb/Symbol/Symbol.h"
41ac7ddfbfSEd Maste #include "lldb/Target/ABI.h"
424bb0738eSEd Maste #include "lldb/Target/CPPLanguageRuntime.h"
43ac7ddfbfSEd Maste #include "lldb/Target/DynamicLoader.h"
441c3bbb01SEd Maste #include "lldb/Target/InstrumentationRuntime.h"
450127ef0fSEd Maste #include "lldb/Target/JITLoader.h"
461c3bbb01SEd Maste #include "lldb/Target/JITLoaderList.h"
474bb0738eSEd Maste #include "lldb/Target/LanguageRuntime.h"
487aa51b79SEd Maste #include "lldb/Target/MemoryHistory.h"
491c3bbb01SEd Maste #include "lldb/Target/MemoryRegionInfo.h"
50ac7ddfbfSEd Maste #include "lldb/Target/ObjCLanguageRuntime.h"
514bb0738eSEd Maste #include "lldb/Target/OperatingSystem.h"
52ac7ddfbfSEd Maste #include "lldb/Target/Platform.h"
534bb0738eSEd Maste #include "lldb/Target/Process.h"
54ac7ddfbfSEd Maste #include "lldb/Target/RegisterContext.h"
55ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h"
56435933ddSDimitry Andric #include "lldb/Target/StructuredDataPlugin.h"
5735617911SEd Maste #include "lldb/Target/SystemRuntime.h"
58ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
59ac7ddfbfSEd Maste #include "lldb/Target/TargetList.h"
60ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
61ac7ddfbfSEd Maste #include "lldb/Target/ThreadPlan.h"
62ac7ddfbfSEd Maste #include "lldb/Target/ThreadPlanBase.h"
631c3bbb01SEd Maste #include "lldb/Target/UnixSignals.h"
64*b5893f02SDimitry Andric #include "lldb/Utility/Event.h"
65f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
661c3bbb01SEd Maste #include "lldb/Utility/NameMatches.h"
67435933ddSDimitry Andric #include "lldb/Utility/SelectHelper.h"
68*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
69ac7ddfbfSEd Maste 
70ac7ddfbfSEd Maste using namespace lldb;
71ac7ddfbfSEd Maste using namespace lldb_private;
72435933ddSDimitry Andric using namespace std::chrono;
73ac7ddfbfSEd Maste 
74435933ddSDimitry Andric // Comment out line below to disable memory caching, overriding the process
75435933ddSDimitry Andric // setting target.process.disable-memory-cache
76ac7ddfbfSEd Maste #define ENABLE_MEMORY_CACHING
77ac7ddfbfSEd Maste 
78ac7ddfbfSEd Maste #ifdef ENABLE_MEMORY_CACHING
79ac7ddfbfSEd Maste #define DISABLE_MEM_CACHE_DEFAULT false
80ac7ddfbfSEd Maste #else
81ac7ddfbfSEd Maste #define DISABLE_MEM_CACHE_DEFAULT true
82ac7ddfbfSEd Maste #endif
83ac7ddfbfSEd Maste 
84435933ddSDimitry Andric class ProcessOptionValueProperties : public OptionValueProperties {
85ac7ddfbfSEd Maste public:
ProcessOptionValueProperties(const ConstString & name)86435933ddSDimitry Andric   ProcessOptionValueProperties(const ConstString &name)
87435933ddSDimitry Andric       : OptionValueProperties(name) {}
88ac7ddfbfSEd Maste 
894ba319b5SDimitry Andric   // This constructor is used when creating ProcessOptionValueProperties when
904ba319b5SDimitry Andric   // it is part of a new lldb_private::Process instance. It will copy all
914ba319b5SDimitry Andric   // current global property values as needed
ProcessOptionValueProperties(ProcessProperties * global_properties)92435933ddSDimitry Andric   ProcessOptionValueProperties(ProcessProperties *global_properties)
93435933ddSDimitry Andric       : OptionValueProperties(*global_properties->GetValueProperties()) {}
94ac7ddfbfSEd Maste 
GetPropertyAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const95435933ddSDimitry Andric   const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx,
96435933ddSDimitry Andric                                      bool will_modify,
97435933ddSDimitry Andric                                      uint32_t idx) const override {
984ba319b5SDimitry Andric     // When getting the value for a key from the process options, we will
994ba319b5SDimitry Andric     // always try and grab the setting from the current process if there is
1004ba319b5SDimitry Andric     // one. Else we just use the one from this instance.
101435933ddSDimitry Andric     if (exe_ctx) {
102ac7ddfbfSEd Maste       Process *process = exe_ctx->GetProcessPtr();
103435933ddSDimitry Andric       if (process) {
104435933ddSDimitry Andric         ProcessOptionValueProperties *instance_properties =
105435933ddSDimitry Andric             static_cast<ProcessOptionValueProperties *>(
106435933ddSDimitry Andric                 process->GetValueProperties().get());
107ac7ddfbfSEd Maste         if (this != instance_properties)
108ac7ddfbfSEd Maste           return instance_properties->ProtectedGetPropertyAtIndex(idx);
109ac7ddfbfSEd Maste       }
110ac7ddfbfSEd Maste     }
111ac7ddfbfSEd Maste     return ProtectedGetPropertyAtIndex(idx);
112ac7ddfbfSEd Maste   }
113ac7ddfbfSEd Maste };
114ac7ddfbfSEd Maste 
115*b5893f02SDimitry Andric static constexpr PropertyDefinition g_properties[] = {
116435933ddSDimitry Andric     {"disable-memory-cache", OptionValue::eTypeBoolean, false,
117*b5893f02SDimitry Andric      DISABLE_MEM_CACHE_DEFAULT, nullptr, {},
118435933ddSDimitry Andric      "Disable reading and caching of memory in fixed-size units."},
119435933ddSDimitry Andric     {"extra-startup-command", OptionValue::eTypeArray, false,
120*b5893f02SDimitry Andric      OptionValue::eTypeString, nullptr, {},
121435933ddSDimitry Andric      "A list containing extra commands understood by the particular process "
122435933ddSDimitry Andric      "plugin used.  "
123435933ddSDimitry Andric      "For instance, to turn on debugserver logging set this to "
124435933ddSDimitry Andric      "\"QSetLogging:bitmask=LOG_DEFAULT;\""},
125435933ddSDimitry Andric     {"ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true,
126*b5893f02SDimitry Andric      nullptr, {},
127435933ddSDimitry Andric      "If true, breakpoints will be ignored during expression evaluation."},
128435933ddSDimitry Andric     {"unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true,
129*b5893f02SDimitry Andric      nullptr, {}, "If true, errors in expression evaluation will unwind "
130435933ddSDimitry Andric                   "the stack back to the state before the call."},
131435933ddSDimitry Andric     {"python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, nullptr,
132*b5893f02SDimitry Andric      {}, "A path to a python OS plug-in module file that contains a "
133435933ddSDimitry Andric          "OperatingSystemPlugIn class."},
134435933ddSDimitry Andric     {"stop-on-sharedlibrary-events", OptionValue::eTypeBoolean, true, false,
135*b5893f02SDimitry Andric      nullptr, {},
136435933ddSDimitry Andric      "If true, stop when a shared library is loaded or unloaded."},
137435933ddSDimitry Andric     {"detach-keeps-stopped", OptionValue::eTypeBoolean, true, false, nullptr,
138*b5893f02SDimitry Andric      {}, "If true, detach will attempt to keep the process stopped."},
139435933ddSDimitry Andric     {"memory-cache-line-size", OptionValue::eTypeUInt64, false, 512, nullptr,
140*b5893f02SDimitry Andric      {}, "The memory cache line size"},
141435933ddSDimitry Andric     {"optimization-warnings", OptionValue::eTypeBoolean, false, true, nullptr,
142*b5893f02SDimitry Andric      {}, "If true, warn when stopped in code that is optimized where "
143435933ddSDimitry Andric          "stepping and variable availability may not behave as expected."},
144acac075bSDimitry Andric     {"stop-on-exec", OptionValue::eTypeBoolean, true, true,
145*b5893f02SDimitry Andric      nullptr, {},
146*b5893f02SDimitry Andric      "If true, stop when a shared library is loaded or unloaded."}};
147ac7ddfbfSEd Maste 
148ac7ddfbfSEd Maste enum {
149ac7ddfbfSEd Maste   ePropertyDisableMemCache,
150ac7ddfbfSEd Maste   ePropertyExtraStartCommand,
151ac7ddfbfSEd Maste   ePropertyIgnoreBreakpointsInExpressions,
152ac7ddfbfSEd Maste   ePropertyUnwindOnErrorInExpressions,
153ac7ddfbfSEd Maste   ePropertyPythonOSPluginPath,
154ac7ddfbfSEd Maste   ePropertyStopOnSharedLibraryEvents,
1557aa51b79SEd Maste   ePropertyDetachKeepsStopped,
1569f2f44ceSEd Maste   ePropertyMemCacheLineSize,
157acac075bSDimitry Andric   ePropertyWarningOptimization,
158acac075bSDimitry Andric   ePropertyStopOnExec
159ac7ddfbfSEd Maste };
160ac7ddfbfSEd Maste 
ProcessProperties(lldb_private::Process * process)161435933ddSDimitry Andric ProcessProperties::ProcessProperties(lldb_private::Process *process)
162435933ddSDimitry Andric     : Properties(),
1634bb0738eSEd Maste       m_process(process) // Can be nullptr for global ProcessProperties
164ac7ddfbfSEd Maste {
165435933ddSDimitry Andric   if (process == nullptr) {
1667aa51b79SEd Maste     // Global process properties, set them up one time
167435933ddSDimitry Andric     m_collection_sp.reset(
168435933ddSDimitry Andric         new ProcessOptionValueProperties(ConstString("process")));
169ac7ddfbfSEd Maste     m_collection_sp->Initialize(g_properties);
170435933ddSDimitry Andric     m_collection_sp->AppendProperty(
171435933ddSDimitry Andric         ConstString("thread"), ConstString("Settings specific to threads."),
172435933ddSDimitry Andric         true, Thread::GetGlobalProperties()->GetValueProperties());
173435933ddSDimitry Andric   } else {
174435933ddSDimitry Andric     m_collection_sp.reset(
175435933ddSDimitry Andric         new ProcessOptionValueProperties(Process::GetGlobalProperties().get()));
176435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
177435933ddSDimitry Andric         ePropertyPythonOSPluginPath,
178435933ddSDimitry Andric         ProcessProperties::OptionValueChangedCallback, this);
1797aa51b79SEd Maste   }
180ac7ddfbfSEd Maste }
181ac7ddfbfSEd Maste 
1829f2f44ceSEd Maste ProcessProperties::~ProcessProperties() = default;
183ac7ddfbfSEd Maste 
OptionValueChangedCallback(void * baton,OptionValue * option_value)184435933ddSDimitry Andric void ProcessProperties::OptionValueChangedCallback(void *baton,
185435933ddSDimitry Andric                                                    OptionValue *option_value) {
1867aa51b79SEd Maste   ProcessProperties *properties = (ProcessProperties *)baton;
1877aa51b79SEd Maste   if (properties->m_process)
1887aa51b79SEd Maste     properties->m_process->LoadOperatingSystemPlugin(true);
1897aa51b79SEd Maste }
1907aa51b79SEd Maste 
GetDisableMemoryCache() const191435933ddSDimitry Andric bool ProcessProperties::GetDisableMemoryCache() const {
192ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDisableMemCache;
193435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
194435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
195ac7ddfbfSEd Maste }
196ac7ddfbfSEd Maste 
GetMemoryCacheLineSize() const197435933ddSDimitry Andric uint64_t ProcessProperties::GetMemoryCacheLineSize() const {
1987aa51b79SEd Maste   const uint32_t idx = ePropertyMemCacheLineSize;
199435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsUInt64(
200435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
2017aa51b79SEd Maste }
2027aa51b79SEd Maste 
GetExtraStartupCommands() const203435933ddSDimitry Andric Args ProcessProperties::GetExtraStartupCommands() const {
204ac7ddfbfSEd Maste   Args args;
205ac7ddfbfSEd Maste   const uint32_t idx = ePropertyExtraStartCommand;
2064bb0738eSEd Maste   m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
207ac7ddfbfSEd Maste   return args;
208ac7ddfbfSEd Maste }
209ac7ddfbfSEd Maste 
SetExtraStartupCommands(const Args & args)210435933ddSDimitry Andric void ProcessProperties::SetExtraStartupCommands(const Args &args) {
211ac7ddfbfSEd Maste   const uint32_t idx = ePropertyExtraStartCommand;
2124bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
213ac7ddfbfSEd Maste }
214ac7ddfbfSEd Maste 
GetPythonOSPluginPath() const215435933ddSDimitry Andric FileSpec ProcessProperties::GetPythonOSPluginPath() const {
216ac7ddfbfSEd Maste   const uint32_t idx = ePropertyPythonOSPluginPath;
2174bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
218ac7ddfbfSEd Maste }
219ac7ddfbfSEd Maste 
SetPythonOSPluginPath(const FileSpec & file)220435933ddSDimitry Andric void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) {
221ac7ddfbfSEd Maste   const uint32_t idx = ePropertyPythonOSPluginPath;
2224bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file);
223ac7ddfbfSEd Maste }
224ac7ddfbfSEd Maste 
GetIgnoreBreakpointsInExpressions() const225435933ddSDimitry Andric bool ProcessProperties::GetIgnoreBreakpointsInExpressions() const {
226ac7ddfbfSEd Maste   const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
227435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
228435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
229ac7ddfbfSEd Maste }
230ac7ddfbfSEd Maste 
SetIgnoreBreakpointsInExpressions(bool ignore)231435933ddSDimitry Andric void ProcessProperties::SetIgnoreBreakpointsInExpressions(bool ignore) {
232ac7ddfbfSEd Maste   const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
2334bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore);
234ac7ddfbfSEd Maste }
235ac7ddfbfSEd Maste 
GetUnwindOnErrorInExpressions() const236435933ddSDimitry Andric bool ProcessProperties::GetUnwindOnErrorInExpressions() const {
237ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
238435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
239435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
240ac7ddfbfSEd Maste }
241ac7ddfbfSEd Maste 
SetUnwindOnErrorInExpressions(bool ignore)242435933ddSDimitry Andric void ProcessProperties::SetUnwindOnErrorInExpressions(bool ignore) {
243ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
2444bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore);
245ac7ddfbfSEd Maste }
246ac7ddfbfSEd Maste 
GetStopOnSharedLibraryEvents() const247435933ddSDimitry Andric bool ProcessProperties::GetStopOnSharedLibraryEvents() const {
248ac7ddfbfSEd Maste   const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
249435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
250435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
251ac7ddfbfSEd Maste }
252ac7ddfbfSEd Maste 
SetStopOnSharedLibraryEvents(bool stop)253435933ddSDimitry Andric void ProcessProperties::SetStopOnSharedLibraryEvents(bool stop) {
254ac7ddfbfSEd Maste   const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
2554bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop);
256ac7ddfbfSEd Maste }
257ac7ddfbfSEd Maste 
GetDetachKeepsStopped() const258435933ddSDimitry Andric bool ProcessProperties::GetDetachKeepsStopped() const {
259ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDetachKeepsStopped;
260435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
261435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
262ac7ddfbfSEd Maste }
263ac7ddfbfSEd Maste 
SetDetachKeepsStopped(bool stop)264435933ddSDimitry Andric void ProcessProperties::SetDetachKeepsStopped(bool stop) {
265ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDetachKeepsStopped;
2664bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop);
267ac7ddfbfSEd Maste }
268ac7ddfbfSEd Maste 
GetWarningsOptimization() const269435933ddSDimitry Andric bool ProcessProperties::GetWarningsOptimization() const {
2709f2f44ceSEd Maste   const uint32_t idx = ePropertyWarningOptimization;
271435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
272435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
2739f2f44ceSEd Maste }
2749f2f44ceSEd Maste 
GetStopOnExec() const275acac075bSDimitry Andric bool ProcessProperties::GetStopOnExec() const {
276acac075bSDimitry Andric   const uint32_t idx = ePropertyStopOnExec;
277acac075bSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
278acac075bSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
279acac075bSDimitry Andric }
280acac075bSDimitry Andric 
Dump(Stream & s,Platform * platform) const281435933ddSDimitry Andric void ProcessInstanceInfo::Dump(Stream &s, Platform *platform) const {
282ac7ddfbfSEd Maste   const char *cstr;
283ac7ddfbfSEd Maste   if (m_pid != LLDB_INVALID_PROCESS_ID)
284ac7ddfbfSEd Maste     s.Printf("    pid = %" PRIu64 "\n", m_pid);
285ac7ddfbfSEd Maste 
286ac7ddfbfSEd Maste   if (m_parent_pid != LLDB_INVALID_PROCESS_ID)
287ac7ddfbfSEd Maste     s.Printf(" parent = %" PRIu64 "\n", m_parent_pid);
288ac7ddfbfSEd Maste 
289435933ddSDimitry Andric   if (m_executable) {
290ac7ddfbfSEd Maste     s.Printf("   name = %s\n", m_executable.GetFilename().GetCString());
291ac7ddfbfSEd Maste     s.PutCString("   file = ");
292ac7ddfbfSEd Maste     m_executable.Dump(&s);
293ac7ddfbfSEd Maste     s.EOL();
294ac7ddfbfSEd Maste   }
295ac7ddfbfSEd Maste   const uint32_t argc = m_arguments.GetArgumentCount();
296435933ddSDimitry Andric   if (argc > 0) {
297435933ddSDimitry Andric     for (uint32_t i = 0; i < argc; i++) {
298ac7ddfbfSEd Maste       const char *arg = m_arguments.GetArgumentAtIndex(i);
299ac7ddfbfSEd Maste       if (i < 10)
300ac7ddfbfSEd Maste         s.Printf(" arg[%u] = %s\n", i, arg);
301ac7ddfbfSEd Maste       else
302ac7ddfbfSEd Maste         s.Printf("arg[%u] = %s\n", i, arg);
303ac7ddfbfSEd Maste     }
304ac7ddfbfSEd Maste   }
305ac7ddfbfSEd Maste 
3064ba319b5SDimitry Andric   s.Format("{0}", m_environment);
307ac7ddfbfSEd Maste 
308435933ddSDimitry Andric   if (m_arch.IsValid()) {
3099f2f44ceSEd Maste     s.Printf("   arch = ");
3109f2f44ceSEd Maste     m_arch.DumpTriple(s);
3119f2f44ceSEd Maste     s.EOL();
3129f2f44ceSEd Maste   }
313ac7ddfbfSEd Maste 
314435933ddSDimitry Andric   if (m_uid != UINT32_MAX) {
315ac7ddfbfSEd Maste     cstr = platform->GetUserName(m_uid);
316ac7ddfbfSEd Maste     s.Printf("    uid = %-5u (%s)\n", m_uid, cstr ? cstr : "");
317ac7ddfbfSEd Maste   }
318435933ddSDimitry Andric   if (m_gid != UINT32_MAX) {
319ac7ddfbfSEd Maste     cstr = platform->GetGroupName(m_gid);
320ac7ddfbfSEd Maste     s.Printf("    gid = %-5u (%s)\n", m_gid, cstr ? cstr : "");
321ac7ddfbfSEd Maste   }
322435933ddSDimitry Andric   if (m_euid != UINT32_MAX) {
323ac7ddfbfSEd Maste     cstr = platform->GetUserName(m_euid);
324ac7ddfbfSEd Maste     s.Printf("   euid = %-5u (%s)\n", m_euid, cstr ? cstr : "");
325ac7ddfbfSEd Maste   }
326435933ddSDimitry Andric   if (m_egid != UINT32_MAX) {
327ac7ddfbfSEd Maste     cstr = platform->GetGroupName(m_egid);
328ac7ddfbfSEd Maste     s.Printf("   egid = %-5u (%s)\n", m_egid, cstr ? cstr : "");
329ac7ddfbfSEd Maste   }
330ac7ddfbfSEd Maste }
331ac7ddfbfSEd Maste 
DumpTableHeader(Stream & s,Platform * platform,bool show_args,bool verbose)332435933ddSDimitry Andric void ProcessInstanceInfo::DumpTableHeader(Stream &s, Platform *platform,
333435933ddSDimitry Andric                                           bool show_args, bool verbose) {
334ac7ddfbfSEd Maste   const char *label;
335ac7ddfbfSEd Maste   if (show_args || verbose)
336ac7ddfbfSEd Maste     label = "ARGUMENTS";
337ac7ddfbfSEd Maste   else
338ac7ddfbfSEd Maste     label = "NAME";
339ac7ddfbfSEd Maste 
340435933ddSDimitry Andric   if (verbose) {
341435933ddSDimitry Andric     s.Printf("PID    PARENT USER       GROUP      EFF USER   EFF GROUP  TRIPLE "
342435933ddSDimitry Andric              "                  %s\n",
343435933ddSDimitry Andric              label);
344435933ddSDimitry Andric     s.PutCString("====== ====== ========== ========== ========== ========== "
345435933ddSDimitry Andric                  "======================== ============================\n");
346435933ddSDimitry Andric   } else {
3470127ef0fSEd Maste     s.Printf("PID    PARENT USER       TRIPLE                   %s\n", label);
348435933ddSDimitry Andric     s.PutCString("====== ====== ========== ======================== "
349435933ddSDimitry Andric                  "============================\n");
350ac7ddfbfSEd Maste   }
351ac7ddfbfSEd Maste }
352ac7ddfbfSEd Maste 
DumpAsTableRow(Stream & s,Platform * platform,bool show_args,bool verbose) const353435933ddSDimitry Andric void ProcessInstanceInfo::DumpAsTableRow(Stream &s, Platform *platform,
354435933ddSDimitry Andric                                          bool show_args, bool verbose) const {
355435933ddSDimitry Andric   if (m_pid != LLDB_INVALID_PROCESS_ID) {
356ac7ddfbfSEd Maste     const char *cstr;
357ac7ddfbfSEd Maste     s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
358ac7ddfbfSEd Maste 
3599f2f44ceSEd Maste     StreamString arch_strm;
3609f2f44ceSEd Maste     if (m_arch.IsValid())
3619f2f44ceSEd Maste       m_arch.DumpTriple(arch_strm);
362ac7ddfbfSEd Maste 
363435933ddSDimitry Andric     if (verbose) {
364ac7ddfbfSEd Maste       cstr = platform->GetUserName(m_uid);
365435933ddSDimitry Andric       if (cstr &&
366435933ddSDimitry Andric           cstr[0]) // Watch for empty string that indicates lookup failed
367ac7ddfbfSEd Maste         s.Printf("%-10s ", cstr);
368ac7ddfbfSEd Maste       else
369ac7ddfbfSEd Maste         s.Printf("%-10u ", m_uid);
370ac7ddfbfSEd Maste 
371ac7ddfbfSEd Maste       cstr = platform->GetGroupName(m_gid);
372435933ddSDimitry Andric       if (cstr &&
373435933ddSDimitry Andric           cstr[0]) // Watch for empty string that indicates lookup failed
374ac7ddfbfSEd Maste         s.Printf("%-10s ", cstr);
375ac7ddfbfSEd Maste       else
376ac7ddfbfSEd Maste         s.Printf("%-10u ", m_gid);
377ac7ddfbfSEd Maste 
378ac7ddfbfSEd Maste       cstr = platform->GetUserName(m_euid);
379435933ddSDimitry Andric       if (cstr &&
380435933ddSDimitry Andric           cstr[0]) // Watch for empty string that indicates lookup failed
381ac7ddfbfSEd Maste         s.Printf("%-10s ", cstr);
382ac7ddfbfSEd Maste       else
383ac7ddfbfSEd Maste         s.Printf("%-10u ", m_euid);
384ac7ddfbfSEd Maste 
385ac7ddfbfSEd Maste       cstr = platform->GetGroupName(m_egid);
386435933ddSDimitry Andric       if (cstr &&
387435933ddSDimitry Andric           cstr[0]) // Watch for empty string that indicates lookup failed
388ac7ddfbfSEd Maste         s.Printf("%-10s ", cstr);
389ac7ddfbfSEd Maste       else
390ac7ddfbfSEd Maste         s.Printf("%-10u ", m_egid);
3919f2f44ceSEd Maste 
392435933ddSDimitry Andric       s.Printf("%-24s ", arch_strm.GetData());
393435933ddSDimitry Andric     } else {
394435933ddSDimitry Andric       s.Printf("%-10s %-24s ", platform->GetUserName(m_euid),
395435933ddSDimitry Andric                arch_strm.GetData());
396ac7ddfbfSEd Maste     }
397ac7ddfbfSEd Maste 
398435933ddSDimitry Andric     if (verbose || show_args) {
399ac7ddfbfSEd Maste       const uint32_t argc = m_arguments.GetArgumentCount();
400435933ddSDimitry Andric       if (argc > 0) {
401435933ddSDimitry Andric         for (uint32_t i = 0; i < argc; i++) {
402ac7ddfbfSEd Maste           if (i > 0)
403ac7ddfbfSEd Maste             s.PutChar(' ');
404ac7ddfbfSEd Maste           s.PutCString(m_arguments.GetArgumentAtIndex(i));
405ac7ddfbfSEd Maste         }
406ac7ddfbfSEd Maste       }
407435933ddSDimitry Andric     } else {
408ac7ddfbfSEd Maste       s.PutCString(GetName());
409ac7ddfbfSEd Maste     }
410ac7ddfbfSEd Maste 
411ac7ddfbfSEd Maste     s.EOL();
412ac7ddfbfSEd Maste   }
413ac7ddfbfSEd Maste }
414ac7ddfbfSEd Maste 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)4155517e702SDimitry Andric Status ProcessLaunchCommandOptions::SetOptionValue(
416435933ddSDimitry Andric     uint32_t option_idx, llvm::StringRef option_arg,
417435933ddSDimitry Andric     ExecutionContext *execution_context) {
4185517e702SDimitry Andric   Status error;
419ac7ddfbfSEd Maste   const int short_option = m_getopt_table[option_idx].val;
420ac7ddfbfSEd Maste 
421435933ddSDimitry Andric   switch (short_option) {
422ac7ddfbfSEd Maste   case 's': // Stop at program entry point
423ac7ddfbfSEd Maste     launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
424ac7ddfbfSEd Maste     break;
425ac7ddfbfSEd Maste 
426ac7ddfbfSEd Maste   case 'i': // STDIN for read only
427ac7ddfbfSEd Maste   {
4280127ef0fSEd Maste     FileAction action;
429*b5893f02SDimitry Andric     if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
430ac7ddfbfSEd Maste       launch_info.AppendFileAction(action);
431ac7ddfbfSEd Maste     break;
4320127ef0fSEd Maste   }
433ac7ddfbfSEd Maste 
434ac7ddfbfSEd Maste   case 'o': // Open STDOUT for write only
435ac7ddfbfSEd Maste   {
4360127ef0fSEd Maste     FileAction action;
437*b5893f02SDimitry Andric     if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
438ac7ddfbfSEd Maste       launch_info.AppendFileAction(action);
439ac7ddfbfSEd Maste     break;
4400127ef0fSEd Maste   }
441ac7ddfbfSEd Maste 
442ac7ddfbfSEd Maste   case 'e': // STDERR for write only
443ac7ddfbfSEd Maste   {
4440127ef0fSEd Maste     FileAction action;
445*b5893f02SDimitry Andric     if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
446ac7ddfbfSEd Maste       launch_info.AppendFileAction(action);
447ac7ddfbfSEd Maste     break;
4480127ef0fSEd Maste   }
449ac7ddfbfSEd Maste 
450ac7ddfbfSEd Maste   case 'p': // Process plug-in name
451ac7ddfbfSEd Maste     launch_info.SetProcessPluginName(option_arg);
452ac7ddfbfSEd Maste     break;
453ac7ddfbfSEd Maste 
454ac7ddfbfSEd Maste   case 'n': // Disable STDIO
455ac7ddfbfSEd Maste   {
4560127ef0fSEd Maste     FileAction action;
457*b5893f02SDimitry Andric     const FileSpec dev_null(FileSystem::DEV_NULL);
4581c3bbb01SEd Maste     if (action.Open(STDIN_FILENO, dev_null, true, false))
459ac7ddfbfSEd Maste       launch_info.AppendFileAction(action);
4601c3bbb01SEd Maste     if (action.Open(STDOUT_FILENO, dev_null, false, true))
461ac7ddfbfSEd Maste       launch_info.AppendFileAction(action);
4621c3bbb01SEd Maste     if (action.Open(STDERR_FILENO, dev_null, false, true))
463ac7ddfbfSEd Maste       launch_info.AppendFileAction(action);
464ac7ddfbfSEd Maste     break;
4650127ef0fSEd Maste   }
466ac7ddfbfSEd Maste 
467ac7ddfbfSEd Maste   case 'w':
468*b5893f02SDimitry Andric     launch_info.SetWorkingDirectory(FileSpec(option_arg));
469ac7ddfbfSEd Maste     break;
470ac7ddfbfSEd Maste 
471ac7ddfbfSEd Maste   case 't': // Open process in new terminal window
472ac7ddfbfSEd Maste     launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
473ac7ddfbfSEd Maste     break;
474ac7ddfbfSEd Maste 
475435933ddSDimitry Andric   case 'a': {
476435933ddSDimitry Andric     TargetSP target_sp =
477435933ddSDimitry Andric         execution_context ? execution_context->GetTargetSP() : TargetSP();
478435933ddSDimitry Andric     PlatformSP platform_sp =
479435933ddSDimitry Andric         target_sp ? target_sp->GetPlatform() : PlatformSP();
480acac075bSDimitry Andric     launch_info.GetArchitecture() =
481acac075bSDimitry Andric         Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
482435933ddSDimitry Andric   } break;
483ac7ddfbfSEd Maste 
4840127ef0fSEd Maste   case 'A': // Disable ASLR.
4850127ef0fSEd Maste   {
4860127ef0fSEd Maste     bool success;
487435933ddSDimitry Andric     const bool disable_aslr_arg =
4884ba319b5SDimitry Andric         OptionArgParser::ToBoolean(option_arg, true, &success);
4890127ef0fSEd Maste     if (success)
4900127ef0fSEd Maste       disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
4910127ef0fSEd Maste     else
492435933ddSDimitry Andric       error.SetErrorStringWithFormat(
493435933ddSDimitry Andric           "Invalid boolean value for disable-aslr option: '%s'",
494435933ddSDimitry Andric           option_arg.empty() ? "<null>" : option_arg.str().c_str());
495ac7ddfbfSEd Maste     break;
4960127ef0fSEd Maste   }
497ac7ddfbfSEd Maste 
4981c3bbb01SEd Maste   case 'X': // shell expand args.
4991c3bbb01SEd Maste   {
5001c3bbb01SEd Maste     bool success;
5014ba319b5SDimitry Andric     const bool expand_args =
5024ba319b5SDimitry Andric         OptionArgParser::ToBoolean(option_arg, true, &success);
5031c3bbb01SEd Maste     if (success)
5041c3bbb01SEd Maste       launch_info.SetShellExpandArguments(expand_args);
5051c3bbb01SEd Maste     else
506435933ddSDimitry Andric       error.SetErrorStringWithFormat(
507435933ddSDimitry Andric           "Invalid boolean value for shell-expand-args option: '%s'",
508435933ddSDimitry Andric           option_arg.empty() ? "<null>" : option_arg.str().c_str());
5091c3bbb01SEd Maste     break;
5101c3bbb01SEd Maste   }
5111c3bbb01SEd Maste 
512ac7ddfbfSEd Maste   case 'c':
513435933ddSDimitry Andric     if (!option_arg.empty())
514*b5893f02SDimitry Andric       launch_info.SetShell(FileSpec(option_arg));
515ac7ddfbfSEd Maste     else
5167aa51b79SEd Maste       launch_info.SetShell(HostInfo::GetDefaultShell());
517ac7ddfbfSEd Maste     break;
518ac7ddfbfSEd Maste 
519ac7ddfbfSEd Maste   case 'v':
5204ba319b5SDimitry Andric     launch_info.GetEnvironment().insert(option_arg);
521ac7ddfbfSEd Maste     break;
522ac7ddfbfSEd Maste 
523ac7ddfbfSEd Maste   default:
524435933ddSDimitry Andric     error.SetErrorStringWithFormat("unrecognized short option character '%c'",
525435933ddSDimitry Andric                                    short_option);
526ac7ddfbfSEd Maste     break;
527ac7ddfbfSEd Maste   }
528ac7ddfbfSEd Maste   return error;
529ac7ddfbfSEd Maste }
530ac7ddfbfSEd Maste 
531*b5893f02SDimitry Andric static constexpr OptionDefinition g_process_launch_options[] = {
532435933ddSDimitry Andric     {LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument,
533*b5893f02SDimitry Andric      nullptr, {}, 0, eArgTypeNone,
534435933ddSDimitry Andric      "Stop at the entry point of the program when launching a process."},
535435933ddSDimitry Andric     {LLDB_OPT_SET_ALL, false, "disable-aslr", 'A',
536*b5893f02SDimitry Andric      OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
537435933ddSDimitry Andric      "Set whether to disable address space layout randomization when launching "
538435933ddSDimitry Andric      "a process."},
539435933ddSDimitry Andric     {LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument,
540*b5893f02SDimitry Andric      nullptr, {}, 0, eArgTypePlugin,
541435933ddSDimitry Andric      "Name of the process plugin you want to use."},
542435933ddSDimitry Andric     {LLDB_OPT_SET_ALL, false, "working-dir", 'w',
543*b5893f02SDimitry Andric      OptionParser::eRequiredArgument, nullptr, {}, 0,
544435933ddSDimitry Andric      eArgTypeDirectoryName,
545435933ddSDimitry Andric      "Set the current working directory to <path> when running the inferior."},
546435933ddSDimitry Andric     {LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument,
547*b5893f02SDimitry Andric      nullptr, {}, 0, eArgTypeArchitecture,
548435933ddSDimitry Andric      "Set the architecture for the process to launch when ambiguous."},
549435933ddSDimitry Andric     {LLDB_OPT_SET_ALL, false, "environment", 'v',
550*b5893f02SDimitry Andric      OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone,
551435933ddSDimitry Andric      "Specify an environment variable name/value string (--environment "
552435933ddSDimitry Andric      "NAME=VALUE). Can be specified multiple times for subsequent environment "
553435933ddSDimitry Andric      "entries."},
554435933ddSDimitry Andric     {LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "shell", 'c',
555*b5893f02SDimitry Andric      OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeFilename,
556435933ddSDimitry Andric      "Run the process in a shell (not supported on all platforms)."},
557ac7ddfbfSEd Maste 
558435933ddSDimitry Andric     {LLDB_OPT_SET_1, false, "stdin", 'i', OptionParser::eRequiredArgument,
559*b5893f02SDimitry Andric      nullptr, {}, 0, eArgTypeFilename,
560435933ddSDimitry Andric      "Redirect stdin for the process to <filename>."},
561435933ddSDimitry Andric     {LLDB_OPT_SET_1, false, "stdout", 'o', OptionParser::eRequiredArgument,
562*b5893f02SDimitry Andric      nullptr, {}, 0, eArgTypeFilename,
563435933ddSDimitry Andric      "Redirect stdout for the process to <filename>."},
564435933ddSDimitry Andric     {LLDB_OPT_SET_1, false, "stderr", 'e', OptionParser::eRequiredArgument,
565*b5893f02SDimitry Andric      nullptr, {}, 0, eArgTypeFilename,
566435933ddSDimitry Andric      "Redirect stderr for the process to <filename>."},
567ac7ddfbfSEd Maste 
568435933ddSDimitry Andric     {LLDB_OPT_SET_2, false, "tty", 't', OptionParser::eNoArgument, nullptr,
569*b5893f02SDimitry Andric      {}, 0, eArgTypeNone,
570435933ddSDimitry Andric      "Start the process in a terminal (not supported on all platforms)."},
571ac7ddfbfSEd Maste 
572435933ddSDimitry Andric     {LLDB_OPT_SET_3, false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr,
573*b5893f02SDimitry Andric      {}, 0, eArgTypeNone,
574435933ddSDimitry Andric      "Do not set up for terminal I/O to go to running process."},
575435933ddSDimitry Andric     {LLDB_OPT_SET_4, false, "shell-expand-args", 'X',
576*b5893f02SDimitry Andric      OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
577435933ddSDimitry Andric      "Set whether to shell expand arguments to the process when launching."},
578ac7ddfbfSEd Maste };
579ac7ddfbfSEd Maste 
GetDefinitions()580435933ddSDimitry Andric llvm::ArrayRef<OptionDefinition> ProcessLaunchCommandOptions::GetDefinitions() {
581435933ddSDimitry Andric   return llvm::makeArrayRef(g_process_launch_options);
582435933ddSDimitry Andric }
583435933ddSDimitry Andric 
NameMatches(const char * process_name) const584435933ddSDimitry Andric bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
585f678e45dSDimitry Andric   if (m_name_match_type == NameMatch::Ignore || process_name == nullptr)
586ac7ddfbfSEd Maste     return true;
587ac7ddfbfSEd Maste   const char *match_name = m_match_info.GetName();
588ac7ddfbfSEd Maste   if (!match_name)
589ac7ddfbfSEd Maste     return true;
590ac7ddfbfSEd Maste 
591ac7ddfbfSEd Maste   return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
592ac7ddfbfSEd Maste }
593ac7ddfbfSEd Maste 
Matches(const ProcessInstanceInfo & proc_info) const594435933ddSDimitry Andric bool ProcessInstanceInfoMatch::Matches(
595435933ddSDimitry Andric     const ProcessInstanceInfo &proc_info) const {
596ac7ddfbfSEd Maste   if (!NameMatches(proc_info.GetName()))
597ac7ddfbfSEd Maste     return false;
598ac7ddfbfSEd Maste 
599ac7ddfbfSEd Maste   if (m_match_info.ProcessIDIsValid() &&
600ac7ddfbfSEd Maste       m_match_info.GetProcessID() != proc_info.GetProcessID())
601ac7ddfbfSEd Maste     return false;
602ac7ddfbfSEd Maste 
603ac7ddfbfSEd Maste   if (m_match_info.ParentProcessIDIsValid() &&
604ac7ddfbfSEd Maste       m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
605ac7ddfbfSEd Maste     return false;
606ac7ddfbfSEd Maste 
607ac7ddfbfSEd Maste   if (m_match_info.UserIDIsValid() &&
608ac7ddfbfSEd Maste       m_match_info.GetUserID() != proc_info.GetUserID())
609ac7ddfbfSEd Maste     return false;
610ac7ddfbfSEd Maste 
611ac7ddfbfSEd Maste   if (m_match_info.GroupIDIsValid() &&
612ac7ddfbfSEd Maste       m_match_info.GetGroupID() != proc_info.GetGroupID())
613ac7ddfbfSEd Maste     return false;
614ac7ddfbfSEd Maste 
615ac7ddfbfSEd Maste   if (m_match_info.EffectiveUserIDIsValid() &&
616ac7ddfbfSEd Maste       m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())
617ac7ddfbfSEd Maste     return false;
618ac7ddfbfSEd Maste 
619ac7ddfbfSEd Maste   if (m_match_info.EffectiveGroupIDIsValid() &&
620ac7ddfbfSEd Maste       m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
621ac7ddfbfSEd Maste     return false;
622ac7ddfbfSEd Maste 
623ac7ddfbfSEd Maste   if (m_match_info.GetArchitecture().IsValid() &&
624435933ddSDimitry Andric       !m_match_info.GetArchitecture().IsCompatibleMatch(
625435933ddSDimitry Andric           proc_info.GetArchitecture()))
626ac7ddfbfSEd Maste     return false;
627ac7ddfbfSEd Maste   return true;
628ac7ddfbfSEd Maste }
629ac7ddfbfSEd Maste 
MatchAllProcesses() const630435933ddSDimitry Andric bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
631f678e45dSDimitry Andric   if (m_name_match_type != NameMatch::Ignore)
632ac7ddfbfSEd Maste     return false;
633ac7ddfbfSEd Maste 
634ac7ddfbfSEd Maste   if (m_match_info.ProcessIDIsValid())
635ac7ddfbfSEd Maste     return false;
636ac7ddfbfSEd Maste 
637ac7ddfbfSEd Maste   if (m_match_info.ParentProcessIDIsValid())
638ac7ddfbfSEd Maste     return false;
639ac7ddfbfSEd Maste 
640ac7ddfbfSEd Maste   if (m_match_info.UserIDIsValid())
641ac7ddfbfSEd Maste     return false;
642ac7ddfbfSEd Maste 
643ac7ddfbfSEd Maste   if (m_match_info.GroupIDIsValid())
644ac7ddfbfSEd Maste     return false;
645ac7ddfbfSEd Maste 
646ac7ddfbfSEd Maste   if (m_match_info.EffectiveUserIDIsValid())
647ac7ddfbfSEd Maste     return false;
648ac7ddfbfSEd Maste 
649ac7ddfbfSEd Maste   if (m_match_info.EffectiveGroupIDIsValid())
650ac7ddfbfSEd Maste     return false;
651ac7ddfbfSEd Maste 
652ac7ddfbfSEd Maste   if (m_match_info.GetArchitecture().IsValid())
653ac7ddfbfSEd Maste     return false;
654ac7ddfbfSEd Maste 
655ac7ddfbfSEd Maste   if (m_match_all_users)
656ac7ddfbfSEd Maste     return false;
657ac7ddfbfSEd Maste 
658ac7ddfbfSEd Maste   return true;
659ac7ddfbfSEd Maste }
660ac7ddfbfSEd Maste 
Clear()661435933ddSDimitry Andric void ProcessInstanceInfoMatch::Clear() {
662ac7ddfbfSEd Maste   m_match_info.Clear();
663f678e45dSDimitry Andric   m_name_match_type = NameMatch::Ignore;
664ac7ddfbfSEd Maste   m_match_all_users = false;
665ac7ddfbfSEd Maste }
666ac7ddfbfSEd Maste 
FindPlugin(lldb::TargetSP target_sp,llvm::StringRef plugin_name,ListenerSP listener_sp,const FileSpec * crash_file_path)667435933ddSDimitry Andric ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
668435933ddSDimitry Andric                               llvm::StringRef plugin_name,
669435933ddSDimitry Andric                               ListenerSP listener_sp,
670435933ddSDimitry Andric                               const FileSpec *crash_file_path) {
671ac7ddfbfSEd Maste   static uint32_t g_process_unique_id = 0;
672ac7ddfbfSEd Maste 
673ac7ddfbfSEd Maste   ProcessSP process_sp;
6744bb0738eSEd Maste   ProcessCreateInstance create_callback = nullptr;
675435933ddSDimitry Andric   if (!plugin_name.empty()) {
676ac7ddfbfSEd Maste     ConstString const_plugin_name(plugin_name);
677435933ddSDimitry Andric     create_callback =
678435933ddSDimitry Andric         PluginManager::GetProcessCreateCallbackForPluginName(const_plugin_name);
679435933ddSDimitry Andric     if (create_callback) {
6804bb0738eSEd Maste       process_sp = create_callback(target_sp, listener_sp, crash_file_path);
681435933ddSDimitry Andric       if (process_sp) {
682435933ddSDimitry Andric         if (process_sp->CanDebug(target_sp, true)) {
683ac7ddfbfSEd Maste           process_sp->m_process_unique_id = ++g_process_unique_id;
684435933ddSDimitry Andric         } else
685ac7ddfbfSEd Maste           process_sp.reset();
686ac7ddfbfSEd Maste       }
687ac7ddfbfSEd Maste     }
688435933ddSDimitry Andric   } else {
689435933ddSDimitry Andric     for (uint32_t idx = 0;
690435933ddSDimitry Andric          (create_callback =
691435933ddSDimitry Andric               PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr;
692435933ddSDimitry Andric          ++idx) {
6934bb0738eSEd Maste       process_sp = create_callback(target_sp, listener_sp, crash_file_path);
694435933ddSDimitry Andric       if (process_sp) {
695435933ddSDimitry Andric         if (process_sp->CanDebug(target_sp, false)) {
696ac7ddfbfSEd Maste           process_sp->m_process_unique_id = ++g_process_unique_id;
697ac7ddfbfSEd Maste           break;
698435933ddSDimitry Andric         } else
699ac7ddfbfSEd Maste           process_sp.reset();
700ac7ddfbfSEd Maste       }
701ac7ddfbfSEd Maste     }
702ac7ddfbfSEd Maste   }
703ac7ddfbfSEd Maste   return process_sp;
704ac7ddfbfSEd Maste }
705ac7ddfbfSEd Maste 
GetStaticBroadcasterClass()706435933ddSDimitry Andric ConstString &Process::GetStaticBroadcasterClass() {
707ac7ddfbfSEd Maste   static ConstString class_name("lldb.process");
708ac7ddfbfSEd Maste   return class_name;
709ac7ddfbfSEd Maste }
710ac7ddfbfSEd Maste 
Process(lldb::TargetSP target_sp,ListenerSP listener_sp)711435933ddSDimitry Andric Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp)
712435933ddSDimitry Andric     : Process(target_sp, listener_sp,
713435933ddSDimitry Andric               UnixSignals::Create(HostInfo::GetArchitecture())) {
7140127ef0fSEd Maste   // This constructor just delegates to the full Process constructor,
7150127ef0fSEd Maste   // defaulting to using the Host's UnixSignals.
7160127ef0fSEd Maste }
7170127ef0fSEd Maste 
Process(lldb::TargetSP target_sp,ListenerSP listener_sp,const UnixSignalsSP & unix_signals_sp)718435933ddSDimitry Andric Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
719435933ddSDimitry Andric                  const UnixSignalsSP &unix_signals_sp)
720435933ddSDimitry Andric     : ProcessProperties(this), UserID(LLDB_INVALID_PROCESS_ID),
721435933ddSDimitry Andric       Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()),
722435933ddSDimitry Andric                   Process::GetStaticBroadcasterClass().AsCString()),
7234ba319b5SDimitry Andric       m_target_wp(target_sp), m_public_state(eStateUnloaded),
724ac7ddfbfSEd Maste       m_private_state(eStateUnloaded),
725435933ddSDimitry Andric       m_private_state_broadcaster(nullptr,
726435933ddSDimitry Andric                                   "lldb.process.internal_state_broadcaster"),
727435933ddSDimitry Andric       m_private_state_control_broadcaster(
728435933ddSDimitry Andric           nullptr, "lldb.process.internal_state_control_broadcaster"),
729435933ddSDimitry Andric       m_private_state_listener_sp(
730435933ddSDimitry Andric           Listener::MakeListener("lldb.process.internal_state_listener")),
731435933ddSDimitry Andric       m_mod_id(), m_process_unique_id(0), m_thread_index_id(0),
732435933ddSDimitry Andric       m_thread_id_to_index_id_map(), m_exit_status(-1), m_exit_string(),
733435933ddSDimitry Andric       m_exit_status_mutex(), m_thread_mutex(), m_thread_list_real(this),
734435933ddSDimitry Andric       m_thread_list(this), m_extended_thread_list(this),
735435933ddSDimitry Andric       m_extended_thread_stop_id(0), m_queue_list(this), m_queue_list_stop_id(0),
736435933ddSDimitry Andric       m_notifications(), m_image_tokens(), m_listener_sp(listener_sp),
737435933ddSDimitry Andric       m_breakpoint_site_list(), m_dynamic_checkers_ap(),
738435933ddSDimitry Andric       m_unix_signals_sp(unix_signals_sp), m_abi_sp(), m_process_input_reader(),
739435933ddSDimitry Andric       m_stdio_communication("process.stdio"), m_stdio_communication_mutex(),
740435933ddSDimitry Andric       m_stdin_forward(false), m_stdout_data(), m_stderr_data(),
741435933ddSDimitry Andric       m_profile_data_comm_mutex(), m_profile_data(), m_iohandler_sync(0),
742435933ddSDimitry Andric       m_memory_cache(*this), m_allocated_memory_cache(*this),
743435933ddSDimitry Andric       m_should_detach(false), m_next_event_action_ap(), m_public_run_lock(),
744acac075bSDimitry Andric       m_private_run_lock(), m_finalizing(false), m_finalize_called(false),
745435933ddSDimitry Andric       m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
746435933ddSDimitry Andric       m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
747435933ddSDimitry Andric       m_can_interpret_function_calls(false), m_warnings_issued(),
748435933ddSDimitry Andric       m_run_thread_plan_lock(), m_can_jit(eCanJITDontKnow) {
749ac7ddfbfSEd Maste   CheckInWithManager();
750ac7ddfbfSEd Maste 
751ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
752ac7ddfbfSEd Maste   if (log)
7530127ef0fSEd Maste     log->Printf("%p Process::Process()", static_cast<void *>(this));
7540127ef0fSEd Maste 
7550127ef0fSEd Maste   if (!m_unix_signals_sp)
756b91a7dfcSDimitry Andric     m_unix_signals_sp = std::make_shared<UnixSignals>();
757ac7ddfbfSEd Maste 
758ac7ddfbfSEd Maste   SetEventName(eBroadcastBitStateChanged, "state-changed");
759ac7ddfbfSEd Maste   SetEventName(eBroadcastBitInterrupt, "interrupt");
760ac7ddfbfSEd Maste   SetEventName(eBroadcastBitSTDOUT, "stdout-available");
761ac7ddfbfSEd Maste   SetEventName(eBroadcastBitSTDERR, "stderr-available");
762ac7ddfbfSEd Maste   SetEventName(eBroadcastBitProfileData, "profile-data-available");
763435933ddSDimitry Andric   SetEventName(eBroadcastBitStructuredData, "structured-data-available");
764ac7ddfbfSEd Maste 
765435933ddSDimitry Andric   m_private_state_control_broadcaster.SetEventName(
766435933ddSDimitry Andric       eBroadcastInternalStateControlStop, "control-stop");
767435933ddSDimitry Andric   m_private_state_control_broadcaster.SetEventName(
768435933ddSDimitry Andric       eBroadcastInternalStateControlPause, "control-pause");
769435933ddSDimitry Andric   m_private_state_control_broadcaster.SetEventName(
770435933ddSDimitry Andric       eBroadcastInternalStateControlResume, "control-resume");
771ac7ddfbfSEd Maste 
772435933ddSDimitry Andric   m_listener_sp->StartListeningForEvents(
773435933ddSDimitry Andric       this, eBroadcastBitStateChanged | eBroadcastBitInterrupt |
7744bb0738eSEd Maste                 eBroadcastBitSTDOUT | eBroadcastBitSTDERR |
775435933ddSDimitry Andric                 eBroadcastBitProfileData | eBroadcastBitStructuredData);
776ac7ddfbfSEd Maste 
777435933ddSDimitry Andric   m_private_state_listener_sp->StartListeningForEvents(
778435933ddSDimitry Andric       &m_private_state_broadcaster,
7794bb0738eSEd Maste       eBroadcastBitStateChanged | eBroadcastBitInterrupt);
780ac7ddfbfSEd Maste 
7814bb0738eSEd Maste   m_private_state_listener_sp->StartListeningForEvents(
782435933ddSDimitry Andric       &m_private_state_control_broadcaster,
783435933ddSDimitry Andric       eBroadcastInternalStateControlStop | eBroadcastInternalStateControlPause |
784ac7ddfbfSEd Maste           eBroadcastInternalStateControlResume);
7850127ef0fSEd Maste   // We need something valid here, even if just the default UnixSignalsSP.
7860127ef0fSEd Maste   assert(m_unix_signals_sp && "null m_unix_signals_sp after initialization");
7879f2f44ceSEd Maste 
7889f2f44ceSEd Maste   // Allow the platform to override the default cache line size
789435933ddSDimitry Andric   OptionValueSP value_sp =
790435933ddSDimitry Andric       m_collection_sp
791435933ddSDimitry Andric           ->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)
792435933ddSDimitry Andric           ->GetValue();
793435933ddSDimitry Andric   uint32_t platform_cache_line_size =
794435933ddSDimitry Andric       target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize();
7959f2f44ceSEd Maste   if (!value_sp->OptionWasSet() && platform_cache_line_size != 0)
7969f2f44ceSEd Maste     value_sp->SetUInt64Value(platform_cache_line_size);
797ac7ddfbfSEd Maste }
798ac7ddfbfSEd Maste 
~Process()799435933ddSDimitry Andric Process::~Process() {
800ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
801ac7ddfbfSEd Maste   if (log)
8020127ef0fSEd Maste     log->Printf("%p Process::~Process()", static_cast<void *>(this));
803ac7ddfbfSEd Maste   StopPrivateStateThread();
8047aa51b79SEd Maste 
8057aa51b79SEd Maste   // ThreadList::Clear() will try to acquire this process's mutex, so
8064ba319b5SDimitry Andric   // explicitly clear the thread list here to ensure that the mutex is not
8074ba319b5SDimitry Andric   // destroyed before the thread list.
8087aa51b79SEd Maste   m_thread_list.Clear();
809ac7ddfbfSEd Maste }
810ac7ddfbfSEd Maste 
GetGlobalProperties()811435933ddSDimitry Andric const ProcessPropertiesSP &Process::GetGlobalProperties() {
8124bb0738eSEd Maste   // NOTE: intentional leak so we don't crash if global destructor chain gets
8134bb0738eSEd Maste   // called as other threads still use the result of this function
814435933ddSDimitry Andric   static ProcessPropertiesSP *g_settings_sp_ptr =
815435933ddSDimitry Andric       new ProcessPropertiesSP(new ProcessProperties(nullptr));
8164bb0738eSEd Maste   return *g_settings_sp_ptr;
817ac7ddfbfSEd Maste }
818ac7ddfbfSEd Maste 
Finalize()819435933ddSDimitry Andric void Process::Finalize() {
8201c3bbb01SEd Maste   m_finalizing = true;
8211c3bbb01SEd Maste 
8221c3bbb01SEd Maste   // Destroy this process if needed
823435933ddSDimitry Andric   switch (GetPrivateState()) {
824ac7ddfbfSEd Maste   case eStateConnected:
825ac7ddfbfSEd Maste   case eStateAttaching:
826ac7ddfbfSEd Maste   case eStateLaunching:
827ac7ddfbfSEd Maste   case eStateStopped:
828ac7ddfbfSEd Maste   case eStateRunning:
829ac7ddfbfSEd Maste   case eStateStepping:
830ac7ddfbfSEd Maste   case eStateCrashed:
831ac7ddfbfSEd Maste   case eStateSuspended:
8321c3bbb01SEd Maste     Destroy(false);
833ac7ddfbfSEd Maste     break;
834ac7ddfbfSEd Maste 
835ac7ddfbfSEd Maste   case eStateInvalid:
836ac7ddfbfSEd Maste   case eStateUnloaded:
837ac7ddfbfSEd Maste   case eStateDetached:
838ac7ddfbfSEd Maste   case eStateExited:
839ac7ddfbfSEd Maste     break;
840ac7ddfbfSEd Maste   }
841ac7ddfbfSEd Maste 
842ac7ddfbfSEd Maste   // Clear our broadcaster before we proceed with destroying
843ac7ddfbfSEd Maste   Broadcaster::Clear();
844ac7ddfbfSEd Maste 
8454ba319b5SDimitry Andric   // Do any cleanup needed prior to being destructed... Subclasses that
8464ba319b5SDimitry Andric   // override this method should call this superclass method as well.
847ac7ddfbfSEd Maste 
848435933ddSDimitry Andric   // We need to destroy the loader before the derived Process class gets
8494ba319b5SDimitry Andric   // destroyed since it is very likely that undoing the loader will require
8504ba319b5SDimitry Andric   // access to the real process.
851ac7ddfbfSEd Maste   m_dynamic_checkers_ap.reset();
852ac7ddfbfSEd Maste   m_abi_sp.reset();
853ac7ddfbfSEd Maste   m_os_ap.reset();
85435617911SEd Maste   m_system_runtime_ap.reset();
855ac7ddfbfSEd Maste   m_dyld_ap.reset();
8560127ef0fSEd Maste   m_jit_loaders_ap.reset();
857ac7ddfbfSEd Maste   m_thread_list_real.Destroy();
858ac7ddfbfSEd Maste   m_thread_list.Destroy();
859b952cd58SEd Maste   m_extended_thread_list.Destroy();
86012b93ac6SEd Maste   m_queue_list.Clear();
86112b93ac6SEd Maste   m_queue_list_stop_id = 0;
862ac7ddfbfSEd Maste   std::vector<Notifications> empty_notifications;
863ac7ddfbfSEd Maste   m_notifications.swap(empty_notifications);
864ac7ddfbfSEd Maste   m_image_tokens.clear();
865ac7ddfbfSEd Maste   m_memory_cache.Clear();
866ac7ddfbfSEd Maste   m_allocated_memory_cache.Clear();
867ac7ddfbfSEd Maste   m_language_runtimes.clear();
8687aa51b79SEd Maste   m_instrumentation_runtimes.clear();
869ac7ddfbfSEd Maste   m_next_event_action_ap.reset();
8704ba319b5SDimitry Andric   // Clear the last natural stop ID since it has a strong reference to this
8714ba319b5SDimitry Andric   // process
8721c3bbb01SEd Maste   m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
873ac7ddfbfSEd Maste   //#ifdef LLDB_CONFIGURATION_DEBUG
874ac7ddfbfSEd Maste   //    StreamFile s(stdout, false);
875ac7ddfbfSEd Maste   //    EventSP event_sp;
8764bb0738eSEd Maste   //    while (m_private_state_listener_sp->GetNextEvent(event_sp))
877ac7ddfbfSEd Maste   //    {
878ac7ddfbfSEd Maste   //        event_sp->Dump (&s);
879ac7ddfbfSEd Maste   //        s.EOL();
880ac7ddfbfSEd Maste   //    }
881ac7ddfbfSEd Maste   //#endif
882ac7ddfbfSEd Maste   // We have to be very careful here as the m_private_state_listener might
883ac7ddfbfSEd Maste   // contain events that have ProcessSP values in them which can keep this
884ac7ddfbfSEd Maste   // process around forever. These events need to be cleared out.
8854bb0738eSEd Maste   m_private_state_listener_sp->Clear();
886ac7ddfbfSEd Maste   m_public_run_lock.TrySetRunning(); // This will do nothing if already locked
887ac7ddfbfSEd Maste   m_public_run_lock.SetStopped();
888ac7ddfbfSEd Maste   m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
889ac7ddfbfSEd Maste   m_private_run_lock.SetStopped();
890435933ddSDimitry Andric   m_structured_data_plugin_map.clear();
891ac7ddfbfSEd Maste   m_finalize_called = true;
892ac7ddfbfSEd Maste }
893ac7ddfbfSEd Maste 
RegisterNotificationCallbacks(const Notifications & callbacks)894435933ddSDimitry Andric void Process::RegisterNotificationCallbacks(const Notifications &callbacks) {
895ac7ddfbfSEd Maste   m_notifications.push_back(callbacks);
8964bb0738eSEd Maste   if (callbacks.initialize != nullptr)
897ac7ddfbfSEd Maste     callbacks.initialize(callbacks.baton, this);
898ac7ddfbfSEd Maste }
899ac7ddfbfSEd Maste 
UnregisterNotificationCallbacks(const Notifications & callbacks)900435933ddSDimitry Andric bool Process::UnregisterNotificationCallbacks(const Notifications &callbacks) {
901ac7ddfbfSEd Maste   std::vector<Notifications>::iterator pos, end = m_notifications.end();
902435933ddSDimitry Andric   for (pos = m_notifications.begin(); pos != end; ++pos) {
903ac7ddfbfSEd Maste     if (pos->baton == callbacks.baton &&
904ac7ddfbfSEd Maste         pos->initialize == callbacks.initialize &&
905435933ddSDimitry Andric         pos->process_state_changed == callbacks.process_state_changed) {
906ac7ddfbfSEd Maste       m_notifications.erase(pos);
907ac7ddfbfSEd Maste       return true;
908ac7ddfbfSEd Maste     }
909ac7ddfbfSEd Maste   }
910ac7ddfbfSEd Maste   return false;
911ac7ddfbfSEd Maste }
912ac7ddfbfSEd Maste 
SynchronouslyNotifyStateChanged(StateType state)913435933ddSDimitry Andric void Process::SynchronouslyNotifyStateChanged(StateType state) {
914435933ddSDimitry Andric   std::vector<Notifications>::iterator notification_pos,
915435933ddSDimitry Andric       notification_end = m_notifications.end();
916435933ddSDimitry Andric   for (notification_pos = m_notifications.begin();
917435933ddSDimitry Andric        notification_pos != notification_end; ++notification_pos) {
918ac7ddfbfSEd Maste     if (notification_pos->process_state_changed)
919435933ddSDimitry Andric       notification_pos->process_state_changed(notification_pos->baton, this,
920435933ddSDimitry Andric                                               state);
921ac7ddfbfSEd Maste   }
922ac7ddfbfSEd Maste }
923ac7ddfbfSEd Maste 
924435933ddSDimitry Andric // FIXME: We need to do some work on events before the general Listener sees
925435933ddSDimitry Andric // them.
926435933ddSDimitry Andric // For instance if we are continuing from a breakpoint, we need to ensure that
9274ba319b5SDimitry Andric // we do the little "insert real insn, step & stop" trick.  But we can't do
9284ba319b5SDimitry Andric // that when the event is delivered by the broadcaster - since that is done on
9294ba319b5SDimitry Andric // the thread that is waiting for new events, so if we needed more than one
9304ba319b5SDimitry Andric // event for our handling, we would stall.  So instead we do it when we fetch
9314ba319b5SDimitry Andric // the event off of the queue.
932ac7ddfbfSEd Maste //
933ac7ddfbfSEd Maste 
GetNextEvent(EventSP & event_sp)934435933ddSDimitry Andric StateType Process::GetNextEvent(EventSP &event_sp) {
935ac7ddfbfSEd Maste   StateType state = eStateInvalid;
936ac7ddfbfSEd Maste 
937435933ddSDimitry Andric   if (m_listener_sp->GetEventForBroadcaster(this, event_sp,
938435933ddSDimitry Andric                                             std::chrono::seconds(0)) &&
939435933ddSDimitry Andric       event_sp)
940ac7ddfbfSEd Maste     state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
941ac7ddfbfSEd Maste 
942ac7ddfbfSEd Maste   return state;
943ac7ddfbfSEd Maste }
944ac7ddfbfSEd Maste 
SyncIOHandler(uint32_t iohandler_id,const Timeout<std::micro> & timeout)9454ba319b5SDimitry Andric void Process::SyncIOHandler(uint32_t iohandler_id,
9464ba319b5SDimitry Andric                             const Timeout<std::micro> &timeout) {
947435933ddSDimitry Andric   // don't sync (potentially context switch) in case where there is no process
948435933ddSDimitry Andric   // IO
9491c3bbb01SEd Maste   if (!m_process_input_reader)
9501c3bbb01SEd Maste     return;
9511c3bbb01SEd Maste 
9524ba319b5SDimitry Andric   auto Result = m_iohandler_sync.WaitForValueNotEqualTo(iohandler_id, timeout);
9530127ef0fSEd Maste 
9540127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
9554ba319b5SDimitry Andric   if (Result) {
9564ba319b5SDimitry Andric     LLDB_LOG(
9574ba319b5SDimitry Andric         log,
9584ba319b5SDimitry Andric         "waited from m_iohandler_sync to change from {0}. New value is {1}.",
9594ba319b5SDimitry Andric         iohandler_id, *Result);
9604ba319b5SDimitry Andric   } else {
9614ba319b5SDimitry Andric     LLDB_LOG(log, "timed out waiting for m_iohandler_sync to change from {0}.",
9624ba319b5SDimitry Andric              iohandler_id);
9634ba319b5SDimitry Andric   }
9640127ef0fSEd Maste }
965ac7ddfbfSEd Maste 
WaitForProcessToStop(const Timeout<std::micro> & timeout,EventSP * event_sp_ptr,bool wait_always,ListenerSP hijack_listener_sp,Stream * stream,bool use_run_lock)966435933ddSDimitry Andric StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout,
967435933ddSDimitry Andric                                         EventSP *event_sp_ptr, bool wait_always,
9684bb0738eSEd Maste                                         ListenerSP hijack_listener_sp,
969435933ddSDimitry Andric                                         Stream *stream, bool use_run_lock) {
970435933ddSDimitry Andric   // We can't just wait for a "stopped" event, because the stopped event may
9714ba319b5SDimitry Andric   // have restarted the target. We have to actually check each event, and in
9724ba319b5SDimitry Andric   // the case of a stopped event check the restarted flag on the event.
973ac7ddfbfSEd Maste   if (event_sp_ptr)
974ac7ddfbfSEd Maste     event_sp_ptr->reset();
975ac7ddfbfSEd Maste   StateType state = GetState();
9764ba319b5SDimitry Andric   // If we are exited or detached, we won't ever get back to any other valid
9774ba319b5SDimitry Andric   // state...
978ac7ddfbfSEd Maste   if (state == eStateDetached || state == eStateExited)
979ac7ddfbfSEd Maste     return state;
980ac7ddfbfSEd Maste 
98135617911SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
982f678e45dSDimitry Andric   LLDB_LOG(log, "timeout = {0}", timeout);
98335617911SEd Maste 
984435933ddSDimitry Andric   if (!wait_always && StateIsStoppedState(state, true) &&
985435933ddSDimitry Andric       StateIsStoppedState(GetPrivateState(), true)) {
98635617911SEd Maste     if (log)
987435933ddSDimitry Andric       log->Printf("Process::%s returning without waiting for events; process "
988435933ddSDimitry Andric                   "private and public states are already 'stopped'.",
98935617911SEd Maste                   __FUNCTION__);
9901c3bbb01SEd Maste     // We need to toggle the run lock as this won't get done in
9911c3bbb01SEd Maste     // SetPublicState() if the process is hijacked.
9924bb0738eSEd Maste     if (hijack_listener_sp && use_run_lock)
9931c3bbb01SEd Maste       m_public_run_lock.SetStopped();
99435617911SEd Maste     return state;
99535617911SEd Maste   }
99635617911SEd Maste 
997435933ddSDimitry Andric   while (state != eStateInvalid) {
998ac7ddfbfSEd Maste     EventSP event_sp;
999435933ddSDimitry Andric     state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp);
1000ac7ddfbfSEd Maste     if (event_sp_ptr && event_sp)
1001ac7ddfbfSEd Maste       *event_sp_ptr = event_sp;
1002ac7ddfbfSEd Maste 
10034bb0738eSEd Maste     bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr);
1004435933ddSDimitry Andric     Process::HandleProcessStateChangedEvent(event_sp, stream,
1005435933ddSDimitry Andric                                             pop_process_io_handler);
10067aa51b79SEd Maste 
1007435933ddSDimitry Andric     switch (state) {
1008ac7ddfbfSEd Maste     case eStateCrashed:
1009ac7ddfbfSEd Maste     case eStateDetached:
1010ac7ddfbfSEd Maste     case eStateExited:
1011ac7ddfbfSEd Maste     case eStateUnloaded:
101212b93ac6SEd Maste       // We need to toggle the run lock as this won't get done in
101312b93ac6SEd Maste       // SetPublicState() if the process is hijacked.
10144bb0738eSEd Maste       if (hijack_listener_sp && use_run_lock)
101512b93ac6SEd Maste         m_public_run_lock.SetStopped();
1016ac7ddfbfSEd Maste       return state;
1017ac7ddfbfSEd Maste     case eStateStopped:
1018ac7ddfbfSEd Maste       if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
1019ac7ddfbfSEd Maste         continue;
1020435933ddSDimitry Andric       else {
102112b93ac6SEd Maste         // We need to toggle the run lock as this won't get done in
102212b93ac6SEd Maste         // SetPublicState() if the process is hijacked.
10234bb0738eSEd Maste         if (hijack_listener_sp && use_run_lock)
102412b93ac6SEd Maste           m_public_run_lock.SetStopped();
1025ac7ddfbfSEd Maste         return state;
102612b93ac6SEd Maste       }
1027ac7ddfbfSEd Maste     default:
1028ac7ddfbfSEd Maste       continue;
1029ac7ddfbfSEd Maste     }
1030ac7ddfbfSEd Maste   }
1031ac7ddfbfSEd Maste   return state;
1032ac7ddfbfSEd Maste }
1033ac7ddfbfSEd Maste 
HandleProcessStateChangedEvent(const EventSP & event_sp,Stream * stream,bool & pop_process_io_handler)1034435933ddSDimitry Andric bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp,
10357aa51b79SEd Maste                                              Stream *stream,
1036435933ddSDimitry Andric                                              bool &pop_process_io_handler) {
10374bb0738eSEd Maste   const bool handle_pop = pop_process_io_handler;
10387aa51b79SEd Maste 
10397aa51b79SEd Maste   pop_process_io_handler = false;
1040435933ddSDimitry Andric   ProcessSP process_sp =
1041435933ddSDimitry Andric       Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
10427aa51b79SEd Maste 
10437aa51b79SEd Maste   if (!process_sp)
10447aa51b79SEd Maste     return false;
10457aa51b79SEd Maste 
1046435933ddSDimitry Andric   StateType event_state =
1047435933ddSDimitry Andric       Process::ProcessEventData::GetStateFromEvent(event_sp.get());
10487aa51b79SEd Maste   if (event_state == eStateInvalid)
10497aa51b79SEd Maste     return false;
10507aa51b79SEd Maste 
1051435933ddSDimitry Andric   switch (event_state) {
10527aa51b79SEd Maste   case eStateInvalid:
10537aa51b79SEd Maste   case eStateUnloaded:
10547aa51b79SEd Maste   case eStateAttaching:
10557aa51b79SEd Maste   case eStateLaunching:
10567aa51b79SEd Maste   case eStateStepping:
10577aa51b79SEd Maste   case eStateDetached:
10587aa51b79SEd Maste     if (stream)
1059435933ddSDimitry Andric       stream->Printf("Process %" PRIu64 " %s\n", process_sp->GetID(),
10607aa51b79SEd Maste                      StateAsCString(event_state));
10617aa51b79SEd Maste     if (event_state == eStateDetached)
10627aa51b79SEd Maste       pop_process_io_handler = true;
10637aa51b79SEd Maste     break;
10647aa51b79SEd Maste 
10657aa51b79SEd Maste   case eStateConnected:
10667aa51b79SEd Maste   case eStateRunning:
10677aa51b79SEd Maste     // Don't be chatty when we run...
10687aa51b79SEd Maste     break;
10697aa51b79SEd Maste 
10707aa51b79SEd Maste   case eStateExited:
10717aa51b79SEd Maste     if (stream)
10727aa51b79SEd Maste       process_sp->GetStatus(*stream);
10737aa51b79SEd Maste     pop_process_io_handler = true;
10747aa51b79SEd Maste     break;
10757aa51b79SEd Maste 
10767aa51b79SEd Maste   case eStateStopped:
10777aa51b79SEd Maste   case eStateCrashed:
10787aa51b79SEd Maste   case eStateSuspended:
10797aa51b79SEd Maste     // Make sure the program hasn't been auto-restarted:
1080435933ddSDimitry Andric     if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) {
1081435933ddSDimitry Andric       if (stream) {
1082435933ddSDimitry Andric         size_t num_reasons =
1083435933ddSDimitry Andric             Process::ProcessEventData::GetNumRestartedReasons(event_sp.get());
1084435933ddSDimitry Andric         if (num_reasons > 0) {
1085435933ddSDimitry Andric           // FIXME: Do we want to report this, or would that just be annoyingly
1086435933ddSDimitry Andric           // chatty?
1087435933ddSDimitry Andric           if (num_reasons == 1) {
1088435933ddSDimitry Andric             const char *reason =
1089435933ddSDimitry Andric                 Process::ProcessEventData::GetRestartedReasonAtIndex(
1090435933ddSDimitry Andric                     event_sp.get(), 0);
10917aa51b79SEd Maste             stream->Printf("Process %" PRIu64 " stopped and restarted: %s\n",
10927aa51b79SEd Maste                            process_sp->GetID(),
10937aa51b79SEd Maste                            reason ? reason : "<UNKNOWN REASON>");
1094435933ddSDimitry Andric           } else {
1095435933ddSDimitry Andric             stream->Printf("Process %" PRIu64
1096435933ddSDimitry Andric                            " stopped and restarted, reasons:\n",
10977aa51b79SEd Maste                            process_sp->GetID());
10987aa51b79SEd Maste 
1099435933ddSDimitry Andric             for (size_t i = 0; i < num_reasons; i++) {
1100435933ddSDimitry Andric               const char *reason =
1101435933ddSDimitry Andric                   Process::ProcessEventData::GetRestartedReasonAtIndex(
1102435933ddSDimitry Andric                       event_sp.get(), i);
11037aa51b79SEd Maste               stream->Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>");
11047aa51b79SEd Maste             }
11057aa51b79SEd Maste           }
11067aa51b79SEd Maste         }
11077aa51b79SEd Maste       }
1108435933ddSDimitry Andric     } else {
1109435933ddSDimitry Andric       StopInfoSP curr_thread_stop_info_sp;
1110435933ddSDimitry Andric       // Lock the thread list so it doesn't change on us, this is the scope for
1111435933ddSDimitry Andric       // the locker:
11127aa51b79SEd Maste       {
11137aa51b79SEd Maste         ThreadList &thread_list = process_sp->GetThreadList();
11144bb0738eSEd Maste         std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
11157aa51b79SEd Maste 
11167aa51b79SEd Maste         ThreadSP curr_thread(thread_list.GetSelectedThread());
11177aa51b79SEd Maste         ThreadSP thread;
11187aa51b79SEd Maste         StopReason curr_thread_stop_reason = eStopReasonInvalid;
1119435933ddSDimitry Andric         if (curr_thread) {
11207aa51b79SEd Maste           curr_thread_stop_reason = curr_thread->GetStopReason();
1121435933ddSDimitry Andric           curr_thread_stop_info_sp = curr_thread->GetStopInfo();
1122435933ddSDimitry Andric         }
1123435933ddSDimitry Andric         if (!curr_thread || !curr_thread->IsValid() ||
11247aa51b79SEd Maste             curr_thread_stop_reason == eStopReasonInvalid ||
1125435933ddSDimitry Andric             curr_thread_stop_reason == eStopReasonNone) {
1126435933ddSDimitry Andric           // Prefer a thread that has just completed its plan over another
1127435933ddSDimitry Andric           // thread as current thread.
11287aa51b79SEd Maste           ThreadSP plan_thread;
11297aa51b79SEd Maste           ThreadSP other_thread;
1130b91a7dfcSDimitry Andric 
11317aa51b79SEd Maste           const size_t num_threads = thread_list.GetSize();
11327aa51b79SEd Maste           size_t i;
1133435933ddSDimitry Andric           for (i = 0; i < num_threads; ++i) {
11347aa51b79SEd Maste             thread = thread_list.GetThreadAtIndex(i);
11357aa51b79SEd Maste             StopReason thread_stop_reason = thread->GetStopReason();
1136435933ddSDimitry Andric             switch (thread_stop_reason) {
11377aa51b79SEd Maste             case eStopReasonInvalid:
11387aa51b79SEd Maste             case eStopReasonNone:
11397aa51b79SEd Maste               break;
11407aa51b79SEd Maste 
1141435933ddSDimitry Andric             case eStopReasonSignal: {
1142435933ddSDimitry Andric               // Don't select a signal thread if we weren't going to stop at
11434ba319b5SDimitry Andric               // that signal.  We have to have had another reason for stopping
11444ba319b5SDimitry Andric               // here, and the user doesn't want to see this thread.
1145b91a7dfcSDimitry Andric               uint64_t signo = thread->GetStopInfo()->GetValue();
1146435933ddSDimitry Andric               if (process_sp->GetUnixSignals()->GetShouldStop(signo)) {
1147b91a7dfcSDimitry Andric                 if (!other_thread)
1148b91a7dfcSDimitry Andric                   other_thread = thread;
1149b91a7dfcSDimitry Andric               }
1150b91a7dfcSDimitry Andric               break;
1151b91a7dfcSDimitry Andric             }
11527aa51b79SEd Maste             case eStopReasonTrace:
11537aa51b79SEd Maste             case eStopReasonBreakpoint:
11547aa51b79SEd Maste             case eStopReasonWatchpoint:
11557aa51b79SEd Maste             case eStopReasonException:
11567aa51b79SEd Maste             case eStopReasonExec:
11577aa51b79SEd Maste             case eStopReasonThreadExiting:
11587aa51b79SEd Maste             case eStopReasonInstrumentation:
11597aa51b79SEd Maste               if (!other_thread)
11607aa51b79SEd Maste                 other_thread = thread;
11617aa51b79SEd Maste               break;
11627aa51b79SEd Maste             case eStopReasonPlanComplete:
11637aa51b79SEd Maste               if (!plan_thread)
11647aa51b79SEd Maste                 plan_thread = thread;
11657aa51b79SEd Maste               break;
11667aa51b79SEd Maste             }
11677aa51b79SEd Maste           }
11687aa51b79SEd Maste           if (plan_thread)
11697aa51b79SEd Maste             thread_list.SetSelectedThreadByID(plan_thread->GetID());
11707aa51b79SEd Maste           else if (other_thread)
11717aa51b79SEd Maste             thread_list.SetSelectedThreadByID(other_thread->GetID());
1172435933ddSDimitry Andric           else {
11737aa51b79SEd Maste             if (curr_thread && curr_thread->IsValid())
11747aa51b79SEd Maste               thread = curr_thread;
11757aa51b79SEd Maste             else
11767aa51b79SEd Maste               thread = thread_list.GetThreadAtIndex(0);
11777aa51b79SEd Maste 
11787aa51b79SEd Maste             if (thread)
11797aa51b79SEd Maste               thread_list.SetSelectedThreadByID(thread->GetID());
11807aa51b79SEd Maste           }
11817aa51b79SEd Maste         }
11827aa51b79SEd Maste       }
1183435933ddSDimitry Andric       // Drop the ThreadList mutex by here, since GetThreadStatus below might
11844ba319b5SDimitry Andric       // have to run code, e.g. for Data formatters, and if we hold the
11854ba319b5SDimitry Andric       // ThreadList mutex, then the process is going to have a hard time
11864ba319b5SDimitry Andric       // restarting the process.
1187435933ddSDimitry Andric       if (stream) {
11887aa51b79SEd Maste         Debugger &debugger = process_sp->GetTarget().GetDebugger();
1189435933ddSDimitry Andric         if (debugger.GetTargetList().GetSelectedTarget().get() ==
1190435933ddSDimitry Andric             &process_sp->GetTarget()) {
11917aa51b79SEd Maste           const bool only_threads_with_stop_reason = true;
11927aa51b79SEd Maste           const uint32_t start_frame = 0;
11937aa51b79SEd Maste           const uint32_t num_frames = 1;
11947aa51b79SEd Maste           const uint32_t num_frames_with_source = 1;
1195435933ddSDimitry Andric           const bool stop_format = true;
11967aa51b79SEd Maste           process_sp->GetStatus(*stream);
1197435933ddSDimitry Andric           process_sp->GetThreadStatus(*stream, only_threads_with_stop_reason,
1198435933ddSDimitry Andric                                       start_frame, num_frames,
1199435933ddSDimitry Andric                                       num_frames_with_source,
1200435933ddSDimitry Andric                                       stop_format);
1201435933ddSDimitry Andric           if (curr_thread_stop_info_sp) {
1202435933ddSDimitry Andric             lldb::addr_t crashing_address;
1203435933ddSDimitry Andric             ValueObjectSP valobj_sp = StopInfo::GetCrashingDereference(
1204435933ddSDimitry Andric                 curr_thread_stop_info_sp, &crashing_address);
1205435933ddSDimitry Andric             if (valobj_sp) {
1206435933ddSDimitry Andric               const bool qualify_cxx_base_classes = false;
1207435933ddSDimitry Andric 
1208435933ddSDimitry Andric               const ValueObject::GetExpressionPathFormat format =
1209435933ddSDimitry Andric                   ValueObject::GetExpressionPathFormat::
1210435933ddSDimitry Andric                       eGetExpressionPathFormatHonorPointers;
1211435933ddSDimitry Andric               stream->PutCString("Likely cause: ");
1212435933ddSDimitry Andric               valobj_sp->GetExpressionPath(*stream, qualify_cxx_base_classes,
1213435933ddSDimitry Andric                                            format);
1214435933ddSDimitry Andric               stream->Printf(" accessed 0x%" PRIx64 "\n", crashing_address);
12157aa51b79SEd Maste             }
1216435933ddSDimitry Andric           }
1217435933ddSDimitry Andric         } else {
1218435933ddSDimitry Andric           uint32_t target_idx = debugger.GetTargetList().GetIndexOfTarget(
1219435933ddSDimitry Andric               process_sp->GetTarget().shared_from_this());
12207aa51b79SEd Maste           if (target_idx != UINT32_MAX)
12217aa51b79SEd Maste             stream->Printf("Target %d: (", target_idx);
12227aa51b79SEd Maste           else
12237aa51b79SEd Maste             stream->Printf("Target <unknown index>: (");
12247aa51b79SEd Maste           process_sp->GetTarget().Dump(stream, eDescriptionLevelBrief);
12257aa51b79SEd Maste           stream->Printf(") stopped.\n");
12267aa51b79SEd Maste         }
12277aa51b79SEd Maste       }
12287aa51b79SEd Maste 
12297aa51b79SEd Maste       // Pop the process IO handler
12307aa51b79SEd Maste       pop_process_io_handler = true;
12317aa51b79SEd Maste     }
12327aa51b79SEd Maste     break;
12337aa51b79SEd Maste   }
12347aa51b79SEd Maste 
12357aa51b79SEd Maste   if (handle_pop && pop_process_io_handler)
12367aa51b79SEd Maste     process_sp->PopProcessIOHandler();
12377aa51b79SEd Maste 
12387aa51b79SEd Maste   return true;
12397aa51b79SEd Maste }
12407aa51b79SEd Maste 
HijackProcessEvents(ListenerSP listener_sp)1241435933ddSDimitry Andric bool Process::HijackProcessEvents(ListenerSP listener_sp) {
1242435933ddSDimitry Andric   if (listener_sp) {
1243435933ddSDimitry Andric     return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged |
1244435933ddSDimitry Andric                                               eBroadcastBitInterrupt);
1245435933ddSDimitry Andric   } else
1246ac7ddfbfSEd Maste     return false;
1247ac7ddfbfSEd Maste }
1248ac7ddfbfSEd Maste 
RestoreProcessEvents()1249435933ddSDimitry Andric void Process::RestoreProcessEvents() { RestoreBroadcaster(); }
1250ac7ddfbfSEd Maste 
GetStateChangedEvents(EventSP & event_sp,const Timeout<std::micro> & timeout,ListenerSP hijack_listener_sp)1251435933ddSDimitry Andric StateType Process::GetStateChangedEvents(EventSP &event_sp,
1252435933ddSDimitry Andric                                          const Timeout<std::micro> &timeout,
1253435933ddSDimitry Andric                                          ListenerSP hijack_listener_sp) {
1254ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1255f678e45dSDimitry Andric   LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout);
1256ac7ddfbfSEd Maste 
12574bb0738eSEd Maste   ListenerSP listener_sp = hijack_listener_sp;
12584bb0738eSEd Maste   if (!listener_sp)
12594bb0738eSEd Maste     listener_sp = m_listener_sp;
126012b93ac6SEd Maste 
1261ac7ddfbfSEd Maste   StateType state = eStateInvalid;
1262435933ddSDimitry Andric   if (listener_sp->GetEventForBroadcasterWithType(
1263435933ddSDimitry Andric           this, eBroadcastBitStateChanged | eBroadcastBitInterrupt, event_sp,
1264435933ddSDimitry Andric           timeout)) {
1265ac7ddfbfSEd Maste     if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
1266ac7ddfbfSEd Maste       state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
1267f678e45dSDimitry Andric     else
1268f678e45dSDimitry Andric       LLDB_LOG(log, "got no event or was interrupted.");
1269ac7ddfbfSEd Maste   }
1270ac7ddfbfSEd Maste 
1271f678e45dSDimitry Andric   LLDB_LOG(log, "timeout = {0}, event_sp) => {1}", timeout, state);
1272ac7ddfbfSEd Maste   return state;
1273ac7ddfbfSEd Maste }
1274ac7ddfbfSEd Maste 
PeekAtStateChangedEvents()1275435933ddSDimitry Andric Event *Process::PeekAtStateChangedEvents() {
1276ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1277ac7ddfbfSEd Maste 
1278ac7ddfbfSEd Maste   if (log)
1279ac7ddfbfSEd Maste     log->Printf("Process::%s...", __FUNCTION__);
1280ac7ddfbfSEd Maste 
1281ac7ddfbfSEd Maste   Event *event_ptr;
1282435933ddSDimitry Andric   event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType(
1283435933ddSDimitry Andric       this, eBroadcastBitStateChanged);
1284435933ddSDimitry Andric   if (log) {
1285435933ddSDimitry Andric     if (event_ptr) {
1286435933ddSDimitry Andric       log->Printf(
1287435933ddSDimitry Andric           "Process::%s (event_ptr) => %s", __FUNCTION__,
1288ac7ddfbfSEd Maste           StateAsCString(ProcessEventData::GetStateFromEvent(event_ptr)));
1289435933ddSDimitry Andric     } else {
1290435933ddSDimitry Andric       log->Printf("Process::%s no events found", __FUNCTION__);
1291ac7ddfbfSEd Maste     }
1292ac7ddfbfSEd Maste   }
1293ac7ddfbfSEd Maste   return event_ptr;
1294ac7ddfbfSEd Maste }
1295ac7ddfbfSEd Maste 
1296ac7ddfbfSEd Maste StateType
GetStateChangedEventsPrivate(EventSP & event_sp,const Timeout<std::micro> & timeout)1297435933ddSDimitry Andric Process::GetStateChangedEventsPrivate(EventSP &event_sp,
1298435933ddSDimitry Andric                                       const Timeout<std::micro> &timeout) {
1299ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1300f678e45dSDimitry Andric   LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout);
1301ac7ddfbfSEd Maste 
1302ac7ddfbfSEd Maste   StateType state = eStateInvalid;
1303435933ddSDimitry Andric   if (m_private_state_listener_sp->GetEventForBroadcasterWithType(
1304ac7ddfbfSEd Maste           &m_private_state_broadcaster,
1305435933ddSDimitry Andric           eBroadcastBitStateChanged | eBroadcastBitInterrupt, event_sp,
1306435933ddSDimitry Andric           timeout))
1307ac7ddfbfSEd Maste     if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
1308ac7ddfbfSEd Maste       state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
1309ac7ddfbfSEd Maste 
1310f678e45dSDimitry Andric   LLDB_LOG(log, "timeout = {0}, event_sp) => {1}", timeout,
13110127ef0fSEd Maste            state == eStateInvalid ? "TIMEOUT" : StateAsCString(state));
1312ac7ddfbfSEd Maste   return state;
1313ac7ddfbfSEd Maste }
1314ac7ddfbfSEd Maste 
GetEventsPrivate(EventSP & event_sp,const Timeout<std::micro> & timeout,bool control_only)1315435933ddSDimitry Andric bool Process::GetEventsPrivate(EventSP &event_sp,
1316435933ddSDimitry Andric                                const Timeout<std::micro> &timeout,
1317435933ddSDimitry Andric                                bool control_only) {
1318ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1319f678e45dSDimitry Andric   LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout);
1320ac7ddfbfSEd Maste 
1321ac7ddfbfSEd Maste   if (control_only)
1322435933ddSDimitry Andric     return m_private_state_listener_sp->GetEventForBroadcaster(
1323435933ddSDimitry Andric         &m_private_state_control_broadcaster, event_sp, timeout);
1324ac7ddfbfSEd Maste   else
1325435933ddSDimitry Andric     return m_private_state_listener_sp->GetEvent(event_sp, timeout);
1326ac7ddfbfSEd Maste }
1327ac7ddfbfSEd Maste 
IsRunning() const1328435933ddSDimitry Andric bool Process::IsRunning() const {
1329ac7ddfbfSEd Maste   return StateIsRunningState(m_public_state.GetValue());
1330ac7ddfbfSEd Maste }
1331ac7ddfbfSEd Maste 
GetExitStatus()1332435933ddSDimitry Andric int Process::GetExitStatus() {
13334bb0738eSEd Maste   std::lock_guard<std::mutex> guard(m_exit_status_mutex);
13347aa51b79SEd Maste 
1335ac7ddfbfSEd Maste   if (m_public_state.GetValue() == eStateExited)
1336ac7ddfbfSEd Maste     return m_exit_status;
1337ac7ddfbfSEd Maste   return -1;
1338ac7ddfbfSEd Maste }
1339ac7ddfbfSEd Maste 
GetExitDescription()1340435933ddSDimitry Andric const char *Process::GetExitDescription() {
13414bb0738eSEd Maste   std::lock_guard<std::mutex> guard(m_exit_status_mutex);
13427aa51b79SEd Maste 
1343ac7ddfbfSEd Maste   if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty())
1344ac7ddfbfSEd Maste     return m_exit_string.c_str();
13454bb0738eSEd Maste   return nullptr;
1346ac7ddfbfSEd Maste }
1347ac7ddfbfSEd Maste 
SetExitStatus(int status,const char * cstr)1348435933ddSDimitry Andric bool Process::SetExitStatus(int status, const char *cstr) {
13491c3bbb01SEd Maste   // Use a mutex to protect setting the exit status.
13504bb0738eSEd Maste   std::lock_guard<std::mutex> guard(m_exit_status_mutex);
13511c3bbb01SEd Maste 
1352435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
1353435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
1354ac7ddfbfSEd Maste   if (log)
1355435933ddSDimitry Andric     log->Printf(
1356435933ddSDimitry Andric         "Process::SetExitStatus (status=%i (0x%8.8x), description=%s%s%s)",
1357435933ddSDimitry Andric         status, status, cstr ? "\"" : "", cstr ? cstr : "NULL",
1358ac7ddfbfSEd Maste         cstr ? "\"" : "");
1359ac7ddfbfSEd Maste 
1360ac7ddfbfSEd Maste   // We were already in the exited state
1361435933ddSDimitry Andric   if (m_private_state.GetValue() == eStateExited) {
1362ac7ddfbfSEd Maste     if (log)
1363435933ddSDimitry Andric       log->Printf("Process::SetExitStatus () ignoring exit status because "
1364435933ddSDimitry Andric                   "state was already set to eStateExited");
1365ac7ddfbfSEd Maste     return false;
1366ac7ddfbfSEd Maste   }
1367ac7ddfbfSEd Maste 
1368ac7ddfbfSEd Maste   m_exit_status = status;
1369ac7ddfbfSEd Maste   if (cstr)
1370ac7ddfbfSEd Maste     m_exit_string = cstr;
1371ac7ddfbfSEd Maste   else
1372ac7ddfbfSEd Maste     m_exit_string.clear();
13731c3bbb01SEd Maste 
13744ba319b5SDimitry Andric   // Clear the last natural stop ID since it has a strong reference to this
13754ba319b5SDimitry Andric   // process
13761c3bbb01SEd Maste   m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
1377ac7ddfbfSEd Maste 
1378ac7ddfbfSEd Maste   SetPrivateState(eStateExited);
13791c3bbb01SEd Maste 
13801c3bbb01SEd Maste   // Allow subclasses to do some cleanup
13811c3bbb01SEd Maste   DidExit();
13821c3bbb01SEd Maste 
1383ac7ddfbfSEd Maste   return true;
1384ac7ddfbfSEd Maste }
1385ac7ddfbfSEd Maste 
IsAlive()1386435933ddSDimitry Andric bool Process::IsAlive() {
1387435933ddSDimitry Andric   switch (m_private_state.GetValue()) {
13889f2f44ceSEd Maste   case eStateConnected:
13899f2f44ceSEd Maste   case eStateAttaching:
13909f2f44ceSEd Maste   case eStateLaunching:
13919f2f44ceSEd Maste   case eStateStopped:
13929f2f44ceSEd Maste   case eStateRunning:
13939f2f44ceSEd Maste   case eStateStepping:
13949f2f44ceSEd Maste   case eStateCrashed:
13959f2f44ceSEd Maste   case eStateSuspended:
13969f2f44ceSEd Maste     return true;
13974bb0738eSEd Maste   default:
13984bb0738eSEd Maste     return false;
13999f2f44ceSEd Maste   }
14009f2f44ceSEd Maste }
14019f2f44ceSEd Maste 
14024ba319b5SDimitry Andric // This static callback can be used to watch for local child processes on the
14034ba319b5SDimitry Andric // current host. The child process exits, the process will be found in the
14044ba319b5SDimitry Andric // global target list (we want to be completely sure that the
1405ac7ddfbfSEd Maste // lldb_private::Process doesn't go away before we can deliver the signal.
SetProcessExitStatus(lldb::pid_t pid,bool exited,int signo,int exit_status)1406435933ddSDimitry Andric bool Process::SetProcessExitStatus(
1407435933ddSDimitry Andric     lldb::pid_t pid, bool exited,
1408ac7ddfbfSEd Maste     int signo,      // Zero for no signal
1409ac7ddfbfSEd Maste     int exit_status // Exit value of process if signal is zero
1410435933ddSDimitry Andric     ) {
1411ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
1412ac7ddfbfSEd Maste   if (log)
1413435933ddSDimitry Andric     log->Printf("Process::SetProcessExitStatus (pid=%" PRIu64
1414435933ddSDimitry Andric                 ", exited=%i, signal=%i, exit_status=%i)\n",
1415435933ddSDimitry Andric                 pid, exited, signo, exit_status);
1416ac7ddfbfSEd Maste 
1417435933ddSDimitry Andric   if (exited) {
1418ac7ddfbfSEd Maste     TargetSP target_sp(Debugger::FindTargetWithProcessID(pid));
1419435933ddSDimitry Andric     if (target_sp) {
1420ac7ddfbfSEd Maste       ProcessSP process_sp(target_sp->GetProcessSP());
1421435933ddSDimitry Andric       if (process_sp) {
14224bb0738eSEd Maste         const char *signal_cstr = nullptr;
1423ac7ddfbfSEd Maste         if (signo)
1424b91a7dfcSDimitry Andric           signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
1425ac7ddfbfSEd Maste 
1426ac7ddfbfSEd Maste         process_sp->SetExitStatus(exit_status, signal_cstr);
1427ac7ddfbfSEd Maste       }
1428ac7ddfbfSEd Maste     }
1429ac7ddfbfSEd Maste     return true;
1430ac7ddfbfSEd Maste   }
1431ac7ddfbfSEd Maste   return false;
1432ac7ddfbfSEd Maste }
1433ac7ddfbfSEd Maste 
UpdateThreadListIfNeeded()1434435933ddSDimitry Andric void Process::UpdateThreadListIfNeeded() {
1435ac7ddfbfSEd Maste   const uint32_t stop_id = GetStopID();
1436435933ddSDimitry Andric   if (m_thread_list.GetSize(false) == 0 ||
1437435933ddSDimitry Andric       stop_id != m_thread_list.GetStopID()) {
1438ac7ddfbfSEd Maste     const StateType state = GetPrivateState();
1439435933ddSDimitry Andric     if (StateIsStoppedState(state, true)) {
14404bb0738eSEd Maste       std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
14414ba319b5SDimitry Andric       // m_thread_list does have its own mutex, but we need to hold onto the
14424ba319b5SDimitry Andric       // mutex between the call to UpdateThreadList(...) and the
14434ba319b5SDimitry Andric       // os->UpdateThreadList(...) so it doesn't change on us
1444ac7ddfbfSEd Maste       ThreadList &old_thread_list = m_thread_list;
1445ac7ddfbfSEd Maste       ThreadList real_thread_list(this);
1446ac7ddfbfSEd Maste       ThreadList new_thread_list(this);
14474ba319b5SDimitry Andric       // Always update the thread list with the protocol specific thread list,
14484ba319b5SDimitry Andric       // but only update if "true" is returned
1449435933ddSDimitry Andric       if (UpdateThreadList(m_thread_list_real, real_thread_list)) {
1450435933ddSDimitry Andric         // Don't call into the OperatingSystem to update the thread list if we
14514ba319b5SDimitry Andric         // are shutting down, since that may call back into the SBAPI's,
14524ba319b5SDimitry Andric         // requiring the API lock which is already held by whoever is shutting
14534ba319b5SDimitry Andric         // us down, causing a deadlock.
1454ac7ddfbfSEd Maste         OperatingSystem *os = GetOperatingSystem();
1455435933ddSDimitry Andric         if (os && !m_destroy_in_process) {
1456ac7ddfbfSEd Maste           // Clear any old backing threads where memory threads might have been
1457ac7ddfbfSEd Maste           // backed by actual threads from the lldb_private::Process subclass
1458ac7ddfbfSEd Maste           size_t num_old_threads = old_thread_list.GetSize(false);
1459ac7ddfbfSEd Maste           for (size_t i = 0; i < num_old_threads; ++i)
1460ac7ddfbfSEd Maste             old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
1461ac7ddfbfSEd Maste 
1462435933ddSDimitry Andric           // Turn off dynamic types to ensure we don't run any expressions.
14634ba319b5SDimitry Andric           // Objective-C can run an expression to determine if a SBValue is a
14644ba319b5SDimitry Andric           // dynamic type or not and we need to avoid this. OperatingSystem
14654ba319b5SDimitry Andric           // plug-ins can't run expressions that require running code...
14661c3bbb01SEd Maste 
14671c3bbb01SEd Maste           Target &target = GetTarget();
1468435933ddSDimitry Andric           const lldb::DynamicValueType saved_prefer_dynamic =
1469435933ddSDimitry Andric               target.GetPreferDynamicValue();
14701c3bbb01SEd Maste           if (saved_prefer_dynamic != lldb::eNoDynamicValues)
14711c3bbb01SEd Maste             target.SetPreferDynamicValue(lldb::eNoDynamicValues);
14721c3bbb01SEd Maste 
1473ac7ddfbfSEd Maste           // Now let the OperatingSystem plug-in update the thread list
14741c3bbb01SEd Maste 
1475435933ddSDimitry Andric           os->UpdateThreadList(
1476435933ddSDimitry Andric               old_thread_list, // Old list full of threads created by OS plug-in
1477435933ddSDimitry Andric               real_thread_list, // The actual thread list full of threads
1478435933ddSDimitry Andric                                 // created by each lldb_private::Process
1479435933ddSDimitry Andric                                 // subclass
1480435933ddSDimitry Andric               new_thread_list); // The new thread list that we will show to the
1481435933ddSDimitry Andric                                 // user that gets filled in
14821c3bbb01SEd Maste 
14831c3bbb01SEd Maste           if (saved_prefer_dynamic != lldb::eNoDynamicValues)
14841c3bbb01SEd Maste             target.SetPreferDynamicValue(saved_prefer_dynamic);
1485435933ddSDimitry Andric         } else {
1486435933ddSDimitry Andric           // No OS plug-in, the new thread list is the same as the real thread
1487435933ddSDimitry Andric           // list
1488ac7ddfbfSEd Maste           new_thread_list = real_thread_list;
1489ac7ddfbfSEd Maste         }
1490ac7ddfbfSEd Maste 
1491ac7ddfbfSEd Maste         m_thread_list_real.Update(real_thread_list);
1492ac7ddfbfSEd Maste         m_thread_list.Update(new_thread_list);
1493ac7ddfbfSEd Maste         m_thread_list.SetStopID(stop_id);
1494b952cd58SEd Maste 
1495435933ddSDimitry Andric         if (GetLastNaturalStopID() != m_extended_thread_stop_id) {
1496b952cd58SEd Maste           // Clear any extended threads that we may have accumulated previously
1497b952cd58SEd Maste           m_extended_thread_list.Clear();
1498b952cd58SEd Maste           m_extended_thread_stop_id = GetLastNaturalStopID();
149912b93ac6SEd Maste 
150012b93ac6SEd Maste           m_queue_list.Clear();
150112b93ac6SEd Maste           m_queue_list_stop_id = GetLastNaturalStopID();
1502b952cd58SEd Maste         }
1503ac7ddfbfSEd Maste       }
1504ac7ddfbfSEd Maste     }
1505ac7ddfbfSEd Maste   }
1506ac7ddfbfSEd Maste }
1507ac7ddfbfSEd Maste 
UpdateQueueListIfNeeded()1508435933ddSDimitry Andric void Process::UpdateQueueListIfNeeded() {
1509435933ddSDimitry Andric   if (m_system_runtime_ap) {
1510435933ddSDimitry Andric     if (m_queue_list.GetSize() == 0 ||
1511435933ddSDimitry Andric         m_queue_list_stop_id != GetLastNaturalStopID()) {
151212b93ac6SEd Maste       const StateType state = GetPrivateState();
1513435933ddSDimitry Andric       if (StateIsStoppedState(state, true)) {
151412b93ac6SEd Maste         m_system_runtime_ap->PopulateQueueList(m_queue_list);
151512b93ac6SEd Maste         m_queue_list_stop_id = GetLastNaturalStopID();
151612b93ac6SEd Maste       }
151712b93ac6SEd Maste     }
151812b93ac6SEd Maste   }
151912b93ac6SEd Maste }
152012b93ac6SEd Maste 
CreateOSPluginThread(lldb::tid_t tid,lldb::addr_t context)1521435933ddSDimitry Andric ThreadSP Process::CreateOSPluginThread(lldb::tid_t tid, lldb::addr_t context) {
1522ac7ddfbfSEd Maste   OperatingSystem *os = GetOperatingSystem();
1523ac7ddfbfSEd Maste   if (os)
1524ac7ddfbfSEd Maste     return os->CreateThread(tid, context);
1525ac7ddfbfSEd Maste   return ThreadSP();
1526ac7ddfbfSEd Maste }
1527ac7ddfbfSEd Maste 
GetNextThreadIndexID(uint64_t thread_id)1528435933ddSDimitry Andric uint32_t Process::GetNextThreadIndexID(uint64_t thread_id) {
1529ac7ddfbfSEd Maste   return AssignIndexIDToThread(thread_id);
1530ac7ddfbfSEd Maste }
1531ac7ddfbfSEd Maste 
HasAssignedIndexIDToThread(uint64_t thread_id)1532435933ddSDimitry Andric bool Process::HasAssignedIndexIDToThread(uint64_t thread_id) {
1533435933ddSDimitry Andric   return (m_thread_id_to_index_id_map.find(thread_id) !=
1534435933ddSDimitry Andric           m_thread_id_to_index_id_map.end());
1535ac7ddfbfSEd Maste }
1536ac7ddfbfSEd Maste 
AssignIndexIDToThread(uint64_t thread_id)1537435933ddSDimitry Andric uint32_t Process::AssignIndexIDToThread(uint64_t thread_id) {
1538ac7ddfbfSEd Maste   uint32_t result = 0;
1539435933ddSDimitry Andric   std::map<uint64_t, uint32_t>::iterator iterator =
1540435933ddSDimitry Andric       m_thread_id_to_index_id_map.find(thread_id);
1541435933ddSDimitry Andric   if (iterator == m_thread_id_to_index_id_map.end()) {
1542ac7ddfbfSEd Maste     result = ++m_thread_index_id;
1543ac7ddfbfSEd Maste     m_thread_id_to_index_id_map[thread_id] = result;
1544435933ddSDimitry Andric   } else {
1545ac7ddfbfSEd Maste     result = iterator->second;
1546ac7ddfbfSEd Maste   }
1547ac7ddfbfSEd Maste 
1548ac7ddfbfSEd Maste   return result;
1549ac7ddfbfSEd Maste }
1550ac7ddfbfSEd Maste 
GetState()1551435933ddSDimitry Andric StateType Process::GetState() {
1552ac7ddfbfSEd Maste   return m_public_state.GetValue();
1553ac7ddfbfSEd Maste }
1554ac7ddfbfSEd Maste 
StateChangedIsExternallyHijacked()1555435933ddSDimitry Andric bool Process::StateChangedIsExternallyHijacked() {
1556435933ddSDimitry Andric   if (IsHijackedForEvent(eBroadcastBitStateChanged)) {
15574bb0738eSEd Maste     const char *hijacking_name = GetHijackingListenerName();
1558435933ddSDimitry Andric     if (hijacking_name &&
1559435933ddSDimitry Andric         strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack"))
15607aa51b79SEd Maste       return true;
15617aa51b79SEd Maste   }
15627aa51b79SEd Maste   return false;
15637aa51b79SEd Maste }
15647aa51b79SEd Maste 
SetPublicState(StateType new_state,bool restarted)1565435933ddSDimitry Andric void Process::SetPublicState(StateType new_state, bool restarted) {
1566435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
1567435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
1568ac7ddfbfSEd Maste   if (log)
1569435933ddSDimitry Andric     log->Printf("Process::SetPublicState (state = %s, restarted = %i)",
1570435933ddSDimitry Andric                 StateAsCString(new_state), restarted);
1571ac7ddfbfSEd Maste   const StateType old_state = m_public_state.GetValue();
1572ac7ddfbfSEd Maste   m_public_state.SetValue(new_state);
1573ac7ddfbfSEd Maste 
15744ba319b5SDimitry Andric   // On the transition from Run to Stopped, we unlock the writer end of the run
15754ba319b5SDimitry Andric   // lock.  The lock gets locked in Resume, which is the public API to tell the
15764ba319b5SDimitry Andric   // program to run.
1577435933ddSDimitry Andric   if (!StateChangedIsExternallyHijacked()) {
1578435933ddSDimitry Andric     if (new_state == eStateDetached) {
1579ac7ddfbfSEd Maste       if (log)
1580435933ddSDimitry Andric         log->Printf(
1581435933ddSDimitry Andric             "Process::SetPublicState (%s) -- unlocking run lock for detach",
1582435933ddSDimitry Andric             StateAsCString(new_state));
1583ac7ddfbfSEd Maste       m_public_run_lock.SetStopped();
1584435933ddSDimitry Andric     } else {
1585ac7ddfbfSEd Maste       const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
1586ac7ddfbfSEd Maste       const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
1587435933ddSDimitry Andric       if ((old_state_is_stopped != new_state_is_stopped)) {
1588435933ddSDimitry Andric         if (new_state_is_stopped && !restarted) {
1589ac7ddfbfSEd Maste           if (log)
1590435933ddSDimitry Andric             log->Printf("Process::SetPublicState (%s) -- unlocking run lock",
1591435933ddSDimitry Andric                         StateAsCString(new_state));
1592ac7ddfbfSEd Maste           m_public_run_lock.SetStopped();
1593ac7ddfbfSEd Maste         }
1594ac7ddfbfSEd Maste       }
1595ac7ddfbfSEd Maste     }
1596ac7ddfbfSEd Maste   }
1597ac7ddfbfSEd Maste }
1598ac7ddfbfSEd Maste 
Resume()15995517e702SDimitry Andric Status Process::Resume() {
1600435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
1601435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
1602ac7ddfbfSEd Maste   if (log)
1603ac7ddfbfSEd Maste     log->Printf("Process::Resume -- locking run lock");
1604435933ddSDimitry Andric   if (!m_public_run_lock.TrySetRunning()) {
16055517e702SDimitry Andric     Status error("Resume request failed - process still running.");
1606ac7ddfbfSEd Maste     if (log)
1607ac7ddfbfSEd Maste       log->Printf("Process::Resume: -- TrySetRunning failed, not resuming.");
1608ac7ddfbfSEd Maste     return error;
1609ac7ddfbfSEd Maste   }
1610acac075bSDimitry Andric   Status error = PrivateResume();
1611acac075bSDimitry Andric   if (!error.Success()) {
1612acac075bSDimitry Andric     // Undo running state change
1613acac075bSDimitry Andric     m_public_run_lock.SetStopped();
1614acac075bSDimitry Andric   }
1615acac075bSDimitry Andric   return error;
1616ac7ddfbfSEd Maste }
1617ac7ddfbfSEd Maste 
ResumeSynchronous(Stream * stream)16185517e702SDimitry Andric Status Process::ResumeSynchronous(Stream *stream) {
1619435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
1620435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
16217aa51b79SEd Maste   if (log)
16227aa51b79SEd Maste     log->Printf("Process::ResumeSynchronous -- locking run lock");
1623435933ddSDimitry Andric   if (!m_public_run_lock.TrySetRunning()) {
16245517e702SDimitry Andric     Status error("Resume request failed - process still running.");
16257aa51b79SEd Maste     if (log)
16267aa51b79SEd Maste       log->Printf("Process::Resume: -- TrySetRunning failed, not resuming.");
16277aa51b79SEd Maste     return error;
16287aa51b79SEd Maste   }
16297aa51b79SEd Maste 
1630435933ddSDimitry Andric   ListenerSP listener_sp(
1631435933ddSDimitry Andric       Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack"));
16324bb0738eSEd Maste   HijackProcessEvents(listener_sp);
16337aa51b79SEd Maste 
16345517e702SDimitry Andric   Status error = PrivateResume();
1635435933ddSDimitry Andric   if (error.Success()) {
1636435933ddSDimitry Andric     StateType state =
1637435933ddSDimitry Andric         WaitForProcessToStop(llvm::None, NULL, true, listener_sp, stream);
1638435933ddSDimitry Andric     const bool must_be_alive =
1639435933ddSDimitry Andric         false; // eStateExited is ok, so this must be false
16401c3bbb01SEd Maste     if (!StateIsStoppedState(state, must_be_alive))
1641435933ddSDimitry Andric       error.SetErrorStringWithFormat(
1642435933ddSDimitry Andric           "process not in stopped state after synchronous resume: %s",
1643435933ddSDimitry Andric           StateAsCString(state));
1644acac075bSDimitry Andric   } else {
1645acac075bSDimitry Andric     // Undo running state change
1646acac075bSDimitry Andric     m_public_run_lock.SetStopped();
16471c3bbb01SEd Maste   }
16487aa51b79SEd Maste 
16497aa51b79SEd Maste   // Undo the hijacking of process events...
16507aa51b79SEd Maste   RestoreProcessEvents();
16517aa51b79SEd Maste 
16527aa51b79SEd Maste   return error;
16537aa51b79SEd Maste }
16547aa51b79SEd Maste 
GetPrivateState()1655435933ddSDimitry Andric StateType Process::GetPrivateState() { return m_private_state.GetValue(); }
1656ac7ddfbfSEd Maste 
SetPrivateState(StateType new_state)1657435933ddSDimitry Andric void Process::SetPrivateState(StateType new_state) {
16580127ef0fSEd Maste   if (m_finalize_called)
16590127ef0fSEd Maste     return;
16600127ef0fSEd Maste 
1661435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
1662435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
1663ac7ddfbfSEd Maste   bool state_changed = false;
1664ac7ddfbfSEd Maste 
1665ac7ddfbfSEd Maste   if (log)
1666ac7ddfbfSEd Maste     log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
1667ac7ddfbfSEd Maste 
16684bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex());
16694bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex());
1670ac7ddfbfSEd Maste 
1671ac7ddfbfSEd Maste   const StateType old_state = m_private_state.GetValueNoLock();
1672ac7ddfbfSEd Maste   state_changed = old_state != new_state;
1673ac7ddfbfSEd Maste 
1674ac7ddfbfSEd Maste   const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
1675ac7ddfbfSEd Maste   const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
1676435933ddSDimitry Andric   if (old_state_is_stopped != new_state_is_stopped) {
1677ac7ddfbfSEd Maste     if (new_state_is_stopped)
1678ac7ddfbfSEd Maste       m_private_run_lock.SetStopped();
1679ac7ddfbfSEd Maste     else
1680ac7ddfbfSEd Maste       m_private_run_lock.SetRunning();
1681ac7ddfbfSEd Maste   }
1682ac7ddfbfSEd Maste 
1683435933ddSDimitry Andric   if (state_changed) {
1684ac7ddfbfSEd Maste     m_private_state.SetValueNoLock(new_state);
1685435933ddSDimitry Andric     EventSP event_sp(
1686435933ddSDimitry Andric         new Event(eBroadcastBitStateChanged,
1687435933ddSDimitry Andric                   new ProcessEventData(shared_from_this(), new_state)));
1688435933ddSDimitry Andric     if (StateIsStoppedState(new_state, false)) {
16894ba319b5SDimitry Andric       // Note, this currently assumes that all threads in the list stop when
16904ba319b5SDimitry Andric       // the process stops.  In the future we will want to support a debugging
16914ba319b5SDimitry Andric       // model where some threads continue to run while others are stopped.
16924ba319b5SDimitry Andric       // When that happens we will either need a way for the thread list to
16934ba319b5SDimitry Andric       // identify which threads are stopping or create a special thread list
16944ba319b5SDimitry Andric       // containing only threads which actually stopped.
1695ac7ddfbfSEd Maste       //
16964ba319b5SDimitry Andric       // The process plugin is responsible for managing the actual behavior of
16974ba319b5SDimitry Andric       // the threads and should have stopped any threads that are going to stop
16984ba319b5SDimitry Andric       // before we get here.
1699ac7ddfbfSEd Maste       m_thread_list.DidStop();
1700ac7ddfbfSEd Maste 
1701ac7ddfbfSEd Maste       m_mod_id.BumpStopID();
17021c3bbb01SEd Maste       if (!m_mod_id.IsLastResumeForUserExpression())
17031c3bbb01SEd Maste         m_mod_id.SetStopEventForLastNaturalStopID(event_sp);
1704ac7ddfbfSEd Maste       m_memory_cache.Clear();
1705ac7ddfbfSEd Maste       if (log)
1706435933ddSDimitry Andric         log->Printf("Process::SetPrivateState (%s) stop_id = %u",
1707435933ddSDimitry Andric                     StateAsCString(new_state), m_mod_id.GetStopID());
1708ac7ddfbfSEd Maste     }
17091c3bbb01SEd Maste 
1710ac7ddfbfSEd Maste     // Use our target to get a shared pointer to ourselves...
17114bb0738eSEd Maste     if (m_finalize_called && !PrivateStateThreadIsValid())
17121c3bbb01SEd Maste       BroadcastEvent(event_sp);
1713ac7ddfbfSEd Maste     else
17141c3bbb01SEd Maste       m_private_state_broadcaster.BroadcastEvent(event_sp);
1715435933ddSDimitry Andric   } else {
1716ac7ddfbfSEd Maste     if (log)
1717435933ddSDimitry Andric       log->Printf(
1718435933ddSDimitry Andric           "Process::SetPrivateState (%s) state didn't change. Ignoring...",
1719435933ddSDimitry Andric           StateAsCString(new_state));
1720ac7ddfbfSEd Maste   }
1721ac7ddfbfSEd Maste }
1722ac7ddfbfSEd Maste 
SetRunningUserExpression(bool on)1723435933ddSDimitry Andric void Process::SetRunningUserExpression(bool on) {
1724ac7ddfbfSEd Maste   m_mod_id.SetRunningUserExpression(on);
1725ac7ddfbfSEd Maste }
1726ac7ddfbfSEd Maste 
SetRunningUtilityFunction(bool on)1727*b5893f02SDimitry Andric void Process::SetRunningUtilityFunction(bool on) {
1728*b5893f02SDimitry Andric   m_mod_id.SetRunningUtilityFunction(on);
1729*b5893f02SDimitry Andric }
1730*b5893f02SDimitry Andric 
GetImageInfoAddress()1731435933ddSDimitry Andric addr_t Process::GetImageInfoAddress() { return LLDB_INVALID_ADDRESS; }
1732ac7ddfbfSEd Maste 
GetABI()1733435933ddSDimitry Andric const lldb::ABISP &Process::GetABI() {
1734ac7ddfbfSEd Maste   if (!m_abi_sp)
1735a580b014SDimitry Andric     m_abi_sp = ABI::FindPlugin(shared_from_this(), GetTarget().GetArchitecture());
1736ac7ddfbfSEd Maste   return m_abi_sp;
1737ac7ddfbfSEd Maste }
1738ac7ddfbfSEd Maste 
GetLanguageRuntime(lldb::LanguageType language,bool retry_if_null)1739435933ddSDimitry Andric LanguageRuntime *Process::GetLanguageRuntime(lldb::LanguageType language,
1740435933ddSDimitry Andric                                              bool retry_if_null) {
17411c3bbb01SEd Maste   if (m_finalizing)
17421c3bbb01SEd Maste     return nullptr;
17431c3bbb01SEd Maste 
1744ac7ddfbfSEd Maste   LanguageRuntimeCollection::iterator pos;
1745ac7ddfbfSEd Maste   pos = m_language_runtimes.find(language);
1746435933ddSDimitry Andric   if (pos == m_language_runtimes.end() || (retry_if_null && !(*pos).second)) {
1747435933ddSDimitry Andric     lldb::LanguageRuntimeSP runtime_sp(
1748435933ddSDimitry Andric         LanguageRuntime::FindPlugin(this, language));
1749ac7ddfbfSEd Maste 
1750ac7ddfbfSEd Maste     m_language_runtimes[language] = runtime_sp;
1751ac7ddfbfSEd Maste     return runtime_sp.get();
1752435933ddSDimitry Andric   } else
1753ac7ddfbfSEd Maste     return (*pos).second.get();
1754ac7ddfbfSEd Maste }
1755ac7ddfbfSEd Maste 
GetCPPLanguageRuntime(bool retry_if_null)1756435933ddSDimitry Andric CPPLanguageRuntime *Process::GetCPPLanguageRuntime(bool retry_if_null) {
1757435933ddSDimitry Andric   LanguageRuntime *runtime =
1758435933ddSDimitry Andric       GetLanguageRuntime(eLanguageTypeC_plus_plus, retry_if_null);
1759435933ddSDimitry Andric   if (runtime != nullptr &&
1760435933ddSDimitry Andric       runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
1761ac7ddfbfSEd Maste     return static_cast<CPPLanguageRuntime *>(runtime);
17624bb0738eSEd Maste   return nullptr;
1763ac7ddfbfSEd Maste }
1764ac7ddfbfSEd Maste 
GetObjCLanguageRuntime(bool retry_if_null)1765435933ddSDimitry Andric ObjCLanguageRuntime *Process::GetObjCLanguageRuntime(bool retry_if_null) {
1766435933ddSDimitry Andric   LanguageRuntime *runtime =
1767435933ddSDimitry Andric       GetLanguageRuntime(eLanguageTypeObjC, retry_if_null);
17684bb0738eSEd Maste   if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeObjC)
1769ac7ddfbfSEd Maste     return static_cast<ObjCLanguageRuntime *>(runtime);
17704bb0738eSEd Maste   return nullptr;
1771ac7ddfbfSEd Maste }
1772ac7ddfbfSEd Maste 
IsPossibleDynamicValue(ValueObject & in_value)1773435933ddSDimitry Andric bool Process::IsPossibleDynamicValue(ValueObject &in_value) {
17741c3bbb01SEd Maste   if (m_finalizing)
17751c3bbb01SEd Maste     return false;
17761c3bbb01SEd Maste 
1777ac7ddfbfSEd Maste   if (in_value.IsDynamic())
1778ac7ddfbfSEd Maste     return false;
1779ac7ddfbfSEd Maste   LanguageType known_type = in_value.GetObjectRuntimeLanguage();
1780ac7ddfbfSEd Maste 
1781435933ddSDimitry Andric   if (known_type != eLanguageTypeUnknown && known_type != eLanguageTypeC) {
1782ac7ddfbfSEd Maste     LanguageRuntime *runtime = GetLanguageRuntime(known_type);
1783ac7ddfbfSEd Maste     return runtime ? runtime->CouldHaveDynamicValue(in_value) : false;
1784ac7ddfbfSEd Maste   }
1785ac7ddfbfSEd Maste 
1786ac7ddfbfSEd Maste   LanguageRuntime *cpp_runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus);
1787ac7ddfbfSEd Maste   if (cpp_runtime && cpp_runtime->CouldHaveDynamicValue(in_value))
1788ac7ddfbfSEd Maste     return true;
1789ac7ddfbfSEd Maste 
1790ac7ddfbfSEd Maste   LanguageRuntime *objc_runtime = GetLanguageRuntime(eLanguageTypeObjC);
1791ac7ddfbfSEd Maste   return objc_runtime ? objc_runtime->CouldHaveDynamicValue(in_value) : false;
1792ac7ddfbfSEd Maste }
1793ac7ddfbfSEd Maste 
SetDynamicCheckers(DynamicCheckerFunctions * dynamic_checkers)1794435933ddSDimitry Andric void Process::SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers) {
17951c3bbb01SEd Maste   m_dynamic_checkers_ap.reset(dynamic_checkers);
17961c3bbb01SEd Maste }
17971c3bbb01SEd Maste 
GetBreakpointSiteList()1798435933ddSDimitry Andric BreakpointSiteList &Process::GetBreakpointSiteList() {
1799ac7ddfbfSEd Maste   return m_breakpoint_site_list;
1800ac7ddfbfSEd Maste }
1801ac7ddfbfSEd Maste 
GetBreakpointSiteList() const1802435933ddSDimitry Andric const BreakpointSiteList &Process::GetBreakpointSiteList() const {
1803ac7ddfbfSEd Maste   return m_breakpoint_site_list;
1804ac7ddfbfSEd Maste }
1805ac7ddfbfSEd Maste 
DisableAllBreakpointSites()1806435933ddSDimitry Andric void Process::DisableAllBreakpointSites() {
1807ac7ddfbfSEd Maste   m_breakpoint_site_list.ForEach([this](BreakpointSite *bp_site) -> void {
1808ac7ddfbfSEd Maste     //        bp_site->SetEnabled(true);
1809ac7ddfbfSEd Maste     DisableBreakpointSite(bp_site);
1810ac7ddfbfSEd Maste   });
1811ac7ddfbfSEd Maste }
1812ac7ddfbfSEd Maste 
ClearBreakpointSiteByID(lldb::user_id_t break_id)18135517e702SDimitry Andric Status Process::ClearBreakpointSiteByID(lldb::user_id_t break_id) {
18145517e702SDimitry Andric   Status error(DisableBreakpointSiteByID(break_id));
1815ac7ddfbfSEd Maste 
1816ac7ddfbfSEd Maste   if (error.Success())
1817ac7ddfbfSEd Maste     m_breakpoint_site_list.Remove(break_id);
1818ac7ddfbfSEd Maste 
1819ac7ddfbfSEd Maste   return error;
1820ac7ddfbfSEd Maste }
1821ac7ddfbfSEd Maste 
DisableBreakpointSiteByID(lldb::user_id_t break_id)18225517e702SDimitry Andric Status Process::DisableBreakpointSiteByID(lldb::user_id_t break_id) {
18235517e702SDimitry Andric   Status error;
1824ac7ddfbfSEd Maste   BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID(break_id);
1825435933ddSDimitry Andric   if (bp_site_sp) {
1826ac7ddfbfSEd Maste     if (bp_site_sp->IsEnabled())
1827ac7ddfbfSEd Maste       error = DisableBreakpointSite(bp_site_sp.get());
1828435933ddSDimitry Andric   } else {
1829435933ddSDimitry Andric     error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64,
1830435933ddSDimitry Andric                                    break_id);
1831ac7ddfbfSEd Maste   }
1832ac7ddfbfSEd Maste 
1833ac7ddfbfSEd Maste   return error;
1834ac7ddfbfSEd Maste }
1835ac7ddfbfSEd Maste 
EnableBreakpointSiteByID(lldb::user_id_t break_id)18365517e702SDimitry Andric Status Process::EnableBreakpointSiteByID(lldb::user_id_t break_id) {
18375517e702SDimitry Andric   Status error;
1838ac7ddfbfSEd Maste   BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID(break_id);
1839435933ddSDimitry Andric   if (bp_site_sp) {
1840ac7ddfbfSEd Maste     if (!bp_site_sp->IsEnabled())
1841ac7ddfbfSEd Maste       error = EnableBreakpointSite(bp_site_sp.get());
1842435933ddSDimitry Andric   } else {
1843435933ddSDimitry Andric     error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64,
1844435933ddSDimitry Andric                                    break_id);
1845ac7ddfbfSEd Maste   }
1846ac7ddfbfSEd Maste   return error;
1847ac7ddfbfSEd Maste }
1848ac7ddfbfSEd Maste 
1849ac7ddfbfSEd Maste lldb::break_id_t
CreateBreakpointSite(const BreakpointLocationSP & owner,bool use_hardware)1850435933ddSDimitry Andric Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
1851435933ddSDimitry Andric                               bool use_hardware) {
185212b93ac6SEd Maste   addr_t load_addr = LLDB_INVALID_ADDRESS;
185312b93ac6SEd Maste 
185412b93ac6SEd Maste   bool show_error = true;
1855435933ddSDimitry Andric   switch (GetState()) {
185612b93ac6SEd Maste   case eStateInvalid:
185712b93ac6SEd Maste   case eStateUnloaded:
185812b93ac6SEd Maste   case eStateConnected:
185912b93ac6SEd Maste   case eStateAttaching:
186012b93ac6SEd Maste   case eStateLaunching:
186112b93ac6SEd Maste   case eStateDetached:
186212b93ac6SEd Maste   case eStateExited:
186312b93ac6SEd Maste     show_error = false;
186412b93ac6SEd Maste     break;
186512b93ac6SEd Maste 
186612b93ac6SEd Maste   case eStateStopped:
186712b93ac6SEd Maste   case eStateRunning:
186812b93ac6SEd Maste   case eStateStepping:
186912b93ac6SEd Maste   case eStateCrashed:
187012b93ac6SEd Maste   case eStateSuspended:
187112b93ac6SEd Maste     show_error = IsAlive();
187212b93ac6SEd Maste     break;
187312b93ac6SEd Maste   }
187412b93ac6SEd Maste 
18754ba319b5SDimitry Andric   // Reset the IsIndirect flag here, in case the location changes from pointing
18764ba319b5SDimitry Andric   // to a indirect symbol to a regular symbol.
187712b93ac6SEd Maste   owner->SetIsIndirect(false);
187812b93ac6SEd Maste 
1879435933ddSDimitry Andric   if (owner->ShouldResolveIndirectFunctions()) {
188012b93ac6SEd Maste     Symbol *symbol = owner->GetAddress().CalculateSymbolContextSymbol();
1881435933ddSDimitry Andric     if (symbol && symbol->IsIndirect()) {
18825517e702SDimitry Andric       Status error;
18831c3bbb01SEd Maste       Address symbol_address = symbol->GetAddress();
18841c3bbb01SEd Maste       load_addr = ResolveIndirectFunction(&symbol_address, error);
1885435933ddSDimitry Andric       if (!error.Success() && show_error) {
1886435933ddSDimitry Andric         GetTarget().GetDebugger().GetErrorFile()->Printf(
1887435933ddSDimitry Andric             "warning: failed to resolve indirect function at 0x%" PRIx64
1888435933ddSDimitry Andric             " for breakpoint %i.%i: %s\n",
18899f2f44ceSEd Maste             symbol->GetLoadAddress(&GetTarget()),
1890435933ddSDimitry Andric             owner->GetBreakpoint().GetID(), owner->GetID(),
18910127ef0fSEd Maste             error.AsCString() ? error.AsCString() : "unknown error");
189212b93ac6SEd Maste         return LLDB_INVALID_BREAK_ID;
189312b93ac6SEd Maste       }
189412b93ac6SEd Maste       Address resolved_address(load_addr);
18959f2f44ceSEd Maste       load_addr = resolved_address.GetOpcodeLoadAddress(&GetTarget());
189612b93ac6SEd Maste       owner->SetIsIndirect(true);
1897435933ddSDimitry Andric     } else
18989f2f44ceSEd Maste       load_addr = owner->GetAddress().GetOpcodeLoadAddress(&GetTarget());
1899435933ddSDimitry Andric   } else
19009f2f44ceSEd Maste     load_addr = owner->GetAddress().GetOpcodeLoadAddress(&GetTarget());
190112b93ac6SEd Maste 
1902435933ddSDimitry Andric   if (load_addr != LLDB_INVALID_ADDRESS) {
1903ac7ddfbfSEd Maste     BreakpointSiteSP bp_site_sp;
1904ac7ddfbfSEd Maste 
1905435933ddSDimitry Andric     // Look up this breakpoint site.  If it exists, then add this new owner,
19064ba319b5SDimitry Andric     // otherwise create a new breakpoint site and add it.
1907ac7ddfbfSEd Maste 
1908ac7ddfbfSEd Maste     bp_site_sp = m_breakpoint_site_list.FindByAddress(load_addr);
1909ac7ddfbfSEd Maste 
1910435933ddSDimitry Andric     if (bp_site_sp) {
1911ac7ddfbfSEd Maste       bp_site_sp->AddOwner(owner);
1912ac7ddfbfSEd Maste       owner->SetBreakpointSite(bp_site_sp);
1913ac7ddfbfSEd Maste       return bp_site_sp->GetID();
1914435933ddSDimitry Andric     } else {
1915435933ddSDimitry Andric       bp_site_sp.reset(new BreakpointSite(&m_breakpoint_site_list, owner,
1916435933ddSDimitry Andric                                           load_addr, use_hardware));
1917435933ddSDimitry Andric       if (bp_site_sp) {
19185517e702SDimitry Andric         Status error = EnableBreakpointSite(bp_site_sp.get());
1919435933ddSDimitry Andric         if (error.Success()) {
1920ac7ddfbfSEd Maste           owner->SetBreakpointSite(bp_site_sp);
1921ac7ddfbfSEd Maste           return m_breakpoint_site_list.Add(bp_site_sp);
1922435933ddSDimitry Andric         } else {
1923*b5893f02SDimitry Andric           if (show_error || use_hardware) {
192435617911SEd Maste             // Report error for setting breakpoint...
1925435933ddSDimitry Andric             GetTarget().GetDebugger().GetErrorFile()->Printf(
1926435933ddSDimitry Andric                 "warning: failed to set breakpoint site at 0x%" PRIx64
1927435933ddSDimitry Andric                 " for breakpoint %i.%i: %s\n",
1928435933ddSDimitry Andric                 load_addr, owner->GetBreakpoint().GetID(), owner->GetID(),
19290127ef0fSEd Maste                 error.AsCString() ? error.AsCString() : "unknown error");
193035617911SEd Maste           }
1931ac7ddfbfSEd Maste         }
1932ac7ddfbfSEd Maste       }
1933ac7ddfbfSEd Maste     }
1934b952cd58SEd Maste   }
1935ac7ddfbfSEd Maste   // We failed to enable the breakpoint
1936ac7ddfbfSEd Maste   return LLDB_INVALID_BREAK_ID;
1937ac7ddfbfSEd Maste }
1938ac7ddfbfSEd Maste 
RemoveOwnerFromBreakpointSite(lldb::user_id_t owner_id,lldb::user_id_t owner_loc_id,BreakpointSiteSP & bp_site_sp)1939435933ddSDimitry Andric void Process::RemoveOwnerFromBreakpointSite(lldb::user_id_t owner_id,
1940435933ddSDimitry Andric                                             lldb::user_id_t owner_loc_id,
1941435933ddSDimitry Andric                                             BreakpointSiteSP &bp_site_sp) {
1942ac7ddfbfSEd Maste   uint32_t num_owners = bp_site_sp->RemoveOwner(owner_id, owner_loc_id);
1943435933ddSDimitry Andric   if (num_owners == 0) {
1944ac7ddfbfSEd Maste     // Don't try to disable the site if we don't have a live process anymore.
1945ac7ddfbfSEd Maste     if (IsAlive())
1946ac7ddfbfSEd Maste       DisableBreakpointSite(bp_site_sp.get());
1947ac7ddfbfSEd Maste     m_breakpoint_site_list.RemoveByAddress(bp_site_sp->GetLoadAddress());
1948ac7ddfbfSEd Maste   }
1949ac7ddfbfSEd Maste }
1950ac7ddfbfSEd Maste 
RemoveBreakpointOpcodesFromBuffer(addr_t bp_addr,size_t size,uint8_t * buf) const1951435933ddSDimitry Andric size_t Process::RemoveBreakpointOpcodesFromBuffer(addr_t bp_addr, size_t size,
1952435933ddSDimitry Andric                                                   uint8_t *buf) const {
1953ac7ddfbfSEd Maste   size_t bytes_removed = 0;
1954ac7ddfbfSEd Maste   BreakpointSiteList bp_sites_in_range;
1955ac7ddfbfSEd Maste 
1956435933ddSDimitry Andric   if (m_breakpoint_site_list.FindInRange(bp_addr, bp_addr + size,
1957435933ddSDimitry Andric                                          bp_sites_in_range)) {
1958f678e45dSDimitry Andric     bp_sites_in_range.ForEach([bp_addr, size,
1959f678e45dSDimitry Andric                                buf](BreakpointSite *bp_site) -> void {
1960435933ddSDimitry Andric       if (bp_site->GetType() == BreakpointSite::eSoftware) {
1961ac7ddfbfSEd Maste         addr_t intersect_addr;
1962ac7ddfbfSEd Maste         size_t intersect_size;
1963ac7ddfbfSEd Maste         size_t opcode_offset;
1964435933ddSDimitry Andric         if (bp_site->IntersectsRange(bp_addr, size, &intersect_addr,
1965435933ddSDimitry Andric                                      &intersect_size, &opcode_offset)) {
1966ac7ddfbfSEd Maste           assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size);
1967435933ddSDimitry Andric           assert(bp_addr < intersect_addr + intersect_size &&
1968435933ddSDimitry Andric                  intersect_addr + intersect_size <= bp_addr + size);
1969ac7ddfbfSEd Maste           assert(opcode_offset + intersect_size <= bp_site->GetByteSize());
1970ac7ddfbfSEd Maste           size_t buf_offset = intersect_addr - bp_addr;
1971435933ddSDimitry Andric           ::memcpy(buf + buf_offset,
1972435933ddSDimitry Andric                    bp_site->GetSavedOpcodeBytes() + opcode_offset,
1973435933ddSDimitry Andric                    intersect_size);
1974ac7ddfbfSEd Maste         }
1975ac7ddfbfSEd Maste       }
1976ac7ddfbfSEd Maste     });
1977ac7ddfbfSEd Maste   }
1978ac7ddfbfSEd Maste   return bytes_removed;
1979ac7ddfbfSEd Maste }
1980ac7ddfbfSEd Maste 
GetSoftwareBreakpointTrapOpcode(BreakpointSite * bp_site)1981435933ddSDimitry Andric size_t Process::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
19829f2f44ceSEd Maste   PlatformSP platform_sp(GetTarget().GetPlatform());
1983ac7ddfbfSEd Maste   if (platform_sp)
19849f2f44ceSEd Maste     return platform_sp->GetSoftwareBreakpointTrapOpcode(GetTarget(), bp_site);
1985ac7ddfbfSEd Maste   return 0;
1986ac7ddfbfSEd Maste }
1987ac7ddfbfSEd Maste 
EnableSoftwareBreakpoint(BreakpointSite * bp_site)19885517e702SDimitry Andric Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) {
19895517e702SDimitry Andric   Status error;
19904bb0738eSEd Maste   assert(bp_site != nullptr);
1991ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
1992ac7ddfbfSEd Maste   const addr_t bp_addr = bp_site->GetLoadAddress();
1993ac7ddfbfSEd Maste   if (log)
1994435933ddSDimitry Andric     log->Printf(
1995435933ddSDimitry Andric         "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64,
1996435933ddSDimitry Andric         bp_site->GetID(), (uint64_t)bp_addr);
1997435933ddSDimitry Andric   if (bp_site->IsEnabled()) {
1998ac7ddfbfSEd Maste     if (log)
1999435933ddSDimitry Andric       log->Printf(
2000435933ddSDimitry Andric           "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
2001435933ddSDimitry Andric           " -- already enabled",
2002435933ddSDimitry Andric           bp_site->GetID(), (uint64_t)bp_addr);
2003ac7ddfbfSEd Maste     return error;
2004ac7ddfbfSEd Maste   }
2005ac7ddfbfSEd Maste 
2006435933ddSDimitry Andric   if (bp_addr == LLDB_INVALID_ADDRESS) {
2007ac7ddfbfSEd Maste     error.SetErrorString("BreakpointSite contains an invalid load address.");
2008ac7ddfbfSEd Maste     return error;
2009ac7ddfbfSEd Maste   }
2010ac7ddfbfSEd Maste   // Ask the lldb::Process subclass to fill in the correct software breakpoint
2011ac7ddfbfSEd Maste   // trap for the breakpoint site
2012ac7ddfbfSEd Maste   const size_t bp_opcode_size = GetSoftwareBreakpointTrapOpcode(bp_site);
2013ac7ddfbfSEd Maste 
2014435933ddSDimitry Andric   if (bp_opcode_size == 0) {
2015435933ddSDimitry Andric     error.SetErrorStringWithFormat("Process::GetSoftwareBreakpointTrapOpcode() "
2016435933ddSDimitry Andric                                    "returned zero, unable to get breakpoint "
2017435933ddSDimitry Andric                                    "trap for address 0x%" PRIx64,
2018435933ddSDimitry Andric                                    bp_addr);
2019435933ddSDimitry Andric   } else {
2020ac7ddfbfSEd Maste     const uint8_t *const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes();
2021ac7ddfbfSEd Maste 
2022435933ddSDimitry Andric     if (bp_opcode_bytes == nullptr) {
2023435933ddSDimitry Andric       error.SetErrorString(
2024435933ddSDimitry Andric           "BreakpointSite doesn't contain a valid breakpoint trap opcode.");
2025ac7ddfbfSEd Maste       return error;
2026ac7ddfbfSEd Maste     }
2027ac7ddfbfSEd Maste 
2028ac7ddfbfSEd Maste     // Save the original opcode by reading it
2029435933ddSDimitry Andric     if (DoReadMemory(bp_addr, bp_site->GetSavedOpcodeBytes(), bp_opcode_size,
2030435933ddSDimitry Andric                      error) == bp_opcode_size) {
2031ac7ddfbfSEd Maste       // Write a software breakpoint in place of the original opcode
2032435933ddSDimitry Andric       if (DoWriteMemory(bp_addr, bp_opcode_bytes, bp_opcode_size, error) ==
2033435933ddSDimitry Andric           bp_opcode_size) {
2034ac7ddfbfSEd Maste         uint8_t verify_bp_opcode_bytes[64];
2035435933ddSDimitry Andric         if (DoReadMemory(bp_addr, verify_bp_opcode_bytes, bp_opcode_size,
2036435933ddSDimitry Andric                          error) == bp_opcode_size) {
2037435933ddSDimitry Andric           if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes,
2038435933ddSDimitry Andric                        bp_opcode_size) == 0) {
2039ac7ddfbfSEd Maste             bp_site->SetEnabled(true);
2040ac7ddfbfSEd Maste             bp_site->SetType(BreakpointSite::eSoftware);
2041ac7ddfbfSEd Maste             if (log)
2042435933ddSDimitry Andric               log->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) "
2043435933ddSDimitry Andric                           "addr = 0x%" PRIx64 " -- SUCCESS",
2044435933ddSDimitry Andric                           bp_site->GetID(), (uint64_t)bp_addr);
2045435933ddSDimitry Andric           } else
2046435933ddSDimitry Andric             error.SetErrorString(
2047435933ddSDimitry Andric                 "failed to verify the breakpoint trap in memory.");
2048435933ddSDimitry Andric         } else
2049435933ddSDimitry Andric           error.SetErrorString(
2050435933ddSDimitry Andric               "Unable to read memory to verify breakpoint trap.");
2051435933ddSDimitry Andric       } else
2052ac7ddfbfSEd Maste         error.SetErrorString("Unable to write breakpoint trap to memory.");
2053435933ddSDimitry Andric     } else
2054ac7ddfbfSEd Maste       error.SetErrorString("Unable to read memory at breakpoint address.");
2055ac7ddfbfSEd Maste   }
2056ac7ddfbfSEd Maste   if (log && error.Fail())
2057435933ddSDimitry Andric     log->Printf(
2058435933ddSDimitry Andric         "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
2059435933ddSDimitry Andric         " -- FAILED: %s",
2060435933ddSDimitry Andric         bp_site->GetID(), (uint64_t)bp_addr, error.AsCString());
2061ac7ddfbfSEd Maste   return error;
2062ac7ddfbfSEd Maste }
2063ac7ddfbfSEd Maste 
DisableSoftwareBreakpoint(BreakpointSite * bp_site)20645517e702SDimitry Andric Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
20655517e702SDimitry Andric   Status error;
20664bb0738eSEd Maste   assert(bp_site != nullptr);
2067ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
2068ac7ddfbfSEd Maste   addr_t bp_addr = bp_site->GetLoadAddress();
2069ac7ddfbfSEd Maste   lldb::user_id_t breakID = bp_site->GetID();
2070ac7ddfbfSEd Maste   if (log)
2071435933ddSDimitry Andric     log->Printf("Process::DisableSoftwareBreakpoint (breakID = %" PRIu64
2072435933ddSDimitry Andric                 ") addr = 0x%" PRIx64,
2073435933ddSDimitry Andric                 breakID, (uint64_t)bp_addr);
2074ac7ddfbfSEd Maste 
2075435933ddSDimitry Andric   if (bp_site->IsHardware()) {
2076ac7ddfbfSEd Maste     error.SetErrorString("Breakpoint site is a hardware breakpoint.");
2077435933ddSDimitry Andric   } else if (bp_site->IsEnabled()) {
2078ac7ddfbfSEd Maste     const size_t break_op_size = bp_site->GetByteSize();
2079ac7ddfbfSEd Maste     const uint8_t *const break_op = bp_site->GetTrapOpcodeBytes();
2080435933ddSDimitry Andric     if (break_op_size > 0) {
20810127ef0fSEd Maste       // Clear a software breakpoint instruction
2082ac7ddfbfSEd Maste       uint8_t curr_break_op[8];
2083ac7ddfbfSEd Maste       assert(break_op_size <= sizeof(curr_break_op));
2084ac7ddfbfSEd Maste       bool break_op_found = false;
2085ac7ddfbfSEd Maste 
2086ac7ddfbfSEd Maste       // Read the breakpoint opcode
2087435933ddSDimitry Andric       if (DoReadMemory(bp_addr, curr_break_op, break_op_size, error) ==
2088435933ddSDimitry Andric           break_op_size) {
2089ac7ddfbfSEd Maste         bool verify = false;
20901c3bbb01SEd Maste         // Make sure the breakpoint opcode exists at this address
2091435933ddSDimitry Andric         if (::memcmp(curr_break_op, break_op, break_op_size) == 0) {
2092ac7ddfbfSEd Maste           break_op_found = true;
2093ac7ddfbfSEd Maste           // We found a valid breakpoint opcode at this address, now restore
2094ac7ddfbfSEd Maste           // the saved opcode.
2095435933ddSDimitry Andric           if (DoWriteMemory(bp_addr, bp_site->GetSavedOpcodeBytes(),
2096435933ddSDimitry Andric                             break_op_size, error) == break_op_size) {
2097ac7ddfbfSEd Maste             verify = true;
2098435933ddSDimitry Andric           } else
2099435933ddSDimitry Andric             error.SetErrorString(
2100435933ddSDimitry Andric                 "Memory write failed when restoring original opcode.");
2101435933ddSDimitry Andric         } else {
2102435933ddSDimitry Andric           error.SetErrorString(
2103435933ddSDimitry Andric               "Original breakpoint trap is no longer in memory.");
2104435933ddSDimitry Andric           // Set verify to true and so we can check if the original opcode has
2105435933ddSDimitry Andric           // already been restored
2106ac7ddfbfSEd Maste           verify = true;
2107ac7ddfbfSEd Maste         }
2108ac7ddfbfSEd Maste 
2109435933ddSDimitry Andric         if (verify) {
2110ac7ddfbfSEd Maste           uint8_t verify_opcode[8];
2111ac7ddfbfSEd Maste           assert(break_op_size < sizeof(verify_opcode));
2112ac7ddfbfSEd Maste           // Verify that our original opcode made it back to the inferior
2113435933ddSDimitry Andric           if (DoReadMemory(bp_addr, verify_opcode, break_op_size, error) ==
2114435933ddSDimitry Andric               break_op_size) {
2115ac7ddfbfSEd Maste             // compare the memory we just read with the original opcode
2116435933ddSDimitry Andric             if (::memcmp(bp_site->GetSavedOpcodeBytes(), verify_opcode,
2117435933ddSDimitry Andric                          break_op_size) == 0) {
2118ac7ddfbfSEd Maste               // SUCCESS
2119ac7ddfbfSEd Maste               bp_site->SetEnabled(false);
2120ac7ddfbfSEd Maste               if (log)
2121435933ddSDimitry Andric                 log->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) "
2122435933ddSDimitry Andric                             "addr = 0x%" PRIx64 " -- SUCCESS",
2123435933ddSDimitry Andric                             bp_site->GetID(), (uint64_t)bp_addr);
2124ac7ddfbfSEd Maste               return error;
2125435933ddSDimitry Andric             } else {
2126ac7ddfbfSEd Maste               if (break_op_found)
2127ac7ddfbfSEd Maste                 error.SetErrorString("Failed to restore original opcode.");
2128ac7ddfbfSEd Maste             }
2129435933ddSDimitry Andric           } else
2130435933ddSDimitry Andric             error.SetErrorString("Failed to read memory to verify that "
2131435933ddSDimitry Andric                                  "breakpoint trap was restored.");
2132ac7ddfbfSEd Maste         }
2133435933ddSDimitry Andric       } else
2134435933ddSDimitry Andric         error.SetErrorString(
2135435933ddSDimitry Andric             "Unable to read memory that should contain the breakpoint trap.");
2136ac7ddfbfSEd Maste     }
2137435933ddSDimitry Andric   } else {
2138ac7ddfbfSEd Maste     if (log)
2139435933ddSDimitry Andric       log->Printf(
2140435933ddSDimitry Andric           "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
2141435933ddSDimitry Andric           " -- already disabled",
2142435933ddSDimitry Andric           bp_site->GetID(), (uint64_t)bp_addr);
2143ac7ddfbfSEd Maste     return error;
2144ac7ddfbfSEd Maste   }
2145ac7ddfbfSEd Maste 
2146ac7ddfbfSEd Maste   if (log)
2147435933ddSDimitry Andric     log->Printf(
2148435933ddSDimitry Andric         "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
2149435933ddSDimitry Andric         " -- FAILED: %s",
2150435933ddSDimitry Andric         bp_site->GetID(), (uint64_t)bp_addr, error.AsCString());
2151ac7ddfbfSEd Maste   return error;
2152ac7ddfbfSEd Maste }
2153ac7ddfbfSEd Maste 
21544ba319b5SDimitry Andric // Uncomment to verify memory caching works after making changes to caching
21554ba319b5SDimitry Andric // code
2156ac7ddfbfSEd Maste //#define VERIFY_MEMORY_READS
2157ac7ddfbfSEd Maste 
ReadMemory(addr_t addr,void * buf,size_t size,Status & error)21585517e702SDimitry Andric size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) {
2159b952cd58SEd Maste   error.Clear();
2160435933ddSDimitry Andric   if (!GetDisableMemoryCache()) {
2161ac7ddfbfSEd Maste #if defined(VERIFY_MEMORY_READS)
2162ac7ddfbfSEd Maste     // Memory caching is enabled, with debug verification
2163ac7ddfbfSEd Maste 
2164435933ddSDimitry Andric     if (buf && size) {
2165ac7ddfbfSEd Maste       // Uncomment the line below to make sure memory caching is working.
2166ac7ddfbfSEd Maste       // I ran this through the test suite and got no assertions, so I am
2167ac7ddfbfSEd Maste       // pretty confident this is working well. If any changes are made to
2168ac7ddfbfSEd Maste       // memory caching, uncomment the line below and test your changes!
2169ac7ddfbfSEd Maste 
2170ac7ddfbfSEd Maste       // Verify all memory reads by using the cache first, then redundantly
2171ac7ddfbfSEd Maste       // reading the same memory from the inferior and comparing to make sure
2172ac7ddfbfSEd Maste       // everything is exactly the same.
2173ac7ddfbfSEd Maste       std::string verify_buf(size, '\0');
2174ac7ddfbfSEd Maste       assert(verify_buf.size() == size);
2175435933ddSDimitry Andric       const size_t cache_bytes_read =
2176435933ddSDimitry Andric           m_memory_cache.Read(this, addr, buf, size, error);
21775517e702SDimitry Andric       Status verify_error;
2178435933ddSDimitry Andric       const size_t verify_bytes_read =
2179435933ddSDimitry Andric           ReadMemoryFromInferior(addr, const_cast<char *>(verify_buf.data()),
2180435933ddSDimitry Andric                                  verify_buf.size(), verify_error);
2181ac7ddfbfSEd Maste       assert(cache_bytes_read == verify_bytes_read);
2182ac7ddfbfSEd Maste       assert(memcmp(buf, verify_buf.data(), verify_buf.size()) == 0);
2183ac7ddfbfSEd Maste       assert(verify_error.Success() == error.Success());
2184ac7ddfbfSEd Maste       return cache_bytes_read;
2185ac7ddfbfSEd Maste     }
2186ac7ddfbfSEd Maste     return 0;
2187ac7ddfbfSEd Maste #else  // !defined(VERIFY_MEMORY_READS)
2188ac7ddfbfSEd Maste     // Memory caching is enabled, without debug verification
2189ac7ddfbfSEd Maste 
2190ac7ddfbfSEd Maste     return m_memory_cache.Read(addr, buf, size, error);
2191ac7ddfbfSEd Maste #endif // defined (VERIFY_MEMORY_READS)
2192435933ddSDimitry Andric   } else {
2193ac7ddfbfSEd Maste     // Memory caching is disabled
2194ac7ddfbfSEd Maste 
2195ac7ddfbfSEd Maste     return ReadMemoryFromInferior(addr, buf, size, error);
2196ac7ddfbfSEd Maste   }
2197ac7ddfbfSEd Maste }
2198ac7ddfbfSEd Maste 
ReadCStringFromMemory(addr_t addr,std::string & out_str,Status & error)2199435933ddSDimitry Andric size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str,
22005517e702SDimitry Andric                                       Status &error) {
2201ac7ddfbfSEd Maste   char buf[256];
2202ac7ddfbfSEd Maste   out_str.clear();
2203ac7ddfbfSEd Maste   addr_t curr_addr = addr;
2204435933ddSDimitry Andric   while (true) {
2205ac7ddfbfSEd Maste     size_t length = ReadCStringFromMemory(curr_addr, buf, sizeof(buf), error);
2206ac7ddfbfSEd Maste     if (length == 0)
2207ac7ddfbfSEd Maste       break;
2208ac7ddfbfSEd Maste     out_str.append(buf, length);
22094ba319b5SDimitry Andric     // If we got "length - 1" bytes, we didn't get the whole C string, we need
22104ba319b5SDimitry Andric     // to read some more characters
2211ac7ddfbfSEd Maste     if (length == sizeof(buf) - 1)
2212ac7ddfbfSEd Maste       curr_addr += length;
2213ac7ddfbfSEd Maste     else
2214ac7ddfbfSEd Maste       break;
2215ac7ddfbfSEd Maste   }
2216ac7ddfbfSEd Maste   return out_str.size();
2217ac7ddfbfSEd Maste }
2218ac7ddfbfSEd Maste 
ReadStringFromMemory(addr_t addr,char * dst,size_t max_bytes,Status & error,size_t type_width)2219435933ddSDimitry Andric size_t Process::ReadStringFromMemory(addr_t addr, char *dst, size_t max_bytes,
22205517e702SDimitry Andric                                      Status &error, size_t type_width) {
2221ac7ddfbfSEd Maste   size_t total_bytes_read = 0;
2222435933ddSDimitry Andric   if (dst && max_bytes && type_width && max_bytes >= type_width) {
22234ba319b5SDimitry Andric     // Ensure a null terminator independent of the number of bytes that is
22244ba319b5SDimitry Andric     // read.
2225ac7ddfbfSEd Maste     memset(dst, 0, max_bytes);
2226ac7ddfbfSEd Maste     size_t bytes_left = max_bytes - type_width;
2227ac7ddfbfSEd Maste 
2228ac7ddfbfSEd Maste     const char terminator[4] = {'\0', '\0', '\0', '\0'};
2229435933ddSDimitry Andric     assert(sizeof(terminator) >= type_width && "Attempting to validate a "
2230435933ddSDimitry Andric                                                "string with more than 4 bytes "
2231435933ddSDimitry Andric                                                "per character!");
2232ac7ddfbfSEd Maste 
2233ac7ddfbfSEd Maste     addr_t curr_addr = addr;
2234ac7ddfbfSEd Maste     const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize();
2235ac7ddfbfSEd Maste     char *curr_dst = dst;
2236ac7ddfbfSEd Maste 
2237ac7ddfbfSEd Maste     error.Clear();
2238435933ddSDimitry Andric     while (bytes_left > 0 && error.Success()) {
2239435933ddSDimitry Andric       addr_t cache_line_bytes_left =
2240435933ddSDimitry Andric           cache_line_size - (curr_addr % cache_line_size);
2241435933ddSDimitry Andric       addr_t bytes_to_read =
2242435933ddSDimitry Andric           std::min<addr_t>(bytes_left, cache_line_bytes_left);
2243ac7ddfbfSEd Maste       size_t bytes_read = ReadMemory(curr_addr, curr_dst, bytes_to_read, error);
2244ac7ddfbfSEd Maste 
2245ac7ddfbfSEd Maste       if (bytes_read == 0)
2246ac7ddfbfSEd Maste         break;
2247ac7ddfbfSEd Maste 
2248435933ddSDimitry Andric       // Search for a null terminator of correct size and alignment in
2249435933ddSDimitry Andric       // bytes_read
2250ac7ddfbfSEd Maste       size_t aligned_start = total_bytes_read - total_bytes_read % type_width;
2251435933ddSDimitry Andric       for (size_t i = aligned_start;
2252435933ddSDimitry Andric            i + type_width <= total_bytes_read + bytes_read; i += type_width)
2253435933ddSDimitry Andric         if (::memcmp(&dst[i], terminator, type_width) == 0) {
2254ac7ddfbfSEd Maste           error.Clear();
2255ac7ddfbfSEd Maste           return i;
2256ac7ddfbfSEd Maste         }
2257ac7ddfbfSEd Maste 
2258ac7ddfbfSEd Maste       total_bytes_read += bytes_read;
2259ac7ddfbfSEd Maste       curr_dst += bytes_read;
2260ac7ddfbfSEd Maste       curr_addr += bytes_read;
2261ac7ddfbfSEd Maste       bytes_left -= bytes_read;
2262ac7ddfbfSEd Maste     }
2263435933ddSDimitry Andric   } else {
2264ac7ddfbfSEd Maste     if (max_bytes)
2265ac7ddfbfSEd Maste       error.SetErrorString("invalid arguments");
2266ac7ddfbfSEd Maste   }
2267ac7ddfbfSEd Maste   return total_bytes_read;
2268ac7ddfbfSEd Maste }
2269ac7ddfbfSEd Maste 
2270435933ddSDimitry Andric // Deprecated in favor of ReadStringFromMemory which has wchar support and
22714ba319b5SDimitry Andric // correct code to find null terminators.
ReadCStringFromMemory(addr_t addr,char * dst,size_t dst_max_len,Status & result_error)2272435933ddSDimitry Andric size_t Process::ReadCStringFromMemory(addr_t addr, char *dst,
22735517e702SDimitry Andric                                       size_t dst_max_len,
22745517e702SDimitry Andric                                       Status &result_error) {
2275ac7ddfbfSEd Maste   size_t total_cstr_len = 0;
2276435933ddSDimitry Andric   if (dst && dst_max_len) {
2277ac7ddfbfSEd Maste     result_error.Clear();
2278ac7ddfbfSEd Maste     // NULL out everything just to be safe
2279ac7ddfbfSEd Maste     memset(dst, 0, dst_max_len);
22805517e702SDimitry Andric     Status error;
2281ac7ddfbfSEd Maste     addr_t curr_addr = addr;
2282ac7ddfbfSEd Maste     const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize();
2283ac7ddfbfSEd Maste     size_t bytes_left = dst_max_len - 1;
2284ac7ddfbfSEd Maste     char *curr_dst = dst;
2285ac7ddfbfSEd Maste 
2286435933ddSDimitry Andric     while (bytes_left > 0) {
2287435933ddSDimitry Andric       addr_t cache_line_bytes_left =
2288435933ddSDimitry Andric           cache_line_size - (curr_addr % cache_line_size);
2289435933ddSDimitry Andric       addr_t bytes_to_read =
2290435933ddSDimitry Andric           std::min<addr_t>(bytes_left, cache_line_bytes_left);
2291ac7ddfbfSEd Maste       size_t bytes_read = ReadMemory(curr_addr, curr_dst, bytes_to_read, error);
2292ac7ddfbfSEd Maste 
2293435933ddSDimitry Andric       if (bytes_read == 0) {
2294ac7ddfbfSEd Maste         result_error = error;
2295ac7ddfbfSEd Maste         dst[total_cstr_len] = '\0';
2296ac7ddfbfSEd Maste         break;
2297ac7ddfbfSEd Maste       }
2298ac7ddfbfSEd Maste       const size_t len = strlen(curr_dst);
2299ac7ddfbfSEd Maste 
2300ac7ddfbfSEd Maste       total_cstr_len += len;
2301ac7ddfbfSEd Maste 
2302ac7ddfbfSEd Maste       if (len < bytes_to_read)
2303ac7ddfbfSEd Maste         break;
2304ac7ddfbfSEd Maste 
2305ac7ddfbfSEd Maste       curr_dst += bytes_read;
2306ac7ddfbfSEd Maste       curr_addr += bytes_read;
2307ac7ddfbfSEd Maste       bytes_left -= bytes_read;
2308ac7ddfbfSEd Maste     }
2309435933ddSDimitry Andric   } else {
23104bb0738eSEd Maste     if (dst == nullptr)
2311ac7ddfbfSEd Maste       result_error.SetErrorString("invalid arguments");
2312ac7ddfbfSEd Maste     else
2313ac7ddfbfSEd Maste       result_error.Clear();
2314ac7ddfbfSEd Maste   }
2315ac7ddfbfSEd Maste   return total_cstr_len;
2316ac7ddfbfSEd Maste }
2317ac7ddfbfSEd Maste 
ReadMemoryFromInferior(addr_t addr,void * buf,size_t size,Status & error)2318435933ddSDimitry Andric size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size,
23195517e702SDimitry Andric                                        Status &error) {
23204bb0738eSEd Maste   if (buf == nullptr || size == 0)
2321ac7ddfbfSEd Maste     return 0;
2322ac7ddfbfSEd Maste 
2323ac7ddfbfSEd Maste   size_t bytes_read = 0;
2324ac7ddfbfSEd Maste   uint8_t *bytes = (uint8_t *)buf;
2325ac7ddfbfSEd Maste 
2326435933ddSDimitry Andric   while (bytes_read < size) {
2327ac7ddfbfSEd Maste     const size_t curr_size = size - bytes_read;
2328435933ddSDimitry Andric     const size_t curr_bytes_read =
2329435933ddSDimitry Andric         DoReadMemory(addr + bytes_read, bytes + bytes_read, curr_size, error);
2330ac7ddfbfSEd Maste     bytes_read += curr_bytes_read;
2331ac7ddfbfSEd Maste     if (curr_bytes_read == curr_size || curr_bytes_read == 0)
2332ac7ddfbfSEd Maste       break;
2333ac7ddfbfSEd Maste   }
2334ac7ddfbfSEd Maste 
2335ac7ddfbfSEd Maste   // Replace any software breakpoint opcodes that fall into this range back
2336ac7ddfbfSEd Maste   // into "buf" before we return
2337ac7ddfbfSEd Maste   if (bytes_read > 0)
2338ac7ddfbfSEd Maste     RemoveBreakpointOpcodesFromBuffer(addr, bytes_read, (uint8_t *)buf);
2339ac7ddfbfSEd Maste   return bytes_read;
2340ac7ddfbfSEd Maste }
2341ac7ddfbfSEd Maste 
ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr,size_t integer_byte_size,uint64_t fail_value,Status & error)2342435933ddSDimitry Andric uint64_t Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr,
2343435933ddSDimitry Andric                                                 size_t integer_byte_size,
2344435933ddSDimitry Andric                                                 uint64_t fail_value,
23455517e702SDimitry Andric                                                 Status &error) {
2346ac7ddfbfSEd Maste   Scalar scalar;
2347435933ddSDimitry Andric   if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar,
2348435933ddSDimitry Andric                                   error))
2349ac7ddfbfSEd Maste     return scalar.ULongLong(fail_value);
2350ac7ddfbfSEd Maste   return fail_value;
2351ac7ddfbfSEd Maste }
2352ac7ddfbfSEd Maste 
ReadSignedIntegerFromMemory(lldb::addr_t vm_addr,size_t integer_byte_size,int64_t fail_value,Status & error)2353435933ddSDimitry Andric int64_t Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr,
2354435933ddSDimitry Andric                                              size_t integer_byte_size,
23555517e702SDimitry Andric                                              int64_t fail_value,
23565517e702SDimitry Andric                                              Status &error) {
23574bb0738eSEd Maste   Scalar scalar;
2358435933ddSDimitry Andric   if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, true, scalar,
2359435933ddSDimitry Andric                                   error))
23604bb0738eSEd Maste     return scalar.SLongLong(fail_value);
23614bb0738eSEd Maste   return fail_value;
23624bb0738eSEd Maste }
23634bb0738eSEd Maste 
ReadPointerFromMemory(lldb::addr_t vm_addr,Status & error)23645517e702SDimitry Andric addr_t Process::ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error) {
2365ac7ddfbfSEd Maste   Scalar scalar;
2366435933ddSDimitry Andric   if (ReadScalarIntegerFromMemory(vm_addr, GetAddressByteSize(), false, scalar,
2367435933ddSDimitry Andric                                   error))
2368ac7ddfbfSEd Maste     return scalar.ULongLong(LLDB_INVALID_ADDRESS);
2369ac7ddfbfSEd Maste   return LLDB_INVALID_ADDRESS;
2370ac7ddfbfSEd Maste }
2371ac7ddfbfSEd Maste 
WritePointerToMemory(lldb::addr_t vm_addr,lldb::addr_t ptr_value,Status & error)2372435933ddSDimitry Andric bool Process::WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value,
23735517e702SDimitry Andric                                    Status &error) {
2374ac7ddfbfSEd Maste   Scalar scalar;
2375ac7ddfbfSEd Maste   const uint32_t addr_byte_size = GetAddressByteSize();
2376ac7ddfbfSEd Maste   if (addr_byte_size <= 4)
2377ac7ddfbfSEd Maste     scalar = (uint32_t)ptr_value;
2378ac7ddfbfSEd Maste   else
2379ac7ddfbfSEd Maste     scalar = ptr_value;
2380435933ddSDimitry Andric   return WriteScalarToMemory(vm_addr, scalar, addr_byte_size, error) ==
2381435933ddSDimitry Andric          addr_byte_size;
2382ac7ddfbfSEd Maste }
2383ac7ddfbfSEd Maste 
WriteMemoryPrivate(addr_t addr,const void * buf,size_t size,Status & error)2384435933ddSDimitry Andric size_t Process::WriteMemoryPrivate(addr_t addr, const void *buf, size_t size,
23855517e702SDimitry Andric                                    Status &error) {
2386ac7ddfbfSEd Maste   size_t bytes_written = 0;
2387ac7ddfbfSEd Maste   const uint8_t *bytes = (const uint8_t *)buf;
2388ac7ddfbfSEd Maste 
2389435933ddSDimitry Andric   while (bytes_written < size) {
2390ac7ddfbfSEd Maste     const size_t curr_size = size - bytes_written;
2391435933ddSDimitry Andric     const size_t curr_bytes_written = DoWriteMemory(
2392435933ddSDimitry Andric         addr + bytes_written, bytes + bytes_written, curr_size, error);
2393ac7ddfbfSEd Maste     bytes_written += curr_bytes_written;
2394ac7ddfbfSEd Maste     if (curr_bytes_written == curr_size || curr_bytes_written == 0)
2395ac7ddfbfSEd Maste       break;
2396ac7ddfbfSEd Maste   }
2397ac7ddfbfSEd Maste   return bytes_written;
2398ac7ddfbfSEd Maste }
2399ac7ddfbfSEd Maste 
WriteMemory(addr_t addr,const void * buf,size_t size,Status & error)2400435933ddSDimitry Andric size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
24015517e702SDimitry Andric                             Status &error) {
2402ac7ddfbfSEd Maste #if defined(ENABLE_MEMORY_CACHING)
2403ac7ddfbfSEd Maste   m_memory_cache.Flush(addr, size);
2404ac7ddfbfSEd Maste #endif
2405ac7ddfbfSEd Maste 
24064bb0738eSEd Maste   if (buf == nullptr || size == 0)
2407ac7ddfbfSEd Maste     return 0;
2408ac7ddfbfSEd Maste 
2409ac7ddfbfSEd Maste   m_mod_id.BumpMemoryID();
2410ac7ddfbfSEd Maste 
2411ac7ddfbfSEd Maste   // We need to write any data that would go where any current software traps
2412ac7ddfbfSEd Maste   // (enabled software breakpoints) any software traps (breakpoints) that we
2413ac7ddfbfSEd Maste   // may have placed in our tasks memory.
2414ac7ddfbfSEd Maste 
2415ac7ddfbfSEd Maste   BreakpointSiteList bp_sites_in_range;
2416ac7ddfbfSEd Maste 
2417435933ddSDimitry Andric   if (m_breakpoint_site_list.FindInRange(addr, addr + size,
2418435933ddSDimitry Andric                                          bp_sites_in_range)) {
2419ac7ddfbfSEd Maste     // No breakpoint sites overlap
2420ac7ddfbfSEd Maste     if (bp_sites_in_range.IsEmpty())
2421ac7ddfbfSEd Maste       return WriteMemoryPrivate(addr, buf, size, error);
2422435933ddSDimitry Andric     else {
2423ac7ddfbfSEd Maste       const uint8_t *ubuf = (const uint8_t *)buf;
2424ac7ddfbfSEd Maste       uint64_t bytes_written = 0;
2425ac7ddfbfSEd Maste 
2426435933ddSDimitry Andric       bp_sites_in_range.ForEach([this, addr, size, &bytes_written, &ubuf,
2427435933ddSDimitry Andric                                  &error](BreakpointSite *bp) -> void {
2428ac7ddfbfSEd Maste 
2429435933ddSDimitry Andric         if (error.Success()) {
2430ac7ddfbfSEd Maste           addr_t intersect_addr;
2431ac7ddfbfSEd Maste           size_t intersect_size;
2432ac7ddfbfSEd Maste           size_t opcode_offset;
2433435933ddSDimitry Andric           const bool intersects = bp->IntersectsRange(
2434435933ddSDimitry Andric               addr, size, &intersect_addr, &intersect_size, &opcode_offset);
24359f2f44ceSEd Maste           UNUSED_IF_ASSERT_DISABLED(intersects);
2436ac7ddfbfSEd Maste           assert(intersects);
2437ac7ddfbfSEd Maste           assert(addr <= intersect_addr && intersect_addr < addr + size);
2438435933ddSDimitry Andric           assert(addr < intersect_addr + intersect_size &&
2439435933ddSDimitry Andric                  intersect_addr + intersect_size <= addr + size);
2440ac7ddfbfSEd Maste           assert(opcode_offset + intersect_size <= bp->GetByteSize());
2441ac7ddfbfSEd Maste 
2442ac7ddfbfSEd Maste           // Check for bytes before this breakpoint
2443ac7ddfbfSEd Maste           const addr_t curr_addr = addr + bytes_written;
2444435933ddSDimitry Andric           if (intersect_addr > curr_addr) {
24454ba319b5SDimitry Andric             // There are some bytes before this breakpoint that we need to just
24464ba319b5SDimitry Andric             // write to memory
2447ac7ddfbfSEd Maste             size_t curr_size = intersect_addr - curr_addr;
2448435933ddSDimitry Andric             size_t curr_bytes_written = WriteMemoryPrivate(
2449435933ddSDimitry Andric                 curr_addr, ubuf + bytes_written, curr_size, error);
2450ac7ddfbfSEd Maste             bytes_written += curr_bytes_written;
2451435933ddSDimitry Andric             if (curr_bytes_written != curr_size) {
24524ba319b5SDimitry Andric               // We weren't able to write all of the requested bytes, we are
24534ba319b5SDimitry Andric               // done looping and will return the number of bytes that we have
24544ba319b5SDimitry Andric               // written so far.
2455ac7ddfbfSEd Maste               if (error.Success())
2456ac7ddfbfSEd Maste                 error.SetErrorToGenericError();
2457ac7ddfbfSEd Maste             }
2458ac7ddfbfSEd Maste           }
2459ac7ddfbfSEd Maste           // Now write any bytes that would cover up any software breakpoints
2460ac7ddfbfSEd Maste           // directly into the breakpoint opcode buffer
2461435933ddSDimitry Andric           ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset,
2462435933ddSDimitry Andric                    ubuf + bytes_written, intersect_size);
2463ac7ddfbfSEd Maste           bytes_written += intersect_size;
2464ac7ddfbfSEd Maste         }
2465ac7ddfbfSEd Maste       });
2466ac7ddfbfSEd Maste 
2467ac7ddfbfSEd Maste       if (bytes_written < size)
2468435933ddSDimitry Andric         WriteMemoryPrivate(addr + bytes_written, ubuf + bytes_written,
2469435933ddSDimitry Andric                            size - bytes_written, error);
2470ac7ddfbfSEd Maste     }
2471435933ddSDimitry Andric   } else {
2472ac7ddfbfSEd Maste     return WriteMemoryPrivate(addr, buf, size, error);
2473ac7ddfbfSEd Maste   }
2474ac7ddfbfSEd Maste 
2475ac7ddfbfSEd Maste   // Write any remaining bytes after the last breakpoint if we have any left
2476ac7ddfbfSEd Maste   return 0; // bytes_written;
2477ac7ddfbfSEd Maste }
2478ac7ddfbfSEd Maste 
WriteScalarToMemory(addr_t addr,const Scalar & scalar,size_t byte_size,Status & error)2479435933ddSDimitry Andric size_t Process::WriteScalarToMemory(addr_t addr, const Scalar &scalar,
24805517e702SDimitry Andric                                     size_t byte_size, Status &error) {
2481ac7ddfbfSEd Maste   if (byte_size == UINT32_MAX)
2482ac7ddfbfSEd Maste     byte_size = scalar.GetByteSize();
2483435933ddSDimitry Andric   if (byte_size > 0) {
2484ac7ddfbfSEd Maste     uint8_t buf[32];
2485435933ddSDimitry Andric     const size_t mem_size =
2486435933ddSDimitry Andric         scalar.GetAsMemoryData(buf, byte_size, GetByteOrder(), error);
2487ac7ddfbfSEd Maste     if (mem_size > 0)
2488ac7ddfbfSEd Maste       return WriteMemory(addr, buf, mem_size, error);
2489ac7ddfbfSEd Maste     else
2490ac7ddfbfSEd Maste       error.SetErrorString("failed to get scalar as memory data");
2491435933ddSDimitry Andric   } else {
2492ac7ddfbfSEd Maste     error.SetErrorString("invalid scalar value");
2493ac7ddfbfSEd Maste   }
2494ac7ddfbfSEd Maste   return 0;
2495ac7ddfbfSEd Maste }
2496ac7ddfbfSEd Maste 
ReadScalarIntegerFromMemory(addr_t addr,uint32_t byte_size,bool is_signed,Scalar & scalar,Status & error)2497435933ddSDimitry Andric size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size,
2498435933ddSDimitry Andric                                             bool is_signed, Scalar &scalar,
24995517e702SDimitry Andric                                             Status &error) {
2500ac7ddfbfSEd Maste   uint64_t uval = 0;
2501435933ddSDimitry Andric   if (byte_size == 0) {
2502ac7ddfbfSEd Maste     error.SetErrorString("byte size is zero");
2503435933ddSDimitry Andric   } else if (byte_size & (byte_size - 1)) {
2504435933ddSDimitry Andric     error.SetErrorStringWithFormat("byte size %u is not a power of 2",
2505435933ddSDimitry Andric                                    byte_size);
2506435933ddSDimitry Andric   } else if (byte_size <= sizeof(uval)) {
2507ac7ddfbfSEd Maste     const size_t bytes_read = ReadMemory(addr, &uval, byte_size, error);
2508435933ddSDimitry Andric     if (bytes_read == byte_size) {
2509435933ddSDimitry Andric       DataExtractor data(&uval, sizeof(uval), GetByteOrder(),
2510435933ddSDimitry Andric                          GetAddressByteSize());
2511ac7ddfbfSEd Maste       lldb::offset_t offset = 0;
2512ac7ddfbfSEd Maste       if (byte_size <= 4)
2513ac7ddfbfSEd Maste         scalar = data.GetMaxU32(&offset, byte_size);
2514ac7ddfbfSEd Maste       else
2515ac7ddfbfSEd Maste         scalar = data.GetMaxU64(&offset, byte_size);
2516ac7ddfbfSEd Maste       if (is_signed)
2517ac7ddfbfSEd Maste         scalar.SignExtend(byte_size * 8);
2518ac7ddfbfSEd Maste       return bytes_read;
2519ac7ddfbfSEd Maste     }
2520435933ddSDimitry Andric   } else {
2521435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2522435933ddSDimitry Andric         "byte size of %u is too large for integer scalar type", byte_size);
2523ac7ddfbfSEd Maste   }
2524ac7ddfbfSEd Maste   return 0;
2525ac7ddfbfSEd Maste }
2526ac7ddfbfSEd Maste 
WriteObjectFile(std::vector<ObjectFile::LoadableData> entries)25274ba319b5SDimitry Andric Status Process::WriteObjectFile(std::vector<ObjectFile::LoadableData> entries) {
25284ba319b5SDimitry Andric   Status error;
25294ba319b5SDimitry Andric   for (const auto &Entry : entries) {
25304ba319b5SDimitry Andric     WriteMemory(Entry.Dest, Entry.Contents.data(), Entry.Contents.size(),
25314ba319b5SDimitry Andric                 error);
25324ba319b5SDimitry Andric     if (!error.Success())
25334ba319b5SDimitry Andric       break;
25344ba319b5SDimitry Andric   }
25354ba319b5SDimitry Andric   return error;
25364ba319b5SDimitry Andric }
25374ba319b5SDimitry Andric 
2538ac7ddfbfSEd Maste #define USE_ALLOCATE_MEMORY_CACHE 1
AllocateMemory(size_t size,uint32_t permissions,Status & error)2539435933ddSDimitry Andric addr_t Process::AllocateMemory(size_t size, uint32_t permissions,
25405517e702SDimitry Andric                                Status &error) {
25414ba319b5SDimitry Andric   if (GetPrivateState() != eStateStopped) {
25424ba319b5SDimitry Andric     error.SetErrorToGenericError();
2543ac7ddfbfSEd Maste     return LLDB_INVALID_ADDRESS;
25444ba319b5SDimitry Andric   }
2545ac7ddfbfSEd Maste 
2546ac7ddfbfSEd Maste #if defined(USE_ALLOCATE_MEMORY_CACHE)
2547ac7ddfbfSEd Maste   return m_allocated_memory_cache.AllocateMemory(size, permissions, error);
2548ac7ddfbfSEd Maste #else
2549ac7ddfbfSEd Maste   addr_t allocated_addr = DoAllocateMemory(size, permissions, error);
2550ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
2551ac7ddfbfSEd Maste   if (log)
2552435933ddSDimitry Andric     log->Printf("Process::AllocateMemory(size=%" PRIu64
2553435933ddSDimitry Andric                 ", permissions=%s) => 0x%16.16" PRIx64
2554435933ddSDimitry Andric                 " (m_stop_id = %u m_memory_id = %u)",
2555435933ddSDimitry Andric                 (uint64_t)size, GetPermissionsAsCString(permissions),
2556435933ddSDimitry Andric                 (uint64_t)allocated_addr, m_mod_id.GetStopID(),
2557ac7ddfbfSEd Maste                 m_mod_id.GetMemoryID());
2558ac7ddfbfSEd Maste   return allocated_addr;
2559ac7ddfbfSEd Maste #endif
2560ac7ddfbfSEd Maste }
2561ac7ddfbfSEd Maste 
CallocateMemory(size_t size,uint32_t permissions,Status & error)2562435933ddSDimitry Andric addr_t Process::CallocateMemory(size_t size, uint32_t permissions,
25635517e702SDimitry Andric                                 Status &error) {
25649f2f44ceSEd Maste   addr_t return_addr = AllocateMemory(size, permissions, error);
2565435933ddSDimitry Andric   if (error.Success()) {
25669f2f44ceSEd Maste     std::string buffer(size, 0);
25679f2f44ceSEd Maste     WriteMemory(return_addr, buffer.c_str(), size, error);
25689f2f44ceSEd Maste   }
25699f2f44ceSEd Maste   return return_addr;
25709f2f44ceSEd Maste }
25719f2f44ceSEd Maste 
CanJIT()2572435933ddSDimitry Andric bool Process::CanJIT() {
2573435933ddSDimitry Andric   if (m_can_jit == eCanJITDontKnow) {
25740127ef0fSEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
25755517e702SDimitry Andric     Status err;
2576ac7ddfbfSEd Maste 
2577435933ddSDimitry Andric     uint64_t allocated_memory = AllocateMemory(
2578435933ddSDimitry Andric         8, ePermissionsReadable | ePermissionsWritable | ePermissionsExecutable,
2579ac7ddfbfSEd Maste         err);
2580ac7ddfbfSEd Maste 
2581435933ddSDimitry Andric     if (err.Success()) {
2582ac7ddfbfSEd Maste       m_can_jit = eCanJITYes;
25830127ef0fSEd Maste       if (log)
2584435933ddSDimitry Andric         log->Printf("Process::%s pid %" PRIu64
2585435933ddSDimitry Andric                     " allocation test passed, CanJIT () is true",
2586435933ddSDimitry Andric                     __FUNCTION__, GetID());
2587435933ddSDimitry Andric     } else {
2588ac7ddfbfSEd Maste       m_can_jit = eCanJITNo;
25890127ef0fSEd Maste       if (log)
2590435933ddSDimitry Andric         log->Printf("Process::%s pid %" PRIu64
2591435933ddSDimitry Andric                     " allocation test failed, CanJIT () is false: %s",
2592435933ddSDimitry Andric                     __FUNCTION__, GetID(), err.AsCString());
25930127ef0fSEd Maste     }
2594ac7ddfbfSEd Maste 
2595ac7ddfbfSEd Maste     DeallocateMemory(allocated_memory);
2596ac7ddfbfSEd Maste   }
2597ac7ddfbfSEd Maste 
2598ac7ddfbfSEd Maste   return m_can_jit == eCanJITYes;
2599ac7ddfbfSEd Maste }
2600ac7ddfbfSEd Maste 
SetCanJIT(bool can_jit)2601435933ddSDimitry Andric void Process::SetCanJIT(bool can_jit) {
2602ac7ddfbfSEd Maste   m_can_jit = (can_jit ? eCanJITYes : eCanJITNo);
2603ac7ddfbfSEd Maste }
2604ac7ddfbfSEd Maste 
SetCanRunCode(bool can_run_code)2605435933ddSDimitry Andric void Process::SetCanRunCode(bool can_run_code) {
2606b91a7dfcSDimitry Andric   SetCanJIT(can_run_code);
2607b91a7dfcSDimitry Andric   m_can_interpret_function_calls = can_run_code;
2608b91a7dfcSDimitry Andric }
2609b91a7dfcSDimitry Andric 
DeallocateMemory(addr_t ptr)26105517e702SDimitry Andric Status Process::DeallocateMemory(addr_t ptr) {
26115517e702SDimitry Andric   Status error;
2612ac7ddfbfSEd Maste #if defined(USE_ALLOCATE_MEMORY_CACHE)
2613435933ddSDimitry Andric   if (!m_allocated_memory_cache.DeallocateMemory(ptr)) {
2614435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2615435933ddSDimitry Andric         "deallocation of memory at 0x%" PRIx64 " failed.", (uint64_t)ptr);
2616ac7ddfbfSEd Maste   }
2617ac7ddfbfSEd Maste #else
2618ac7ddfbfSEd Maste   error = DoDeallocateMemory(ptr);
2619ac7ddfbfSEd Maste 
2620ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
2621ac7ddfbfSEd Maste   if (log)
2622435933ddSDimitry Andric     log->Printf("Process::DeallocateMemory(addr=0x%16.16" PRIx64
2623435933ddSDimitry Andric                 ") => err = %s (m_stop_id = %u, m_memory_id = %u)",
2624435933ddSDimitry Andric                 ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(),
2625ac7ddfbfSEd Maste                 m_mod_id.GetMemoryID());
2626ac7ddfbfSEd Maste #endif
2627ac7ddfbfSEd Maste   return error;
2628ac7ddfbfSEd Maste }
2629ac7ddfbfSEd Maste 
ReadModuleFromMemory(const FileSpec & file_spec,lldb::addr_t header_addr,size_t size_to_read)2630435933ddSDimitry Andric ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec,
26310127ef0fSEd Maste                                        lldb::addr_t header_addr,
2632435933ddSDimitry Andric                                        size_t size_to_read) {
26339f2f44ceSEd Maste   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
2634435933ddSDimitry Andric   if (log) {
2635435933ddSDimitry Andric     log->Printf("Process::ReadModuleFromMemory reading %s binary from memory",
2636435933ddSDimitry Andric                 file_spec.GetPath().c_str());
26379f2f44ceSEd Maste   }
2638ac7ddfbfSEd Maste   ModuleSP module_sp(new Module(file_spec, ArchSpec()));
2639435933ddSDimitry Andric   if (module_sp) {
26405517e702SDimitry Andric     Status error;
2641435933ddSDimitry Andric     ObjectFile *objfile = module_sp->GetMemoryObjectFile(
2642435933ddSDimitry Andric         shared_from_this(), header_addr, error, size_to_read);
2643ac7ddfbfSEd Maste     if (objfile)
2644ac7ddfbfSEd Maste       return module_sp;
2645ac7ddfbfSEd Maste   }
2646ac7ddfbfSEd Maste   return ModuleSP();
2647ac7ddfbfSEd Maste }
2648ac7ddfbfSEd Maste 
GetLoadAddressPermissions(lldb::addr_t load_addr,uint32_t & permissions)2649435933ddSDimitry Andric bool Process::GetLoadAddressPermissions(lldb::addr_t load_addr,
2650435933ddSDimitry Andric                                         uint32_t &permissions) {
26511c3bbb01SEd Maste   MemoryRegionInfo range_info;
26521c3bbb01SEd Maste   permissions = 0;
26535517e702SDimitry Andric   Status error(GetMemoryRegionInfo(load_addr, range_info));
26541c3bbb01SEd Maste   if (!error.Success())
26551c3bbb01SEd Maste     return false;
2656435933ddSDimitry Andric   if (range_info.GetReadable() == MemoryRegionInfo::eDontKnow ||
2657435933ddSDimitry Andric       range_info.GetWritable() == MemoryRegionInfo::eDontKnow ||
2658435933ddSDimitry Andric       range_info.GetExecutable() == MemoryRegionInfo::eDontKnow) {
26591c3bbb01SEd Maste     return false;
26601c3bbb01SEd Maste   }
26611c3bbb01SEd Maste 
26621c3bbb01SEd Maste   if (range_info.GetReadable() == MemoryRegionInfo::eYes)
26631c3bbb01SEd Maste     permissions |= lldb::ePermissionsReadable;
26641c3bbb01SEd Maste 
26651c3bbb01SEd Maste   if (range_info.GetWritable() == MemoryRegionInfo::eYes)
26661c3bbb01SEd Maste     permissions |= lldb::ePermissionsWritable;
26671c3bbb01SEd Maste 
26681c3bbb01SEd Maste   if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
26691c3bbb01SEd Maste     permissions |= lldb::ePermissionsExecutable;
26701c3bbb01SEd Maste 
26711c3bbb01SEd Maste   return true;
26721c3bbb01SEd Maste }
26731c3bbb01SEd Maste 
EnableWatchpoint(Watchpoint * watchpoint,bool notify)26745517e702SDimitry Andric Status Process::EnableWatchpoint(Watchpoint *watchpoint, bool notify) {
26755517e702SDimitry Andric   Status error;
2676ac7ddfbfSEd Maste   error.SetErrorString("watchpoints are not supported");
2677ac7ddfbfSEd Maste   return error;
2678ac7ddfbfSEd Maste }
2679ac7ddfbfSEd Maste 
DisableWatchpoint(Watchpoint * watchpoint,bool notify)26805517e702SDimitry Andric Status Process::DisableWatchpoint(Watchpoint *watchpoint, bool notify) {
26815517e702SDimitry Andric   Status error;
2682ac7ddfbfSEd Maste   error.SetErrorString("watchpoints are not supported");
2683ac7ddfbfSEd Maste   return error;
2684ac7ddfbfSEd Maste }
2685ac7ddfbfSEd Maste 
2686ac7ddfbfSEd Maste StateType
WaitForProcessStopPrivate(EventSP & event_sp,const Timeout<std::micro> & timeout)2687435933ddSDimitry Andric Process::WaitForProcessStopPrivate(EventSP &event_sp,
2688435933ddSDimitry Andric                                    const Timeout<std::micro> &timeout) {
2689ac7ddfbfSEd Maste   StateType state;
26904ba319b5SDimitry Andric 
2691435933ddSDimitry Andric   while (true) {
2692ac7ddfbfSEd Maste     event_sp.reset();
2693435933ddSDimitry Andric     state = GetStateChangedEventsPrivate(event_sp, timeout);
2694ac7ddfbfSEd Maste 
2695ac7ddfbfSEd Maste     if (StateIsStoppedState(state, false))
2696ac7ddfbfSEd Maste       break;
2697ac7ddfbfSEd Maste 
2698ac7ddfbfSEd Maste     // If state is invalid, then we timed out
2699ac7ddfbfSEd Maste     if (state == eStateInvalid)
2700ac7ddfbfSEd Maste       break;
2701ac7ddfbfSEd Maste 
2702ac7ddfbfSEd Maste     if (event_sp)
2703ac7ddfbfSEd Maste       HandlePrivateEvent(event_sp);
2704ac7ddfbfSEd Maste   }
2705ac7ddfbfSEd Maste   return state;
2706ac7ddfbfSEd Maste }
2707ac7ddfbfSEd Maste 
LoadOperatingSystemPlugin(bool flush)2708435933ddSDimitry Andric void Process::LoadOperatingSystemPlugin(bool flush) {
27097aa51b79SEd Maste   if (flush)
27107aa51b79SEd Maste     m_thread_list.Clear();
27114bb0738eSEd Maste   m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
27127aa51b79SEd Maste   if (flush)
27137aa51b79SEd Maste     Flush();
27147aa51b79SEd Maste }
27157aa51b79SEd Maste 
Launch(ProcessLaunchInfo & launch_info)27165517e702SDimitry Andric Status Process::Launch(ProcessLaunchInfo &launch_info) {
27175517e702SDimitry Andric   Status error;
2718ac7ddfbfSEd Maste   m_abi_sp.reset();
2719ac7ddfbfSEd Maste   m_dyld_ap.reset();
27200127ef0fSEd Maste   m_jit_loaders_ap.reset();
272135617911SEd Maste   m_system_runtime_ap.reset();
2722ac7ddfbfSEd Maste   m_os_ap.reset();
2723ac7ddfbfSEd Maste   m_process_input_reader.reset();
2724ac7ddfbfSEd Maste 
27259f2f44ceSEd Maste   Module *exe_module = GetTarget().GetExecutableModulePointer();
2726435933ddSDimitry Andric   if (exe_module) {
2727ac7ddfbfSEd Maste     char local_exec_file_path[PATH_MAX];
2728ac7ddfbfSEd Maste     char platform_exec_file_path[PATH_MAX];
2729435933ddSDimitry Andric     exe_module->GetFileSpec().GetPath(local_exec_file_path,
2730435933ddSDimitry Andric                                       sizeof(local_exec_file_path));
2731435933ddSDimitry Andric     exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path,
2732435933ddSDimitry Andric                                               sizeof(platform_exec_file_path));
2733*b5893f02SDimitry Andric     if (FileSystem::Instance().Exists(exe_module->GetFileSpec())) {
2734b952cd58SEd Maste       // Install anything that might need to be installed prior to launching.
2735b952cd58SEd Maste       // For host systems, this will do nothing, but if we are connected to a
2736b952cd58SEd Maste       // remote platform it will install any needed binaries
2737b952cd58SEd Maste       error = GetTarget().Install(&launch_info);
2738b952cd58SEd Maste       if (error.Fail())
2739b952cd58SEd Maste         return error;
2740b952cd58SEd Maste 
2741ac7ddfbfSEd Maste       if (PrivateStateThreadIsValid())
2742ac7ddfbfSEd Maste         PausePrivateStateThread();
2743ac7ddfbfSEd Maste 
2744ac7ddfbfSEd Maste       error = WillLaunch(exe_module);
2745435933ddSDimitry Andric       if (error.Success()) {
2746ac7ddfbfSEd Maste         const bool restarted = false;
2747ac7ddfbfSEd Maste         SetPublicState(eStateLaunching, restarted);
2748ac7ddfbfSEd Maste         m_should_detach = false;
2749ac7ddfbfSEd Maste 
2750435933ddSDimitry Andric         if (m_public_run_lock.TrySetRunning()) {
2751ac7ddfbfSEd Maste           // Now launch using these arguments.
2752ac7ddfbfSEd Maste           error = DoLaunch(exe_module, launch_info);
2753435933ddSDimitry Andric         } else {
2754ac7ddfbfSEd Maste           // This shouldn't happen
2755ac7ddfbfSEd Maste           error.SetErrorString("failed to acquire process run lock");
2756ac7ddfbfSEd Maste         }
2757ac7ddfbfSEd Maste 
2758435933ddSDimitry Andric         if (error.Fail()) {
2759435933ddSDimitry Andric           if (GetID() != LLDB_INVALID_PROCESS_ID) {
2760ac7ddfbfSEd Maste             SetID(LLDB_INVALID_PROCESS_ID);
2761ac7ddfbfSEd Maste             const char *error_string = error.AsCString();
27624bb0738eSEd Maste             if (error_string == nullptr)
2763ac7ddfbfSEd Maste               error_string = "launch failed";
2764ac7ddfbfSEd Maste             SetExitStatus(-1, error_string);
2765ac7ddfbfSEd Maste           }
2766435933ddSDimitry Andric         } else {
2767ac7ddfbfSEd Maste           EventSP event_sp;
27684ba319b5SDimitry Andric 
27694ba319b5SDimitry Andric           // Now wait for the process to launch and return control to us, and then call
27704ba319b5SDimitry Andric           // DidLaunch:
2771435933ddSDimitry Andric           StateType state = WaitForProcessStopPrivate(event_sp, seconds(10));
2772ac7ddfbfSEd Maste 
2773435933ddSDimitry Andric           if (state == eStateInvalid || !event_sp) {
27744ba319b5SDimitry Andric             // We were able to launch the process, but we failed to catch the
27754ba319b5SDimitry Andric             // initial stop.
27761c3bbb01SEd Maste             error.SetErrorString("failed to catch stop after launch");
2777ac7ddfbfSEd Maste             SetExitStatus(0, "failed to catch stop after launch");
27781c3bbb01SEd Maste             Destroy(false);
2779435933ddSDimitry Andric           } else if (state == eStateStopped || state == eStateCrashed) {
2780ac7ddfbfSEd Maste             DidLaunch();
2781ac7ddfbfSEd Maste 
2782ac7ddfbfSEd Maste             DynamicLoader *dyld = GetDynamicLoader();
2783ac7ddfbfSEd Maste             if (dyld)
2784ac7ddfbfSEd Maste               dyld->DidLaunch();
2785ac7ddfbfSEd Maste 
27860127ef0fSEd Maste             GetJITLoaders().DidLaunch();
27870127ef0fSEd Maste 
278835617911SEd Maste             SystemRuntime *system_runtime = GetSystemRuntime();
278935617911SEd Maste             if (system_runtime)
279035617911SEd Maste               system_runtime->DidLaunch();
279135617911SEd Maste 
2792f678e45dSDimitry Andric             if (!m_os_ap)
27937aa51b79SEd Maste                 LoadOperatingSystemPlugin(false);
27947aa51b79SEd Maste 
27954ba319b5SDimitry Andric             // We successfully launched the process and stopped, now it the
27964ba319b5SDimitry Andric             // right time to set up signal filters before resuming.
2797f678e45dSDimitry Andric             UpdateAutomaticSignalFiltering();
2798f678e45dSDimitry Andric 
2799435933ddSDimitry Andric             // Note, the stop event was consumed above, but not handled. This
28004ba319b5SDimitry Andric             // was done to give DidLaunch a chance to run. The target is either
28014ba319b5SDimitry Andric             // stopped or crashed. Directly set the state.  This is done to
28024ba319b5SDimitry Andric             // prevent a stop message with a bunch of spurious output on thread
28034ba319b5SDimitry Andric             // status, as well as not pop a ProcessIOHandler.
28047aa51b79SEd Maste             SetPublicState(state, false);
2805ac7ddfbfSEd Maste 
2806ac7ddfbfSEd Maste             if (PrivateStateThreadIsValid())
2807ac7ddfbfSEd Maste               ResumePrivateStateThread();
2808ac7ddfbfSEd Maste             else
2809ac7ddfbfSEd Maste               StartPrivateStateThread();
28107aa51b79SEd Maste 
2811435933ddSDimitry Andric             // Target was stopped at entry as was intended. Need to notify the
28124ba319b5SDimitry Andric             // listeners about it.
2813435933ddSDimitry Andric             if (state == eStateStopped &&
2814435933ddSDimitry Andric                 launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
28151c3bbb01SEd Maste               HandlePrivateEvent(event_sp);
2816435933ddSDimitry Andric           } else if (state == eStateExited) {
2817435933ddSDimitry Andric             // We exited while trying to launch somehow.  Don't call DidLaunch
28184ba319b5SDimitry Andric             // as that's not likely to work, and return an invalid pid.
2819ac7ddfbfSEd Maste             HandlePrivateEvent(event_sp);
2820ac7ddfbfSEd Maste           }
2821ac7ddfbfSEd Maste         }
2822ac7ddfbfSEd Maste       }
2823435933ddSDimitry Andric     } else {
2824435933ddSDimitry Andric       error.SetErrorStringWithFormat("file doesn't exist: '%s'",
2825435933ddSDimitry Andric                                      local_exec_file_path);
2826ac7ddfbfSEd Maste     }
2827ac7ddfbfSEd Maste   }
2828ac7ddfbfSEd Maste   return error;
2829ac7ddfbfSEd Maste }
2830ac7ddfbfSEd Maste 
LoadCore()28315517e702SDimitry Andric Status Process::LoadCore() {
28325517e702SDimitry Andric   Status error = DoLoadCore();
2833435933ddSDimitry Andric   if (error.Success()) {
2834435933ddSDimitry Andric     ListenerSP listener_sp(
2835435933ddSDimitry Andric         Listener::MakeListener("lldb.process.load_core_listener"));
28364bb0738eSEd Maste     HijackProcessEvents(listener_sp);
28371c3bbb01SEd Maste 
2838ac7ddfbfSEd Maste     if (PrivateStateThreadIsValid())
2839ac7ddfbfSEd Maste       ResumePrivateStateThread();
2840ac7ddfbfSEd Maste     else
2841ac7ddfbfSEd Maste       StartPrivateStateThread();
2842ac7ddfbfSEd Maste 
2843ac7ddfbfSEd Maste     DynamicLoader *dyld = GetDynamicLoader();
2844ac7ddfbfSEd Maste     if (dyld)
2845ac7ddfbfSEd Maste       dyld->DidAttach();
2846ac7ddfbfSEd Maste 
28470127ef0fSEd Maste     GetJITLoaders().DidAttach();
28480127ef0fSEd Maste 
284935617911SEd Maste     SystemRuntime *system_runtime = GetSystemRuntime();
285035617911SEd Maste     if (system_runtime)
285135617911SEd Maste       system_runtime->DidAttach();
285235617911SEd Maste 
2853f678e45dSDimitry Andric     if (!m_os_ap)
2854f678e45dSDimitry Andric       LoadOperatingSystemPlugin(false);
2855f678e45dSDimitry Andric 
2856ac7ddfbfSEd Maste     // We successfully loaded a core file, now pretend we stopped so we can
28574ba319b5SDimitry Andric     // show all of the threads in the core file and explore the crashed state.
2858ac7ddfbfSEd Maste     SetPrivateState(eStateStopped);
2859ac7ddfbfSEd Maste 
28604ba319b5SDimitry Andric     // Wait for a stopped event since we just posted one above...
28611c3bbb01SEd Maste     lldb::EventSP event_sp;
28624ba319b5SDimitry Andric     StateType state =
28634ba319b5SDimitry Andric         WaitForProcessToStop(seconds(10), &event_sp, true, listener_sp);
28641c3bbb01SEd Maste 
2865435933ddSDimitry Andric     if (!StateIsStoppedState(state, false)) {
28661c3bbb01SEd Maste       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
28671c3bbb01SEd Maste       if (log)
2868435933ddSDimitry Andric         log->Printf("Process::Halt() failed to stop, state is: %s",
2869435933ddSDimitry Andric                     StateAsCString(state));
2870435933ddSDimitry Andric       error.SetErrorString(
2871435933ddSDimitry Andric           "Did not get stopped event after loading the core file.");
28721c3bbb01SEd Maste     }
28731c3bbb01SEd Maste     RestoreProcessEvents();
2874ac7ddfbfSEd Maste   }
2875ac7ddfbfSEd Maste   return error;
2876ac7ddfbfSEd Maste }
2877ac7ddfbfSEd Maste 
GetDynamicLoader()2878435933ddSDimitry Andric DynamicLoader *Process::GetDynamicLoader() {
28794bb0738eSEd Maste   if (!m_dyld_ap)
28804bb0738eSEd Maste     m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
2881ac7ddfbfSEd Maste   return m_dyld_ap.get();
2882ac7ddfbfSEd Maste }
2883ac7ddfbfSEd Maste 
GetAuxvData()2884435933ddSDimitry Andric const lldb::DataBufferSP Process::GetAuxvData() { return DataBufferSP(); }
28850127ef0fSEd Maste 
GetJITLoaders()2886435933ddSDimitry Andric JITLoaderList &Process::GetJITLoaders() {
2887435933ddSDimitry Andric   if (!m_jit_loaders_ap) {
28880127ef0fSEd Maste     m_jit_loaders_ap.reset(new JITLoaderList());
28890127ef0fSEd Maste     JITLoader::LoadPlugins(this, *m_jit_loaders_ap);
28900127ef0fSEd Maste   }
28910127ef0fSEd Maste   return *m_jit_loaders_ap;
28920127ef0fSEd Maste }
28930127ef0fSEd Maste 
GetSystemRuntime()2894435933ddSDimitry Andric SystemRuntime *Process::GetSystemRuntime() {
28954bb0738eSEd Maste   if (!m_system_runtime_ap)
289635617911SEd Maste     m_system_runtime_ap.reset(SystemRuntime::FindPlugin(this));
289735617911SEd Maste   return m_system_runtime_ap.get();
289835617911SEd Maste }
289935617911SEd Maste 
AttachCompletionHandler(Process * process,uint32_t exec_count)2900435933ddSDimitry Andric Process::AttachCompletionHandler::AttachCompletionHandler(Process *process,
2901435933ddSDimitry Andric                                                           uint32_t exec_count)
2902435933ddSDimitry Andric     : NextEventAction(process), m_exec_count(exec_count) {
29030127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
29040127ef0fSEd Maste   if (log)
2905435933ddSDimitry Andric     log->Printf(
2906435933ddSDimitry Andric         "Process::AttachCompletionHandler::%s process=%p, exec_count=%" PRIu32,
2907435933ddSDimitry Andric         __FUNCTION__, static_cast<void *>(process), exec_count);
29080127ef0fSEd Maste }
2909ac7ddfbfSEd Maste 
2910ac7ddfbfSEd Maste Process::NextEventAction::EventActionResult
PerformAction(lldb::EventSP & event_sp)2911435933ddSDimitry Andric Process::AttachCompletionHandler::PerformAction(lldb::EventSP &event_sp) {
29120127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
29130127ef0fSEd Maste 
2914ac7ddfbfSEd Maste   StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
29150127ef0fSEd Maste   if (log)
2916435933ddSDimitry Andric     log->Printf(
2917435933ddSDimitry Andric         "Process::AttachCompletionHandler::%s called with state %s (%d)",
2918435933ddSDimitry Andric         __FUNCTION__, StateAsCString(state), static_cast<int>(state));
29190127ef0fSEd Maste 
2920435933ddSDimitry Andric   switch (state) {
29211c3bbb01SEd Maste   case eStateAttaching:
29221c3bbb01SEd Maste     return eEventActionSuccess;
29231c3bbb01SEd Maste 
2924ac7ddfbfSEd Maste   case eStateRunning:
2925ac7ddfbfSEd Maste   case eStateConnected:
2926ac7ddfbfSEd Maste     return eEventActionRetry;
2927ac7ddfbfSEd Maste 
2928ac7ddfbfSEd Maste   case eStateStopped:
2929ac7ddfbfSEd Maste   case eStateCrashed:
2930ac7ddfbfSEd Maste     // During attach, prior to sending the eStateStopped event,
2931ac7ddfbfSEd Maste     // lldb_private::Process subclasses must set the new process ID.
2932ac7ddfbfSEd Maste     assert(m_process->GetID() != LLDB_INVALID_PROCESS_ID);
29334ba319b5SDimitry Andric     // We don't want these events to be reported, so go set the
29344ba319b5SDimitry Andric     // ShouldReportStop here:
2935ac7ddfbfSEd Maste     m_process->GetThreadList().SetShouldReportStop(eVoteNo);
2936ac7ddfbfSEd Maste 
2937435933ddSDimitry Andric     if (m_exec_count > 0) {
2938ac7ddfbfSEd Maste       --m_exec_count;
29390127ef0fSEd Maste 
29400127ef0fSEd Maste       if (log)
2941435933ddSDimitry Andric         log->Printf("Process::AttachCompletionHandler::%s state %s: reduced "
2942435933ddSDimitry Andric                     "remaining exec count to %" PRIu32 ", requesting resume",
2943435933ddSDimitry Andric                     __FUNCTION__, StateAsCString(state), m_exec_count);
29440127ef0fSEd Maste 
2945ac7ddfbfSEd Maste       RequestResume();
2946ac7ddfbfSEd Maste       return eEventActionRetry;
2947435933ddSDimitry Andric     } else {
29480127ef0fSEd Maste       if (log)
2949435933ddSDimitry Andric         log->Printf("Process::AttachCompletionHandler::%s state %s: no more "
2950435933ddSDimitry Andric                     "execs expected to start, continuing with attach",
2951435933ddSDimitry Andric                     __FUNCTION__, StateAsCString(state));
29520127ef0fSEd Maste 
2953ac7ddfbfSEd Maste       m_process->CompleteAttach();
2954ac7ddfbfSEd Maste       return eEventActionSuccess;
2955ac7ddfbfSEd Maste     }
2956ac7ddfbfSEd Maste     break;
2957ac7ddfbfSEd Maste 
2958ac7ddfbfSEd Maste   default:
2959ac7ddfbfSEd Maste   case eStateExited:
2960ac7ddfbfSEd Maste   case eStateInvalid:
2961ac7ddfbfSEd Maste     break;
2962ac7ddfbfSEd Maste   }
2963ac7ddfbfSEd Maste 
2964ac7ddfbfSEd Maste   m_exit_string.assign("No valid Process");
2965ac7ddfbfSEd Maste   return eEventActionExit;
2966ac7ddfbfSEd Maste }
2967ac7ddfbfSEd Maste 
2968ac7ddfbfSEd Maste Process::NextEventAction::EventActionResult
HandleBeingInterrupted()2969435933ddSDimitry Andric Process::AttachCompletionHandler::HandleBeingInterrupted() {
2970ac7ddfbfSEd Maste   return eEventActionSuccess;
2971ac7ddfbfSEd Maste }
2972ac7ddfbfSEd Maste 
GetExitString()2973435933ddSDimitry Andric const char *Process::AttachCompletionHandler::GetExitString() {
2974ac7ddfbfSEd Maste   return m_exit_string.c_str();
2975ac7ddfbfSEd Maste }
2976ac7ddfbfSEd Maste 
GetListenerForProcess(Debugger & debugger)2977435933ddSDimitry Andric ListenerSP ProcessAttachInfo::GetListenerForProcess(Debugger &debugger) {
29787aa51b79SEd Maste   if (m_listener_sp)
29794bb0738eSEd Maste     return m_listener_sp;
29807aa51b79SEd Maste   else
29817aa51b79SEd Maste     return debugger.GetListener();
29827aa51b79SEd Maste }
29837aa51b79SEd Maste 
Attach(ProcessAttachInfo & attach_info)29845517e702SDimitry Andric Status Process::Attach(ProcessAttachInfo &attach_info) {
2985ac7ddfbfSEd Maste   m_abi_sp.reset();
2986ac7ddfbfSEd Maste   m_process_input_reader.reset();
2987ac7ddfbfSEd Maste   m_dyld_ap.reset();
29880127ef0fSEd Maste   m_jit_loaders_ap.reset();
298935617911SEd Maste   m_system_runtime_ap.reset();
2990ac7ddfbfSEd Maste   m_os_ap.reset();
2991ac7ddfbfSEd Maste 
2992ac7ddfbfSEd Maste   lldb::pid_t attach_pid = attach_info.GetProcessID();
29935517e702SDimitry Andric   Status error;
2994435933ddSDimitry Andric   if (attach_pid == LLDB_INVALID_PROCESS_ID) {
2995ac7ddfbfSEd Maste     char process_name[PATH_MAX];
2996ac7ddfbfSEd Maste 
2997435933ddSDimitry Andric     if (attach_info.GetExecutableFile().GetPath(process_name,
2998435933ddSDimitry Andric                                                 sizeof(process_name))) {
2999ac7ddfbfSEd Maste       const bool wait_for_launch = attach_info.GetWaitForLaunch();
3000ac7ddfbfSEd Maste 
3001435933ddSDimitry Andric       if (wait_for_launch) {
3002ac7ddfbfSEd Maste         error = WillAttachToProcessWithName(process_name, wait_for_launch);
3003435933ddSDimitry Andric         if (error.Success()) {
3004435933ddSDimitry Andric           if (m_public_run_lock.TrySetRunning()) {
3005ac7ddfbfSEd Maste             m_should_detach = true;
3006ac7ddfbfSEd Maste             const bool restarted = false;
3007ac7ddfbfSEd Maste             SetPublicState(eStateAttaching, restarted);
3008ac7ddfbfSEd Maste             // Now attach using these arguments.
300912b93ac6SEd Maste             error = DoAttachToProcessWithName(process_name, attach_info);
3010435933ddSDimitry Andric           } else {
3011ac7ddfbfSEd Maste             // This shouldn't happen
3012ac7ddfbfSEd Maste             error.SetErrorString("failed to acquire process run lock");
3013ac7ddfbfSEd Maste           }
3014ac7ddfbfSEd Maste 
3015435933ddSDimitry Andric           if (error.Fail()) {
3016435933ddSDimitry Andric             if (GetID() != LLDB_INVALID_PROCESS_ID) {
3017ac7ddfbfSEd Maste               SetID(LLDB_INVALID_PROCESS_ID);
30184bb0738eSEd Maste               if (error.AsCString() == nullptr)
3019ac7ddfbfSEd Maste                 error.SetErrorString("attach failed");
3020ac7ddfbfSEd Maste 
3021ac7ddfbfSEd Maste               SetExitStatus(-1, error.AsCString());
3022ac7ddfbfSEd Maste             }
3023435933ddSDimitry Andric           } else {
3024435933ddSDimitry Andric             SetNextEventAction(new Process::AttachCompletionHandler(
3025435933ddSDimitry Andric                 this, attach_info.GetResumeCount()));
3026ac7ddfbfSEd Maste             StartPrivateStateThread();
3027ac7ddfbfSEd Maste           }
3028ac7ddfbfSEd Maste           return error;
3029ac7ddfbfSEd Maste         }
3030435933ddSDimitry Andric       } else {
3031ac7ddfbfSEd Maste         ProcessInstanceInfoList process_infos;
30329f2f44ceSEd Maste         PlatformSP platform_sp(GetTarget().GetPlatform());
3033ac7ddfbfSEd Maste 
3034435933ddSDimitry Andric         if (platform_sp) {
3035ac7ddfbfSEd Maste           ProcessInstanceInfoMatch match_info;
3036ac7ddfbfSEd Maste           match_info.GetProcessInfo() = attach_info;
3037f678e45dSDimitry Andric           match_info.SetNameMatchType(NameMatch::Equals);
3038ac7ddfbfSEd Maste           platform_sp->FindProcesses(match_info, process_infos);
3039ac7ddfbfSEd Maste           const uint32_t num_matches = process_infos.GetSize();
3040435933ddSDimitry Andric           if (num_matches == 1) {
3041ac7ddfbfSEd Maste             attach_pid = process_infos.GetProcessIDAtIndex(0);
3042ac7ddfbfSEd Maste             // Fall through and attach using the above process ID
3043435933ddSDimitry Andric           } else {
3044435933ddSDimitry Andric             match_info.GetProcessInfo().GetExecutableFile().GetPath(
3045435933ddSDimitry Andric                 process_name, sizeof(process_name));
3046435933ddSDimitry Andric             if (num_matches > 1) {
30470127ef0fSEd Maste               StreamString s;
3048435933ddSDimitry Andric               ProcessInstanceInfo::DumpTableHeader(s, platform_sp.get(), true,
3049435933ddSDimitry Andric                                                    false);
3050435933ddSDimitry Andric               for (size_t i = 0; i < num_matches; i++) {
3051435933ddSDimitry Andric                 process_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(
3052435933ddSDimitry Andric                     s, platform_sp.get(), true, false);
30530127ef0fSEd Maste               }
3054435933ddSDimitry Andric               error.SetErrorStringWithFormat(
3055435933ddSDimitry Andric                   "more than one process named %s:\n%s", process_name,
30560127ef0fSEd Maste                   s.GetData());
3057435933ddSDimitry Andric             } else
3058435933ddSDimitry Andric               error.SetErrorStringWithFormat(
3059435933ddSDimitry Andric                   "could not find a process named %s", process_name);
30600127ef0fSEd Maste           }
3061435933ddSDimitry Andric         } else {
3062435933ddSDimitry Andric           error.SetErrorString(
3063435933ddSDimitry Andric               "invalid platform, can't find processes by name");
3064ac7ddfbfSEd Maste           return error;
3065ac7ddfbfSEd Maste         }
3066ac7ddfbfSEd Maste       }
3067435933ddSDimitry Andric     } else {
3068ac7ddfbfSEd Maste       error.SetErrorString("invalid process name");
3069ac7ddfbfSEd Maste     }
3070ac7ddfbfSEd Maste   }
3071ac7ddfbfSEd Maste 
3072435933ddSDimitry Andric   if (attach_pid != LLDB_INVALID_PROCESS_ID) {
3073ac7ddfbfSEd Maste     error = WillAttachToProcessWithID(attach_pid);
3074435933ddSDimitry Andric     if (error.Success()) {
3075ac7ddfbfSEd Maste 
3076435933ddSDimitry Andric       if (m_public_run_lock.TrySetRunning()) {
3077ac7ddfbfSEd Maste         // Now attach using these arguments.
3078ac7ddfbfSEd Maste         m_should_detach = true;
3079ac7ddfbfSEd Maste         const bool restarted = false;
3080ac7ddfbfSEd Maste         SetPublicState(eStateAttaching, restarted);
3081ac7ddfbfSEd Maste         error = DoAttachToProcessWithID(attach_pid, attach_info);
3082435933ddSDimitry Andric       } else {
3083ac7ddfbfSEd Maste         // This shouldn't happen
3084ac7ddfbfSEd Maste         error.SetErrorString("failed to acquire process run lock");
3085ac7ddfbfSEd Maste       }
3086ac7ddfbfSEd Maste 
3087435933ddSDimitry Andric       if (error.Success()) {
3088435933ddSDimitry Andric         SetNextEventAction(new Process::AttachCompletionHandler(
3089435933ddSDimitry Andric             this, attach_info.GetResumeCount()));
3090ac7ddfbfSEd Maste         StartPrivateStateThread();
3091435933ddSDimitry Andric       } else {
3092ac7ddfbfSEd Maste         if (GetID() != LLDB_INVALID_PROCESS_ID)
3093ac7ddfbfSEd Maste           SetID(LLDB_INVALID_PROCESS_ID);
30947aa51b79SEd Maste 
3095ac7ddfbfSEd Maste         const char *error_string = error.AsCString();
30964bb0738eSEd Maste         if (error_string == nullptr)
3097ac7ddfbfSEd Maste           error_string = "attach failed";
3098ac7ddfbfSEd Maste 
3099ac7ddfbfSEd Maste         SetExitStatus(-1, error_string);
3100ac7ddfbfSEd Maste       }
3101ac7ddfbfSEd Maste     }
3102ac7ddfbfSEd Maste   }
3103ac7ddfbfSEd Maste   return error;
3104ac7ddfbfSEd Maste }
3105ac7ddfbfSEd Maste 
CompleteAttach()3106435933ddSDimitry Andric void Process::CompleteAttach() {
3107435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS |
3108435933ddSDimitry Andric                                                   LIBLLDB_LOG_TARGET));
31090127ef0fSEd Maste   if (log)
31100127ef0fSEd Maste     log->Printf("Process::%s()", __FUNCTION__);
31110127ef0fSEd Maste 
3112ac7ddfbfSEd Maste   // Let the process subclass figure out at much as it can about the process
3113ac7ddfbfSEd Maste   // before we go looking for a dynamic loader plug-in.
31140127ef0fSEd Maste   ArchSpec process_arch;
31150127ef0fSEd Maste   DidAttach(process_arch);
31160127ef0fSEd Maste 
3117435933ddSDimitry Andric   if (process_arch.IsValid()) {
31189f2f44ceSEd Maste     GetTarget().SetArchitecture(process_arch);
3119435933ddSDimitry Andric     if (log) {
31200127ef0fSEd Maste       const char *triple_str = process_arch.GetTriple().getTriple().c_str();
3121435933ddSDimitry Andric       log->Printf("Process::%s replacing process architecture with DidAttach() "
3122435933ddSDimitry Andric                   "architecture: %s",
3123435933ddSDimitry Andric                   __FUNCTION__, triple_str ? triple_str : "<null>");
31240127ef0fSEd Maste     }
31250127ef0fSEd Maste   }
3126ac7ddfbfSEd Maste 
3127435933ddSDimitry Andric   // We just attached.  If we have a platform, ask it for the process
31284ba319b5SDimitry Andric   // architecture, and if it isn't the same as the one we've already set,
31294ba319b5SDimitry Andric   // switch architectures.
31309f2f44ceSEd Maste   PlatformSP platform_sp(GetTarget().GetPlatform());
31314bb0738eSEd Maste   assert(platform_sp);
3132435933ddSDimitry Andric   if (platform_sp) {
31339f2f44ceSEd Maste     const ArchSpec &target_arch = GetTarget().GetArchitecture();
3134435933ddSDimitry Andric     if (target_arch.IsValid() &&
3135435933ddSDimitry Andric         !platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr)) {
3136ac7ddfbfSEd Maste       ArchSpec platform_arch;
3137435933ddSDimitry Andric       platform_sp =
3138435933ddSDimitry Andric           platform_sp->GetPlatformForArchitecture(target_arch, &platform_arch);
3139435933ddSDimitry Andric       if (platform_sp) {
31409f2f44ceSEd Maste         GetTarget().SetPlatform(platform_sp);
31419f2f44ceSEd Maste         GetTarget().SetArchitecture(platform_arch);
31420127ef0fSEd Maste         if (log)
3143435933ddSDimitry Andric           log->Printf("Process::%s switching platform to %s and architecture "
3144435933ddSDimitry Andric                       "to %s based on info from attach",
3145435933ddSDimitry Andric                       __FUNCTION__, platform_sp->GetName().AsCString(""),
3146435933ddSDimitry Andric                       platform_arch.GetTriple().getTriple().c_str());
3147ac7ddfbfSEd Maste       }
3148435933ddSDimitry Andric     } else if (!process_arch.IsValid()) {
3149ac7ddfbfSEd Maste       ProcessInstanceInfo process_info;
31504bb0738eSEd Maste       GetProcessInfo(process_info);
3151ac7ddfbfSEd Maste       const ArchSpec &process_arch = process_info.GetArchitecture();
3152435933ddSDimitry Andric       if (process_arch.IsValid() &&
3153435933ddSDimitry Andric           !GetTarget().GetArchitecture().IsExactMatch(process_arch)) {
31549f2f44ceSEd Maste         GetTarget().SetArchitecture(process_arch);
31550127ef0fSEd Maste         if (log)
3156435933ddSDimitry Andric           log->Printf("Process::%s switching architecture to %s based on info "
3157435933ddSDimitry Andric                       "the platform retrieved for pid %" PRIu64,
3158435933ddSDimitry Andric                       __FUNCTION__,
3159435933ddSDimitry Andric                       process_arch.GetTriple().getTriple().c_str(), GetID());
31600127ef0fSEd Maste       }
3161ac7ddfbfSEd Maste     }
3162ac7ddfbfSEd Maste   }
3163ac7ddfbfSEd Maste 
3164ac7ddfbfSEd Maste   // We have completed the attach, now it is time to find the dynamic loader
3165ac7ddfbfSEd Maste   // plug-in
3166ac7ddfbfSEd Maste   DynamicLoader *dyld = GetDynamicLoader();
3167435933ddSDimitry Andric   if (dyld) {
3168ac7ddfbfSEd Maste     dyld->DidAttach();
3169435933ddSDimitry Andric     if (log) {
31709f2f44ceSEd Maste       ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
3171435933ddSDimitry Andric       log->Printf("Process::%s after DynamicLoader::DidAttach(), target "
3172435933ddSDimitry Andric                   "executable is %s (using %s plugin)",
31730127ef0fSEd Maste                   __FUNCTION__,
3174435933ddSDimitry Andric                   exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
3175435933ddSDimitry Andric                                 : "<none>",
31760127ef0fSEd Maste                   dyld->GetPluginName().AsCString("<unnamed>"));
31770127ef0fSEd Maste     }
31780127ef0fSEd Maste   }
31790127ef0fSEd Maste 
31800127ef0fSEd Maste   GetJITLoaders().DidAttach();
3181ac7ddfbfSEd Maste 
318235617911SEd Maste   SystemRuntime *system_runtime = GetSystemRuntime();
3183435933ddSDimitry Andric   if (system_runtime) {
318435617911SEd Maste     system_runtime->DidAttach();
3185435933ddSDimitry Andric     if (log) {
31869f2f44ceSEd Maste       ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
3187435933ddSDimitry Andric       log->Printf("Process::%s after SystemRuntime::DidAttach(), target "
3188435933ddSDimitry Andric                   "executable is %s (using %s plugin)",
31890127ef0fSEd Maste                   __FUNCTION__,
3190435933ddSDimitry Andric                   exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
3191435933ddSDimitry Andric                                 : "<none>",
31920127ef0fSEd Maste                   system_runtime->GetPluginName().AsCString("<unnamed>"));
31930127ef0fSEd Maste     }
31940127ef0fSEd Maste   }
319535617911SEd Maste 
3196f678e45dSDimitry Andric   if (!m_os_ap)
3197f678e45dSDimitry Andric     LoadOperatingSystemPlugin(false);
3198ac7ddfbfSEd Maste   // Figure out which one is the executable, and set that in our target:
31999f2f44ceSEd Maste   const ModuleList &target_modules = GetTarget().GetImages();
32004bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3201ac7ddfbfSEd Maste   size_t num_modules = target_modules.GetSize();
3202ac7ddfbfSEd Maste   ModuleSP new_executable_module_sp;
3203ac7ddfbfSEd Maste 
3204435933ddSDimitry Andric   for (size_t i = 0; i < num_modules; i++) {
3205ac7ddfbfSEd Maste     ModuleSP module_sp(target_modules.GetModuleAtIndexUnlocked(i));
3206435933ddSDimitry Andric     if (module_sp && module_sp->IsExecutable()) {
32079f2f44ceSEd Maste       if (GetTarget().GetExecutableModulePointer() != module_sp.get())
3208ac7ddfbfSEd Maste         new_executable_module_sp = module_sp;
3209ac7ddfbfSEd Maste       break;
3210ac7ddfbfSEd Maste     }
3211ac7ddfbfSEd Maste   }
3212435933ddSDimitry Andric   if (new_executable_module_sp) {
3213*b5893f02SDimitry Andric     GetTarget().SetExecutableModule(new_executable_module_sp,
3214*b5893f02SDimitry Andric                                     eLoadDependentsNo);
3215435933ddSDimitry Andric     if (log) {
32169f2f44ceSEd Maste       ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
3217435933ddSDimitry Andric       log->Printf(
3218435933ddSDimitry Andric           "Process::%s after looping through modules, target executable is %s",
32190127ef0fSEd Maste           __FUNCTION__,
3220435933ddSDimitry Andric           exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
3221435933ddSDimitry Andric                         : "<none>");
32220127ef0fSEd Maste     }
32230127ef0fSEd Maste   }
3224ac7ddfbfSEd Maste }
3225ac7ddfbfSEd Maste 
ConnectRemote(Stream * strm,llvm::StringRef remote_url)32265517e702SDimitry Andric Status Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) {
3227ac7ddfbfSEd Maste   m_abi_sp.reset();
3228ac7ddfbfSEd Maste   m_process_input_reader.reset();
3229ac7ddfbfSEd Maste 
3230435933ddSDimitry Andric   // Find the process and its architecture.  Make sure it matches the
3231435933ddSDimitry Andric   // architecture of the current Target, and if not adjust it.
3232ac7ddfbfSEd Maste 
32335517e702SDimitry Andric   Status error(DoConnectRemote(strm, remote_url));
3234435933ddSDimitry Andric   if (error.Success()) {
3235435933ddSDimitry Andric     if (GetID() != LLDB_INVALID_PROCESS_ID) {
3236ac7ddfbfSEd Maste       EventSP event_sp;
3237435933ddSDimitry Andric       StateType state = WaitForProcessStopPrivate(event_sp, llvm::None);
3238ac7ddfbfSEd Maste 
3239435933ddSDimitry Andric       if (state == eStateStopped || state == eStateCrashed) {
3240ac7ddfbfSEd Maste         // If we attached and actually have a process on the other end, then
3241ac7ddfbfSEd Maste         // this ended up being the equivalent of an attach.
3242ac7ddfbfSEd Maste         CompleteAttach();
3243ac7ddfbfSEd Maste 
3244ac7ddfbfSEd Maste         // This delays passing the stopped event to listeners till
3245ac7ddfbfSEd Maste         // CompleteAttach gets a chance to complete...
3246ac7ddfbfSEd Maste         HandlePrivateEvent(event_sp);
3247ac7ddfbfSEd Maste       }
3248ac7ddfbfSEd Maste     }
3249ac7ddfbfSEd Maste 
3250ac7ddfbfSEd Maste     if (PrivateStateThreadIsValid())
3251ac7ddfbfSEd Maste       ResumePrivateStateThread();
3252ac7ddfbfSEd Maste     else
3253ac7ddfbfSEd Maste       StartPrivateStateThread();
3254ac7ddfbfSEd Maste   }
3255ac7ddfbfSEd Maste   return error;
3256ac7ddfbfSEd Maste }
3257ac7ddfbfSEd Maste 
PrivateResume()32585517e702SDimitry Andric Status Process::PrivateResume() {
3259435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS |
3260435933ddSDimitry Andric                                                   LIBLLDB_LOG_STEP));
3261ac7ddfbfSEd Maste   if (log)
3262435933ddSDimitry Andric     log->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s "
3263435933ddSDimitry Andric                 "private state: %s",
3264435933ddSDimitry Andric                 m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()),
3265ac7ddfbfSEd Maste                 StateAsCString(m_private_state.GetValue()));
3266ac7ddfbfSEd Maste 
32674ba319b5SDimitry Andric   // If signals handing status changed we might want to update our signal
32684ba319b5SDimitry Andric   // filters before resuming.
3269f678e45dSDimitry Andric   UpdateAutomaticSignalFiltering();
3270f678e45dSDimitry Andric 
32715517e702SDimitry Andric   Status error(WillResume());
3272ac7ddfbfSEd Maste   // Tell the process it is about to resume before the thread list
3273435933ddSDimitry Andric   if (error.Success()) {
32744ba319b5SDimitry Andric     // Now let the thread list know we are about to resume so it can let all of
32754ba319b5SDimitry Andric     // our threads know that they are about to be resumed. Threads will each be
32764ba319b5SDimitry Andric     // called with Thread::WillResume(StateType) where StateType contains the
32774ba319b5SDimitry Andric     // state that they are supposed to have when the process is resumed
32784ba319b5SDimitry Andric     // (suspended/running/stepping). Threads should also check their resume
32794ba319b5SDimitry Andric     // signal in lldb::Thread::GetResumeSignal() to see if they are supposed to
32804ba319b5SDimitry Andric     // start back up with a signal.
3281435933ddSDimitry Andric     if (m_thread_list.WillResume()) {
3282ac7ddfbfSEd Maste       // Last thing, do the PreResumeActions.
3283435933ddSDimitry Andric       if (!RunPreResumeActions()) {
3284435933ddSDimitry Andric         error.SetErrorStringWithFormat(
3285435933ddSDimitry Andric             "Process::PrivateResume PreResumeActions failed, not resuming.");
3286435933ddSDimitry Andric       } else {
3287ac7ddfbfSEd Maste         m_mod_id.BumpResumeID();
3288ac7ddfbfSEd Maste         error = DoResume();
3289435933ddSDimitry Andric         if (error.Success()) {
3290ac7ddfbfSEd Maste           DidResume();
3291ac7ddfbfSEd Maste           m_thread_list.DidResume();
3292ac7ddfbfSEd Maste           if (log)
3293ac7ddfbfSEd Maste             log->Printf("Process thinks the process has resumed.");
3294*b5893f02SDimitry Andric         } else {
3295*b5893f02SDimitry Andric           if (log)
3296*b5893f02SDimitry Andric             log->Printf(
3297*b5893f02SDimitry Andric                 "Process::PrivateResume() DoResume failed.");
3298*b5893f02SDimitry Andric           return error;
3299ac7ddfbfSEd Maste         }
3300ac7ddfbfSEd Maste       }
3301435933ddSDimitry Andric     } else {
33024ba319b5SDimitry Andric       // Somebody wanted to run without running (e.g. we were faking a step
33034ba319b5SDimitry Andric       // from one frame of a set of inlined frames that share the same PC to
33044ba319b5SDimitry Andric       // another.)  So generate a continue & a stopped event, and let the world
33054ba319b5SDimitry Andric       // handle them.
3306ac7ddfbfSEd Maste       if (log)
3307435933ddSDimitry Andric         log->Printf(
3308435933ddSDimitry Andric             "Process::PrivateResume() asked to simulate a start & stop.");
3309ac7ddfbfSEd Maste 
3310ac7ddfbfSEd Maste       SetPrivateState(eStateRunning);
3311ac7ddfbfSEd Maste       SetPrivateState(eStateStopped);
3312ac7ddfbfSEd Maste     }
3313435933ddSDimitry Andric   } else if (log)
3314435933ddSDimitry Andric     log->Printf("Process::PrivateResume() got an error \"%s\".",
3315435933ddSDimitry Andric                 error.AsCString("<unknown error>"));
3316ac7ddfbfSEd Maste   return error;
3317ac7ddfbfSEd Maste }
3318ac7ddfbfSEd Maste 
Halt(bool clear_thread_plans,bool use_run_lock)33195517e702SDimitry Andric Status Process::Halt(bool clear_thread_plans, bool use_run_lock) {
33209f2f44ceSEd Maste   if (!StateIsRunningState(m_public_state.GetValue()))
33215517e702SDimitry Andric     return Status("Process is not running.");
33229f2f44ceSEd Maste 
33234ba319b5SDimitry Andric   // Don't clear the m_clear_thread_plans_on_stop, only set it to true if in
33244ba319b5SDimitry Andric   // case it was already set and some thread plan logic calls halt on its own.
3325ac7ddfbfSEd Maste   m_clear_thread_plans_on_stop |= clear_thread_plans;
3326ac7ddfbfSEd Maste 
3327435933ddSDimitry Andric   ListenerSP halt_listener_sp(
3328435933ddSDimitry Andric       Listener::MakeListener("lldb.process.halt_listener"));
33294bb0738eSEd Maste   HijackProcessEvents(halt_listener_sp);
3330ac7ddfbfSEd Maste 
3331ac7ddfbfSEd Maste   EventSP event_sp;
3332ac7ddfbfSEd Maste 
33339f2f44ceSEd Maste   SendAsyncInterrupt();
3334ac7ddfbfSEd Maste 
3335435933ddSDimitry Andric   if (m_public_state.GetValue() == eStateAttaching) {
33364ba319b5SDimitry Andric     // Don't hijack and eat the eStateExited as the code that was doing the
33374ba319b5SDimitry Andric     // attach will be waiting for this event...
33389f2f44ceSEd Maste     RestoreProcessEvents();
3339ac7ddfbfSEd Maste     SetExitStatus(SIGKILL, "Cancelled async attach.");
33401c3bbb01SEd Maste     Destroy(false);
33415517e702SDimitry Andric     return Status();
3342ac7ddfbfSEd Maste   }
33439f2f44ceSEd Maste 
33449f2f44ceSEd Maste   // Wait for 10 second for the process to stop.
3345435933ddSDimitry Andric   StateType state = WaitForProcessToStop(
3346435933ddSDimitry Andric       seconds(10), &event_sp, true, halt_listener_sp, nullptr, use_run_lock);
33479f2f44ceSEd Maste   RestoreProcessEvents();
3348ac7ddfbfSEd Maste 
3349435933ddSDimitry Andric   if (state == eStateInvalid || !event_sp) {
33509f2f44ceSEd Maste     // We timed out and didn't get a stop event...
33515517e702SDimitry Andric     return Status("Halt timed out. State = %s", StateAsCString(GetState()));
3352ac7ddfbfSEd Maste   }
3353ac7ddfbfSEd Maste 
33549f2f44ceSEd Maste   BroadcastEvent(event_sp);
3355ac7ddfbfSEd Maste 
33565517e702SDimitry Andric   return Status();
3357ac7ddfbfSEd Maste }
3358ac7ddfbfSEd Maste 
StopForDestroyOrDetach(lldb::EventSP & exit_event_sp)33595517e702SDimitry Andric Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
33605517e702SDimitry Andric   Status error;
3361435933ddSDimitry Andric 
3362435933ddSDimitry Andric   // Check both the public & private states here.  If we're hung evaluating an
33634ba319b5SDimitry Andric   // expression, for instance, then the public state will be stopped, but we
33644ba319b5SDimitry Andric   // still need to interrupt.
3365435933ddSDimitry Andric   if (m_public_state.GetValue() == eStateRunning ||
3366435933ddSDimitry Andric       m_private_state.GetValue() == eStateRunning) {
3367ac7ddfbfSEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
3368ac7ddfbfSEd Maste     if (log)
33699f2f44ceSEd Maste       log->Printf("Process::%s() About to stop.", __FUNCTION__);
33709f2f44ceSEd Maste 
3371435933ddSDimitry Andric     ListenerSP listener_sp(
3372435933ddSDimitry Andric         Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack"));
33734bb0738eSEd Maste     HijackProcessEvents(listener_sp);
33749f2f44ceSEd Maste 
33759f2f44ceSEd Maste     SendAsyncInterrupt();
33769f2f44ceSEd Maste 
33779f2f44ceSEd Maste     // Consume the interrupt event.
3378435933ddSDimitry Andric     StateType state =
3379435933ddSDimitry Andric         WaitForProcessToStop(seconds(10), &exit_event_sp, true, listener_sp);
33809f2f44ceSEd Maste 
33819f2f44ceSEd Maste     RestoreProcessEvents();
3382ac7ddfbfSEd Maste 
3383435933ddSDimitry Andric     // If the process exited while we were waiting for it to stop, put the
33844ba319b5SDimitry Andric     // exited event into the shared pointer passed in and return.  Our caller
33854ba319b5SDimitry Andric     // doesn't need to do anything else, since they don't have a process
33864ba319b5SDimitry Andric     // anymore...
3387ac7ddfbfSEd Maste 
3388435933ddSDimitry Andric     if (state == eStateExited || m_private_state.GetValue() == eStateExited) {
3389ac7ddfbfSEd Maste       if (log)
3390435933ddSDimitry Andric         log->Printf("Process::%s() Process exited while waiting to stop.",
3391435933ddSDimitry Andric                     __FUNCTION__);
3392ac7ddfbfSEd Maste       return error;
3393435933ddSDimitry Andric     } else
3394ac7ddfbfSEd Maste       exit_event_sp.reset(); // It is ok to consume any non-exit stop events
3395ac7ddfbfSEd Maste 
3396435933ddSDimitry Andric     if (state != eStateStopped) {
3397ac7ddfbfSEd Maste       if (log)
3398435933ddSDimitry Andric         log->Printf("Process::%s() failed to stop, state is: %s", __FUNCTION__,
3399435933ddSDimitry Andric                     StateAsCString(state));
3400435933ddSDimitry Andric       // If we really couldn't stop the process then we should just error out
34014ba319b5SDimitry Andric       // here, but if the lower levels just bobbled sending the event and we
34024ba319b5SDimitry Andric       // really are stopped, then continue on.
3403ac7ddfbfSEd Maste       StateType private_state = m_private_state.GetValue();
3404435933ddSDimitry Andric       if (private_state != eStateStopped) {
34055517e702SDimitry Andric         return Status(
34065517e702SDimitry Andric             "Attempt to stop the target in order to detach timed out. "
3407435933ddSDimitry Andric             "State = %s",
3408435933ddSDimitry Andric             StateAsCString(GetState()));
3409ac7ddfbfSEd Maste       }
3410ac7ddfbfSEd Maste     }
3411ac7ddfbfSEd Maste   }
3412ac7ddfbfSEd Maste   return error;
3413ac7ddfbfSEd Maste }
3414ac7ddfbfSEd Maste 
Detach(bool keep_stopped)34155517e702SDimitry Andric Status Process::Detach(bool keep_stopped) {
3416ac7ddfbfSEd Maste   EventSP exit_event_sp;
34175517e702SDimitry Andric   Status error;
3418ac7ddfbfSEd Maste   m_destroy_in_process = true;
3419ac7ddfbfSEd Maste 
3420ac7ddfbfSEd Maste   error = WillDetach();
3421ac7ddfbfSEd Maste 
3422435933ddSDimitry Andric   if (error.Success()) {
3423435933ddSDimitry Andric     if (DetachRequiresHalt()) {
34249f2f44ceSEd Maste       error = StopForDestroyOrDetach(exit_event_sp);
3425435933ddSDimitry Andric       if (!error.Success()) {
3426ac7ddfbfSEd Maste         m_destroy_in_process = false;
3427ac7ddfbfSEd Maste         return error;
3428435933ddSDimitry Andric       } else if (exit_event_sp) {
3429435933ddSDimitry Andric         // We shouldn't need to do anything else here.  There's no process left
3430435933ddSDimitry Andric         // to detach from...
3431ac7ddfbfSEd Maste         StopPrivateStateThread();
3432ac7ddfbfSEd Maste         m_destroy_in_process = false;
3433ac7ddfbfSEd Maste         return error;
3434ac7ddfbfSEd Maste       }
3435ac7ddfbfSEd Maste     }
3436ac7ddfbfSEd Maste 
34370127ef0fSEd Maste     m_thread_list.DiscardThreadPlans();
34380127ef0fSEd Maste     DisableAllBreakpointSites();
34390127ef0fSEd Maste 
3440ac7ddfbfSEd Maste     error = DoDetach(keep_stopped);
3441435933ddSDimitry Andric     if (error.Success()) {
3442ac7ddfbfSEd Maste       DidDetach();
3443ac7ddfbfSEd Maste       StopPrivateStateThread();
3444435933ddSDimitry Andric     } else {
3445ac7ddfbfSEd Maste       return error;
3446ac7ddfbfSEd Maste     }
3447ac7ddfbfSEd Maste   }
3448ac7ddfbfSEd Maste   m_destroy_in_process = false;
3449ac7ddfbfSEd Maste 
34504ba319b5SDimitry Andric   // If we exited when we were waiting for a process to stop, then forward the
34514ba319b5SDimitry Andric   // event here so we don't lose the event
3452435933ddSDimitry Andric   if (exit_event_sp) {
34534ba319b5SDimitry Andric     // Directly broadcast our exited event because we shut down our private
34544ba319b5SDimitry Andric     // state thread above
3455ac7ddfbfSEd Maste     BroadcastEvent(exit_event_sp);
3456ac7ddfbfSEd Maste   }
3457ac7ddfbfSEd Maste 
3458435933ddSDimitry Andric   // If we have been interrupted (to kill us) in the middle of running, we may
34594ba319b5SDimitry Andric   // not end up propagating the last events through the event system, in which
34604ba319b5SDimitry Andric   // case we might strand the write lock.  Unlock it here so when we do to tear
34614ba319b5SDimitry Andric   // down the process we don't get an error destroying the lock.
3462ac7ddfbfSEd Maste 
3463ac7ddfbfSEd Maste   m_public_run_lock.SetStopped();
3464ac7ddfbfSEd Maste   return error;
3465ac7ddfbfSEd Maste }
3466ac7ddfbfSEd Maste 
Destroy(bool force_kill)34675517e702SDimitry Andric Status Process::Destroy(bool force_kill) {
3468ac7ddfbfSEd Maste 
3469435933ddSDimitry Andric   // Tell ourselves we are in the process of destroying the process, so that we
34704ba319b5SDimitry Andric   // don't do any unnecessary work that might hinder the destruction.  Remember
34714ba319b5SDimitry Andric   // to set this back to false when we are done.  That way if the attempt
3472435933ddSDimitry Andric   // failed and the process stays around for some reason it won't be in a
3473435933ddSDimitry Andric   // confused state.
3474ac7ddfbfSEd Maste 
34751c3bbb01SEd Maste   if (force_kill)
34761c3bbb01SEd Maste     m_should_detach = false;
34771c3bbb01SEd Maste 
3478435933ddSDimitry Andric   if (GetShouldDetach()) {
34791c3bbb01SEd Maste     // FIXME: This will have to be a process setting:
34801c3bbb01SEd Maste     bool keep_stopped = false;
34811c3bbb01SEd Maste     Detach(keep_stopped);
34821c3bbb01SEd Maste   }
34831c3bbb01SEd Maste 
3484ac7ddfbfSEd Maste   m_destroy_in_process = true;
3485ac7ddfbfSEd Maste 
34865517e702SDimitry Andric   Status error(WillDestroy());
3487435933ddSDimitry Andric   if (error.Success()) {
3488ac7ddfbfSEd Maste     EventSP exit_event_sp;
3489435933ddSDimitry Andric     if (DestroyRequiresHalt()) {
34909f2f44ceSEd Maste       error = StopForDestroyOrDetach(exit_event_sp);
3491ac7ddfbfSEd Maste     }
3492ac7ddfbfSEd Maste 
3493435933ddSDimitry Andric     if (m_public_state.GetValue() != eStateRunning) {
34944ba319b5SDimitry Andric       // Ditch all thread plans, and remove all our breakpoints: in case we
34954ba319b5SDimitry Andric       // have to restart the target to kill it, we don't want it hitting a
34964ba319b5SDimitry Andric       // breakpoint... Only do this if we've stopped, however, since if we
34974ba319b5SDimitry Andric       // didn't manage to halt it above, then we're not going to have much luck
34984ba319b5SDimitry Andric       // doing this now.
3499ac7ddfbfSEd Maste       m_thread_list.DiscardThreadPlans();
3500ac7ddfbfSEd Maste       DisableAllBreakpointSites();
3501ac7ddfbfSEd Maste     }
3502ac7ddfbfSEd Maste 
3503ac7ddfbfSEd Maste     error = DoDestroy();
3504435933ddSDimitry Andric     if (error.Success()) {
3505ac7ddfbfSEd Maste       DidDestroy();
3506ac7ddfbfSEd Maste       StopPrivateStateThread();
3507ac7ddfbfSEd Maste     }
3508ac7ddfbfSEd Maste     m_stdio_communication.Disconnect();
35091c3bbb01SEd Maste     m_stdio_communication.StopReadThread();
35101c3bbb01SEd Maste     m_stdin_forward = false;
35110127ef0fSEd Maste 
3512435933ddSDimitry Andric     if (m_process_input_reader) {
35130127ef0fSEd Maste       m_process_input_reader->SetIsDone(true);
35140127ef0fSEd Maste       m_process_input_reader->Cancel();
3515ac7ddfbfSEd Maste       m_process_input_reader.reset();
35160127ef0fSEd Maste     }
3517ac7ddfbfSEd Maste 
35184ba319b5SDimitry Andric     // If we exited when we were waiting for a process to stop, then forward
35194ba319b5SDimitry Andric     // the event here so we don't lose the event
3520435933ddSDimitry Andric     if (exit_event_sp) {
35214ba319b5SDimitry Andric       // Directly broadcast our exited event because we shut down our private
35224ba319b5SDimitry Andric       // state thread above
3523ac7ddfbfSEd Maste       BroadcastEvent(exit_event_sp);
3524ac7ddfbfSEd Maste     }
3525ac7ddfbfSEd Maste 
35264ba319b5SDimitry Andric     // If we have been interrupted (to kill us) in the middle of running, we
35274ba319b5SDimitry Andric     // may not end up propagating the last events through the event system, in
35284ba319b5SDimitry Andric     // which case we might strand the write lock.  Unlock it here so when we do
35294ba319b5SDimitry Andric     // to tear down the process we don't get an error destroying the lock.
3530ac7ddfbfSEd Maste     m_public_run_lock.SetStopped();
3531ac7ddfbfSEd Maste   }
3532ac7ddfbfSEd Maste 
3533ac7ddfbfSEd Maste   m_destroy_in_process = false;
3534ac7ddfbfSEd Maste 
3535ac7ddfbfSEd Maste   return error;
3536ac7ddfbfSEd Maste }
3537ac7ddfbfSEd Maste 
Signal(int signal)35385517e702SDimitry Andric Status Process::Signal(int signal) {
35395517e702SDimitry Andric   Status error(WillSignal());
3540435933ddSDimitry Andric   if (error.Success()) {
3541ac7ddfbfSEd Maste     error = DoSignal(signal);
3542ac7ddfbfSEd Maste     if (error.Success())
3543ac7ddfbfSEd Maste       DidSignal();
3544ac7ddfbfSEd Maste   }
3545ac7ddfbfSEd Maste   return error;
3546ac7ddfbfSEd Maste }
3547ac7ddfbfSEd Maste 
SetUnixSignals(UnixSignalsSP && signals_sp)3548435933ddSDimitry Andric void Process::SetUnixSignals(UnixSignalsSP &&signals_sp) {
35491c3bbb01SEd Maste   assert(signals_sp && "null signals_sp");
35501c3bbb01SEd Maste   m_unix_signals_sp = signals_sp;
35511c3bbb01SEd Maste }
35521c3bbb01SEd Maste 
GetUnixSignals()3553435933ddSDimitry Andric const lldb::UnixSignalsSP &Process::GetUnixSignals() {
35541c3bbb01SEd Maste   assert(m_unix_signals_sp && "null m_unix_signals_sp");
3555b91a7dfcSDimitry Andric   return m_unix_signals_sp;
35561c3bbb01SEd Maste }
35571c3bbb01SEd Maste 
GetByteOrder() const3558435933ddSDimitry Andric lldb::ByteOrder Process::GetByteOrder() const {
35599f2f44ceSEd Maste   return GetTarget().GetArchitecture().GetByteOrder();
3560ac7ddfbfSEd Maste }
3561ac7ddfbfSEd Maste 
GetAddressByteSize() const3562435933ddSDimitry Andric uint32_t Process::GetAddressByteSize() const {
35639f2f44ceSEd Maste   return GetTarget().GetArchitecture().GetAddressByteSize();
3564ac7ddfbfSEd Maste }
3565ac7ddfbfSEd Maste 
ShouldBroadcastEvent(Event * event_ptr)3566435933ddSDimitry Andric bool Process::ShouldBroadcastEvent(Event *event_ptr) {
3567435933ddSDimitry Andric   const StateType state =
3568435933ddSDimitry Andric       Process::ProcessEventData::GetStateFromEvent(event_ptr);
3569ac7ddfbfSEd Maste   bool return_value = true;
3570435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS |
3571435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
3572ac7ddfbfSEd Maste 
3573435933ddSDimitry Andric   switch (state) {
3574ac7ddfbfSEd Maste   case eStateDetached:
3575ac7ddfbfSEd Maste   case eStateExited:
3576ac7ddfbfSEd Maste   case eStateUnloaded:
35771c3bbb01SEd Maste     m_stdio_communication.SynchronizeWithReadThread();
35789f2f44ceSEd Maste     m_stdio_communication.Disconnect();
35799f2f44ceSEd Maste     m_stdio_communication.StopReadThread();
35809f2f44ceSEd Maste     m_stdin_forward = false;
35819f2f44ceSEd Maste 
35824bb0738eSEd Maste     LLVM_FALLTHROUGH;
35831c3bbb01SEd Maste   case eStateConnected:
35841c3bbb01SEd Maste   case eStateAttaching:
35851c3bbb01SEd Maste   case eStateLaunching:
3586435933ddSDimitry Andric     // These events indicate changes in the state of the debugging session,
3587435933ddSDimitry Andric     // always report them.
3588ac7ddfbfSEd Maste     return_value = true;
3589ac7ddfbfSEd Maste     break;
3590ac7ddfbfSEd Maste   case eStateInvalid:
3591ac7ddfbfSEd Maste     // We stopped for no apparent reason, don't report it.
3592ac7ddfbfSEd Maste     return_value = false;
3593ac7ddfbfSEd Maste     break;
3594ac7ddfbfSEd Maste   case eStateRunning:
3595ac7ddfbfSEd Maste   case eStateStepping:
35964ba319b5SDimitry Andric     // If we've started the target running, we handle the cases where we are
35974ba319b5SDimitry Andric     // already running and where there is a transition from stopped to running
35984ba319b5SDimitry Andric     // differently. running -> running: Automatically suppress extra running
35994ba319b5SDimitry Andric     // events stopped -> running: Report except when there is one or more no
36004ba319b5SDimitry Andric     // votes
3601ac7ddfbfSEd Maste     //     and no yes votes.
3602ac7ddfbfSEd Maste     SynchronouslyNotifyStateChanged(state);
360312b93ac6SEd Maste     if (m_force_next_event_delivery)
360412b93ac6SEd Maste       return_value = true;
3605435933ddSDimitry Andric     else {
3606435933ddSDimitry Andric       switch (m_last_broadcast_state) {
3607ac7ddfbfSEd Maste       case eStateRunning:
3608ac7ddfbfSEd Maste       case eStateStepping:
3609ac7ddfbfSEd Maste         // We always suppress multiple runnings with no PUBLIC stop in between.
3610ac7ddfbfSEd Maste         return_value = false;
3611ac7ddfbfSEd Maste         break;
3612ac7ddfbfSEd Maste       default:
3613ac7ddfbfSEd Maste         // TODO: make this work correctly. For now always report
36144ba319b5SDimitry Andric         // run if we aren't running so we don't miss any running events. If I
36154ba319b5SDimitry Andric         // run the lldb/test/thread/a.out file and break at main.cpp:58, run
36164ba319b5SDimitry Andric         // and hit the breakpoints on multiple threads, then somehow during the
36174ba319b5SDimitry Andric         // stepping over of all breakpoints no run gets reported.
3618ac7ddfbfSEd Maste 
3619ac7ddfbfSEd Maste         // This is a transition from stop to run.
3620435933ddSDimitry Andric         switch (m_thread_list.ShouldReportRun(event_ptr)) {
3621ac7ddfbfSEd Maste         case eVoteYes:
3622ac7ddfbfSEd Maste         case eVoteNoOpinion:
3623ac7ddfbfSEd Maste           return_value = true;
3624ac7ddfbfSEd Maste           break;
3625ac7ddfbfSEd Maste         case eVoteNo:
3626ac7ddfbfSEd Maste           return_value = false;
3627ac7ddfbfSEd Maste           break;
3628ac7ddfbfSEd Maste         }
3629ac7ddfbfSEd Maste         break;
3630ac7ddfbfSEd Maste       }
363112b93ac6SEd Maste     }
3632ac7ddfbfSEd Maste     break;
3633ac7ddfbfSEd Maste   case eStateStopped:
3634ac7ddfbfSEd Maste   case eStateCrashed:
3635ac7ddfbfSEd Maste   case eStateSuspended:
36364ba319b5SDimitry Andric     // We've stopped.  First see if we're going to restart the target. If we
36374ba319b5SDimitry Andric     // are going to stop, then we always broadcast the event. If we aren't
36384ba319b5SDimitry Andric     // going to stop, let the thread plans decide if we're going to report this
36394ba319b5SDimitry Andric     // event. If no thread has an opinion, we don't report it.
3640ac7ddfbfSEd Maste 
36411c3bbb01SEd Maste     m_stdio_communication.SynchronizeWithReadThread();
3642ac7ddfbfSEd Maste     RefreshStateAfterStop();
3643435933ddSDimitry Andric     if (ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
3644ac7ddfbfSEd Maste       if (log)
3645435933ddSDimitry Andric         log->Printf("Process::ShouldBroadcastEvent (%p) stopped due to an "
3646435933ddSDimitry Andric                     "interrupt, state: %s",
3647435933ddSDimitry Andric                     static_cast<void *>(event_ptr), StateAsCString(state));
3648435933ddSDimitry Andric       // Even though we know we are going to stop, we should let the threads
36494ba319b5SDimitry Andric       // have a look at the stop, so they can properly set their state.
36500127ef0fSEd Maste       m_thread_list.ShouldStop(event_ptr);
3651ac7ddfbfSEd Maste       return_value = true;
3652435933ddSDimitry Andric     } else {
3653ac7ddfbfSEd Maste       bool was_restarted = ProcessEventData::GetRestartedFromEvent(event_ptr);
3654ac7ddfbfSEd Maste       bool should_resume = false;
3655ac7ddfbfSEd Maste 
3656435933ddSDimitry Andric       // It makes no sense to ask "ShouldStop" if we've already been
36574ba319b5SDimitry Andric       // restarted... Asking the thread list is also not likely to go well,
36584ba319b5SDimitry Andric       // since we are running again. So in that case just report the event.
3659ac7ddfbfSEd Maste 
3660ac7ddfbfSEd Maste       if (!was_restarted)
36614bb0738eSEd Maste         should_resume = !m_thread_list.ShouldStop(event_ptr);
3662ac7ddfbfSEd Maste 
3663435933ddSDimitry Andric       if (was_restarted || should_resume || m_resume_requested) {
3664ac7ddfbfSEd Maste         Vote stop_vote = m_thread_list.ShouldReportStop(event_ptr);
3665ac7ddfbfSEd Maste         if (log)
3666435933ddSDimitry Andric           log->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: "
3667435933ddSDimitry Andric                       "%s was_restarted: %i stop_vote: %d.",
3668435933ddSDimitry Andric                       should_resume, StateAsCString(state), was_restarted,
3669435933ddSDimitry Andric                       stop_vote);
3670ac7ddfbfSEd Maste 
3671435933ddSDimitry Andric         switch (stop_vote) {
3672ac7ddfbfSEd Maste         case eVoteYes:
3673ac7ddfbfSEd Maste           return_value = true;
3674ac7ddfbfSEd Maste           break;
3675ac7ddfbfSEd Maste         case eVoteNoOpinion:
3676ac7ddfbfSEd Maste         case eVoteNo:
3677ac7ddfbfSEd Maste           return_value = false;
3678ac7ddfbfSEd Maste           break;
3679ac7ddfbfSEd Maste         }
3680ac7ddfbfSEd Maste 
3681435933ddSDimitry Andric         if (!was_restarted) {
3682ac7ddfbfSEd Maste           if (log)
3683435933ddSDimitry Andric             log->Printf("Process::ShouldBroadcastEvent (%p) Restarting process "
3684435933ddSDimitry Andric                         "from state: %s",
3685435933ddSDimitry Andric                         static_cast<void *>(event_ptr), StateAsCString(state));
3686ac7ddfbfSEd Maste           ProcessEventData::SetRestartedInEvent(event_ptr, true);
3687ac7ddfbfSEd Maste           PrivateResume();
3688ac7ddfbfSEd Maste         }
3689435933ddSDimitry Andric       } else {
3690ac7ddfbfSEd Maste         return_value = true;
3691ac7ddfbfSEd Maste         SynchronouslyNotifyStateChanged(state);
3692ac7ddfbfSEd Maste       }
3693ac7ddfbfSEd Maste     }
3694ac7ddfbfSEd Maste     break;
3695ac7ddfbfSEd Maste   }
3696ac7ddfbfSEd Maste 
369712b93ac6SEd Maste   // Forcing the next event delivery is a one shot deal.  So reset it here.
369812b93ac6SEd Maste   m_force_next_event_delivery = false;
369912b93ac6SEd Maste 
3700435933ddSDimitry Andric   // We do some coalescing of events (for instance two consecutive running
37014ba319b5SDimitry Andric   // events get coalesced.) But we only coalesce against events we actually
37024ba319b5SDimitry Andric   // broadcast.  So we use m_last_broadcast_state to track that.  NB - you
37034ba319b5SDimitry Andric   // can't use "m_public_state.GetValue()" for that purpose, as was originally
37044ba319b5SDimitry Andric   // done, because the PublicState reflects the last event pulled off the
37054ba319b5SDimitry Andric   // queue, and there may be several events stacked up on the queue unserviced.
37064ba319b5SDimitry Andric   // So the PublicState may not reflect the last broadcasted event yet.
37074ba319b5SDimitry Andric   // m_last_broadcast_state gets updated here.
3708ac7ddfbfSEd Maste 
3709ac7ddfbfSEd Maste   if (return_value)
3710ac7ddfbfSEd Maste     m_last_broadcast_state = state;
3711ac7ddfbfSEd Maste 
3712ac7ddfbfSEd Maste   if (log)
3713435933ddSDimitry Andric     log->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last "
3714435933ddSDimitry Andric                 "broadcast state: %s - %s",
37150127ef0fSEd Maste                 static_cast<void *>(event_ptr), StateAsCString(state),
3716ac7ddfbfSEd Maste                 StateAsCString(m_last_broadcast_state),
3717ac7ddfbfSEd Maste                 return_value ? "YES" : "NO");
3718ac7ddfbfSEd Maste   return return_value;
3719ac7ddfbfSEd Maste }
3720ac7ddfbfSEd Maste 
StartPrivateStateThread(bool is_secondary_thread)3721435933ddSDimitry Andric bool Process::StartPrivateStateThread(bool is_secondary_thread) {
3722ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
3723ac7ddfbfSEd Maste 
3724ac7ddfbfSEd Maste   bool already_running = PrivateStateThreadIsValid();
3725ac7ddfbfSEd Maste   if (log)
3726435933ddSDimitry Andric     log->Printf("Process::%s()%s ", __FUNCTION__,
3727435933ddSDimitry Andric                 already_running ? " already running"
3728435933ddSDimitry Andric                                 : " starting private state thread");
3729ac7ddfbfSEd Maste 
37301c3bbb01SEd Maste   if (!is_secondary_thread && already_running)
3731ac7ddfbfSEd Maste     return true;
3732ac7ddfbfSEd Maste 
37334ba319b5SDimitry Andric   // Create a thread that watches our internal state and controls which events
37344ba319b5SDimitry Andric   // make it to clients (into the DCProcess event queue).
3735ac7ddfbfSEd Maste   char thread_name[1024];
3736f678e45dSDimitry Andric   uint32_t max_len = llvm::get_max_thread_name_length();
3737f678e45dSDimitry Andric   if (max_len > 0 && max_len <= 30) {
3738435933ddSDimitry Andric     // On platforms with abbreviated thread name lengths, choose thread names
3739435933ddSDimitry Andric     // that fit within the limit.
37400127ef0fSEd Maste     if (already_running)
37410127ef0fSEd Maste       snprintf(thread_name, sizeof(thread_name), "intern-state-OV");
37420127ef0fSEd Maste     else
37430127ef0fSEd Maste       snprintf(thread_name, sizeof(thread_name), "intern-state");
3744435933ddSDimitry Andric   } else {
3745ac7ddfbfSEd Maste     if (already_running)
3746435933ddSDimitry Andric       snprintf(thread_name, sizeof(thread_name),
3747435933ddSDimitry Andric                "<lldb.process.internal-state-override(pid=%" PRIu64 ")>",
3748435933ddSDimitry Andric                GetID());
3749ac7ddfbfSEd Maste     else
3750435933ddSDimitry Andric       snprintf(thread_name, sizeof(thread_name),
3751435933ddSDimitry Andric                "<lldb.process.internal-state(pid=%" PRIu64 ")>", GetID());
37520127ef0fSEd Maste   }
3753ac7ddfbfSEd Maste 
3754ac7ddfbfSEd Maste   // Create the private state thread, and start it running.
3755435933ddSDimitry Andric   PrivateStateThreadArgs *args_ptr =
3756435933ddSDimitry Andric       new PrivateStateThreadArgs(this, is_secondary_thread);
3757435933ddSDimitry Andric   m_private_state_thread =
3758435933ddSDimitry Andric       ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread,
3759435933ddSDimitry Andric                                    (void *)args_ptr, nullptr, 8 * 1024 * 1024);
3760435933ddSDimitry Andric   if (m_private_state_thread.IsJoinable()) {
3761ac7ddfbfSEd Maste     ResumePrivateStateThread();
3762ac7ddfbfSEd Maste     return true;
3763435933ddSDimitry Andric   } else
3764ac7ddfbfSEd Maste     return false;
3765ac7ddfbfSEd Maste }
3766ac7ddfbfSEd Maste 
PausePrivateStateThread()3767435933ddSDimitry Andric void Process::PausePrivateStateThread() {
3768ac7ddfbfSEd Maste   ControlPrivateStateThread(eBroadcastInternalStateControlPause);
3769ac7ddfbfSEd Maste }
3770ac7ddfbfSEd Maste 
ResumePrivateStateThread()3771435933ddSDimitry Andric void Process::ResumePrivateStateThread() {
3772ac7ddfbfSEd Maste   ControlPrivateStateThread(eBroadcastInternalStateControlResume);
3773ac7ddfbfSEd Maste }
3774ac7ddfbfSEd Maste 
StopPrivateStateThread()3775435933ddSDimitry Andric void Process::StopPrivateStateThread() {
37764bb0738eSEd Maste   if (m_private_state_thread.IsJoinable())
3777ac7ddfbfSEd Maste     ControlPrivateStateThread(eBroadcastInternalStateControlStop);
3778435933ddSDimitry Andric   else {
3779ac7ddfbfSEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
3780ac7ddfbfSEd Maste     if (log)
3781435933ddSDimitry Andric       log->Printf(
3782435933ddSDimitry Andric           "Went to stop the private state thread, but it was already invalid.");
3783ac7ddfbfSEd Maste   }
3784ac7ddfbfSEd Maste }
3785ac7ddfbfSEd Maste 
ControlPrivateStateThread(uint32_t signal)3786435933ddSDimitry Andric void Process::ControlPrivateStateThread(uint32_t signal) {
3787ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
3788ac7ddfbfSEd Maste 
3789ac7ddfbfSEd Maste   assert(signal == eBroadcastInternalStateControlStop ||
3790ac7ddfbfSEd Maste          signal == eBroadcastInternalStateControlPause ||
3791ac7ddfbfSEd Maste          signal == eBroadcastInternalStateControlResume);
3792ac7ddfbfSEd Maste 
3793ac7ddfbfSEd Maste   if (log)
3794ac7ddfbfSEd Maste     log->Printf("Process::%s (signal = %d)", __FUNCTION__, signal);
3795ac7ddfbfSEd Maste 
37964bb0738eSEd Maste   // Signal the private state thread
3797435933ddSDimitry Andric   if (m_private_state_thread.IsJoinable()) {
37984bb0738eSEd Maste     // Broadcast the event.
37994ba319b5SDimitry Andric     // It is important to do this outside of the if below, because it's
38004ba319b5SDimitry Andric     // possible that the thread state is invalid but that the thread is waiting
38014ba319b5SDimitry Andric     // on a control event instead of simply being on its way out (this should
38024ba319b5SDimitry Andric     // not happen, but it apparently can).
3803ac7ddfbfSEd Maste     if (log)
3804ac7ddfbfSEd Maste       log->Printf("Sending control event of type: %d.", signal);
38054bb0738eSEd Maste     std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt());
3806435933ddSDimitry Andric     m_private_state_control_broadcaster.BroadcastEvent(signal,
3807435933ddSDimitry Andric                                                        event_receipt_sp);
38084bb0738eSEd Maste 
38094bb0738eSEd Maste     // Wait for the event receipt or for the private state thread to exit
38104bb0738eSEd Maste     bool receipt_received = false;
3811435933ddSDimitry Andric     if (PrivateStateThreadIsValid()) {
3812435933ddSDimitry Andric       while (!receipt_received) {
38134ba319b5SDimitry Andric         // Check for a receipt for 2 seconds and then check if the private
38144ba319b5SDimitry Andric         // state thread is still around.
38154ba319b5SDimitry Andric         receipt_received =
38164ba319b5SDimitry Andric             event_receipt_sp->WaitForEventReceived(std::chrono::seconds(2));
3817435933ddSDimitry Andric         if (!receipt_received) {
38184ba319b5SDimitry Andric           // Check if the private state thread is still around. If it isn't
38194ba319b5SDimitry Andric           // then we are done waiting
38204bb0738eSEd Maste           if (!PrivateStateThreadIsValid())
38214bb0738eSEd Maste             break; // Private state thread exited or is exiting, we are done
38224bb0738eSEd Maste         }
38234bb0738eSEd Maste       }
38244bb0738eSEd Maste     }
3825ac7ddfbfSEd Maste 
3826435933ddSDimitry Andric     if (signal == eBroadcastInternalStateControlStop) {
3827ac7ddfbfSEd Maste       thread_result_t result = NULL;
38284bb0738eSEd Maste       m_private_state_thread.Join(&result);
38297aa51b79SEd Maste       m_private_state_thread.Reset();
3830ac7ddfbfSEd Maste     }
3831435933ddSDimitry Andric   } else {
3832ac7ddfbfSEd Maste     if (log)
3833435933ddSDimitry Andric       log->Printf(
3834435933ddSDimitry Andric           "Private state thread already dead, no need to signal it to stop.");
3835ac7ddfbfSEd Maste   }
3836ac7ddfbfSEd Maste }
3837ac7ddfbfSEd Maste 
SendAsyncInterrupt()3838435933ddSDimitry Andric void Process::SendAsyncInterrupt() {
3839ac7ddfbfSEd Maste   if (PrivateStateThreadIsValid())
3840435933ddSDimitry Andric     m_private_state_broadcaster.BroadcastEvent(Process::eBroadcastBitInterrupt,
3841435933ddSDimitry Andric                                                nullptr);
3842ac7ddfbfSEd Maste   else
38434bb0738eSEd Maste     BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr);
3844ac7ddfbfSEd Maste }
3845ac7ddfbfSEd Maste 
HandlePrivateEvent(EventSP & event_sp)3846435933ddSDimitry Andric void Process::HandlePrivateEvent(EventSP &event_sp) {
3847ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
3848ac7ddfbfSEd Maste   m_resume_requested = false;
3849ac7ddfbfSEd Maste 
3850435933ddSDimitry Andric   const StateType new_state =
3851435933ddSDimitry Andric       Process::ProcessEventData::GetStateFromEvent(event_sp.get());
3852ac7ddfbfSEd Maste 
3853ac7ddfbfSEd Maste   // First check to see if anybody wants a shot at this event:
3854435933ddSDimitry Andric   if (m_next_event_action_ap) {
3855435933ddSDimitry Andric     NextEventAction::EventActionResult action_result =
3856435933ddSDimitry Andric         m_next_event_action_ap->PerformAction(event_sp);
3857ac7ddfbfSEd Maste     if (log)
3858ac7ddfbfSEd Maste       log->Printf("Ran next event action, result was %d.", action_result);
3859ac7ddfbfSEd Maste 
3860435933ddSDimitry Andric     switch (action_result) {
3861ac7ddfbfSEd Maste     case NextEventAction::eEventActionSuccess:
38624bb0738eSEd Maste       SetNextEventAction(nullptr);
3863ac7ddfbfSEd Maste       break;
3864ac7ddfbfSEd Maste 
3865ac7ddfbfSEd Maste     case NextEventAction::eEventActionRetry:
3866ac7ddfbfSEd Maste       break;
3867ac7ddfbfSEd Maste 
3868ac7ddfbfSEd Maste     case NextEventAction::eEventActionExit:
38694ba319b5SDimitry Andric       // Handle Exiting Here.  If we already got an exited event, we should
38704ba319b5SDimitry Andric       // just propagate it.  Otherwise, swallow this event, and set our state
38714ba319b5SDimitry Andric       // to exit so the next event will kill us.
3872435933ddSDimitry Andric       if (new_state != eStateExited) {
3873ac7ddfbfSEd Maste         // FIXME: should cons up an exited event, and discard this one.
3874ac7ddfbfSEd Maste         SetExitStatus(0, m_next_event_action_ap->GetExitString());
38754bb0738eSEd Maste         SetNextEventAction(nullptr);
3876ac7ddfbfSEd Maste         return;
3877ac7ddfbfSEd Maste       }
38784bb0738eSEd Maste       SetNextEventAction(nullptr);
3879ac7ddfbfSEd Maste       break;
3880ac7ddfbfSEd Maste     }
3881ac7ddfbfSEd Maste   }
3882ac7ddfbfSEd Maste 
3883ac7ddfbfSEd Maste   // See if we should broadcast this state to external clients?
3884ac7ddfbfSEd Maste   const bool should_broadcast = ShouldBroadcastEvent(event_sp.get());
3885ac7ddfbfSEd Maste 
3886435933ddSDimitry Andric   if (should_broadcast) {
38870127ef0fSEd Maste     const bool is_hijacked = IsHijackedForEvent(eBroadcastBitStateChanged);
3888435933ddSDimitry Andric     if (log) {
3889435933ddSDimitry Andric       log->Printf("Process::%s (pid = %" PRIu64
3890435933ddSDimitry Andric                   ") broadcasting new state %s (old state %s) to %s",
3891435933ddSDimitry Andric                   __FUNCTION__, GetID(), StateAsCString(new_state),
3892ac7ddfbfSEd Maste                   StateAsCString(GetState()),
38930127ef0fSEd Maste                   is_hijacked ? "hijacked" : "public");
3894ac7ddfbfSEd Maste     }
3895ac7ddfbfSEd Maste     Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
3896435933ddSDimitry Andric     if (StateIsRunningState(new_state)) {
38974ba319b5SDimitry Andric       // Only push the input handler if we aren't fowarding events, as this
38984ba319b5SDimitry Andric       // means the curses GUI is in use... Or don't push it if we are launching
38994ba319b5SDimitry Andric       // since it will come up stopped.
3900435933ddSDimitry Andric       if (!GetTarget().GetDebugger().IsForwardingEvents() &&
3901435933ddSDimitry Andric           new_state != eStateLaunching && new_state != eStateAttaching) {
390212b93ac6SEd Maste         PushProcessIOHandler();
3903435933ddSDimitry Andric         m_iohandler_sync.SetValue(m_iohandler_sync.GetValue() + 1,
3904435933ddSDimitry Andric                                   eBroadcastAlways);
39051c3bbb01SEd Maste         if (log)
3906435933ddSDimitry Andric           log->Printf("Process::%s updated m_iohandler_sync to %d",
3907435933ddSDimitry Andric                       __FUNCTION__, m_iohandler_sync.GetValue());
39081c3bbb01SEd Maste       }
3909435933ddSDimitry Andric     } else if (StateIsStoppedState(new_state, false)) {
3910435933ddSDimitry Andric       if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) {
39114ba319b5SDimitry Andric         // If the lldb_private::Debugger is handling the events, we don't want
39124ba319b5SDimitry Andric         // to pop the process IOHandler here, we want to do it when we receive
39134ba319b5SDimitry Andric         // the stopped event so we can carefully control when the process
39144ba319b5SDimitry Andric         // IOHandler is popped because when we stop we want to display some
39154ba319b5SDimitry Andric         // text stating how and why we stopped, then maybe some
39164ba319b5SDimitry Andric         // process/thread/frame info, and then we want the "(lldb) " prompt to
39174ba319b5SDimitry Andric         // show up. If we pop the process IOHandler here, then we will cause
39184ba319b5SDimitry Andric         // the command interpreter to become the top IOHandler after the
39194ba319b5SDimitry Andric         // process pops off and it will update its prompt right away... See the
39204ba319b5SDimitry Andric         // Debugger.cpp file where it calls the function as
39210127ef0fSEd Maste         // "process_sp->PopProcessIOHandler()" to see where I am talking about.
39220127ef0fSEd Maste         // Otherwise we end up getting overlapping "(lldb) " prompts and
39230127ef0fSEd Maste         // garbled output.
39240127ef0fSEd Maste         //
39250127ef0fSEd Maste         // If we aren't handling the events in the debugger (which is indicated
39264ba319b5SDimitry Andric         // by "m_target.GetDebugger().IsHandlingEvents()" returning false) or
39274ba319b5SDimitry Andric         // we are hijacked, then we always pop the process IO handler manually.
39280127ef0fSEd Maste         // Hijacking happens when the internal process state thread is running
39294ba319b5SDimitry Andric         // thread plans, or when commands want to run in synchronous mode and
39304ba319b5SDimitry Andric         // they call "process->WaitForProcessToStop()". An example of something
39310127ef0fSEd Maste         // that will hijack the events is a simple expression:
39320127ef0fSEd Maste         //
39330127ef0fSEd Maste         //  (lldb) expr (int)puts("hello")
39340127ef0fSEd Maste         //
39350127ef0fSEd Maste         // This will cause the internal process state thread to resume and halt
39360127ef0fSEd Maste         // the process (and _it_ will hijack the eBroadcastBitStateChanged
39370127ef0fSEd Maste         // events) and we do need the IO handler to be pushed and popped
39380127ef0fSEd Maste         // correctly.
39390127ef0fSEd Maste 
39404bb0738eSEd Maste         if (is_hijacked || !GetTarget().GetDebugger().IsHandlingEvents())
394112b93ac6SEd Maste           PopProcessIOHandler();
39420127ef0fSEd Maste       }
39430127ef0fSEd Maste     }
3944ac7ddfbfSEd Maste 
3945ac7ddfbfSEd Maste     BroadcastEvent(event_sp);
3946435933ddSDimitry Andric   } else {
3947435933ddSDimitry Andric     if (log) {
3948435933ddSDimitry Andric       log->Printf(
3949435933ddSDimitry Andric           "Process::%s (pid = %" PRIu64
3950435933ddSDimitry Andric           ") suppressing state %s (old state %s): should_broadcast == false",
3951435933ddSDimitry Andric           __FUNCTION__, GetID(), StateAsCString(new_state),
3952ac7ddfbfSEd Maste           StateAsCString(GetState()));
3953ac7ddfbfSEd Maste     }
3954ac7ddfbfSEd Maste   }
39559f2f44ceSEd Maste }
39569f2f44ceSEd Maste 
HaltPrivate()39575517e702SDimitry Andric Status Process::HaltPrivate() {
39589f2f44ceSEd Maste   EventSP event_sp;
39595517e702SDimitry Andric   Status error(WillHalt());
39609f2f44ceSEd Maste   if (error.Fail())
39619f2f44ceSEd Maste     return error;
39629f2f44ceSEd Maste 
39639f2f44ceSEd Maste   // Ask the process subclass to actually halt our process
39649f2f44ceSEd Maste   bool caused_stop;
39659f2f44ceSEd Maste   error = DoHalt(caused_stop);
39669f2f44ceSEd Maste 
39679f2f44ceSEd Maste   DidHalt();
39689f2f44ceSEd Maste   return error;
3969ac7ddfbfSEd Maste }
3970ac7ddfbfSEd Maste 
PrivateStateThread(void * arg)3971435933ddSDimitry Andric thread_result_t Process::PrivateStateThread(void *arg) {
3972435933ddSDimitry Andric   std::unique_ptr<PrivateStateThreadArgs> args_up(
3973435933ddSDimitry Andric       static_cast<PrivateStateThreadArgs *>(arg));
3974435933ddSDimitry Andric   thread_result_t result =
3975435933ddSDimitry Andric       args_up->process->RunPrivateStateThread(args_up->is_secondary_thread);
3976ac7ddfbfSEd Maste   return result;
3977ac7ddfbfSEd Maste }
3978ac7ddfbfSEd Maste 
RunPrivateStateThread(bool is_secondary_thread)3979435933ddSDimitry Andric thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
3980ac7ddfbfSEd Maste   bool control_only = true;
3981ac7ddfbfSEd Maste 
3982ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
3983ac7ddfbfSEd Maste   if (log)
39840127ef0fSEd Maste     log->Printf("Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...",
39850127ef0fSEd Maste                 __FUNCTION__, static_cast<void *>(this), GetID());
3986ac7ddfbfSEd Maste 
3987ac7ddfbfSEd Maste   bool exit_now = false;
39889f2f44ceSEd Maste   bool interrupt_requested = false;
3989435933ddSDimitry Andric   while (!exit_now) {
3990ac7ddfbfSEd Maste     EventSP event_sp;
3991435933ddSDimitry Andric     GetEventsPrivate(event_sp, llvm::None, control_only);
3992435933ddSDimitry Andric     if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster)) {
3993ac7ddfbfSEd Maste       if (log)
3994435933ddSDimitry Andric         log->Printf("Process::%s (arg = %p, pid = %" PRIu64
3995435933ddSDimitry Andric                     ") got a control event: %d",
39960127ef0fSEd Maste                     __FUNCTION__, static_cast<void *>(this), GetID(),
39970127ef0fSEd Maste                     event_sp->GetType());
3998ac7ddfbfSEd Maste 
3999435933ddSDimitry Andric       switch (event_sp->GetType()) {
4000ac7ddfbfSEd Maste       case eBroadcastInternalStateControlStop:
4001ac7ddfbfSEd Maste         exit_now = true;
40020127ef0fSEd Maste         break; // doing any internal state management below
4003ac7ddfbfSEd Maste 
4004ac7ddfbfSEd Maste       case eBroadcastInternalStateControlPause:
4005ac7ddfbfSEd Maste         control_only = true;
4006ac7ddfbfSEd Maste         break;
4007ac7ddfbfSEd Maste 
4008ac7ddfbfSEd Maste       case eBroadcastInternalStateControlResume:
4009ac7ddfbfSEd Maste         control_only = false;
4010ac7ddfbfSEd Maste         break;
4011ac7ddfbfSEd Maste       }
4012ac7ddfbfSEd Maste 
4013ac7ddfbfSEd Maste       continue;
4014435933ddSDimitry Andric     } else if (event_sp->GetType() == eBroadcastBitInterrupt) {
4015435933ddSDimitry Andric       if (m_public_state.GetValue() == eStateAttaching) {
4016ac7ddfbfSEd Maste         if (log)
4017435933ddSDimitry Andric           log->Printf("Process::%s (arg = %p, pid = %" PRIu64
4018435933ddSDimitry Andric                       ") woke up with an interrupt while attaching - "
4019435933ddSDimitry Andric                       "forwarding interrupt.",
4020435933ddSDimitry Andric                       __FUNCTION__, static_cast<void *>(this), GetID());
40214bb0738eSEd Maste         BroadcastEvent(eBroadcastBitInterrupt, nullptr);
4022435933ddSDimitry Andric       } else if (StateIsRunningState(m_last_broadcast_state)) {
4023ac7ddfbfSEd Maste         if (log)
4024435933ddSDimitry Andric           log->Printf("Process::%s (arg = %p, pid = %" PRIu64
4025435933ddSDimitry Andric                       ") woke up with an interrupt - Halting.",
4026435933ddSDimitry Andric                       __FUNCTION__, static_cast<void *>(this), GetID());
40275517e702SDimitry Andric         Status error = HaltPrivate();
40289f2f44ceSEd Maste         if (error.Fail() && log)
4029435933ddSDimitry Andric           log->Printf("Process::%s (arg = %p, pid = %" PRIu64
4030435933ddSDimitry Andric                       ") failed to halt the process: %s",
4031435933ddSDimitry Andric                       __FUNCTION__, static_cast<void *>(this), GetID(),
4032435933ddSDimitry Andric                       error.AsCString());
40334ba319b5SDimitry Andric         // Halt should generate a stopped event. Make a note of the fact that
40344ba319b5SDimitry Andric         // we were doing the interrupt, so we can set the interrupted flag
40354ba319b5SDimitry Andric         // after we receive the event. We deliberately set this to true even if
40364ba319b5SDimitry Andric         // HaltPrivate failed, so that we can interrupt on the next natural
40374ba319b5SDimitry Andric         // stop.
40389f2f44ceSEd Maste         interrupt_requested = true;
4039435933ddSDimitry Andric       } else {
4040435933ddSDimitry Andric         // This can happen when someone (e.g. Process::Halt) sees that we are
40414ba319b5SDimitry Andric         // running and sends an interrupt request, but the process actually
40424ba319b5SDimitry Andric         // stops before we receive it. In that case, we can just ignore the
40434ba319b5SDimitry Andric         // request. We use m_last_broadcast_state, because the Stopped event
40444ba319b5SDimitry Andric         // may not have been popped of the event queue yet, which is when the
40454ba319b5SDimitry Andric         // public state gets updated.
40469f2f44ceSEd Maste         if (log)
4047435933ddSDimitry Andric           log->Printf(
4048435933ddSDimitry Andric               "Process::%s ignoring interrupt as we have already stopped.",
4049435933ddSDimitry Andric               __FUNCTION__);
4050ac7ddfbfSEd Maste       }
4051ac7ddfbfSEd Maste       continue;
4052ac7ddfbfSEd Maste     }
4053ac7ddfbfSEd Maste 
4054435933ddSDimitry Andric     const StateType internal_state =
4055435933ddSDimitry Andric         Process::ProcessEventData::GetStateFromEvent(event_sp.get());
4056ac7ddfbfSEd Maste 
4057435933ddSDimitry Andric     if (internal_state != eStateInvalid) {
4058ac7ddfbfSEd Maste       if (m_clear_thread_plans_on_stop &&
4059435933ddSDimitry Andric           StateIsStoppedState(internal_state, true)) {
4060ac7ddfbfSEd Maste         m_clear_thread_plans_on_stop = false;
4061ac7ddfbfSEd Maste         m_thread_list.DiscardThreadPlans();
4062ac7ddfbfSEd Maste       }
40639f2f44ceSEd Maste 
4064435933ddSDimitry Andric       if (interrupt_requested) {
4065435933ddSDimitry Andric         if (StateIsStoppedState(internal_state, true)) {
4066435933ddSDimitry Andric           // We requested the interrupt, so mark this as such in the stop event
40674ba319b5SDimitry Andric           // so clients can tell an interrupted process from a natural stop
40689f2f44ceSEd Maste           ProcessEventData::SetInterruptedInEvent(event_sp.get(), true);
40699f2f44ceSEd Maste           interrupt_requested = false;
4070435933ddSDimitry Andric         } else if (log) {
4071435933ddSDimitry Andric           log->Printf("Process::%s interrupt_requested, but a non-stopped "
4072435933ddSDimitry Andric                       "state '%s' received.",
40739f2f44ceSEd Maste                       __FUNCTION__, StateAsCString(internal_state));
40749f2f44ceSEd Maste         }
40759f2f44ceSEd Maste       }
40769f2f44ceSEd Maste 
4077ac7ddfbfSEd Maste       HandlePrivateEvent(event_sp);
4078ac7ddfbfSEd Maste     }
4079ac7ddfbfSEd Maste 
4080435933ddSDimitry Andric     if (internal_state == eStateInvalid || internal_state == eStateExited ||
4081435933ddSDimitry Andric         internal_state == eStateDetached) {
4082ac7ddfbfSEd Maste       if (log)
4083435933ddSDimitry Andric         log->Printf("Process::%s (arg = %p, pid = %" PRIu64
4084435933ddSDimitry Andric                     ") about to exit with internal state %s...",
40850127ef0fSEd Maste                     __FUNCTION__, static_cast<void *>(this), GetID(),
40860127ef0fSEd Maste                     StateAsCString(internal_state));
4087ac7ddfbfSEd Maste 
4088ac7ddfbfSEd Maste       break;
4089ac7ddfbfSEd Maste     }
4090ac7ddfbfSEd Maste   }
4091ac7ddfbfSEd Maste 
4092ac7ddfbfSEd Maste   // Verify log is still enabled before attempting to write to it...
4093ac7ddfbfSEd Maste   if (log)
40940127ef0fSEd Maste     log->Printf("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...",
40950127ef0fSEd Maste                 __FUNCTION__, static_cast<void *>(this), GetID());
4096ac7ddfbfSEd Maste 
4097435933ddSDimitry Andric   // If we are a secondary thread, then the primary thread we are working for
40984ba319b5SDimitry Andric   // will have already acquired the public_run_lock, and isn't done with what
40994ba319b5SDimitry Andric   // it was doing yet, so don't try to change it on the way out.
41001c3bbb01SEd Maste   if (!is_secondary_thread)
4101ac7ddfbfSEd Maste     m_public_run_lock.SetStopped();
4102ac7ddfbfSEd Maste   return NULL;
4103ac7ddfbfSEd Maste }
4104ac7ddfbfSEd Maste 
4105ac7ddfbfSEd Maste //------------------------------------------------------------------
4106ac7ddfbfSEd Maste // Process Event Data
4107ac7ddfbfSEd Maste //------------------------------------------------------------------
4108ac7ddfbfSEd Maste 
ProcessEventData()4109435933ddSDimitry Andric Process::ProcessEventData::ProcessEventData()
4110435933ddSDimitry Andric     : EventData(), m_process_wp(), m_state(eStateInvalid), m_restarted(false),
4111435933ddSDimitry Andric       m_update_state(0), m_interrupted(false) {}
4112ac7ddfbfSEd Maste 
ProcessEventData(const ProcessSP & process_sp,StateType state)4113435933ddSDimitry Andric Process::ProcessEventData::ProcessEventData(const ProcessSP &process_sp,
4114435933ddSDimitry Andric                                             StateType state)
4115435933ddSDimitry Andric     : EventData(), m_process_wp(), m_state(state), m_restarted(false),
4116435933ddSDimitry Andric       m_update_state(0), m_interrupted(false) {
41171c3bbb01SEd Maste   if (process_sp)
41181c3bbb01SEd Maste     m_process_wp = process_sp;
4119ac7ddfbfSEd Maste }
4120ac7ddfbfSEd Maste 
41219f2f44ceSEd Maste Process::ProcessEventData::~ProcessEventData() = default;
4122ac7ddfbfSEd Maste 
GetFlavorString()4123435933ddSDimitry Andric const ConstString &Process::ProcessEventData::GetFlavorString() {
4124ac7ddfbfSEd Maste   static ConstString g_flavor("Process::ProcessEventData");
4125ac7ddfbfSEd Maste   return g_flavor;
4126ac7ddfbfSEd Maste }
4127ac7ddfbfSEd Maste 
GetFlavor() const4128435933ddSDimitry Andric const ConstString &Process::ProcessEventData::GetFlavor() const {
4129ac7ddfbfSEd Maste   return ProcessEventData::GetFlavorString();
4130ac7ddfbfSEd Maste }
4131ac7ddfbfSEd Maste 
DoOnRemoval(Event * event_ptr)4132435933ddSDimitry Andric void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
41331c3bbb01SEd Maste   ProcessSP process_sp(m_process_wp.lock());
41341c3bbb01SEd Maste 
41351c3bbb01SEd Maste   if (!process_sp)
41361c3bbb01SEd Maste     return;
41371c3bbb01SEd Maste 
4138435933ddSDimitry Andric   // This function gets called twice for each event, once when the event gets
41394ba319b5SDimitry Andric   // pulled off of the private process event queue, and then any number of
41404ba319b5SDimitry Andric   // times, first when it gets pulled off of the public event queue, then other
41414ba319b5SDimitry Andric   // times when we're pretending that this is where we stopped at the end of
41424ba319b5SDimitry Andric   // expression evaluation.  m_update_state is used to distinguish these three
41434ba319b5SDimitry Andric   // cases; it is 0 when we're just pulling it off for private handling, and >
41444ba319b5SDimitry Andric   // 1 for expression evaluation, and we don't want to do the breakpoint
4145435933ddSDimitry Andric   // command handling then.
4146ac7ddfbfSEd Maste   if (m_update_state != 1)
4147ac7ddfbfSEd Maste     return;
4148ac7ddfbfSEd Maste 
4149435933ddSDimitry Andric   process_sp->SetPublicState(
4150435933ddSDimitry Andric       m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
4151ac7ddfbfSEd Maste 
4152435933ddSDimitry Andric   if (m_state == eStateStopped && !m_restarted) {
41534ba319b5SDimitry Andric     // Let process subclasses know we are about to do a public stop and do
41544ba319b5SDimitry Andric     // anything they might need to in order to speed up register and memory
41554ba319b5SDimitry Andric     // accesses.
4156435933ddSDimitry Andric     process_sp->WillPublicStop();
4157435933ddSDimitry Andric   }
4158435933ddSDimitry Andric 
4159435933ddSDimitry Andric   // If this is a halt event, even if the halt stopped with some reason other
41604ba319b5SDimitry Andric   // than a plain interrupt (e.g. we had already stopped for a breakpoint when
41614ba319b5SDimitry Andric   // the halt request came through) don't do the StopInfo actions, as they may
41620127ef0fSEd Maste   // end up restarting the process.
41630127ef0fSEd Maste   if (m_interrupted)
41640127ef0fSEd Maste     return;
41650127ef0fSEd Maste 
41660127ef0fSEd Maste   // If we're stopped and haven't restarted, then do the StopInfo actions here:
4167435933ddSDimitry Andric   if (m_state == eStateStopped && !m_restarted) {
41681c3bbb01SEd Maste     ThreadList &curr_thread_list = process_sp->GetThreadList();
4169ac7ddfbfSEd Maste     uint32_t num_threads = curr_thread_list.GetSize();
4170ac7ddfbfSEd Maste     uint32_t idx;
4171ac7ddfbfSEd Maste 
4172435933ddSDimitry Andric     // The actions might change one of the thread's stop_info's opinions about
41734ba319b5SDimitry Andric     // whether we should stop the process, so we need to query that as we go.
4174ac7ddfbfSEd Maste 
4175435933ddSDimitry Andric     // One other complication here, is that we try to catch any case where the
41764ba319b5SDimitry Andric     // target has run (except for expressions) and immediately exit, but if we
41774ba319b5SDimitry Andric     // get that wrong (which is possible) then the thread list might have
41784ba319b5SDimitry Andric     // changed, and that would cause our iteration here to crash.  We could
41794ba319b5SDimitry Andric     // make a copy of the thread list, but we'd really like to also know if it
41804ba319b5SDimitry Andric     // has changed at all, so we make up a vector of the thread ID's and check
41814ba319b5SDimitry Andric     // what we get back against this list & bag out if anything differs.
4182ac7ddfbfSEd Maste     std::vector<uint32_t> thread_index_array(num_threads);
4183ac7ddfbfSEd Maste     for (idx = 0; idx < num_threads; ++idx)
4184435933ddSDimitry Andric       thread_index_array[idx] =
4185435933ddSDimitry Andric           curr_thread_list.GetThreadAtIndex(idx)->GetIndexID();
4186ac7ddfbfSEd Maste 
4187435933ddSDimitry Andric     // Use this to track whether we should continue from here.  We will only
41884ba319b5SDimitry Andric     // continue the target running if no thread says we should stop.  Of course
41894ba319b5SDimitry Andric     // if some thread's PerformAction actually sets the target running, then it
41904ba319b5SDimitry Andric     // doesn't matter what the other threads say...
4191ac7ddfbfSEd Maste 
4192ac7ddfbfSEd Maste     bool still_should_stop = false;
4193ac7ddfbfSEd Maste 
4194435933ddSDimitry Andric     // Sometimes - for instance if we have a bug in the stub we are talking to,
41954ba319b5SDimitry Andric     // we stop but no thread has a valid stop reason.  In that case we should
41964ba319b5SDimitry Andric     // just stop, because we have no way of telling what the right thing to do
41974ba319b5SDimitry Andric     // is, and it's better to let the user decide than continue behind their
41984ba319b5SDimitry Andric     // backs.
4199ac7ddfbfSEd Maste 
4200ac7ddfbfSEd Maste     bool does_anybody_have_an_opinion = false;
4201ac7ddfbfSEd Maste 
4202435933ddSDimitry Andric     for (idx = 0; idx < num_threads; ++idx) {
42031c3bbb01SEd Maste       curr_thread_list = process_sp->GetThreadList();
4204435933ddSDimitry Andric       if (curr_thread_list.GetSize() != num_threads) {
4205435933ddSDimitry Andric         Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
4206435933ddSDimitry Andric                                                         LIBLLDB_LOG_PROCESS));
4207ac7ddfbfSEd Maste         if (log)
4208435933ddSDimitry Andric           log->Printf(
4209435933ddSDimitry Andric               "Number of threads changed from %u to %u while processing event.",
4210435933ddSDimitry Andric               num_threads, curr_thread_list.GetSize());
4211ac7ddfbfSEd Maste         break;
4212ac7ddfbfSEd Maste       }
4213ac7ddfbfSEd Maste 
4214ac7ddfbfSEd Maste       lldb::ThreadSP thread_sp = curr_thread_list.GetThreadAtIndex(idx);
4215ac7ddfbfSEd Maste 
4216435933ddSDimitry Andric       if (thread_sp->GetIndexID() != thread_index_array[idx]) {
4217435933ddSDimitry Andric         Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
4218435933ddSDimitry Andric                                                         LIBLLDB_LOG_PROCESS));
4219ac7ddfbfSEd Maste         if (log)
4220435933ddSDimitry Andric           log->Printf("The thread at position %u changed from %u to %u while "
4221435933ddSDimitry Andric                       "processing event.",
4222435933ddSDimitry Andric                       idx, thread_index_array[idx], thread_sp->GetIndexID());
4223ac7ddfbfSEd Maste         break;
4224ac7ddfbfSEd Maste       }
4225ac7ddfbfSEd Maste 
4226ac7ddfbfSEd Maste       StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
4227435933ddSDimitry Andric       if (stop_info_sp && stop_info_sp->IsValid()) {
4228ac7ddfbfSEd Maste         does_anybody_have_an_opinion = true;
4229ac7ddfbfSEd Maste         bool this_thread_wants_to_stop;
4230435933ddSDimitry Andric         if (stop_info_sp->GetOverrideShouldStop()) {
4231435933ddSDimitry Andric           this_thread_wants_to_stop =
4232435933ddSDimitry Andric               stop_info_sp->GetOverriddenShouldStopValue();
4233435933ddSDimitry Andric         } else {
4234ac7ddfbfSEd Maste           stop_info_sp->PerformAction(event_ptr);
42354ba319b5SDimitry Andric           // The stop action might restart the target.  If it does, then we
42364ba319b5SDimitry Andric           // want to mark that in the event so that whoever is receiving it
42374ba319b5SDimitry Andric           // will know to wait for the running event and reflect that state
42384ba319b5SDimitry Andric           // appropriately. We also need to stop processing actions, since they
42394ba319b5SDimitry Andric           // aren't expecting the target to be running.
4240ac7ddfbfSEd Maste 
4241ac7ddfbfSEd Maste           // FIXME: we might have run.
4242435933ddSDimitry Andric           if (stop_info_sp->HasTargetRunSinceMe()) {
4243ac7ddfbfSEd Maste             SetRestarted(true);
4244ac7ddfbfSEd Maste             break;
4245ac7ddfbfSEd Maste           }
4246ac7ddfbfSEd Maste 
4247ac7ddfbfSEd Maste           this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
4248ac7ddfbfSEd Maste         }
4249ac7ddfbfSEd Maste 
42504bb0738eSEd Maste         if (!still_should_stop)
4251ac7ddfbfSEd Maste           still_should_stop = this_thread_wants_to_stop;
4252ac7ddfbfSEd Maste       }
4253ac7ddfbfSEd Maste     }
4254ac7ddfbfSEd Maste 
4255435933ddSDimitry Andric     if (!GetRestarted()) {
4256435933ddSDimitry Andric       if (!still_should_stop && does_anybody_have_an_opinion) {
4257ac7ddfbfSEd Maste         // We've been asked to continue, so do that here.
4258ac7ddfbfSEd Maste         SetRestarted(true);
42594ba319b5SDimitry Andric         // Use the public resume method here, since this is just extending a
42604ba319b5SDimitry Andric         // public resume.
42611c3bbb01SEd Maste         process_sp->PrivateResume();
4262435933ddSDimitry Andric       } else {
42634ba319b5SDimitry Andric         // If we didn't restart, run the Stop Hooks here: They might also
42644ba319b5SDimitry Andric         // restart the target, so watch for that.
42651c3bbb01SEd Maste         process_sp->GetTarget().RunStopHooks();
42661c3bbb01SEd Maste         if (process_sp->GetPrivateState() == eStateRunning)
4267ac7ddfbfSEd Maste           SetRestarted(true);
4268ac7ddfbfSEd Maste       }
4269ac7ddfbfSEd Maste     }
4270ac7ddfbfSEd Maste   }
4271ac7ddfbfSEd Maste }
4272ac7ddfbfSEd Maste 
Dump(Stream * s) const4273435933ddSDimitry Andric void Process::ProcessEventData::Dump(Stream *s) const {
42741c3bbb01SEd Maste   ProcessSP process_sp(m_process_wp.lock());
42751c3bbb01SEd Maste 
42761c3bbb01SEd Maste   if (process_sp)
42770127ef0fSEd Maste     s->Printf(" process = %p (pid = %" PRIu64 "), ",
42781c3bbb01SEd Maste               static_cast<void *>(process_sp.get()), process_sp->GetID());
42791c3bbb01SEd Maste   else
42801c3bbb01SEd Maste     s->PutCString(" process = NULL, ");
4281ac7ddfbfSEd Maste 
4282ac7ddfbfSEd Maste   s->Printf("state = %s", StateAsCString(GetState()));
4283ac7ddfbfSEd Maste }
4284ac7ddfbfSEd Maste 
4285ac7ddfbfSEd Maste const Process::ProcessEventData *
GetEventDataFromEvent(const Event * event_ptr)4286435933ddSDimitry Andric Process::ProcessEventData::GetEventDataFromEvent(const Event *event_ptr) {
4287435933ddSDimitry Andric   if (event_ptr) {
4288ac7ddfbfSEd Maste     const EventData *event_data = event_ptr->GetData();
4289435933ddSDimitry Andric     if (event_data &&
4290435933ddSDimitry Andric         event_data->GetFlavor() == ProcessEventData::GetFlavorString())
4291ac7ddfbfSEd Maste       return static_cast<const ProcessEventData *>(event_ptr->GetData());
4292ac7ddfbfSEd Maste   }
42934bb0738eSEd Maste   return nullptr;
4294ac7ddfbfSEd Maste }
4295ac7ddfbfSEd Maste 
4296ac7ddfbfSEd Maste ProcessSP
GetProcessFromEvent(const Event * event_ptr)4297435933ddSDimitry Andric Process::ProcessEventData::GetProcessFromEvent(const Event *event_ptr) {
4298ac7ddfbfSEd Maste   ProcessSP process_sp;
4299ac7ddfbfSEd Maste   const ProcessEventData *data = GetEventDataFromEvent(event_ptr);
4300ac7ddfbfSEd Maste   if (data)
4301ac7ddfbfSEd Maste     process_sp = data->GetProcessSP();
4302ac7ddfbfSEd Maste   return process_sp;
4303ac7ddfbfSEd Maste }
4304ac7ddfbfSEd Maste 
GetStateFromEvent(const Event * event_ptr)4305435933ddSDimitry Andric StateType Process::ProcessEventData::GetStateFromEvent(const Event *event_ptr) {
4306ac7ddfbfSEd Maste   const ProcessEventData *data = GetEventDataFromEvent(event_ptr);
43074bb0738eSEd Maste   if (data == nullptr)
4308ac7ddfbfSEd Maste     return eStateInvalid;
4309ac7ddfbfSEd Maste   else
4310ac7ddfbfSEd Maste     return data->GetState();
4311ac7ddfbfSEd Maste }
4312ac7ddfbfSEd Maste 
GetRestartedFromEvent(const Event * event_ptr)4313435933ddSDimitry Andric bool Process::ProcessEventData::GetRestartedFromEvent(const Event *event_ptr) {
4314ac7ddfbfSEd Maste   const ProcessEventData *data = GetEventDataFromEvent(event_ptr);
43154bb0738eSEd Maste   if (data == nullptr)
4316ac7ddfbfSEd Maste     return false;
4317ac7ddfbfSEd Maste   else
4318ac7ddfbfSEd Maste     return data->GetRestarted();
4319ac7ddfbfSEd Maste }
4320ac7ddfbfSEd Maste 
SetRestartedInEvent(Event * event_ptr,bool new_value)4321435933ddSDimitry Andric void Process::ProcessEventData::SetRestartedInEvent(Event *event_ptr,
4322435933ddSDimitry Andric                                                     bool new_value) {
4323435933ddSDimitry Andric   ProcessEventData *data =
4324435933ddSDimitry Andric       const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr));
43254bb0738eSEd Maste   if (data != nullptr)
4326ac7ddfbfSEd Maste     data->SetRestarted(new_value);
4327ac7ddfbfSEd Maste }
4328ac7ddfbfSEd Maste 
4329ac7ddfbfSEd Maste size_t
GetNumRestartedReasons(const Event * event_ptr)4330435933ddSDimitry Andric Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr) {
4331435933ddSDimitry Andric   ProcessEventData *data =
4332435933ddSDimitry Andric       const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr));
43334bb0738eSEd Maste   if (data != nullptr)
4334ac7ddfbfSEd Maste     return data->GetNumRestartedReasons();
4335ac7ddfbfSEd Maste   else
4336ac7ddfbfSEd Maste     return 0;
4337ac7ddfbfSEd Maste }
4338ac7ddfbfSEd Maste 
4339ac7ddfbfSEd Maste const char *
GetRestartedReasonAtIndex(const Event * event_ptr,size_t idx)4340435933ddSDimitry Andric Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr,
4341435933ddSDimitry Andric                                                      size_t idx) {
4342435933ddSDimitry Andric   ProcessEventData *data =
4343435933ddSDimitry Andric       const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr));
43444bb0738eSEd Maste   if (data != nullptr)
4345ac7ddfbfSEd Maste     return data->GetRestartedReasonAtIndex(idx);
4346ac7ddfbfSEd Maste   else
43474bb0738eSEd Maste     return nullptr;
4348ac7ddfbfSEd Maste }
4349ac7ddfbfSEd Maste 
AddRestartedReason(Event * event_ptr,const char * reason)4350435933ddSDimitry Andric void Process::ProcessEventData::AddRestartedReason(Event *event_ptr,
4351435933ddSDimitry Andric                                                    const char *reason) {
4352435933ddSDimitry Andric   ProcessEventData *data =
4353435933ddSDimitry Andric       const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr));
43544bb0738eSEd Maste   if (data != nullptr)
4355ac7ddfbfSEd Maste     data->AddRestartedReason(reason);
4356ac7ddfbfSEd Maste }
4357ac7ddfbfSEd Maste 
GetInterruptedFromEvent(const Event * event_ptr)4358435933ddSDimitry Andric bool Process::ProcessEventData::GetInterruptedFromEvent(
4359435933ddSDimitry Andric     const Event *event_ptr) {
4360ac7ddfbfSEd Maste   const ProcessEventData *data = GetEventDataFromEvent(event_ptr);
43614bb0738eSEd Maste   if (data == nullptr)
4362ac7ddfbfSEd Maste     return false;
4363ac7ddfbfSEd Maste   else
4364ac7ddfbfSEd Maste     return data->GetInterrupted();
4365ac7ddfbfSEd Maste }
4366ac7ddfbfSEd Maste 
SetInterruptedInEvent(Event * event_ptr,bool new_value)4367435933ddSDimitry Andric void Process::ProcessEventData::SetInterruptedInEvent(Event *event_ptr,
4368435933ddSDimitry Andric                                                       bool new_value) {
4369435933ddSDimitry Andric   ProcessEventData *data =
4370435933ddSDimitry Andric       const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr));
43714bb0738eSEd Maste   if (data != nullptr)
4372ac7ddfbfSEd Maste     data->SetInterrupted(new_value);
4373ac7ddfbfSEd Maste }
4374ac7ddfbfSEd Maste 
SetUpdateStateOnRemoval(Event * event_ptr)4375435933ddSDimitry Andric bool Process::ProcessEventData::SetUpdateStateOnRemoval(Event *event_ptr) {
4376435933ddSDimitry Andric   ProcessEventData *data =
4377435933ddSDimitry Andric       const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr));
4378435933ddSDimitry Andric   if (data) {
4379ac7ddfbfSEd Maste     data->SetUpdateStateOnRemoval();
4380ac7ddfbfSEd Maste     return true;
4381ac7ddfbfSEd Maste   }
4382ac7ddfbfSEd Maste   return false;
4383ac7ddfbfSEd Maste }
4384ac7ddfbfSEd Maste 
CalculateTarget()43854ba319b5SDimitry Andric lldb::TargetSP Process::CalculateTarget() { return m_target_wp.lock(); }
4386ac7ddfbfSEd Maste 
CalculateExecutionContext(ExecutionContext & exe_ctx)4387435933ddSDimitry Andric void Process::CalculateExecutionContext(ExecutionContext &exe_ctx) {
43889f2f44ceSEd Maste   exe_ctx.SetTargetPtr(&GetTarget());
4389ac7ddfbfSEd Maste   exe_ctx.SetProcessPtr(this);
43904bb0738eSEd Maste   exe_ctx.SetThreadPtr(nullptr);
43914bb0738eSEd Maste   exe_ctx.SetFramePtr(nullptr);
4392ac7ddfbfSEd Maste }
4393ac7ddfbfSEd Maste 
4394ac7ddfbfSEd Maste // uint32_t
4395435933ddSDimitry Andric // Process::ListProcessesMatchingName (const char *name, StringList &matches,
4396435933ddSDimitry Andric // std::vector<lldb::pid_t> &pids)
4397ac7ddfbfSEd Maste //{
4398ac7ddfbfSEd Maste //    return 0;
4399ac7ddfbfSEd Maste //}
4400ac7ddfbfSEd Maste //
4401ac7ddfbfSEd Maste // ArchSpec
4402ac7ddfbfSEd Maste // Process::GetArchSpecForExistingProcess (lldb::pid_t pid)
4403ac7ddfbfSEd Maste //{
4404ac7ddfbfSEd Maste //    return Host::GetArchSpecForExistingProcess (pid);
4405ac7ddfbfSEd Maste //}
4406ac7ddfbfSEd Maste //
4407ac7ddfbfSEd Maste // ArchSpec
4408ac7ddfbfSEd Maste // Process::GetArchSpecForExistingProcess (const char *process_name)
4409ac7ddfbfSEd Maste //{
4410ac7ddfbfSEd Maste //    return Host::GetArchSpecForExistingProcess (process_name);
4411ac7ddfbfSEd Maste //}
44124bb0738eSEd Maste 
AppendSTDOUT(const char * s,size_t len)4413435933ddSDimitry Andric void Process::AppendSTDOUT(const char *s, size_t len) {
44144bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
4415ac7ddfbfSEd Maste   m_stdout_data.append(s, len);
4416435933ddSDimitry Andric   BroadcastEventIfUnique(eBroadcastBitSTDOUT,
4417435933ddSDimitry Andric                          new ProcessEventData(shared_from_this(), GetState()));
4418ac7ddfbfSEd Maste }
4419ac7ddfbfSEd Maste 
AppendSTDERR(const char * s,size_t len)4420435933ddSDimitry Andric void Process::AppendSTDERR(const char *s, size_t len) {
44214bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
4422ac7ddfbfSEd Maste   m_stderr_data.append(s, len);
4423435933ddSDimitry Andric   BroadcastEventIfUnique(eBroadcastBitSTDERR,
4424435933ddSDimitry Andric                          new ProcessEventData(shared_from_this(), GetState()));
4425ac7ddfbfSEd Maste }
4426ac7ddfbfSEd Maste 
BroadcastAsyncProfileData(const std::string & one_profile_data)4427435933ddSDimitry Andric void Process::BroadcastAsyncProfileData(const std::string &one_profile_data) {
44284bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex);
4429ac7ddfbfSEd Maste   m_profile_data.push_back(one_profile_data);
4430435933ddSDimitry Andric   BroadcastEventIfUnique(eBroadcastBitProfileData,
4431435933ddSDimitry Andric                          new ProcessEventData(shared_from_this(), GetState()));
4432ac7ddfbfSEd Maste }
4433ac7ddfbfSEd Maste 
BroadcastStructuredData(const StructuredData::ObjectSP & object_sp,const StructuredDataPluginSP & plugin_sp)4434435933ddSDimitry Andric void Process::BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
4435435933ddSDimitry Andric                                       const StructuredDataPluginSP &plugin_sp) {
4436435933ddSDimitry Andric   BroadcastEvent(
4437435933ddSDimitry Andric       eBroadcastBitStructuredData,
4438435933ddSDimitry Andric       new EventDataStructuredData(shared_from_this(), object_sp, plugin_sp));
4439435933ddSDimitry Andric }
4440435933ddSDimitry Andric 
4441435933ddSDimitry Andric StructuredDataPluginSP
GetStructuredDataPlugin(const ConstString & type_name) const4442435933ddSDimitry Andric Process::GetStructuredDataPlugin(const ConstString &type_name) const {
4443435933ddSDimitry Andric   auto find_it = m_structured_data_plugin_map.find(type_name);
4444435933ddSDimitry Andric   if (find_it != m_structured_data_plugin_map.end())
4445435933ddSDimitry Andric     return find_it->second;
4446435933ddSDimitry Andric   else
4447435933ddSDimitry Andric     return StructuredDataPluginSP();
4448435933ddSDimitry Andric }
4449435933ddSDimitry Andric 
GetAsyncProfileData(char * buf,size_t buf_size,Status & error)44505517e702SDimitry Andric size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Status &error) {
44514bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex);
4452ac7ddfbfSEd Maste   if (m_profile_data.empty())
4453ac7ddfbfSEd Maste     return 0;
4454ac7ddfbfSEd Maste 
4455ac7ddfbfSEd Maste   std::string &one_profile_data = m_profile_data.front();
4456ac7ddfbfSEd Maste   size_t bytes_available = one_profile_data.size();
4457435933ddSDimitry Andric   if (bytes_available > 0) {
4458ac7ddfbfSEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
4459ac7ddfbfSEd Maste     if (log)
44600127ef0fSEd Maste       log->Printf("Process::GetProfileData (buf = %p, size = %" PRIu64 ")",
4461435933ddSDimitry Andric                   static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
4462435933ddSDimitry Andric     if (bytes_available > buf_size) {
4463ac7ddfbfSEd Maste       memcpy(buf, one_profile_data.c_str(), buf_size);
4464ac7ddfbfSEd Maste       one_profile_data.erase(0, buf_size);
4465ac7ddfbfSEd Maste       bytes_available = buf_size;
4466435933ddSDimitry Andric     } else {
4467ac7ddfbfSEd Maste       memcpy(buf, one_profile_data.c_str(), bytes_available);
4468ac7ddfbfSEd Maste       m_profile_data.erase(m_profile_data.begin());
4469ac7ddfbfSEd Maste     }
4470ac7ddfbfSEd Maste   }
4471ac7ddfbfSEd Maste   return bytes_available;
4472ac7ddfbfSEd Maste }
4473ac7ddfbfSEd Maste 
4474ac7ddfbfSEd Maste //------------------------------------------------------------------
4475ac7ddfbfSEd Maste // Process STDIO
4476ac7ddfbfSEd Maste //------------------------------------------------------------------
4477ac7ddfbfSEd Maste 
GetSTDOUT(char * buf,size_t buf_size,Status & error)44785517e702SDimitry Andric size_t Process::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
44794bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
4480ac7ddfbfSEd Maste   size_t bytes_available = m_stdout_data.size();
4481435933ddSDimitry Andric   if (bytes_available > 0) {
4482ac7ddfbfSEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
4483ac7ddfbfSEd Maste     if (log)
44840127ef0fSEd Maste       log->Printf("Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")",
4485435933ddSDimitry Andric                   static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
4486435933ddSDimitry Andric     if (bytes_available > buf_size) {
4487ac7ddfbfSEd Maste       memcpy(buf, m_stdout_data.c_str(), buf_size);
4488ac7ddfbfSEd Maste       m_stdout_data.erase(0, buf_size);
4489ac7ddfbfSEd Maste       bytes_available = buf_size;
4490435933ddSDimitry Andric     } else {
4491ac7ddfbfSEd Maste       memcpy(buf, m_stdout_data.c_str(), bytes_available);
4492ac7ddfbfSEd Maste       m_stdout_data.clear();
4493ac7ddfbfSEd Maste     }
4494ac7ddfbfSEd Maste   }
4495ac7ddfbfSEd Maste   return bytes_available;
4496ac7ddfbfSEd Maste }
4497ac7ddfbfSEd Maste 
GetSTDERR(char * buf,size_t buf_size,Status & error)44985517e702SDimitry Andric size_t Process::GetSTDERR(char *buf, size_t buf_size, Status &error) {
44994bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex);
4500ac7ddfbfSEd Maste   size_t bytes_available = m_stderr_data.size();
4501435933ddSDimitry Andric   if (bytes_available > 0) {
4502ac7ddfbfSEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
4503ac7ddfbfSEd Maste     if (log)
45040127ef0fSEd Maste       log->Printf("Process::GetSTDERR (buf = %p, size = %" PRIu64 ")",
4505435933ddSDimitry Andric                   static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
4506435933ddSDimitry Andric     if (bytes_available > buf_size) {
4507ac7ddfbfSEd Maste       memcpy(buf, m_stderr_data.c_str(), buf_size);
4508ac7ddfbfSEd Maste       m_stderr_data.erase(0, buf_size);
4509ac7ddfbfSEd Maste       bytes_available = buf_size;
4510435933ddSDimitry Andric     } else {
4511ac7ddfbfSEd Maste       memcpy(buf, m_stderr_data.c_str(), bytes_available);
4512ac7ddfbfSEd Maste       m_stderr_data.clear();
4513ac7ddfbfSEd Maste     }
4514ac7ddfbfSEd Maste   }
4515ac7ddfbfSEd Maste   return bytes_available;
4516ac7ddfbfSEd Maste }
4517ac7ddfbfSEd Maste 
STDIOReadThreadBytesReceived(void * baton,const void * src,size_t src_len)4518435933ddSDimitry Andric void Process::STDIOReadThreadBytesReceived(void *baton, const void *src,
4519435933ddSDimitry Andric                                            size_t src_len) {
4520ac7ddfbfSEd Maste   Process *process = (Process *)baton;
4521ac7ddfbfSEd Maste   process->AppendSTDOUT(static_cast<const char *>(src), src_len);
4522ac7ddfbfSEd Maste }
4523ac7ddfbfSEd Maste 
4524435933ddSDimitry Andric class IOHandlerProcessSTDIO : public IOHandler {
452512b93ac6SEd Maste public:
IOHandlerProcessSTDIO(Process * process,int write_fd)4526435933ddSDimitry Andric   IOHandlerProcessSTDIO(Process *process, int write_fd)
4527435933ddSDimitry Andric       : IOHandler(process->GetTarget().GetDebugger(),
4528435933ddSDimitry Andric                   IOHandler::Type::ProcessIO),
4529435933ddSDimitry Andric         m_process(process), m_write_file(write_fd, false) {
45301c3bbb01SEd Maste     m_pipe.CreateNew(false);
453112b93ac6SEd Maste     m_read_file.SetDescriptor(GetInputFD(), false);
453212b93ac6SEd Maste   }
453312b93ac6SEd Maste 
45349f2f44ceSEd Maste   ~IOHandlerProcessSTDIO() override = default;
453512b93ac6SEd Maste 
45364ba319b5SDimitry Andric   // Each IOHandler gets to run until it is done. It should read data from the
45374ba319b5SDimitry Andric   // "in" and place output into "out" and "err and return when done.
Run()4538435933ddSDimitry Andric   void Run() override {
4539435933ddSDimitry Andric     if (!m_read_file.IsValid() || !m_write_file.IsValid() ||
4540435933ddSDimitry Andric         !m_pipe.CanRead() || !m_pipe.CanWrite()) {
45411c3bbb01SEd Maste       SetIsDone(true);
45421c3bbb01SEd Maste       return;
45431c3bbb01SEd Maste     }
45441c3bbb01SEd Maste 
454512b93ac6SEd Maste     SetIsDone(false);
454612b93ac6SEd Maste     const int read_fd = m_read_file.GetDescriptor();
454712b93ac6SEd Maste     TerminalState terminal_state;
454812b93ac6SEd Maste     terminal_state.Save(read_fd, false);
454912b93ac6SEd Maste     Terminal terminal(read_fd);
455012b93ac6SEd Maste     terminal.SetCanonical(false);
455112b93ac6SEd Maste     terminal.SetEcho(false);
455212b93ac6SEd Maste // FD_ZERO, FD_SET are not supported on windows
45530127ef0fSEd Maste #ifndef _WIN32
45541c3bbb01SEd Maste     const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
45554bb0738eSEd Maste     m_is_running = true;
4556435933ddSDimitry Andric     while (!GetIsDone()) {
4557435933ddSDimitry Andric       SelectHelper select_helper;
4558435933ddSDimitry Andric       select_helper.FDSetRead(read_fd);
4559435933ddSDimitry Andric       select_helper.FDSetRead(pipe_read_fd);
45605517e702SDimitry Andric       Status error = select_helper.Select();
45614bb0738eSEd Maste 
4562435933ddSDimitry Andric       if (error.Fail()) {
456312b93ac6SEd Maste         SetIsDone(true);
4564435933ddSDimitry Andric       } else {
456512b93ac6SEd Maste         char ch = 0;
456612b93ac6SEd Maste         size_t n;
4567435933ddSDimitry Andric         if (select_helper.FDIsSetRead(read_fd)) {
456812b93ac6SEd Maste           n = 1;
4569435933ddSDimitry Andric           if (m_read_file.Read(&ch, n).Success() && n == 1) {
457012b93ac6SEd Maste             if (m_write_file.Write(&ch, n).Fail() || n != 1)
457112b93ac6SEd Maste               SetIsDone(true);
4572435933ddSDimitry Andric           } else
457312b93ac6SEd Maste             SetIsDone(true);
457412b93ac6SEd Maste         }
4575435933ddSDimitry Andric         if (select_helper.FDIsSetRead(pipe_read_fd)) {
45767aa51b79SEd Maste           size_t bytes_read;
457712b93ac6SEd Maste           // Consume the interrupt byte
45785517e702SDimitry Andric           Status error = m_pipe.Read(&ch, 1, bytes_read);
4579435933ddSDimitry Andric           if (error.Success()) {
4580435933ddSDimitry Andric             switch (ch) {
45810127ef0fSEd Maste             case 'q':
458212b93ac6SEd Maste               SetIsDone(true);
45830127ef0fSEd Maste               break;
45840127ef0fSEd Maste             case 'i':
45850127ef0fSEd Maste               if (StateIsRunningState(m_process->GetState()))
45869f2f44ceSEd Maste                 m_process->SendAsyncInterrupt();
45870127ef0fSEd Maste               break;
45880127ef0fSEd Maste             }
45890127ef0fSEd Maste           }
459012b93ac6SEd Maste         }
459112b93ac6SEd Maste       }
459212b93ac6SEd Maste     }
45934bb0738eSEd Maste     m_is_running = false;
459412b93ac6SEd Maste #endif
459512b93ac6SEd Maste     terminal_state.Restore();
459612b93ac6SEd Maste   }
459712b93ac6SEd Maste 
Cancel()4598435933ddSDimitry Andric   void Cancel() override {
45994bb0738eSEd Maste     SetIsDone(true);
4600435933ddSDimitry Andric     // Only write to our pipe to cancel if we are in
46014ba319b5SDimitry Andric     // IOHandlerProcessSTDIO::Run(). We can end up with a python command that
46024ba319b5SDimitry Andric     // is being run from the command interpreter:
46034bb0738eSEd Maste     //
46044bb0738eSEd Maste     // (lldb) step_process_thousands_of_times
46054bb0738eSEd Maste     //
46064bb0738eSEd Maste     // In this case the command interpreter will be in the middle of handling
46074bb0738eSEd Maste     // the command and if the process pushes and pops the IOHandler thousands
46084bb0738eSEd Maste     // of times, we can end up writing to m_pipe without ever consuming the
46094bb0738eSEd Maste     // bytes from the pipe in IOHandlerProcessSTDIO::Run() and end up
46104bb0738eSEd Maste     // deadlocking when the pipe gets fed up and blocks until data is consumed.
4611435933ddSDimitry Andric     if (m_is_running) {
46120127ef0fSEd Maste       char ch = 'q'; // Send 'q' for quit
46137aa51b79SEd Maste       size_t bytes_written = 0;
46147aa51b79SEd Maste       m_pipe.Write(&ch, 1, bytes_written);
461512b93ac6SEd Maste     }
46164bb0738eSEd Maste   }
461712b93ac6SEd Maste 
Interrupt()4618435933ddSDimitry Andric   bool Interrupt() override {
46194ba319b5SDimitry Andric     // Do only things that are safe to do in an interrupt context (like in a
46204ba319b5SDimitry Andric     // SIGINT handler), like write 1 byte to a file descriptor. This will
46210127ef0fSEd Maste     // interrupt the IOHandlerProcessSTDIO::Run() and we can look at the byte
4622435933ddSDimitry Andric     // that was written to the pipe and then call
46234ba319b5SDimitry Andric     // m_process->SendAsyncInterrupt() from a much safer location in code.
4624435933ddSDimitry Andric     if (m_active) {
46250127ef0fSEd Maste       char ch = 'i'; // Send 'i' for interrupt
46267aa51b79SEd Maste       size_t bytes_written = 0;
46275517e702SDimitry Andric       Status result = m_pipe.Write(&ch, 1, bytes_written);
46287aa51b79SEd Maste       return result.Success();
4629435933ddSDimitry Andric     } else {
4630435933ddSDimitry Andric       // This IOHandler might be pushed on the stack, but not being run
46314ba319b5SDimitry Andric       // currently so do the right thing if we aren't actively watching for
46324ba319b5SDimitry Andric       // STDIN by sending the interrupt to the process. Otherwise the write to
46334ba319b5SDimitry Andric       // the pipe above would do nothing. This can happen when the command
46344ba319b5SDimitry Andric       // interpreter is running and gets a "expression ...". It will be on the
46354ba319b5SDimitry Andric       // IOHandler thread and sending the input is complete to the delegate
46364ba319b5SDimitry Andric       // which will cause the expression to run, which will push the process IO
46374ba319b5SDimitry Andric       // handler, but not run it.
46380127ef0fSEd Maste 
4639435933ddSDimitry Andric       if (StateIsRunningState(m_process->GetState())) {
46406fcb8242SEd Maste         m_process->SendAsyncInterrupt();
46410127ef0fSEd Maste         return true;
46420127ef0fSEd Maste       }
46430127ef0fSEd Maste     }
46440127ef0fSEd Maste     return false;
46456fcb8242SEd Maste   }
46466fcb8242SEd Maste 
GotEOF()4647435933ddSDimitry Andric   void GotEOF() override {}
464812b93ac6SEd Maste 
464912b93ac6SEd Maste protected:
465012b93ac6SEd Maste   Process *m_process;
465112b93ac6SEd Maste   File m_read_file;  // Read from this file (usually actual STDIN for LLDB
4652435933ddSDimitry Andric   File m_write_file; // Write to this file (usually the master pty for getting
4653435933ddSDimitry Andric                      // io to debuggee)
46540127ef0fSEd Maste   Pipe m_pipe;
4655435933ddSDimitry Andric   std::atomic<bool> m_is_running{false};
465612b93ac6SEd Maste };
465712b93ac6SEd Maste 
SetSTDIOFileDescriptor(int fd)4658435933ddSDimitry Andric void Process::SetSTDIOFileDescriptor(int fd) {
4659ac7ddfbfSEd Maste   // First set up the Read Thread for reading/handling process I/O
4660ac7ddfbfSEd Maste 
4661435933ddSDimitry Andric   std::unique_ptr<ConnectionFileDescriptor> conn_ap(
4662435933ddSDimitry Andric       new ConnectionFileDescriptor(fd, true));
4663ac7ddfbfSEd Maste 
4664435933ddSDimitry Andric   if (conn_ap) {
4665ac7ddfbfSEd Maste     m_stdio_communication.SetConnection(conn_ap.release());
4666435933ddSDimitry Andric     if (m_stdio_communication.IsConnected()) {
4667435933ddSDimitry Andric       m_stdio_communication.SetReadThreadBytesReceivedCallback(
4668435933ddSDimitry Andric           STDIOReadThreadBytesReceived, this);
4669ac7ddfbfSEd Maste       m_stdio_communication.StartReadThread();
4670ac7ddfbfSEd Maste 
4671ac7ddfbfSEd Maste       // Now read thread is set up, set up input reader.
4672ac7ddfbfSEd Maste 
46734bb0738eSEd Maste       if (!m_process_input_reader)
467412b93ac6SEd Maste         m_process_input_reader.reset(new IOHandlerProcessSTDIO(this, fd));
4675ac7ddfbfSEd Maste     }
4676ac7ddfbfSEd Maste   }
4677ac7ddfbfSEd Maste }
4678ac7ddfbfSEd Maste 
ProcessIOHandlerIsActive()4679435933ddSDimitry Andric bool Process::ProcessIOHandlerIsActive() {
46800127ef0fSEd Maste   IOHandlerSP io_handler_sp(m_process_input_reader);
46810127ef0fSEd Maste   if (io_handler_sp)
46829f2f44ceSEd Maste     return GetTarget().GetDebugger().IsTopIOHandler(io_handler_sp);
46830127ef0fSEd Maste   return false;
46840127ef0fSEd Maste }
PushProcessIOHandler()4685435933ddSDimitry Andric bool Process::PushProcessIOHandler() {
468612b93ac6SEd Maste   IOHandlerSP io_handler_sp(m_process_input_reader);
4687435933ddSDimitry Andric   if (io_handler_sp) {
46881c3bbb01SEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
46891c3bbb01SEd Maste     if (log)
46901c3bbb01SEd Maste       log->Printf("Process::%s pushing IO handler", __FUNCTION__);
46911c3bbb01SEd Maste 
469212b93ac6SEd Maste     io_handler_sp->SetIsDone(false);
4693*b5893f02SDimitry Andric     // If we evaluate an utility function, then we don't cancel the current
4694*b5893f02SDimitry Andric     // IOHandler. Our IOHandler is non-interactive and shouldn't disturb the
4695*b5893f02SDimitry Andric     // existing IOHandler that potentially provides the user interface (e.g.
4696*b5893f02SDimitry Andric     // the IOHandler for Editline).
4697*b5893f02SDimitry Andric     bool cancel_top_handler = !m_mod_id.IsRunningUtilityFunction();
4698*b5893f02SDimitry Andric     GetTarget().GetDebugger().PushIOHandler(io_handler_sp, cancel_top_handler);
46990127ef0fSEd Maste     return true;
470012b93ac6SEd Maste   }
47010127ef0fSEd Maste   return false;
4702ac7ddfbfSEd Maste }
4703ac7ddfbfSEd Maste 
PopProcessIOHandler()4704435933ddSDimitry Andric bool Process::PopProcessIOHandler() {
470512b93ac6SEd Maste   IOHandlerSP io_handler_sp(m_process_input_reader);
470612b93ac6SEd Maste   if (io_handler_sp)
47079f2f44ceSEd Maste     return GetTarget().GetDebugger().PopIOHandler(io_handler_sp);
47080127ef0fSEd Maste   return false;
4709ac7ddfbfSEd Maste }
4710ac7ddfbfSEd Maste 
4711ac7ddfbfSEd Maste // The process needs to know about installed plug-ins
SettingsInitialize()4712435933ddSDimitry Andric void Process::SettingsInitialize() { Thread::SettingsInitialize(); }
4713ac7ddfbfSEd Maste 
SettingsTerminate()4714435933ddSDimitry Andric void Process::SettingsTerminate() { Thread::SettingsTerminate(); }
4715ac7ddfbfSEd Maste 
4716435933ddSDimitry Andric namespace {
47174ba319b5SDimitry Andric // RestorePlanState is used to record the "is private", "is master" and "okay
47184ba319b5SDimitry Andric // to discard" fields of the plan we are running, and reset it on Clean or on
47194ba319b5SDimitry Andric // destruction. It will only reset the state once, so you can call Clean and
47204ba319b5SDimitry Andric // then monkey with the state and it won't get reset on you again.
47219f2f44ceSEd Maste 
4722435933ddSDimitry Andric class RestorePlanState {
47239f2f44ceSEd Maste public:
RestorePlanState(lldb::ThreadPlanSP thread_plan_sp)4724435933ddSDimitry Andric   RestorePlanState(lldb::ThreadPlanSP thread_plan_sp)
4725435933ddSDimitry Andric       : m_thread_plan_sp(thread_plan_sp), m_already_reset(false) {
4726435933ddSDimitry Andric     if (m_thread_plan_sp) {
47279f2f44ceSEd Maste       m_private = m_thread_plan_sp->GetPrivate();
47289f2f44ceSEd Maste       m_is_master = m_thread_plan_sp->IsMasterPlan();
47299f2f44ceSEd Maste       m_okay_to_discard = m_thread_plan_sp->OkayToDiscard();
47309f2f44ceSEd Maste     }
47319f2f44ceSEd Maste   }
47329f2f44ceSEd Maste 
~RestorePlanState()4733435933ddSDimitry Andric   ~RestorePlanState() { Clean(); }
47349f2f44ceSEd Maste 
Clean()4735435933ddSDimitry Andric   void Clean() {
4736435933ddSDimitry Andric     if (!m_already_reset && m_thread_plan_sp) {
47379f2f44ceSEd Maste       m_already_reset = true;
47389f2f44ceSEd Maste       m_thread_plan_sp->SetPrivate(m_private);
47399f2f44ceSEd Maste       m_thread_plan_sp->SetIsMasterPlan(m_is_master);
47409f2f44ceSEd Maste       m_thread_plan_sp->SetOkayToDiscard(m_okay_to_discard);
47419f2f44ceSEd Maste     }
47429f2f44ceSEd Maste   }
47439f2f44ceSEd Maste 
47449f2f44ceSEd Maste private:
47459f2f44ceSEd Maste   lldb::ThreadPlanSP m_thread_plan_sp;
47469f2f44ceSEd Maste   bool m_already_reset;
47479f2f44ceSEd Maste   bool m_private;
47489f2f44ceSEd Maste   bool m_is_master;
47499f2f44ceSEd Maste   bool m_okay_to_discard;
47509f2f44ceSEd Maste };
47519f2f44ceSEd Maste } // anonymous namespace
47529f2f44ceSEd Maste 
4753435933ddSDimitry Andric static microseconds
GetOneThreadExpressionTimeout(const EvaluateExpressionOptions & options)4754435933ddSDimitry Andric GetOneThreadExpressionTimeout(const EvaluateExpressionOptions &options) {
4755435933ddSDimitry Andric   const milliseconds default_one_thread_timeout(250);
4756435933ddSDimitry Andric 
4757435933ddSDimitry Andric   // If the overall wait is forever, then we don't need to worry about it.
4758435933ddSDimitry Andric   if (!options.GetTimeout()) {
4759435933ddSDimitry Andric     return options.GetOneThreadTimeout() ? *options.GetOneThreadTimeout()
4760435933ddSDimitry Andric                                          : default_one_thread_timeout;
4761435933ddSDimitry Andric   }
4762435933ddSDimitry Andric 
4763435933ddSDimitry Andric   // If the one thread timeout is set, use it.
4764435933ddSDimitry Andric   if (options.GetOneThreadTimeout())
4765435933ddSDimitry Andric     return *options.GetOneThreadTimeout();
4766435933ddSDimitry Andric 
4767435933ddSDimitry Andric   // Otherwise use half the total timeout, bounded by the
4768435933ddSDimitry Andric   // default_one_thread_timeout.
4769435933ddSDimitry Andric   return std::min<microseconds>(default_one_thread_timeout,
4770435933ddSDimitry Andric                                 *options.GetTimeout() / 2);
4771435933ddSDimitry Andric }
4772435933ddSDimitry Andric 
4773435933ddSDimitry Andric static Timeout<std::micro>
GetExpressionTimeout(const EvaluateExpressionOptions & options,bool before_first_timeout)4774435933ddSDimitry Andric GetExpressionTimeout(const EvaluateExpressionOptions &options,
4775435933ddSDimitry Andric                      bool before_first_timeout) {
47764ba319b5SDimitry Andric   // If we are going to run all threads the whole time, or if we are only going
47774ba319b5SDimitry Andric   // to run one thread, we can just return the overall timeout.
4778435933ddSDimitry Andric   if (!options.GetStopOthers() || !options.GetTryAllThreads())
4779435933ddSDimitry Andric     return options.GetTimeout();
4780435933ddSDimitry Andric 
4781435933ddSDimitry Andric   if (before_first_timeout)
4782435933ddSDimitry Andric     return GetOneThreadExpressionTimeout(options);
4783435933ddSDimitry Andric 
4784435933ddSDimitry Andric   if (!options.GetTimeout())
4785435933ddSDimitry Andric     return llvm::None;
4786435933ddSDimitry Andric   else
4787435933ddSDimitry Andric     return *options.GetTimeout() - GetOneThreadExpressionTimeout(options);
4788435933ddSDimitry Andric }
4789435933ddSDimitry Andric 
4790302affcbSDimitry Andric static llvm::Optional<ExpressionResults>
HandleStoppedEvent(Thread & thread,const ThreadPlanSP & thread_plan_sp,RestorePlanState & restorer,const EventSP & event_sp,EventSP & event_to_broadcast_sp,const EvaluateExpressionOptions & options,bool handle_interrupts)4791302affcbSDimitry Andric HandleStoppedEvent(Thread &thread, const ThreadPlanSP &thread_plan_sp,
4792302affcbSDimitry Andric                    RestorePlanState &restorer, const EventSP &event_sp,
4793302affcbSDimitry Andric                    EventSP &event_to_broadcast_sp,
4794302affcbSDimitry Andric                    const EvaluateExpressionOptions &options, bool handle_interrupts) {
4795302affcbSDimitry Andric   Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS);
4796302affcbSDimitry Andric 
4797302affcbSDimitry Andric   ThreadPlanSP plan = thread.GetCompletedPlan();
4798302affcbSDimitry Andric   if (plan == thread_plan_sp && plan->PlanSucceeded()) {
4799302affcbSDimitry Andric     LLDB_LOG(log, "execution completed successfully");
4800302affcbSDimitry Andric 
4801302affcbSDimitry Andric     // Restore the plan state so it will get reported as intended when we are
4802302affcbSDimitry Andric     // done.
4803302affcbSDimitry Andric     restorer.Clean();
4804302affcbSDimitry Andric     return eExpressionCompleted;
4805302affcbSDimitry Andric   }
4806302affcbSDimitry Andric 
4807302affcbSDimitry Andric   StopInfoSP stop_info_sp = thread.GetStopInfo();
4808302affcbSDimitry Andric   if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint &&
4809302affcbSDimitry Andric       stop_info_sp->ShouldNotify(event_sp.get())) {
4810302affcbSDimitry Andric     LLDB_LOG(log, "stopped for breakpoint: {0}.", stop_info_sp->GetDescription());
4811302affcbSDimitry Andric     if (!options.DoesIgnoreBreakpoints()) {
4812302affcbSDimitry Andric       // Restore the plan state and then force Private to false.  We are going
4813302affcbSDimitry Andric       // to stop because of this plan so we need it to become a public plan or
48144ba319b5SDimitry Andric       // it won't report correctly when we continue to its termination later
48154ba319b5SDimitry Andric       // on.
4816302affcbSDimitry Andric       restorer.Clean();
4817302affcbSDimitry Andric       thread_plan_sp->SetPrivate(false);
4818302affcbSDimitry Andric       event_to_broadcast_sp = event_sp;
4819302affcbSDimitry Andric     }
4820302affcbSDimitry Andric     return eExpressionHitBreakpoint;
4821302affcbSDimitry Andric   }
4822302affcbSDimitry Andric 
4823302affcbSDimitry Andric   if (!handle_interrupts &&
4824302affcbSDimitry Andric       Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
4825302affcbSDimitry Andric     return llvm::None;
4826302affcbSDimitry Andric 
4827302affcbSDimitry Andric   LLDB_LOG(log, "thread plan did not successfully complete");
4828302affcbSDimitry Andric   if (!options.DoesUnwindOnError())
4829302affcbSDimitry Andric     event_to_broadcast_sp = event_sp;
4830302affcbSDimitry Andric   return eExpressionInterrupted;
4831302affcbSDimitry Andric }
4832302affcbSDimitry Andric 
48330127ef0fSEd Maste ExpressionResults
RunThreadPlan(ExecutionContext & exe_ctx,lldb::ThreadPlanSP & thread_plan_sp,const EvaluateExpressionOptions & options,DiagnosticManager & diagnostic_manager)4834435933ddSDimitry Andric Process::RunThreadPlan(ExecutionContext &exe_ctx,
4835435933ddSDimitry Andric                        lldb::ThreadPlanSP &thread_plan_sp,
4836435933ddSDimitry Andric                        const EvaluateExpressionOptions &options,
4837435933ddSDimitry Andric                        DiagnosticManager &diagnostic_manager) {
48380127ef0fSEd Maste   ExpressionResults return_value = eExpressionSetupError;
4839ac7ddfbfSEd Maste 
48404bb0738eSEd Maste   std::lock_guard<std::mutex> run_thread_plan_locker(m_run_thread_plan_lock);
48414bb0738eSEd Maste 
4842435933ddSDimitry Andric   if (!thread_plan_sp) {
4843435933ddSDimitry Andric     diagnostic_manager.PutString(
4844435933ddSDimitry Andric         eDiagnosticSeverityError,
4845435933ddSDimitry Andric         "RunThreadPlan called with empty thread plan.");
48460127ef0fSEd Maste     return eExpressionSetupError;
4847ac7ddfbfSEd Maste   }
4848ac7ddfbfSEd Maste 
4849435933ddSDimitry Andric   if (!thread_plan_sp->ValidatePlan(nullptr)) {
4850435933ddSDimitry Andric     diagnostic_manager.PutString(
4851435933ddSDimitry Andric         eDiagnosticSeverityError,
4852435933ddSDimitry Andric         "RunThreadPlan called with an invalid thread plan.");
48530127ef0fSEd Maste     return eExpressionSetupError;
4854ac7ddfbfSEd Maste   }
4855ac7ddfbfSEd Maste 
4856435933ddSDimitry Andric   if (exe_ctx.GetProcessPtr() != this) {
4857435933ddSDimitry Andric     diagnostic_manager.PutString(eDiagnosticSeverityError,
4858435933ddSDimitry Andric                                  "RunThreadPlan called on wrong process.");
48590127ef0fSEd Maste     return eExpressionSetupError;
4860ac7ddfbfSEd Maste   }
4861ac7ddfbfSEd Maste 
4862ac7ddfbfSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
4863435933ddSDimitry Andric   if (thread == nullptr) {
4864435933ddSDimitry Andric     diagnostic_manager.PutString(eDiagnosticSeverityError,
4865435933ddSDimitry Andric                                  "RunThreadPlan called with invalid thread.");
48660127ef0fSEd Maste     return eExpressionSetupError;
4867ac7ddfbfSEd Maste   }
4868ac7ddfbfSEd Maste 
4869435933ddSDimitry Andric   // We need to change some of the thread plan attributes for the thread plan
48704ba319b5SDimitry Andric   // runner.  This will restore them when we are done:
48719f2f44ceSEd Maste 
48729f2f44ceSEd Maste   RestorePlanState thread_plan_restorer(thread_plan_sp);
48739f2f44ceSEd Maste 
48744ba319b5SDimitry Andric   // We rely on the thread plan we are running returning "PlanCompleted" if
48754ba319b5SDimitry Andric   // when it successfully completes. For that to be true the plan can't be
48764ba319b5SDimitry Andric   // private - since private plans suppress themselves in the GetCompletedPlan
48774ba319b5SDimitry Andric   // call.
4878ac7ddfbfSEd Maste 
4879ac7ddfbfSEd Maste   thread_plan_sp->SetPrivate(false);
4880ac7ddfbfSEd Maste 
4881435933ddSDimitry Andric   // The plans run with RunThreadPlan also need to be terminal master plans or
48824ba319b5SDimitry Andric   // when they are done we will end up asking the plan above us whether we
48834ba319b5SDimitry Andric   // should stop, which may give the wrong answer.
48849f2f44ceSEd Maste 
48859f2f44ceSEd Maste   thread_plan_sp->SetIsMasterPlan(true);
48869f2f44ceSEd Maste   thread_plan_sp->SetOkayToDiscard(false);
48879f2f44ceSEd Maste 
4888*b5893f02SDimitry Andric   // If we are running some utility expression for LLDB, we now have to mark
4889*b5893f02SDimitry Andric   // this in the ProcesModID of this process. This RAII takes care of marking
4890*b5893f02SDimitry Andric   // and reverting the mark it once we are done running the expression.
4891*b5893f02SDimitry Andric   UtilityFunctionScope util_scope(options.IsForUtilityExpr() ? this : nullptr);
4892*b5893f02SDimitry Andric 
4893435933ddSDimitry Andric   if (m_private_state.GetValue() != eStateStopped) {
4894435933ddSDimitry Andric     diagnostic_manager.PutString(
4895435933ddSDimitry Andric         eDiagnosticSeverityError,
48964bb0738eSEd Maste         "RunThreadPlan called while the private state was not stopped.");
48970127ef0fSEd Maste     return eExpressionSetupError;
4898ac7ddfbfSEd Maste   }
4899ac7ddfbfSEd Maste 
4900ac7ddfbfSEd Maste   // Save the thread & frame from the exe_ctx for restoration after we run
4901ac7ddfbfSEd Maste   const uint32_t thread_idx_id = thread->GetIndexID();
4902ac7ddfbfSEd Maste   StackFrameSP selected_frame_sp = thread->GetSelectedFrame();
4903435933ddSDimitry Andric   if (!selected_frame_sp) {
49044bb0738eSEd Maste     thread->SetSelectedFrame(nullptr);
4905ac7ddfbfSEd Maste     selected_frame_sp = thread->GetSelectedFrame();
4906435933ddSDimitry Andric     if (!selected_frame_sp) {
4907435933ddSDimitry Andric       diagnostic_manager.Printf(
4908435933ddSDimitry Andric           eDiagnosticSeverityError,
4909435933ddSDimitry Andric           "RunThreadPlan called without a selected frame on thread %d",
4910435933ddSDimitry Andric           thread_idx_id);
49110127ef0fSEd Maste       return eExpressionSetupError;
4912ac7ddfbfSEd Maste     }
4913ac7ddfbfSEd Maste   }
4914ac7ddfbfSEd Maste 
49154ba319b5SDimitry Andric   // Make sure the timeout values make sense. The one thread timeout needs to
49164ba319b5SDimitry Andric   // be smaller than the overall timeout.
4917435933ddSDimitry Andric   if (options.GetOneThreadTimeout() && options.GetTimeout() &&
4918435933ddSDimitry Andric       *options.GetTimeout() < *options.GetOneThreadTimeout()) {
4919435933ddSDimitry Andric     diagnostic_manager.PutString(eDiagnosticSeverityError,
4920435933ddSDimitry Andric                                  "RunThreadPlan called with one thread "
4921435933ddSDimitry Andric                                  "timeout greater than total timeout");
4922435933ddSDimitry Andric     return eExpressionSetupError;
4923435933ddSDimitry Andric   }
4924435933ddSDimitry Andric 
4925ac7ddfbfSEd Maste   StackID ctx_frame_id = selected_frame_sp->GetStackID();
4926ac7ddfbfSEd Maste 
4927435933ddSDimitry Andric   // N.B. Running the target may unset the currently selected thread and frame.
49284ba319b5SDimitry Andric   // We don't want to do that either, so we should arrange to reset them as
49294ba319b5SDimitry Andric   // well.
4930ac7ddfbfSEd Maste 
4931ac7ddfbfSEd Maste   lldb::ThreadSP selected_thread_sp = GetThreadList().GetSelectedThread();
4932ac7ddfbfSEd Maste 
4933ac7ddfbfSEd Maste   uint32_t selected_tid;
4934ac7ddfbfSEd Maste   StackID selected_stack_id;
4935435933ddSDimitry Andric   if (selected_thread_sp) {
4936ac7ddfbfSEd Maste     selected_tid = selected_thread_sp->GetIndexID();
4937ac7ddfbfSEd Maste     selected_stack_id = selected_thread_sp->GetSelectedFrame()->GetStackID();
4938435933ddSDimitry Andric   } else {
4939ac7ddfbfSEd Maste     selected_tid = LLDB_INVALID_THREAD_ID;
4940ac7ddfbfSEd Maste   }
4941ac7ddfbfSEd Maste 
49427aa51b79SEd Maste   HostThread backup_private_state_thread;
49437aa51b79SEd Maste   lldb::StateType old_state = eStateInvalid;
4944ac7ddfbfSEd Maste   lldb::ThreadPlanSP stopper_base_plan_sp;
4945ac7ddfbfSEd Maste 
4946435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
4947435933ddSDimitry Andric                                                   LIBLLDB_LOG_PROCESS));
4948435933ddSDimitry Andric   if (m_private_state_thread.EqualsThread(Host::GetCurrentThread())) {
4949435933ddSDimitry Andric     // Yikes, we are running on the private state thread!  So we can't wait for
49504ba319b5SDimitry Andric     // public events on this thread, since we are the thread that is generating
49514ba319b5SDimitry Andric     // public events. The simplest thing to do is to spin up a temporary thread
49524ba319b5SDimitry Andric     // to handle private state thread events while we are fielding public
49534ba319b5SDimitry Andric     // events here.
4954ac7ddfbfSEd Maste     if (log)
4955435933ddSDimitry Andric       log->Printf("Running thread plan on private state thread, spinning up "
4956435933ddSDimitry Andric                   "another state thread to handle the events.");
4957ac7ddfbfSEd Maste 
4958ac7ddfbfSEd Maste     backup_private_state_thread = m_private_state_thread;
4959ac7ddfbfSEd Maste 
4960435933ddSDimitry Andric     // One other bit of business: we want to run just this thread plan and
49614ba319b5SDimitry Andric     // anything it pushes, and then stop, returning control here. But in the
49624ba319b5SDimitry Andric     // normal course of things, the plan above us on the stack would be given a
49634ba319b5SDimitry Andric     // shot at the stop event before deciding to stop, and we don't want that.
49644ba319b5SDimitry Andric     // So we insert a "stopper" base plan on the stack before the plan we want
49654ba319b5SDimitry Andric     // to run.  Since base plans always stop and return control to the user,
49664ba319b5SDimitry Andric     // that will do just what we want.
4967ac7ddfbfSEd Maste     stopper_base_plan_sp.reset(new ThreadPlanBase(*thread));
4968ac7ddfbfSEd Maste     thread->QueueThreadPlan(stopper_base_plan_sp, false);
4969435933ddSDimitry Andric     // Have to make sure our public state is stopped, since otherwise the
4970435933ddSDimitry Andric     // reporting logic below doesn't work correctly.
4971ac7ddfbfSEd Maste     old_state = m_public_state.GetValue();
4972ac7ddfbfSEd Maste     m_public_state.SetValueNoLock(eStateStopped);
4973ac7ddfbfSEd Maste 
4974ac7ddfbfSEd Maste     // Now spin up the private state thread:
4975ac7ddfbfSEd Maste     StartPrivateStateThread(true);
4976ac7ddfbfSEd Maste   }
4977ac7ddfbfSEd Maste 
4978435933ddSDimitry Andric   thread->QueueThreadPlan(
4979435933ddSDimitry Andric       thread_plan_sp, false); // This used to pass "true" does that make sense?
4980ac7ddfbfSEd Maste 
4981435933ddSDimitry Andric   if (options.GetDebug()) {
49824ba319b5SDimitry Andric     // In this case, we aren't actually going to run, we just want to stop
49834ba319b5SDimitry Andric     // right away. Flush this thread so we will refetch the stacks and show the
49844ba319b5SDimitry Andric     // correct backtrace.
4985435933ddSDimitry Andric     // FIXME: To make this prettier we should invent some stop reason for this,
4986435933ddSDimitry Andric     // but that
4987435933ddSDimitry Andric     // is only cosmetic, and this functionality is only of use to lldb
49884ba319b5SDimitry Andric     // developers who can live with not pretty...
4989b952cd58SEd Maste     thread->Flush();
49900127ef0fSEd Maste     return eExpressionStoppedForDebug;
4991b952cd58SEd Maste   }
4992b952cd58SEd Maste 
4993435933ddSDimitry Andric   ListenerSP listener_sp(
4994435933ddSDimitry Andric       Listener::MakeListener("lldb.process.listener.run-thread-plan"));
4995ac7ddfbfSEd Maste 
4996ac7ddfbfSEd Maste   lldb::EventSP event_to_broadcast_sp;
4997ac7ddfbfSEd Maste 
4998ac7ddfbfSEd Maste   {
4999435933ddSDimitry Andric     // This process event hijacker Hijacks the Public events and its destructor
50004ba319b5SDimitry Andric     // makes sure that the process events get restored on exit to the function.
5001ac7ddfbfSEd Maste     //
5002435933ddSDimitry Andric     // If the event needs to propagate beyond the hijacker (e.g., the process
50034ba319b5SDimitry Andric     // exits during execution), then the event is put into
50044ba319b5SDimitry Andric     // event_to_broadcast_sp for rebroadcasting.
5005ac7ddfbfSEd Maste 
50064bb0738eSEd Maste     ProcessEventHijacker run_thread_plan_hijacker(*this, listener_sp);
5007ac7ddfbfSEd Maste 
5008435933ddSDimitry Andric     if (log) {
5009ac7ddfbfSEd Maste       StreamString s;
5010ac7ddfbfSEd Maste       thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
5011435933ddSDimitry Andric       log->Printf("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64
5012435933ddSDimitry Andric                   " to run thread plan \"%s\".",
5013435933ddSDimitry Andric                   thread->GetIndexID(), thread->GetID(), s.GetData());
5014ac7ddfbfSEd Maste     }
5015ac7ddfbfSEd Maste 
5016ac7ddfbfSEd Maste     bool got_event;
5017ac7ddfbfSEd Maste     lldb::EventSP event_sp;
5018ac7ddfbfSEd Maste     lldb::StateType stop_state = lldb::eStateInvalid;
5019ac7ddfbfSEd Maste 
5020435933ddSDimitry Andric     bool before_first_timeout = true; // This is set to false the first time
5021435933ddSDimitry Andric                                       // that we have to halt the target.
5022ac7ddfbfSEd Maste     bool do_resume = true;
5023ac7ddfbfSEd Maste     bool handle_running_event = true;
5024ac7ddfbfSEd Maste 
5025ac7ddfbfSEd Maste     // This is just for accounting:
5026ac7ddfbfSEd Maste     uint32_t num_resumes = 0;
5027ac7ddfbfSEd Maste 
5028435933ddSDimitry Andric     // If we are going to run all threads the whole time, or if we are only
5029435933ddSDimitry Andric     // going to run one thread, then we don't need the first timeout.  So we
5030435933ddSDimitry Andric     // pretend we are after the first timeout already.
50310127ef0fSEd Maste     if (!options.GetStopOthers() || !options.GetTryAllThreads())
50320127ef0fSEd Maste       before_first_timeout = false;
50330127ef0fSEd Maste 
50340127ef0fSEd Maste     if (log)
5035435933ddSDimitry Andric       log->Printf("Stop others: %u, try all: %u, before_first: %u.\n",
5036435933ddSDimitry Andric                   options.GetStopOthers(), options.GetTryAllThreads(),
5037435933ddSDimitry Andric                   before_first_timeout);
5038ac7ddfbfSEd Maste 
50394ba319b5SDimitry Andric     // This isn't going to work if there are unfetched events on the queue. Are
50404ba319b5SDimitry Andric     // there cases where we might want to run the remaining events here, and
50414ba319b5SDimitry Andric     // then try to call the function?  That's probably being too tricky for our
50424ba319b5SDimitry Andric     // own good.
504312b93ac6SEd Maste 
50444bb0738eSEd Maste     Event *other_events = listener_sp->PeekAtNextEvent();
5045435933ddSDimitry Andric     if (other_events != nullptr) {
5046435933ddSDimitry Andric       diagnostic_manager.PutString(
5047435933ddSDimitry Andric           eDiagnosticSeverityError,
50484bb0738eSEd Maste           "RunThreadPlan called with pending events on the queue.");
50490127ef0fSEd Maste       return eExpressionSetupError;
505012b93ac6SEd Maste     }
505112b93ac6SEd Maste 
5052435933ddSDimitry Andric     // We also need to make sure that the next event is delivered.  We might be
50534ba319b5SDimitry Andric     // calling a function as part of a thread plan, in which case the last
50544ba319b5SDimitry Andric     // delivered event could be the running event, and we don't want event
50554ba319b5SDimitry Andric     // coalescing to cause us to lose OUR running event...
505612b93ac6SEd Maste     ForceNextEventDelivery();
505712b93ac6SEd Maste 
5058435933ddSDimitry Andric // This while loop must exit out the bottom, there's cleanup that we need to do
50594ba319b5SDimitry Andric // when we are done. So don't call return anywhere within it.
5060ac7ddfbfSEd Maste 
50610127ef0fSEd Maste #ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT
50624ba319b5SDimitry Andric     // It's pretty much impossible to write test cases for things like: One
50634ba319b5SDimitry Andric     // thread timeout expires, I go to halt, but the process already stopped on
50644ba319b5SDimitry Andric     // the function call stop breakpoint.  Turning on this define will make us
50654ba319b5SDimitry Andric     // not fetch the first event till after the halt.  So if you run a quick
50664ba319b5SDimitry Andric     // function, it will have completed, and the completion event will be
50674ba319b5SDimitry Andric     // waiting, when you interrupt for halt. The expression evaluation should
50684ba319b5SDimitry Andric     // still succeed.
50690127ef0fSEd Maste     bool miss_first_event = true;
50700127ef0fSEd Maste #endif
5071435933ddSDimitry Andric     while (true) {
50724ba319b5SDimitry Andric       // We usually want to resume the process if we get to the top of the
50734ba319b5SDimitry Andric       // loop. The only exception is if we get two running events with no
50744ba319b5SDimitry Andric       // intervening stop, which can happen, we will just wait for then next
50754ba319b5SDimitry Andric       // stop event.
5076ac7ddfbfSEd Maste       if (log)
5077435933ddSDimitry Andric         log->Printf("Top of while loop: do_resume: %i handle_running_event: %i "
5078435933ddSDimitry Andric                     "before_first_timeout: %i.",
5079435933ddSDimitry Andric                     do_resume, handle_running_event, before_first_timeout);
5080ac7ddfbfSEd Maste 
5081435933ddSDimitry Andric       if (do_resume || handle_running_event) {
5082435933ddSDimitry Andric         // Do the initial resume and wait for the running event before going
5083435933ddSDimitry Andric         // further.
5084ac7ddfbfSEd Maste 
5085435933ddSDimitry Andric         if (do_resume) {
5086ac7ddfbfSEd Maste           num_resumes++;
50875517e702SDimitry Andric           Status resume_error = PrivateResume();
5088435933ddSDimitry Andric           if (!resume_error.Success()) {
5089435933ddSDimitry Andric             diagnostic_manager.Printf(
5090435933ddSDimitry Andric                 eDiagnosticSeverityError,
50914bb0738eSEd Maste                 "couldn't resume inferior the %d time: \"%s\".", num_resumes,
5092ac7ddfbfSEd Maste                 resume_error.AsCString());
50930127ef0fSEd Maste             return_value = eExpressionSetupError;
5094ac7ddfbfSEd Maste             break;
5095ac7ddfbfSEd Maste           }
5096ac7ddfbfSEd Maste         }
5097ac7ddfbfSEd Maste 
5098435933ddSDimitry Andric         got_event =
5099435933ddSDimitry Andric             listener_sp->GetEvent(event_sp, std::chrono::milliseconds(500));
5100435933ddSDimitry Andric         if (!got_event) {
5101ac7ddfbfSEd Maste           if (log)
5102435933ddSDimitry Andric             log->Printf("Process::RunThreadPlan(): didn't get any event after "
5103435933ddSDimitry Andric                         "resume %" PRIu32 ", exiting.",
5104ac7ddfbfSEd Maste                         num_resumes);
5105ac7ddfbfSEd Maste 
51064bb0738eSEd Maste           diagnostic_manager.Printf(eDiagnosticSeverityError,
5107435933ddSDimitry Andric                                     "didn't get any event after resume %" PRIu32
5108435933ddSDimitry Andric                                     ", exiting.",
5109435933ddSDimitry Andric                                     num_resumes);
51100127ef0fSEd Maste           return_value = eExpressionSetupError;
5111ac7ddfbfSEd Maste           break;
5112ac7ddfbfSEd Maste         }
5113ac7ddfbfSEd Maste 
5114435933ddSDimitry Andric         stop_state =
5115435933ddSDimitry Andric             Process::ProcessEventData::GetStateFromEvent(event_sp.get());
5116ac7ddfbfSEd Maste 
5117435933ddSDimitry Andric         if (stop_state != eStateRunning) {
5118ac7ddfbfSEd Maste           bool restarted = false;
5119ac7ddfbfSEd Maste 
5120435933ddSDimitry Andric           if (stop_state == eStateStopped) {
5121435933ddSDimitry Andric             restarted = Process::ProcessEventData::GetRestartedFromEvent(
5122435933ddSDimitry Andric                 event_sp.get());
5123ac7ddfbfSEd Maste             if (log)
5124435933ddSDimitry Andric               log->Printf(
5125435933ddSDimitry Andric                   "Process::RunThreadPlan(): didn't get running event after "
5126435933ddSDimitry Andric                   "resume %d, got %s instead (restarted: %i, do_resume: %i, "
5127435933ddSDimitry Andric                   "handle_running_event: %i).",
5128435933ddSDimitry Andric                   num_resumes, StateAsCString(stop_state), restarted, do_resume,
5129ac7ddfbfSEd Maste                   handle_running_event);
5130ac7ddfbfSEd Maste           }
5131ac7ddfbfSEd Maste 
5132435933ddSDimitry Andric           if (restarted) {
5133435933ddSDimitry Andric             // This is probably an overabundance of caution, I don't think I
51344ba319b5SDimitry Andric             // should ever get a stopped & restarted event here.  But if I do,
51354ba319b5SDimitry Andric             // the best thing is to Halt and then get out of here.
51369f2f44ceSEd Maste             const bool clear_thread_plans = false;
51379f2f44ceSEd Maste             const bool use_run_lock = false;
51389f2f44ceSEd Maste             Halt(clear_thread_plans, use_run_lock);
5139ac7ddfbfSEd Maste           }
5140ac7ddfbfSEd Maste 
5141435933ddSDimitry Andric           diagnostic_manager.Printf(
5142435933ddSDimitry Andric               eDiagnosticSeverityError,
51434bb0738eSEd Maste               "didn't get running event after initial resume, got %s instead.",
5144ac7ddfbfSEd Maste               StateAsCString(stop_state));
51450127ef0fSEd Maste           return_value = eExpressionSetupError;
5146ac7ddfbfSEd Maste           break;
5147ac7ddfbfSEd Maste         }
5148ac7ddfbfSEd Maste 
5149ac7ddfbfSEd Maste         if (log)
5150ac7ddfbfSEd Maste           log->PutCString("Process::RunThreadPlan(): resuming succeeded.");
51514ba319b5SDimitry Andric         // We need to call the function synchronously, so spin waiting for it
51524ba319b5SDimitry Andric         // to return. If we get interrupted while executing, we're going to
51534ba319b5SDimitry Andric         // lose our context, and won't be able to gather the result at this
51544ba319b5SDimitry Andric         // point. We set the timeout AFTER the resume, since the resume takes
51554ba319b5SDimitry Andric         // some time and we don't want to charge that to the timeout.
5156435933ddSDimitry Andric       } else {
5157ac7ddfbfSEd Maste         if (log)
5158ac7ddfbfSEd Maste           log->PutCString("Process::RunThreadPlan(): waiting for next event.");
5159ac7ddfbfSEd Maste       }
5160ac7ddfbfSEd Maste 
5161ac7ddfbfSEd Maste       do_resume = true;
5162ac7ddfbfSEd Maste       handle_running_event = true;
5163ac7ddfbfSEd Maste 
5164ac7ddfbfSEd Maste       // Now wait for the process to stop again:
5165ac7ddfbfSEd Maste       event_sp.reset();
5166ac7ddfbfSEd Maste 
5167435933ddSDimitry Andric       Timeout<std::micro> timeout =
5168435933ddSDimitry Andric           GetExpressionTimeout(options, before_first_timeout);
5169435933ddSDimitry Andric       if (log) {
5170435933ddSDimitry Andric         if (timeout) {
5171435933ddSDimitry Andric           auto now = system_clock::now();
5172435933ddSDimitry Andric           log->Printf("Process::RunThreadPlan(): about to wait - now is %s - "
5173435933ddSDimitry Andric                       "endpoint is %s",
5174435933ddSDimitry Andric                       llvm::to_string(now).c_str(),
5175435933ddSDimitry Andric                       llvm::to_string(now + *timeout).c_str());
5176435933ddSDimitry Andric         } else {
5177ac7ddfbfSEd Maste           log->Printf("Process::RunThreadPlan(): about to wait forever.");
5178ac7ddfbfSEd Maste         }
5179ac7ddfbfSEd Maste       }
5180ac7ddfbfSEd Maste 
51810127ef0fSEd Maste #ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT
51820127ef0fSEd Maste       // See comment above...
5183435933ddSDimitry Andric       if (miss_first_event) {
51840127ef0fSEd Maste         usleep(1000);
51850127ef0fSEd Maste         miss_first_event = false;
51860127ef0fSEd Maste         got_event = false;
5187435933ddSDimitry Andric       } else
51880127ef0fSEd Maste #endif
5189435933ddSDimitry Andric         got_event = listener_sp->GetEvent(event_sp, timeout);
5190ac7ddfbfSEd Maste 
5191435933ddSDimitry Andric       if (got_event) {
5192435933ddSDimitry Andric         if (event_sp) {
5193ac7ddfbfSEd Maste           bool keep_going = false;
5194435933ddSDimitry Andric           if (event_sp->GetType() == eBroadcastBitInterrupt) {
51959f2f44ceSEd Maste             const bool clear_thread_plans = false;
51969f2f44ceSEd Maste             const bool use_run_lock = false;
51979f2f44ceSEd Maste             Halt(clear_thread_plans, use_run_lock);
51980127ef0fSEd Maste             return_value = eExpressionInterrupted;
5199435933ddSDimitry Andric             diagnostic_manager.PutString(eDiagnosticSeverityRemark,
5200435933ddSDimitry Andric                                          "execution halted by user interrupt.");
5201435933ddSDimitry Andric             if (log)
5202435933ddSDimitry Andric               log->Printf("Process::RunThreadPlan(): Got  interrupted by "
5203435933ddSDimitry Andric                           "eBroadcastBitInterrupted, exiting.");
5204435933ddSDimitry Andric             break;
5205435933ddSDimitry Andric           } else {
5206435933ddSDimitry Andric             stop_state =
5207435933ddSDimitry Andric                 Process::ProcessEventData::GetStateFromEvent(event_sp.get());
5208ac7ddfbfSEd Maste             if (log)
52094bb0738eSEd Maste               log->Printf(
5210435933ddSDimitry Andric                   "Process::RunThreadPlan(): in while loop, got event: %s.",
5211435933ddSDimitry Andric                   StateAsCString(stop_state));
5212ac7ddfbfSEd Maste 
5213435933ddSDimitry Andric             switch (stop_state) {
5214435933ddSDimitry Andric             case lldb::eStateStopped: {
5215ac7ddfbfSEd Maste               // We stopped, figure out what we are going to do now.
5216435933ddSDimitry Andric               ThreadSP thread_sp =
5217435933ddSDimitry Andric                   GetThreadList().FindThreadByIndexID(thread_idx_id);
5218435933ddSDimitry Andric               if (!thread_sp) {
5219435933ddSDimitry Andric                 // Ooh, our thread has vanished.  Unlikely that this was
5220435933ddSDimitry Andric                 // successful execution...
5221ac7ddfbfSEd Maste                 if (log)
5222435933ddSDimitry Andric                   log->Printf("Process::RunThreadPlan(): execution completed "
5223435933ddSDimitry Andric                               "but our thread (index-id=%u) has vanished.",
5224435933ddSDimitry Andric                               thread_idx_id);
52250127ef0fSEd Maste                 return_value = eExpressionInterrupted;
5226302affcbSDimitry Andric               } else if (Process::ProcessEventData::GetRestartedFromEvent(
5227302affcbSDimitry Andric                              event_sp.get())) {
5228435933ddSDimitry Andric                 // If we were restarted, we just need to go back up to fetch
5229435933ddSDimitry Andric                 // another event.
5230435933ddSDimitry Andric                 if (log) {
5231435933ddSDimitry Andric                   log->Printf("Process::RunThreadPlan(): Got a stop and "
5232435933ddSDimitry Andric                               "restart, so we'll continue waiting.");
5233ac7ddfbfSEd Maste                 }
5234ac7ddfbfSEd Maste                 keep_going = true;
5235ac7ddfbfSEd Maste                 do_resume = false;
5236ac7ddfbfSEd Maste                 handle_running_event = true;
5237435933ddSDimitry Andric               } else {
5238302affcbSDimitry Andric                 const bool handle_interrupts = true;
5239302affcbSDimitry Andric                 return_value = *HandleStoppedEvent(
5240302affcbSDimitry Andric                     *thread, thread_plan_sp, thread_plan_restorer, event_sp,
5241302affcbSDimitry Andric                     event_to_broadcast_sp, options, handle_interrupts);
5242ac7ddfbfSEd Maste               }
5243435933ddSDimitry Andric             } break;
5244ac7ddfbfSEd Maste 
5245ac7ddfbfSEd Maste             case lldb::eStateRunning:
5246435933ddSDimitry Andric               // This shouldn't really happen, but sometimes we do get two
52474ba319b5SDimitry Andric               // running events without an intervening stop, and in that case
52484ba319b5SDimitry Andric               // we should just go back to waiting for the stop.
5249ac7ddfbfSEd Maste               do_resume = false;
5250ac7ddfbfSEd Maste               keep_going = true;
5251ac7ddfbfSEd Maste               handle_running_event = false;
5252ac7ddfbfSEd Maste               break;
5253ac7ddfbfSEd Maste 
5254ac7ddfbfSEd Maste             default:
5255ac7ddfbfSEd Maste               if (log)
5256435933ddSDimitry Andric                 log->Printf("Process::RunThreadPlan(): execution stopped with "
5257435933ddSDimitry Andric                             "unexpected state: %s.",
5258435933ddSDimitry Andric                             StateAsCString(stop_state));
5259ac7ddfbfSEd Maste 
5260ac7ddfbfSEd Maste               if (stop_state == eStateExited)
5261ac7ddfbfSEd Maste                 event_to_broadcast_sp = event_sp;
5262ac7ddfbfSEd Maste 
5263435933ddSDimitry Andric               diagnostic_manager.PutString(
5264435933ddSDimitry Andric                   eDiagnosticSeverityError,
52654bb0738eSEd Maste                   "execution stopped with unexpected state.");
52660127ef0fSEd Maste               return_value = eExpressionInterrupted;
5267ac7ddfbfSEd Maste               break;
5268ac7ddfbfSEd Maste             }
5269ac7ddfbfSEd Maste           }
5270ac7ddfbfSEd Maste 
5271ac7ddfbfSEd Maste           if (keep_going)
5272ac7ddfbfSEd Maste             continue;
5273ac7ddfbfSEd Maste           else
5274ac7ddfbfSEd Maste             break;
5275435933ddSDimitry Andric         } else {
5276ac7ddfbfSEd Maste           if (log)
5277435933ddSDimitry Andric             log->PutCString("Process::RunThreadPlan(): got_event was true, but "
5278435933ddSDimitry Andric                             "the event pointer was null.  How odd...");
52790127ef0fSEd Maste           return_value = eExpressionInterrupted;
5280ac7ddfbfSEd Maste           break;
5281ac7ddfbfSEd Maste         }
5282435933ddSDimitry Andric       } else {
52834ba319b5SDimitry Andric         // If we didn't get an event that means we've timed out... We will
52844ba319b5SDimitry Andric         // interrupt the process here.  Depending on what we were asked to do
52854ba319b5SDimitry Andric         // we will either exit, or try with all threads running for the same
52864ba319b5SDimitry Andric         // timeout.
5287ac7ddfbfSEd Maste 
5288ac7ddfbfSEd Maste         if (log) {
5289435933ddSDimitry Andric           if (options.GetTryAllThreads()) {
5290435933ddSDimitry Andric             if (before_first_timeout) {
5291f678e45dSDimitry Andric               LLDB_LOG(log,
5292f678e45dSDimitry Andric                        "Running function with one thread timeout timed out.");
5293435933ddSDimitry Andric             } else
5294f678e45dSDimitry Andric               LLDB_LOG(log, "Restarting function with all threads enabled and "
5295f678e45dSDimitry Andric                             "timeout: {0} timed out, abandoning execution.",
5296f678e45dSDimitry Andric                        timeout);
5297435933ddSDimitry Andric           } else
5298f678e45dSDimitry Andric             LLDB_LOG(log, "Running function with timeout: {0} timed out, "
5299ac7ddfbfSEd Maste                           "abandoning execution.",
5300f678e45dSDimitry Andric                      timeout);
5301ac7ddfbfSEd Maste         }
5302ac7ddfbfSEd Maste 
5303435933ddSDimitry Andric         // It is possible that between the time we issued the Halt, and we get
53044ba319b5SDimitry Andric         // around to calling Halt the target could have stopped.  That's fine,
53054ba319b5SDimitry Andric         // Halt will figure that out and send the appropriate Stopped event.
5306435933ddSDimitry Andric         // BUT it is also possible that we stopped & restarted (e.g. hit a
5307435933ddSDimitry Andric         // signal with "stop" set to false.)  In
5308435933ddSDimitry Andric         // that case, we'll get the stopped & restarted event, and we should go
53094ba319b5SDimitry Andric         // back to waiting for the Halt's stopped event.  That's what this
53104ba319b5SDimitry Andric         // while loop does.
5311ac7ddfbfSEd Maste 
5312ac7ddfbfSEd Maste         bool back_to_top = true;
5313ac7ddfbfSEd Maste         uint32_t try_halt_again = 0;
5314ac7ddfbfSEd Maste         bool do_halt = true;
5315ac7ddfbfSEd Maste         const uint32_t num_retries = 5;
5316435933ddSDimitry Andric         while (try_halt_again < num_retries) {
53175517e702SDimitry Andric           Status halt_error;
5318435933ddSDimitry Andric           if (do_halt) {
5319ac7ddfbfSEd Maste             if (log)
5320ac7ddfbfSEd Maste               log->Printf("Process::RunThreadPlan(): Running Halt.");
53219f2f44ceSEd Maste             const bool clear_thread_plans = false;
53229f2f44ceSEd Maste             const bool use_run_lock = false;
53239f2f44ceSEd Maste             Halt(clear_thread_plans, use_run_lock);
5324ac7ddfbfSEd Maste           }
5325435933ddSDimitry Andric           if (halt_error.Success()) {
5326ac7ddfbfSEd Maste             if (log)
5327ac7ddfbfSEd Maste               log->PutCString("Process::RunThreadPlan(): Halt succeeded.");
5328ac7ddfbfSEd Maste 
5329435933ddSDimitry Andric             got_event =
5330435933ddSDimitry Andric                 listener_sp->GetEvent(event_sp, std::chrono::milliseconds(500));
5331ac7ddfbfSEd Maste 
5332435933ddSDimitry Andric             if (got_event) {
5333435933ddSDimitry Andric               stop_state =
5334435933ddSDimitry Andric                   Process::ProcessEventData::GetStateFromEvent(event_sp.get());
5335435933ddSDimitry Andric               if (log) {
5336435933ddSDimitry Andric                 log->Printf("Process::RunThreadPlan(): Stopped with event: %s",
5337435933ddSDimitry Andric                             StateAsCString(stop_state));
5338435933ddSDimitry Andric                 if (stop_state == lldb::eStateStopped &&
5339435933ddSDimitry Andric                     Process::ProcessEventData::GetInterruptedFromEvent(
5340435933ddSDimitry Andric                         event_sp.get()))
5341ac7ddfbfSEd Maste                   log->PutCString("    Event was the Halt interruption event.");
5342ac7ddfbfSEd Maste               }
5343ac7ddfbfSEd Maste 
5344435933ddSDimitry Andric               if (stop_state == lldb::eStateStopped) {
5345435933ddSDimitry Andric                 if (Process::ProcessEventData::GetRestartedFromEvent(
5346435933ddSDimitry Andric                         event_sp.get())) {
5347ac7ddfbfSEd Maste                   if (log)
5348435933ddSDimitry Andric                     log->PutCString("Process::RunThreadPlan(): Went to halt "
5349435933ddSDimitry Andric                                     "but got a restarted event, there must be "
5350435933ddSDimitry Andric                                     "an un-restarted stopped event so try "
5351435933ddSDimitry Andric                                     "again...  "
5352ac7ddfbfSEd Maste                                     "Exiting wait loop.");
5353ac7ddfbfSEd Maste                   try_halt_again++;
5354ac7ddfbfSEd Maste                   do_halt = false;
5355ac7ddfbfSEd Maste                   continue;
5356ac7ddfbfSEd Maste                 }
5357ac7ddfbfSEd Maste 
5358302affcbSDimitry Andric                 // Between the time we initiated the Halt and the time we
53594ba319b5SDimitry Andric                 // delivered it, the process could have already finished its
53604ba319b5SDimitry Andric                 // job.  Check that here:
5361302affcbSDimitry Andric                 const bool handle_interrupts = false;
5362302affcbSDimitry Andric                 if (auto result = HandleStoppedEvent(
5363302affcbSDimitry Andric                         *thread, thread_plan_sp, thread_plan_restorer, event_sp,
5364302affcbSDimitry Andric                         event_to_broadcast_sp, options, handle_interrupts)) {
5365302affcbSDimitry Andric                   return_value = *result;
5366302affcbSDimitry Andric                   back_to_top = false;
5367302affcbSDimitry Andric                   break;
5368302affcbSDimitry Andric                 }
5369302affcbSDimitry Andric 
5370435933ddSDimitry Andric                 if (!options.GetTryAllThreads()) {
5371ac7ddfbfSEd Maste                   if (log)
5372435933ddSDimitry Andric                     log->PutCString("Process::RunThreadPlan(): try_all_threads "
5373435933ddSDimitry Andric                                     "was false, we stopped so now we're "
5374435933ddSDimitry Andric                                     "quitting.");
53750127ef0fSEd Maste                   return_value = eExpressionInterrupted;
5376ac7ddfbfSEd Maste                   back_to_top = false;
5377ac7ddfbfSEd Maste                   break;
5378ac7ddfbfSEd Maste                 }
5379ac7ddfbfSEd Maste 
5380435933ddSDimitry Andric                 if (before_first_timeout) {
5381435933ddSDimitry Andric                   // Set all the other threads to run, and return to the top of
5382435933ddSDimitry Andric                   // the loop, which will continue;
5383ac7ddfbfSEd Maste                   before_first_timeout = false;
5384ac7ddfbfSEd Maste                   thread_plan_sp->SetStopOthers(false);
5385ac7ddfbfSEd Maste                   if (log)
5386435933ddSDimitry Andric                     log->PutCString(
5387435933ddSDimitry Andric                         "Process::RunThreadPlan(): about to resume.");
5388ac7ddfbfSEd Maste 
5389ac7ddfbfSEd Maste                   back_to_top = true;
5390ac7ddfbfSEd Maste                   break;
5391435933ddSDimitry Andric                 } else {
5392ac7ddfbfSEd Maste                   // Running all threads failed, so return Interrupted.
5393ac7ddfbfSEd Maste                   if (log)
5394435933ddSDimitry Andric                     log->PutCString("Process::RunThreadPlan(): running all "
5395435933ddSDimitry Andric                                     "threads timed out.");
53960127ef0fSEd Maste                   return_value = eExpressionInterrupted;
5397ac7ddfbfSEd Maste                   back_to_top = false;
5398ac7ddfbfSEd Maste                   break;
5399ac7ddfbfSEd Maste                 }
5400ac7ddfbfSEd Maste               }
5401435933ddSDimitry Andric             } else {
5402435933ddSDimitry Andric               if (log)
5403435933ddSDimitry Andric                 log->PutCString("Process::RunThreadPlan(): halt said it "
5404435933ddSDimitry Andric                                 "succeeded, but I got no event.  "
5405ac7ddfbfSEd Maste                                 "I'm getting out of here passing Interrupted.");
54060127ef0fSEd Maste               return_value = eExpressionInterrupted;
5407ac7ddfbfSEd Maste               back_to_top = false;
5408ac7ddfbfSEd Maste               break;
5409ac7ddfbfSEd Maste             }
5410435933ddSDimitry Andric           } else {
5411ac7ddfbfSEd Maste             try_halt_again++;
5412ac7ddfbfSEd Maste             continue;
5413ac7ddfbfSEd Maste           }
5414ac7ddfbfSEd Maste         }
5415ac7ddfbfSEd Maste 
5416ac7ddfbfSEd Maste         if (!back_to_top || try_halt_again > num_retries)
5417ac7ddfbfSEd Maste           break;
5418ac7ddfbfSEd Maste         else
5419ac7ddfbfSEd Maste           continue;
5420ac7ddfbfSEd Maste       }
5421ac7ddfbfSEd Maste     } // END WAIT LOOP
5422ac7ddfbfSEd Maste 
54234ba319b5SDimitry Andric     // If we had to start up a temporary private state thread to run this
54244ba319b5SDimitry Andric     // thread plan, shut it down now.
5425435933ddSDimitry Andric     if (backup_private_state_thread.IsJoinable()) {
5426ac7ddfbfSEd Maste       StopPrivateStateThread();
54275517e702SDimitry Andric       Status error;
5428ac7ddfbfSEd Maste       m_private_state_thread = backup_private_state_thread;
5429435933ddSDimitry Andric       if (stopper_base_plan_sp) {
5430ac7ddfbfSEd Maste         thread->DiscardThreadPlansUpToPlan(stopper_base_plan_sp);
5431ac7ddfbfSEd Maste       }
54327aa51b79SEd Maste       if (old_state != eStateInvalid)
5433ac7ddfbfSEd Maste         m_public_state.SetValueNoLock(old_state);
5434ac7ddfbfSEd Maste     }
5435ac7ddfbfSEd Maste 
5436435933ddSDimitry Andric     if (return_value != eExpressionCompleted && log) {
54379f2f44ceSEd Maste       // Print a backtrace into the log so we can figure out where we are:
54389f2f44ceSEd Maste       StreamString s;
54399f2f44ceSEd Maste       s.PutCString("Thread state after unsuccessful completion: \n");
5440435933ddSDimitry Andric       thread->GetStackFrameStatus(s, 0, UINT32_MAX, true, UINT32_MAX);
5441435933ddSDimitry Andric       log->PutString(s.GetString());
54429f2f44ceSEd Maste     }
5443435933ddSDimitry Andric     // Restore the thread state if we are going to discard the plan execution.
54444ba319b5SDimitry Andric     // There are three cases where this could happen: 1) The execution
54454ba319b5SDimitry Andric     // successfully completed 2) We hit a breakpoint, and ignore_breakpoints
54464ba319b5SDimitry Andric     // was true 3) We got some other error, and discard_on_error was true
5447435933ddSDimitry Andric     bool should_unwind = (return_value == eExpressionInterrupted &&
5448435933ddSDimitry Andric                           options.DoesUnwindOnError()) ||
5449435933ddSDimitry Andric                          (return_value == eExpressionHitBreakpoint &&
5450435933ddSDimitry Andric                           options.DoesIgnoreBreakpoints());
5451ac7ddfbfSEd Maste 
5452435933ddSDimitry Andric     if (return_value == eExpressionCompleted || should_unwind) {
5453ac7ddfbfSEd Maste       thread_plan_sp->RestoreThreadState();
5454ac7ddfbfSEd Maste     }
5455ac7ddfbfSEd Maste 
5456ac7ddfbfSEd Maste     // Now do some processing on the results of the run:
5457435933ddSDimitry Andric     if (return_value == eExpressionInterrupted ||
5458435933ddSDimitry Andric         return_value == eExpressionHitBreakpoint) {
5459435933ddSDimitry Andric       if (log) {
5460ac7ddfbfSEd Maste         StreamString s;
5461ac7ddfbfSEd Maste         if (event_sp)
5462ac7ddfbfSEd Maste           event_sp->Dump(&s);
5463435933ddSDimitry Andric         else {
5464435933ddSDimitry Andric           log->PutCString("Process::RunThreadPlan(): Stop event that "
5465435933ddSDimitry Andric                           "interrupted us is NULL.");
5466ac7ddfbfSEd Maste         }
5467ac7ddfbfSEd Maste 
5468ac7ddfbfSEd Maste         StreamString ts;
5469ac7ddfbfSEd Maste 
54704bb0738eSEd Maste         const char *event_explanation = nullptr;
5471ac7ddfbfSEd Maste 
5472435933ddSDimitry Andric         do {
5473435933ddSDimitry Andric           if (!event_sp) {
5474ac7ddfbfSEd Maste             event_explanation = "<no event>";
5475ac7ddfbfSEd Maste             break;
5476435933ddSDimitry Andric           } else if (event_sp->GetType() == eBroadcastBitInterrupt) {
5477ac7ddfbfSEd Maste             event_explanation = "<user interrupt>";
5478ac7ddfbfSEd Maste             break;
5479435933ddSDimitry Andric           } else {
5480435933ddSDimitry Andric             const Process::ProcessEventData *event_data =
5481435933ddSDimitry Andric                 Process::ProcessEventData::GetEventDataFromEvent(
5482435933ddSDimitry Andric                     event_sp.get());
5483ac7ddfbfSEd Maste 
5484435933ddSDimitry Andric             if (!event_data) {
5485ac7ddfbfSEd Maste               event_explanation = "<no event data>";
5486ac7ddfbfSEd Maste               break;
5487ac7ddfbfSEd Maste             }
5488ac7ddfbfSEd Maste 
5489ac7ddfbfSEd Maste             Process *process = event_data->GetProcessSP().get();
5490ac7ddfbfSEd Maste 
5491435933ddSDimitry Andric             if (!process) {
5492ac7ddfbfSEd Maste               event_explanation = "<no process>";
5493ac7ddfbfSEd Maste               break;
5494ac7ddfbfSEd Maste             }
5495ac7ddfbfSEd Maste 
5496ac7ddfbfSEd Maste             ThreadList &thread_list = process->GetThreadList();
5497ac7ddfbfSEd Maste 
5498ac7ddfbfSEd Maste             uint32_t num_threads = thread_list.GetSize();
5499ac7ddfbfSEd Maste             uint32_t thread_index;
5500ac7ddfbfSEd Maste 
5501ac7ddfbfSEd Maste             ts.Printf("<%u threads> ", num_threads);
5502ac7ddfbfSEd Maste 
5503435933ddSDimitry Andric             for (thread_index = 0; thread_index < num_threads; ++thread_index) {
5504ac7ddfbfSEd Maste               Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
5505ac7ddfbfSEd Maste 
5506435933ddSDimitry Andric               if (!thread) {
5507ac7ddfbfSEd Maste                 ts.Printf("<?> ");
5508ac7ddfbfSEd Maste                 continue;
5509ac7ddfbfSEd Maste               }
5510ac7ddfbfSEd Maste 
5511ac7ddfbfSEd Maste               ts.Printf("<0x%4.4" PRIx64 " ", thread->GetID());
5512435933ddSDimitry Andric               RegisterContext *register_context =
5513435933ddSDimitry Andric                   thread->GetRegisterContext().get();
5514ac7ddfbfSEd Maste 
5515ac7ddfbfSEd Maste               if (register_context)
5516ac7ddfbfSEd Maste                 ts.Printf("[ip 0x%" PRIx64 "] ", register_context->GetPC());
5517ac7ddfbfSEd Maste               else
5518ac7ddfbfSEd Maste                 ts.Printf("[ip unknown] ");
5519ac7ddfbfSEd Maste 
5520435933ddSDimitry Andric               // Show the private stop info here, the public stop info will be
5521435933ddSDimitry Andric               // from the last natural stop.
55229f2f44ceSEd Maste               lldb::StopInfoSP stop_info_sp = thread->GetPrivateStopInfo();
5523435933ddSDimitry Andric               if (stop_info_sp) {
5524ac7ddfbfSEd Maste                 const char *stop_desc = stop_info_sp->GetDescription();
5525ac7ddfbfSEd Maste                 if (stop_desc)
5526ac7ddfbfSEd Maste                   ts.PutCString(stop_desc);
5527ac7ddfbfSEd Maste               }
5528ac7ddfbfSEd Maste               ts.Printf(">");
5529ac7ddfbfSEd Maste             }
5530ac7ddfbfSEd Maste 
5531ac7ddfbfSEd Maste             event_explanation = ts.GetData();
5532ac7ddfbfSEd Maste           }
5533ac7ddfbfSEd Maste         } while (0);
5534ac7ddfbfSEd Maste 
5535ac7ddfbfSEd Maste         if (event_explanation)
5536435933ddSDimitry Andric           log->Printf("Process::RunThreadPlan(): execution interrupted: %s %s",
5537435933ddSDimitry Andric                       s.GetData(), event_explanation);
5538ac7ddfbfSEd Maste         else
5539435933ddSDimitry Andric           log->Printf("Process::RunThreadPlan(): execution interrupted: %s",
5540435933ddSDimitry Andric                       s.GetData());
5541ac7ddfbfSEd Maste       }
5542ac7ddfbfSEd Maste 
5543435933ddSDimitry Andric       if (should_unwind) {
5544ac7ddfbfSEd Maste         if (log)
5545435933ddSDimitry Andric           log->Printf("Process::RunThreadPlan: ExecutionInterrupted - "
5546435933ddSDimitry Andric                       "discarding thread plans up to %p.",
55470127ef0fSEd Maste                       static_cast<void *>(thread_plan_sp.get()));
5548ac7ddfbfSEd Maste         thread->DiscardThreadPlansUpToPlan(thread_plan_sp);
5549435933ddSDimitry Andric       } else {
5550ac7ddfbfSEd Maste         if (log)
5551435933ddSDimitry Andric           log->Printf("Process::RunThreadPlan: ExecutionInterrupted - for "
5552435933ddSDimitry Andric                       "plan: %p not discarding.",
55530127ef0fSEd Maste                       static_cast<void *>(thread_plan_sp.get()));
5554ac7ddfbfSEd Maste       }
5555435933ddSDimitry Andric     } else if (return_value == eExpressionSetupError) {
5556ac7ddfbfSEd Maste       if (log)
5557ac7ddfbfSEd Maste         log->PutCString("Process::RunThreadPlan(): execution set up error.");
5558ac7ddfbfSEd Maste 
5559435933ddSDimitry Andric       if (options.DoesUnwindOnError()) {
5560ac7ddfbfSEd Maste         thread->DiscardThreadPlansUpToPlan(thread_plan_sp);
5561ac7ddfbfSEd Maste       }
5562435933ddSDimitry Andric     } else {
5563435933ddSDimitry Andric       if (thread->IsThreadPlanDone(thread_plan_sp.get())) {
5564ac7ddfbfSEd Maste         if (log)
5565ac7ddfbfSEd Maste           log->PutCString("Process::RunThreadPlan(): thread plan is done");
55660127ef0fSEd Maste         return_value = eExpressionCompleted;
5567435933ddSDimitry Andric       } else if (thread->WasThreadPlanDiscarded(thread_plan_sp.get())) {
5568ac7ddfbfSEd Maste         if (log)
5569435933ddSDimitry Andric           log->PutCString(
5570435933ddSDimitry Andric               "Process::RunThreadPlan(): thread plan was discarded");
55710127ef0fSEd Maste         return_value = eExpressionDiscarded;
5572435933ddSDimitry Andric       } else {
5573ac7ddfbfSEd Maste         if (log)
5574435933ddSDimitry Andric           log->PutCString(
5575435933ddSDimitry Andric               "Process::RunThreadPlan(): thread plan stopped in mid course");
5576435933ddSDimitry Andric         if (options.DoesUnwindOnError() && thread_plan_sp) {
5577ac7ddfbfSEd Maste           if (log)
5578435933ddSDimitry Andric             log->PutCString("Process::RunThreadPlan(): discarding thread plan "
5579435933ddSDimitry Andric                             "'cause unwind_on_error is set.");
5580ac7ddfbfSEd Maste           thread->DiscardThreadPlansUpToPlan(thread_plan_sp);
5581ac7ddfbfSEd Maste         }
5582ac7ddfbfSEd Maste       }
5583ac7ddfbfSEd Maste     }
5584ac7ddfbfSEd Maste 
5585435933ddSDimitry Andric     // Thread we ran the function in may have gone away because we ran the
55864ba319b5SDimitry Andric     // target Check that it's still there, and if it is put it back in the
55874ba319b5SDimitry Andric     // context. Also restore the frame in the context if it is still present.
5588ac7ddfbfSEd Maste     thread = GetThreadList().FindThreadByIndexID(thread_idx_id, true).get();
5589435933ddSDimitry Andric     if (thread) {
5590ac7ddfbfSEd Maste       exe_ctx.SetFrameSP(thread->GetFrameWithStackID(ctx_frame_id));
5591ac7ddfbfSEd Maste     }
5592ac7ddfbfSEd Maste 
5593435933ddSDimitry Andric     // Also restore the current process'es selected frame & thread, since this
55944ba319b5SDimitry Andric     // function calling may be done behind the user's back.
5595ac7ddfbfSEd Maste 
5596435933ddSDimitry Andric     if (selected_tid != LLDB_INVALID_THREAD_ID) {
5597435933ddSDimitry Andric       if (GetThreadList().SetSelectedThreadByIndexID(selected_tid) &&
5598435933ddSDimitry Andric           selected_stack_id.IsValid()) {
5599ac7ddfbfSEd Maste         // We were able to restore the selected thread, now restore the frame:
56004bb0738eSEd Maste         std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex());
5601435933ddSDimitry Andric         StackFrameSP old_frame_sp =
5602435933ddSDimitry Andric             GetThreadList().GetSelectedThread()->GetFrameWithStackID(
5603435933ddSDimitry Andric                 selected_stack_id);
5604ac7ddfbfSEd Maste         if (old_frame_sp)
5605435933ddSDimitry Andric           GetThreadList().GetSelectedThread()->SetSelectedFrame(
5606435933ddSDimitry Andric               old_frame_sp.get());
5607ac7ddfbfSEd Maste       }
5608ac7ddfbfSEd Maste     }
5609ac7ddfbfSEd Maste   }
5610ac7ddfbfSEd Maste 
5611ac7ddfbfSEd Maste   // If the process exited during the run of the thread plan, notify everyone.
5612ac7ddfbfSEd Maste 
5613435933ddSDimitry Andric   if (event_to_broadcast_sp) {
5614ac7ddfbfSEd Maste     if (log)
5615ac7ddfbfSEd Maste       log->PutCString("Process::RunThreadPlan(): rebroadcasting event.");
5616ac7ddfbfSEd Maste     BroadcastEvent(event_to_broadcast_sp);
5617ac7ddfbfSEd Maste   }
5618ac7ddfbfSEd Maste 
5619ac7ddfbfSEd Maste   return return_value;
5620ac7ddfbfSEd Maste }
5621ac7ddfbfSEd Maste 
ExecutionResultAsCString(ExpressionResults result)5622435933ddSDimitry Andric const char *Process::ExecutionResultAsCString(ExpressionResults result) {
5623ac7ddfbfSEd Maste   const char *result_name;
5624ac7ddfbfSEd Maste 
5625435933ddSDimitry Andric   switch (result) {
56260127ef0fSEd Maste   case eExpressionCompleted:
56270127ef0fSEd Maste     result_name = "eExpressionCompleted";
5628ac7ddfbfSEd Maste     break;
56290127ef0fSEd Maste   case eExpressionDiscarded:
56300127ef0fSEd Maste     result_name = "eExpressionDiscarded";
5631ac7ddfbfSEd Maste     break;
56320127ef0fSEd Maste   case eExpressionInterrupted:
56330127ef0fSEd Maste     result_name = "eExpressionInterrupted";
5634ac7ddfbfSEd Maste     break;
56350127ef0fSEd Maste   case eExpressionHitBreakpoint:
56360127ef0fSEd Maste     result_name = "eExpressionHitBreakpoint";
5637ac7ddfbfSEd Maste     break;
56380127ef0fSEd Maste   case eExpressionSetupError:
56390127ef0fSEd Maste     result_name = "eExpressionSetupError";
5640ac7ddfbfSEd Maste     break;
56410127ef0fSEd Maste   case eExpressionParseError:
56420127ef0fSEd Maste     result_name = "eExpressionParseError";
5643ac7ddfbfSEd Maste     break;
56440127ef0fSEd Maste   case eExpressionResultUnavailable:
56450127ef0fSEd Maste     result_name = "eExpressionResultUnavailable";
56460127ef0fSEd Maste     break;
56470127ef0fSEd Maste   case eExpressionTimedOut:
56480127ef0fSEd Maste     result_name = "eExpressionTimedOut";
56490127ef0fSEd Maste     break;
56500127ef0fSEd Maste   case eExpressionStoppedForDebug:
56510127ef0fSEd Maste     result_name = "eExpressionStoppedForDebug";
5652b952cd58SEd Maste     break;
5653ac7ddfbfSEd Maste   }
5654ac7ddfbfSEd Maste   return result_name;
5655ac7ddfbfSEd Maste }
5656ac7ddfbfSEd Maste 
GetStatus(Stream & strm)5657435933ddSDimitry Andric void Process::GetStatus(Stream &strm) {
5658ac7ddfbfSEd Maste   const StateType state = GetState();
5659435933ddSDimitry Andric   if (StateIsStoppedState(state, false)) {
5660435933ddSDimitry Andric     if (state == eStateExited) {
5661ac7ddfbfSEd Maste       int exit_status = GetExitStatus();
5662ac7ddfbfSEd Maste       const char *exit_description = GetExitDescription();
5663ac7ddfbfSEd Maste       strm.Printf("Process %" PRIu64 " exited with status = %i (0x%8.8x) %s\n",
5664435933ddSDimitry Andric                   GetID(), exit_status, exit_status,
5665ac7ddfbfSEd Maste                   exit_description ? exit_description : "");
5666435933ddSDimitry Andric     } else {
5667ac7ddfbfSEd Maste       if (state == eStateConnected)
5668ac7ddfbfSEd Maste         strm.Printf("Connected to remote target.\n");
5669ac7ddfbfSEd Maste       else
5670ac7ddfbfSEd Maste         strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state));
5671ac7ddfbfSEd Maste     }
5672435933ddSDimitry Andric   } else {
5673ac7ddfbfSEd Maste     strm.Printf("Process %" PRIu64 " is running.\n", GetID());
5674ac7ddfbfSEd Maste   }
5675ac7ddfbfSEd Maste }
5676ac7ddfbfSEd Maste 
GetThreadStatus(Stream & strm,bool only_threads_with_stop_reason,uint32_t start_frame,uint32_t num_frames,uint32_t num_frames_with_source,bool stop_format)5677435933ddSDimitry Andric size_t Process::GetThreadStatus(Stream &strm,
5678ac7ddfbfSEd Maste                                 bool only_threads_with_stop_reason,
5679435933ddSDimitry Andric                                 uint32_t start_frame, uint32_t num_frames,
5680435933ddSDimitry Andric                                 uint32_t num_frames_with_source,
5681435933ddSDimitry Andric                                 bool stop_format) {
5682ac7ddfbfSEd Maste   size_t num_thread_infos_dumped = 0;
5683ac7ddfbfSEd Maste 
5684435933ddSDimitry Andric   // You can't hold the thread list lock while calling Thread::GetStatus.  That
56854ba319b5SDimitry Andric   // very well might run code (e.g. if we need it to get return values or
56864ba319b5SDimitry Andric   // arguments.)  For that to work the process has to be able to acquire it.
56874ba319b5SDimitry Andric   // So instead copy the thread ID's, and look them up one by one:
56880127ef0fSEd Maste 
56890127ef0fSEd Maste   uint32_t num_threads;
56907aa51b79SEd Maste   std::vector<lldb::tid_t> thread_id_array;
56910127ef0fSEd Maste   // Scope for thread list locker;
56920127ef0fSEd Maste   {
56934bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex());
56940127ef0fSEd Maste     ThreadList &curr_thread_list = GetThreadList();
56950127ef0fSEd Maste     num_threads = curr_thread_list.GetSize();
56960127ef0fSEd Maste     uint32_t idx;
56977aa51b79SEd Maste     thread_id_array.resize(num_threads);
56980127ef0fSEd Maste     for (idx = 0; idx < num_threads; ++idx)
56997aa51b79SEd Maste       thread_id_array[idx] = curr_thread_list.GetThreadAtIndex(idx)->GetID();
57000127ef0fSEd Maste   }
57010127ef0fSEd Maste 
5702435933ddSDimitry Andric   for (uint32_t i = 0; i < num_threads; i++) {
57037aa51b79SEd Maste     ThreadSP thread_sp(GetThreadList().FindThreadByID(thread_id_array[i]));
5704435933ddSDimitry Andric     if (thread_sp) {
5705435933ddSDimitry Andric       if (only_threads_with_stop_reason) {
57060127ef0fSEd Maste         StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
57074bb0738eSEd Maste         if (!stop_info_sp || !stop_info_sp->IsValid())
5708ac7ddfbfSEd Maste           continue;
5709ac7ddfbfSEd Maste       }
5710435933ddSDimitry Andric       thread_sp->GetStatus(strm, start_frame, num_frames,
5711435933ddSDimitry Andric                            num_frames_with_source,
5712435933ddSDimitry Andric                            stop_format);
5713ac7ddfbfSEd Maste       ++num_thread_infos_dumped;
5714435933ddSDimitry Andric     } else {
57150127ef0fSEd Maste       Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
57160127ef0fSEd Maste       if (log)
5717435933ddSDimitry Andric         log->Printf("Process::GetThreadStatus - thread 0x" PRIu64
5718435933ddSDimitry Andric                     " vanished while running Thread::GetStatus.");
57190127ef0fSEd Maste     }
5720ac7ddfbfSEd Maste   }
5721ac7ddfbfSEd Maste   return num_thread_infos_dumped;
5722ac7ddfbfSEd Maste }
5723ac7ddfbfSEd Maste 
AddInvalidMemoryRegion(const LoadRange & region)5724435933ddSDimitry Andric void Process::AddInvalidMemoryRegion(const LoadRange &region) {
5725ac7ddfbfSEd Maste   m_memory_cache.AddInvalidRange(region.GetRangeBase(), region.GetByteSize());
5726ac7ddfbfSEd Maste }
5727ac7ddfbfSEd Maste 
RemoveInvalidMemoryRange(const LoadRange & region)5728435933ddSDimitry Andric bool Process::RemoveInvalidMemoryRange(const LoadRange &region) {
5729435933ddSDimitry Andric   return m_memory_cache.RemoveInvalidRange(region.GetRangeBase(),
5730435933ddSDimitry Andric                                            region.GetByteSize());
5731ac7ddfbfSEd Maste }
5732ac7ddfbfSEd Maste 
AddPreResumeAction(PreResumeActionCallback callback,void * baton)5733435933ddSDimitry Andric void Process::AddPreResumeAction(PreResumeActionCallback callback,
5734435933ddSDimitry Andric                                  void *baton) {
5735ac7ddfbfSEd Maste   m_pre_resume_actions.push_back(PreResumeCallbackAndBaton(callback, baton));
5736ac7ddfbfSEd Maste }
5737ac7ddfbfSEd Maste 
RunPreResumeActions()5738435933ddSDimitry Andric bool Process::RunPreResumeActions() {
5739ac7ddfbfSEd Maste   bool result = true;
5740435933ddSDimitry Andric   while (!m_pre_resume_actions.empty()) {
5741ac7ddfbfSEd Maste     struct PreResumeCallbackAndBaton action = m_pre_resume_actions.back();
5742ac7ddfbfSEd Maste     m_pre_resume_actions.pop_back();
5743ac7ddfbfSEd Maste     bool this_result = action.callback(action.baton);
57444bb0738eSEd Maste     if (result)
57457aa51b79SEd Maste       result = this_result;
5746ac7ddfbfSEd Maste   }
5747ac7ddfbfSEd Maste   return result;
5748ac7ddfbfSEd Maste }
5749ac7ddfbfSEd Maste 
ClearPreResumeActions()5750435933ddSDimitry Andric void Process::ClearPreResumeActions() { m_pre_resume_actions.clear(); }
5751435933ddSDimitry Andric 
ClearPreResumeAction(PreResumeActionCallback callback,void * baton)5752435933ddSDimitry Andric void Process::ClearPreResumeAction(PreResumeActionCallback callback, void *baton)
5753ac7ddfbfSEd Maste {
5754435933ddSDimitry Andric     PreResumeCallbackAndBaton element(callback, baton);
5755435933ddSDimitry Andric     auto found_iter = std::find(m_pre_resume_actions.begin(), m_pre_resume_actions.end(), element);
5756435933ddSDimitry Andric     if (found_iter != m_pre_resume_actions.end())
5757435933ddSDimitry Andric     {
5758435933ddSDimitry Andric         m_pre_resume_actions.erase(found_iter);
5759435933ddSDimitry Andric     }
5760ac7ddfbfSEd Maste }
5761ac7ddfbfSEd Maste 
GetRunLock()5762435933ddSDimitry Andric ProcessRunLock &Process::GetRunLock() {
57631c3bbb01SEd Maste   if (m_private_state_thread.EqualsThread(Host::GetCurrentThread()))
57641c3bbb01SEd Maste     return m_private_run_lock;
57651c3bbb01SEd Maste   else
57661c3bbb01SEd Maste     return m_public_run_lock;
57671c3bbb01SEd Maste }
57681c3bbb01SEd Maste 
Flush()5769435933ddSDimitry Andric void Process::Flush() {
5770ac7ddfbfSEd Maste   m_thread_list.Flush();
577112b93ac6SEd Maste   m_extended_thread_list.Flush();
577212b93ac6SEd Maste   m_extended_thread_stop_id = 0;
577312b93ac6SEd Maste   m_queue_list.Clear();
577412b93ac6SEd Maste   m_queue_list_stop_id = 0;
5775ac7ddfbfSEd Maste }
5776ac7ddfbfSEd Maste 
DidExec()5777435933ddSDimitry Andric void Process::DidExec() {
57780127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
57790127ef0fSEd Maste   if (log)
57800127ef0fSEd Maste     log->Printf("Process::%s()", __FUNCTION__);
57810127ef0fSEd Maste 
5782ac7ddfbfSEd Maste   Target &target = GetTarget();
5783ac7ddfbfSEd Maste   target.CleanupProcess();
5784b952cd58SEd Maste   target.ClearModules(false);
5785ac7ddfbfSEd Maste   m_dynamic_checkers_ap.reset();
5786ac7ddfbfSEd Maste   m_abi_sp.reset();
578735617911SEd Maste   m_system_runtime_ap.reset();
5788ac7ddfbfSEd Maste   m_os_ap.reset();
5789ac7ddfbfSEd Maste   m_dyld_ap.reset();
57900127ef0fSEd Maste   m_jit_loaders_ap.reset();
5791ac7ddfbfSEd Maste   m_image_tokens.clear();
5792ac7ddfbfSEd Maste   m_allocated_memory_cache.Clear();
5793ac7ddfbfSEd Maste   m_language_runtimes.clear();
57947aa51b79SEd Maste   m_instrumentation_runtimes.clear();
5795ac7ddfbfSEd Maste   m_thread_list.DiscardThreadPlans();
5796ac7ddfbfSEd Maste   m_memory_cache.Clear(true);
5797ac7ddfbfSEd Maste   DoDidExec();
5798ac7ddfbfSEd Maste   CompleteAttach();
5799435933ddSDimitry Andric   // Flush the process (threads and all stack frames) after running
58004ba319b5SDimitry Andric   // CompleteAttach() in case the dynamic loader loaded things in new
58014ba319b5SDimitry Andric   // locations.
580235617911SEd Maste   Flush();
5803b952cd58SEd Maste 
58044ba319b5SDimitry Andric   // After we figure out what was loaded/unloaded in CompleteAttach, we need to
58054ba319b5SDimitry Andric   // let the target know so it can do any cleanup it needs to.
5806b952cd58SEd Maste   target.DidExec();
5807ac7ddfbfSEd Maste }
580835617911SEd Maste 
ResolveIndirectFunction(const Address * address,Status & error)58095517e702SDimitry Andric addr_t Process::ResolveIndirectFunction(const Address *address, Status &error) {
5810435933ddSDimitry Andric   if (address == nullptr) {
581112b93ac6SEd Maste     error.SetErrorString("Invalid address argument");
581212b93ac6SEd Maste     return LLDB_INVALID_ADDRESS;
581312b93ac6SEd Maste   }
581412b93ac6SEd Maste 
581512b93ac6SEd Maste   addr_t function_addr = LLDB_INVALID_ADDRESS;
581612b93ac6SEd Maste 
581712b93ac6SEd Maste   addr_t addr = address->GetLoadAddress(&GetTarget());
5818435933ddSDimitry Andric   std::map<addr_t, addr_t>::const_iterator iter =
5819435933ddSDimitry Andric       m_resolved_indirect_addresses.find(addr);
5820435933ddSDimitry Andric   if (iter != m_resolved_indirect_addresses.end()) {
582112b93ac6SEd Maste     function_addr = (*iter).second;
5822435933ddSDimitry Andric   } else {
5823435933ddSDimitry Andric     if (!InferiorCall(this, address, function_addr)) {
582412b93ac6SEd Maste       Symbol *symbol = address->CalculateSymbolContextSymbol();
5825435933ddSDimitry Andric       error.SetErrorStringWithFormat(
5826435933ddSDimitry Andric           "Unable to call resolver for indirect function %s",
582712b93ac6SEd Maste           symbol ? symbol->GetName().AsCString() : "<UNKNOWN>");
582812b93ac6SEd Maste       function_addr = LLDB_INVALID_ADDRESS;
5829435933ddSDimitry Andric     } else {
5830435933ddSDimitry Andric       m_resolved_indirect_addresses.insert(
5831435933ddSDimitry Andric           std::pair<addr_t, addr_t>(addr, function_addr));
583212b93ac6SEd Maste     }
583312b93ac6SEd Maste   }
583412b93ac6SEd Maste   return function_addr;
583512b93ac6SEd Maste }
583612b93ac6SEd Maste 
ModulesDidLoad(ModuleList & module_list)5837435933ddSDimitry Andric void Process::ModulesDidLoad(ModuleList &module_list) {
58380127ef0fSEd Maste   SystemRuntime *sys_runtime = GetSystemRuntime();
5839435933ddSDimitry Andric   if (sys_runtime) {
58400127ef0fSEd Maste     sys_runtime->ModulesDidLoad(module_list);
58410127ef0fSEd Maste   }
58420127ef0fSEd Maste 
58430127ef0fSEd Maste   GetJITLoaders().ModulesDidLoad(module_list);
58447aa51b79SEd Maste 
58457aa51b79SEd Maste   // Give runtimes a chance to be created.
5846435933ddSDimitry Andric   InstrumentationRuntime::ModulesDidLoad(module_list, this,
5847435933ddSDimitry Andric                                          m_instrumentation_runtimes);
58487aa51b79SEd Maste 
58497aa51b79SEd Maste   // Tell runtimes about new modules.
5850435933ddSDimitry Andric   for (auto pos = m_instrumentation_runtimes.begin();
5851435933ddSDimitry Andric        pos != m_instrumentation_runtimes.end(); ++pos) {
58527aa51b79SEd Maste     InstrumentationRuntimeSP runtime = pos->second;
58537aa51b79SEd Maste     runtime->ModulesDidLoad(module_list);
58547aa51b79SEd Maste   }
58557aa51b79SEd Maste 
58564ba319b5SDimitry Andric   // Let any language runtimes we have already created know about the modules
58574ba319b5SDimitry Andric   // that loaded.
58581c3bbb01SEd Maste 
58594ba319b5SDimitry Andric   // Iterate over a copy of this language runtime list in case the language
5860*b5893f02SDimitry Andric   // runtime ModulesDidLoad somehow causes the language runtime to be
58614ba319b5SDimitry Andric   // unloaded.
58621c3bbb01SEd Maste   LanguageRuntimeCollection language_runtimes(m_language_runtimes);
5863435933ddSDimitry Andric   for (const auto &pair : language_runtimes) {
58644ba319b5SDimitry Andric     // We must check language_runtime_sp to make sure it is not nullptr as we
58654ba319b5SDimitry Andric     // might cache the fact that we didn't have a language runtime for a
58664ba319b5SDimitry Andric     // language.
58671c3bbb01SEd Maste     LanguageRuntimeSP language_runtime_sp = pair.second;
58681c3bbb01SEd Maste     if (language_runtime_sp)
58691c3bbb01SEd Maste       language_runtime_sp->ModulesDidLoad(module_list);
58701c3bbb01SEd Maste   }
58719f2f44ceSEd Maste 
58724bb0738eSEd Maste   // If we don't have an operating system plug-in, try to load one since
58734bb0738eSEd Maste   // loading shared libraries might cause a new one to try and load
58744bb0738eSEd Maste   if (!m_os_ap)
58759f2f44ceSEd Maste     LoadOperatingSystemPlugin(false);
5876435933ddSDimitry Andric 
5877435933ddSDimitry Andric   // Give structured-data plugins a chance to see the modified modules.
5878435933ddSDimitry Andric   for (auto pair : m_structured_data_plugin_map) {
5879435933ddSDimitry Andric     if (pair.second)
5880435933ddSDimitry Andric       pair.second->ModulesDidLoad(*this, module_list);
5881435933ddSDimitry Andric   }
58829f2f44ceSEd Maste }
58839f2f44ceSEd Maste 
PrintWarning(uint64_t warning_type,const void * repeat_key,const char * fmt,...)5884435933ddSDimitry Andric void Process::PrintWarning(uint64_t warning_type, const void *repeat_key,
5885435933ddSDimitry Andric                            const char *fmt, ...) {
58869f2f44ceSEd Maste   bool print_warning = true;
58879f2f44ceSEd Maste 
58889f2f44ceSEd Maste   StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
58894bb0738eSEd Maste   if (!stream_sp)
58909f2f44ceSEd Maste     return;
5891435933ddSDimitry Andric   if (warning_type == eWarningsOptimization && !GetWarningsOptimization()) {
58929f2f44ceSEd Maste     return;
58939f2f44ceSEd Maste   }
58949f2f44ceSEd Maste 
5895435933ddSDimitry Andric   if (repeat_key != nullptr) {
58969f2f44ceSEd Maste     WarningsCollection::iterator it = m_warnings_issued.find(warning_type);
5897435933ddSDimitry Andric     if (it == m_warnings_issued.end()) {
58989f2f44ceSEd Maste       m_warnings_issued[warning_type] = WarningsPointerSet();
58999f2f44ceSEd Maste       m_warnings_issued[warning_type].insert(repeat_key);
5900435933ddSDimitry Andric     } else {
5901435933ddSDimitry Andric       if (it->second.find(repeat_key) != it->second.end()) {
59029f2f44ceSEd Maste         print_warning = false;
5903435933ddSDimitry Andric       } else {
59049f2f44ceSEd Maste         it->second.insert(repeat_key);
59059f2f44ceSEd Maste       }
59069f2f44ceSEd Maste     }
59079f2f44ceSEd Maste   }
59089f2f44ceSEd Maste 
5909435933ddSDimitry Andric   if (print_warning) {
59109f2f44ceSEd Maste     va_list args;
59119f2f44ceSEd Maste     va_start(args, fmt);
59129f2f44ceSEd Maste     stream_sp->PrintfVarArg(fmt, args);
59139f2f44ceSEd Maste     va_end(args);
59149f2f44ceSEd Maste   }
59159f2f44ceSEd Maste }
59169f2f44ceSEd Maste 
PrintWarningOptimization(const SymbolContext & sc)5917435933ddSDimitry Andric void Process::PrintWarningOptimization(const SymbolContext &sc) {
5918435933ddSDimitry Andric   if (GetWarningsOptimization() && sc.module_sp &&
5919435933ddSDimitry Andric       !sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function &&
5920435933ddSDimitry Andric       sc.function->GetIsOptimized()) {
5921435933ddSDimitry Andric     PrintWarning(Process::Warnings::eWarningsOptimization, sc.module_sp.get(),
5922435933ddSDimitry Andric                  "%s was compiled with optimization - stepping may behave "
5923435933ddSDimitry Andric                  "oddly; variables may not be available.\n",
5924435933ddSDimitry Andric                  sc.module_sp->GetFileSpec().GetFilename().GetCString());
59259f2f44ceSEd Maste   }
59267aa51b79SEd Maste }
59277aa51b79SEd Maste 
GetProcessInfo(ProcessInstanceInfo & info)5928435933ddSDimitry Andric bool Process::GetProcessInfo(ProcessInstanceInfo &info) {
59294bb0738eSEd Maste   info.Clear();
59304bb0738eSEd Maste 
59314bb0738eSEd Maste   PlatformSP platform_sp = GetTarget().GetPlatform();
59324bb0738eSEd Maste   if (!platform_sp)
59334bb0738eSEd Maste     return false;
59344bb0738eSEd Maste 
59354bb0738eSEd Maste   return platform_sp->GetProcessInfo(GetID(), info);
59364bb0738eSEd Maste }
59374bb0738eSEd Maste 
GetHistoryThreads(lldb::addr_t addr)5938435933ddSDimitry Andric ThreadCollectionSP Process::GetHistoryThreads(lldb::addr_t addr) {
59397aa51b79SEd Maste   ThreadCollectionSP threads;
59407aa51b79SEd Maste 
5941435933ddSDimitry Andric   const MemoryHistorySP &memory_history =
5942435933ddSDimitry Andric       MemoryHistory::FindPlugin(shared_from_this());
59437aa51b79SEd Maste 
59444bb0738eSEd Maste   if (!memory_history) {
59457aa51b79SEd Maste     return threads;
59467aa51b79SEd Maste   }
59477aa51b79SEd Maste 
59487aa51b79SEd Maste   threads.reset(new ThreadCollection(memory_history->GetHistoryThreads(addr)));
59497aa51b79SEd Maste 
59507aa51b79SEd Maste   return threads;
59517aa51b79SEd Maste }
59527aa51b79SEd Maste 
59537aa51b79SEd Maste InstrumentationRuntimeSP
GetInstrumentationRuntime(lldb::InstrumentationRuntimeType type)5954435933ddSDimitry Andric Process::GetInstrumentationRuntime(lldb::InstrumentationRuntimeType type) {
59557aa51b79SEd Maste   InstrumentationRuntimeCollection::iterator pos;
59567aa51b79SEd Maste   pos = m_instrumentation_runtimes.find(type);
5957435933ddSDimitry Andric   if (pos == m_instrumentation_runtimes.end()) {
59587aa51b79SEd Maste     return InstrumentationRuntimeSP();
5959435933ddSDimitry Andric   } else
59607aa51b79SEd Maste     return (*pos).second;
59610127ef0fSEd Maste }
59621c3bbb01SEd Maste 
GetModuleSpec(const FileSpec & module_file_spec,const ArchSpec & arch,ModuleSpec & module_spec)5963435933ddSDimitry Andric bool Process::GetModuleSpec(const FileSpec &module_file_spec,
5964435933ddSDimitry Andric                             const ArchSpec &arch, ModuleSpec &module_spec) {
59651c3bbb01SEd Maste   module_spec.Clear();
59661c3bbb01SEd Maste   return false;
59671c3bbb01SEd Maste }
59689f2f44ceSEd Maste 
AddImageToken(lldb::addr_t image_ptr)5969435933ddSDimitry Andric size_t Process::AddImageToken(lldb::addr_t image_ptr) {
59709f2f44ceSEd Maste   m_image_tokens.push_back(image_ptr);
59719f2f44ceSEd Maste   return m_image_tokens.size() - 1;
59729f2f44ceSEd Maste }
59739f2f44ceSEd Maste 
GetImagePtrFromToken(size_t token) const5974435933ddSDimitry Andric lldb::addr_t Process::GetImagePtrFromToken(size_t token) const {
59759f2f44ceSEd Maste   if (token < m_image_tokens.size())
59769f2f44ceSEd Maste     return m_image_tokens[token];
59779f2f44ceSEd Maste   return LLDB_INVALID_IMAGE_TOKEN;
59789f2f44ceSEd Maste }
59799f2f44ceSEd Maste 
ResetImageToken(size_t token)5980435933ddSDimitry Andric void Process::ResetImageToken(size_t token) {
59819f2f44ceSEd Maste   if (token < m_image_tokens.size())
59829f2f44ceSEd Maste     m_image_tokens[token] = LLDB_INVALID_IMAGE_TOKEN;
59839f2f44ceSEd Maste }
5984444ed5c5SDimitry Andric 
5985444ed5c5SDimitry Andric Address
AdvanceAddressToNextBranchInstruction(Address default_stop_addr,AddressRange range_bounds)5986435933ddSDimitry Andric Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
5987435933ddSDimitry Andric                                                AddressRange range_bounds) {
5988444ed5c5SDimitry Andric   Target &target = GetTarget();
5989444ed5c5SDimitry Andric   DisassemblerSP disassembler_sp;
59904bb0738eSEd Maste   InstructionList *insn_list = nullptr;
5991444ed5c5SDimitry Andric 
5992444ed5c5SDimitry Andric   Address retval = default_stop_addr;
5993444ed5c5SDimitry Andric 
59944bb0738eSEd Maste   if (!target.GetUseFastStepping())
5995444ed5c5SDimitry Andric     return retval;
59964bb0738eSEd Maste   if (!default_stop_addr.IsValid())
5997444ed5c5SDimitry Andric     return retval;
5998444ed5c5SDimitry Andric 
5999444ed5c5SDimitry Andric   ExecutionContext exe_ctx(this);
6000444ed5c5SDimitry Andric   const char *plugin_name = nullptr;
6001444ed5c5SDimitry Andric   const char *flavor = nullptr;
6002444ed5c5SDimitry Andric   const bool prefer_file_cache = true;
6003435933ddSDimitry Andric   disassembler_sp = Disassembler::DisassembleRange(
6004435933ddSDimitry Andric       target.GetArchitecture(), plugin_name, flavor, exe_ctx, range_bounds,
6005444ed5c5SDimitry Andric       prefer_file_cache);
60064bb0738eSEd Maste   if (disassembler_sp)
6007444ed5c5SDimitry Andric     insn_list = &disassembler_sp->GetInstructionList();
6008444ed5c5SDimitry Andric 
6009435933ddSDimitry Andric   if (insn_list == nullptr) {
6010444ed5c5SDimitry Andric     return retval;
6011444ed5c5SDimitry Andric   }
6012444ed5c5SDimitry Andric 
6013435933ddSDimitry Andric   size_t insn_offset =
6014435933ddSDimitry Andric       insn_list->GetIndexOfInstructionAtAddress(default_stop_addr);
6015435933ddSDimitry Andric   if (insn_offset == UINT32_MAX) {
6016444ed5c5SDimitry Andric     return retval;
6017444ed5c5SDimitry Andric   }
6018444ed5c5SDimitry Andric 
6019435933ddSDimitry Andric   uint32_t branch_index =
6020435933ddSDimitry Andric       insn_list->GetIndexOfNextBranchInstruction(insn_offset, target);
6021435933ddSDimitry Andric   if (branch_index == UINT32_MAX) {
6022444ed5c5SDimitry Andric     return retval;
6023444ed5c5SDimitry Andric   }
6024444ed5c5SDimitry Andric 
6025435933ddSDimitry Andric   if (branch_index > insn_offset) {
6026435933ddSDimitry Andric     Address next_branch_insn_address =
6027435933ddSDimitry Andric         insn_list->GetInstructionAtIndex(branch_index)->GetAddress();
6028435933ddSDimitry Andric     if (next_branch_insn_address.IsValid() &&
6029435933ddSDimitry Andric         range_bounds.ContainsFileAddress(next_branch_insn_address)) {
6030444ed5c5SDimitry Andric       retval = next_branch_insn_address;
6031444ed5c5SDimitry Andric     }
6032444ed5c5SDimitry Andric   }
6033444ed5c5SDimitry Andric 
60344bb0738eSEd Maste   return retval;
6035444ed5c5SDimitry Andric }
6036444ed5c5SDimitry Andric 
60375517e702SDimitry Andric Status
GetMemoryRegions(lldb_private::MemoryRegionInfos & region_list)6038*b5893f02SDimitry Andric Process::GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) {
60394bb0738eSEd Maste 
60405517e702SDimitry Andric   Status error;
60414bb0738eSEd Maste 
60424bb0738eSEd Maste   lldb::addr_t range_end = 0;
60434bb0738eSEd Maste 
60444bb0738eSEd Maste   region_list.clear();
6045435933ddSDimitry Andric   do {
6046*b5893f02SDimitry Andric     lldb_private::MemoryRegionInfo region_info;
6047*b5893f02SDimitry Andric     error = GetMemoryRegionInfo(range_end, region_info);
60484bb0738eSEd Maste     // GetMemoryRegionInfo should only return an error if it is unimplemented.
6049435933ddSDimitry Andric     if (error.Fail()) {
60504bb0738eSEd Maste       region_list.clear();
60514bb0738eSEd Maste       break;
60524bb0738eSEd Maste     }
60534bb0738eSEd Maste 
6054*b5893f02SDimitry Andric     range_end = region_info.GetRange().GetRangeEnd();
6055*b5893f02SDimitry Andric     if (region_info.GetMapped() == MemoryRegionInfo::eYes) {
6056*b5893f02SDimitry Andric       region_list.push_back(std::move(region_info));
60574bb0738eSEd Maste     }
60584bb0738eSEd Maste   } while (range_end != LLDB_INVALID_ADDRESS);
60594bb0738eSEd Maste 
60604bb0738eSEd Maste   return error;
6061435933ddSDimitry Andric }
60624bb0738eSEd Maste 
60635517e702SDimitry Andric Status
ConfigureStructuredData(const ConstString & type_name,const StructuredData::ObjectSP & config_sp)60645517e702SDimitry Andric Process::ConfigureStructuredData(const ConstString &type_name,
60655517e702SDimitry Andric                                  const StructuredData::ObjectSP &config_sp) {
60664ba319b5SDimitry Andric   // If you get this, the Process-derived class needs to implement a method to
60674ba319b5SDimitry Andric   // enable an already-reported asynchronous structured data feature. See
60684ba319b5SDimitry Andric   // ProcessGDBRemote for an example implementation over gdb-remote.
60695517e702SDimitry Andric   return Status("unimplemented");
6070435933ddSDimitry Andric }
6071435933ddSDimitry Andric 
MapSupportedStructuredDataPlugins(const StructuredData::Array & supported_type_names)6072435933ddSDimitry Andric void Process::MapSupportedStructuredDataPlugins(
6073435933ddSDimitry Andric     const StructuredData::Array &supported_type_names) {
6074435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
6075435933ddSDimitry Andric 
6076435933ddSDimitry Andric   // Bail out early if there are no type names to map.
6077435933ddSDimitry Andric   if (supported_type_names.GetSize() == 0) {
6078435933ddSDimitry Andric     if (log)
6079435933ddSDimitry Andric       log->Printf("Process::%s(): no structured data types supported",
6080435933ddSDimitry Andric                   __FUNCTION__);
6081435933ddSDimitry Andric     return;
6082435933ddSDimitry Andric   }
6083435933ddSDimitry Andric 
6084435933ddSDimitry Andric   // Convert StructuredData type names to ConstString instances.
6085435933ddSDimitry Andric   std::set<ConstString> const_type_names;
6086435933ddSDimitry Andric 
6087435933ddSDimitry Andric   if (log)
6088435933ddSDimitry Andric     log->Printf("Process::%s(): the process supports the following async "
6089435933ddSDimitry Andric                 "structured data types:",
6090435933ddSDimitry Andric                 __FUNCTION__);
6091435933ddSDimitry Andric 
6092435933ddSDimitry Andric   supported_type_names.ForEach(
6093435933ddSDimitry Andric       [&const_type_names, &log](StructuredData::Object *object) {
6094435933ddSDimitry Andric         if (!object) {
6095435933ddSDimitry Andric           // Invalid - shouldn't be null objects in the array.
6096435933ddSDimitry Andric           return false;
6097435933ddSDimitry Andric         }
6098435933ddSDimitry Andric 
6099435933ddSDimitry Andric         auto type_name = object->GetAsString();
6100435933ddSDimitry Andric         if (!type_name) {
6101435933ddSDimitry Andric           // Invalid format - all type names should be strings.
6102435933ddSDimitry Andric           return false;
6103435933ddSDimitry Andric         }
6104435933ddSDimitry Andric 
6105435933ddSDimitry Andric         const_type_names.insert(ConstString(type_name->GetValue()));
61065517e702SDimitry Andric         LLDB_LOG(log, "- {0}", type_name->GetValue());
6107435933ddSDimitry Andric         return true;
6108435933ddSDimitry Andric       });
6109435933ddSDimitry Andric 
61104ba319b5SDimitry Andric   // For each StructuredDataPlugin, if the plugin handles any of the types in
61114ba319b5SDimitry Andric   // the supported_type_names, map that type name to that plugin. Stop when
61124ba319b5SDimitry Andric   // we've consumed all the type names.
61134ba319b5SDimitry Andric   // FIXME: should we return an error if there are type names nobody
61144ba319b5SDimitry Andric   // supports?
61154ba319b5SDimitry Andric   for (uint32_t plugin_index = 0; !const_type_names.empty(); plugin_index++) {
61164ba319b5SDimitry Andric     auto create_instance =
6117435933ddSDimitry Andric            PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(
6118435933ddSDimitry Andric                plugin_index);
61194ba319b5SDimitry Andric     if (!create_instance)
61204ba319b5SDimitry Andric       break;
61214ba319b5SDimitry Andric 
6122435933ddSDimitry Andric     // Create the plugin.
6123435933ddSDimitry Andric     StructuredDataPluginSP plugin_sp = (*create_instance)(*this);
6124435933ddSDimitry Andric     if (!plugin_sp) {
61254ba319b5SDimitry Andric       // This plugin doesn't think it can work with the process. Move on to the
61264ba319b5SDimitry Andric       // next.
6127435933ddSDimitry Andric       continue;
6128435933ddSDimitry Andric     }
6129435933ddSDimitry Andric 
61304ba319b5SDimitry Andric     // For any of the remaining type names, map any that this plugin supports.
6131435933ddSDimitry Andric     std::vector<ConstString> names_to_remove;
6132435933ddSDimitry Andric     for (auto &type_name : const_type_names) {
6133435933ddSDimitry Andric       if (plugin_sp->SupportsStructuredDataType(type_name)) {
6134435933ddSDimitry Andric         m_structured_data_plugin_map.insert(
6135435933ddSDimitry Andric             std::make_pair(type_name, plugin_sp));
6136435933ddSDimitry Andric         names_to_remove.push_back(type_name);
6137435933ddSDimitry Andric         if (log)
6138435933ddSDimitry Andric           log->Printf("Process::%s(): using plugin %s for type name "
6139435933ddSDimitry Andric                       "%s",
6140435933ddSDimitry Andric                       __FUNCTION__, plugin_sp->GetPluginName().GetCString(),
6141435933ddSDimitry Andric                       type_name.GetCString());
6142435933ddSDimitry Andric       }
6143435933ddSDimitry Andric     }
6144435933ddSDimitry Andric 
6145435933ddSDimitry Andric     // Remove the type names that were consumed by this plugin.
6146435933ddSDimitry Andric     for (auto &type_name : names_to_remove)
6147435933ddSDimitry Andric       const_type_names.erase(type_name);
6148435933ddSDimitry Andric   }
6149435933ddSDimitry Andric }
6150435933ddSDimitry Andric 
RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)6151435933ddSDimitry Andric bool Process::RouteAsyncStructuredData(
6152435933ddSDimitry Andric     const StructuredData::ObjectSP object_sp) {
6153435933ddSDimitry Andric   // Nothing to do if there's no data.
6154435933ddSDimitry Andric   if (!object_sp)
6155435933ddSDimitry Andric     return false;
6156435933ddSDimitry Andric 
61574ba319b5SDimitry Andric   // The contract is this must be a dictionary, so we can look up the routing
61584ba319b5SDimitry Andric   // key via the top-level 'type' string value within the dictionary.
6159435933ddSDimitry Andric   StructuredData::Dictionary *dictionary = object_sp->GetAsDictionary();
6160435933ddSDimitry Andric   if (!dictionary)
6161435933ddSDimitry Andric     return false;
6162435933ddSDimitry Andric 
6163435933ddSDimitry Andric   // Grab the async structured type name (i.e. the feature/plugin name).
6164435933ddSDimitry Andric   ConstString type_name;
6165435933ddSDimitry Andric   if (!dictionary->GetValueForKeyAsString("type", type_name))
6166435933ddSDimitry Andric     return false;
6167435933ddSDimitry Andric 
6168435933ddSDimitry Andric   // Check if there's a plugin registered for this type name.
6169435933ddSDimitry Andric   auto find_it = m_structured_data_plugin_map.find(type_name);
6170435933ddSDimitry Andric   if (find_it == m_structured_data_plugin_map.end()) {
6171435933ddSDimitry Andric     // We don't have a mapping for this structured data type.
6172435933ddSDimitry Andric     return false;
6173435933ddSDimitry Andric   }
6174435933ddSDimitry Andric 
6175435933ddSDimitry Andric   // Route the structured data to the plugin.
6176435933ddSDimitry Andric   find_it->second->HandleArrivalOfStructuredData(*this, type_name, object_sp);
6177435933ddSDimitry Andric   return true;
6178444ed5c5SDimitry Andric }
6179f678e45dSDimitry Andric 
UpdateAutomaticSignalFiltering()61805517e702SDimitry Andric Status Process::UpdateAutomaticSignalFiltering() {
6181f678e45dSDimitry Andric   // Default implementation does nothign.
6182f678e45dSDimitry Andric   // No automatic signal filtering to speak of.
61835517e702SDimitry Andric   return Status();
6184f678e45dSDimitry Andric }
61854ba319b5SDimitry Andric 
GetLoadImageUtilityFunction(Platform * platform,llvm::function_ref<std::unique_ptr<UtilityFunction> ()> factory)61864ba319b5SDimitry Andric UtilityFunction *Process::GetLoadImageUtilityFunction(
61874ba319b5SDimitry Andric     Platform *platform,
61884ba319b5SDimitry Andric     llvm::function_ref<std::unique_ptr<UtilityFunction>()> factory) {
61894ba319b5SDimitry Andric   if (platform != GetTarget().GetPlatform().get())
61904ba319b5SDimitry Andric     return nullptr;
61914ba319b5SDimitry Andric   std::call_once(m_dlopen_utility_func_flag_once,
61924ba319b5SDimitry Andric                  [&] { m_dlopen_utility_func_up = factory(); });
61934ba319b5SDimitry Andric   return m_dlopen_utility_func_up.get();
61944ba319b5SDimitry Andric }
6195