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 ®ion) {
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 ®ion) {
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 ®ion_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