File: | build/source/lldb/source/Target/Process.cpp |
Warning: | line 5492, column 15 Value stored to 'result_name' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- Process.cpp -------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include <atomic> |
10 | #include <memory> |
11 | #include <mutex> |
12 | #include <optional> |
13 | |
14 | #include "llvm/ADT/ScopeExit.h" |
15 | #include "llvm/Support/ScopedPrinter.h" |
16 | #include "llvm/Support/Threading.h" |
17 | |
18 | #include "lldb/Breakpoint/BreakpointLocation.h" |
19 | #include "lldb/Breakpoint/StoppointCallbackContext.h" |
20 | #include "lldb/Core/Debugger.h" |
21 | #include "lldb/Core/Module.h" |
22 | #include "lldb/Core/ModuleSpec.h" |
23 | #include "lldb/Core/PluginManager.h" |
24 | #include "lldb/Core/StreamFile.h" |
25 | #include "lldb/Expression/DiagnosticManager.h" |
26 | #include "lldb/Expression/DynamicCheckerFunctions.h" |
27 | #include "lldb/Expression/UserExpression.h" |
28 | #include "lldb/Expression/UtilityFunction.h" |
29 | #include "lldb/Host/ConnectionFileDescriptor.h" |
30 | #include "lldb/Host/FileSystem.h" |
31 | #include "lldb/Host/Host.h" |
32 | #include "lldb/Host/HostInfo.h" |
33 | #include "lldb/Host/OptionParser.h" |
34 | #include "lldb/Host/Pipe.h" |
35 | #include "lldb/Host/Terminal.h" |
36 | #include "lldb/Host/ThreadLauncher.h" |
37 | #include "lldb/Interpreter/CommandInterpreter.h" |
38 | #include "lldb/Interpreter/OptionArgParser.h" |
39 | #include "lldb/Interpreter/OptionValueProperties.h" |
40 | #include "lldb/Symbol/Function.h" |
41 | #include "lldb/Symbol/Symbol.h" |
42 | #include "lldb/Target/ABI.h" |
43 | #include "lldb/Target/AssertFrameRecognizer.h" |
44 | #include "lldb/Target/DynamicLoader.h" |
45 | #include "lldb/Target/InstrumentationRuntime.h" |
46 | #include "lldb/Target/JITLoader.h" |
47 | #include "lldb/Target/JITLoaderList.h" |
48 | #include "lldb/Target/Language.h" |
49 | #include "lldb/Target/LanguageRuntime.h" |
50 | #include "lldb/Target/MemoryHistory.h" |
51 | #include "lldb/Target/MemoryRegionInfo.h" |
52 | #include "lldb/Target/OperatingSystem.h" |
53 | #include "lldb/Target/Platform.h" |
54 | #include "lldb/Target/Process.h" |
55 | #include "lldb/Target/RegisterContext.h" |
56 | #include "lldb/Target/StopInfo.h" |
57 | #include "lldb/Target/StructuredDataPlugin.h" |
58 | #include "lldb/Target/SystemRuntime.h" |
59 | #include "lldb/Target/Target.h" |
60 | #include "lldb/Target/TargetList.h" |
61 | #include "lldb/Target/Thread.h" |
62 | #include "lldb/Target/ThreadPlan.h" |
63 | #include "lldb/Target/ThreadPlanBase.h" |
64 | #include "lldb/Target/ThreadPlanCallFunction.h" |
65 | #include "lldb/Target/ThreadPlanStack.h" |
66 | #include "lldb/Target/UnixSignals.h" |
67 | #include "lldb/Utility/Event.h" |
68 | #include "lldb/Utility/LLDBLog.h" |
69 | #include "lldb/Utility/Log.h" |
70 | #include "lldb/Utility/NameMatches.h" |
71 | #include "lldb/Utility/ProcessInfo.h" |
72 | #include "lldb/Utility/SelectHelper.h" |
73 | #include "lldb/Utility/State.h" |
74 | #include "lldb/Utility/Timer.h" |
75 | |
76 | using namespace lldb; |
77 | using namespace lldb_private; |
78 | using namespace std::chrono; |
79 | |
80 | // Comment out line below to disable memory caching, overriding the process |
81 | // setting target.process.disable-memory-cache |
82 | #define ENABLE_MEMORY_CACHING |
83 | |
84 | #ifdef ENABLE_MEMORY_CACHING |
85 | #define DISABLE_MEM_CACHE_DEFAULTfalse false |
86 | #else |
87 | #define DISABLE_MEM_CACHE_DEFAULTfalse true |
88 | #endif |
89 | |
90 | class ProcessOptionValueProperties |
91 | : public Cloneable<ProcessOptionValueProperties, OptionValueProperties> { |
92 | public: |
93 | ProcessOptionValueProperties(ConstString name) : Cloneable(name) {} |
94 | |
95 | const Property * |
96 | GetPropertyAtIndex(uint32_t idx, |
97 | const ExecutionContext *exe_ctx) const override { |
98 | // When getting the value for a key from the process options, we will |
99 | // always try and grab the setting from the current process if there is |
100 | // one. Else we just use the one from this instance. |
101 | if (exe_ctx) { |
102 | Process *process = exe_ctx->GetProcessPtr(); |
103 | if (process) { |
104 | ProcessOptionValueProperties *instance_properties = |
105 | static_cast<ProcessOptionValueProperties *>( |
106 | process->GetValueProperties().get()); |
107 | if (this != instance_properties) |
108 | return instance_properties->ProtectedGetPropertyAtIndex(idx); |
109 | } |
110 | } |
111 | return ProtectedGetPropertyAtIndex(idx); |
112 | } |
113 | }; |
114 | |
115 | static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = { |
116 | { |
117 | eFollowParent, |
118 | "parent", |
119 | "Continue tracing the parent process and detach the child.", |
120 | }, |
121 | { |
122 | eFollowChild, |
123 | "child", |
124 | "Trace the child process and detach the parent.", |
125 | }, |
126 | }; |
127 | |
128 | #define LLDB_PROPERTIES_process |
129 | #include "TargetProperties.inc" |
130 | |
131 | enum { |
132 | #define LLDB_PROPERTIES_process |
133 | #include "TargetPropertiesEnum.inc" |
134 | ePropertyExperimental, |
135 | }; |
136 | |
137 | #define LLDB_PROPERTIES_process_experimental |
138 | #include "TargetProperties.inc" |
139 | |
140 | enum { |
141 | #define LLDB_PROPERTIES_process_experimental |
142 | #include "TargetPropertiesEnum.inc" |
143 | }; |
144 | |
145 | class ProcessExperimentalOptionValueProperties |
146 | : public Cloneable<ProcessExperimentalOptionValueProperties, |
147 | OptionValueProperties> { |
148 | public: |
149 | ProcessExperimentalOptionValueProperties() |
150 | : Cloneable( |
151 | ConstString(Properties::GetExperimentalSettingsName())) {} |
152 | }; |
153 | |
154 | ProcessExperimentalProperties::ProcessExperimentalProperties() |
155 | : Properties(OptionValuePropertiesSP( |
156 | new ProcessExperimentalOptionValueProperties())) { |
157 | m_collection_sp->Initialize(g_process_experimental_properties); |
158 | } |
159 | |
160 | ProcessProperties::ProcessProperties(lldb_private::Process *process) |
161 | : Properties(), |
162 | m_process(process) // Can be nullptr for global ProcessProperties |
163 | { |
164 | if (process == nullptr) { |
165 | // Global process properties, set them up one time |
166 | m_collection_sp = |
167 | std::make_shared<ProcessOptionValueProperties>(ConstString("process")); |
168 | m_collection_sp->Initialize(g_process_properties); |
169 | m_collection_sp->AppendProperty( |
170 | ConstString("thread"), "Settings specific to threads.", true, |
171 | Thread::GetGlobalProperties().GetValueProperties()); |
172 | } else { |
173 | m_collection_sp = |
174 | OptionValueProperties::CreateLocalCopy(Process::GetGlobalProperties()); |
175 | m_collection_sp->SetValueChangedCallback( |
176 | ePropertyPythonOSPluginPath, |
177 | [this] { m_process->LoadOperatingSystemPlugin(true); }); |
178 | } |
179 | |
180 | m_experimental_properties_up = |
181 | std::make_unique<ProcessExperimentalProperties>(); |
182 | m_collection_sp->AppendProperty( |
183 | ConstString(Properties::GetExperimentalSettingsName()), |
184 | "Experimental settings - setting these won't produce " |
185 | "errors if the setting is not present.", |
186 | true, m_experimental_properties_up->GetValueProperties()); |
187 | } |
188 | |
189 | ProcessProperties::~ProcessProperties() = default; |
190 | |
191 | bool ProcessProperties::GetDisableMemoryCache() const { |
192 | const uint32_t idx = ePropertyDisableMemCache; |
193 | return GetPropertyAtIndexAs<bool>( |
194 | idx, g_process_properties[idx].default_uint_value != 0); |
195 | } |
196 | |
197 | uint64_t ProcessProperties::GetMemoryCacheLineSize() const { |
198 | const uint32_t idx = ePropertyMemCacheLineSize; |
199 | return GetPropertyAtIndexAs<uint64_t>( |
200 | idx, g_process_properties[idx].default_uint_value); |
201 | } |
202 | |
203 | Args ProcessProperties::GetExtraStartupCommands() const { |
204 | Args args; |
205 | const uint32_t idx = ePropertyExtraStartCommand; |
206 | m_collection_sp->GetPropertyAtIndexAsArgs(idx, args); |
207 | return args; |
208 | } |
209 | |
210 | void ProcessProperties::SetExtraStartupCommands(const Args &args) { |
211 | const uint32_t idx = ePropertyExtraStartCommand; |
212 | m_collection_sp->SetPropertyAtIndexFromArgs(idx, args); |
213 | } |
214 | |
215 | FileSpec ProcessProperties::GetPythonOSPluginPath() const { |
216 | const uint32_t idx = ePropertyPythonOSPluginPath; |
217 | return GetPropertyAtIndexAs<FileSpec>(idx, {}); |
218 | } |
219 | |
220 | uint32_t ProcessProperties::GetVirtualAddressableBits() const { |
221 | const uint32_t idx = ePropertyVirtualAddressableBits; |
222 | return GetPropertyAtIndexAs<uint64_t>( |
223 | idx, g_process_properties[idx].default_uint_value); |
224 | } |
225 | |
226 | void ProcessProperties::SetVirtualAddressableBits(uint32_t bits) { |
227 | const uint32_t idx = ePropertyVirtualAddressableBits; |
228 | SetPropertyAtIndex(idx, bits); |
229 | } |
230 | void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) { |
231 | const uint32_t idx = ePropertyPythonOSPluginPath; |
232 | SetPropertyAtIndex(idx, file); |
233 | } |
234 | |
235 | bool ProcessProperties::GetIgnoreBreakpointsInExpressions() const { |
236 | const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions; |
237 | return GetPropertyAtIndexAs<bool>( |
238 | idx, g_process_properties[idx].default_uint_value != 0); |
239 | } |
240 | |
241 | void ProcessProperties::SetIgnoreBreakpointsInExpressions(bool ignore) { |
242 | const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions; |
243 | SetPropertyAtIndex(idx, ignore); |
244 | } |
245 | |
246 | bool ProcessProperties::GetUnwindOnErrorInExpressions() const { |
247 | const uint32_t idx = ePropertyUnwindOnErrorInExpressions; |
248 | return GetPropertyAtIndexAs<bool>( |
249 | idx, g_process_properties[idx].default_uint_value != 0); |
250 | } |
251 | |
252 | void ProcessProperties::SetUnwindOnErrorInExpressions(bool ignore) { |
253 | const uint32_t idx = ePropertyUnwindOnErrorInExpressions; |
254 | SetPropertyAtIndex(idx, ignore); |
255 | } |
256 | |
257 | bool ProcessProperties::GetStopOnSharedLibraryEvents() const { |
258 | const uint32_t idx = ePropertyStopOnSharedLibraryEvents; |
259 | return GetPropertyAtIndexAs<bool>( |
260 | idx, g_process_properties[idx].default_uint_value != 0); |
261 | } |
262 | |
263 | void ProcessProperties::SetStopOnSharedLibraryEvents(bool stop) { |
264 | const uint32_t idx = ePropertyStopOnSharedLibraryEvents; |
265 | SetPropertyAtIndex(idx, stop); |
266 | } |
267 | |
268 | bool ProcessProperties::GetDisableLangRuntimeUnwindPlans() const { |
269 | const uint32_t idx = ePropertyDisableLangRuntimeUnwindPlans; |
270 | return GetPropertyAtIndexAs<bool>( |
271 | idx, g_process_properties[idx].default_uint_value != 0); |
272 | } |
273 | |
274 | void ProcessProperties::SetDisableLangRuntimeUnwindPlans(bool disable) { |
275 | const uint32_t idx = ePropertyDisableLangRuntimeUnwindPlans; |
276 | SetPropertyAtIndex(idx, disable); |
277 | m_process->Flush(); |
278 | } |
279 | |
280 | bool ProcessProperties::GetDetachKeepsStopped() const { |
281 | const uint32_t idx = ePropertyDetachKeepsStopped; |
282 | return GetPropertyAtIndexAs<bool>( |
283 | idx, g_process_properties[idx].default_uint_value != 0); |
284 | } |
285 | |
286 | void ProcessProperties::SetDetachKeepsStopped(bool stop) { |
287 | const uint32_t idx = ePropertyDetachKeepsStopped; |
288 | SetPropertyAtIndex(idx, stop); |
289 | } |
290 | |
291 | bool ProcessProperties::GetWarningsOptimization() const { |
292 | const uint32_t idx = ePropertyWarningOptimization; |
293 | return GetPropertyAtIndexAs<bool>( |
294 | idx, g_process_properties[idx].default_uint_value != 0); |
295 | } |
296 | |
297 | bool ProcessProperties::GetWarningsUnsupportedLanguage() const { |
298 | const uint32_t idx = ePropertyWarningUnsupportedLanguage; |
299 | return GetPropertyAtIndexAs<bool>( |
300 | idx, g_process_properties[idx].default_uint_value != 0); |
301 | } |
302 | |
303 | bool ProcessProperties::GetStopOnExec() const { |
304 | const uint32_t idx = ePropertyStopOnExec; |
305 | return GetPropertyAtIndexAs<bool>( |
306 | idx, g_process_properties[idx].default_uint_value != 0); |
307 | } |
308 | |
309 | std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const { |
310 | const uint32_t idx = ePropertyUtilityExpressionTimeout; |
311 | uint64_t value = GetPropertyAtIndexAs<uint64_t>( |
312 | idx, g_process_properties[idx].default_uint_value); |
313 | return std::chrono::seconds(value); |
314 | } |
315 | |
316 | std::chrono::seconds ProcessProperties::GetInterruptTimeout() const { |
317 | const uint32_t idx = ePropertyInterruptTimeout; |
318 | uint64_t value = GetPropertyAtIndexAs<uint64_t>( |
319 | idx, g_process_properties[idx].default_uint_value); |
320 | return std::chrono::seconds(value); |
321 | } |
322 | |
323 | bool ProcessProperties::GetSteppingRunsAllThreads() const { |
324 | const uint32_t idx = ePropertySteppingRunsAllThreads; |
325 | return GetPropertyAtIndexAs<bool>( |
326 | idx, g_process_properties[idx].default_uint_value != 0); |
327 | } |
328 | |
329 | bool ProcessProperties::GetOSPluginReportsAllThreads() const { |
330 | const bool fail_value = true; |
331 | const Property *exp_property = |
332 | m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); |
333 | OptionValueProperties *exp_values = |
334 | exp_property->GetValue()->GetAsProperties(); |
335 | if (!exp_values) |
336 | return fail_value; |
337 | |
338 | return exp_values |
339 | ->GetPropertyAtIndexAs<bool>(ePropertyOSPluginReportsAllThreads) |
340 | .value_or(fail_value); |
341 | } |
342 | |
343 | void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) { |
344 | const Property *exp_property = |
345 | m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); |
346 | OptionValueProperties *exp_values = |
347 | exp_property->GetValue()->GetAsProperties(); |
348 | if (exp_values) |
349 | exp_values->SetPropertyAtIndex(ePropertyOSPluginReportsAllThreads, |
350 | does_report); |
351 | } |
352 | |
353 | FollowForkMode ProcessProperties::GetFollowForkMode() const { |
354 | const uint32_t idx = ePropertyFollowForkMode; |
355 | return GetPropertyAtIndexAs<FollowForkMode>( |
356 | idx, static_cast<FollowForkMode>( |
357 | g_process_properties[idx].default_uint_value)); |
358 | } |
359 | |
360 | ProcessSP Process::FindPlugin(lldb::TargetSP target_sp, |
361 | llvm::StringRef plugin_name, |
362 | ListenerSP listener_sp, |
363 | const FileSpec *crash_file_path, |
364 | bool can_connect) { |
365 | static uint32_t g_process_unique_id = 0; |
366 | |
367 | ProcessSP process_sp; |
368 | ProcessCreateInstance create_callback = nullptr; |
369 | if (!plugin_name.empty()) { |
370 | create_callback = |
371 | PluginManager::GetProcessCreateCallbackForPluginName(plugin_name); |
372 | if (create_callback) { |
373 | process_sp = create_callback(target_sp, listener_sp, crash_file_path, |
374 | can_connect); |
375 | if (process_sp) { |
376 | if (process_sp->CanDebug(target_sp, true)) { |
377 | process_sp->m_process_unique_id = ++g_process_unique_id; |
378 | } else |
379 | process_sp.reset(); |
380 | } |
381 | } |
382 | } else { |
383 | for (uint32_t idx = 0; |
384 | (create_callback = |
385 | PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr; |
386 | ++idx) { |
387 | process_sp = create_callback(target_sp, listener_sp, crash_file_path, |
388 | can_connect); |
389 | if (process_sp) { |
390 | if (process_sp->CanDebug(target_sp, false)) { |
391 | process_sp->m_process_unique_id = ++g_process_unique_id; |
392 | break; |
393 | } else |
394 | process_sp.reset(); |
395 | } |
396 | } |
397 | } |
398 | return process_sp; |
399 | } |
400 | |
401 | ConstString &Process::GetStaticBroadcasterClass() { |
402 | static ConstString class_name("lldb.process"); |
403 | return class_name; |
404 | } |
405 | |
406 | Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) |
407 | : Process(target_sp, listener_sp, UnixSignals::CreateForHost()) { |
408 | // This constructor just delegates to the full Process constructor, |
409 | // defaulting to using the Host's UnixSignals. |
410 | } |
411 | |
412 | Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, |
413 | const UnixSignalsSP &unix_signals_sp) |
414 | : ProcessProperties(this), |
415 | Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()), |
416 | Process::GetStaticBroadcasterClass().AsCString()), |
417 | m_target_wp(target_sp), m_public_state(eStateUnloaded), |
418 | m_private_state(eStateUnloaded), |
419 | m_private_state_broadcaster(nullptr, |
420 | "lldb.process.internal_state_broadcaster"), |
421 | m_private_state_control_broadcaster( |
422 | nullptr, "lldb.process.internal_state_control_broadcaster"), |
423 | m_private_state_listener_sp( |
424 | Listener::MakeListener("lldb.process.internal_state_listener")), |
425 | m_mod_id(), m_process_unique_id(0), m_thread_index_id(0), |
426 | m_thread_id_to_index_id_map(), m_exit_status(-1), m_exit_string(), |
427 | m_exit_status_mutex(), m_thread_mutex(), m_thread_list_real(this), |
428 | m_thread_list(this), m_thread_plans(*this), m_extended_thread_list(this), |
429 | m_extended_thread_stop_id(0), m_queue_list(this), m_queue_list_stop_id(0), |
430 | m_notifications(), m_image_tokens(), m_listener_sp(listener_sp), |
431 | m_breakpoint_site_list(), m_dynamic_checkers_up(), |
432 | m_unix_signals_sp(unix_signals_sp), m_abi_sp(), m_process_input_reader(), |
433 | m_stdio_communication("process.stdio"), m_stdio_communication_mutex(), |
434 | m_stdin_forward(false), m_stdout_data(), m_stderr_data(), |
435 | m_profile_data_comm_mutex(), m_profile_data(), m_iohandler_sync(0), |
436 | m_memory_cache(*this), m_allocated_memory_cache(*this), |
437 | m_should_detach(false), m_next_event_action_up(), m_public_run_lock(), |
438 | m_private_run_lock(), m_currently_handling_do_on_removals(false), |
439 | m_resume_requested(false), m_finalizing(false), |
440 | m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false), |
441 | m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false), |
442 | m_can_interpret_function_calls(false), m_run_thread_plan_lock(), |
443 | m_can_jit(eCanJITDontKnow) { |
444 | CheckInWithManager(); |
445 | |
446 | Log *log = GetLog(LLDBLog::Object); |
447 | LLDB_LOGF(log, "%p Process::Process()", static_cast<void *>(this))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("%p Process::Process()", static_cast <void *>(this)); } while (0); |
448 | |
449 | if (!m_unix_signals_sp) |
450 | m_unix_signals_sp = std::make_shared<UnixSignals>(); |
451 | |
452 | SetEventName(eBroadcastBitStateChanged, "state-changed"); |
453 | SetEventName(eBroadcastBitInterrupt, "interrupt"); |
454 | SetEventName(eBroadcastBitSTDOUT, "stdout-available"); |
455 | SetEventName(eBroadcastBitSTDERR, "stderr-available"); |
456 | SetEventName(eBroadcastBitProfileData, "profile-data-available"); |
457 | SetEventName(eBroadcastBitStructuredData, "structured-data-available"); |
458 | |
459 | m_private_state_control_broadcaster.SetEventName( |
460 | eBroadcastInternalStateControlStop, "control-stop"); |
461 | m_private_state_control_broadcaster.SetEventName( |
462 | eBroadcastInternalStateControlPause, "control-pause"); |
463 | m_private_state_control_broadcaster.SetEventName( |
464 | eBroadcastInternalStateControlResume, "control-resume"); |
465 | |
466 | m_listener_sp->StartListeningForEvents( |
467 | this, eBroadcastBitStateChanged | eBroadcastBitInterrupt | |
468 | eBroadcastBitSTDOUT | eBroadcastBitSTDERR | |
469 | eBroadcastBitProfileData | eBroadcastBitStructuredData); |
470 | |
471 | m_private_state_listener_sp->StartListeningForEvents( |
472 | &m_private_state_broadcaster, |
473 | eBroadcastBitStateChanged | eBroadcastBitInterrupt); |
474 | |
475 | m_private_state_listener_sp->StartListeningForEvents( |
476 | &m_private_state_control_broadcaster, |
477 | eBroadcastInternalStateControlStop | eBroadcastInternalStateControlPause | |
478 | eBroadcastInternalStateControlResume); |
479 | // We need something valid here, even if just the default UnixSignalsSP. |
480 | assert(m_unix_signals_sp && "null m_unix_signals_sp after initialization")(static_cast <bool> (m_unix_signals_sp && "null m_unix_signals_sp after initialization" ) ? void (0) : __assert_fail ("m_unix_signals_sp && \"null m_unix_signals_sp after initialization\"" , "lldb/source/Target/Process.cpp", 480, __extension__ __PRETTY_FUNCTION__ )); |
481 | |
482 | // Allow the platform to override the default cache line size |
483 | OptionValueSP value_sp = |
484 | m_collection_sp->GetPropertyAtIndex(ePropertyMemCacheLineSize) |
485 | ->GetValue(); |
486 | uint32_t platform_cache_line_size = |
487 | target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize(); |
488 | if (!value_sp->OptionWasSet() && platform_cache_line_size != 0) |
489 | value_sp->SetUInt64Value(platform_cache_line_size); |
490 | |
491 | RegisterAssertFrameRecognizer(this); |
492 | } |
493 | |
494 | Process::~Process() { |
495 | Log *log = GetLog(LLDBLog::Object); |
496 | LLDB_LOGF(log, "%p Process::~Process()", static_cast<void *>(this))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("%p Process::~Process()", static_cast <void *>(this)); } while (0); |
497 | StopPrivateStateThread(); |
498 | |
499 | // ThreadList::Clear() will try to acquire this process's mutex, so |
500 | // explicitly clear the thread list here to ensure that the mutex is not |
501 | // destroyed before the thread list. |
502 | m_thread_list.Clear(); |
503 | } |
504 | |
505 | ProcessProperties &Process::GetGlobalProperties() { |
506 | // NOTE: intentional leak so we don't crash if global destructor chain gets |
507 | // called as other threads still use the result of this function |
508 | static ProcessProperties *g_settings_ptr = |
509 | new ProcessProperties(nullptr); |
510 | return *g_settings_ptr; |
511 | } |
512 | |
513 | void Process::Finalize() { |
514 | if (m_finalizing.exchange(true)) |
515 | return; |
516 | |
517 | // Destroy the process. This will call the virtual function DoDestroy under |
518 | // the hood, giving our derived class a chance to do the ncessary tear down. |
519 | DestroyImpl(false); |
520 | |
521 | // Clear our broadcaster before we proceed with destroying |
522 | Broadcaster::Clear(); |
523 | |
524 | // Do any cleanup needed prior to being destructed... Subclasses that |
525 | // override this method should call this superclass method as well. |
526 | |
527 | // We need to destroy the loader before the derived Process class gets |
528 | // destroyed since it is very likely that undoing the loader will require |
529 | // access to the real process. |
530 | m_dynamic_checkers_up.reset(); |
531 | m_abi_sp.reset(); |
532 | m_os_up.reset(); |
533 | m_system_runtime_up.reset(); |
534 | m_dyld_up.reset(); |
535 | m_jit_loaders_up.reset(); |
536 | m_thread_plans.Clear(); |
537 | m_thread_list_real.Destroy(); |
538 | m_thread_list.Destroy(); |
539 | m_extended_thread_list.Destroy(); |
540 | m_queue_list.Clear(); |
541 | m_queue_list_stop_id = 0; |
542 | std::vector<Notifications> empty_notifications; |
543 | m_notifications.swap(empty_notifications); |
544 | m_image_tokens.clear(); |
545 | m_memory_cache.Clear(); |
546 | m_allocated_memory_cache.Clear(/*deallocate_memory=*/true); |
547 | { |
548 | std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); |
549 | m_language_runtimes.clear(); |
550 | } |
551 | m_instrumentation_runtimes.clear(); |
552 | m_next_event_action_up.reset(); |
553 | // Clear the last natural stop ID since it has a strong reference to this |
554 | // process |
555 | m_mod_id.SetStopEventForLastNaturalStopID(EventSP()); |
556 | //#ifdef LLDB_CONFIGURATION_DEBUG |
557 | // StreamFile s(stdout, false); |
558 | // EventSP event_sp; |
559 | // while (m_private_state_listener_sp->GetNextEvent(event_sp)) |
560 | // { |
561 | // event_sp->Dump (&s); |
562 | // s.EOL(); |
563 | // } |
564 | //#endif |
565 | // We have to be very careful here as the m_private_state_listener might |
566 | // contain events that have ProcessSP values in them which can keep this |
567 | // process around forever. These events need to be cleared out. |
568 | m_private_state_listener_sp->Clear(); |
569 | m_public_run_lock.TrySetRunning(); // This will do nothing if already locked |
570 | m_public_run_lock.SetStopped(); |
571 | m_private_run_lock.TrySetRunning(); // This will do nothing if already locked |
572 | m_private_run_lock.SetStopped(); |
573 | m_structured_data_plugin_map.clear(); |
574 | } |
575 | |
576 | void Process::RegisterNotificationCallbacks(const Notifications &callbacks) { |
577 | m_notifications.push_back(callbacks); |
578 | if (callbacks.initialize != nullptr) |
579 | callbacks.initialize(callbacks.baton, this); |
580 | } |
581 | |
582 | bool Process::UnregisterNotificationCallbacks(const Notifications &callbacks) { |
583 | std::vector<Notifications>::iterator pos, end = m_notifications.end(); |
584 | for (pos = m_notifications.begin(); pos != end; ++pos) { |
585 | if (pos->baton == callbacks.baton && |
586 | pos->initialize == callbacks.initialize && |
587 | pos->process_state_changed == callbacks.process_state_changed) { |
588 | m_notifications.erase(pos); |
589 | return true; |
590 | } |
591 | } |
592 | return false; |
593 | } |
594 | |
595 | void Process::SynchronouslyNotifyStateChanged(StateType state) { |
596 | std::vector<Notifications>::iterator notification_pos, |
597 | notification_end = m_notifications.end(); |
598 | for (notification_pos = m_notifications.begin(); |
599 | notification_pos != notification_end; ++notification_pos) { |
600 | if (notification_pos->process_state_changed) |
601 | notification_pos->process_state_changed(notification_pos->baton, this, |
602 | state); |
603 | } |
604 | } |
605 | |
606 | // FIXME: We need to do some work on events before the general Listener sees |
607 | // them. |
608 | // For instance if we are continuing from a breakpoint, we need to ensure that |
609 | // we do the little "insert real insn, step & stop" trick. But we can't do |
610 | // that when the event is delivered by the broadcaster - since that is done on |
611 | // the thread that is waiting for new events, so if we needed more than one |
612 | // event for our handling, we would stall. So instead we do it when we fetch |
613 | // the event off of the queue. |
614 | // |
615 | |
616 | StateType Process::GetNextEvent(EventSP &event_sp) { |
617 | StateType state = eStateInvalid; |
618 | |
619 | if (m_listener_sp->GetEventForBroadcaster(this, event_sp, |
620 | std::chrono::seconds(0)) && |
621 | event_sp) |
622 | state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
623 | |
624 | return state; |
625 | } |
626 | |
627 | void Process::SyncIOHandler(uint32_t iohandler_id, |
628 | const Timeout<std::micro> &timeout) { |
629 | // don't sync (potentially context switch) in case where there is no process |
630 | // IO |
631 | if (!m_process_input_reader) |
632 | return; |
633 | |
634 | auto Result = m_iohandler_sync.WaitForValueNotEqualTo(iohandler_id, timeout); |
635 | |
636 | Log *log = GetLog(LLDBLog::Process); |
637 | if (Result) { |
638 | LLDB_LOG(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "waited from m_iohandler_sync to change from {0}. New value is {1}." , iohandler_id, *Result); } while (0) |
639 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "waited from m_iohandler_sync to change from {0}. New value is {1}." , iohandler_id, *Result); } while (0) |
640 | "waited from m_iohandler_sync to change from {0}. New value is {1}.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "waited from m_iohandler_sync to change from {0}. New value is {1}." , iohandler_id, *Result); } while (0) |
641 | iohandler_id, *Result)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "waited from m_iohandler_sync to change from {0}. New value is {1}." , iohandler_id, *Result); } while (0); |
642 | } else { |
643 | LLDB_LOG(log, "timed out waiting for m_iohandler_sync to change from {0}.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timed out waiting for m_iohandler_sync to change from {0}." , iohandler_id); } while (0) |
644 | iohandler_id)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timed out waiting for m_iohandler_sync to change from {0}." , iohandler_id); } while (0); |
645 | } |
646 | } |
647 | |
648 | StateType Process::WaitForProcessToStop( |
649 | const Timeout<std::micro> &timeout, EventSP *event_sp_ptr, bool wait_always, |
650 | ListenerSP hijack_listener_sp, Stream *stream, bool use_run_lock, |
651 | SelectMostRelevant select_most_relevant) { |
652 | // We can't just wait for a "stopped" event, because the stopped event may |
653 | // have restarted the target. We have to actually check each event, and in |
654 | // the case of a stopped event check the restarted flag on the event. |
655 | if (event_sp_ptr) |
656 | event_sp_ptr->reset(); |
657 | StateType state = GetState(); |
658 | // If we are exited or detached, we won't ever get back to any other valid |
659 | // state... |
660 | if (state == eStateDetached || state == eStateExited) |
661 | return state; |
662 | |
663 | Log *log = GetLog(LLDBLog::Process); |
664 | LLDB_LOG(log, "timeout = {0}", timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}", timeout); } while (0); |
665 | |
666 | if (!wait_always && StateIsStoppedState(state, true) && |
667 | StateIsStoppedState(GetPrivateState(), true)) { |
668 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s returning without waiting for events; process " "private and public states are already 'stopped'.", __FUNCTION__ ); } while (0) |
669 | "Process::%s returning without waiting for events; process "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s returning without waiting for events; process " "private and public states are already 'stopped'.", __FUNCTION__ ); } while (0) |
670 | "private and public states are already 'stopped'.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s returning without waiting for events; process " "private and public states are already 'stopped'.", __FUNCTION__ ); } while (0) |
671 | __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s returning without waiting for events; process " "private and public states are already 'stopped'.", __FUNCTION__ ); } while (0); |
672 | // We need to toggle the run lock as this won't get done in |
673 | // SetPublicState() if the process is hijacked. |
674 | if (hijack_listener_sp && use_run_lock) |
675 | m_public_run_lock.SetStopped(); |
676 | return state; |
677 | } |
678 | |
679 | while (state != eStateInvalid) { |
680 | EventSP event_sp; |
681 | state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp); |
682 | if (event_sp_ptr && event_sp) |
683 | *event_sp_ptr = event_sp; |
684 | |
685 | bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr); |
686 | Process::HandleProcessStateChangedEvent( |
687 | event_sp, stream, select_most_relevant, pop_process_io_handler); |
688 | |
689 | switch (state) { |
690 | case eStateCrashed: |
691 | case eStateDetached: |
692 | case eStateExited: |
693 | case eStateUnloaded: |
694 | // We need to toggle the run lock as this won't get done in |
695 | // SetPublicState() if the process is hijacked. |
696 | if (hijack_listener_sp && use_run_lock) |
697 | m_public_run_lock.SetStopped(); |
698 | return state; |
699 | case eStateStopped: |
700 | if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) |
701 | continue; |
702 | else { |
703 | // We need to toggle the run lock as this won't get done in |
704 | // SetPublicState() if the process is hijacked. |
705 | if (hijack_listener_sp && use_run_lock) |
706 | m_public_run_lock.SetStopped(); |
707 | return state; |
708 | } |
709 | default: |
710 | continue; |
711 | } |
712 | } |
713 | return state; |
714 | } |
715 | |
716 | bool Process::HandleProcessStateChangedEvent( |
717 | const EventSP &event_sp, Stream *stream, |
718 | SelectMostRelevant select_most_relevant, |
719 | bool &pop_process_io_handler) { |
720 | const bool handle_pop = pop_process_io_handler; |
721 | |
722 | pop_process_io_handler = false; |
723 | ProcessSP process_sp = |
724 | Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); |
725 | |
726 | if (!process_sp) |
727 | return false; |
728 | |
729 | StateType event_state = |
730 | Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
731 | if (event_state == eStateInvalid) |
732 | return false; |
733 | |
734 | switch (event_state) { |
735 | case eStateInvalid: |
736 | case eStateUnloaded: |
737 | case eStateAttaching: |
738 | case eStateLaunching: |
739 | case eStateStepping: |
740 | case eStateDetached: |
741 | if (stream) |
742 | stream->Printf("Process %" PRIu64"l" "u" " %s\n", process_sp->GetID(), |
743 | StateAsCString(event_state)); |
744 | if (event_state == eStateDetached) |
745 | pop_process_io_handler = true; |
746 | break; |
747 | |
748 | case eStateConnected: |
749 | case eStateRunning: |
750 | // Don't be chatty when we run... |
751 | break; |
752 | |
753 | case eStateExited: |
754 | if (stream) |
755 | process_sp->GetStatus(*stream); |
756 | pop_process_io_handler = true; |
757 | break; |
758 | |
759 | case eStateStopped: |
760 | case eStateCrashed: |
761 | case eStateSuspended: |
762 | // Make sure the program hasn't been auto-restarted: |
763 | if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) { |
764 | if (stream) { |
765 | size_t num_reasons = |
766 | Process::ProcessEventData::GetNumRestartedReasons(event_sp.get()); |
767 | if (num_reasons > 0) { |
768 | // FIXME: Do we want to report this, or would that just be annoyingly |
769 | // chatty? |
770 | if (num_reasons == 1) { |
771 | const char *reason = |
772 | Process::ProcessEventData::GetRestartedReasonAtIndex( |
773 | event_sp.get(), 0); |
774 | stream->Printf("Process %" PRIu64"l" "u" " stopped and restarted: %s\n", |
775 | process_sp->GetID(), |
776 | reason ? reason : "<UNKNOWN REASON>"); |
777 | } else { |
778 | stream->Printf("Process %" PRIu64"l" "u" |
779 | " stopped and restarted, reasons:\n", |
780 | process_sp->GetID()); |
781 | |
782 | for (size_t i = 0; i < num_reasons; i++) { |
783 | const char *reason = |
784 | Process::ProcessEventData::GetRestartedReasonAtIndex( |
785 | event_sp.get(), i); |
786 | stream->Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>"); |
787 | } |
788 | } |
789 | } |
790 | } |
791 | } else { |
792 | StopInfoSP curr_thread_stop_info_sp; |
793 | // Lock the thread list so it doesn't change on us, this is the scope for |
794 | // the locker: |
795 | { |
796 | ThreadList &thread_list = process_sp->GetThreadList(); |
797 | std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex()); |
798 | |
799 | ThreadSP curr_thread(thread_list.GetSelectedThread()); |
800 | ThreadSP thread; |
801 | StopReason curr_thread_stop_reason = eStopReasonInvalid; |
802 | bool prefer_curr_thread = false; |
803 | if (curr_thread && curr_thread->IsValid()) { |
804 | curr_thread_stop_reason = curr_thread->GetStopReason(); |
805 | switch (curr_thread_stop_reason) { |
806 | case eStopReasonNone: |
807 | case eStopReasonInvalid: |
808 | // Don't prefer the current thread if it didn't stop for a reason. |
809 | break; |
810 | case eStopReasonSignal: { |
811 | // We need to do the same computation we do for other threads |
812 | // below in case the current thread happens to be the one that |
813 | // stopped for the no-stop signal. |
814 | uint64_t signo = curr_thread->GetStopInfo()->GetValue(); |
815 | if (process_sp->GetUnixSignals()->GetShouldStop(signo)) |
816 | prefer_curr_thread = true; |
817 | } break; |
818 | default: |
819 | prefer_curr_thread = true; |
820 | break; |
821 | } |
822 | curr_thread_stop_info_sp = curr_thread->GetStopInfo(); |
823 | } |
824 | |
825 | if (!prefer_curr_thread) { |
826 | // Prefer a thread that has just completed its plan over another |
827 | // thread as current thread. |
828 | ThreadSP plan_thread; |
829 | ThreadSP other_thread; |
830 | |
831 | const size_t num_threads = thread_list.GetSize(); |
832 | size_t i; |
833 | for (i = 0; i < num_threads; ++i) { |
834 | thread = thread_list.GetThreadAtIndex(i); |
835 | StopReason thread_stop_reason = thread->GetStopReason(); |
836 | switch (thread_stop_reason) { |
837 | case eStopReasonInvalid: |
838 | case eStopReasonNone: |
839 | break; |
840 | |
841 | case eStopReasonSignal: { |
842 | // Don't select a signal thread if we weren't going to stop at |
843 | // that signal. We have to have had another reason for stopping |
844 | // here, and the user doesn't want to see this thread. |
845 | uint64_t signo = thread->GetStopInfo()->GetValue(); |
846 | if (process_sp->GetUnixSignals()->GetShouldStop(signo)) { |
847 | if (!other_thread) |
848 | other_thread = thread; |
849 | } |
850 | break; |
851 | } |
852 | case eStopReasonTrace: |
853 | case eStopReasonBreakpoint: |
854 | case eStopReasonWatchpoint: |
855 | case eStopReasonException: |
856 | case eStopReasonExec: |
857 | case eStopReasonFork: |
858 | case eStopReasonVFork: |
859 | case eStopReasonVForkDone: |
860 | case eStopReasonThreadExiting: |
861 | case eStopReasonInstrumentation: |
862 | case eStopReasonProcessorTrace: |
863 | if (!other_thread) |
864 | other_thread = thread; |
865 | break; |
866 | case eStopReasonPlanComplete: |
867 | if (!plan_thread) |
868 | plan_thread = thread; |
869 | break; |
870 | } |
871 | } |
872 | if (plan_thread) |
873 | thread_list.SetSelectedThreadByID(plan_thread->GetID()); |
874 | else if (other_thread) |
875 | thread_list.SetSelectedThreadByID(other_thread->GetID()); |
876 | else { |
877 | if (curr_thread && curr_thread->IsValid()) |
878 | thread = curr_thread; |
879 | else |
880 | thread = thread_list.GetThreadAtIndex(0); |
881 | |
882 | if (thread) |
883 | thread_list.SetSelectedThreadByID(thread->GetID()); |
884 | } |
885 | } |
886 | } |
887 | // Drop the ThreadList mutex by here, since GetThreadStatus below might |
888 | // have to run code, e.g. for Data formatters, and if we hold the |
889 | // ThreadList mutex, then the process is going to have a hard time |
890 | // restarting the process. |
891 | if (stream) { |
892 | Debugger &debugger = process_sp->GetTarget().GetDebugger(); |
893 | if (debugger.GetTargetList().GetSelectedTarget().get() == |
894 | &process_sp->GetTarget()) { |
895 | ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); |
896 | |
897 | if (!thread_sp || !thread_sp->IsValid()) |
898 | return false; |
899 | |
900 | const bool only_threads_with_stop_reason = true; |
901 | const uint32_t start_frame = |
902 | thread_sp->GetSelectedFrameIndex(select_most_relevant); |
903 | const uint32_t num_frames = 1; |
904 | const uint32_t num_frames_with_source = 1; |
905 | const bool stop_format = true; |
906 | |
907 | process_sp->GetStatus(*stream); |
908 | process_sp->GetThreadStatus(*stream, only_threads_with_stop_reason, |
909 | start_frame, num_frames, |
910 | num_frames_with_source, |
911 | stop_format); |
912 | if (curr_thread_stop_info_sp) { |
913 | lldb::addr_t crashing_address; |
914 | ValueObjectSP valobj_sp = StopInfo::GetCrashingDereference( |
915 | curr_thread_stop_info_sp, &crashing_address); |
916 | if (valobj_sp) { |
917 | const ValueObject::GetExpressionPathFormat format = |
918 | ValueObject::GetExpressionPathFormat:: |
919 | eGetExpressionPathFormatHonorPointers; |
920 | stream->PutCString("Likely cause: "); |
921 | valobj_sp->GetExpressionPath(*stream, format); |
922 | stream->Printf(" accessed 0x%" PRIx64"l" "x" "\n", crashing_address); |
923 | } |
924 | } |
925 | } else { |
926 | uint32_t target_idx = debugger.GetTargetList().GetIndexOfTarget( |
927 | process_sp->GetTarget().shared_from_this()); |
928 | if (target_idx != UINT32_MAX(4294967295U)) |
929 | stream->Printf("Target %d: (", target_idx); |
930 | else |
931 | stream->Printf("Target <unknown index>: ("); |
932 | process_sp->GetTarget().Dump(stream, eDescriptionLevelBrief); |
933 | stream->Printf(") stopped.\n"); |
934 | } |
935 | } |
936 | |
937 | // Pop the process IO handler |
938 | pop_process_io_handler = true; |
939 | } |
940 | break; |
941 | } |
942 | |
943 | if (handle_pop && pop_process_io_handler) |
944 | process_sp->PopProcessIOHandler(); |
945 | |
946 | return true; |
947 | } |
948 | |
949 | bool Process::HijackProcessEvents(ListenerSP listener_sp) { |
950 | if (listener_sp) { |
951 | return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged | |
952 | eBroadcastBitInterrupt); |
953 | } else |
954 | return false; |
955 | } |
956 | |
957 | void Process::RestoreProcessEvents() { RestoreBroadcaster(); } |
958 | |
959 | StateType Process::GetStateChangedEvents(EventSP &event_sp, |
960 | const Timeout<std::micro> &timeout, |
961 | ListenerSP hijack_listener_sp) { |
962 | Log *log = GetLog(LLDBLog::Process); |
963 | LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}, event_sp)...", timeout); } while (0); |
964 | |
965 | ListenerSP listener_sp = hijack_listener_sp; |
966 | if (!listener_sp) |
967 | listener_sp = m_listener_sp; |
968 | |
969 | StateType state = eStateInvalid; |
970 | if (listener_sp->GetEventForBroadcasterWithType( |
971 | this, eBroadcastBitStateChanged | eBroadcastBitInterrupt, event_sp, |
972 | timeout)) { |
973 | if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged) |
974 | state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
975 | else |
976 | LLDB_LOG(log, "got no event or was interrupted.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "got no event or was interrupted."); } while (0); |
977 | } |
978 | |
979 | LLDB_LOG(log, "timeout = {0}, event_sp) => {1}", timeout, state)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}, event_sp) => {1}", timeout, state); } while (0); |
980 | return state; |
981 | } |
982 | |
983 | Event *Process::PeekAtStateChangedEvents() { |
984 | Log *log = GetLog(LLDBLog::Process); |
985 | |
986 | LLDB_LOGF(log, "Process::%s...", __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s...", __FUNCTION__); } while (0); |
987 | |
988 | Event *event_ptr; |
989 | event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType( |
990 | this, eBroadcastBitStateChanged); |
991 | if (log) { |
992 | if (event_ptr) { |
993 | LLDB_LOGF(log, "Process::%s (event_ptr) => %s", __FUNCTION__,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (event_ptr) => %s", __FUNCTION__ , StateAsCString(ProcessEventData::GetStateFromEvent(event_ptr ))); } while (0) |
994 | StateAsCString(ProcessEventData::GetStateFromEvent(event_ptr)))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (event_ptr) => %s", __FUNCTION__ , StateAsCString(ProcessEventData::GetStateFromEvent(event_ptr ))); } while (0); |
995 | } else { |
996 | LLDB_LOGF(log, "Process::%s no events found", __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s no events found", __FUNCTION__ ); } while (0); |
997 | } |
998 | } |
999 | return event_ptr; |
1000 | } |
1001 | |
1002 | StateType |
1003 | Process::GetStateChangedEventsPrivate(EventSP &event_sp, |
1004 | const Timeout<std::micro> &timeout) { |
1005 | Log *log = GetLog(LLDBLog::Process); |
1006 | LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}, event_sp)...", timeout); } while (0); |
1007 | |
1008 | StateType state = eStateInvalid; |
1009 | if (m_private_state_listener_sp->GetEventForBroadcasterWithType( |
1010 | &m_private_state_broadcaster, |
1011 | eBroadcastBitStateChanged | eBroadcastBitInterrupt, event_sp, |
1012 | timeout)) |
1013 | if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged) |
1014 | state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
1015 | |
1016 | LLDB_LOG(log, "timeout = {0}, event_sp) => {1}", timeout,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}, event_sp) => {1}", timeout, state == eStateInvalid ? "TIMEOUT" : StateAsCString(state)); } while (0) |
1017 | state == eStateInvalid ? "TIMEOUT" : StateAsCString(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}, event_sp) => {1}", timeout, state == eStateInvalid ? "TIMEOUT" : StateAsCString(state)); } while (0); |
1018 | return state; |
1019 | } |
1020 | |
1021 | bool Process::GetEventsPrivate(EventSP &event_sp, |
1022 | const Timeout<std::micro> &timeout, |
1023 | bool control_only) { |
1024 | Log *log = GetLog(LLDBLog::Process); |
1025 | LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "timeout = {0}, event_sp)...", timeout); } while (0); |
1026 | |
1027 | if (control_only) |
1028 | return m_private_state_listener_sp->GetEventForBroadcaster( |
1029 | &m_private_state_control_broadcaster, event_sp, timeout); |
1030 | else |
1031 | return m_private_state_listener_sp->GetEvent(event_sp, timeout); |
1032 | } |
1033 | |
1034 | bool Process::IsRunning() const { |
1035 | return StateIsRunningState(m_public_state.GetValue()); |
1036 | } |
1037 | |
1038 | int Process::GetExitStatus() { |
1039 | std::lock_guard<std::mutex> guard(m_exit_status_mutex); |
1040 | |
1041 | if (m_public_state.GetValue() == eStateExited) |
1042 | return m_exit_status; |
1043 | return -1; |
1044 | } |
1045 | |
1046 | const char *Process::GetExitDescription() { |
1047 | std::lock_guard<std::mutex> guard(m_exit_status_mutex); |
1048 | |
1049 | if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty()) |
1050 | return m_exit_string.c_str(); |
1051 | return nullptr; |
1052 | } |
1053 | |
1054 | bool Process::SetExitStatus(int status, const char *cstr) { |
1055 | // Use a mutex to protect setting the exit status. |
1056 | std::lock_guard<std::mutex> guard(m_exit_status_mutex); |
1057 | |
1058 | Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); |
1059 | LLDB_LOG(log, "(plugin = %s status=%i (0x%8.8x), description=%s%s%s)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s status=%i (0x%8.8x), description=%s%s%s)", GetPluginName ().data(), status, status, cstr ? "\"" : "", cstr ? cstr : "NULL" , cstr ? "\"" : ""); } while (0) |
1060 | GetPluginName().data(), status, status, cstr ? "\"" : "",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s status=%i (0x%8.8x), description=%s%s%s)", GetPluginName ().data(), status, status, cstr ? "\"" : "", cstr ? cstr : "NULL" , cstr ? "\"" : ""); } while (0) |
1061 | cstr ? cstr : "NULL", cstr ? "\"" : "")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s status=%i (0x%8.8x), description=%s%s%s)", GetPluginName ().data(), status, status, cstr ? "\"" : "", cstr ? cstr : "NULL" , cstr ? "\"" : ""); } while (0); |
1062 | |
1063 | // We were already in the exited state |
1064 | if (m_private_state.GetValue() == eStateExited) { |
1065 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) ignoring exit status because state was already set " "to eStateExited", GetPluginName().data()); } while (0) |
1066 | "(plugin = %s) ignoring exit status because state was already set "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) ignoring exit status because state was already set " "to eStateExited", GetPluginName().data()); } while (0) |
1067 | "to eStateExited",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) ignoring exit status because state was already set " "to eStateExited", GetPluginName().data()); } while (0) |
1068 | GetPluginName().data())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) ignoring exit status because state was already set " "to eStateExited", GetPluginName().data()); } while (0); |
1069 | return false; |
1070 | } |
1071 | |
1072 | m_exit_status = status; |
1073 | if (cstr) |
1074 | m_exit_string = cstr; |
1075 | else |
1076 | m_exit_string.clear(); |
1077 | |
1078 | // Clear the last natural stop ID since it has a strong reference to this |
1079 | // process |
1080 | m_mod_id.SetStopEventForLastNaturalStopID(EventSP()); |
1081 | |
1082 | SetPrivateState(eStateExited); |
1083 | |
1084 | // Allow subclasses to do some cleanup |
1085 | DidExit(); |
1086 | |
1087 | return true; |
1088 | } |
1089 | |
1090 | bool Process::IsAlive() { |
1091 | switch (m_private_state.GetValue()) { |
1092 | case eStateConnected: |
1093 | case eStateAttaching: |
1094 | case eStateLaunching: |
1095 | case eStateStopped: |
1096 | case eStateRunning: |
1097 | case eStateStepping: |
1098 | case eStateCrashed: |
1099 | case eStateSuspended: |
1100 | return true; |
1101 | default: |
1102 | return false; |
1103 | } |
1104 | } |
1105 | |
1106 | // This static callback can be used to watch for local child processes on the |
1107 | // current host. The child process exits, the process will be found in the |
1108 | // global target list (we want to be completely sure that the |
1109 | // lldb_private::Process doesn't go away before we can deliver the signal. |
1110 | bool Process::SetProcessExitStatus( |
1111 | lldb::pid_t pid, bool exited, |
1112 | int signo, // Zero for no signal |
1113 | int exit_status // Exit value of process if signal is zero |
1114 | ) { |
1115 | Log *log = GetLog(LLDBLog::Process); |
1116 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::SetProcessExitStatus (pid=%" "l" "u" ", exited=%i, signal=%i, exit_status=%i)\n", pid, exited , signo, exit_status); } while (0) |
1117 | "Process::SetProcessExitStatus (pid=%" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::SetProcessExitStatus (pid=%" "l" "u" ", exited=%i, signal=%i, exit_status=%i)\n", pid, exited , signo, exit_status); } while (0) |
1118 | ", exited=%i, signal=%i, exit_status=%i)\n",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::SetProcessExitStatus (pid=%" "l" "u" ", exited=%i, signal=%i, exit_status=%i)\n", pid, exited , signo, exit_status); } while (0) |
1119 | pid, exited, signo, exit_status)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::SetProcessExitStatus (pid=%" "l" "u" ", exited=%i, signal=%i, exit_status=%i)\n", pid, exited , signo, exit_status); } while (0); |
1120 | |
1121 | if (exited) { |
1122 | TargetSP target_sp(Debugger::FindTargetWithProcessID(pid)); |
1123 | if (target_sp) { |
1124 | ProcessSP process_sp(target_sp->GetProcessSP()); |
1125 | if (process_sp) { |
1126 | const char *signal_cstr = nullptr; |
1127 | if (signo) |
1128 | signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo); |
1129 | |
1130 | process_sp->SetExitStatus(exit_status, signal_cstr); |
1131 | } |
1132 | } |
1133 | return true; |
1134 | } |
1135 | return false; |
1136 | } |
1137 | |
1138 | bool Process::UpdateThreadList(ThreadList &old_thread_list, |
1139 | ThreadList &new_thread_list) { |
1140 | m_thread_plans.ClearThreadCache(); |
1141 | return DoUpdateThreadList(old_thread_list, new_thread_list); |
1142 | } |
1143 | |
1144 | void Process::UpdateThreadListIfNeeded() { |
1145 | const uint32_t stop_id = GetStopID(); |
1146 | if (m_thread_list.GetSize(false) == 0 || |
1147 | stop_id != m_thread_list.GetStopID()) { |
1148 | bool clear_unused_threads = true; |
1149 | const StateType state = GetPrivateState(); |
1150 | if (StateIsStoppedState(state, true)) { |
1151 | std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); |
1152 | m_thread_list.SetStopID(stop_id); |
1153 | |
1154 | // m_thread_list does have its own mutex, but we need to hold onto the |
1155 | // mutex between the call to UpdateThreadList(...) and the |
1156 | // os->UpdateThreadList(...) so it doesn't change on us |
1157 | ThreadList &old_thread_list = m_thread_list; |
1158 | ThreadList real_thread_list(this); |
1159 | ThreadList new_thread_list(this); |
1160 | // Always update the thread list with the protocol specific thread list, |
1161 | // but only update if "true" is returned |
1162 | if (UpdateThreadList(m_thread_list_real, real_thread_list)) { |
1163 | // Don't call into the OperatingSystem to update the thread list if we |
1164 | // are shutting down, since that may call back into the SBAPI's, |
1165 | // requiring the API lock which is already held by whoever is shutting |
1166 | // us down, causing a deadlock. |
1167 | OperatingSystem *os = GetOperatingSystem(); |
1168 | if (os && !m_destroy_in_process) { |
1169 | // Clear any old backing threads where memory threads might have been |
1170 | // backed by actual threads from the lldb_private::Process subclass |
1171 | size_t num_old_threads = old_thread_list.GetSize(false); |
1172 | for (size_t i = 0; i < num_old_threads; ++i) |
1173 | old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread(); |
1174 | // See if the OS plugin reports all threads. If it does, then |
1175 | // it is safe to clear unseen thread's plans here. Otherwise we |
1176 | // should preserve them in case they show up again: |
1177 | clear_unused_threads = GetOSPluginReportsAllThreads(); |
1178 | |
1179 | // Turn off dynamic types to ensure we don't run any expressions. |
1180 | // Objective-C can run an expression to determine if a SBValue is a |
1181 | // dynamic type or not and we need to avoid this. OperatingSystem |
1182 | // plug-ins can't run expressions that require running code... |
1183 | |
1184 | Target &target = GetTarget(); |
1185 | const lldb::DynamicValueType saved_prefer_dynamic = |
1186 | target.GetPreferDynamicValue(); |
1187 | if (saved_prefer_dynamic != lldb::eNoDynamicValues) |
1188 | target.SetPreferDynamicValue(lldb::eNoDynamicValues); |
1189 | |
1190 | // Now let the OperatingSystem plug-in update the thread list |
1191 | |
1192 | os->UpdateThreadList( |
1193 | old_thread_list, // Old list full of threads created by OS plug-in |
1194 | real_thread_list, // The actual thread list full of threads |
1195 | // created by each lldb_private::Process |
1196 | // subclass |
1197 | new_thread_list); // The new thread list that we will show to the |
1198 | // user that gets filled in |
1199 | |
1200 | if (saved_prefer_dynamic != lldb::eNoDynamicValues) |
1201 | target.SetPreferDynamicValue(saved_prefer_dynamic); |
1202 | } else { |
1203 | // No OS plug-in, the new thread list is the same as the real thread |
1204 | // list. |
1205 | new_thread_list = real_thread_list; |
1206 | } |
1207 | |
1208 | m_thread_list_real.Update(real_thread_list); |
1209 | m_thread_list.Update(new_thread_list); |
1210 | m_thread_list.SetStopID(stop_id); |
1211 | |
1212 | if (GetLastNaturalStopID() != m_extended_thread_stop_id) { |
1213 | // Clear any extended threads that we may have accumulated previously |
1214 | m_extended_thread_list.Clear(); |
1215 | m_extended_thread_stop_id = GetLastNaturalStopID(); |
1216 | |
1217 | m_queue_list.Clear(); |
1218 | m_queue_list_stop_id = GetLastNaturalStopID(); |
1219 | } |
1220 | } |
1221 | // Now update the plan stack map. |
1222 | // If we do have an OS plugin, any absent real threads in the |
1223 | // m_thread_list have already been removed from the ThreadPlanStackMap. |
1224 | // So any remaining threads are OS Plugin threads, and those we want to |
1225 | // preserve in case they show up again. |
1226 | m_thread_plans.Update(m_thread_list, clear_unused_threads); |
1227 | } |
1228 | } |
1229 | } |
1230 | |
1231 | ThreadPlanStack *Process::FindThreadPlans(lldb::tid_t tid) { |
1232 | return m_thread_plans.Find(tid); |
1233 | } |
1234 | |
1235 | bool Process::PruneThreadPlansForTID(lldb::tid_t tid) { |
1236 | return m_thread_plans.PrunePlansForTID(tid); |
1237 | } |
1238 | |
1239 | void Process::PruneThreadPlans() { |
1240 | m_thread_plans.Update(GetThreadList(), true, false); |
1241 | } |
1242 | |
1243 | bool Process::DumpThreadPlansForTID(Stream &strm, lldb::tid_t tid, |
1244 | lldb::DescriptionLevel desc_level, |
1245 | bool internal, bool condense_trivial, |
1246 | bool skip_unreported_plans) { |
1247 | return m_thread_plans.DumpPlansForTID( |
1248 | strm, tid, desc_level, internal, condense_trivial, skip_unreported_plans); |
1249 | } |
1250 | void Process::DumpThreadPlans(Stream &strm, lldb::DescriptionLevel desc_level, |
1251 | bool internal, bool condense_trivial, |
1252 | bool skip_unreported_plans) { |
1253 | m_thread_plans.DumpPlans(strm, desc_level, internal, condense_trivial, |
1254 | skip_unreported_plans); |
1255 | } |
1256 | |
1257 | void Process::UpdateQueueListIfNeeded() { |
1258 | if (m_system_runtime_up) { |
1259 | if (m_queue_list.GetSize() == 0 || |
1260 | m_queue_list_stop_id != GetLastNaturalStopID()) { |
1261 | const StateType state = GetPrivateState(); |
1262 | if (StateIsStoppedState(state, true)) { |
1263 | m_system_runtime_up->PopulateQueueList(m_queue_list); |
1264 | m_queue_list_stop_id = GetLastNaturalStopID(); |
1265 | } |
1266 | } |
1267 | } |
1268 | } |
1269 | |
1270 | ThreadSP Process::CreateOSPluginThread(lldb::tid_t tid, lldb::addr_t context) { |
1271 | OperatingSystem *os = GetOperatingSystem(); |
1272 | if (os) |
1273 | return os->CreateThread(tid, context); |
1274 | return ThreadSP(); |
1275 | } |
1276 | |
1277 | uint32_t Process::GetNextThreadIndexID(uint64_t thread_id) { |
1278 | return AssignIndexIDToThread(thread_id); |
1279 | } |
1280 | |
1281 | bool Process::HasAssignedIndexIDToThread(uint64_t thread_id) { |
1282 | return (m_thread_id_to_index_id_map.find(thread_id) != |
1283 | m_thread_id_to_index_id_map.end()); |
1284 | } |
1285 | |
1286 | uint32_t Process::AssignIndexIDToThread(uint64_t thread_id) { |
1287 | uint32_t result = 0; |
1288 | std::map<uint64_t, uint32_t>::iterator iterator = |
1289 | m_thread_id_to_index_id_map.find(thread_id); |
1290 | if (iterator == m_thread_id_to_index_id_map.end()) { |
1291 | result = ++m_thread_index_id; |
1292 | m_thread_id_to_index_id_map[thread_id] = result; |
1293 | } else { |
1294 | result = iterator->second; |
1295 | } |
1296 | |
1297 | return result; |
1298 | } |
1299 | |
1300 | StateType Process::GetState() { |
1301 | if (CurrentThreadIsPrivateStateThread()) |
1302 | return m_private_state.GetValue(); |
1303 | else |
1304 | return m_public_state.GetValue(); |
1305 | } |
1306 | |
1307 | void Process::SetPublicState(StateType new_state, bool restarted) { |
1308 | const bool new_state_is_stopped = StateIsStoppedState(new_state, false); |
1309 | if (new_state_is_stopped) { |
1310 | // This will only set the time if the public stop time has no value, so |
1311 | // it is ok to call this multiple times. With a public stop we can't look |
1312 | // at the stop ID because many private stops might have happened, so we |
1313 | // can't check for a stop ID of zero. This allows the "statistics" command |
1314 | // to dump the time it takes to reach somewhere in your code, like a |
1315 | // breakpoint you set. |
1316 | GetTarget().GetStatistics().SetFirstPublicStopTime(); |
1317 | } |
1318 | |
1319 | Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); |
1320 | LLDB_LOG(log, "(plugin = %s, state = %s, restarted = %i)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s, restarted = %i)", GetPluginName( ).data(), StateAsCString(new_state), restarted); } while (0) |
1321 | GetPluginName().data(), StateAsCString(new_state), restarted)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s, restarted = %i)", GetPluginName( ).data(), StateAsCString(new_state), restarted); } while (0); |
1322 | const StateType old_state = m_public_state.GetValue(); |
1323 | m_public_state.SetValue(new_state); |
1324 | |
1325 | // On the transition from Run to Stopped, we unlock the writer end of the run |
1326 | // lock. The lock gets locked in Resume, which is the public API to tell the |
1327 | // program to run. |
1328 | if (!StateChangedIsExternallyHijacked()) { |
1329 | if (new_state == eStateDetached) { |
1330 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) -- unlocking run lock for detach" , GetPluginName().data(), StateAsCString(new_state)); } while (0) |
1331 | "(plugin = %s, state = %s) -- unlocking run lock for detach",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) -- unlocking run lock for detach" , GetPluginName().data(), StateAsCString(new_state)); } while (0) |
1332 | GetPluginName().data(), StateAsCString(new_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) -- unlocking run lock for detach" , GetPluginName().data(), StateAsCString(new_state)); } while (0); |
1333 | m_public_run_lock.SetStopped(); |
1334 | } else { |
1335 | const bool old_state_is_stopped = StateIsStoppedState(old_state, false); |
1336 | if ((old_state_is_stopped != new_state_is_stopped)) { |
1337 | if (new_state_is_stopped && !restarted) { |
1338 | LLDB_LOG(log, "(plugin = %s, state = %s) -- unlocking run lock",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) -- unlocking run lock", GetPluginName ().data(), StateAsCString(new_state)); } while (0) |
1339 | GetPluginName().data(), StateAsCString(new_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) -- unlocking run lock", GetPluginName ().data(), StateAsCString(new_state)); } while (0); |
1340 | m_public_run_lock.SetStopped(); |
1341 | } |
1342 | } |
1343 | } |
1344 | } |
1345 | } |
1346 | |
1347 | Status Process::Resume() { |
1348 | Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); |
1349 | LLDB_LOG(log, "(plugin = %s) -- locking run lock", GetPluginName().data())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) -- locking run lock", GetPluginName().data() ); } while (0); |
1350 | if (!m_public_run_lock.TrySetRunning()) { |
1351 | Status error("Resume request failed - process still running."); |
1352 | LLDB_LOG(log, "(plugin = %s) -- TrySetRunning failed, not resuming.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) -- TrySetRunning failed, not resuming.", GetPluginName ().data()); } while (0) |
1353 | GetPluginName().data())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s) -- TrySetRunning failed, not resuming.", GetPluginName ().data()); } while (0); |
1354 | return error; |
1355 | } |
1356 | Status error = PrivateResume(); |
1357 | if (!error.Success()) { |
1358 | // Undo running state change |
1359 | m_public_run_lock.SetStopped(); |
1360 | } |
1361 | return error; |
1362 | } |
1363 | |
1364 | Status Process::ResumeSynchronous(Stream *stream) { |
1365 | Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); |
1366 | LLDB_LOGF(log, "Process::ResumeSynchronous -- locking run lock")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ResumeSynchronous -- locking run lock" ); } while (0); |
1367 | if (!m_public_run_lock.TrySetRunning()) { |
1368 | Status error("Resume request failed - process still running."); |
1369 | LLDB_LOGF(log, "Process::Resume: -- TrySetRunning failed, not resuming.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::Resume: -- TrySetRunning failed, not resuming." ); } while (0); |
1370 | return error; |
1371 | } |
1372 | |
1373 | ListenerSP listener_sp( |
1374 | Listener::MakeListener(ResumeSynchronousHijackListenerName.data())); |
1375 | HijackProcessEvents(listener_sp); |
1376 | |
1377 | Status error = PrivateResume(); |
1378 | if (error.Success()) { |
1379 | StateType state = |
1380 | WaitForProcessToStop(std::nullopt, nullptr, true, listener_sp, stream, |
1381 | true /* use_run_lock */, SelectMostRelevantFrame); |
1382 | const bool must_be_alive = |
1383 | false; // eStateExited is ok, so this must be false |
1384 | if (!StateIsStoppedState(state, must_be_alive)) |
1385 | error.SetErrorStringWithFormat( |
1386 | "process not in stopped state after synchronous resume: %s", |
1387 | StateAsCString(state)); |
1388 | } else { |
1389 | // Undo running state change |
1390 | m_public_run_lock.SetStopped(); |
1391 | } |
1392 | |
1393 | // Undo the hijacking of process events... |
1394 | RestoreProcessEvents(); |
1395 | |
1396 | return error; |
1397 | } |
1398 | |
1399 | bool Process::StateChangedIsExternallyHijacked() { |
1400 | if (IsHijackedForEvent(eBroadcastBitStateChanged)) { |
1401 | llvm::StringRef hijacking_name = GetHijackingListenerName(); |
1402 | if (!hijacking_name.starts_with("lldb.internal")) |
1403 | return true; |
1404 | } |
1405 | return false; |
1406 | } |
1407 | |
1408 | bool Process::StateChangedIsHijackedForSynchronousResume() { |
1409 | if (IsHijackedForEvent(eBroadcastBitStateChanged)) { |
1410 | llvm::StringRef hijacking_name = GetHijackingListenerName(); |
1411 | if (hijacking_name == ResumeSynchronousHijackListenerName) |
1412 | return true; |
1413 | } |
1414 | return false; |
1415 | } |
1416 | |
1417 | StateType Process::GetPrivateState() { return m_private_state.GetValue(); } |
1418 | |
1419 | void Process::SetPrivateState(StateType new_state) { |
1420 | if (m_finalizing) |
1421 | return; |
1422 | |
1423 | Log *log(GetLog(LLDBLog::State | LLDBLog::Process | LLDBLog::Unwind)); |
1424 | bool state_changed = false; |
1425 | |
1426 | LLDB_LOG(log, "(plugin = %s, state = %s)", GetPluginName().data(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s)", GetPluginName().data(), StateAsCString (new_state)); } while (0) |
1427 | StateAsCString(new_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s)", GetPluginName().data(), StateAsCString (new_state)); } while (0); |
1428 | |
1429 | std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex()); |
1430 | std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex()); |
1431 | |
1432 | const StateType old_state = m_private_state.GetValueNoLock(); |
1433 | state_changed = old_state != new_state; |
1434 | |
1435 | const bool old_state_is_stopped = StateIsStoppedState(old_state, false); |
1436 | const bool new_state_is_stopped = StateIsStoppedState(new_state, false); |
1437 | if (old_state_is_stopped != new_state_is_stopped) { |
1438 | if (new_state_is_stopped) |
1439 | m_private_run_lock.SetStopped(); |
1440 | else |
1441 | m_private_run_lock.SetRunning(); |
1442 | } |
1443 | |
1444 | if (state_changed) { |
1445 | m_private_state.SetValueNoLock(new_state); |
1446 | EventSP event_sp( |
1447 | new Event(eBroadcastBitStateChanged, |
1448 | new ProcessEventData(shared_from_this(), new_state))); |
1449 | if (StateIsStoppedState(new_state, false)) { |
1450 | // Note, this currently assumes that all threads in the list stop when |
1451 | // the process stops. In the future we will want to support a debugging |
1452 | // model where some threads continue to run while others are stopped. |
1453 | // When that happens we will either need a way for the thread list to |
1454 | // identify which threads are stopping or create a special thread list |
1455 | // containing only threads which actually stopped. |
1456 | // |
1457 | // The process plugin is responsible for managing the actual behavior of |
1458 | // the threads and should have stopped any threads that are going to stop |
1459 | // before we get here. |
1460 | m_thread_list.DidStop(); |
1461 | |
1462 | if (m_mod_id.BumpStopID() == 0) |
1463 | GetTarget().GetStatistics().SetFirstPrivateStopTime(); |
1464 | |
1465 | if (!m_mod_id.IsLastResumeForUserExpression()) |
1466 | m_mod_id.SetStopEventForLastNaturalStopID(event_sp); |
1467 | m_memory_cache.Clear(); |
1468 | LLDB_LOG(log, "(plugin = %s, state = %s, stop_id = %u",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s, stop_id = %u", GetPluginName().data (), StateAsCString(new_state), m_mod_id.GetStopID()); } while (0) |
1469 | GetPluginName().data(), StateAsCString(new_state),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s, stop_id = %u", GetPluginName().data (), StateAsCString(new_state), m_mod_id.GetStopID()); } while (0) |
1470 | m_mod_id.GetStopID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s, stop_id = %u", GetPluginName().data (), StateAsCString(new_state), m_mod_id.GetStopID()); } while (0); |
1471 | } |
1472 | |
1473 | m_private_state_broadcaster.BroadcastEvent(event_sp); |
1474 | } else { |
1475 | LLDB_LOG(log, "(plugin = %s, state = %s) state didn't change. Ignoring...",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) state didn't change. Ignoring..." , GetPluginName().data(), StateAsCString(new_state)); } while (0) |
1476 | GetPluginName().data(), StateAsCString(new_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "(plugin = %s, state = %s) state didn't change. Ignoring..." , GetPluginName().data(), StateAsCString(new_state)); } while (0); |
1477 | } |
1478 | } |
1479 | |
1480 | void Process::SetRunningUserExpression(bool on) { |
1481 | m_mod_id.SetRunningUserExpression(on); |
1482 | } |
1483 | |
1484 | void Process::SetRunningUtilityFunction(bool on) { |
1485 | m_mod_id.SetRunningUtilityFunction(on); |
1486 | } |
1487 | |
1488 | addr_t Process::GetImageInfoAddress() { return LLDB_INVALID_ADDRESS(18446744073709551615UL); } |
1489 | |
1490 | const lldb::ABISP &Process::GetABI() { |
1491 | if (!m_abi_sp) |
1492 | m_abi_sp = ABI::FindPlugin(shared_from_this(), GetTarget().GetArchitecture()); |
1493 | return m_abi_sp; |
1494 | } |
1495 | |
1496 | std::vector<LanguageRuntime *> Process::GetLanguageRuntimes() { |
1497 | std::vector<LanguageRuntime *> language_runtimes; |
1498 | |
1499 | if (m_finalizing) |
1500 | return language_runtimes; |
1501 | |
1502 | std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); |
1503 | // Before we pass off a copy of the language runtimes, we must make sure that |
1504 | // our collection is properly populated. It's possible that some of the |
1505 | // language runtimes were not loaded yet, either because nobody requested it |
1506 | // yet or the proper condition for loading wasn't yet met (e.g. libc++.so |
1507 | // hadn't been loaded). |
1508 | for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) { |
1509 | if (LanguageRuntime *runtime = GetLanguageRuntime(lang_type)) |
1510 | language_runtimes.emplace_back(runtime); |
1511 | } |
1512 | |
1513 | return language_runtimes; |
1514 | } |
1515 | |
1516 | LanguageRuntime *Process::GetLanguageRuntime(lldb::LanguageType language) { |
1517 | if (m_finalizing) |
1518 | return nullptr; |
1519 | |
1520 | LanguageRuntime *runtime = nullptr; |
1521 | |
1522 | std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); |
1523 | LanguageRuntimeCollection::iterator pos; |
1524 | pos = m_language_runtimes.find(language); |
1525 | if (pos == m_language_runtimes.end() || !pos->second) { |
1526 | lldb::LanguageRuntimeSP runtime_sp( |
1527 | LanguageRuntime::FindPlugin(this, language)); |
1528 | |
1529 | m_language_runtimes[language] = runtime_sp; |
1530 | runtime = runtime_sp.get(); |
1531 | } else |
1532 | runtime = pos->second.get(); |
1533 | |
1534 | if (runtime) |
1535 | // It's possible that a language runtime can support multiple LanguageTypes, |
1536 | // for example, CPPLanguageRuntime will support eLanguageTypeC_plus_plus, |
1537 | // eLanguageTypeC_plus_plus_03, etc. Because of this, we should get the |
1538 | // primary language type and make sure that our runtime supports it. |
1539 | assert(runtime->GetLanguageType() == Language::GetPrimaryLanguage(language))(static_cast <bool> (runtime->GetLanguageType() == Language ::GetPrimaryLanguage(language)) ? void (0) : __assert_fail ("runtime->GetLanguageType() == Language::GetPrimaryLanguage(language)" , "lldb/source/Target/Process.cpp", 1539, __extension__ __PRETTY_FUNCTION__ )); |
1540 | |
1541 | return runtime; |
1542 | } |
1543 | |
1544 | bool Process::IsPossibleDynamicValue(ValueObject &in_value) { |
1545 | if (m_finalizing) |
1546 | return false; |
1547 | |
1548 | if (in_value.IsDynamic()) |
1549 | return false; |
1550 | LanguageType known_type = in_value.GetObjectRuntimeLanguage(); |
1551 | |
1552 | if (known_type != eLanguageTypeUnknown && known_type != eLanguageTypeC) { |
1553 | LanguageRuntime *runtime = GetLanguageRuntime(known_type); |
1554 | return runtime ? runtime->CouldHaveDynamicValue(in_value) : false; |
1555 | } |
1556 | |
1557 | for (LanguageRuntime *runtime : GetLanguageRuntimes()) { |
1558 | if (runtime->CouldHaveDynamicValue(in_value)) |
1559 | return true; |
1560 | } |
1561 | |
1562 | return false; |
1563 | } |
1564 | |
1565 | void Process::SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers) { |
1566 | m_dynamic_checkers_up.reset(dynamic_checkers); |
1567 | } |
1568 | |
1569 | BreakpointSiteList &Process::GetBreakpointSiteList() { |
1570 | return m_breakpoint_site_list; |
1571 | } |
1572 | |
1573 | const BreakpointSiteList &Process::GetBreakpointSiteList() const { |
1574 | return m_breakpoint_site_list; |
1575 | } |
1576 | |
1577 | void Process::DisableAllBreakpointSites() { |
1578 | m_breakpoint_site_list.ForEach([this](BreakpointSite *bp_site) -> void { |
1579 | // bp_site->SetEnabled(true); |
1580 | DisableBreakpointSite(bp_site); |
1581 | }); |
1582 | } |
1583 | |
1584 | Status Process::ClearBreakpointSiteByID(lldb::user_id_t break_id) { |
1585 | Status error(DisableBreakpointSiteByID(break_id)); |
1586 | |
1587 | if (error.Success()) |
1588 | m_breakpoint_site_list.Remove(break_id); |
1589 | |
1590 | return error; |
1591 | } |
1592 | |
1593 | Status Process::DisableBreakpointSiteByID(lldb::user_id_t break_id) { |
1594 | Status error; |
1595 | BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID(break_id); |
1596 | if (bp_site_sp) { |
1597 | if (bp_site_sp->IsEnabled()) |
1598 | error = DisableBreakpointSite(bp_site_sp.get()); |
1599 | } else { |
1600 | error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64"l" "u", |
1601 | break_id); |
1602 | } |
1603 | |
1604 | return error; |
1605 | } |
1606 | |
1607 | Status Process::EnableBreakpointSiteByID(lldb::user_id_t break_id) { |
1608 | Status error; |
1609 | BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID(break_id); |
1610 | if (bp_site_sp) { |
1611 | if (!bp_site_sp->IsEnabled()) |
1612 | error = EnableBreakpointSite(bp_site_sp.get()); |
1613 | } else { |
1614 | error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64"l" "u", |
1615 | break_id); |
1616 | } |
1617 | return error; |
1618 | } |
1619 | |
1620 | lldb::break_id_t |
1621 | Process::CreateBreakpointSite(const BreakpointLocationSP &owner, |
1622 | bool use_hardware) { |
1623 | addr_t load_addr = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
1624 | |
1625 | bool show_error = true; |
1626 | switch (GetState()) { |
1627 | case eStateInvalid: |
1628 | case eStateUnloaded: |
1629 | case eStateConnected: |
1630 | case eStateAttaching: |
1631 | case eStateLaunching: |
1632 | case eStateDetached: |
1633 | case eStateExited: |
1634 | show_error = false; |
1635 | break; |
1636 | |
1637 | case eStateStopped: |
1638 | case eStateRunning: |
1639 | case eStateStepping: |
1640 | case eStateCrashed: |
1641 | case eStateSuspended: |
1642 | show_error = IsAlive(); |
1643 | break; |
1644 | } |
1645 | |
1646 | // Reset the IsIndirect flag here, in case the location changes from pointing |
1647 | // to a indirect symbol to a regular symbol. |
1648 | owner->SetIsIndirect(false); |
1649 | |
1650 | if (owner->ShouldResolveIndirectFunctions()) { |
1651 | Symbol *symbol = owner->GetAddress().CalculateSymbolContextSymbol(); |
1652 | if (symbol && symbol->IsIndirect()) { |
1653 | Status error; |
1654 | Address symbol_address = symbol->GetAddress(); |
1655 | load_addr = ResolveIndirectFunction(&symbol_address, error); |
1656 | if (!error.Success() && show_error) { |
1657 | GetTarget().GetDebugger().GetErrorStream().Printf( |
1658 | "warning: failed to resolve indirect function at 0x%" PRIx64"l" "x" |
1659 | " for breakpoint %i.%i: %s\n", |
1660 | symbol->GetLoadAddress(&GetTarget()), |
1661 | owner->GetBreakpoint().GetID(), owner->GetID(), |
1662 | error.AsCString() ? error.AsCString() : "unknown error"); |
1663 | return LLDB_INVALID_BREAK_ID0; |
1664 | } |
1665 | Address resolved_address(load_addr); |
1666 | load_addr = resolved_address.GetOpcodeLoadAddress(&GetTarget()); |
1667 | owner->SetIsIndirect(true); |
1668 | } else |
1669 | load_addr = owner->GetAddress().GetOpcodeLoadAddress(&GetTarget()); |
1670 | } else |
1671 | load_addr = owner->GetAddress().GetOpcodeLoadAddress(&GetTarget()); |
1672 | |
1673 | if (load_addr != LLDB_INVALID_ADDRESS(18446744073709551615UL)) { |
1674 | BreakpointSiteSP bp_site_sp; |
1675 | |
1676 | // Look up this breakpoint site. If it exists, then add this new owner, |
1677 | // otherwise create a new breakpoint site and add it. |
1678 | |
1679 | bp_site_sp = m_breakpoint_site_list.FindByAddress(load_addr); |
1680 | |
1681 | if (bp_site_sp) { |
1682 | bp_site_sp->AddOwner(owner); |
1683 | owner->SetBreakpointSite(bp_site_sp); |
1684 | return bp_site_sp->GetID(); |
1685 | } else { |
1686 | bp_site_sp.reset(new BreakpointSite(&m_breakpoint_site_list, owner, |
1687 | load_addr, use_hardware)); |
1688 | if (bp_site_sp) { |
1689 | Status error = EnableBreakpointSite(bp_site_sp.get()); |
1690 | if (error.Success()) { |
1691 | owner->SetBreakpointSite(bp_site_sp); |
1692 | return m_breakpoint_site_list.Add(bp_site_sp); |
1693 | } else { |
1694 | if (show_error || use_hardware) { |
1695 | // Report error for setting breakpoint... |
1696 | GetTarget().GetDebugger().GetErrorStream().Printf( |
1697 | "warning: failed to set breakpoint site at 0x%" PRIx64"l" "x" |
1698 | " for breakpoint %i.%i: %s\n", |
1699 | load_addr, owner->GetBreakpoint().GetID(), owner->GetID(), |
1700 | error.AsCString() ? error.AsCString() : "unknown error"); |
1701 | } |
1702 | } |
1703 | } |
1704 | } |
1705 | } |
1706 | // We failed to enable the breakpoint |
1707 | return LLDB_INVALID_BREAK_ID0; |
1708 | } |
1709 | |
1710 | void Process::RemoveOwnerFromBreakpointSite(lldb::user_id_t owner_id, |
1711 | lldb::user_id_t owner_loc_id, |
1712 | BreakpointSiteSP &bp_site_sp) { |
1713 | uint32_t num_owners = bp_site_sp->RemoveOwner(owner_id, owner_loc_id); |
1714 | if (num_owners == 0) { |
1715 | // Don't try to disable the site if we don't have a live process anymore. |
1716 | if (IsAlive()) |
1717 | DisableBreakpointSite(bp_site_sp.get()); |
1718 | m_breakpoint_site_list.RemoveByAddress(bp_site_sp->GetLoadAddress()); |
1719 | } |
1720 | } |
1721 | |
1722 | size_t Process::RemoveBreakpointOpcodesFromBuffer(addr_t bp_addr, size_t size, |
1723 | uint8_t *buf) const { |
1724 | size_t bytes_removed = 0; |
1725 | BreakpointSiteList bp_sites_in_range; |
1726 | |
1727 | if (m_breakpoint_site_list.FindInRange(bp_addr, bp_addr + size, |
1728 | bp_sites_in_range)) { |
1729 | bp_sites_in_range.ForEach([bp_addr, size, |
1730 | buf](BreakpointSite *bp_site) -> void { |
1731 | if (bp_site->GetType() == BreakpointSite::eSoftware) { |
1732 | addr_t intersect_addr; |
1733 | size_t intersect_size; |
1734 | size_t opcode_offset; |
1735 | if (bp_site->IntersectsRange(bp_addr, size, &intersect_addr, |
1736 | &intersect_size, &opcode_offset)) { |
1737 | assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size)(static_cast <bool> (bp_addr <= intersect_addr && intersect_addr < bp_addr + size) ? void (0) : __assert_fail ("bp_addr <= intersect_addr && intersect_addr < bp_addr + size" , "lldb/source/Target/Process.cpp", 1737, __extension__ __PRETTY_FUNCTION__ )); |
1738 | assert(bp_addr < intersect_addr + intersect_size &&(static_cast <bool> (bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size ) ? void (0) : __assert_fail ("bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size" , "lldb/source/Target/Process.cpp", 1739, __extension__ __PRETTY_FUNCTION__ )) |
1739 | intersect_addr + intersect_size <= bp_addr + size)(static_cast <bool> (bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size ) ? void (0) : __assert_fail ("bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size" , "lldb/source/Target/Process.cpp", 1739, __extension__ __PRETTY_FUNCTION__ )); |
1740 | assert(opcode_offset + intersect_size <= bp_site->GetByteSize())(static_cast <bool> (opcode_offset + intersect_size <= bp_site->GetByteSize()) ? void (0) : __assert_fail ("opcode_offset + intersect_size <= bp_site->GetByteSize()" , "lldb/source/Target/Process.cpp", 1740, __extension__ __PRETTY_FUNCTION__ )); |
1741 | size_t buf_offset = intersect_addr - bp_addr; |
1742 | ::memcpy(buf + buf_offset, |
1743 | bp_site->GetSavedOpcodeBytes() + opcode_offset, |
1744 | intersect_size); |
1745 | } |
1746 | } |
1747 | }); |
1748 | } |
1749 | return bytes_removed; |
1750 | } |
1751 | |
1752 | size_t Process::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) { |
1753 | PlatformSP platform_sp(GetTarget().GetPlatform()); |
1754 | if (platform_sp) |
1755 | return platform_sp->GetSoftwareBreakpointTrapOpcode(GetTarget(), bp_site); |
1756 | return 0; |
1757 | } |
1758 | |
1759 | Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) { |
1760 | Status error; |
1761 | assert(bp_site != nullptr)(static_cast <bool> (bp_site != nullptr) ? void (0) : __assert_fail ("bp_site != nullptr", "lldb/source/Target/Process.cpp", 1761 , __extension__ __PRETTY_FUNCTION__)); |
1762 | Log *log = GetLog(LLDBLog::Breakpoints); |
1763 | const addr_t bp_addr = bp_site->GetLoadAddress(); |
1764 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x", bp_site->GetID(), (uint64_t)bp_addr); } while (0 ) |
1765 | log, "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x", bp_site->GetID(), (uint64_t)bp_addr); } while (0 ) |
1766 | bp_site->GetID(), (uint64_t)bp_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x", bp_site->GetID(), (uint64_t)bp_addr); } while (0 ); |
1767 | if (bp_site->IsEnabled()) { |
1768 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already enabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1769 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already enabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1770 | "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already enabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1771 | " -- already enabled",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already enabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1772 | bp_site->GetID(), (uint64_t)bp_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already enabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0); |
1773 | return error; |
1774 | } |
1775 | |
1776 | if (bp_addr == LLDB_INVALID_ADDRESS(18446744073709551615UL)) { |
1777 | error.SetErrorString("BreakpointSite contains an invalid load address."); |
1778 | return error; |
1779 | } |
1780 | // Ask the lldb::Process subclass to fill in the correct software breakpoint |
1781 | // trap for the breakpoint site |
1782 | const size_t bp_opcode_size = GetSoftwareBreakpointTrapOpcode(bp_site); |
1783 | |
1784 | if (bp_opcode_size == 0) { |
1785 | error.SetErrorStringWithFormat("Process::GetSoftwareBreakpointTrapOpcode() " |
1786 | "returned zero, unable to get breakpoint " |
1787 | "trap for address 0x%" PRIx64"l" "x", |
1788 | bp_addr); |
1789 | } else { |
1790 | const uint8_t *const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes(); |
1791 | |
1792 | if (bp_opcode_bytes == nullptr) { |
1793 | error.SetErrorString( |
1794 | "BreakpointSite doesn't contain a valid breakpoint trap opcode."); |
1795 | return error; |
1796 | } |
1797 | |
1798 | // Save the original opcode by reading it |
1799 | if (DoReadMemory(bp_addr, bp_site->GetSavedOpcodeBytes(), bp_opcode_size, |
1800 | error) == bp_opcode_size) { |
1801 | // Write a software breakpoint in place of the original opcode |
1802 | if (DoWriteMemory(bp_addr, bp_opcode_bytes, bp_opcode_size, error) == |
1803 | bp_opcode_size) { |
1804 | uint8_t verify_bp_opcode_bytes[64]; |
1805 | if (DoReadMemory(bp_addr, verify_bp_opcode_bytes, bp_opcode_size, |
1806 | error) == bp_opcode_size) { |
1807 | if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, |
1808 | bp_opcode_size) == 0) { |
1809 | bp_site->SetEnabled(true); |
1810 | bp_site->SetType(BreakpointSite::eSoftware); |
1811 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1812 | "Process::EnableSoftwareBreakpoint (site_id = %d) "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1813 | "addr = 0x%" PRIx64 " -- SUCCESS",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1814 | bp_site->GetID(), (uint64_t)bp_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0); |
1815 | } else |
1816 | error.SetErrorString( |
1817 | "failed to verify the breakpoint trap in memory."); |
1818 | } else |
1819 | error.SetErrorString( |
1820 | "Unable to read memory to verify breakpoint trap."); |
1821 | } else |
1822 | error.SetErrorString("Unable to write breakpoint trap to memory."); |
1823 | } else |
1824 | error.SetErrorString("Unable to read memory at breakpoint address."); |
1825 | } |
1826 | if (log && error.Fail()) |
1827 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1828 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1829 | "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1830 | " -- FAILED: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1831 | bp_site->GetID(), (uint64_t)bp_addr, error.AsCString())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0); |
1832 | return error; |
1833 | } |
1834 | |
1835 | Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { |
1836 | Status error; |
1837 | assert(bp_site != nullptr)(static_cast <bool> (bp_site != nullptr) ? void (0) : __assert_fail ("bp_site != nullptr", "lldb/source/Target/Process.cpp", 1837 , __extension__ __PRETTY_FUNCTION__)); |
1838 | Log *log = GetLog(LLDBLog::Breakpoints); |
1839 | addr_t bp_addr = bp_site->GetLoadAddress(); |
1840 | lldb::user_id_t breakID = bp_site->GetID(); |
1841 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (breakID = %" "l" "u" ") addr = 0x%" "l" "x", breakID, (uint64_t)bp_addr); } while (0) |
1842 | "Process::DisableSoftwareBreakpoint (breakID = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (breakID = %" "l" "u" ") addr = 0x%" "l" "x", breakID, (uint64_t)bp_addr); } while (0) |
1843 | ") addr = 0x%" PRIx64,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (breakID = %" "l" "u" ") addr = 0x%" "l" "x", breakID, (uint64_t)bp_addr); } while (0) |
1844 | breakID, (uint64_t)bp_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (breakID = %" "l" "u" ") addr = 0x%" "l" "x", breakID, (uint64_t)bp_addr); } while (0); |
1845 | |
1846 | if (bp_site->IsHardware()) { |
1847 | error.SetErrorString("Breakpoint site is a hardware breakpoint."); |
1848 | } else if (bp_site->IsEnabled()) { |
1849 | const size_t break_op_size = bp_site->GetByteSize(); |
1850 | const uint8_t *const break_op = bp_site->GetTrapOpcodeBytes(); |
1851 | if (break_op_size > 0) { |
1852 | // Clear a software breakpoint instruction |
1853 | uint8_t curr_break_op[8]; |
1854 | assert(break_op_size <= sizeof(curr_break_op))(static_cast <bool> (break_op_size <= sizeof(curr_break_op )) ? void (0) : __assert_fail ("break_op_size <= sizeof(curr_break_op)" , "lldb/source/Target/Process.cpp", 1854, __extension__ __PRETTY_FUNCTION__ )); |
1855 | bool break_op_found = false; |
1856 | |
1857 | // Read the breakpoint opcode |
1858 | if (DoReadMemory(bp_addr, curr_break_op, break_op_size, error) == |
1859 | break_op_size) { |
1860 | bool verify = false; |
1861 | // Make sure the breakpoint opcode exists at this address |
1862 | if (::memcmp(curr_break_op, break_op, break_op_size) == 0) { |
1863 | break_op_found = true; |
1864 | // We found a valid breakpoint opcode at this address, now restore |
1865 | // the saved opcode. |
1866 | if (DoWriteMemory(bp_addr, bp_site->GetSavedOpcodeBytes(), |
1867 | break_op_size, error) == break_op_size) { |
1868 | verify = true; |
1869 | } else |
1870 | error.SetErrorString( |
1871 | "Memory write failed when restoring original opcode."); |
1872 | } else { |
1873 | error.SetErrorString( |
1874 | "Original breakpoint trap is no longer in memory."); |
1875 | // Set verify to true and so we can check if the original opcode has |
1876 | // already been restored |
1877 | verify = true; |
1878 | } |
1879 | |
1880 | if (verify) { |
1881 | uint8_t verify_opcode[8]; |
1882 | assert(break_op_size < sizeof(verify_opcode))(static_cast <bool> (break_op_size < sizeof(verify_opcode )) ? void (0) : __assert_fail ("break_op_size < sizeof(verify_opcode)" , "lldb/source/Target/Process.cpp", 1882, __extension__ __PRETTY_FUNCTION__ )); |
1883 | // Verify that our original opcode made it back to the inferior |
1884 | if (DoReadMemory(bp_addr, verify_opcode, break_op_size, error) == |
1885 | break_op_size) { |
1886 | // compare the memory we just read with the original opcode |
1887 | if (::memcmp(bp_site->GetSavedOpcodeBytes(), verify_opcode, |
1888 | break_op_size) == 0) { |
1889 | // SUCCESS |
1890 | bp_site->SetEnabled(false); |
1891 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1892 | "Process::DisableSoftwareBreakpoint (site_id = %d) "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1893 | "addr = 0x%" PRIx64 " -- SUCCESS",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1894 | bp_site->GetID(), (uint64_t)bp_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) " "addr = 0x%" "l" "x" " -- SUCCESS", bp_site->GetID(), (uint64_t )bp_addr); } while (0); |
1895 | return error; |
1896 | } else { |
1897 | if (break_op_found) |
1898 | error.SetErrorString("Failed to restore original opcode."); |
1899 | } |
1900 | } else |
1901 | error.SetErrorString("Failed to read memory to verify that " |
1902 | "breakpoint trap was restored."); |
1903 | } |
1904 | } else |
1905 | error.SetErrorString( |
1906 | "Unable to read memory that should contain the breakpoint trap."); |
1907 | } |
1908 | } else { |
1909 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already disabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1910 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already disabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1911 | "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already disabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1912 | " -- already disabled",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already disabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0) |
1913 | bp_site->GetID(), (uint64_t)bp_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- already disabled", bp_site->GetID(), (uint64_t )bp_addr); } while (0); |
1914 | return error; |
1915 | } |
1916 | |
1917 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1918 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1919 | "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1920 | " -- FAILED: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0) |
1921 | bp_site->GetID(), (uint64_t)bp_addr, error.AsCString())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" "l" "x" " -- FAILED: %s", bp_site->GetID(), (uint64_t)bp_addr , error.AsCString()); } while (0); |
1922 | return error; |
1923 | } |
1924 | |
1925 | // Uncomment to verify memory caching works after making changes to caching |
1926 | // code |
1927 | //#define VERIFY_MEMORY_READS |
1928 | |
1929 | size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { |
1930 | if (ABISP abi_sp = GetABI()) |
1931 | addr = abi_sp->FixAnyAddress(addr); |
1932 | |
1933 | error.Clear(); |
1934 | if (!GetDisableMemoryCache()) { |
1935 | #if defined(VERIFY_MEMORY_READS) |
1936 | // Memory caching is enabled, with debug verification |
1937 | |
1938 | if (buf && size) { |
1939 | // Uncomment the line below to make sure memory caching is working. |
1940 | // I ran this through the test suite and got no assertions, so I am |
1941 | // pretty confident this is working well. If any changes are made to |
1942 | // memory caching, uncomment the line below and test your changes! |
1943 | |
1944 | // Verify all memory reads by using the cache first, then redundantly |
1945 | // reading the same memory from the inferior and comparing to make sure |
1946 | // everything is exactly the same. |
1947 | std::string verify_buf(size, '\0'); |
1948 | assert(verify_buf.size() == size)(static_cast <bool> (verify_buf.size() == size) ? void ( 0) : __assert_fail ("verify_buf.size() == size", "lldb/source/Target/Process.cpp" , 1948, __extension__ __PRETTY_FUNCTION__)); |
1949 | const size_t cache_bytes_read = |
1950 | m_memory_cache.Read(this, addr, buf, size, error); |
1951 | Status verify_error; |
1952 | const size_t verify_bytes_read = |
1953 | ReadMemoryFromInferior(addr, const_cast<char *>(verify_buf.data()), |
1954 | verify_buf.size(), verify_error); |
1955 | assert(cache_bytes_read == verify_bytes_read)(static_cast <bool> (cache_bytes_read == verify_bytes_read ) ? void (0) : __assert_fail ("cache_bytes_read == verify_bytes_read" , "lldb/source/Target/Process.cpp", 1955, __extension__ __PRETTY_FUNCTION__ )); |
1956 | assert(memcmp(buf, verify_buf.data(), verify_buf.size()) == 0)(static_cast <bool> (memcmp(buf, verify_buf.data(), verify_buf .size()) == 0) ? void (0) : __assert_fail ("memcmp(buf, verify_buf.data(), verify_buf.size()) == 0" , "lldb/source/Target/Process.cpp", 1956, __extension__ __PRETTY_FUNCTION__ )); |
1957 | assert(verify_error.Success() == error.Success())(static_cast <bool> (verify_error.Success() == error.Success ()) ? void (0) : __assert_fail ("verify_error.Success() == error.Success()" , "lldb/source/Target/Process.cpp", 1957, __extension__ __PRETTY_FUNCTION__ )); |
1958 | return cache_bytes_read; |
1959 | } |
1960 | return 0; |
1961 | #else // !defined(VERIFY_MEMORY_READS) |
1962 | // Memory caching is enabled, without debug verification |
1963 | |
1964 | return m_memory_cache.Read(addr, buf, size, error); |
1965 | #endif // defined (VERIFY_MEMORY_READS) |
1966 | } else { |
1967 | // Memory caching is disabled |
1968 | |
1969 | return ReadMemoryFromInferior(addr, buf, size, error); |
1970 | } |
1971 | } |
1972 | |
1973 | size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str, |
1974 | Status &error) { |
1975 | char buf[256]; |
1976 | out_str.clear(); |
1977 | addr_t curr_addr = addr; |
1978 | while (true) { |
1979 | size_t length = ReadCStringFromMemory(curr_addr, buf, sizeof(buf), error); |
1980 | if (length == 0) |
1981 | break; |
1982 | out_str.append(buf, length); |
1983 | // If we got "length - 1" bytes, we didn't get the whole C string, we need |
1984 | // to read some more characters |
1985 | if (length == sizeof(buf) - 1) |
1986 | curr_addr += length; |
1987 | else |
1988 | break; |
1989 | } |
1990 | return out_str.size(); |
1991 | } |
1992 | |
1993 | // Deprecated in favor of ReadStringFromMemory which has wchar support and |
1994 | // correct code to find null terminators. |
1995 | size_t Process::ReadCStringFromMemory(addr_t addr, char *dst, |
1996 | size_t dst_max_len, |
1997 | Status &result_error) { |
1998 | size_t total_cstr_len = 0; |
1999 | if (dst && dst_max_len) { |
2000 | result_error.Clear(); |
2001 | // NULL out everything just to be safe |
2002 | memset(dst, 0, dst_max_len); |
2003 | Status error; |
2004 | addr_t curr_addr = addr; |
2005 | const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize(); |
2006 | size_t bytes_left = dst_max_len - 1; |
2007 | char *curr_dst = dst; |
2008 | |
2009 | while (bytes_left > 0) { |
2010 | addr_t cache_line_bytes_left = |
2011 | cache_line_size - (curr_addr % cache_line_size); |
2012 | addr_t bytes_to_read = |
2013 | std::min<addr_t>(bytes_left, cache_line_bytes_left); |
2014 | size_t bytes_read = ReadMemory(curr_addr, curr_dst, bytes_to_read, error); |
2015 | |
2016 | if (bytes_read == 0) { |
2017 | result_error = error; |
2018 | dst[total_cstr_len] = '\0'; |
2019 | break; |
2020 | } |
2021 | const size_t len = strlen(curr_dst); |
2022 | |
2023 | total_cstr_len += len; |
2024 | |
2025 | if (len < bytes_to_read) |
2026 | break; |
2027 | |
2028 | curr_dst += bytes_read; |
2029 | curr_addr += bytes_read; |
2030 | bytes_left -= bytes_read; |
2031 | } |
2032 | } else { |
2033 | if (dst == nullptr) |
2034 | result_error.SetErrorString("invalid arguments"); |
2035 | else |
2036 | result_error.Clear(); |
2037 | } |
2038 | return total_cstr_len; |
2039 | } |
2040 | |
2041 | size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size, |
2042 | Status &error) { |
2043 | LLDB_SCOPED_TIMER()static ::lldb_private::Timer::Category _cat(__PRETTY_FUNCTION__ ); ::lldb_private::Timer _scoped_timer(_cat, "%s", __PRETTY_FUNCTION__ ); |
2044 | |
2045 | if (ABISP abi_sp = GetABI()) |
2046 | addr = abi_sp->FixAnyAddress(addr); |
2047 | |
2048 | if (buf == nullptr || size == 0) |
2049 | return 0; |
2050 | |
2051 | size_t bytes_read = 0; |
2052 | uint8_t *bytes = (uint8_t *)buf; |
2053 | |
2054 | while (bytes_read < size) { |
2055 | const size_t curr_size = size - bytes_read; |
2056 | const size_t curr_bytes_read = |
2057 | DoReadMemory(addr + bytes_read, bytes + bytes_read, curr_size, error); |
2058 | bytes_read += curr_bytes_read; |
2059 | if (curr_bytes_read == curr_size || curr_bytes_read == 0) |
2060 | break; |
2061 | } |
2062 | |
2063 | // Replace any software breakpoint opcodes that fall into this range back |
2064 | // into "buf" before we return |
2065 | if (bytes_read > 0) |
2066 | RemoveBreakpointOpcodesFromBuffer(addr, bytes_read, (uint8_t *)buf); |
2067 | return bytes_read; |
2068 | } |
2069 | |
2070 | uint64_t Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr, |
2071 | size_t integer_byte_size, |
2072 | uint64_t fail_value, |
2073 | Status &error) { |
2074 | Scalar scalar; |
2075 | if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar, |
2076 | error)) |
2077 | return scalar.ULongLong(fail_value); |
2078 | return fail_value; |
2079 | } |
2080 | |
2081 | int64_t Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr, |
2082 | size_t integer_byte_size, |
2083 | int64_t fail_value, |
2084 | Status &error) { |
2085 | Scalar scalar; |
2086 | if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, true, scalar, |
2087 | error)) |
2088 | return scalar.SLongLong(fail_value); |
2089 | return fail_value; |
2090 | } |
2091 | |
2092 | addr_t Process::ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error) { |
2093 | Scalar scalar; |
2094 | if (ReadScalarIntegerFromMemory(vm_addr, GetAddressByteSize(), false, scalar, |
2095 | error)) |
2096 | return scalar.ULongLong(LLDB_INVALID_ADDRESS(18446744073709551615UL)); |
2097 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); |
2098 | } |
2099 | |
2100 | bool Process::WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value, |
2101 | Status &error) { |
2102 | Scalar scalar; |
2103 | const uint32_t addr_byte_size = GetAddressByteSize(); |
2104 | if (addr_byte_size <= 4) |
2105 | scalar = (uint32_t)ptr_value; |
2106 | else |
2107 | scalar = ptr_value; |
2108 | return WriteScalarToMemory(vm_addr, scalar, addr_byte_size, error) == |
2109 | addr_byte_size; |
2110 | } |
2111 | |
2112 | size_t Process::WriteMemoryPrivate(addr_t addr, const void *buf, size_t size, |
2113 | Status &error) { |
2114 | size_t bytes_written = 0; |
2115 | const uint8_t *bytes = (const uint8_t *)buf; |
2116 | |
2117 | while (bytes_written < size) { |
2118 | const size_t curr_size = size - bytes_written; |
2119 | const size_t curr_bytes_written = DoWriteMemory( |
2120 | addr + bytes_written, bytes + bytes_written, curr_size, error); |
2121 | bytes_written += curr_bytes_written; |
2122 | if (curr_bytes_written == curr_size || curr_bytes_written == 0) |
2123 | break; |
2124 | } |
2125 | return bytes_written; |
2126 | } |
2127 | |
2128 | size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size, |
2129 | Status &error) { |
2130 | if (ABISP abi_sp = GetABI()) |
2131 | addr = abi_sp->FixAnyAddress(addr); |
2132 | |
2133 | #if defined(ENABLE_MEMORY_CACHING) |
2134 | m_memory_cache.Flush(addr, size); |
2135 | #endif |
2136 | |
2137 | if (buf == nullptr || size == 0) |
2138 | return 0; |
2139 | |
2140 | m_mod_id.BumpMemoryID(); |
2141 | |
2142 | // We need to write any data that would go where any current software traps |
2143 | // (enabled software breakpoints) any software traps (breakpoints) that we |
2144 | // may have placed in our tasks memory. |
2145 | |
2146 | BreakpointSiteList bp_sites_in_range; |
2147 | if (!m_breakpoint_site_list.FindInRange(addr, addr + size, bp_sites_in_range)) |
2148 | return WriteMemoryPrivate(addr, buf, size, error); |
2149 | |
2150 | // No breakpoint sites overlap |
2151 | if (bp_sites_in_range.IsEmpty()) |
2152 | return WriteMemoryPrivate(addr, buf, size, error); |
2153 | |
2154 | const uint8_t *ubuf = (const uint8_t *)buf; |
2155 | uint64_t bytes_written = 0; |
2156 | |
2157 | bp_sites_in_range.ForEach([this, addr, size, &bytes_written, &ubuf, |
2158 | &error](BreakpointSite *bp) -> void { |
2159 | if (error.Fail()) |
2160 | return; |
2161 | |
2162 | if (bp->GetType() != BreakpointSite::eSoftware) |
2163 | return; |
2164 | |
2165 | addr_t intersect_addr; |
2166 | size_t intersect_size; |
2167 | size_t opcode_offset; |
2168 | const bool intersects = bp->IntersectsRange( |
2169 | addr, size, &intersect_addr, &intersect_size, &opcode_offset); |
2170 | UNUSED_IF_ASSERT_DISABLED(intersects)((void)(intersects)); |
2171 | assert(intersects)(static_cast <bool> (intersects) ? void (0) : __assert_fail ("intersects", "lldb/source/Target/Process.cpp", 2171, __extension__ __PRETTY_FUNCTION__)); |
2172 | assert(addr <= intersect_addr && intersect_addr < addr + size)(static_cast <bool> (addr <= intersect_addr && intersect_addr < addr + size) ? void (0) : __assert_fail ( "addr <= intersect_addr && intersect_addr < addr + size" , "lldb/source/Target/Process.cpp", 2172, __extension__ __PRETTY_FUNCTION__ )); |
2173 | assert(addr < intersect_addr + intersect_size &&(static_cast <bool> (addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size ) ? void (0) : __assert_fail ("addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size" , "lldb/source/Target/Process.cpp", 2174, __extension__ __PRETTY_FUNCTION__ )) |
2174 | intersect_addr + intersect_size <= addr + size)(static_cast <bool> (addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size ) ? void (0) : __assert_fail ("addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size" , "lldb/source/Target/Process.cpp", 2174, __extension__ __PRETTY_FUNCTION__ )); |
2175 | assert(opcode_offset + intersect_size <= bp->GetByteSize())(static_cast <bool> (opcode_offset + intersect_size <= bp->GetByteSize()) ? void (0) : __assert_fail ("opcode_offset + intersect_size <= bp->GetByteSize()" , "lldb/source/Target/Process.cpp", 2175, __extension__ __PRETTY_FUNCTION__ )); |
2176 | |
2177 | // Check for bytes before this breakpoint |
2178 | const addr_t curr_addr = addr + bytes_written; |
2179 | if (intersect_addr > curr_addr) { |
2180 | // There are some bytes before this breakpoint that we need to just |
2181 | // write to memory |
2182 | size_t curr_size = intersect_addr - curr_addr; |
2183 | size_t curr_bytes_written = |
2184 | WriteMemoryPrivate(curr_addr, ubuf + bytes_written, curr_size, error); |
2185 | bytes_written += curr_bytes_written; |
2186 | if (curr_bytes_written != curr_size) { |
2187 | // We weren't able to write all of the requested bytes, we are |
2188 | // done looping and will return the number of bytes that we have |
2189 | // written so far. |
2190 | if (error.Success()) |
2191 | error.SetErrorToGenericError(); |
2192 | } |
2193 | } |
2194 | // Now write any bytes that would cover up any software breakpoints |
2195 | // directly into the breakpoint opcode buffer |
2196 | ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, |
2197 | intersect_size); |
2198 | bytes_written += intersect_size; |
2199 | }); |
2200 | |
2201 | // Write any remaining bytes after the last breakpoint if we have any left |
2202 | if (bytes_written < size) |
2203 | bytes_written += |
2204 | WriteMemoryPrivate(addr + bytes_written, ubuf + bytes_written, |
2205 | size - bytes_written, error); |
2206 | |
2207 | return bytes_written; |
2208 | } |
2209 | |
2210 | size_t Process::WriteScalarToMemory(addr_t addr, const Scalar &scalar, |
2211 | size_t byte_size, Status &error) { |
2212 | if (byte_size == UINT32_MAX(4294967295U)) |
2213 | byte_size = scalar.GetByteSize(); |
2214 | if (byte_size > 0) { |
2215 | uint8_t buf[32]; |
2216 | const size_t mem_size = |
2217 | scalar.GetAsMemoryData(buf, byte_size, GetByteOrder(), error); |
2218 | if (mem_size > 0) |
2219 | return WriteMemory(addr, buf, mem_size, error); |
2220 | else |
2221 | error.SetErrorString("failed to get scalar as memory data"); |
2222 | } else { |
2223 | error.SetErrorString("invalid scalar value"); |
2224 | } |
2225 | return 0; |
2226 | } |
2227 | |
2228 | size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size, |
2229 | bool is_signed, Scalar &scalar, |
2230 | Status &error) { |
2231 | uint64_t uval = 0; |
2232 | if (byte_size == 0) { |
2233 | error.SetErrorString("byte size is zero"); |
2234 | } else if (byte_size & (byte_size - 1)) { |
2235 | error.SetErrorStringWithFormat("byte size %u is not a power of 2", |
2236 | byte_size); |
2237 | } else if (byte_size <= sizeof(uval)) { |
2238 | const size_t bytes_read = ReadMemory(addr, &uval, byte_size, error); |
2239 | if (bytes_read == byte_size) { |
2240 | DataExtractor data(&uval, sizeof(uval), GetByteOrder(), |
2241 | GetAddressByteSize()); |
2242 | lldb::offset_t offset = 0; |
2243 | if (byte_size <= 4) |
2244 | scalar = data.GetMaxU32(&offset, byte_size); |
2245 | else |
2246 | scalar = data.GetMaxU64(&offset, byte_size); |
2247 | if (is_signed) |
2248 | scalar.SignExtend(byte_size * 8); |
2249 | return bytes_read; |
2250 | } |
2251 | } else { |
2252 | error.SetErrorStringWithFormat( |
2253 | "byte size of %u is too large for integer scalar type", byte_size); |
2254 | } |
2255 | return 0; |
2256 | } |
2257 | |
2258 | Status Process::WriteObjectFile(std::vector<ObjectFile::LoadableData> entries) { |
2259 | Status error; |
2260 | for (const auto &Entry : entries) { |
2261 | WriteMemory(Entry.Dest, Entry.Contents.data(), Entry.Contents.size(), |
2262 | error); |
2263 | if (!error.Success()) |
2264 | break; |
2265 | } |
2266 | return error; |
2267 | } |
2268 | |
2269 | #define USE_ALLOCATE_MEMORY_CACHE1 1 |
2270 | addr_t Process::AllocateMemory(size_t size, uint32_t permissions, |
2271 | Status &error) { |
2272 | if (GetPrivateState() != eStateStopped) { |
2273 | error.SetErrorToGenericError(); |
2274 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); |
2275 | } |
2276 | |
2277 | #if defined(USE_ALLOCATE_MEMORY_CACHE1) |
2278 | return m_allocated_memory_cache.AllocateMemory(size, permissions, error); |
2279 | #else |
2280 | addr_t allocated_addr = DoAllocateMemory(size, permissions, error); |
2281 | Log *log = GetLog(LLDBLog::Process); |
2282 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0) |
2283 | "Process::AllocateMemory(size=%" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0) |
2284 | ", permissions=%s) => 0x%16.16" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0) |
2285 | " (m_stop_id = %u m_memory_id = %u)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0) |
2286 | (uint64_t)size, GetPermissionsAsCString(permissions),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0) |
2287 | (uint64_t)allocated_addr, m_mod_id.GetStopID(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0) |
2288 | m_mod_id.GetMemoryID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AllocateMemory(size=%" "l" "u" ", permissions=%s) => 0x%16.16" "l" "x" " (m_stop_id = %u m_memory_id = %u)" , (uint64_t)size, GetPermissionsAsCString(permissions), (uint64_t )allocated_addr, m_mod_id.GetStopID(), m_mod_id.GetMemoryID() ); } while (0); |
2289 | return allocated_addr; |
2290 | #endif |
2291 | } |
2292 | |
2293 | addr_t Process::CallocateMemory(size_t size, uint32_t permissions, |
2294 | Status &error) { |
2295 | addr_t return_addr = AllocateMemory(size, permissions, error); |
2296 | if (error.Success()) { |
2297 | std::string buffer(size, 0); |
2298 | WriteMemory(return_addr, buffer.c_str(), size, error); |
2299 | } |
2300 | return return_addr; |
2301 | } |
2302 | |
2303 | bool Process::CanJIT() { |
2304 | if (m_can_jit == eCanJITDontKnow) { |
2305 | Log *log = GetLog(LLDBLog::Process); |
2306 | Status err; |
2307 | |
2308 | uint64_t allocated_memory = AllocateMemory( |
2309 | 8, ePermissionsReadable | ePermissionsWritable | ePermissionsExecutable, |
2310 | err); |
2311 | |
2312 | if (err.Success()) { |
2313 | m_can_jit = eCanJITYes; |
2314 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test passed, CanJIT () is true" , __FUNCTION__, GetID()); } while (0) |
2315 | "Process::%s pid %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test passed, CanJIT () is true" , __FUNCTION__, GetID()); } while (0) |
2316 | " allocation test passed, CanJIT () is true",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test passed, CanJIT () is true" , __FUNCTION__, GetID()); } while (0) |
2317 | __FUNCTION__, GetID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test passed, CanJIT () is true" , __FUNCTION__, GetID()); } while (0); |
2318 | } else { |
2319 | m_can_jit = eCanJITNo; |
2320 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test failed, CanJIT () is false: %s" , __FUNCTION__, GetID(), err.AsCString()); } while (0) |
2321 | "Process::%s pid %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test failed, CanJIT () is false: %s" , __FUNCTION__, GetID(), err.AsCString()); } while (0) |
2322 | " allocation test failed, CanJIT () is false: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test failed, CanJIT () is false: %s" , __FUNCTION__, GetID(), err.AsCString()); } while (0) |
2323 | __FUNCTION__, GetID(), err.AsCString())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pid %" "l" "u" " allocation test failed, CanJIT () is false: %s" , __FUNCTION__, GetID(), err.AsCString()); } while (0); |
2324 | } |
2325 | |
2326 | DeallocateMemory(allocated_memory); |
2327 | } |
2328 | |
2329 | return m_can_jit == eCanJITYes; |
2330 | } |
2331 | |
2332 | void Process::SetCanJIT(bool can_jit) { |
2333 | m_can_jit = (can_jit ? eCanJITYes : eCanJITNo); |
2334 | } |
2335 | |
2336 | void Process::SetCanRunCode(bool can_run_code) { |
2337 | SetCanJIT(can_run_code); |
2338 | m_can_interpret_function_calls = can_run_code; |
2339 | } |
2340 | |
2341 | Status Process::DeallocateMemory(addr_t ptr) { |
2342 | Status error; |
2343 | #if defined(USE_ALLOCATE_MEMORY_CACHE1) |
2344 | if (!m_allocated_memory_cache.DeallocateMemory(ptr)) { |
2345 | error.SetErrorStringWithFormat( |
2346 | "deallocation of memory at 0x%" PRIx64"l" "x" " failed.", (uint64_t)ptr); |
2347 | } |
2348 | #else |
2349 | error = DoDeallocateMemory(ptr); |
2350 | |
2351 | Log *log = GetLog(LLDBLog::Process); |
2352 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DeallocateMemory(addr=0x%16.16" "l" "x" ") => err = %s (m_stop_id = %u, m_memory_id = %u)" , ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(), m_mod_id .GetMemoryID()); } while (0) |
2353 | "Process::DeallocateMemory(addr=0x%16.16" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DeallocateMemory(addr=0x%16.16" "l" "x" ") => err = %s (m_stop_id = %u, m_memory_id = %u)" , ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(), m_mod_id .GetMemoryID()); } while (0) |
2354 | ") => err = %s (m_stop_id = %u, m_memory_id = %u)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DeallocateMemory(addr=0x%16.16" "l" "x" ") => err = %s (m_stop_id = %u, m_memory_id = %u)" , ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(), m_mod_id .GetMemoryID()); } while (0) |
2355 | ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DeallocateMemory(addr=0x%16.16" "l" "x" ") => err = %s (m_stop_id = %u, m_memory_id = %u)" , ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(), m_mod_id .GetMemoryID()); } while (0) |
2356 | m_mod_id.GetMemoryID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::DeallocateMemory(addr=0x%16.16" "l" "x" ") => err = %s (m_stop_id = %u, m_memory_id = %u)" , ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(), m_mod_id .GetMemoryID()); } while (0); |
2357 | #endif |
2358 | return error; |
2359 | } |
2360 | |
2361 | bool Process::GetWatchpointReportedAfter() { |
2362 | if (std::optional<bool> subclass_override = DoGetWatchpointReportedAfter()) |
2363 | return *subclass_override; |
2364 | |
2365 | bool reported_after = true; |
2366 | const ArchSpec &arch = GetTarget().GetArchitecture(); |
2367 | if (!arch.IsValid()) |
2368 | return reported_after; |
2369 | llvm::Triple triple = arch.GetTriple(); |
2370 | |
2371 | if (triple.isMIPS() || triple.isPPC64() || triple.isRISCV() || |
2372 | triple.isAArch64() || triple.isArmMClass() || triple.isARM()) |
2373 | reported_after = false; |
2374 | |
2375 | return reported_after; |
2376 | } |
2377 | |
2378 | ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec, |
2379 | lldb::addr_t header_addr, |
2380 | size_t size_to_read) { |
2381 | Log *log = GetLog(LLDBLog::Host); |
2382 | if (log) { |
2383 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ReadModuleFromMemory reading %s binary from memory" , file_spec.GetPath().c_str()); } while (0) |
2384 | "Process::ReadModuleFromMemory reading %s binary from memory",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ReadModuleFromMemory reading %s binary from memory" , file_spec.GetPath().c_str()); } while (0) |
2385 | file_spec.GetPath().c_str())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ReadModuleFromMemory reading %s binary from memory" , file_spec.GetPath().c_str()); } while (0); |
2386 | } |
2387 | ModuleSP module_sp(new Module(file_spec, ArchSpec())); |
2388 | if (module_sp) { |
2389 | Status error; |
2390 | ObjectFile *objfile = module_sp->GetMemoryObjectFile( |
2391 | shared_from_this(), header_addr, error, size_to_read); |
2392 | if (objfile) |
2393 | return module_sp; |
2394 | } |
2395 | return ModuleSP(); |
2396 | } |
2397 | |
2398 | bool Process::GetLoadAddressPermissions(lldb::addr_t load_addr, |
2399 | uint32_t &permissions) { |
2400 | MemoryRegionInfo range_info; |
2401 | permissions = 0; |
2402 | Status error(GetMemoryRegionInfo(load_addr, range_info)); |
2403 | if (!error.Success()) |
2404 | return false; |
2405 | if (range_info.GetReadable() == MemoryRegionInfo::eDontKnow || |
2406 | range_info.GetWritable() == MemoryRegionInfo::eDontKnow || |
2407 | range_info.GetExecutable() == MemoryRegionInfo::eDontKnow) { |
2408 | return false; |
2409 | } |
2410 | |
2411 | if (range_info.GetReadable() == MemoryRegionInfo::eYes) |
2412 | permissions |= lldb::ePermissionsReadable; |
2413 | |
2414 | if (range_info.GetWritable() == MemoryRegionInfo::eYes) |
2415 | permissions |= lldb::ePermissionsWritable; |
2416 | |
2417 | if (range_info.GetExecutable() == MemoryRegionInfo::eYes) |
2418 | permissions |= lldb::ePermissionsExecutable; |
2419 | |
2420 | return true; |
2421 | } |
2422 | |
2423 | Status Process::EnableWatchpoint(Watchpoint *watchpoint, bool notify) { |
2424 | Status error; |
2425 | error.SetErrorString("watchpoints are not supported"); |
2426 | return error; |
2427 | } |
2428 | |
2429 | Status Process::DisableWatchpoint(Watchpoint *watchpoint, bool notify) { |
2430 | Status error; |
2431 | error.SetErrorString("watchpoints are not supported"); |
2432 | return error; |
2433 | } |
2434 | |
2435 | StateType |
2436 | Process::WaitForProcessStopPrivate(EventSP &event_sp, |
2437 | const Timeout<std::micro> &timeout) { |
2438 | StateType state; |
2439 | |
2440 | while (true) { |
2441 | event_sp.reset(); |
2442 | state = GetStateChangedEventsPrivate(event_sp, timeout); |
2443 | |
2444 | if (StateIsStoppedState(state, false)) |
2445 | break; |
2446 | |
2447 | // If state is invalid, then we timed out |
2448 | if (state == eStateInvalid) |
2449 | break; |
2450 | |
2451 | if (event_sp) |
2452 | HandlePrivateEvent(event_sp); |
2453 | } |
2454 | return state; |
2455 | } |
2456 | |
2457 | void Process::LoadOperatingSystemPlugin(bool flush) { |
2458 | if (flush) |
2459 | m_thread_list.Clear(); |
2460 | m_os_up.reset(OperatingSystem::FindPlugin(this, nullptr)); |
2461 | if (flush) |
2462 | Flush(); |
2463 | } |
2464 | |
2465 | Status Process::Launch(ProcessLaunchInfo &launch_info) { |
2466 | StateType state_after_launch = eStateInvalid; |
2467 | EventSP first_stop_event_sp; |
2468 | Status status = |
2469 | LaunchPrivate(launch_info, state_after_launch, first_stop_event_sp); |
2470 | if (status.Fail()) |
2471 | return status; |
2472 | |
2473 | if (state_after_launch != eStateStopped && |
2474 | state_after_launch != eStateCrashed) |
2475 | return Status(); |
2476 | |
2477 | // Note, the stop event was consumed above, but not handled. This |
2478 | // was done to give DidLaunch a chance to run. The target is either |
2479 | // stopped or crashed. Directly set the state. This is done to |
2480 | // prevent a stop message with a bunch of spurious output on thread |
2481 | // status, as well as not pop a ProcessIOHandler. |
2482 | SetPublicState(state_after_launch, false); |
2483 | |
2484 | if (PrivateStateThreadIsValid()) |
2485 | ResumePrivateStateThread(); |
2486 | else |
2487 | StartPrivateStateThread(); |
2488 | |
2489 | // Target was stopped at entry as was intended. Need to notify the |
2490 | // listeners about it. |
2491 | if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) |
2492 | HandlePrivateEvent(first_stop_event_sp); |
2493 | |
2494 | return Status(); |
2495 | } |
2496 | |
2497 | Status Process::LaunchPrivate(ProcessLaunchInfo &launch_info, StateType &state, |
2498 | EventSP &event_sp) { |
2499 | Status error; |
2500 | m_abi_sp.reset(); |
2501 | m_dyld_up.reset(); |
2502 | m_jit_loaders_up.reset(); |
2503 | m_system_runtime_up.reset(); |
2504 | m_os_up.reset(); |
2505 | m_process_input_reader.reset(); |
2506 | |
2507 | Module *exe_module = GetTarget().GetExecutableModulePointer(); |
2508 | |
2509 | // The "remote executable path" is hooked up to the local Executable |
2510 | // module. But we should be able to debug a remote process even if the |
2511 | // executable module only exists on the remote. However, there needs to |
2512 | // be a way to express this path, without actually having a module. |
2513 | // The way to do that is to set the ExecutableFile in the LaunchInfo. |
2514 | // Figure that out here: |
2515 | |
2516 | FileSpec exe_spec_to_use; |
2517 | if (!exe_module) { |
2518 | if (!launch_info.GetExecutableFile()) { |
2519 | error.SetErrorString("executable module does not exist"); |
2520 | return error; |
2521 | } |
2522 | exe_spec_to_use = launch_info.GetExecutableFile(); |
2523 | } else |
2524 | exe_spec_to_use = exe_module->GetFileSpec(); |
2525 | |
2526 | if (exe_module && FileSystem::Instance().Exists(exe_module->GetFileSpec())) { |
2527 | // Install anything that might need to be installed prior to launching. |
2528 | // For host systems, this will do nothing, but if we are connected to a |
2529 | // remote platform it will install any needed binaries |
2530 | error = GetTarget().Install(&launch_info); |
2531 | if (error.Fail()) |
2532 | return error; |
2533 | } |
2534 | |
2535 | // Listen and queue events that are broadcasted during the process launch. |
2536 | ListenerSP listener_sp(Listener::MakeListener("LaunchEventHijack")); |
2537 | HijackProcessEvents(listener_sp); |
2538 | auto on_exit = llvm::make_scope_exit([this]() { RestoreProcessEvents(); }); |
2539 | |
2540 | if (PrivateStateThreadIsValid()) |
2541 | PausePrivateStateThread(); |
2542 | |
2543 | error = WillLaunch(exe_module); |
2544 | if (error.Fail()) { |
2545 | std::string local_exec_file_path = exe_spec_to_use.GetPath(); |
2546 | return Status("file doesn't exist: '%s'", local_exec_file_path.c_str()); |
2547 | } |
2548 | |
2549 | const bool restarted = false; |
2550 | SetPublicState(eStateLaunching, restarted); |
2551 | m_should_detach = false; |
2552 | |
2553 | if (m_public_run_lock.TrySetRunning()) { |
2554 | // Now launch using these arguments. |
2555 | error = DoLaunch(exe_module, launch_info); |
2556 | } else { |
2557 | // This shouldn't happen |
2558 | error.SetErrorString("failed to acquire process run lock"); |
2559 | } |
2560 | |
2561 | if (error.Fail()) { |
2562 | if (GetID() != LLDB_INVALID_PROCESS_ID0) { |
2563 | SetID(LLDB_INVALID_PROCESS_ID0); |
2564 | const char *error_string = error.AsCString(); |
2565 | if (error_string == nullptr) |
2566 | error_string = "launch failed"; |
2567 | SetExitStatus(-1, error_string); |
2568 | } |
2569 | return error; |
2570 | } |
2571 | |
2572 | // Now wait for the process to launch and return control to us, and then |
2573 | // call DidLaunch: |
2574 | state = WaitForProcessStopPrivate(event_sp, seconds(10)); |
2575 | |
2576 | if (state == eStateInvalid || !event_sp) { |
2577 | // We were able to launch the process, but we failed to catch the |
2578 | // initial stop. |
2579 | error.SetErrorString("failed to catch stop after launch"); |
2580 | SetExitStatus(0, error.AsCString()); |
2581 | Destroy(false); |
2582 | return error; |
2583 | } |
2584 | |
2585 | if (state == eStateExited) { |
2586 | // We exited while trying to launch somehow. Don't call DidLaunch |
2587 | // as that's not likely to work, and return an invalid pid. |
2588 | HandlePrivateEvent(event_sp); |
2589 | return Status(); |
2590 | } |
2591 | |
2592 | if (state == eStateStopped || state == eStateCrashed) { |
2593 | DidLaunch(); |
2594 | |
2595 | // Now that we know the process type, update its signal responses from the |
2596 | // ones stored in the Target: |
2597 | if (m_unix_signals_sp) { |
2598 | StreamSP warning_strm = GetTarget().GetDebugger().GetAsyncErrorStream(); |
2599 | GetTarget().UpdateSignalsFromDummy(m_unix_signals_sp, warning_strm); |
2600 | } |
2601 | |
2602 | DynamicLoader *dyld = GetDynamicLoader(); |
2603 | if (dyld) |
2604 | dyld->DidLaunch(); |
2605 | |
2606 | GetJITLoaders().DidLaunch(); |
2607 | |
2608 | SystemRuntime *system_runtime = GetSystemRuntime(); |
2609 | if (system_runtime) |
2610 | system_runtime->DidLaunch(); |
2611 | |
2612 | if (!m_os_up) |
2613 | LoadOperatingSystemPlugin(false); |
2614 | |
2615 | // We successfully launched the process and stopped, now it the |
2616 | // right time to set up signal filters before resuming. |
2617 | UpdateAutomaticSignalFiltering(); |
2618 | return Status(); |
2619 | } |
2620 | |
2621 | return Status("Unexpected process state after the launch: %s, expected %s, " |
2622 | "%s, %s or %s", |
2623 | StateAsCString(state), StateAsCString(eStateInvalid), |
2624 | StateAsCString(eStateExited), StateAsCString(eStateStopped), |
2625 | StateAsCString(eStateCrashed)); |
2626 | } |
2627 | |
2628 | Status Process::LoadCore() { |
2629 | Status error = DoLoadCore(); |
2630 | if (error.Success()) { |
2631 | ListenerSP listener_sp( |
2632 | Listener::MakeListener("lldb.process.load_core_listener")); |
2633 | HijackProcessEvents(listener_sp); |
2634 | |
2635 | if (PrivateStateThreadIsValid()) |
2636 | ResumePrivateStateThread(); |
2637 | else |
2638 | StartPrivateStateThread(); |
2639 | |
2640 | DynamicLoader *dyld = GetDynamicLoader(); |
2641 | if (dyld) |
2642 | dyld->DidAttach(); |
2643 | |
2644 | GetJITLoaders().DidAttach(); |
2645 | |
2646 | SystemRuntime *system_runtime = GetSystemRuntime(); |
2647 | if (system_runtime) |
2648 | system_runtime->DidAttach(); |
2649 | |
2650 | if (!m_os_up) |
2651 | LoadOperatingSystemPlugin(false); |
2652 | |
2653 | // We successfully loaded a core file, now pretend we stopped so we can |
2654 | // show all of the threads in the core file and explore the crashed state. |
2655 | SetPrivateState(eStateStopped); |
2656 | |
2657 | // Wait for a stopped event since we just posted one above... |
2658 | lldb::EventSP event_sp; |
2659 | StateType state = |
2660 | WaitForProcessToStop(std::nullopt, &event_sp, true, listener_sp, |
2661 | nullptr, true, SelectMostRelevantFrame); |
2662 | |
2663 | if (!StateIsStoppedState(state, false)) { |
2664 | Log *log = GetLog(LLDBLog::Process); |
2665 | LLDB_LOGF(log, "Process::Halt() failed to stop, state is: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::Halt() failed to stop, state is: %s" , StateAsCString(state)); } while (0) |
2666 | StateAsCString(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::Halt() failed to stop, state is: %s" , StateAsCString(state)); } while (0); |
2667 | error.SetErrorString( |
2668 | "Did not get stopped event after loading the core file."); |
2669 | } |
2670 | RestoreProcessEvents(); |
2671 | } |
2672 | return error; |
2673 | } |
2674 | |
2675 | DynamicLoader *Process::GetDynamicLoader() { |
2676 | if (!m_dyld_up) |
2677 | m_dyld_up.reset(DynamicLoader::FindPlugin(this, "")); |
2678 | return m_dyld_up.get(); |
2679 | } |
2680 | |
2681 | void Process::SetDynamicLoader(DynamicLoaderUP dyld_up) { |
2682 | m_dyld_up = std::move(dyld_up); |
2683 | } |
2684 | |
2685 | DataExtractor Process::GetAuxvData() { return DataExtractor(); } |
2686 | |
2687 | llvm::Expected<bool> Process::SaveCore(llvm::StringRef outfile) { |
2688 | return false; |
2689 | } |
2690 | |
2691 | JITLoaderList &Process::GetJITLoaders() { |
2692 | if (!m_jit_loaders_up) { |
2693 | m_jit_loaders_up = std::make_unique<JITLoaderList>(); |
2694 | JITLoader::LoadPlugins(this, *m_jit_loaders_up); |
2695 | } |
2696 | return *m_jit_loaders_up; |
2697 | } |
2698 | |
2699 | SystemRuntime *Process::GetSystemRuntime() { |
2700 | if (!m_system_runtime_up) |
2701 | m_system_runtime_up.reset(SystemRuntime::FindPlugin(this)); |
2702 | return m_system_runtime_up.get(); |
2703 | } |
2704 | |
2705 | Process::AttachCompletionHandler::AttachCompletionHandler(Process *process, |
2706 | uint32_t exec_count) |
2707 | : NextEventAction(process), m_exec_count(exec_count) { |
2708 | Log *log = GetLog(LLDBLog::Process); |
2709 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s process=%p, exec_count=%" "u", __FUNCTION__, static_cast<void *>(process), exec_count ); } while (0) |
2710 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s process=%p, exec_count=%" "u", __FUNCTION__, static_cast<void *>(process), exec_count ); } while (0) |
2711 | "Process::AttachCompletionHandler::%s process=%p, exec_count=%" PRIu32,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s process=%p, exec_count=%" "u", __FUNCTION__, static_cast<void *>(process), exec_count ); } while (0) |
2712 | __FUNCTION__, static_cast<void *>(process), exec_count)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s process=%p, exec_count=%" "u", __FUNCTION__, static_cast<void *>(process), exec_count ); } while (0); |
2713 | } |
2714 | |
2715 | Process::NextEventAction::EventActionResult |
2716 | Process::AttachCompletionHandler::PerformAction(lldb::EventSP &event_sp) { |
2717 | Log *log = GetLog(LLDBLog::Process); |
2718 | |
2719 | StateType state = ProcessEventData::GetStateFromEvent(event_sp.get()); |
2720 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s called with state %s (%d)" , __FUNCTION__, StateAsCString(state), static_cast<int> (state)); } while (0) |
2721 | "Process::AttachCompletionHandler::%s called with state %s (%d)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s called with state %s (%d)" , __FUNCTION__, StateAsCString(state), static_cast<int> (state)); } while (0) |
2722 | __FUNCTION__, StateAsCString(state), static_cast<int>(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s called with state %s (%d)" , __FUNCTION__, StateAsCString(state), static_cast<int> (state)); } while (0); |
2723 | |
2724 | switch (state) { |
2725 | case eStateAttaching: |
2726 | return eEventActionSuccess; |
2727 | |
2728 | case eStateRunning: |
2729 | case eStateConnected: |
2730 | return eEventActionRetry; |
2731 | |
2732 | case eStateStopped: |
2733 | case eStateCrashed: |
2734 | // During attach, prior to sending the eStateStopped event, |
2735 | // lldb_private::Process subclasses must set the new process ID. |
2736 | assert(m_process->GetID() != LLDB_INVALID_PROCESS_ID)(static_cast <bool> (m_process->GetID() != 0) ? void (0) : __assert_fail ("m_process->GetID() != LLDB_INVALID_PROCESS_ID" , "lldb/source/Target/Process.cpp", 2736, __extension__ __PRETTY_FUNCTION__ )); |
2737 | // We don't want these events to be reported, so go set the |
2738 | // ShouldReportStop here: |
2739 | m_process->GetThreadList().SetShouldReportStop(eVoteNo); |
2740 | |
2741 | if (m_exec_count > 0) { |
2742 | --m_exec_count; |
2743 | |
2744 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: reduced " "remaining exec count to %" "u" ", requesting resume", __FUNCTION__ , StateAsCString(state), m_exec_count); } while (0) |
2745 | "Process::AttachCompletionHandler::%s state %s: reduced "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: reduced " "remaining exec count to %" "u" ", requesting resume", __FUNCTION__ , StateAsCString(state), m_exec_count); } while (0) |
2746 | "remaining exec count to %" PRIu32 ", requesting resume",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: reduced " "remaining exec count to %" "u" ", requesting resume", __FUNCTION__ , StateAsCString(state), m_exec_count); } while (0) |
2747 | __FUNCTION__, StateAsCString(state), m_exec_count)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: reduced " "remaining exec count to %" "u" ", requesting resume", __FUNCTION__ , StateAsCString(state), m_exec_count); } while (0); |
2748 | |
2749 | RequestResume(); |
2750 | return eEventActionRetry; |
2751 | } else { |
2752 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: no more " "execs expected to start, continuing with attach", __FUNCTION__ , StateAsCString(state)); } while (0) |
2753 | "Process::AttachCompletionHandler::%s state %s: no more "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: no more " "execs expected to start, continuing with attach", __FUNCTION__ , StateAsCString(state)); } while (0) |
2754 | "execs expected to start, continuing with attach",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: no more " "execs expected to start, continuing with attach", __FUNCTION__ , StateAsCString(state)); } while (0) |
2755 | __FUNCTION__, StateAsCString(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::AttachCompletionHandler::%s state %s: no more " "execs expected to start, continuing with attach", __FUNCTION__ , StateAsCString(state)); } while (0); |
2756 | |
2757 | m_process->CompleteAttach(); |
2758 | return eEventActionSuccess; |
2759 | } |
2760 | break; |
2761 | |
2762 | default: |
2763 | case eStateExited: |
2764 | case eStateInvalid: |
2765 | break; |
2766 | } |
2767 | |
2768 | m_exit_string.assign("No valid Process"); |
2769 | return eEventActionExit; |
2770 | } |
2771 | |
2772 | Process::NextEventAction::EventActionResult |
2773 | Process::AttachCompletionHandler::HandleBeingInterrupted() { |
2774 | return eEventActionSuccess; |
2775 | } |
2776 | |
2777 | const char *Process::AttachCompletionHandler::GetExitString() { |
2778 | return m_exit_string.c_str(); |
2779 | } |
2780 | |
2781 | ListenerSP ProcessAttachInfo::GetListenerForProcess(Debugger &debugger) { |
2782 | if (m_listener_sp) |
2783 | return m_listener_sp; |
2784 | else |
2785 | return debugger.GetListener(); |
2786 | } |
2787 | |
2788 | Status Process::WillLaunch(Module *module) { |
2789 | return DoWillLaunch(module); |
2790 | } |
2791 | |
2792 | Status Process::WillAttachToProcessWithID(lldb::pid_t pid) { |
2793 | return DoWillAttachToProcessWithID(pid); |
2794 | } |
2795 | |
2796 | Status Process::WillAttachToProcessWithName(const char *process_name, |
2797 | bool wait_for_launch) { |
2798 | return DoWillAttachToProcessWithName(process_name, wait_for_launch); |
2799 | } |
2800 | |
2801 | Status Process::Attach(ProcessAttachInfo &attach_info) { |
2802 | m_abi_sp.reset(); |
2803 | m_process_input_reader.reset(); |
2804 | m_dyld_up.reset(); |
2805 | m_jit_loaders_up.reset(); |
2806 | m_system_runtime_up.reset(); |
2807 | m_os_up.reset(); |
2808 | |
2809 | lldb::pid_t attach_pid = attach_info.GetProcessID(); |
2810 | Status error; |
2811 | if (attach_pid == LLDB_INVALID_PROCESS_ID0) { |
2812 | char process_name[PATH_MAX4096]; |
2813 | |
2814 | if (attach_info.GetExecutableFile().GetPath(process_name, |
2815 | sizeof(process_name))) { |
2816 | const bool wait_for_launch = attach_info.GetWaitForLaunch(); |
2817 | |
2818 | if (wait_for_launch) { |
2819 | error = WillAttachToProcessWithName(process_name, wait_for_launch); |
2820 | if (error.Success()) { |
2821 | if (m_public_run_lock.TrySetRunning()) { |
2822 | m_should_detach = true; |
2823 | const bool restarted = false; |
2824 | SetPublicState(eStateAttaching, restarted); |
2825 | // Now attach using these arguments. |
2826 | error = DoAttachToProcessWithName(process_name, attach_info); |
2827 | } else { |
2828 | // This shouldn't happen |
2829 | error.SetErrorString("failed to acquire process run lock"); |
2830 | } |
2831 | |
2832 | if (error.Fail()) { |
2833 | if (GetID() != LLDB_INVALID_PROCESS_ID0) { |
2834 | SetID(LLDB_INVALID_PROCESS_ID0); |
2835 | if (error.AsCString() == nullptr) |
2836 | error.SetErrorString("attach failed"); |
2837 | |
2838 | SetExitStatus(-1, error.AsCString()); |
2839 | } |
2840 | } else { |
2841 | SetNextEventAction(new Process::AttachCompletionHandler( |
2842 | this, attach_info.GetResumeCount())); |
2843 | StartPrivateStateThread(); |
2844 | } |
2845 | return error; |
2846 | } |
2847 | } else { |
2848 | ProcessInstanceInfoList process_infos; |
2849 | PlatformSP platform_sp(GetTarget().GetPlatform()); |
2850 | |
2851 | if (platform_sp) { |
2852 | ProcessInstanceInfoMatch match_info; |
2853 | match_info.GetProcessInfo() = attach_info; |
2854 | match_info.SetNameMatchType(NameMatch::Equals); |
2855 | platform_sp->FindProcesses(match_info, process_infos); |
2856 | const uint32_t num_matches = process_infos.size(); |
2857 | if (num_matches == 1) { |
2858 | attach_pid = process_infos[0].GetProcessID(); |
2859 | // Fall through and attach using the above process ID |
2860 | } else { |
2861 | match_info.GetProcessInfo().GetExecutableFile().GetPath( |
2862 | process_name, sizeof(process_name)); |
2863 | if (num_matches > 1) { |
2864 | StreamString s; |
2865 | ProcessInstanceInfo::DumpTableHeader(s, true, false); |
2866 | for (size_t i = 0; i < num_matches; i++) { |
2867 | process_infos[i].DumpAsTableRow( |
2868 | s, platform_sp->GetUserIDResolver(), true, false); |
2869 | } |
2870 | error.SetErrorStringWithFormat( |
2871 | "more than one process named %s:\n%s", process_name, |
2872 | s.GetData()); |
2873 | } else |
2874 | error.SetErrorStringWithFormat( |
2875 | "could not find a process named %s", process_name); |
2876 | } |
2877 | } else { |
2878 | error.SetErrorString( |
2879 | "invalid platform, can't find processes by name"); |
2880 | return error; |
2881 | } |
2882 | } |
2883 | } else { |
2884 | error.SetErrorString("invalid process name"); |
2885 | } |
2886 | } |
2887 | |
2888 | if (attach_pid != LLDB_INVALID_PROCESS_ID0) { |
2889 | error = WillAttachToProcessWithID(attach_pid); |
2890 | if (error.Success()) { |
2891 | |
2892 | if (m_public_run_lock.TrySetRunning()) { |
2893 | // Now attach using these arguments. |
2894 | m_should_detach = true; |
2895 | const bool restarted = false; |
2896 | SetPublicState(eStateAttaching, restarted); |
2897 | error = DoAttachToProcessWithID(attach_pid, attach_info); |
2898 | } else { |
2899 | // This shouldn't happen |
2900 | error.SetErrorString("failed to acquire process run lock"); |
2901 | } |
2902 | |
2903 | if (error.Success()) { |
2904 | SetNextEventAction(new Process::AttachCompletionHandler( |
2905 | this, attach_info.GetResumeCount())); |
2906 | StartPrivateStateThread(); |
2907 | } else { |
2908 | if (GetID() != LLDB_INVALID_PROCESS_ID0) |
2909 | SetID(LLDB_INVALID_PROCESS_ID0); |
2910 | |
2911 | const char *error_string = error.AsCString(); |
2912 | if (error_string == nullptr) |
2913 | error_string = "attach failed"; |
2914 | |
2915 | SetExitStatus(-1, error_string); |
2916 | } |
2917 | } |
2918 | } |
2919 | return error; |
2920 | } |
2921 | |
2922 | void Process::CompleteAttach() { |
2923 | Log *log(GetLog(LLDBLog::Process | LLDBLog::Target)); |
2924 | LLDB_LOGF(log, "Process::%s()", __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s()", __FUNCTION__); } while (0); |
2925 | |
2926 | // Let the process subclass figure out at much as it can about the process |
2927 | // before we go looking for a dynamic loader plug-in. |
2928 | ArchSpec process_arch; |
2929 | DidAttach(process_arch); |
2930 | |
2931 | if (process_arch.IsValid()) { |
2932 | GetTarget().SetArchitecture(process_arch); |
2933 | if (log) { |
2934 | const char *triple_str = process_arch.GetTriple().getTriple().c_str(); |
2935 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s replacing process architecture with DidAttach() " "architecture: %s", __FUNCTION__, triple_str ? triple_str : "<null>" ); } while (0) |
2936 | "Process::%s replacing process architecture with DidAttach() "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s replacing process architecture with DidAttach() " "architecture: %s", __FUNCTION__, triple_str ? triple_str : "<null>" ); } while (0) |
2937 | "architecture: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s replacing process architecture with DidAttach() " "architecture: %s", __FUNCTION__, triple_str ? triple_str : "<null>" ); } while (0) |
2938 | __FUNCTION__, triple_str ? triple_str : "<null>")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s replacing process architecture with DidAttach() " "architecture: %s", __FUNCTION__, triple_str ? triple_str : "<null>" ); } while (0); |
2939 | } |
2940 | } |
2941 | |
2942 | // We just attached. If we have a platform, ask it for the process |
2943 | // architecture, and if it isn't the same as the one we've already set, |
2944 | // switch architectures. |
2945 | PlatformSP platform_sp(GetTarget().GetPlatform()); |
2946 | assert(platform_sp)(static_cast <bool> (platform_sp) ? void (0) : __assert_fail ("platform_sp", "lldb/source/Target/Process.cpp", 2946, __extension__ __PRETTY_FUNCTION__)); |
2947 | ArchSpec process_host_arch = GetSystemArchitecture(); |
2948 | if (platform_sp) { |
2949 | const ArchSpec &target_arch = GetTarget().GetArchitecture(); |
2950 | if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture( |
2951 | target_arch, process_host_arch, |
2952 | ArchSpec::CompatibleMatch, nullptr)) { |
2953 | ArchSpec platform_arch; |
2954 | platform_sp = GetTarget().GetDebugger().GetPlatformList().GetOrCreate( |
2955 | target_arch, process_host_arch, &platform_arch); |
2956 | if (platform_sp) { |
2957 | GetTarget().SetPlatform(platform_sp); |
2958 | GetTarget().SetArchitecture(platform_arch); |
2959 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "switching platform to {0} and architecture to {1} based on " "info from attach", platform_sp->GetName(), platform_arch .GetTriple().getTriple()); } while (0) |
2960 | "switching platform to {0} and architecture to {1} based on "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "switching platform to {0} and architecture to {1} based on " "info from attach", platform_sp->GetName(), platform_arch .GetTriple().getTriple()); } while (0) |
2961 | "info from attach",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "switching platform to {0} and architecture to {1} based on " "info from attach", platform_sp->GetName(), platform_arch .GetTriple().getTriple()); } while (0) |
2962 | platform_sp->GetName(), platform_arch.GetTriple().getTriple())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "switching platform to {0} and architecture to {1} based on " "info from attach", platform_sp->GetName(), platform_arch .GetTriple().getTriple()); } while (0); |
2963 | } |
2964 | } else if (!process_arch.IsValid()) { |
2965 | ProcessInstanceInfo process_info; |
2966 | GetProcessInfo(process_info); |
2967 | const ArchSpec &process_arch = process_info.GetArchitecture(); |
2968 | const ArchSpec &target_arch = GetTarget().GetArchitecture(); |
2969 | if (process_arch.IsValid() && |
2970 | target_arch.IsCompatibleMatch(process_arch) && |
2971 | !target_arch.IsExactMatch(process_arch)) { |
2972 | GetTarget().SetArchitecture(process_arch); |
2973 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s switching architecture to %s based on info " "the platform retrieved for pid %" "l" "u", __FUNCTION__, process_arch .GetTriple().getTriple().c_str(), GetID()); } while (0) |
2974 | "Process::%s switching architecture to %s based on info "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s switching architecture to %s based on info " "the platform retrieved for pid %" "l" "u", __FUNCTION__, process_arch .GetTriple().getTriple().c_str(), GetID()); } while (0) |
2975 | "the platform retrieved for pid %" PRIu64,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s switching architecture to %s based on info " "the platform retrieved for pid %" "l" "u", __FUNCTION__, process_arch .GetTriple().getTriple().c_str(), GetID()); } while (0) |
2976 | __FUNCTION__, process_arch.GetTriple().getTriple().c_str(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s switching architecture to %s based on info " "the platform retrieved for pid %" "l" "u", __FUNCTION__, process_arch .GetTriple().getTriple().c_str(), GetID()); } while (0) |
2977 | GetID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s switching architecture to %s based on info " "the platform retrieved for pid %" "l" "u", __FUNCTION__, process_arch .GetTriple().getTriple().c_str(), GetID()); } while (0); |
2978 | } |
2979 | } |
2980 | } |
2981 | // Now that we know the process type, update its signal responses from the |
2982 | // ones stored in the Target: |
2983 | if (m_unix_signals_sp) { |
2984 | StreamSP warning_strm = GetTarget().GetDebugger().GetAsyncErrorStream(); |
2985 | GetTarget().UpdateSignalsFromDummy(m_unix_signals_sp, warning_strm); |
2986 | } |
2987 | |
2988 | // We have completed the attach, now it is time to find the dynamic loader |
2989 | // plug-in |
2990 | DynamicLoader *dyld = GetDynamicLoader(); |
2991 | if (dyld) { |
2992 | dyld->DidAttach(); |
2993 | if (log) { |
2994 | ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); |
2995 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after DynamicLoader::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), dyld->GetPluginName()); } while (0) |
2996 | "after DynamicLoader::DidAttach(), target "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after DynamicLoader::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), dyld->GetPluginName()); } while (0) |
2997 | "executable is {0} (using {1} plugin)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after DynamicLoader::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), dyld->GetPluginName()); } while (0) |
2998 | exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after DynamicLoader::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), dyld->GetPluginName()); } while (0) |
2999 | dyld->GetPluginName())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after DynamicLoader::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), dyld->GetPluginName()); } while (0); |
3000 | } |
3001 | } |
3002 | |
3003 | GetJITLoaders().DidAttach(); |
3004 | |
3005 | SystemRuntime *system_runtime = GetSystemRuntime(); |
3006 | if (system_runtime) { |
3007 | system_runtime->DidAttach(); |
3008 | if (log) { |
3009 | ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); |
3010 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after SystemRuntime::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), system_runtime->GetPluginName()); } while (0) |
3011 | "after SystemRuntime::DidAttach(), target "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after SystemRuntime::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), system_runtime->GetPluginName()); } while (0) |
3012 | "executable is {0} (using {1} plugin)",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after SystemRuntime::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), system_runtime->GetPluginName()); } while (0) |
3013 | exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after SystemRuntime::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), system_runtime->GetPluginName()); } while (0) |
3014 | system_runtime->GetPluginName())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "after SystemRuntime::DidAttach(), target " "executable is {0} (using {1} plugin)" , exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec( ), system_runtime->GetPluginName()); } while (0); |
3015 | } |
3016 | } |
3017 | |
3018 | if (!m_os_up) { |
3019 | LoadOperatingSystemPlugin(false); |
3020 | if (m_os_up) { |
3021 | // Somebody might have gotten threads before now, but we need to force the |
3022 | // update after we've loaded the OperatingSystem plugin or it won't get a |
3023 | // chance to process the threads. |
3024 | m_thread_list.Clear(); |
3025 | UpdateThreadListIfNeeded(); |
3026 | } |
3027 | } |
3028 | // Figure out which one is the executable, and set that in our target: |
3029 | ModuleSP new_executable_module_sp; |
3030 | for (ModuleSP module_sp : GetTarget().GetImages().Modules()) { |
3031 | if (module_sp && module_sp->IsExecutable()) { |
3032 | if (GetTarget().GetExecutableModulePointer() != module_sp.get()) |
3033 | new_executable_module_sp = module_sp; |
3034 | break; |
3035 | } |
3036 | } |
3037 | if (new_executable_module_sp) { |
3038 | GetTarget().SetExecutableModule(new_executable_module_sp, |
3039 | eLoadDependentsNo); |
3040 | if (log) { |
3041 | ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); |
3042 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s after looping through modules, target executable is %s" , __FUNCTION__, exe_module_sp ? exe_module_sp->GetFileSpec ().GetPath().c_str() : "<none>"); } while (0) |
3043 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s after looping through modules, target executable is %s" , __FUNCTION__, exe_module_sp ? exe_module_sp->GetFileSpec ().GetPath().c_str() : "<none>"); } while (0) |
3044 | "Process::%s after looping through modules, target executable is %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s after looping through modules, target executable is %s" , __FUNCTION__, exe_module_sp ? exe_module_sp->GetFileSpec ().GetPath().c_str() : "<none>"); } while (0) |
3045 | __FUNCTION__,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s after looping through modules, target executable is %s" , __FUNCTION__, exe_module_sp ? exe_module_sp->GetFileSpec ().GetPath().c_str() : "<none>"); } while (0) |
3046 | exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s after looping through modules, target executable is %s" , __FUNCTION__, exe_module_sp ? exe_module_sp->GetFileSpec ().GetPath().c_str() : "<none>"); } while (0) |
3047 | : "<none>")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s after looping through modules, target executable is %s" , __FUNCTION__, exe_module_sp ? exe_module_sp->GetFileSpec ().GetPath().c_str() : "<none>"); } while (0); |
3048 | } |
3049 | } |
3050 | } |
3051 | |
3052 | Status Process::ConnectRemote(llvm::StringRef remote_url) { |
3053 | m_abi_sp.reset(); |
3054 | m_process_input_reader.reset(); |
3055 | |
3056 | // Find the process and its architecture. Make sure it matches the |
3057 | // architecture of the current Target, and if not adjust it. |
3058 | |
3059 | Status error(DoConnectRemote(remote_url)); |
3060 | if (error.Success()) { |
3061 | if (GetID() != LLDB_INVALID_PROCESS_ID0) { |
3062 | EventSP event_sp; |
3063 | StateType state = WaitForProcessStopPrivate(event_sp, std::nullopt); |
3064 | |
3065 | if (state == eStateStopped || state == eStateCrashed) { |
3066 | // If we attached and actually have a process on the other end, then |
3067 | // this ended up being the equivalent of an attach. |
3068 | CompleteAttach(); |
3069 | |
3070 | // This delays passing the stopped event to listeners till |
3071 | // CompleteAttach gets a chance to complete... |
3072 | HandlePrivateEvent(event_sp); |
3073 | } |
3074 | } |
3075 | |
3076 | if (PrivateStateThreadIsValid()) |
3077 | ResumePrivateStateThread(); |
3078 | else |
3079 | StartPrivateStateThread(); |
3080 | } |
3081 | return error; |
3082 | } |
3083 | |
3084 | Status Process::PrivateResume() { |
3085 | Log *log(GetLog(LLDBLog::Process | LLDBLog::Step)); |
3086 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s " "private state: %s", m_mod_id.GetStopID(), StateAsCString(m_public_state .GetValue()), StateAsCString(m_private_state.GetValue())); } while (0) |
3087 | "Process::PrivateResume() m_stop_id = %u, public state: %s "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s " "private state: %s", m_mod_id.GetStopID(), StateAsCString(m_public_state .GetValue()), StateAsCString(m_private_state.GetValue())); } while (0) |
3088 | "private state: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s " "private state: %s", m_mod_id.GetStopID(), StateAsCString(m_public_state .GetValue()), StateAsCString(m_private_state.GetValue())); } while (0) |
3089 | m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s " "private state: %s", m_mod_id.GetStopID(), StateAsCString(m_public_state .GetValue()), StateAsCString(m_private_state.GetValue())); } while (0) |
3090 | StateAsCString(m_private_state.GetValue()))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s " "private state: %s", m_mod_id.GetStopID(), StateAsCString(m_public_state .GetValue()), StateAsCString(m_private_state.GetValue())); } while (0); |
3091 | |
3092 | // If signals handing status changed we might want to update our signal |
3093 | // filters before resuming. |
3094 | UpdateAutomaticSignalFiltering(); |
3095 | |
3096 | Status error(WillResume()); |
3097 | // Tell the process it is about to resume before the thread list |
3098 | if (error.Success()) { |
3099 | // Now let the thread list know we are about to resume so it can let all of |
3100 | // our threads know that they are about to be resumed. Threads will each be |
3101 | // called with Thread::WillResume(StateType) where StateType contains the |
3102 | // state that they are supposed to have when the process is resumed |
3103 | // (suspended/running/stepping). Threads should also check their resume |
3104 | // signal in lldb::Thread::GetResumeSignal() to see if they are supposed to |
3105 | // start back up with a signal. |
3106 | if (m_thread_list.WillResume()) { |
3107 | // Last thing, do the PreResumeActions. |
3108 | if (!RunPreResumeActions()) { |
3109 | error.SetErrorString( |
3110 | "Process::PrivateResume PreResumeActions failed, not resuming."); |
3111 | } else { |
3112 | m_mod_id.BumpResumeID(); |
3113 | error = DoResume(); |
3114 | if (error.Success()) { |
3115 | DidResume(); |
3116 | m_thread_list.DidResume(); |
3117 | LLDB_LOGF(log, "Process thinks the process has resumed.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process thinks the process has resumed." ); } while (0); |
3118 | } else { |
3119 | LLDB_LOGF(log, "Process::PrivateResume() DoResume failed.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() DoResume failed." ); } while (0); |
3120 | return error; |
3121 | } |
3122 | } |
3123 | } else { |
3124 | // Somebody wanted to run without running (e.g. we were faking a step |
3125 | // from one frame of a set of inlined frames that share the same PC to |
3126 | // another.) So generate a continue & a stopped event, and let the world |
3127 | // handle them. |
3128 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() asked to simulate a start & stop." ); } while (0) |
3129 | "Process::PrivateResume() asked to simulate a start & stop.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() asked to simulate a start & stop." ); } while (0); |
3130 | |
3131 | SetPrivateState(eStateRunning); |
3132 | SetPrivateState(eStateStopped); |
3133 | } |
3134 | } else |
3135 | LLDB_LOGF(log, "Process::PrivateResume() got an error \"%s\".",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() got an error \"%s\"." , error.AsCString("<unknown error>")); } while (0) |
3136 | error.AsCString("<unknown error>"))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::PrivateResume() got an error \"%s\"." , error.AsCString("<unknown error>")); } while (0); |
3137 | return error; |
3138 | } |
3139 | |
3140 | Status Process::Halt(bool clear_thread_plans, bool use_run_lock) { |
3141 | if (!StateIsRunningState(m_public_state.GetValue())) |
3142 | return Status("Process is not running."); |
3143 | |
3144 | // Don't clear the m_clear_thread_plans_on_stop, only set it to true if in |
3145 | // case it was already set and some thread plan logic calls halt on its own. |
3146 | m_clear_thread_plans_on_stop |= clear_thread_plans; |
3147 | |
3148 | ListenerSP halt_listener_sp( |
3149 | Listener::MakeListener("lldb.process.halt_listener")); |
3150 | HijackProcessEvents(halt_listener_sp); |
3151 | |
3152 | EventSP event_sp; |
3153 | |
3154 | SendAsyncInterrupt(); |
3155 | |
3156 | if (m_public_state.GetValue() == eStateAttaching) { |
3157 | // Don't hijack and eat the eStateExited as the code that was doing the |
3158 | // attach will be waiting for this event... |
3159 | RestoreProcessEvents(); |
3160 | SetExitStatus(SIGKILL9, "Cancelled async attach."); |
3161 | Destroy(false); |
3162 | return Status(); |
3163 | } |
3164 | |
3165 | // Wait for the process halt timeout seconds for the process to stop. |
3166 | // If we are going to use the run lock, that means we're stopping out to the |
3167 | // user, so we should also select the most relevant frame. |
3168 | SelectMostRelevant select_most_relevant = |
3169 | use_run_lock ? SelectMostRelevantFrame : DoNoSelectMostRelevantFrame; |
3170 | StateType state = WaitForProcessToStop(GetInterruptTimeout(), &event_sp, true, |
3171 | halt_listener_sp, nullptr, |
3172 | use_run_lock, select_most_relevant); |
3173 | RestoreProcessEvents(); |
3174 | |
3175 | if (state == eStateInvalid || !event_sp) { |
3176 | // We timed out and didn't get a stop event... |
3177 | return Status("Halt timed out. State = %s", StateAsCString(GetState())); |
3178 | } |
3179 | |
3180 | BroadcastEvent(event_sp); |
3181 | |
3182 | return Status(); |
3183 | } |
3184 | |
3185 | Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) { |
3186 | Status error; |
3187 | |
3188 | // Check both the public & private states here. If we're hung evaluating an |
3189 | // expression, for instance, then the public state will be stopped, but we |
3190 | // still need to interrupt. |
3191 | if (m_public_state.GetValue() == eStateRunning || |
3192 | m_private_state.GetValue() == eStateRunning) { |
3193 | Log *log = GetLog(LLDBLog::Process); |
3194 | LLDB_LOGF(log, "Process::%s() About to stop.", __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s() About to stop.", __FUNCTION__ ); } while (0); |
3195 | |
3196 | ListenerSP listener_sp( |
3197 | Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack")); |
3198 | HijackProcessEvents(listener_sp); |
3199 | |
3200 | SendAsyncInterrupt(); |
3201 | |
3202 | // Consume the interrupt event. |
3203 | StateType state = WaitForProcessToStop(GetInterruptTimeout(), |
3204 | &exit_event_sp, true, listener_sp); |
3205 | |
3206 | RestoreProcessEvents(); |
3207 | |
3208 | // If the process exited while we were waiting for it to stop, put the |
3209 | // exited event into the shared pointer passed in and return. Our caller |
3210 | // doesn't need to do anything else, since they don't have a process |
3211 | // anymore... |
3212 | |
3213 | if (state == eStateExited || m_private_state.GetValue() == eStateExited) { |
3214 | LLDB_LOGF(log, "Process::%s() Process exited while waiting to stop.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s() Process exited while waiting to stop." , __FUNCTION__); } while (0) |
3215 | __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s() Process exited while waiting to stop." , __FUNCTION__); } while (0); |
3216 | return error; |
3217 | } else |
3218 | exit_event_sp.reset(); // It is ok to consume any non-exit stop events |
3219 | |
3220 | if (state != eStateStopped) { |
3221 | LLDB_LOGF(log, "Process::%s() failed to stop, state is: %s", __FUNCTION__,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s() failed to stop, state is: %s" , __FUNCTION__, StateAsCString(state)); } while (0) |
3222 | StateAsCString(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s() failed to stop, state is: %s" , __FUNCTION__, StateAsCString(state)); } while (0); |
3223 | // If we really couldn't stop the process then we should just error out |
3224 | // here, but if the lower levels just bobbled sending the event and we |
3225 | // really are stopped, then continue on. |
3226 | StateType private_state = m_private_state.GetValue(); |
3227 | if (private_state != eStateStopped) { |
3228 | return Status( |
3229 | "Attempt to stop the target in order to detach timed out. " |
3230 | "State = %s", |
3231 | StateAsCString(GetState())); |
3232 | } |
3233 | } |
3234 | } |
3235 | return error; |
3236 | } |
3237 | |
3238 | Status Process::Detach(bool keep_stopped) { |
3239 | EventSP exit_event_sp; |
3240 | Status error; |
3241 | m_destroy_in_process = true; |
3242 | |
3243 | error = WillDetach(); |
3244 | |
3245 | if (error.Success()) { |
3246 | if (DetachRequiresHalt()) { |
3247 | error = StopForDestroyOrDetach(exit_event_sp); |
3248 | if (!error.Success()) { |
3249 | m_destroy_in_process = false; |
3250 | return error; |
3251 | } else if (exit_event_sp) { |
3252 | // We shouldn't need to do anything else here. There's no process left |
3253 | // to detach from... |
3254 | StopPrivateStateThread(); |
3255 | m_destroy_in_process = false; |
3256 | return error; |
3257 | } |
3258 | } |
3259 | |
3260 | m_thread_list.DiscardThreadPlans(); |
3261 | DisableAllBreakpointSites(); |
3262 | |
3263 | error = DoDetach(keep_stopped); |
3264 | if (error.Success()) { |
3265 | DidDetach(); |
3266 | StopPrivateStateThread(); |
3267 | } else { |
3268 | return error; |
3269 | } |
3270 | } |
3271 | m_destroy_in_process = false; |
3272 | |
3273 | // If we exited when we were waiting for a process to stop, then forward the |
3274 | // event here so we don't lose the event |
3275 | if (exit_event_sp) { |
3276 | // Directly broadcast our exited event because we shut down our private |
3277 | // state thread above |
3278 | BroadcastEvent(exit_event_sp); |
3279 | } |
3280 | |
3281 | // If we have been interrupted (to kill us) in the middle of running, we may |
3282 | // not end up propagating the last events through the event system, in which |
3283 | // case we might strand the write lock. Unlock it here so when we do to tear |
3284 | // down the process we don't get an error destroying the lock. |
3285 | |
3286 | m_public_run_lock.SetStopped(); |
3287 | return error; |
3288 | } |
3289 | |
3290 | Status Process::Destroy(bool force_kill) { |
3291 | // If we've already called Process::Finalize then there's nothing useful to |
3292 | // be done here. Finalize has actually called Destroy already. |
3293 | if (m_finalizing) |
3294 | return {}; |
3295 | return DestroyImpl(force_kill); |
3296 | } |
3297 | |
3298 | Status Process::DestroyImpl(bool force_kill) { |
3299 | // Tell ourselves we are in the process of destroying the process, so that we |
3300 | // don't do any unnecessary work that might hinder the destruction. Remember |
3301 | // to set this back to false when we are done. That way if the attempt |
3302 | // failed and the process stays around for some reason it won't be in a |
3303 | // confused state. |
3304 | |
3305 | if (force_kill) |
3306 | m_should_detach = false; |
3307 | |
3308 | if (GetShouldDetach()) { |
3309 | // FIXME: This will have to be a process setting: |
3310 | bool keep_stopped = false; |
3311 | Detach(keep_stopped); |
3312 | } |
3313 | |
3314 | m_destroy_in_process = true; |
3315 | |
3316 | Status error(WillDestroy()); |
3317 | if (error.Success()) { |
3318 | EventSP exit_event_sp; |
3319 | if (DestroyRequiresHalt()) { |
3320 | error = StopForDestroyOrDetach(exit_event_sp); |
3321 | } |
3322 | |
3323 | if (m_public_state.GetValue() == eStateStopped) { |
3324 | // Ditch all thread plans, and remove all our breakpoints: in case we |
3325 | // have to restart the target to kill it, we don't want it hitting a |
3326 | // breakpoint... Only do this if we've stopped, however, since if we |
3327 | // didn't manage to halt it above, then we're not going to have much luck |
3328 | // doing this now. |
3329 | m_thread_list.DiscardThreadPlans(); |
3330 | DisableAllBreakpointSites(); |
3331 | } |
3332 | |
3333 | error = DoDestroy(); |
3334 | if (error.Success()) { |
3335 | DidDestroy(); |
3336 | StopPrivateStateThread(); |
3337 | } |
3338 | m_stdio_communication.StopReadThread(); |
3339 | m_stdio_communication.Disconnect(); |
3340 | m_stdin_forward = false; |
3341 | |
3342 | if (m_process_input_reader) { |
3343 | m_process_input_reader->SetIsDone(true); |
3344 | m_process_input_reader->Cancel(); |
3345 | m_process_input_reader.reset(); |
3346 | } |
3347 | |
3348 | // If we exited when we were waiting for a process to stop, then forward |
3349 | // the event here so we don't lose the event |
3350 | if (exit_event_sp) { |
3351 | // Directly broadcast our exited event because we shut down our private |
3352 | // state thread above |
3353 | BroadcastEvent(exit_event_sp); |
3354 | } |
3355 | |
3356 | // If we have been interrupted (to kill us) in the middle of running, we |
3357 | // may not end up propagating the last events through the event system, in |
3358 | // which case we might strand the write lock. Unlock it here so when we do |
3359 | // to tear down the process we don't get an error destroying the lock. |
3360 | m_public_run_lock.SetStopped(); |
3361 | } |
3362 | |
3363 | m_destroy_in_process = false; |
3364 | |
3365 | return error; |
3366 | } |
3367 | |
3368 | Status Process::Signal(int signal) { |
3369 | Status error(WillSignal()); |
3370 | if (error.Success()) { |
3371 | error = DoSignal(signal); |
3372 | if (error.Success()) |
3373 | DidSignal(); |
3374 | } |
3375 | return error; |
3376 | } |
3377 | |
3378 | void Process::SetUnixSignals(UnixSignalsSP &&signals_sp) { |
3379 | assert(signals_sp && "null signals_sp")(static_cast <bool> (signals_sp && "null signals_sp" ) ? void (0) : __assert_fail ("signals_sp && \"null signals_sp\"" , "lldb/source/Target/Process.cpp", 3379, __extension__ __PRETTY_FUNCTION__ )); |
3380 | m_unix_signals_sp = std::move(signals_sp); |
3381 | } |
3382 | |
3383 | const lldb::UnixSignalsSP &Process::GetUnixSignals() { |
3384 | assert(m_unix_signals_sp && "null m_unix_signals_sp")(static_cast <bool> (m_unix_signals_sp && "null m_unix_signals_sp" ) ? void (0) : __assert_fail ("m_unix_signals_sp && \"null m_unix_signals_sp\"" , "lldb/source/Target/Process.cpp", 3384, __extension__ __PRETTY_FUNCTION__ )); |
3385 | return m_unix_signals_sp; |
3386 | } |
3387 | |
3388 | lldb::ByteOrder Process::GetByteOrder() const { |
3389 | return GetTarget().GetArchitecture().GetByteOrder(); |
3390 | } |
3391 | |
3392 | uint32_t Process::GetAddressByteSize() const { |
3393 | return GetTarget().GetArchitecture().GetAddressByteSize(); |
3394 | } |
3395 | |
3396 | bool Process::ShouldBroadcastEvent(Event *event_ptr) { |
3397 | const StateType state = |
3398 | Process::ProcessEventData::GetStateFromEvent(event_ptr); |
3399 | bool return_value = true; |
3400 | Log *log(GetLog(LLDBLog::Events | LLDBLog::Process)); |
3401 | |
3402 | switch (state) { |
3403 | case eStateDetached: |
3404 | case eStateExited: |
3405 | case eStateUnloaded: |
3406 | m_stdio_communication.SynchronizeWithReadThread(); |
3407 | m_stdio_communication.StopReadThread(); |
3408 | m_stdio_communication.Disconnect(); |
3409 | m_stdin_forward = false; |
3410 | |
3411 | [[fallthrough]]; |
3412 | case eStateConnected: |
3413 | case eStateAttaching: |
3414 | case eStateLaunching: |
3415 | // These events indicate changes in the state of the debugging session, |
3416 | // always report them. |
3417 | return_value = true; |
3418 | break; |
3419 | case eStateInvalid: |
3420 | // We stopped for no apparent reason, don't report it. |
3421 | return_value = false; |
3422 | break; |
3423 | case eStateRunning: |
3424 | case eStateStepping: |
3425 | // If we've started the target running, we handle the cases where we are |
3426 | // already running and where there is a transition from stopped to running |
3427 | // differently. running -> running: Automatically suppress extra running |
3428 | // events stopped -> running: Report except when there is one or more no |
3429 | // votes |
3430 | // and no yes votes. |
3431 | SynchronouslyNotifyStateChanged(state); |
3432 | if (m_force_next_event_delivery) |
3433 | return_value = true; |
3434 | else { |
3435 | switch (m_last_broadcast_state) { |
3436 | case eStateRunning: |
3437 | case eStateStepping: |
3438 | // We always suppress multiple runnings with no PUBLIC stop in between. |
3439 | return_value = false; |
3440 | break; |
3441 | default: |
3442 | // TODO: make this work correctly. For now always report |
3443 | // run if we aren't running so we don't miss any running events. If I |
3444 | // run the lldb/test/thread/a.out file and break at main.cpp:58, run |
3445 | // and hit the breakpoints on multiple threads, then somehow during the |
3446 | // stepping over of all breakpoints no run gets reported. |
3447 | |
3448 | // This is a transition from stop to run. |
3449 | switch (m_thread_list.ShouldReportRun(event_ptr)) { |
3450 | case eVoteYes: |
3451 | case eVoteNoOpinion: |
3452 | return_value = true; |
3453 | break; |
3454 | case eVoteNo: |
3455 | return_value = false; |
3456 | break; |
3457 | } |
3458 | break; |
3459 | } |
3460 | } |
3461 | break; |
3462 | case eStateStopped: |
3463 | case eStateCrashed: |
3464 | case eStateSuspended: |
3465 | // We've stopped. First see if we're going to restart the target. If we |
3466 | // are going to stop, then we always broadcast the event. If we aren't |
3467 | // going to stop, let the thread plans decide if we're going to report this |
3468 | // event. If no thread has an opinion, we don't report it. |
3469 | |
3470 | m_stdio_communication.SynchronizeWithReadThread(); |
3471 | RefreshStateAfterStop(); |
3472 | if (ProcessEventData::GetInterruptedFromEvent(event_ptr)) { |
3473 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) stopped due to an " "interrupt, state: %s", static_cast<void *>(event_ptr) , StateAsCString(state)); } while (0) |
3474 | "Process::ShouldBroadcastEvent (%p) stopped due to an "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) stopped due to an " "interrupt, state: %s", static_cast<void *>(event_ptr) , StateAsCString(state)); } while (0) |
3475 | "interrupt, state: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) stopped due to an " "interrupt, state: %s", static_cast<void *>(event_ptr) , StateAsCString(state)); } while (0) |
3476 | static_cast<void *>(event_ptr), StateAsCString(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) stopped due to an " "interrupt, state: %s", static_cast<void *>(event_ptr) , StateAsCString(state)); } while (0); |
3477 | // Even though we know we are going to stop, we should let the threads |
3478 | // have a look at the stop, so they can properly set their state. |
3479 | m_thread_list.ShouldStop(event_ptr); |
3480 | return_value = true; |
3481 | } else { |
3482 | bool was_restarted = ProcessEventData::GetRestartedFromEvent(event_ptr); |
3483 | bool should_resume = false; |
3484 | |
3485 | // It makes no sense to ask "ShouldStop" if we've already been |
3486 | // restarted... Asking the thread list is also not likely to go well, |
3487 | // since we are running again. So in that case just report the event. |
3488 | |
3489 | if (!was_restarted) |
3490 | should_resume = !m_thread_list.ShouldStop(event_ptr); |
3491 | |
3492 | if (was_restarted || should_resume || m_resume_requested) { |
3493 | Vote report_stop_vote = m_thread_list.ShouldReportStop(event_ptr); |
3494 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: " "%s was_restarted: %i report_stop_vote: %d.", should_resume, StateAsCString(state), was_restarted, report_stop_vote); } while (0) |
3495 | "Process::ShouldBroadcastEvent: should_resume: %i state: "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: " "%s was_restarted: %i report_stop_vote: %d.", should_resume, StateAsCString(state), was_restarted, report_stop_vote); } while (0) |
3496 | "%s was_restarted: %i report_stop_vote: %d.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: " "%s was_restarted: %i report_stop_vote: %d.", should_resume, StateAsCString(state), was_restarted, report_stop_vote); } while (0) |
3497 | should_resume, StateAsCString(state), was_restarted,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: " "%s was_restarted: %i report_stop_vote: %d.", should_resume, StateAsCString(state), was_restarted, report_stop_vote); } while (0) |
3498 | report_stop_vote)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: " "%s was_restarted: %i report_stop_vote: %d.", should_resume, StateAsCString(state), was_restarted, report_stop_vote); } while (0); |
3499 | |
3500 | switch (report_stop_vote) { |
3501 | case eVoteYes: |
3502 | return_value = true; |
3503 | break; |
3504 | case eVoteNoOpinion: |
3505 | case eVoteNo: |
3506 | return_value = false; |
3507 | break; |
3508 | } |
3509 | |
3510 | if (!was_restarted) { |
3511 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) Restarting process " "from state: %s", static_cast<void *>(event_ptr), StateAsCString (state)); } while (0) |
3512 | "Process::ShouldBroadcastEvent (%p) Restarting process "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) Restarting process " "from state: %s", static_cast<void *>(event_ptr), StateAsCString (state)); } while (0) |
3513 | "from state: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) Restarting process " "from state: %s", static_cast<void *>(event_ptr), StateAsCString (state)); } while (0) |
3514 | static_cast<void *>(event_ptr), StateAsCString(state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) Restarting process " "from state: %s", static_cast<void *>(event_ptr), StateAsCString (state)); } while (0); |
3515 | ProcessEventData::SetRestartedInEvent(event_ptr, true); |
3516 | PrivateResume(); |
3517 | } |
3518 | } else { |
3519 | return_value = true; |
3520 | SynchronouslyNotifyStateChanged(state); |
3521 | } |
3522 | } |
3523 | break; |
3524 | } |
3525 | |
3526 | // Forcing the next event delivery is a one shot deal. So reset it here. |
3527 | m_force_next_event_delivery = false; |
3528 | |
3529 | // We do some coalescing of events (for instance two consecutive running |
3530 | // events get coalesced.) But we only coalesce against events we actually |
3531 | // broadcast. So we use m_last_broadcast_state to track that. NB - you |
3532 | // can't use "m_public_state.GetValue()" for that purpose, as was originally |
3533 | // done, because the PublicState reflects the last event pulled off the |
3534 | // queue, and there may be several events stacked up on the queue unserviced. |
3535 | // So the PublicState may not reflect the last broadcasted event yet. |
3536 | // m_last_broadcast_state gets updated here. |
3537 | |
3538 | if (return_value) |
3539 | m_last_broadcast_state = state; |
3540 | |
3541 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last " "broadcast state: %s - %s", static_cast<void *>(event_ptr ), StateAsCString(state), StateAsCString(m_last_broadcast_state ), return_value ? "YES" : "NO"); } while (0) |
3542 | "Process::ShouldBroadcastEvent (%p) => new state: %s, last "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last " "broadcast state: %s - %s", static_cast<void *>(event_ptr ), StateAsCString(state), StateAsCString(m_last_broadcast_state ), return_value ? "YES" : "NO"); } while (0) |
3543 | "broadcast state: %s - %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last " "broadcast state: %s - %s", static_cast<void *>(event_ptr ), StateAsCString(state), StateAsCString(m_last_broadcast_state ), return_value ? "YES" : "NO"); } while (0) |
3544 | static_cast<void *>(event_ptr), StateAsCString(state),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last " "broadcast state: %s - %s", static_cast<void *>(event_ptr ), StateAsCString(state), StateAsCString(m_last_broadcast_state ), return_value ? "YES" : "NO"); } while (0) |
3545 | StateAsCString(m_last_broadcast_state),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last " "broadcast state: %s - %s", static_cast<void *>(event_ptr ), StateAsCString(state), StateAsCString(m_last_broadcast_state ), return_value ? "YES" : "NO"); } while (0) |
3546 | return_value ? "YES" : "NO")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last " "broadcast state: %s - %s", static_cast<void *>(event_ptr ), StateAsCString(state), StateAsCString(m_last_broadcast_state ), return_value ? "YES" : "NO"); } while (0); |
3547 | return return_value; |
3548 | } |
3549 | |
3550 | bool Process::StartPrivateStateThread(bool is_secondary_thread) { |
3551 | Log *log = GetLog(LLDBLog::Events); |
3552 | |
3553 | bool already_running = PrivateStateThreadIsValid(); |
3554 | LLDB_LOGF(log, "Process::%s()%s ", __FUNCTION__,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread"); } while (0) |
3555 | already_running ? " already running"do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread"); } while (0) |
3556 | : " starting private state thread")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread"); } while (0); |
3557 | |
3558 | if (!is_secondary_thread && already_running) |
3559 | return true; |
3560 | |
3561 | // Create a thread that watches our internal state and controls which events |
3562 | // make it to clients (into the DCProcess event queue). |
3563 | char thread_name[1024]; |
3564 | uint32_t max_len = llvm::get_max_thread_name_length(); |
3565 | if (max_len > 0 && max_len <= 30) { |
3566 | // On platforms with abbreviated thread name lengths, choose thread names |
3567 | // that fit within the limit. |
3568 | if (already_running) |
3569 | snprintf(thread_name, sizeof(thread_name), "intern-state-OV"); |
3570 | else |
3571 | snprintf(thread_name, sizeof(thread_name), "intern-state"); |
3572 | } else { |
3573 | if (already_running) |
3574 | snprintf(thread_name, sizeof(thread_name), |
3575 | "<lldb.process.internal-state-override(pid=%" PRIu64"l" "u" ")>", |
3576 | GetID()); |
3577 | else |
3578 | snprintf(thread_name, sizeof(thread_name), |
3579 | "<lldb.process.internal-state(pid=%" PRIu64"l" "u" ")>", GetID()); |
3580 | } |
3581 | |
3582 | llvm::Expected<HostThread> private_state_thread = |
3583 | ThreadLauncher::LaunchThread( |
3584 | thread_name, |
3585 | [this, is_secondary_thread] { |
3586 | return RunPrivateStateThread(is_secondary_thread); |
3587 | }, |
3588 | 8 * 1024 * 1024); |
3589 | if (!private_state_thread) { |
3590 | LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}",do { ::lldb_private::Log *log_private = (GetLog(LLDBLog::Host )); if (log_private) log_private->Format("lldb/source/Target/Process.cpp" , __func__, "failed to launch host thread: {}", llvm::toString (private_state_thread.takeError())); } while (0) |
3591 | llvm::toString(private_state_thread.takeError()))do { ::lldb_private::Log *log_private = (GetLog(LLDBLog::Host )); if (log_private) log_private->Format("lldb/source/Target/Process.cpp" , __func__, "failed to launch host thread: {}", llvm::toString (private_state_thread.takeError())); } while (0); |
3592 | return false; |
3593 | } |
3594 | |
3595 | assert(private_state_thread->IsJoinable())(static_cast <bool> (private_state_thread->IsJoinable ()) ? void (0) : __assert_fail ("private_state_thread->IsJoinable()" , "lldb/source/Target/Process.cpp", 3595, __extension__ __PRETTY_FUNCTION__ )); |
3596 | m_private_state_thread = *private_state_thread; |
3597 | ResumePrivateStateThread(); |
3598 | return true; |
3599 | } |
3600 | |
3601 | void Process::PausePrivateStateThread() { |
3602 | ControlPrivateStateThread(eBroadcastInternalStateControlPause); |
3603 | } |
3604 | |
3605 | void Process::ResumePrivateStateThread() { |
3606 | ControlPrivateStateThread(eBroadcastInternalStateControlResume); |
3607 | } |
3608 | |
3609 | void Process::StopPrivateStateThread() { |
3610 | if (m_private_state_thread.IsJoinable()) |
3611 | ControlPrivateStateThread(eBroadcastInternalStateControlStop); |
3612 | else { |
3613 | Log *log = GetLog(LLDBLog::Process); |
3614 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Went to stop the private state thread, but it was already invalid." ); } while (0) |
3615 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Went to stop the private state thread, but it was already invalid." ); } while (0) |
3616 | "Went to stop the private state thread, but it was already invalid.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Went to stop the private state thread, but it was already invalid." ); } while (0); |
3617 | } |
3618 | } |
3619 | |
3620 | void Process::ControlPrivateStateThread(uint32_t signal) { |
3621 | Log *log = GetLog(LLDBLog::Process); |
3622 | |
3623 | assert(signal == eBroadcastInternalStateControlStop ||(static_cast <bool> (signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || signal == eBroadcastInternalStateControlResume) ? void (0) : __assert_fail ("signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || signal == eBroadcastInternalStateControlResume" , "lldb/source/Target/Process.cpp", 3625, __extension__ __PRETTY_FUNCTION__ )) |
3624 | signal == eBroadcastInternalStateControlPause ||(static_cast <bool> (signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || signal == eBroadcastInternalStateControlResume) ? void (0) : __assert_fail ("signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || signal == eBroadcastInternalStateControlResume" , "lldb/source/Target/Process.cpp", 3625, __extension__ __PRETTY_FUNCTION__ )) |
3625 | signal == eBroadcastInternalStateControlResume)(static_cast <bool> (signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || signal == eBroadcastInternalStateControlResume) ? void (0) : __assert_fail ("signal == eBroadcastInternalStateControlStop || signal == eBroadcastInternalStateControlPause || signal == eBroadcastInternalStateControlResume" , "lldb/source/Target/Process.cpp", 3625, __extension__ __PRETTY_FUNCTION__ )); |
3626 | |
3627 | LLDB_LOGF(log, "Process::%s (signal = %d)", __FUNCTION__, signal)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (signal = %d)", __FUNCTION__ , signal); } while (0); |
3628 | |
3629 | // Signal the private state thread |
3630 | if (m_private_state_thread.IsJoinable()) { |
3631 | // Broadcast the event. |
3632 | // It is important to do this outside of the if below, because it's |
3633 | // possible that the thread state is invalid but that the thread is waiting |
3634 | // on a control event instead of simply being on its way out (this should |
3635 | // not happen, but it apparently can). |
3636 | LLDB_LOGF(log, "Sending control event of type: %d.", signal)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Sending control event of type: %d." , signal); } while (0); |
3637 | std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt()); |
3638 | m_private_state_control_broadcaster.BroadcastEvent(signal, |
3639 | event_receipt_sp); |
3640 | |
3641 | // Wait for the event receipt or for the private state thread to exit |
3642 | bool receipt_received = false; |
3643 | if (PrivateStateThreadIsValid()) { |
3644 | while (!receipt_received) { |
3645 | // Check for a receipt for n seconds and then check if the private |
3646 | // state thread is still around. |
3647 | receipt_received = |
3648 | event_receipt_sp->WaitForEventReceived(GetUtilityExpressionTimeout()); |
3649 | if (!receipt_received) { |
3650 | // Check if the private state thread is still around. If it isn't |
3651 | // then we are done waiting |
3652 | if (!PrivateStateThreadIsValid()) |
3653 | break; // Private state thread exited or is exiting, we are done |
3654 | } |
3655 | } |
3656 | } |
3657 | |
3658 | if (signal == eBroadcastInternalStateControlStop) { |
3659 | thread_result_t result = {}; |
3660 | m_private_state_thread.Join(&result); |
3661 | m_private_state_thread.Reset(); |
3662 | } |
3663 | } else { |
3664 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Private state thread already dead, no need to signal it to stop." ); } while (0) |
3665 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Private state thread already dead, no need to signal it to stop." ); } while (0) |
3666 | "Private state thread already dead, no need to signal it to stop.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Private state thread already dead, no need to signal it to stop." ); } while (0); |
3667 | } |
3668 | } |
3669 | |
3670 | void Process::SendAsyncInterrupt() { |
3671 | if (PrivateStateThreadIsValid()) |
3672 | m_private_state_broadcaster.BroadcastEvent(Process::eBroadcastBitInterrupt, |
3673 | nullptr); |
3674 | else |
3675 | BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); |
3676 | } |
3677 | |
3678 | void Process::HandlePrivateEvent(EventSP &event_sp) { |
3679 | Log *log = GetLog(LLDBLog::Process); |
3680 | m_resume_requested = false; |
3681 | |
3682 | const StateType new_state = |
3683 | Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
3684 | |
3685 | // First check to see if anybody wants a shot at this event: |
3686 | if (m_next_event_action_up) { |
3687 | NextEventAction::EventActionResult action_result = |
3688 | m_next_event_action_up->PerformAction(event_sp); |
3689 | LLDB_LOGF(log, "Ran next event action, result was %d.", action_result)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Ran next event action, result was %d." , action_result); } while (0); |
3690 | |
3691 | switch (action_result) { |
3692 | case NextEventAction::eEventActionSuccess: |
3693 | SetNextEventAction(nullptr); |
3694 | break; |
3695 | |
3696 | case NextEventAction::eEventActionRetry: |
3697 | break; |
3698 | |
3699 | case NextEventAction::eEventActionExit: |
3700 | // Handle Exiting Here. If we already got an exited event, we should |
3701 | // just propagate it. Otherwise, swallow this event, and set our state |
3702 | // to exit so the next event will kill us. |
3703 | if (new_state != eStateExited) { |
3704 | // FIXME: should cons up an exited event, and discard this one. |
3705 | SetExitStatus(0, m_next_event_action_up->GetExitString()); |
3706 | SetNextEventAction(nullptr); |
3707 | return; |
3708 | } |
3709 | SetNextEventAction(nullptr); |
3710 | break; |
3711 | } |
3712 | } |
3713 | |
3714 | // See if we should broadcast this state to external clients? |
3715 | const bool should_broadcast = ShouldBroadcastEvent(event_sp.get()); |
3716 | |
3717 | if (should_broadcast) { |
3718 | const bool is_hijacked = IsHijackedForEvent(eBroadcastBitStateChanged); |
3719 | if (log) { |
3720 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") broadcasting new state %s (old state %s) to %s" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState()), is_hijacked ? "hijacked" : "public"); } while ( 0) |
3721 | "Process::%s (pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") broadcasting new state %s (old state %s) to %s" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState()), is_hijacked ? "hijacked" : "public"); } while ( 0) |
3722 | ") broadcasting new state %s (old state %s) to %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") broadcasting new state %s (old state %s) to %s" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState()), is_hijacked ? "hijacked" : "public"); } while ( 0) |
3723 | __FUNCTION__, GetID(), StateAsCString(new_state),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") broadcasting new state %s (old state %s) to %s" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState()), is_hijacked ? "hijacked" : "public"); } while ( 0) |
3724 | StateAsCString(GetState()),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") broadcasting new state %s (old state %s) to %s" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState()), is_hijacked ? "hijacked" : "public"); } while ( 0) |
3725 | is_hijacked ? "hijacked" : "public")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") broadcasting new state %s (old state %s) to %s" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState()), is_hijacked ? "hijacked" : "public"); } while ( 0); |
3726 | } |
3727 | Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get()); |
3728 | if (StateIsRunningState(new_state)) { |
3729 | // Only push the input handler if we aren't fowarding events, as this |
3730 | // means the curses GUI is in use... Or don't push it if we are launching |
3731 | // since it will come up stopped. |
3732 | if (!GetTarget().GetDebugger().IsForwardingEvents() && |
3733 | new_state != eStateLaunching && new_state != eStateAttaching) { |
3734 | PushProcessIOHandler(); |
3735 | m_iohandler_sync.SetValue(m_iohandler_sync.GetValue() + 1, |
3736 | eBroadcastAlways); |
3737 | LLDB_LOGF(log, "Process::%s updated m_iohandler_sync to %d",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s updated m_iohandler_sync to %d" , __FUNCTION__, m_iohandler_sync.GetValue()); } while (0) |
3738 | __FUNCTION__, m_iohandler_sync.GetValue())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s updated m_iohandler_sync to %d" , __FUNCTION__, m_iohandler_sync.GetValue()); } while (0); |
3739 | } |
3740 | } else if (StateIsStoppedState(new_state, false)) { |
3741 | if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) { |
3742 | // If the lldb_private::Debugger is handling the events, we don't want |
3743 | // to pop the process IOHandler here, we want to do it when we receive |
3744 | // the stopped event so we can carefully control when the process |
3745 | // IOHandler is popped because when we stop we want to display some |
3746 | // text stating how and why we stopped, then maybe some |
3747 | // process/thread/frame info, and then we want the "(lldb) " prompt to |
3748 | // show up. If we pop the process IOHandler here, then we will cause |
3749 | // the command interpreter to become the top IOHandler after the |
3750 | // process pops off and it will update its prompt right away... See the |
3751 | // Debugger.cpp file where it calls the function as |
3752 | // "process_sp->PopProcessIOHandler()" to see where I am talking about. |
3753 | // Otherwise we end up getting overlapping "(lldb) " prompts and |
3754 | // garbled output. |
3755 | // |
3756 | // If we aren't handling the events in the debugger (which is indicated |
3757 | // by "m_target.GetDebugger().IsHandlingEvents()" returning false) or |
3758 | // we are hijacked, then we always pop the process IO handler manually. |
3759 | // Hijacking happens when the internal process state thread is running |
3760 | // thread plans, or when commands want to run in synchronous mode and |
3761 | // they call "process->WaitForProcessToStop()". An example of something |
3762 | // that will hijack the events is a simple expression: |
3763 | // |
3764 | // (lldb) expr (int)puts("hello") |
3765 | // |
3766 | // This will cause the internal process state thread to resume and halt |
3767 | // the process (and _it_ will hijack the eBroadcastBitStateChanged |
3768 | // events) and we do need the IO handler to be pushed and popped |
3769 | // correctly. |
3770 | |
3771 | if (is_hijacked || !GetTarget().GetDebugger().IsHandlingEvents()) |
3772 | PopProcessIOHandler(); |
3773 | } |
3774 | } |
3775 | |
3776 | BroadcastEvent(event_sp); |
3777 | } else { |
3778 | if (log) { |
3779 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") suppressing state %s (old state %s): should_broadcast == false" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState())); } while (0) |
3780 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") suppressing state %s (old state %s): should_broadcast == false" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState())); } while (0) |
3781 | "Process::%s (pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") suppressing state %s (old state %s): should_broadcast == false" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState())); } while (0) |
3782 | ") suppressing state %s (old state %s): should_broadcast == false",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") suppressing state %s (old state %s): should_broadcast == false" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState())); } while (0) |
3783 | __FUNCTION__, GetID(), StateAsCString(new_state),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") suppressing state %s (old state %s): should_broadcast == false" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState())); } while (0) |
3784 | StateAsCString(GetState()))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (pid = %" "l" "u" ") suppressing state %s (old state %s): should_broadcast == false" , __FUNCTION__, GetID(), StateAsCString(new_state), StateAsCString (GetState())); } while (0); |
3785 | } |
3786 | } |
3787 | } |
3788 | |
3789 | Status Process::HaltPrivate() { |
3790 | EventSP event_sp; |
3791 | Status error(WillHalt()); |
3792 | if (error.Fail()) |
3793 | return error; |
3794 | |
3795 | // Ask the process subclass to actually halt our process |
3796 | bool caused_stop; |
3797 | error = DoHalt(caused_stop); |
3798 | |
3799 | DidHalt(); |
3800 | return error; |
3801 | } |
3802 | |
3803 | thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) { |
3804 | bool control_only = true; |
3805 | |
3806 | Log *log = GetLog(LLDBLog::Process); |
3807 | LLDB_LOGF(log, "Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") thread starting...", __FUNCTION__, static_cast<void *>(this), GetID()); } while (0) |
3808 | __FUNCTION__, static_cast<void *>(this), GetID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") thread starting...", __FUNCTION__, static_cast<void *>(this), GetID()); } while (0); |
3809 | |
3810 | bool exit_now = false; |
3811 | bool interrupt_requested = false; |
3812 | while (!exit_now) { |
3813 | EventSP event_sp; |
3814 | GetEventsPrivate(event_sp, std::nullopt, control_only); |
3815 | if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster)) { |
3816 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") got a control event: %d", __FUNCTION__, static_cast< void *>(this), GetID(), event_sp->GetType()); } while ( 0) |
3817 | "Process::%s (arg = %p, pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") got a control event: %d", __FUNCTION__, static_cast< void *>(this), GetID(), event_sp->GetType()); } while ( 0) |
3818 | ") got a control event: %d",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") got a control event: %d", __FUNCTION__, static_cast< void *>(this), GetID(), event_sp->GetType()); } while ( 0) |
3819 | __FUNCTION__, static_cast<void *>(this), GetID(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") got a control event: %d", __FUNCTION__, static_cast< void *>(this), GetID(), event_sp->GetType()); } while ( 0) |
3820 | event_sp->GetType())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") got a control event: %d", __FUNCTION__, static_cast< void *>(this), GetID(), event_sp->GetType()); } while ( 0); |
3821 | |
3822 | switch (event_sp->GetType()) { |
3823 | case eBroadcastInternalStateControlStop: |
3824 | exit_now = true; |
3825 | break; // doing any internal state management below |
3826 | |
3827 | case eBroadcastInternalStateControlPause: |
3828 | control_only = true; |
3829 | break; |
3830 | |
3831 | case eBroadcastInternalStateControlResume: |
3832 | control_only = false; |
3833 | break; |
3834 | } |
3835 | |
3836 | continue; |
3837 | } else if (event_sp->GetType() == eBroadcastBitInterrupt) { |
3838 | if (m_public_state.GetValue() == eStateAttaching) { |
3839 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt while attaching - " "forwarding interrupt." , __FUNCTION__, static_cast<void *>(this), GetID()); } while (0) |
3840 | "Process::%s (arg = %p, pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt while attaching - " "forwarding interrupt." , __FUNCTION__, static_cast<void *>(this), GetID()); } while (0) |
3841 | ") woke up with an interrupt while attaching - "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt while attaching - " "forwarding interrupt." , __FUNCTION__, static_cast<void *>(this), GetID()); } while (0) |
3842 | "forwarding interrupt.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt while attaching - " "forwarding interrupt." , __FUNCTION__, static_cast<void *>(this), GetID()); } while (0) |
3843 | __FUNCTION__, static_cast<void *>(this), GetID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt while attaching - " "forwarding interrupt." , __FUNCTION__, static_cast<void *>(this), GetID()); } while (0); |
3844 | BroadcastEvent(eBroadcastBitInterrupt, nullptr); |
3845 | } else if (StateIsRunningState(m_last_broadcast_state)) { |
3846 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt - Halting.", __FUNCTION__, static_cast <void *>(this), GetID()); } while (0) |
3847 | "Process::%s (arg = %p, pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt - Halting.", __FUNCTION__, static_cast <void *>(this), GetID()); } while (0) |
3848 | ") woke up with an interrupt - Halting.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt - Halting.", __FUNCTION__, static_cast <void *>(this), GetID()); } while (0) |
3849 | __FUNCTION__, static_cast<void *>(this), GetID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") woke up with an interrupt - Halting.", __FUNCTION__, static_cast <void *>(this), GetID()); } while (0); |
3850 | Status error = HaltPrivate(); |
3851 | if (error.Fail() && log) |
3852 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") failed to halt the process: %s", __FUNCTION__, static_cast <void *>(this), GetID(), error.AsCString()); } while (0 ) |
3853 | "Process::%s (arg = %p, pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") failed to halt the process: %s", __FUNCTION__, static_cast <void *>(this), GetID(), error.AsCString()); } while (0 ) |
3854 | ") failed to halt the process: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") failed to halt the process: %s", __FUNCTION__, static_cast <void *>(this), GetID(), error.AsCString()); } while (0 ) |
3855 | __FUNCTION__, static_cast<void *>(this), GetID(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") failed to halt the process: %s", __FUNCTION__, static_cast <void *>(this), GetID(), error.AsCString()); } while (0 ) |
3856 | error.AsCString())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") failed to halt the process: %s", __FUNCTION__, static_cast <void *>(this), GetID(), error.AsCString()); } while (0 ); |
3857 | // Halt should generate a stopped event. Make a note of the fact that |
3858 | // we were doing the interrupt, so we can set the interrupted flag |
3859 | // after we receive the event. We deliberately set this to true even if |
3860 | // HaltPrivate failed, so that we can interrupt on the next natural |
3861 | // stop. |
3862 | interrupt_requested = true; |
3863 | } else { |
3864 | // This can happen when someone (e.g. Process::Halt) sees that we are |
3865 | // running and sends an interrupt request, but the process actually |
3866 | // stops before we receive it. In that case, we can just ignore the |
3867 | // request. We use m_last_broadcast_state, because the Stopped event |
3868 | // may not have been popped of the event queue yet, which is when the |
3869 | // public state gets updated. |
3870 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s ignoring interrupt as we have already stopped." , __FUNCTION__); } while (0) |
3871 | "Process::%s ignoring interrupt as we have already stopped.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s ignoring interrupt as we have already stopped." , __FUNCTION__); } while (0) |
3872 | __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s ignoring interrupt as we have already stopped." , __FUNCTION__); } while (0); |
3873 | } |
3874 | continue; |
3875 | } |
3876 | |
3877 | const StateType internal_state = |
3878 | Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
3879 | |
3880 | if (internal_state != eStateInvalid) { |
3881 | if (m_clear_thread_plans_on_stop && |
3882 | StateIsStoppedState(internal_state, true)) { |
3883 | m_clear_thread_plans_on_stop = false; |
3884 | m_thread_list.DiscardThreadPlans(); |
3885 | } |
3886 | |
3887 | if (interrupt_requested) { |
3888 | if (StateIsStoppedState(internal_state, true)) { |
3889 | // We requested the interrupt, so mark this as such in the stop event |
3890 | // so clients can tell an interrupted process from a natural stop |
3891 | ProcessEventData::SetInterruptedInEvent(event_sp.get(), true); |
3892 | interrupt_requested = false; |
3893 | } else if (log) { |
3894 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s interrupt_requested, but a non-stopped " "state '%s' received.", __FUNCTION__, StateAsCString(internal_state )); } while (0) |
3895 | "Process::%s interrupt_requested, but a non-stopped "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s interrupt_requested, but a non-stopped " "state '%s' received.", __FUNCTION__, StateAsCString(internal_state )); } while (0) |
3896 | "state '%s' received.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s interrupt_requested, but a non-stopped " "state '%s' received.", __FUNCTION__, StateAsCString(internal_state )); } while (0) |
3897 | __FUNCTION__, StateAsCString(internal_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s interrupt_requested, but a non-stopped " "state '%s' received.", __FUNCTION__, StateAsCString(internal_state )); } while (0); |
3898 | } |
3899 | } |
3900 | |
3901 | HandlePrivateEvent(event_sp); |
3902 | } |
3903 | |
3904 | if (internal_state == eStateInvalid || internal_state == eStateExited || |
3905 | internal_state == eStateDetached) { |
3906 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") about to exit with internal state %s...", __FUNCTION__ , static_cast<void *>(this), GetID(), StateAsCString(internal_state )); } while (0) |
3907 | "Process::%s (arg = %p, pid = %" PRIu64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") about to exit with internal state %s...", __FUNCTION__ , static_cast<void *>(this), GetID(), StateAsCString(internal_state )); } while (0) |
3908 | ") about to exit with internal state %s...",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") about to exit with internal state %s...", __FUNCTION__ , static_cast<void *>(this), GetID(), StateAsCString(internal_state )); } while (0) |
3909 | __FUNCTION__, static_cast<void *>(this), GetID(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") about to exit with internal state %s...", __FUNCTION__ , static_cast<void *>(this), GetID(), StateAsCString(internal_state )); } while (0) |
3910 | StateAsCString(internal_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") about to exit with internal state %s...", __FUNCTION__ , static_cast<void *>(this), GetID(), StateAsCString(internal_state )); } while (0); |
3911 | |
3912 | break; |
3913 | } |
3914 | } |
3915 | |
3916 | // Verify log is still enabled before attempting to write to it... |
3917 | LLDB_LOGF(log, "Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") thread exiting...", __FUNCTION__, static_cast<void *>(this), GetID()); } while (0) |
3918 | __FUNCTION__, static_cast<void *>(this), GetID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s (arg = %p, pid = %" "l" "u" ") thread exiting...", __FUNCTION__, static_cast<void *>(this), GetID()); } while (0); |
3919 | |
3920 | // If we are a secondary thread, then the primary thread we are working for |
3921 | // will have already acquired the public_run_lock, and isn't done with what |
3922 | // it was doing yet, so don't try to change it on the way out. |
3923 | if (!is_secondary_thread) |
3924 | m_public_run_lock.SetStopped(); |
3925 | return {}; |
3926 | } |
3927 | |
3928 | // Process Event Data |
3929 | |
3930 | Process::ProcessEventData::ProcessEventData() : EventData(), m_process_wp() {} |
3931 | |
3932 | Process::ProcessEventData::ProcessEventData(const ProcessSP &process_sp, |
3933 | StateType state) |
3934 | : EventData(), m_process_wp(), m_state(state) { |
3935 | if (process_sp) |
3936 | m_process_wp = process_sp; |
3937 | } |
3938 | |
3939 | Process::ProcessEventData::~ProcessEventData() = default; |
3940 | |
3941 | llvm::StringRef Process::ProcessEventData::GetFlavorString() { |
3942 | return "Process::ProcessEventData"; |
3943 | } |
3944 | |
3945 | llvm::StringRef Process::ProcessEventData::GetFlavor() const { |
3946 | return ProcessEventData::GetFlavorString(); |
3947 | } |
3948 | |
3949 | bool Process::ProcessEventData::ShouldStop(Event *event_ptr, |
3950 | bool &found_valid_stopinfo) { |
3951 | found_valid_stopinfo = false; |
3952 | |
3953 | ProcessSP process_sp(m_process_wp.lock()); |
3954 | if (!process_sp) |
3955 | return false; |
3956 | |
3957 | ThreadList &curr_thread_list = process_sp->GetThreadList(); |
3958 | uint32_t num_threads = curr_thread_list.GetSize(); |
3959 | uint32_t idx; |
3960 | |
3961 | // The actions might change one of the thread's stop_info's opinions about |
3962 | // whether we should stop the process, so we need to query that as we go. |
3963 | |
3964 | // One other complication here, is that we try to catch any case where the |
3965 | // target has run (except for expressions) and immediately exit, but if we |
3966 | // get that wrong (which is possible) then the thread list might have |
3967 | // changed, and that would cause our iteration here to crash. We could |
3968 | // make a copy of the thread list, but we'd really like to also know if it |
3969 | // has changed at all, so we make up a vector of the thread ID's and check |
3970 | // what we get back against this list & bag out if anything differs. |
3971 | ThreadList not_suspended_thread_list(process_sp.get()); |
3972 | std::vector<uint32_t> thread_index_array(num_threads); |
3973 | uint32_t not_suspended_idx = 0; |
3974 | for (idx = 0; idx < num_threads; ++idx) { |
3975 | lldb::ThreadSP thread_sp = curr_thread_list.GetThreadAtIndex(idx); |
3976 | |
3977 | /* |
3978 | Filter out all suspended threads, they could not be the reason |
3979 | of stop and no need to perform any actions on them. |
3980 | */ |
3981 | if (thread_sp->GetResumeState() != eStateSuspended) { |
3982 | not_suspended_thread_list.AddThread(thread_sp); |
3983 | thread_index_array[not_suspended_idx] = thread_sp->GetIndexID(); |
3984 | not_suspended_idx++; |
3985 | } |
3986 | } |
3987 | |
3988 | // Use this to track whether we should continue from here. We will only |
3989 | // continue the target running if no thread says we should stop. Of course |
3990 | // if some thread's PerformAction actually sets the target running, then it |
3991 | // doesn't matter what the other threads say... |
3992 | |
3993 | bool still_should_stop = false; |
3994 | |
3995 | // Sometimes - for instance if we have a bug in the stub we are talking to, |
3996 | // we stop but no thread has a valid stop reason. In that case we should |
3997 | // just stop, because we have no way of telling what the right thing to do |
3998 | // is, and it's better to let the user decide than continue behind their |
3999 | // backs. |
4000 | |
4001 | for (idx = 0; idx < not_suspended_thread_list.GetSize(); ++idx) { |
4002 | curr_thread_list = process_sp->GetThreadList(); |
4003 | if (curr_thread_list.GetSize() != num_threads) { |
4004 | Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); |
4005 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Number of threads changed from %u to %u while processing event." , num_threads, curr_thread_list.GetSize()); } while (0) |
4006 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Number of threads changed from %u to %u while processing event." , num_threads, curr_thread_list.GetSize()); } while (0) |
4007 | "Number of threads changed from %u to %u while processing event.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Number of threads changed from %u to %u while processing event." , num_threads, curr_thread_list.GetSize()); } while (0) |
4008 | num_threads, curr_thread_list.GetSize())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Number of threads changed from %u to %u while processing event." , num_threads, curr_thread_list.GetSize()); } while (0); |
4009 | break; |
4010 | } |
4011 | |
4012 | lldb::ThreadSP thread_sp = not_suspended_thread_list.GetThreadAtIndex(idx); |
4013 | |
4014 | if (thread_sp->GetIndexID() != thread_index_array[idx]) { |
4015 | Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); |
4016 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("The thread at position %u changed from %u to %u while " "processing event.", idx, thread_index_array[idx], thread_sp ->GetIndexID()); } while (0) |
4017 | "The thread at position %u changed from %u to %u while "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("The thread at position %u changed from %u to %u while " "processing event.", idx, thread_index_array[idx], thread_sp ->GetIndexID()); } while (0) |
4018 | "processing event.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("The thread at position %u changed from %u to %u while " "processing event.", idx, thread_index_array[idx], thread_sp ->GetIndexID()); } while (0) |
4019 | idx, thread_index_array[idx], thread_sp->GetIndexID())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("The thread at position %u changed from %u to %u while " "processing event.", idx, thread_index_array[idx], thread_sp ->GetIndexID()); } while (0); |
4020 | break; |
4021 | } |
4022 | |
4023 | StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); |
4024 | if (stop_info_sp && stop_info_sp->IsValid()) { |
4025 | found_valid_stopinfo = true; |
4026 | bool this_thread_wants_to_stop; |
4027 | if (stop_info_sp->GetOverrideShouldStop()) { |
4028 | this_thread_wants_to_stop = |
4029 | stop_info_sp->GetOverriddenShouldStopValue(); |
4030 | } else { |
4031 | stop_info_sp->PerformAction(event_ptr); |
4032 | // The stop action might restart the target. If it does, then we |
4033 | // want to mark that in the event so that whoever is receiving it |
4034 | // will know to wait for the running event and reflect that state |
4035 | // appropriately. We also need to stop processing actions, since they |
4036 | // aren't expecting the target to be running. |
4037 | |
4038 | // FIXME: we might have run. |
4039 | if (stop_info_sp->HasTargetRunSinceMe()) { |
4040 | SetRestarted(true); |
4041 | break; |
4042 | } |
4043 | |
4044 | this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr); |
4045 | } |
4046 | |
4047 | if (!still_should_stop) |
4048 | still_should_stop = this_thread_wants_to_stop; |
4049 | } |
4050 | } |
4051 | |
4052 | return still_should_stop; |
4053 | } |
4054 | |
4055 | void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) { |
4056 | ProcessSP process_sp(m_process_wp.lock()); |
4057 | |
4058 | if (!process_sp) |
4059 | return; |
4060 | |
4061 | // This function gets called twice for each event, once when the event gets |
4062 | // pulled off of the private process event queue, and then any number of |
4063 | // times, first when it gets pulled off of the public event queue, then other |
4064 | // times when we're pretending that this is where we stopped at the end of |
4065 | // expression evaluation. m_update_state is used to distinguish these three |
4066 | // cases; it is 0 when we're just pulling it off for private handling, and > |
4067 | // 1 for expression evaluation, and we don't want to do the breakpoint |
4068 | // command handling then. |
4069 | if (m_update_state != 1) |
4070 | return; |
4071 | |
4072 | process_sp->SetPublicState( |
4073 | m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr)); |
4074 | |
4075 | if (m_state == eStateStopped && !m_restarted) { |
4076 | // Let process subclasses know we are about to do a public stop and do |
4077 | // anything they might need to in order to speed up register and memory |
4078 | // accesses. |
4079 | process_sp->WillPublicStop(); |
4080 | } |
4081 | |
4082 | // If this is a halt event, even if the halt stopped with some reason other |
4083 | // than a plain interrupt (e.g. we had already stopped for a breakpoint when |
4084 | // the halt request came through) don't do the StopInfo actions, as they may |
4085 | // end up restarting the process. |
4086 | if (m_interrupted) |
4087 | return; |
4088 | |
4089 | // If we're not stopped or have restarted, then skip the StopInfo actions: |
4090 | if (m_state != eStateStopped || m_restarted) { |
4091 | return; |
4092 | } |
4093 | |
4094 | bool does_anybody_have_an_opinion = false; |
4095 | bool still_should_stop = ShouldStop(event_ptr, does_anybody_have_an_opinion); |
4096 | |
4097 | if (GetRestarted()) { |
4098 | return; |
4099 | } |
4100 | |
4101 | if (!still_should_stop && does_anybody_have_an_opinion) { |
4102 | // We've been asked to continue, so do that here. |
4103 | SetRestarted(true); |
4104 | // Use the public resume method here, since this is just extending a |
4105 | // public resume. |
4106 | process_sp->PrivateResume(); |
4107 | } else { |
4108 | bool hijacked = process_sp->IsHijackedForEvent(eBroadcastBitStateChanged) && |
4109 | !process_sp->StateChangedIsHijackedForSynchronousResume(); |
4110 | |
4111 | if (!hijacked) { |
4112 | // If we didn't restart, run the Stop Hooks here. |
4113 | // Don't do that if state changed events aren't hooked up to the |
4114 | // public (or SyncResume) broadcasters. StopHooks are just for |
4115 | // real public stops. They might also restart the target, |
4116 | // so watch for that. |
4117 | if (process_sp->GetTarget().RunStopHooks()) |
4118 | SetRestarted(true); |
4119 | } |
4120 | } |
4121 | } |
4122 | |
4123 | void Process::ProcessEventData::Dump(Stream *s) const { |
4124 | ProcessSP process_sp(m_process_wp.lock()); |
4125 | |
4126 | if (process_sp) |
4127 | s->Printf(" process = %p (pid = %" PRIu64"l" "u" "), ", |
4128 | static_cast<void *>(process_sp.get()), process_sp->GetID()); |
4129 | else |
4130 | s->PutCString(" process = NULL, "); |
4131 | |
4132 | s->Printf("state = %s", StateAsCString(GetState())); |
4133 | } |
4134 | |
4135 | const Process::ProcessEventData * |
4136 | Process::ProcessEventData::GetEventDataFromEvent(const Event *event_ptr) { |
4137 | if (event_ptr) { |
4138 | const EventData *event_data = event_ptr->GetData(); |
4139 | if (event_data && |
4140 | event_data->GetFlavor() == ProcessEventData::GetFlavorString()) |
4141 | return static_cast<const ProcessEventData *>(event_ptr->GetData()); |
4142 | } |
4143 | return nullptr; |
4144 | } |
4145 | |
4146 | ProcessSP |
4147 | Process::ProcessEventData::GetProcessFromEvent(const Event *event_ptr) { |
4148 | ProcessSP process_sp; |
4149 | const ProcessEventData *data = GetEventDataFromEvent(event_ptr); |
4150 | if (data) |
4151 | process_sp = data->GetProcessSP(); |
4152 | return process_sp; |
4153 | } |
4154 | |
4155 | StateType Process::ProcessEventData::GetStateFromEvent(const Event *event_ptr) { |
4156 | const ProcessEventData *data = GetEventDataFromEvent(event_ptr); |
4157 | if (data == nullptr) |
4158 | return eStateInvalid; |
4159 | else |
4160 | return data->GetState(); |
4161 | } |
4162 | |
4163 | bool Process::ProcessEventData::GetRestartedFromEvent(const Event *event_ptr) { |
4164 | const ProcessEventData *data = GetEventDataFromEvent(event_ptr); |
4165 | if (data == nullptr) |
4166 | return false; |
4167 | else |
4168 | return data->GetRestarted(); |
4169 | } |
4170 | |
4171 | void Process::ProcessEventData::SetRestartedInEvent(Event *event_ptr, |
4172 | bool new_value) { |
4173 | ProcessEventData *data = |
4174 | const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr)); |
4175 | if (data != nullptr) |
4176 | data->SetRestarted(new_value); |
4177 | } |
4178 | |
4179 | size_t |
4180 | Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr) { |
4181 | ProcessEventData *data = |
4182 | const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr)); |
4183 | if (data != nullptr) |
4184 | return data->GetNumRestartedReasons(); |
4185 | else |
4186 | return 0; |
4187 | } |
4188 | |
4189 | const char * |
4190 | Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, |
4191 | size_t idx) { |
4192 | ProcessEventData *data = |
4193 | const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr)); |
4194 | if (data != nullptr) |
4195 | return data->GetRestartedReasonAtIndex(idx); |
4196 | else |
4197 | return nullptr; |
4198 | } |
4199 | |
4200 | void Process::ProcessEventData::AddRestartedReason(Event *event_ptr, |
4201 | const char *reason) { |
4202 | ProcessEventData *data = |
4203 | const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr)); |
4204 | if (data != nullptr) |
4205 | data->AddRestartedReason(reason); |
4206 | } |
4207 | |
4208 | bool Process::ProcessEventData::GetInterruptedFromEvent( |
4209 | const Event *event_ptr) { |
4210 | const ProcessEventData *data = GetEventDataFromEvent(event_ptr); |
4211 | if (data == nullptr) |
4212 | return false; |
4213 | else |
4214 | return data->GetInterrupted(); |
4215 | } |
4216 | |
4217 | void Process::ProcessEventData::SetInterruptedInEvent(Event *event_ptr, |
4218 | bool new_value) { |
4219 | ProcessEventData *data = |
4220 | const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr)); |
4221 | if (data != nullptr) |
4222 | data->SetInterrupted(new_value); |
4223 | } |
4224 | |
4225 | bool Process::ProcessEventData::SetUpdateStateOnRemoval(Event *event_ptr) { |
4226 | ProcessEventData *data = |
4227 | const_cast<ProcessEventData *>(GetEventDataFromEvent(event_ptr)); |
4228 | if (data) { |
4229 | data->SetUpdateStateOnRemoval(); |
4230 | return true; |
4231 | } |
4232 | return false; |
4233 | } |
4234 | |
4235 | lldb::TargetSP Process::CalculateTarget() { return m_target_wp.lock(); } |
4236 | |
4237 | void Process::CalculateExecutionContext(ExecutionContext &exe_ctx) { |
4238 | exe_ctx.SetTargetPtr(&GetTarget()); |
4239 | exe_ctx.SetProcessPtr(this); |
4240 | exe_ctx.SetThreadPtr(nullptr); |
4241 | exe_ctx.SetFramePtr(nullptr); |
4242 | } |
4243 | |
4244 | // uint32_t |
4245 | // Process::ListProcessesMatchingName (const char *name, StringList &matches, |
4246 | // std::vector<lldb::pid_t> &pids) |
4247 | //{ |
4248 | // return 0; |
4249 | //} |
4250 | // |
4251 | // ArchSpec |
4252 | // Process::GetArchSpecForExistingProcess (lldb::pid_t pid) |
4253 | //{ |
4254 | // return Host::GetArchSpecForExistingProcess (pid); |
4255 | //} |
4256 | // |
4257 | // ArchSpec |
4258 | // Process::GetArchSpecForExistingProcess (const char *process_name) |
4259 | //{ |
4260 | // return Host::GetArchSpecForExistingProcess (process_name); |
4261 | //} |
4262 | |
4263 | void Process::AppendSTDOUT(const char *s, size_t len) { |
4264 | std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); |
4265 | m_stdout_data.append(s, len); |
4266 | BroadcastEventIfUnique(eBroadcastBitSTDOUT, |
4267 | new ProcessEventData(shared_from_this(), GetState())); |
4268 | } |
4269 | |
4270 | void Process::AppendSTDERR(const char *s, size_t len) { |
4271 | std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); |
4272 | m_stderr_data.append(s, len); |
4273 | BroadcastEventIfUnique(eBroadcastBitSTDERR, |
4274 | new ProcessEventData(shared_from_this(), GetState())); |
4275 | } |
4276 | |
4277 | void Process::BroadcastAsyncProfileData(const std::string &one_profile_data) { |
4278 | std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex); |
4279 | m_profile_data.push_back(one_profile_data); |
4280 | BroadcastEventIfUnique(eBroadcastBitProfileData, |
4281 | new ProcessEventData(shared_from_this(), GetState())); |
4282 | } |
4283 | |
4284 | void Process::BroadcastStructuredData(const StructuredData::ObjectSP &object_sp, |
4285 | const StructuredDataPluginSP &plugin_sp) { |
4286 | BroadcastEvent( |
4287 | eBroadcastBitStructuredData, |
4288 | new EventDataStructuredData(shared_from_this(), object_sp, plugin_sp)); |
4289 | } |
4290 | |
4291 | StructuredDataPluginSP |
4292 | Process::GetStructuredDataPlugin(ConstString type_name) const { |
4293 | auto find_it = m_structured_data_plugin_map.find(type_name); |
4294 | if (find_it != m_structured_data_plugin_map.end()) |
4295 | return find_it->second; |
4296 | else |
4297 | return StructuredDataPluginSP(); |
4298 | } |
4299 | |
4300 | size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Status &error) { |
4301 | std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex); |
4302 | if (m_profile_data.empty()) |
4303 | return 0; |
4304 | |
4305 | std::string &one_profile_data = m_profile_data.front(); |
4306 | size_t bytes_available = one_profile_data.size(); |
4307 | if (bytes_available > 0) { |
4308 | Log *log = GetLog(LLDBLog::Process); |
4309 | LLDB_LOGF(log, "Process::GetProfileData (buf = %p, size = %" PRIu64 ")",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::GetProfileData (buf = %p, size = %" "l" "u" ")", static_cast<void *>(buf), static_cast< uint64_t>(buf_size)); } while (0) |
4310 | static_cast<void *>(buf), static_cast<uint64_t>(buf_size))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::GetProfileData (buf = %p, size = %" "l" "u" ")", static_cast<void *>(buf), static_cast< uint64_t>(buf_size)); } while (0); |
4311 | if (bytes_available > buf_size) { |
4312 | memcpy(buf, one_profile_data.c_str(), buf_size); |
4313 | one_profile_data.erase(0, buf_size); |
4314 | bytes_available = buf_size; |
4315 | } else { |
4316 | memcpy(buf, one_profile_data.c_str(), bytes_available); |
4317 | m_profile_data.erase(m_profile_data.begin()); |
4318 | } |
4319 | } |
4320 | return bytes_available; |
4321 | } |
4322 | |
4323 | // Process STDIO |
4324 | |
4325 | size_t Process::GetSTDOUT(char *buf, size_t buf_size, Status &error) { |
4326 | std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); |
4327 | size_t bytes_available = m_stdout_data.size(); |
4328 | if (bytes_available > 0) { |
4329 | Log *log = GetLog(LLDBLog::Process); |
4330 | LLDB_LOGF(log, "Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::GetSTDOUT (buf = %p, size = %" "l" "u" ")", static_cast<void *>(buf), static_cast< uint64_t>(buf_size)); } while (0) |
4331 | static_cast<void *>(buf), static_cast<uint64_t>(buf_size))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::GetSTDOUT (buf = %p, size = %" "l" "u" ")", static_cast<void *>(buf), static_cast< uint64_t>(buf_size)); } while (0); |
4332 | if (bytes_available > buf_size) { |
4333 | memcpy(buf, m_stdout_data.c_str(), buf_size); |
4334 | m_stdout_data.erase(0, buf_size); |
4335 | bytes_available = buf_size; |
4336 | } else { |
4337 | memcpy(buf, m_stdout_data.c_str(), bytes_available); |
4338 | m_stdout_data.clear(); |
4339 | } |
4340 | } |
4341 | return bytes_available; |
4342 | } |
4343 | |
4344 | size_t Process::GetSTDERR(char *buf, size_t buf_size, Status &error) { |
4345 | std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex); |
4346 | size_t bytes_available = m_stderr_data.size(); |
4347 | if (bytes_available > 0) { |
4348 | Log *log = GetLog(LLDBLog::Process); |
4349 | LLDB_LOGF(log, "Process::GetSTDERR (buf = %p, size = %" PRIu64 ")",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::GetSTDERR (buf = %p, size = %" "l" "u" ")", static_cast<void *>(buf), static_cast< uint64_t>(buf_size)); } while (0) |
4350 | static_cast<void *>(buf), static_cast<uint64_t>(buf_size))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::GetSTDERR (buf = %p, size = %" "l" "u" ")", static_cast<void *>(buf), static_cast< uint64_t>(buf_size)); } while (0); |
4351 | if (bytes_available > buf_size) { |
4352 | memcpy(buf, m_stderr_data.c_str(), buf_size); |
4353 | m_stderr_data.erase(0, buf_size); |
4354 | bytes_available = buf_size; |
4355 | } else { |
4356 | memcpy(buf, m_stderr_data.c_str(), bytes_available); |
4357 | m_stderr_data.clear(); |
4358 | } |
4359 | } |
4360 | return bytes_available; |
4361 | } |
4362 | |
4363 | void Process::STDIOReadThreadBytesReceived(void *baton, const void *src, |
4364 | size_t src_len) { |
4365 | Process *process = (Process *)baton; |
4366 | process->AppendSTDOUT(static_cast<const char *>(src), src_len); |
4367 | } |
4368 | |
4369 | class IOHandlerProcessSTDIO : public IOHandler { |
4370 | public: |
4371 | IOHandlerProcessSTDIO(Process *process, int write_fd) |
4372 | : IOHandler(process->GetTarget().GetDebugger(), |
4373 | IOHandler::Type::ProcessIO), |
4374 | m_process(process), |
4375 | m_read_file(GetInputFD(), File::eOpenOptionReadOnly, false), |
4376 | m_write_file(write_fd, File::eOpenOptionWriteOnly, false) { |
4377 | m_pipe.CreateNew(false); |
4378 | } |
4379 | |
4380 | ~IOHandlerProcessSTDIO() override = default; |
4381 | |
4382 | void SetIsRunning(bool running) { |
4383 | std::lock_guard<std::mutex> guard(m_mutex); |
4384 | SetIsDone(!running); |
4385 | m_is_running = running; |
4386 | } |
4387 | |
4388 | // Each IOHandler gets to run until it is done. It should read data from the |
4389 | // "in" and place output into "out" and "err and return when done. |
4390 | void Run() override { |
4391 | if (!m_read_file.IsValid() || !m_write_file.IsValid() || |
4392 | !m_pipe.CanRead() || !m_pipe.CanWrite()) { |
4393 | SetIsDone(true); |
4394 | return; |
4395 | } |
4396 | |
4397 | SetIsDone(false); |
4398 | const int read_fd = m_read_file.GetDescriptor(); |
4399 | Terminal terminal(read_fd); |
4400 | TerminalState terminal_state(terminal, false); |
4401 | // FIXME: error handling? |
4402 | llvm::consumeError(terminal.SetCanonical(false)); |
4403 | llvm::consumeError(terminal.SetEcho(false)); |
4404 | // FD_ZERO, FD_SET are not supported on windows |
4405 | #ifndef _WIN32 |
4406 | const int pipe_read_fd = m_pipe.GetReadFileDescriptor(); |
4407 | SetIsRunning(true); |
4408 | while (true) { |
4409 | { |
4410 | std::lock_guard<std::mutex> guard(m_mutex); |
4411 | if (GetIsDone()) |
4412 | break; |
4413 | } |
4414 | |
4415 | SelectHelper select_helper; |
4416 | select_helper.FDSetRead(read_fd); |
4417 | select_helper.FDSetRead(pipe_read_fd); |
4418 | Status error = select_helper.Select(); |
4419 | |
4420 | if (error.Fail()) |
4421 | break; |
4422 | |
4423 | char ch = 0; |
4424 | size_t n; |
4425 | if (select_helper.FDIsSetRead(read_fd)) { |
4426 | n = 1; |
4427 | if (m_read_file.Read(&ch, n).Success() && n == 1) { |
4428 | if (m_write_file.Write(&ch, n).Fail() || n != 1) |
4429 | break; |
4430 | } else |
4431 | break; |
4432 | } |
4433 | |
4434 | if (select_helper.FDIsSetRead(pipe_read_fd)) { |
4435 | size_t bytes_read; |
4436 | // Consume the interrupt byte |
4437 | Status error = m_pipe.Read(&ch, 1, bytes_read); |
4438 | if (error.Success()) { |
4439 | if (ch == 'q') |
4440 | break; |
4441 | if (ch == 'i') |
4442 | if (StateIsRunningState(m_process->GetState())) |
4443 | m_process->SendAsyncInterrupt(); |
4444 | } |
4445 | } |
4446 | } |
4447 | SetIsRunning(false); |
4448 | #endif |
4449 | } |
4450 | |
4451 | void Cancel() override { |
4452 | std::lock_guard<std::mutex> guard(m_mutex); |
4453 | SetIsDone(true); |
4454 | // Only write to our pipe to cancel if we are in |
4455 | // IOHandlerProcessSTDIO::Run(). We can end up with a python command that |
4456 | // is being run from the command interpreter: |
4457 | // |
4458 | // (lldb) step_process_thousands_of_times |
4459 | // |
4460 | // In this case the command interpreter will be in the middle of handling |
4461 | // the command and if the process pushes and pops the IOHandler thousands |
4462 | // of times, we can end up writing to m_pipe without ever consuming the |
4463 | // bytes from the pipe in IOHandlerProcessSTDIO::Run() and end up |
4464 | // deadlocking when the pipe gets fed up and blocks until data is consumed. |
4465 | if (m_is_running) { |
4466 | char ch = 'q'; // Send 'q' for quit |
4467 | size_t bytes_written = 0; |
4468 | m_pipe.Write(&ch, 1, bytes_written); |
4469 | } |
4470 | } |
4471 | |
4472 | bool Interrupt() override { |
4473 | // Do only things that are safe to do in an interrupt context (like in a |
4474 | // SIGINT handler), like write 1 byte to a file descriptor. This will |
4475 | // interrupt the IOHandlerProcessSTDIO::Run() and we can look at the byte |
4476 | // that was written to the pipe and then call |
4477 | // m_process->SendAsyncInterrupt() from a much safer location in code. |
4478 | if (m_active) { |
4479 | char ch = 'i'; // Send 'i' for interrupt |
4480 | size_t bytes_written = 0; |
4481 | Status result = m_pipe.Write(&ch, 1, bytes_written); |
4482 | return result.Success(); |
4483 | } else { |
4484 | // This IOHandler might be pushed on the stack, but not being run |
4485 | // currently so do the right thing if we aren't actively watching for |
4486 | // STDIN by sending the interrupt to the process. Otherwise the write to |
4487 | // the pipe above would do nothing. This can happen when the command |
4488 | // interpreter is running and gets a "expression ...". It will be on the |
4489 | // IOHandler thread and sending the input is complete to the delegate |
4490 | // which will cause the expression to run, which will push the process IO |
4491 | // handler, but not run it. |
4492 | |
4493 | if (StateIsRunningState(m_process->GetState())) { |
4494 | m_process->SendAsyncInterrupt(); |
4495 | return true; |
4496 | } |
4497 | } |
4498 | return false; |
4499 | } |
4500 | |
4501 | void GotEOF() override {} |
4502 | |
4503 | protected: |
4504 | Process *m_process; |
4505 | NativeFile m_read_file; // Read from this file (usually actual STDIN for LLDB |
4506 | NativeFile m_write_file; // Write to this file (usually the primary pty for |
4507 | // getting io to debuggee) |
4508 | Pipe m_pipe; |
4509 | std::mutex m_mutex; |
4510 | bool m_is_running = false; |
4511 | }; |
4512 | |
4513 | void Process::SetSTDIOFileDescriptor(int fd) { |
4514 | // First set up the Read Thread for reading/handling process I/O |
4515 | m_stdio_communication.SetConnection( |
4516 | std::make_unique<ConnectionFileDescriptor>(fd, true)); |
4517 | if (m_stdio_communication.IsConnected()) { |
4518 | m_stdio_communication.SetReadThreadBytesReceivedCallback( |
4519 | STDIOReadThreadBytesReceived, this); |
4520 | m_stdio_communication.StartReadThread(); |
4521 | |
4522 | // Now read thread is set up, set up input reader. |
4523 | |
4524 | if (!m_process_input_reader) |
4525 | m_process_input_reader = |
4526 | std::make_shared<IOHandlerProcessSTDIO>(this, fd); |
4527 | } |
4528 | } |
4529 | |
4530 | bool Process::ProcessIOHandlerIsActive() { |
4531 | IOHandlerSP io_handler_sp(m_process_input_reader); |
4532 | if (io_handler_sp) |
4533 | return GetTarget().GetDebugger().IsTopIOHandler(io_handler_sp); |
4534 | return false; |
4535 | } |
4536 | bool Process::PushProcessIOHandler() { |
4537 | IOHandlerSP io_handler_sp(m_process_input_reader); |
4538 | if (io_handler_sp) { |
4539 | Log *log = GetLog(LLDBLog::Process); |
4540 | LLDB_LOGF(log, "Process::%s pushing IO handler", __FUNCTION__)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::%s pushing IO handler", __FUNCTION__ ); } while (0); |
4541 | |
4542 | io_handler_sp->SetIsDone(false); |
4543 | // If we evaluate an utility function, then we don't cancel the current |
4544 | // IOHandler. Our IOHandler is non-interactive and shouldn't disturb the |
4545 | // existing IOHandler that potentially provides the user interface (e.g. |
4546 | // the IOHandler for Editline). |
4547 | bool cancel_top_handler = !m_mod_id.IsRunningUtilityFunction(); |
4548 | GetTarget().GetDebugger().RunIOHandlerAsync(io_handler_sp, |
4549 | cancel_top_handler); |
4550 | return true; |
4551 | } |
4552 | return false; |
4553 | } |
4554 | |
4555 | bool Process::PopProcessIOHandler() { |
4556 | IOHandlerSP io_handler_sp(m_process_input_reader); |
4557 | if (io_handler_sp) |
4558 | return GetTarget().GetDebugger().RemoveIOHandler(io_handler_sp); |
4559 | return false; |
4560 | } |
4561 | |
4562 | // The process needs to know about installed plug-ins |
4563 | void Process::SettingsInitialize() { Thread::SettingsInitialize(); } |
4564 | |
4565 | void Process::SettingsTerminate() { Thread::SettingsTerminate(); } |
4566 | |
4567 | namespace { |
4568 | // RestorePlanState is used to record the "is private", "is controlling" and |
4569 | // "okay |
4570 | // to discard" fields of the plan we are running, and reset it on Clean or on |
4571 | // destruction. It will only reset the state once, so you can call Clean and |
4572 | // then monkey with the state and it won't get reset on you again. |
4573 | |
4574 | class RestorePlanState { |
4575 | public: |
4576 | RestorePlanState(lldb::ThreadPlanSP thread_plan_sp) |
4577 | : m_thread_plan_sp(thread_plan_sp) { |
4578 | if (m_thread_plan_sp) { |
4579 | m_private = m_thread_plan_sp->GetPrivate(); |
4580 | m_is_controlling = m_thread_plan_sp->IsControllingPlan(); |
4581 | m_okay_to_discard = m_thread_plan_sp->OkayToDiscard(); |
4582 | } |
4583 | } |
4584 | |
4585 | ~RestorePlanState() { Clean(); } |
4586 | |
4587 | void Clean() { |
4588 | if (!m_already_reset && m_thread_plan_sp) { |
4589 | m_already_reset = true; |
4590 | m_thread_plan_sp->SetPrivate(m_private); |
4591 | m_thread_plan_sp->SetIsControllingPlan(m_is_controlling); |
4592 | m_thread_plan_sp->SetOkayToDiscard(m_okay_to_discard); |
4593 | } |
4594 | } |
4595 | |
4596 | private: |
4597 | lldb::ThreadPlanSP m_thread_plan_sp; |
4598 | bool m_already_reset = false; |
4599 | bool m_private = false; |
4600 | bool m_is_controlling = false; |
4601 | bool m_okay_to_discard = false; |
4602 | }; |
4603 | } // anonymous namespace |
4604 | |
4605 | static microseconds |
4606 | GetOneThreadExpressionTimeout(const EvaluateExpressionOptions &options) { |
4607 | const milliseconds default_one_thread_timeout(250); |
4608 | |
4609 | // If the overall wait is forever, then we don't need to worry about it. |
4610 | if (!options.GetTimeout()) { |
4611 | return options.GetOneThreadTimeout() ? *options.GetOneThreadTimeout() |
4612 | : default_one_thread_timeout; |
4613 | } |
4614 | |
4615 | // If the one thread timeout is set, use it. |
4616 | if (options.GetOneThreadTimeout()) |
4617 | return *options.GetOneThreadTimeout(); |
4618 | |
4619 | // Otherwise use half the total timeout, bounded by the |
4620 | // default_one_thread_timeout. |
4621 | return std::min<microseconds>(default_one_thread_timeout, |
4622 | *options.GetTimeout() / 2); |
4623 | } |
4624 | |
4625 | static Timeout<std::micro> |
4626 | GetExpressionTimeout(const EvaluateExpressionOptions &options, |
4627 | bool before_first_timeout) { |
4628 | // If we are going to run all threads the whole time, or if we are only going |
4629 | // to run one thread, we can just return the overall timeout. |
4630 | if (!options.GetStopOthers() || !options.GetTryAllThreads()) |
4631 | return options.GetTimeout(); |
4632 | |
4633 | if (before_first_timeout) |
4634 | return GetOneThreadExpressionTimeout(options); |
4635 | |
4636 | if (!options.GetTimeout()) |
4637 | return std::nullopt; |
4638 | else |
4639 | return *options.GetTimeout() - GetOneThreadExpressionTimeout(options); |
4640 | } |
4641 | |
4642 | static std::optional<ExpressionResults> |
4643 | HandleStoppedEvent(lldb::tid_t thread_id, const ThreadPlanSP &thread_plan_sp, |
4644 | RestorePlanState &restorer, const EventSP &event_sp, |
4645 | EventSP &event_to_broadcast_sp, |
4646 | const EvaluateExpressionOptions &options, |
4647 | bool handle_interrupts) { |
4648 | Log *log = GetLog(LLDBLog::Step | LLDBLog::Process); |
4649 | |
4650 | ThreadSP thread_sp = thread_plan_sp->GetTarget() |
4651 | .GetProcessSP() |
4652 | ->GetThreadList() |
4653 | .FindThreadByID(thread_id); |
4654 | if (!thread_sp) { |
4655 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "The thread on which we were running the " "expression: tid = {0}, exited while " "the expression was running.", thread_id); } while (0) |
4656 | "The thread on which we were running the "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "The thread on which we were running the " "expression: tid = {0}, exited while " "the expression was running.", thread_id); } while (0) |
4657 | "expression: tid = {0}, exited while "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "The thread on which we were running the " "expression: tid = {0}, exited while " "the expression was running.", thread_id); } while (0) |
4658 | "the expression was running.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "The thread on which we were running the " "expression: tid = {0}, exited while " "the expression was running.", thread_id); } while (0) |
4659 | thread_id)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "The thread on which we were running the " "expression: tid = {0}, exited while " "the expression was running.", thread_id); } while (0); |
4660 | return eExpressionThreadVanished; |
4661 | } |
4662 | |
4663 | ThreadPlanSP plan = thread_sp->GetCompletedPlan(); |
4664 | if (plan == thread_plan_sp && plan->PlanSucceeded()) { |
4665 | LLDB_LOG(log, "execution completed successfully")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "execution completed successfully"); } while (0); |
4666 | |
4667 | // Restore the plan state so it will get reported as intended when we are |
4668 | // done. |
4669 | restorer.Clean(); |
4670 | return eExpressionCompleted; |
4671 | } |
4672 | |
4673 | StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); |
4674 | if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint && |
4675 | stop_info_sp->ShouldNotify(event_sp.get())) { |
4676 | LLDB_LOG(log, "stopped for breakpoint: {0}.", stop_info_sp->GetDescription())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "stopped for breakpoint: {0}.", stop_info_sp->GetDescription ()); } while (0); |
4677 | if (!options.DoesIgnoreBreakpoints()) { |
4678 | // Restore the plan state and then force Private to false. We are going |
4679 | // to stop because of this plan so we need it to become a public plan or |
4680 | // it won't report correctly when we continue to its termination later |
4681 | // on. |
4682 | restorer.Clean(); |
4683 | thread_plan_sp->SetPrivate(false); |
4684 | event_to_broadcast_sp = event_sp; |
4685 | } |
4686 | return eExpressionHitBreakpoint; |
4687 | } |
4688 | |
4689 | if (!handle_interrupts && |
4690 | Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get())) |
4691 | return std::nullopt; |
4692 | |
4693 | LLDB_LOG(log, "thread plan did not successfully complete")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "thread plan did not successfully complete"); } while (0); |
4694 | if (!options.DoesUnwindOnError()) |
4695 | event_to_broadcast_sp = event_sp; |
4696 | return eExpressionInterrupted; |
4697 | } |
4698 | |
4699 | ExpressionResults |
4700 | Process::RunThreadPlan(ExecutionContext &exe_ctx, |
4701 | lldb::ThreadPlanSP &thread_plan_sp, |
4702 | const EvaluateExpressionOptions &options, |
4703 | DiagnosticManager &diagnostic_manager) { |
4704 | ExpressionResults return_value = eExpressionSetupError; |
4705 | |
4706 | std::lock_guard<std::mutex> run_thread_plan_locker(m_run_thread_plan_lock); |
4707 | |
4708 | if (!thread_plan_sp) { |
4709 | diagnostic_manager.PutString( |
4710 | eDiagnosticSeverityError, |
4711 | "RunThreadPlan called with empty thread plan."); |
4712 | return eExpressionSetupError; |
4713 | } |
4714 | |
4715 | if (!thread_plan_sp->ValidatePlan(nullptr)) { |
4716 | diagnostic_manager.PutString( |
4717 | eDiagnosticSeverityError, |
4718 | "RunThreadPlan called with an invalid thread plan."); |
4719 | return eExpressionSetupError; |
4720 | } |
4721 | |
4722 | if (exe_ctx.GetProcessPtr() != this) { |
4723 | diagnostic_manager.PutString(eDiagnosticSeverityError, |
4724 | "RunThreadPlan called on wrong process."); |
4725 | return eExpressionSetupError; |
4726 | } |
4727 | |
4728 | Thread *thread = exe_ctx.GetThreadPtr(); |
4729 | if (thread == nullptr) { |
4730 | diagnostic_manager.PutString(eDiagnosticSeverityError, |
4731 | "RunThreadPlan called with invalid thread."); |
4732 | return eExpressionSetupError; |
4733 | } |
4734 | |
4735 | // Record the thread's id so we can tell when a thread we were using |
4736 | // to run the expression exits during the expression evaluation. |
4737 | lldb::tid_t expr_thread_id = thread->GetID(); |
4738 | |
4739 | // We need to change some of the thread plan attributes for the thread plan |
4740 | // runner. This will restore them when we are done: |
4741 | |
4742 | RestorePlanState thread_plan_restorer(thread_plan_sp); |
4743 | |
4744 | // We rely on the thread plan we are running returning "PlanCompleted" if |
4745 | // when it successfully completes. For that to be true the plan can't be |
4746 | // private - since private plans suppress themselves in the GetCompletedPlan |
4747 | // call. |
4748 | |
4749 | thread_plan_sp->SetPrivate(false); |
4750 | |
4751 | // The plans run with RunThreadPlan also need to be terminal controlling plans |
4752 | // or when they are done we will end up asking the plan above us whether we |
4753 | // should stop, which may give the wrong answer. |
4754 | |
4755 | thread_plan_sp->SetIsControllingPlan(true); |
4756 | thread_plan_sp->SetOkayToDiscard(false); |
4757 | |
4758 | // If we are running some utility expression for LLDB, we now have to mark |
4759 | // this in the ProcesModID of this process. This RAII takes care of marking |
4760 | // and reverting the mark it once we are done running the expression. |
4761 | UtilityFunctionScope util_scope(options.IsForUtilityExpr() ? this : nullptr); |
4762 | |
4763 | if (m_private_state.GetValue() != eStateStopped) { |
4764 | diagnostic_manager.PutString( |
4765 | eDiagnosticSeverityError, |
4766 | "RunThreadPlan called while the private state was not stopped."); |
4767 | return eExpressionSetupError; |
4768 | } |
4769 | |
4770 | // Save the thread & frame from the exe_ctx for restoration after we run |
4771 | const uint32_t thread_idx_id = thread->GetIndexID(); |
4772 | StackFrameSP selected_frame_sp = |
4773 | thread->GetSelectedFrame(DoNoSelectMostRelevantFrame); |
4774 | if (!selected_frame_sp) { |
4775 | thread->SetSelectedFrame(nullptr); |
4776 | selected_frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame); |
4777 | if (!selected_frame_sp) { |
4778 | diagnostic_manager.Printf( |
4779 | eDiagnosticSeverityError, |
4780 | "RunThreadPlan called without a selected frame on thread %d", |
4781 | thread_idx_id); |
4782 | return eExpressionSetupError; |
4783 | } |
4784 | } |
4785 | |
4786 | // Make sure the timeout values make sense. The one thread timeout needs to |
4787 | // be smaller than the overall timeout. |
4788 | if (options.GetOneThreadTimeout() && options.GetTimeout() && |
4789 | *options.GetTimeout() < *options.GetOneThreadTimeout()) { |
4790 | diagnostic_manager.PutString(eDiagnosticSeverityError, |
4791 | "RunThreadPlan called with one thread " |
4792 | "timeout greater than total timeout"); |
4793 | return eExpressionSetupError; |
4794 | } |
4795 | |
4796 | StackID ctx_frame_id = selected_frame_sp->GetStackID(); |
4797 | |
4798 | // N.B. Running the target may unset the currently selected thread and frame. |
4799 | // We don't want to do that either, so we should arrange to reset them as |
4800 | // well. |
4801 | |
4802 | lldb::ThreadSP selected_thread_sp = GetThreadList().GetSelectedThread(); |
4803 | |
4804 | uint32_t selected_tid; |
4805 | StackID selected_stack_id; |
4806 | if (selected_thread_sp) { |
4807 | selected_tid = selected_thread_sp->GetIndexID(); |
4808 | selected_stack_id = |
4809 | selected_thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame) |
4810 | ->GetStackID(); |
4811 | } else { |
4812 | selected_tid = LLDB_INVALID_THREAD_ID0; |
4813 | } |
4814 | |
4815 | HostThread backup_private_state_thread; |
4816 | lldb::StateType old_state = eStateInvalid; |
4817 | lldb::ThreadPlanSP stopper_base_plan_sp; |
4818 | |
4819 | Log *log(GetLog(LLDBLog::Step | LLDBLog::Process)); |
4820 | if (m_private_state_thread.EqualsThread(Host::GetCurrentThread())) { |
4821 | // Yikes, we are running on the private state thread! So we can't wait for |
4822 | // public events on this thread, since we are the thread that is generating |
4823 | // public events. The simplest thing to do is to spin up a temporary thread |
4824 | // to handle private state thread events while we are fielding public |
4825 | // events here. |
4826 | LLDB_LOGF(log, "Running thread plan on private state thread, spinning up "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Running thread plan on private state thread, spinning up " "another state thread to handle the events."); } while (0) |
4827 | "another state thread to handle the events.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Running thread plan on private state thread, spinning up " "another state thread to handle the events."); } while (0); |
4828 | |
4829 | backup_private_state_thread = m_private_state_thread; |
4830 | |
4831 | // One other bit of business: we want to run just this thread plan and |
4832 | // anything it pushes, and then stop, returning control here. But in the |
4833 | // normal course of things, the plan above us on the stack would be given a |
4834 | // shot at the stop event before deciding to stop, and we don't want that. |
4835 | // So we insert a "stopper" base plan on the stack before the plan we want |
4836 | // to run. Since base plans always stop and return control to the user, |
4837 | // that will do just what we want. |
4838 | stopper_base_plan_sp.reset(new ThreadPlanBase(*thread)); |
4839 | thread->QueueThreadPlan(stopper_base_plan_sp, false); |
4840 | // Have to make sure our public state is stopped, since otherwise the |
4841 | // reporting logic below doesn't work correctly. |
4842 | old_state = m_public_state.GetValue(); |
4843 | m_public_state.SetValueNoLock(eStateStopped); |
4844 | |
4845 | // Now spin up the private state thread: |
4846 | StartPrivateStateThread(true); |
4847 | } |
4848 | |
4849 | thread->QueueThreadPlan( |
4850 | thread_plan_sp, false); // This used to pass "true" does that make sense? |
4851 | |
4852 | if (options.GetDebug()) { |
4853 | // In this case, we aren't actually going to run, we just want to stop |
4854 | // right away. Flush this thread so we will refetch the stacks and show the |
4855 | // correct backtrace. |
4856 | // FIXME: To make this prettier we should invent some stop reason for this, |
4857 | // but that |
4858 | // is only cosmetic, and this functionality is only of use to lldb |
4859 | // developers who can live with not pretty... |
4860 | thread->Flush(); |
4861 | return eExpressionStoppedForDebug; |
4862 | } |
4863 | |
4864 | ListenerSP listener_sp( |
4865 | Listener::MakeListener("lldb.process.listener.run-thread-plan")); |
4866 | |
4867 | lldb::EventSP event_to_broadcast_sp; |
4868 | |
4869 | { |
4870 | // This process event hijacker Hijacks the Public events and its destructor |
4871 | // makes sure that the process events get restored on exit to the function. |
4872 | // |
4873 | // If the event needs to propagate beyond the hijacker (e.g., the process |
4874 | // exits during execution), then the event is put into |
4875 | // event_to_broadcast_sp for rebroadcasting. |
4876 | |
4877 | ProcessEventHijacker run_thread_plan_hijacker(*this, listener_sp); |
4878 | |
4879 | if (log) { |
4880 | StreamString s; |
4881 | thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); |
4882 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" "l" "x" " to run thread plan \"%s\".", thread_idx_id, expr_thread_id , s.GetData()); } while (0) |
4883 | "Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" "l" "x" " to run thread plan \"%s\".", thread_idx_id, expr_thread_id , s.GetData()); } while (0) |
4884 | " to run thread plan \"%s\".",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" "l" "x" " to run thread plan \"%s\".", thread_idx_id, expr_thread_id , s.GetData()); } while (0) |
4885 | thread_idx_id, expr_thread_id, s.GetData())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" "l" "x" " to run thread plan \"%s\".", thread_idx_id, expr_thread_id , s.GetData()); } while (0); |
4886 | } |
4887 | |
4888 | bool got_event; |
4889 | lldb::EventSP event_sp; |
4890 | lldb::StateType stop_state = lldb::eStateInvalid; |
4891 | |
4892 | bool before_first_timeout = true; // This is set to false the first time |
4893 | // that we have to halt the target. |
4894 | bool do_resume = true; |
4895 | bool handle_running_event = true; |
4896 | |
4897 | // This is just for accounting: |
4898 | uint32_t num_resumes = 0; |
4899 | |
4900 | // If we are going to run all threads the whole time, or if we are only |
4901 | // going to run one thread, then we don't need the first timeout. So we |
4902 | // pretend we are after the first timeout already. |
4903 | if (!options.GetStopOthers() || !options.GetTryAllThreads()) |
4904 | before_first_timeout = false; |
4905 | |
4906 | LLDB_LOGF(log, "Stop others: %u, try all: %u, before_first: %u.\n",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Stop others: %u, try all: %u, before_first: %u.\n" , options.GetStopOthers(), options.GetTryAllThreads(), before_first_timeout ); } while (0) |
4907 | options.GetStopOthers(), options.GetTryAllThreads(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Stop others: %u, try all: %u, before_first: %u.\n" , options.GetStopOthers(), options.GetTryAllThreads(), before_first_timeout ); } while (0) |
4908 | before_first_timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Stop others: %u, try all: %u, before_first: %u.\n" , options.GetStopOthers(), options.GetTryAllThreads(), before_first_timeout ); } while (0); |
4909 | |
4910 | // This isn't going to work if there are unfetched events on the queue. Are |
4911 | // there cases where we might want to run the remaining events here, and |
4912 | // then try to call the function? That's probably being too tricky for our |
4913 | // own good. |
4914 | |
4915 | Event *other_events = listener_sp->PeekAtNextEvent(); |
4916 | if (other_events != nullptr) { |
4917 | diagnostic_manager.PutString( |
4918 | eDiagnosticSeverityError, |
4919 | "RunThreadPlan called with pending events on the queue."); |
4920 | return eExpressionSetupError; |
4921 | } |
4922 | |
4923 | // We also need to make sure that the next event is delivered. We might be |
4924 | // calling a function as part of a thread plan, in which case the last |
4925 | // delivered event could be the running event, and we don't want event |
4926 | // coalescing to cause us to lose OUR running event... |
4927 | ForceNextEventDelivery(); |
4928 | |
4929 | // This while loop must exit out the bottom, there's cleanup that we need to do |
4930 | // when we are done. So don't call return anywhere within it. |
4931 | |
4932 | #ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT |
4933 | // It's pretty much impossible to write test cases for things like: One |
4934 | // thread timeout expires, I go to halt, but the process already stopped on |
4935 | // the function call stop breakpoint. Turning on this define will make us |
4936 | // not fetch the first event till after the halt. So if you run a quick |
4937 | // function, it will have completed, and the completion event will be |
4938 | // waiting, when you interrupt for halt. The expression evaluation should |
4939 | // still succeed. |
4940 | bool miss_first_event = true; |
4941 | #endif |
4942 | while (true) { |
4943 | // We usually want to resume the process if we get to the top of the |
4944 | // loop. The only exception is if we get two running events with no |
4945 | // intervening stop, which can happen, we will just wait for then next |
4946 | // stop event. |
4947 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Top of while loop: do_resume: %i handle_running_event: %i " "before_first_timeout: %i.", do_resume, handle_running_event , before_first_timeout); } while (0) |
4948 | "Top of while loop: do_resume: %i handle_running_event: %i "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Top of while loop: do_resume: %i handle_running_event: %i " "before_first_timeout: %i.", do_resume, handle_running_event , before_first_timeout); } while (0) |
4949 | "before_first_timeout: %i.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Top of while loop: do_resume: %i handle_running_event: %i " "before_first_timeout: %i.", do_resume, handle_running_event , before_first_timeout); } while (0) |
4950 | do_resume, handle_running_event, before_first_timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Top of while loop: do_resume: %i handle_running_event: %i " "before_first_timeout: %i.", do_resume, handle_running_event , before_first_timeout); } while (0); |
4951 | |
4952 | if (do_resume || handle_running_event) { |
4953 | // Do the initial resume and wait for the running event before going |
4954 | // further. |
4955 | |
4956 | if (do_resume) { |
4957 | num_resumes++; |
4958 | Status resume_error = PrivateResume(); |
4959 | if (!resume_error.Success()) { |
4960 | diagnostic_manager.Printf( |
4961 | eDiagnosticSeverityError, |
4962 | "couldn't resume inferior the %d time: \"%s\".", num_resumes, |
4963 | resume_error.AsCString()); |
4964 | return_value = eExpressionSetupError; |
4965 | break; |
4966 | } |
4967 | } |
4968 | |
4969 | got_event = |
4970 | listener_sp->GetEvent(event_sp, GetUtilityExpressionTimeout()); |
4971 | if (!got_event) { |
4972 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get any event after " "resume %" "u" ", exiting.", num_resumes); } while (0) |
4973 | "Process::RunThreadPlan(): didn't get any event after "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get any event after " "resume %" "u" ", exiting.", num_resumes); } while (0) |
4974 | "resume %" PRIu32 ", exiting.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get any event after " "resume %" "u" ", exiting.", num_resumes); } while (0) |
4975 | num_resumes)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get any event after " "resume %" "u" ", exiting.", num_resumes); } while (0); |
4976 | |
4977 | diagnostic_manager.Printf(eDiagnosticSeverityError, |
4978 | "didn't get any event after resume %" PRIu32"u" |
4979 | ", exiting.", |
4980 | num_resumes); |
4981 | return_value = eExpressionSetupError; |
4982 | break; |
4983 | } |
4984 | |
4985 | stop_state = |
4986 | Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
4987 | |
4988 | if (stop_state != eStateRunning) { |
4989 | bool restarted = false; |
4990 | |
4991 | if (stop_state == eStateStopped) { |
4992 | restarted = Process::ProcessEventData::GetRestartedFromEvent( |
4993 | event_sp.get()); |
4994 | LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0) |
4995 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0) |
4996 | "Process::RunThreadPlan(): didn't get running event after "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0) |
4997 | "resume %d, got %s instead (restarted: %i, do_resume: %i, "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0) |
4998 | "handle_running_event: %i).",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0) |
4999 | num_resumes, StateAsCString(stop_state), restarted, do_resume,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0) |
5000 | handle_running_event)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): didn't get running event after " "resume %d, got %s instead (restarted: %i, do_resume: %i, " "handle_running_event: %i)." , num_resumes, StateAsCString(stop_state), restarted, do_resume , handle_running_event); } while (0); |
5001 | } |
5002 | |
5003 | if (restarted) { |
5004 | // This is probably an overabundance of caution, I don't think I |
5005 | // should ever get a stopped & restarted event here. But if I do, |
5006 | // the best thing is to Halt and then get out of here. |
5007 | const bool clear_thread_plans = false; |
5008 | const bool use_run_lock = false; |
5009 | Halt(clear_thread_plans, use_run_lock); |
5010 | } |
5011 | |
5012 | diagnostic_manager.Printf( |
5013 | eDiagnosticSeverityError, |
5014 | "didn't get running event after initial resume, got %s instead.", |
5015 | StateAsCString(stop_state)); |
5016 | return_value = eExpressionSetupError; |
5017 | break; |
5018 | } |
5019 | |
5020 | if (log) |
5021 | log->PutCString("Process::RunThreadPlan(): resuming succeeded."); |
5022 | // We need to call the function synchronously, so spin waiting for it |
5023 | // to return. If we get interrupted while executing, we're going to |
5024 | // lose our context, and won't be able to gather the result at this |
5025 | // point. We set the timeout AFTER the resume, since the resume takes |
5026 | // some time and we don't want to charge that to the timeout. |
5027 | } else { |
5028 | if (log) |
5029 | log->PutCString("Process::RunThreadPlan(): waiting for next event."); |
5030 | } |
5031 | |
5032 | do_resume = true; |
5033 | handle_running_event = true; |
5034 | |
5035 | // Now wait for the process to stop again: |
5036 | event_sp.reset(); |
5037 | |
5038 | Timeout<std::micro> timeout = |
5039 | GetExpressionTimeout(options, before_first_timeout); |
5040 | if (log) { |
5041 | if (timeout) { |
5042 | auto now = system_clock::now(); |
5043 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): about to wait - now is %s - " "endpoint is %s", llvm::to_string(now).c_str(), llvm::to_string (now + *timeout).c_str()); } while (0) |
5044 | "Process::RunThreadPlan(): about to wait - now is %s - "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): about to wait - now is %s - " "endpoint is %s", llvm::to_string(now).c_str(), llvm::to_string (now + *timeout).c_str()); } while (0) |
5045 | "endpoint is %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): about to wait - now is %s - " "endpoint is %s", llvm::to_string(now).c_str(), llvm::to_string (now + *timeout).c_str()); } while (0) |
5046 | llvm::to_string(now).c_str(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): about to wait - now is %s - " "endpoint is %s", llvm::to_string(now).c_str(), llvm::to_string (now + *timeout).c_str()); } while (0) |
5047 | llvm::to_string(now + *timeout).c_str())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): about to wait - now is %s - " "endpoint is %s", llvm::to_string(now).c_str(), llvm::to_string (now + *timeout).c_str()); } while (0); |
5048 | } else { |
5049 | LLDB_LOGF(log, "Process::RunThreadPlan(): about to wait forever.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): about to wait forever." ); } while (0); |
5050 | } |
5051 | } |
5052 | |
5053 | #ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT |
5054 | // See comment above... |
5055 | if (miss_first_event) { |
5056 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
5057 | miss_first_event = false; |
5058 | got_event = false; |
5059 | } else |
5060 | #endif |
5061 | got_event = listener_sp->GetEvent(event_sp, timeout); |
5062 | |
5063 | if (got_event) { |
5064 | if (event_sp) { |
5065 | bool keep_going = false; |
5066 | if (event_sp->GetType() == eBroadcastBitInterrupt) { |
5067 | const bool clear_thread_plans = false; |
5068 | const bool use_run_lock = false; |
5069 | Halt(clear_thread_plans, use_run_lock); |
5070 | return_value = eExpressionInterrupted; |
5071 | diagnostic_manager.PutString(eDiagnosticSeverityRemark, |
5072 | "execution halted by user interrupt."); |
5073 | LLDB_LOGF(log, "Process::RunThreadPlan(): Got interrupted by "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Got interrupted by " "eBroadcastBitInterrupted, exiting."); } while (0) |
5074 | "eBroadcastBitInterrupted, exiting.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Got interrupted by " "eBroadcastBitInterrupted, exiting."); } while (0); |
5075 | break; |
5076 | } else { |
5077 | stop_state = |
5078 | Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
5079 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): in while loop, got event: %s." , StateAsCString(stop_state)); } while (0) |
5080 | "Process::RunThreadPlan(): in while loop, got event: %s.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): in while loop, got event: %s." , StateAsCString(stop_state)); } while (0) |
5081 | StateAsCString(stop_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): in while loop, got event: %s." , StateAsCString(stop_state)); } while (0); |
5082 | |
5083 | switch (stop_state) { |
5084 | case lldb::eStateStopped: { |
5085 | if (Process::ProcessEventData::GetRestartedFromEvent( |
5086 | event_sp.get())) { |
5087 | // If we were restarted, we just need to go back up to fetch |
5088 | // another event. |
5089 | LLDB_LOGF(log, "Process::RunThreadPlan(): Got a stop and "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Got a stop and " "restart, so we'll continue waiting."); } while (0) |
5090 | "restart, so we'll continue waiting.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Got a stop and " "restart, so we'll continue waiting."); } while (0); |
5091 | keep_going = true; |
5092 | do_resume = false; |
5093 | handle_running_event = true; |
5094 | } else { |
5095 | const bool handle_interrupts = true; |
5096 | return_value = *HandleStoppedEvent( |
5097 | expr_thread_id, thread_plan_sp, thread_plan_restorer, |
5098 | event_sp, event_to_broadcast_sp, options, |
5099 | handle_interrupts); |
5100 | if (return_value == eExpressionThreadVanished) |
5101 | keep_going = false; |
5102 | } |
5103 | } break; |
5104 | |
5105 | case lldb::eStateRunning: |
5106 | // This shouldn't really happen, but sometimes we do get two |
5107 | // running events without an intervening stop, and in that case |
5108 | // we should just go back to waiting for the stop. |
5109 | do_resume = false; |
5110 | keep_going = true; |
5111 | handle_running_event = false; |
5112 | break; |
5113 | |
5114 | default: |
5115 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution stopped with " "unexpected state: %s.", StateAsCString(stop_state)); } while (0) |
5116 | "Process::RunThreadPlan(): execution stopped with "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution stopped with " "unexpected state: %s.", StateAsCString(stop_state)); } while (0) |
5117 | "unexpected state: %s.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution stopped with " "unexpected state: %s.", StateAsCString(stop_state)); } while (0) |
5118 | StateAsCString(stop_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution stopped with " "unexpected state: %s.", StateAsCString(stop_state)); } while (0); |
5119 | |
5120 | if (stop_state == eStateExited) |
5121 | event_to_broadcast_sp = event_sp; |
5122 | |
5123 | diagnostic_manager.PutString( |
5124 | eDiagnosticSeverityError, |
5125 | "execution stopped with unexpected state."); |
5126 | return_value = eExpressionInterrupted; |
5127 | break; |
5128 | } |
5129 | } |
5130 | |
5131 | if (keep_going) |
5132 | continue; |
5133 | else |
5134 | break; |
5135 | } else { |
5136 | if (log) |
5137 | log->PutCString("Process::RunThreadPlan(): got_event was true, but " |
5138 | "the event pointer was null. How odd..."); |
5139 | return_value = eExpressionInterrupted; |
5140 | break; |
5141 | } |
5142 | } else { |
5143 | // If we didn't get an event that means we've timed out... We will |
5144 | // interrupt the process here. Depending on what we were asked to do |
5145 | // we will either exit, or try with all threads running for the same |
5146 | // timeout. |
5147 | |
5148 | if (log) { |
5149 | if (options.GetTryAllThreads()) { |
5150 | if (before_first_timeout) { |
5151 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Running function with one thread timeout timed out."); } while (0) |
5152 | "Running function with one thread timeout timed out.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Running function with one thread timeout timed out."); } while (0); |
5153 | } else |
5154 | LLDB_LOG(log, "Restarting function with all threads enabled and "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Restarting function with all threads enabled and " "timeout: {0} timed out, abandoning execution." , timeout); } while (0) |
5155 | "timeout: {0} timed out, abandoning execution.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Restarting function with all threads enabled and " "timeout: {0} timed out, abandoning execution." , timeout); } while (0) |
5156 | timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Restarting function with all threads enabled and " "timeout: {0} timed out, abandoning execution." , timeout); } while (0); |
5157 | } else |
5158 | LLDB_LOG(log, "Running function with timeout: {0} timed out, "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Running function with timeout: {0} timed out, " "abandoning execution." , timeout); } while (0) |
5159 | "abandoning execution.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Running function with timeout: {0} timed out, " "abandoning execution." , timeout); } while (0) |
5160 | timeout)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Target/Process.cpp", __func__ , "Running function with timeout: {0} timed out, " "abandoning execution." , timeout); } while (0); |
5161 | } |
5162 | |
5163 | // It is possible that between the time we issued the Halt, and we get |
5164 | // around to calling Halt the target could have stopped. That's fine, |
5165 | // Halt will figure that out and send the appropriate Stopped event. |
5166 | // BUT it is also possible that we stopped & restarted (e.g. hit a |
5167 | // signal with "stop" set to false.) In |
5168 | // that case, we'll get the stopped & restarted event, and we should go |
5169 | // back to waiting for the Halt's stopped event. That's what this |
5170 | // while loop does. |
5171 | |
5172 | bool back_to_top = true; |
5173 | uint32_t try_halt_again = 0; |
5174 | bool do_halt = true; |
5175 | const uint32_t num_retries = 5; |
5176 | while (try_halt_again < num_retries) { |
5177 | Status halt_error; |
5178 | if (do_halt) { |
5179 | LLDB_LOGF(log, "Process::RunThreadPlan(): Running Halt.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Running Halt." ); } while (0); |
5180 | const bool clear_thread_plans = false; |
5181 | const bool use_run_lock = false; |
5182 | Halt(clear_thread_plans, use_run_lock); |
5183 | } |
5184 | if (halt_error.Success()) { |
5185 | if (log) |
5186 | log->PutCString("Process::RunThreadPlan(): Halt succeeded."); |
5187 | |
5188 | got_event = |
5189 | listener_sp->GetEvent(event_sp, GetUtilityExpressionTimeout()); |
5190 | |
5191 | if (got_event) { |
5192 | stop_state = |
5193 | Process::ProcessEventData::GetStateFromEvent(event_sp.get()); |
5194 | if (log) { |
5195 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Stopped with event: %s" , StateAsCString(stop_state)); } while (0) |
5196 | "Process::RunThreadPlan(): Stopped with event: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Stopped with event: %s" , StateAsCString(stop_state)); } while (0) |
5197 | StateAsCString(stop_state))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): Stopped with event: %s" , StateAsCString(stop_state)); } while (0); |
5198 | if (stop_state == lldb::eStateStopped && |
5199 | Process::ProcessEventData::GetInterruptedFromEvent( |
5200 | event_sp.get())) |
5201 | log->PutCString(" Event was the Halt interruption event."); |
5202 | } |
5203 | |
5204 | if (stop_state == lldb::eStateStopped) { |
5205 | if (Process::ProcessEventData::GetRestartedFromEvent( |
5206 | event_sp.get())) { |
5207 | if (log) |
5208 | log->PutCString("Process::RunThreadPlan(): Went to halt " |
5209 | "but got a restarted event, there must be " |
5210 | "an un-restarted stopped event so try " |
5211 | "again... " |
5212 | "Exiting wait loop."); |
5213 | try_halt_again++; |
5214 | do_halt = false; |
5215 | continue; |
5216 | } |
5217 | |
5218 | // Between the time we initiated the Halt and the time we |
5219 | // delivered it, the process could have already finished its |
5220 | // job. Check that here: |
5221 | const bool handle_interrupts = false; |
5222 | if (auto result = HandleStoppedEvent( |
5223 | expr_thread_id, thread_plan_sp, thread_plan_restorer, |
5224 | event_sp, event_to_broadcast_sp, options, |
5225 | handle_interrupts)) { |
5226 | return_value = *result; |
5227 | back_to_top = false; |
5228 | break; |
5229 | } |
5230 | |
5231 | if (!options.GetTryAllThreads()) { |
5232 | if (log) |
5233 | log->PutCString("Process::RunThreadPlan(): try_all_threads " |
5234 | "was false, we stopped so now we're " |
5235 | "quitting."); |
5236 | return_value = eExpressionInterrupted; |
5237 | back_to_top = false; |
5238 | break; |
5239 | } |
5240 | |
5241 | if (before_first_timeout) { |
5242 | // Set all the other threads to run, and return to the top of |
5243 | // the loop, which will continue; |
5244 | before_first_timeout = false; |
5245 | thread_plan_sp->SetStopOthers(false); |
5246 | if (log) |
5247 | log->PutCString( |
5248 | "Process::RunThreadPlan(): about to resume."); |
5249 | |
5250 | back_to_top = true; |
5251 | break; |
5252 | } else { |
5253 | // Running all threads failed, so return Interrupted. |
5254 | if (log) |
5255 | log->PutCString("Process::RunThreadPlan(): running all " |
5256 | "threads timed out."); |
5257 | return_value = eExpressionInterrupted; |
5258 | back_to_top = false; |
5259 | break; |
5260 | } |
5261 | } |
5262 | } else { |
5263 | if (log) |
5264 | log->PutCString("Process::RunThreadPlan(): halt said it " |
5265 | "succeeded, but I got no event. " |
5266 | "I'm getting out of here passing Interrupted."); |
5267 | return_value = eExpressionInterrupted; |
5268 | back_to_top = false; |
5269 | break; |
5270 | } |
5271 | } else { |
5272 | try_halt_again++; |
5273 | continue; |
5274 | } |
5275 | } |
5276 | |
5277 | if (!back_to_top || try_halt_again > num_retries) |
5278 | break; |
5279 | else |
5280 | continue; |
5281 | } |
5282 | } // END WAIT LOOP |
5283 | |
5284 | // If we had to start up a temporary private state thread to run this |
5285 | // thread plan, shut it down now. |
5286 | if (backup_private_state_thread.IsJoinable()) { |
5287 | StopPrivateStateThread(); |
5288 | Status error; |
5289 | m_private_state_thread = backup_private_state_thread; |
5290 | if (stopper_base_plan_sp) { |
5291 | thread->DiscardThreadPlansUpToPlan(stopper_base_plan_sp); |
5292 | } |
5293 | if (old_state != eStateInvalid) |
5294 | m_public_state.SetValueNoLock(old_state); |
5295 | } |
5296 | |
5297 | // If our thread went away on us, we need to get out of here without |
5298 | // doing any more work. We don't have to clean up the thread plan, that |
5299 | // will have happened when the Thread was destroyed. |
5300 | if (return_value == eExpressionThreadVanished) { |
5301 | return return_value; |
5302 | } |
5303 | |
5304 | if (return_value != eExpressionCompleted && log) { |
5305 | // Print a backtrace into the log so we can figure out where we are: |
5306 | StreamString s; |
5307 | s.PutCString("Thread state after unsuccessful completion: \n"); |
5308 | thread->GetStackFrameStatus(s, 0, UINT32_MAX(4294967295U), true, UINT32_MAX(4294967295U)); |
5309 | log->PutString(s.GetString()); |
5310 | } |
5311 | // Restore the thread state if we are going to discard the plan execution. |
5312 | // There are three cases where this could happen: 1) The execution |
5313 | // successfully completed 2) We hit a breakpoint, and ignore_breakpoints |
5314 | // was true 3) We got some other error, and discard_on_error was true |
5315 | bool should_unwind = (return_value == eExpressionInterrupted && |
5316 | options.DoesUnwindOnError()) || |
5317 | (return_value == eExpressionHitBreakpoint && |
5318 | options.DoesIgnoreBreakpoints()); |
5319 | |
5320 | if (return_value == eExpressionCompleted || should_unwind) { |
5321 | thread_plan_sp->RestoreThreadState(); |
5322 | } |
5323 | |
5324 | // Now do some processing on the results of the run: |
5325 | if (return_value == eExpressionInterrupted || |
5326 | return_value == eExpressionHitBreakpoint) { |
5327 | if (log) { |
5328 | StreamString s; |
5329 | if (event_sp) |
5330 | event_sp->Dump(&s); |
5331 | else { |
5332 | log->PutCString("Process::RunThreadPlan(): Stop event that " |
5333 | "interrupted us is NULL."); |
5334 | } |
5335 | |
5336 | StreamString ts; |
5337 | |
5338 | const char *event_explanation = nullptr; |
5339 | |
5340 | do { |
5341 | if (!event_sp) { |
5342 | event_explanation = "<no event>"; |
5343 | break; |
5344 | } else if (event_sp->GetType() == eBroadcastBitInterrupt) { |
5345 | event_explanation = "<user interrupt>"; |
5346 | break; |
5347 | } else { |
5348 | const Process::ProcessEventData *event_data = |
5349 | Process::ProcessEventData::GetEventDataFromEvent( |
5350 | event_sp.get()); |
5351 | |
5352 | if (!event_data) { |
5353 | event_explanation = "<no event data>"; |
5354 | break; |
5355 | } |
5356 | |
5357 | Process *process = event_data->GetProcessSP().get(); |
5358 | |
5359 | if (!process) { |
5360 | event_explanation = "<no process>"; |
5361 | break; |
5362 | } |
5363 | |
5364 | ThreadList &thread_list = process->GetThreadList(); |
5365 | |
5366 | uint32_t num_threads = thread_list.GetSize(); |
5367 | uint32_t thread_index; |
5368 | |
5369 | ts.Printf("<%u threads> ", num_threads); |
5370 | |
5371 | for (thread_index = 0; thread_index < num_threads; ++thread_index) { |
5372 | Thread *thread = thread_list.GetThreadAtIndex(thread_index).get(); |
5373 | |
5374 | if (!thread) { |
5375 | ts.Printf("<?> "); |
5376 | continue; |
5377 | } |
5378 | |
5379 | ts.Printf("<0x%4.4" PRIx64"l" "x" " ", thread->GetID()); |
5380 | RegisterContext *register_context = |
5381 | thread->GetRegisterContext().get(); |
5382 | |
5383 | if (register_context) |
5384 | ts.Printf("[ip 0x%" PRIx64"l" "x" "] ", register_context->GetPC()); |
5385 | else |
5386 | ts.Printf("[ip unknown] "); |
5387 | |
5388 | // Show the private stop info here, the public stop info will be |
5389 | // from the last natural stop. |
5390 | lldb::StopInfoSP stop_info_sp = thread->GetPrivateStopInfo(); |
5391 | if (stop_info_sp) { |
5392 | const char *stop_desc = stop_info_sp->GetDescription(); |
5393 | if (stop_desc) |
5394 | ts.PutCString(stop_desc); |
5395 | } |
5396 | ts.Printf(">"); |
5397 | } |
5398 | |
5399 | event_explanation = ts.GetData(); |
5400 | } |
5401 | } while (false); |
5402 | |
5403 | if (event_explanation) |
5404 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution interrupted: %s %s" , s.GetData(), event_explanation); } while (0) |
5405 | "Process::RunThreadPlan(): execution interrupted: %s %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution interrupted: %s %s" , s.GetData(), event_explanation); } while (0) |
5406 | s.GetData(), event_explanation)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution interrupted: %s %s" , s.GetData(), event_explanation); } while (0); |
5407 | else |
5408 | LLDB_LOGF(log, "Process::RunThreadPlan(): execution interrupted: %s",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution interrupted: %s" , s.GetData()); } while (0) |
5409 | s.GetData())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan(): execution interrupted: %s" , s.GetData()); } while (0); |
5410 | } |
5411 | |
5412 | if (should_unwind) { |
5413 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - " "discarding thread plans up to %p.", static_cast<void *> (thread_plan_sp.get())); } while (0) |
5414 | "Process::RunThreadPlan: ExecutionInterrupted - "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - " "discarding thread plans up to %p.", static_cast<void *> (thread_plan_sp.get())); } while (0) |
5415 | "discarding thread plans up to %p.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - " "discarding thread plans up to %p.", static_cast<void *> (thread_plan_sp.get())); } while (0) |
5416 | static_cast<void *>(thread_plan_sp.get()))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - " "discarding thread plans up to %p.", static_cast<void *> (thread_plan_sp.get())); } while (0); |
5417 | thread->DiscardThreadPlansUpToPlan(thread_plan_sp); |
5418 | } else { |
5419 | LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - for " "plan: %p not discarding.", static_cast<void *>(thread_plan_sp .get())); } while (0) |
5420 | "Process::RunThreadPlan: ExecutionInterrupted - for "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - for " "plan: %p not discarding.", static_cast<void *>(thread_plan_sp .get())); } while (0) |
5421 | "plan: %p not discarding.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - for " "plan: %p not discarding.", static_cast<void *>(thread_plan_sp .get())); } while (0) |
5422 | static_cast<void *>(thread_plan_sp.get()))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Process::RunThreadPlan: ExecutionInterrupted - for " "plan: %p not discarding.", static_cast<void *>(thread_plan_sp .get())); } while (0); |
5423 | } |
5424 | } else if (return_value == eExpressionSetupError) { |
5425 | if (log) |
5426 | log->PutCString("Process::RunThreadPlan(): execution set up error."); |
5427 | |
5428 | if (options.DoesUnwindOnError()) { |
5429 | thread->DiscardThreadPlansUpToPlan(thread_plan_sp); |
5430 | } |
5431 | } else { |
5432 | if (thread->IsThreadPlanDone(thread_plan_sp.get())) { |
5433 | if (log) |
5434 | log->PutCString("Process::RunThreadPlan(): thread plan is done"); |
5435 | return_value = eExpressionCompleted; |
5436 | } else if (thread->WasThreadPlanDiscarded(thread_plan_sp.get())) { |
5437 | if (log) |
5438 | log->PutCString( |
5439 | "Process::RunThreadPlan(): thread plan was discarded"); |
5440 | return_value = eExpressionDiscarded; |
5441 | } else { |
5442 | if (log) |
5443 | log->PutCString( |
5444 | "Process::RunThreadPlan(): thread plan stopped in mid course"); |
5445 | if (options.DoesUnwindOnError() && thread_plan_sp) { |
5446 | if (log) |
5447 | log->PutCString("Process::RunThreadPlan(): discarding thread plan " |
5448 | "'cause unwind_on_error is set."); |
5449 | thread->DiscardThreadPlansUpToPlan(thread_plan_sp); |
5450 | } |
5451 | } |
5452 | } |
5453 | |
5454 | // Thread we ran the function in may have gone away because we ran the |
5455 | // target Check that it's still there, and if it is put it back in the |
5456 | // context. Also restore the frame in the context if it is still present. |
5457 | thread = GetThreadList().FindThreadByIndexID(thread_idx_id, true).get(); |
5458 | if (thread) { |
5459 | exe_ctx.SetFrameSP(thread->GetFrameWithStackID(ctx_frame_id)); |
5460 | } |
5461 | |
5462 | // Also restore the current process'es selected frame & thread, since this |
5463 | // function calling may be done behind the user's back. |
5464 | |
5465 | if (selected_tid != LLDB_INVALID_THREAD_ID0) { |
5466 | if (GetThreadList().SetSelectedThreadByIndexID(selected_tid) && |
5467 | selected_stack_id.IsValid()) { |
5468 | // We were able to restore the selected thread, now restore the frame: |
5469 | std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex()); |
5470 | StackFrameSP old_frame_sp = |
5471 | GetThreadList().GetSelectedThread()->GetFrameWithStackID( |
5472 | selected_stack_id); |
5473 | if (old_frame_sp) |
5474 | GetThreadList().GetSelectedThread()->SetSelectedFrame( |
5475 | old_frame_sp.get()); |
5476 | } |
5477 | } |
5478 | } |
5479 | |
5480 | // If the process exited during the run of the thread plan, notify everyone. |
5481 | |
5482 | if (event_to_broadcast_sp) { |
5483 | if (log) |
5484 | log->PutCString("Process::RunThreadPlan(): rebroadcasting event."); |
5485 | BroadcastEvent(event_to_broadcast_sp); |
5486 | } |
5487 | |
5488 | return return_value; |
5489 | } |
5490 | |
5491 | const char *Process::ExecutionResultAsCString(ExpressionResults result) { |
5492 | const char *result_name = "<unknown>"; |
Value stored to 'result_name' during its initialization is never read | |
5493 | |
5494 | switch (result) { |
5495 | case eExpressionCompleted: |
5496 | result_name = "eExpressionCompleted"; |
5497 | break; |
5498 | case eExpressionDiscarded: |
5499 | result_name = "eExpressionDiscarded"; |
5500 | break; |
5501 | case eExpressionInterrupted: |
5502 | result_name = "eExpressionInterrupted"; |
5503 | break; |
5504 | case eExpressionHitBreakpoint: |
5505 | result_name = "eExpressionHitBreakpoint"; |
5506 | break; |
5507 | case eExpressionSetupError: |
5508 | result_name = "eExpressionSetupError"; |
5509 | break; |
5510 | case eExpressionParseError: |
5511 | result_name = "eExpressionParseError"; |
5512 | break; |
5513 | case eExpressionResultUnavailable: |
5514 | result_name = "eExpressionResultUnavailable"; |
5515 | break; |
5516 | case eExpressionTimedOut: |
5517 | result_name = "eExpressionTimedOut"; |
5518 | break; |
5519 | case eExpressionStoppedForDebug: |
5520 | result_name = "eExpressionStoppedForDebug"; |
5521 | break; |
5522 | case eExpressionThreadVanished: |
5523 | result_name = "eExpressionThreadVanished"; |
5524 | } |
5525 | return result_name; |
5526 | } |
5527 | |
5528 | void Process::GetStatus(Stream &strm) { |
5529 | const StateType state = GetState(); |
5530 | if (StateIsStoppedState(state, false)) { |
5531 | if (state == eStateExited) { |
5532 | int exit_status = GetExitStatus(); |
5533 | const char *exit_description = GetExitDescription(); |
5534 | strm.Printf("Process %" PRIu64"l" "u" " exited with status = %i (0x%8.8x) %s\n", |
5535 | GetID(), exit_status, exit_status, |
5536 | exit_description ? exit_description : ""); |
5537 | } else { |
5538 | if (state == eStateConnected) |
5539 | strm.Printf("Connected to remote target.\n"); |
5540 | else |
5541 | strm.Printf("Process %" PRIu64"l" "u" " %s\n", GetID(), StateAsCString(state)); |
5542 | } |
5543 | } else { |
5544 | strm.Printf("Process %" PRIu64"l" "u" " is running.\n", GetID()); |
5545 | } |
5546 | } |
5547 | |
5548 | size_t Process::GetThreadStatus(Stream &strm, |
5549 | bool only_threads_with_stop_reason, |
5550 | uint32_t start_frame, uint32_t num_frames, |
5551 | uint32_t num_frames_with_source, |
5552 | bool stop_format) { |
5553 | size_t num_thread_infos_dumped = 0; |
5554 | |
5555 | // You can't hold the thread list lock while calling Thread::GetStatus. That |
5556 | // very well might run code (e.g. if we need it to get return values or |
5557 | // arguments.) For that to work the process has to be able to acquire it. |
5558 | // So instead copy the thread ID's, and look them up one by one: |
5559 | |
5560 | uint32_t num_threads; |
5561 | std::vector<lldb::tid_t> thread_id_array; |
5562 | // Scope for thread list locker; |
5563 | { |
5564 | std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex()); |
5565 | ThreadList &curr_thread_list = GetThreadList(); |
5566 | num_threads = curr_thread_list.GetSize(); |
5567 | uint32_t idx; |
5568 | thread_id_array.resize(num_threads); |
5569 | for (idx = 0; idx < num_threads; ++idx) |
5570 | thread_id_array[idx] = curr_thread_list.GetThreadAtIndex(idx)->GetID(); |
5571 | } |