aboutsummaryrefslogtreecommitdiff
path: root/source/Target/Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target/Process.cpp')
-rw-r--r--source/Target/Process.cpp951
1 files changed, 504 insertions, 447 deletions
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index e4fe419660e2..3d1065450e81 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -9,21 +9,25 @@
// C Includes
// C++ Includes
+#include <atomic>
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/Process.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Event.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Event.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -36,17 +40,18 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/JITLoader.h"
#include "lldb/Target/JITLoaderList.h"
+#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/OperatingSystem.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Platform.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/SystemRuntime.h"
@@ -57,7 +62,6 @@
#include "lldb/Target/ThreadPlanBase.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/NameMatches.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
using namespace lldb;
using namespace lldb_private;
@@ -111,17 +115,17 @@ public:
static PropertyDefinition
g_properties[] =
{
- { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, NULL, NULL, "Disable reading and caching of memory in fixed-size units." },
- { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used. "
+ { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, nullptr, nullptr, "Disable reading and caching of memory in fixed-size units." },
+ { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, nullptr, nullptr, "A list containing extra commands understood by the particular process plugin used. "
"For instance, to turn on debugserver logging set this to \"QSetLogging:bitmask=LOG_DEFAULT;\"" },
- { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, breakpoints will be ignored during expression evaluation." },
- { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
- { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
- { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." },
- { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, detach will attempt to keep the process stopped." },
- { "memory-cache-line-size" , OptionValue::eTypeUInt64, false, 512, NULL, NULL, "The memory cache line size" },
- { "optimization-warnings" , OptionValue::eTypeBoolean, false, true, NULL, NULL, "If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected." },
- { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
+ { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, breakpoints will be ignored during expression evaluation." },
+ { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
+ { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, nullptr, nullptr, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
+ { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, stop when a shared library is loaded or unloaded." },
+ { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, detach will attempt to keep the process stopped." },
+ { "memory-cache-line-size" , OptionValue::eTypeUInt64, false, 512, nullptr, nullptr, "The memory cache line size" },
+ { "optimization-warnings" , OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected." },
+ { nullptr , OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr }
};
enum {
@@ -137,10 +141,10 @@ enum {
};
ProcessProperties::ProcessProperties (lldb_private::Process *process) :
- Properties (),
- m_process (process) // Can be NULL for global ProcessProperties
+ Properties(),
+ m_process(process) // Can be nullptr for global ProcessProperties
{
- if (process == NULL)
+ if (process == nullptr)
{
// Global process properties, set them up one time
m_collection_sp.reset (new ProcessOptionValueProperties(ConstString("process")));
@@ -171,14 +175,14 @@ bool
ProcessProperties::GetDisableMemoryCache() const
{
const uint32_t idx = ePropertyDisableMemCache;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
uint64_t
ProcessProperties::GetMemoryCacheLineSize() const
{
const uint32_t idx = ePropertyMemCacheLineSize;
- return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value);
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value);
}
Args
@@ -186,7 +190,7 @@ ProcessProperties::GetExtraStartupCommands () const
{
Args args;
const uint32_t idx = ePropertyExtraStartCommand;
- m_collection_sp->GetPropertyAtIndexAsArgs(NULL, idx, args);
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
return args;
}
@@ -194,84 +198,84 @@ void
ProcessProperties::SetExtraStartupCommands (const Args &args)
{
const uint32_t idx = ePropertyExtraStartCommand;
- m_collection_sp->SetPropertyAtIndexFromArgs(NULL, idx, args);
+ m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
}
FileSpec
ProcessProperties::GetPythonOSPluginPath () const
{
const uint32_t idx = ePropertyPythonOSPluginPath;
- return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
}
void
ProcessProperties::SetPythonOSPluginPath (const FileSpec &file)
{
const uint32_t idx = ePropertyPythonOSPluginPath;
- m_collection_sp->SetPropertyAtIndexAsFileSpec(NULL, idx, file);
+ m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file);
}
bool
ProcessProperties::GetIgnoreBreakpointsInExpressions () const
{
const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetIgnoreBreakpointsInExpressions (bool ignore)
{
const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore);
}
bool
ProcessProperties::GetUnwindOnErrorInExpressions () const
{
const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetUnwindOnErrorInExpressions (bool ignore)
{
const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore);
}
bool
ProcessProperties::GetStopOnSharedLibraryEvents () const
{
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetStopOnSharedLibraryEvents (bool stop)
{
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop);
}
bool
ProcessProperties::GetDetachKeepsStopped () const
{
const uint32_t idx = ePropertyDetachKeepsStopped;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetDetachKeepsStopped (bool stop)
{
const uint32_t idx = ePropertyDetachKeepsStopped;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop);
}
bool
ProcessProperties::GetWarningsOptimization () const
{
const uint32_t idx = ePropertyWarningOptimization;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
@@ -294,7 +298,7 @@ ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
const uint32_t argc = m_arguments.GetArgumentCount();
if (argc > 0)
{
- for (uint32_t i=0; i<argc; i++)
+ for (uint32_t i = 0; i < argc; i++)
{
const char *arg = m_arguments.GetArgumentAtIndex(i);
if (i < 10)
@@ -307,7 +311,7 @@ ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
const uint32_t envc = m_environment.GetArgumentCount();
if (envc > 0)
{
- for (uint32_t i=0; i<envc; i++)
+ for (uint32_t i = 0; i < envc; i++)
{
const char *env = m_environment.GetArgumentAtIndex(i);
if (i < 10)
@@ -419,7 +423,7 @@ ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_ar
const uint32_t argc = m_arguments.GetArgumentCount();
if (argc > 0)
{
- for (uint32_t i=0; i<argc; i++)
+ for (uint32_t i = 0; i < argc; i++)
{
if (i > 0)
s.PutChar (' ');
@@ -545,29 +549,29 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
OptionDefinition
ProcessLaunchCommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
-{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching a process."},
-{ LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
-{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
-{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."},
-{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
-{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."},
+{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process." },
+{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching a process." },
+{ LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
+{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior." },
+{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous." },
+{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries." },
+{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)." },
-{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>."},
-{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>."},
-{ LLDB_OPT_SET_1 , false, "stderr", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stderr for the process to <filename>."},
+{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>." },
+{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>." },
+{ LLDB_OPT_SET_1 , false, "stderr", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stderr for the process to <filename>." },
-{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."},
+{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)." },
-{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
-{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching."},
-{ 0 , false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process." },
+{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching." },
+{ 0 , false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
bool
ProcessInstanceInfoMatch::NameMatches (const char *process_name) const
{
- if (m_name_match_type == eNameMatchIgnore || process_name == NULL)
+ if (m_name_match_type == eNameMatchIgnore || process_name == nullptr)
return true;
const char *match_name = m_match_info.GetName();
if (!match_name)
@@ -654,19 +658,19 @@ ProcessInstanceInfoMatch::Clear()
}
ProcessSP
-Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path)
+Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, ListenerSP listener_sp, const FileSpec *crash_file_path)
{
static uint32_t g_process_unique_id = 0;
ProcessSP process_sp;
- ProcessCreateInstance create_callback = NULL;
+ ProcessCreateInstance create_callback = nullptr;
if (plugin_name)
{
ConstString const_plugin_name(plugin_name);
create_callback = PluginManager::GetProcessCreateCallbackForPluginName (const_plugin_name);
if (create_callback)
{
- process_sp = create_callback(target_sp, listener, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path);
if (process_sp)
{
if (process_sp->CanDebug(target_sp, true))
@@ -680,9 +684,9 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener
}
else
{
- for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
- process_sp = create_callback(target_sp, listener, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path);
if (process_sp)
{
if (process_sp->CanDebug(target_sp, false))
@@ -705,113 +709,107 @@ Process::GetStaticBroadcasterClass ()
return class_name;
}
-Process::Process(lldb::TargetSP target_sp, Listener &listener) :
- Process(target_sp, listener, UnixSignals::Create(HostInfo::GetArchitecture()))
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) :
+ Process(target_sp, listener_sp, UnixSignals::Create(HostInfo::GetArchitecture()))
{
// This constructor just delegates to the full Process constructor,
// defaulting to using the Host's UnixSignals.
}
-Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignalsSP &unix_signals_sp) :
- ProcessProperties (this),
- UserID (LLDB_INVALID_PROCESS_ID),
- Broadcaster (&(target_sp->GetDebugger()), Process::GetStaticBroadcasterClass().AsCString()),
- m_target_sp (target_sp),
- m_public_state (eStateUnloaded),
- m_private_state (eStateUnloaded),
- m_private_state_broadcaster (NULL, "lldb.process.internal_state_broadcaster"),
- m_private_state_control_broadcaster (NULL, "lldb.process.internal_state_control_broadcaster"),
- m_private_state_listener ("lldb.process.internal_state_listener"),
- m_private_state_control_wait(),
- m_mod_id (),
- m_process_unique_id(0),
- m_thread_index_id (0),
- m_thread_id_to_index_id_map (),
- m_exit_status (-1),
- m_exit_string (),
- m_exit_status_mutex(),
- m_thread_mutex (Mutex::eMutexTypeRecursive),
- m_thread_list_real (this),
- m_thread_list (this),
- m_extended_thread_list (this),
- m_extended_thread_stop_id (0),
- m_queue_list (this),
- m_queue_list_stop_id (0),
- m_notifications (),
- m_image_tokens (),
- m_listener (listener),
- m_breakpoint_site_list (),
- m_dynamic_checkers_ap (),
- m_unix_signals_sp (unix_signals_sp),
- m_abi_sp (),
- m_process_input_reader (),
- m_stdio_communication ("process.stdio"),
- m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
- m_stdin_forward (false),
- m_stdout_data (),
- m_stderr_data (),
- m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
- m_profile_data (),
- m_iohandler_sync (0),
- m_memory_cache (*this),
- m_allocated_memory_cache (*this),
- m_should_detach (false),
- m_next_event_action_ap(),
- m_public_run_lock (),
- m_private_run_lock (),
- m_stop_info_override_callback (NULL),
- m_finalizing (false),
- m_finalize_called (false),
- m_clear_thread_plans_on_stop (false),
- m_force_next_event_delivery (false),
- m_last_broadcast_state (eStateInvalid),
- m_destroy_in_process (false),
- m_can_interpret_function_calls(false),
- m_warnings_issued (),
- m_can_jit(eCanJITDontKnow)
-{
- CheckInWithManager ();
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSignalsSP &unix_signals_sp)
+ : ProcessProperties(this),
+ UserID(LLDB_INVALID_PROCESS_ID),
+ Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()), Process::GetStaticBroadcasterClass().AsCString()),
+ m_target_sp(target_sp),
+ m_public_state(eStateUnloaded),
+ m_private_state(eStateUnloaded),
+ m_private_state_broadcaster(nullptr, "lldb.process.internal_state_broadcaster"),
+ m_private_state_control_broadcaster(nullptr, "lldb.process.internal_state_control_broadcaster"),
+ m_private_state_listener_sp(Listener::MakeListener("lldb.process.internal_state_listener")),
+ m_mod_id(),
+ m_process_unique_id(0),
+ m_thread_index_id(0),
+ m_thread_id_to_index_id_map(),
+ m_exit_status(-1),
+ m_exit_string(),
+ m_exit_status_mutex(),
+ m_thread_mutex(),
+ m_thread_list_real(this),
+ m_thread_list(this),
+ m_extended_thread_list(this),
+ m_extended_thread_stop_id(0),
+ m_queue_list(this),
+ m_queue_list_stop_id(0),
+ m_notifications(),
+ m_image_tokens(),
+ m_listener_sp(listener_sp),
+ m_breakpoint_site_list(),
+ m_dynamic_checkers_ap(),
+ m_unix_signals_sp(unix_signals_sp),
+ m_abi_sp(),
+ m_process_input_reader(),
+ m_stdio_communication("process.stdio"),
+ m_stdio_communication_mutex(),
+ m_stdin_forward(false),
+ m_stdout_data(),
+ m_stderr_data(),
+ m_profile_data_comm_mutex(),
+ m_profile_data(),
+ m_iohandler_sync(0),
+ m_memory_cache(*this),
+ m_allocated_memory_cache(*this),
+ m_should_detach(false),
+ m_next_event_action_ap(),
+ m_public_run_lock(),
+ m_private_run_lock(),
+ m_stop_info_override_callback(nullptr),
+ m_finalizing(false),
+ m_finalize_called(false),
+ m_clear_thread_plans_on_stop(false),
+ m_force_next_event_delivery(false),
+ m_last_broadcast_state(eStateInvalid),
+ m_destroy_in_process(false),
+ m_can_interpret_function_calls(false),
+ m_warnings_issued(),
+ m_run_thread_plan_lock(),
+ m_can_jit(eCanJITDontKnow)
+{
+ CheckInWithManager();
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Process::Process()", static_cast<void*>(this));
+ log->Printf("%p Process::Process()", static_cast<void *>(this));
if (!m_unix_signals_sp)
m_unix_signals_sp = std::make_shared<UnixSignals>();
- SetEventName (eBroadcastBitStateChanged, "state-changed");
- SetEventName (eBroadcastBitInterrupt, "interrupt");
- SetEventName (eBroadcastBitSTDOUT, "stdout-available");
- SetEventName (eBroadcastBitSTDERR, "stderr-available");
- SetEventName (eBroadcastBitProfileData, "profile-data-available");
-
- m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" );
- m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
- m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume");
-
- listener.StartListeningForEvents (this,
- eBroadcastBitStateChanged |
- eBroadcastBitInterrupt |
- eBroadcastBitSTDOUT |
- eBroadcastBitSTDERR |
- eBroadcastBitProfileData);
-
- m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
- eBroadcastBitStateChanged |
- eBroadcastBitInterrupt);
-
- m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster,
- eBroadcastInternalStateControlStop |
- eBroadcastInternalStateControlPause |
- eBroadcastInternalStateControlResume);
+ SetEventName(eBroadcastBitStateChanged, "state-changed");
+ SetEventName(eBroadcastBitInterrupt, "interrupt");
+ SetEventName(eBroadcastBitSTDOUT, "stdout-available");
+ SetEventName(eBroadcastBitSTDERR, "stderr-available");
+ SetEventName(eBroadcastBitProfileData, "profile-data-available");
+
+ m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlStop, "control-stop");
+ m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlPause, "control-pause");
+ m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlResume, "control-resume");
+
+ m_listener_sp->StartListeningForEvents(this, eBroadcastBitStateChanged | eBroadcastBitInterrupt |
+ eBroadcastBitSTDOUT | eBroadcastBitSTDERR |
+ eBroadcastBitProfileData);
+
+ m_private_state_listener_sp->StartListeningForEvents(&m_private_state_broadcaster,
+ eBroadcastBitStateChanged | eBroadcastBitInterrupt);
+
+ m_private_state_listener_sp->StartListeningForEvents(
+ &m_private_state_control_broadcaster, eBroadcastInternalStateControlStop | eBroadcastInternalStateControlPause |
+ eBroadcastInternalStateControlResume);
// We need something valid here, even if just the default UnixSignalsSP.
- assert (m_unix_signals_sp && "null m_unix_signals_sp after initialization");
+ assert(m_unix_signals_sp && "null m_unix_signals_sp after initialization");
// Allow the platform to override the default cache line size
- OptionValueSP value_sp =
- m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)->GetValue();
+ OptionValueSP value_sp = m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)->GetValue();
uint32_t platform_cache_line_size = target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize();
- if (! value_sp->OptionWasSet() && platform_cache_line_size != 0)
+ if (!value_sp->OptionWasSet() && platform_cache_line_size != 0)
value_sp->SetUInt64Value(platform_cache_line_size);
}
@@ -831,10 +829,14 @@ Process::~Process()
const ProcessPropertiesSP &
Process::GetGlobalProperties()
{
- static ProcessPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new ProcessProperties (NULL));
- return g_settings_sp;
+ // NOTE: intentional leak so we don't crash if global destructor chain gets
+ // called as other threads still use the result of this function
+ static ProcessPropertiesSP *g_settings_sp_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_settings_sp_ptr = new ProcessPropertiesSP(new ProcessProperties(nullptr));
+ });
+ return *g_settings_sp_ptr;
}
void
@@ -890,14 +892,14 @@ Process::Finalize()
m_language_runtimes.clear();
m_instrumentation_runtimes.clear();
m_next_event_action_ap.reset();
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
// Clear the last natural stop ID since it has a strong
// reference to this process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
//#ifdef LLDB_CONFIGURATION_DEBUG
// StreamFile s(stdout, false);
// EventSP event_sp;
-// while (m_private_state_listener.GetNextEvent(event_sp))
+// while (m_private_state_listener_sp->GetNextEvent(event_sp))
// {
// event_sp->Dump (&s);
// s.EOL();
@@ -906,7 +908,7 @@ Process::Finalize()
// We have to be very careful here as the m_private_state_listener might
// contain events that have ProcessSP values in them which can keep this
// process around forever. These events need to be cleared out.
- m_private_state_listener.Clear();
+ m_private_state_listener_sp->Clear();
m_public_run_lock.TrySetRunning(); // This will do nothing if already locked
m_public_run_lock.SetStopped();
m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
@@ -918,7 +920,7 @@ void
Process::RegisterNotificationCallbacks (const Notifications& callbacks)
{
m_notifications.push_back(callbacks);
- if (callbacks.initialize != NULL)
+ if (callbacks.initialize != nullptr)
callbacks.initialize (callbacks.baton, this);
}
@@ -963,7 +965,7 @@ Process::GetNextEvent (EventSP &event_sp)
{
StateType state = eStateInvalid;
- if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp)
+ if (m_listener_sp->GetNextEventForBroadcaster (this, event_sp) && event_sp)
state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
return state;
@@ -973,7 +975,7 @@ void
Process::SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec)
{
// don't sync (potentially context switch) in case where there is no process IO
- if (! m_process_input_reader)
+ if (!m_process_input_reader)
return;
TimeValue timeout = TimeValue::Now();
@@ -990,7 +992,7 @@ StateType
Process::WaitForProcessToStop (const TimeValue *timeout,
EventSP *event_sp_ptr,
bool wait_always,
- Listener *hijack_listener,
+ ListenerSP hijack_listener_sp,
Stream *stream,
bool use_run_lock)
{
@@ -1019,7 +1021,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
__FUNCTION__);
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
- if (hijack_listener && use_run_lock)
+ if (hijack_listener_sp && use_run_lock)
m_public_run_lock.SetStopped();
return state;
}
@@ -1027,11 +1029,11 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
while (state != eStateInvalid)
{
EventSP event_sp;
- state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener);
+ state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener_sp);
if (event_sp_ptr && event_sp)
*event_sp_ptr = event_sp;
- bool pop_process_io_handler = hijack_listener != NULL;
+ bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr);
Process::HandleProcessStateChangedEvent (event_sp, stream, pop_process_io_handler);
switch (state)
@@ -1042,7 +1044,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
case eStateUnloaded:
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
- if (hijack_listener && use_run_lock)
+ if (hijack_listener_sp && use_run_lock)
m_public_run_lock.SetStopped();
return state;
case eStateStopped:
@@ -1052,7 +1054,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
{
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
- if (hijack_listener && use_run_lock)
+ if (hijack_listener_sp && use_run_lock)
m_public_run_lock.SetStopped();
return state;
}
@@ -1068,7 +1070,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp,
Stream *stream,
bool &pop_process_io_handler)
{
- const bool handle_pop = pop_process_io_handler == true;
+ const bool handle_pop = pop_process_io_handler;
pop_process_io_handler = false;
ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
@@ -1088,15 +1090,12 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp,
case eStateLaunching:
case eStateStepping:
case eStateDetached:
- {
- if (stream)
- stream->Printf ("Process %" PRIu64 " %s\n",
- process_sp->GetID(),
- StateAsCString (event_state));
-
- if (event_state == eStateDetached)
- pop_process_io_handler = true;
- }
+ if (stream)
+ stream->Printf("Process %" PRIu64 " %s\n",
+ process_sp->GetID(),
+ StateAsCString (event_state));
+ if (event_state == eStateDetached)
+ pop_process_io_handler = true;
break;
case eStateConnected:
@@ -1149,7 +1148,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp,
// Lock the thread list so it doesn't change on us, this is the scope for the locker:
{
ThreadList &thread_list = process_sp->GetThreadList();
- Mutex::Locker locker (thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
ThreadSP curr_thread (thread_list.GetSelectedThread());
ThreadSP thread;
@@ -1271,7 +1270,6 @@ Process::WaitForState(const TimeValue *timeout,
const uint32_t num_match_states)
{
EventSP event_sp;
- uint32_t i;
StateType state = GetState();
while (state != eStateInvalid)
{
@@ -1280,9 +1278,9 @@ Process::WaitForState(const TimeValue *timeout,
if (state == eStateDetached || state == eStateExited)
return state;
- state = WaitForStateChangedEvents (timeout, event_sp, NULL);
+ state = WaitForStateChangedEvents(timeout, event_sp, nullptr);
- for (i=0; i<num_match_states; ++i)
+ for (uint32_t i = 0; i < num_match_states; ++i)
{
if (match_states[i] == state)
return state;
@@ -1292,11 +1290,11 @@ Process::WaitForState(const TimeValue *timeout,
}
bool
-Process::HijackProcessEvents (Listener *listener)
+Process::HijackProcessEvents (ListenerSP listener_sp)
{
- if (listener != NULL)
+ if (listener_sp)
{
- return HijackBroadcaster(listener, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
+ return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
}
else
return false;
@@ -1309,7 +1307,7 @@ Process::RestoreProcessEvents ()
}
StateType
-Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener)
+Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, ListenerSP hijack_listener_sp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@@ -1317,15 +1315,15 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp,
log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__,
static_cast<const void*>(timeout));
- Listener *listener = hijack_listener;
- if (listener == NULL)
- listener = &m_listener;
+ ListenerSP listener_sp = hijack_listener_sp;
+ if (!listener_sp)
+ listener_sp = m_listener_sp;
StateType state = eStateInvalid;
- if (listener->WaitForEventForBroadcasterWithType (timeout,
- this,
- eBroadcastBitStateChanged | eBroadcastBitInterrupt,
- event_sp))
+ if (listener_sp->WaitForEventForBroadcasterWithType (timeout,
+ this,
+ eBroadcastBitStateChanged | eBroadcastBitInterrupt,
+ event_sp))
{
if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
@@ -1349,7 +1347,7 @@ Process::PeekAtStateChangedEvents ()
log->Printf ("Process::%s...", __FUNCTION__);
Event *event_ptr;
- event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this,
+ event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType (this,
eBroadcastBitStateChanged);
if (log)
{
@@ -1378,7 +1376,7 @@ Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &ev
static_cast<const void*>(timeout));
StateType state = eStateInvalid;
- if (m_private_state_listener.WaitForEventForBroadcasterWithType (timeout,
+ if (m_private_state_listener_sp->WaitForEventForBroadcasterWithType (timeout,
&m_private_state_broadcaster,
eBroadcastBitStateChanged | eBroadcastBitInterrupt,
event_sp))
@@ -1405,9 +1403,9 @@ Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool
static_cast<const void*>(timeout));
if (control_only)
- return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
+ return m_private_state_listener_sp->WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
else
- return m_private_state_listener.WaitForEvent(timeout, event_sp);
+ return m_private_state_listener_sp->WaitForEvent(timeout, event_sp);
}
bool
@@ -1419,7 +1417,7 @@ Process::IsRunning () const
int
Process::GetExitStatus ()
{
- Mutex::Locker locker (m_exit_status_mutex);
+ std::lock_guard<std::mutex> guard(m_exit_status_mutex);
if (m_public_state.GetValue() == eStateExited)
return m_exit_status;
@@ -1429,18 +1427,18 @@ Process::GetExitStatus ()
const char *
Process::GetExitDescription ()
{
- Mutex::Locker locker (m_exit_status_mutex);
+ std::lock_guard<std::mutex> guard(m_exit_status_mutex);
if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty())
return m_exit_string.c_str();
- return NULL;
+ return nullptr;
}
bool
Process::SetExitStatus (int status, const char *cstr)
{
// Use a mutex to protect setting the exit status.
- Mutex::Locker locker (m_exit_status_mutex);
+ std::lock_guard<std::mutex> guard(m_exit_status_mutex);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
if (log)
@@ -1464,14 +1462,6 @@ Process::SetExitStatus (int status, const char *cstr)
else
m_exit_string.clear();
- // When we exit, we don't need the input reader anymore
- if (m_process_input_reader)
- {
- m_process_input_reader->SetIsDone(true);
- m_process_input_reader->Cancel();
- m_process_input_reader.reset();
- }
-
// Clear the last natural stop ID since it has a strong
// reference to this process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
@@ -1489,12 +1479,6 @@ Process::IsAlive ()
{
switch (m_private_state.GetValue())
{
- case eStateInvalid:
- case eStateUnloaded:
- case eStateDetached:
- case eStateExited:
- return false;
-
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
@@ -1504,6 +1488,8 @@ Process::IsAlive ()
case eStateCrashed:
case eStateSuspended:
return true;
+ default:
+ return false;
}
}
@@ -1512,21 +1498,15 @@ Process::IsAlive ()
// found in the global target list (we want to be completely sure that the
// lldb_private::Process doesn't go away before we can deliver the signal.
bool
-Process::SetProcessExitStatus (void *callback_baton,
- lldb::pid_t pid,
- bool exited,
- int signo, // Zero for no signal
- int exit_status // Exit value of process if signal is zero
-)
+Process::SetProcessExitStatus(lldb::pid_t pid, bool exited,
+ int signo, // Zero for no signal
+ int exit_status // Exit value of process if signal is zero
+ )
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n",
- callback_baton,
- pid,
- exited,
- signo,
- exit_status);
+ log->Printf("Process::SetProcessExitStatus (pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n", pid,
+ exited, signo, exit_status);
if (exited)
{
@@ -1536,7 +1516,7 @@ Process::SetProcessExitStatus (void *callback_baton,
ProcessSP process_sp (target_sp->GetProcessSP());
if (process_sp)
{
- const char *signal_cstr = NULL;
+ const char *signal_cstr = nullptr;
if (signo)
signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
@@ -1557,7 +1537,7 @@ Process::UpdateThreadListIfNeeded ()
const StateType state = GetPrivateState();
if (StateIsStoppedState (state, true))
{
- Mutex::Locker locker (m_thread_list.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
// m_thread_list does have its own mutex, but we need to
// hold onto the mutex between the call to UpdateThreadList(...)
// and the os->UpdateThreadList(...) so it doesn't change on us
@@ -1577,7 +1557,7 @@ Process::UpdateThreadListIfNeeded ()
// Clear any old backing threads where memory threads might have been
// backed by actual threads from the lldb_private::Process subclass
size_t num_old_threads = old_thread_list.GetSize(false);
- for (size_t i=0; i<num_old_threads; ++i)
+ for (size_t i = 0; i < num_old_threads; ++i)
old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
// Turn off dynamic types to ensure we don't run any expressions. Objective C
@@ -1626,7 +1606,7 @@ Process::UpdateThreadListIfNeeded ()
void
Process::UpdateQueueListIfNeeded ()
{
- if (m_system_runtime_ap.get())
+ if (m_system_runtime_ap)
{
if (m_queue_list.GetSize() == 0 || m_queue_list_stop_id != GetLastNaturalStopID())
{
@@ -1691,7 +1671,8 @@ Process::StateChangedIsExternallyHijacked()
{
if (IsHijackedForEvent(eBroadcastBitStateChanged))
{
- if (strcmp(m_hijacking_listeners.back()->GetName(), "lldb.Process.ResumeSynchronous.hijack"))
+ const char *hijacking_name = GetHijackingListenerName();
+ if (hijacking_name && strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack"))
return true;
}
return false;
@@ -1764,13 +1745,13 @@ Process::ResumeSynchronous (Stream *stream)
return error;
}
- ListenerSP listener_sp (new Listener("lldb.Process.ResumeSynchronous.hijack"));
- HijackProcessEvents(listener_sp.get());
+ ListenerSP listener_sp (Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack"));
+ HijackProcessEvents(listener_sp);
Error error = PrivateResume();
if (error.Success())
{
- StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp.get(), stream);
+ StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp, stream);
const bool must_be_alive = false; // eStateExited is ok, so this must be false
if (!StateIsStoppedState(state, must_be_alive))
error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state));
@@ -1800,8 +1781,8 @@ Process::SetPrivateState (StateType new_state)
if (log)
log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
- Mutex::Locker thread_locker(m_thread_list.GetMutex());
- Mutex::Locker locker(m_private_state.GetMutex());
+ std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex());
const StateType old_state = m_private_state.GetValueNoLock ();
state_changed = old_state != new_state;
@@ -1844,7 +1825,7 @@ Process::SetPrivateState (StateType new_state)
}
// Use our target to get a shared pointer to ourselves...
- if (m_finalize_called && PrivateStateThreadIsValid() == false)
+ if (m_finalize_called && !PrivateStateThreadIsValid())
BroadcastEvent (event_sp);
else
m_private_state_broadcaster.BroadcastEvent (event_sp);
@@ -1899,18 +1880,18 @@ CPPLanguageRuntime *
Process::GetCPPLanguageRuntime (bool retry_if_null)
{
LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus, retry_if_null);
- if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
+ if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
return static_cast<CPPLanguageRuntime *> (runtime);
- return NULL;
+ return nullptr;
}
ObjCLanguageRuntime *
Process::GetObjCLanguageRuntime (bool retry_if_null)
{
LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeObjC, retry_if_null);
- if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeObjC)
+ if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeObjC)
return static_cast<ObjCLanguageRuntime *> (runtime);
- return NULL;
+ return nullptr;
}
bool
@@ -2167,7 +2148,7 @@ Error
Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site)
{
Error error;
- assert (bp_site != NULL);
+ assert(bp_site != nullptr);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
const addr_t bp_addr = bp_site->GetLoadAddress();
if (log)
@@ -2196,7 +2177,7 @@ Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site)
{
const uint8_t * const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes();
- if (bp_opcode_bytes == NULL)
+ if (bp_opcode_bytes == nullptr)
{
error.SetErrorString ("BreakpointSite doesn't contain a valid breakpoint trap opcode.");
return error;
@@ -2244,7 +2225,7 @@ Error
Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site)
{
Error error;
- assert (bp_site != NULL);
+ assert(bp_site != nullptr);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
addr_t bp_addr = bp_site->GetLoadAddress();
lldb::user_id_t breakID = bp_site->GetID();
@@ -2388,7 +2369,7 @@ Process::ReadCStringFromMemory (addr_t addr, std::string &out_str, Error &error)
char buf[256];
out_str.clear();
addr_t curr_addr = addr;
- while (1)
+ while (true)
{
size_t length = ReadCStringFromMemory (curr_addr, buf, sizeof(buf), error);
if (length == 0)
@@ -2436,7 +2417,7 @@ Process::ReadStringFromMemory (addr_t addr, char *dst, size_t max_bytes, Error &
// Search for a null terminator of correct size and alignment in bytes_read
size_t aligned_start = total_bytes_read - total_bytes_read % type_width;
for (size_t i = aligned_start; i + type_width <= total_bytes_read + bytes_read; i += type_width)
- if (::strncmp(&dst[i], terminator, type_width) == 0)
+ if (::memcmp(&dst[i], terminator, type_width) == 0)
{
error.Clear();
return i;
@@ -2499,7 +2480,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Erro
}
else
{
- if (dst == NULL)
+ if (dst == nullptr)
result_error.SetErrorString("invalid arguments");
else
result_error.Clear();
@@ -2510,7 +2491,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Erro
size_t
Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &error)
{
- if (buf == NULL || size == 0)
+ if (buf == nullptr || size == 0)
return 0;
size_t bytes_read = 0;
@@ -2536,7 +2517,8 @@ Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &err
}
uint64_t
-Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value, Error &error)
+Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value,
+ Error &error)
{
Scalar scalar;
if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar, error))
@@ -2544,6 +2526,15 @@ Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byt
return fail_value;
}
+int64_t
+Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, int64_t fail_value, Error &error)
+{
+ Scalar scalar;
+ if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, true, scalar, error))
+ return scalar.SLongLong(fail_value);
+ return fail_value;
+}
+
addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error)
{
@@ -2594,7 +2585,7 @@ Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
m_memory_cache.Flush (addr, size);
#endif
- if (buf == NULL || size == 0)
+ if (buf == nullptr || size == 0)
return 0;
m_mod_id.BumpMemoryID();
@@ -2905,7 +2896,7 @@ Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp)
StateType state;
// Now wait for the process to launch and return control to us, and then
// call DidLaunch:
- while (1)
+ while (true)
{
event_sp.reset();
state = WaitForStateChangedEventsPrivate (timeout, event_sp);
@@ -2928,7 +2919,7 @@ Process::LoadOperatingSystemPlugin(bool flush)
{
if (flush)
m_thread_list.Clear();
- m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
+ m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
if (flush)
Flush();
}
@@ -2943,7 +2934,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
m_system_runtime_ap.reset();
m_os_ap.reset();
m_process_input_reader.reset();
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
Module *exe_module = GetTarget().GetExecutableModulePointer();
if (exe_module)
@@ -2988,7 +2979,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
{
SetID (LLDB_INVALID_PROCESS_ID);
const char *error_string = error.AsCString();
- if (error_string == NULL)
+ if (error_string == nullptr)
error_string = "launch failed";
SetExitStatus (-1, error_string);
}
@@ -3001,7 +2992,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
timeout_time.OffsetWithSeconds(10);
StateType state = WaitForProcessStopPrivate(&timeout_time, event_sp);
- if (state == eStateInvalid || event_sp.get() == NULL)
+ if (state == eStateInvalid || !event_sp)
{
// We were able to launch the process, but we failed to
// catch the initial stop.
@@ -3066,8 +3057,8 @@ Process::LoadCore ()
Error error = DoLoadCore();
if (error.Success())
{
- Listener listener ("lldb.process.load_core_listener");
- HijackProcessEvents(&listener);
+ ListenerSP listener_sp (Listener::MakeListener("lldb.process.load_core_listener"));
+ HijackProcessEvents(listener_sp);
if (PrivateStateThreadIsValid ())
ResumePrivateStateThread ();
@@ -3084,7 +3075,7 @@ Process::LoadCore ()
if (system_runtime)
system_runtime->DidAttach();
- m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
+ m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
// We successfully loaded a core file, now pretend we stopped so we can
// show all of the threads in the core file and explore the crashed
// state.
@@ -3092,7 +3083,7 @@ Process::LoadCore ()
// Wait indefinitely for a stopped event since we just posted one above...
lldb::EventSP event_sp;
- listener.WaitForEvent (NULL, event_sp);
+ listener_sp->WaitForEvent (nullptr, event_sp);
StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
if (!StateIsStoppedState (state, false))
@@ -3110,8 +3101,8 @@ Process::LoadCore ()
DynamicLoader *
Process::GetDynamicLoader ()
{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
+ if (!m_dyld_ap)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
return m_dyld_ap.get();
}
@@ -3135,8 +3126,8 @@ Process::GetJITLoaders ()
SystemRuntime *
Process::GetSystemRuntime ()
{
- if (m_system_runtime_ap.get() == NULL)
- m_system_runtime_ap.reset (SystemRuntime::FindPlugin(this));
+ if (!m_system_runtime_ap)
+ m_system_runtime_ap.reset(SystemRuntime::FindPlugin(this));
return m_system_runtime_ap.get();
}
@@ -3169,31 +3160,29 @@ Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp)
case eStateStopped:
case eStateCrashed:
+ // During attach, prior to sending the eStateStopped event,
+ // lldb_private::Process subclasses must set the new process ID.
+ assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
+ // We don't want these events to be reported, so go set the ShouldReportStop here:
+ m_process->GetThreadList().SetShouldReportStop (eVoteNo);
+
+ if (m_exec_count > 0)
{
- // During attach, prior to sending the eStateStopped event,
- // lldb_private::Process subclasses must set the new process ID.
- assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
- // We don't want these events to be reported, so go set the ShouldReportStop here:
- m_process->GetThreadList().SetShouldReportStop (eVoteNo);
-
- if (m_exec_count > 0)
- {
- --m_exec_count;
+ --m_exec_count;
- if (log)
- log->Printf ("Process::AttachCompletionHandler::%s state %s: reduced remaining exec count to %" PRIu32 ", requesting resume", __FUNCTION__, StateAsCString(state), m_exec_count);
+ if (log)
+ log->Printf ("Process::AttachCompletionHandler::%s state %s: reduced remaining exec count to %" PRIu32 ", requesting resume", __FUNCTION__, StateAsCString(state), m_exec_count);
- RequestResume();
- return eEventActionRetry;
- }
- else
- {
- if (log)
- log->Printf ("Process::AttachCompletionHandler::%s state %s: no more execs expected to start, continuing with attach", __FUNCTION__, StateAsCString(state));
+ RequestResume();
+ return eEventActionRetry;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Process::AttachCompletionHandler::%s state %s: no more execs expected to start, continuing with attach", __FUNCTION__, StateAsCString(state));
- m_process->CompleteAttach ();
- return eEventActionSuccess;
- }
+ m_process->CompleteAttach ();
+ return eEventActionSuccess;
}
break;
@@ -3219,11 +3208,11 @@ Process::AttachCompletionHandler::GetExitString ()
return m_exit_string.c_str();
}
-Listener &
+ListenerSP
ProcessAttachInfo::GetListenerForProcess (Debugger &debugger)
{
if (m_listener_sp)
- return *m_listener_sp;
+ return m_listener_sp;
else
return debugger.GetListener();
}
@@ -3237,7 +3226,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
m_jit_loaders_ap.reset();
m_system_runtime_ap.reset();
m_os_ap.reset();
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
lldb::pid_t attach_pid = attach_info.GetProcessID();
Error error;
@@ -3273,7 +3262,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
if (GetID() != LLDB_INVALID_PROCESS_ID)
{
SetID (LLDB_INVALID_PROCESS_ID);
- if (error.AsCString() == NULL)
+ if (error.AsCString() == nullptr)
error.SetErrorString("attach failed");
SetExitStatus(-1, error.AsCString());
@@ -3358,7 +3347,6 @@ Process::Attach (ProcessAttachInfo &attach_info)
if (error.Success())
{
-
SetNextEventAction(new Process::AttachCompletionHandler(this, attach_info.GetResumeCount()));
StartPrivateStateThread();
}
@@ -3368,7 +3356,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
SetID (LLDB_INVALID_PROCESS_ID);
const char *error_string = error.AsCString();
- if (error_string == NULL)
+ if (error_string == nullptr)
error_string = "attach failed";
SetExitStatus(-1, error_string);
@@ -3381,7 +3369,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
void
Process::CompleteAttach ()
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TARGET));
if (log)
log->Printf ("Process::%s()", __FUNCTION__);
@@ -3405,11 +3393,11 @@ Process::CompleteAttach ()
// We just attached. If we have a platform, ask it for the process architecture, and if it isn't
// the same as the one we've already set, switch architectures.
PlatformSP platform_sp (GetTarget().GetPlatform ());
- assert (platform_sp.get());
+ assert(platform_sp);
if (platform_sp)
{
const ArchSpec &target_arch = GetTarget().GetArchitecture();
- if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch, false, NULL))
+ if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr))
{
ArchSpec platform_arch;
platform_sp = platform_sp->GetPlatformForArchitecture (target_arch, &platform_arch);
@@ -3424,7 +3412,7 @@ Process::CompleteAttach ()
else if (!process_arch.IsValid())
{
ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo (GetID(), process_info);
+ GetProcessInfo(process_info);
const ArchSpec &process_arch = process_info.GetArchitecture();
if (process_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(process_arch))
{
@@ -3467,10 +3455,10 @@ Process::CompleteAttach ()
}
}
- m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
+ m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
// Figure out which one is the executable, and set that in our target:
const ModuleList &target_modules = GetTarget().GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
size_t num_modules = target_modules.GetSize();
ModuleSP new_executable_module_sp;
@@ -3514,7 +3502,7 @@ Process::ConnectRemote (Stream *strm, const char *remote_url)
if (GetID() != LLDB_INVALID_PROCESS_ID)
{
EventSP event_sp;
- StateType state = WaitForProcessStopPrivate(NULL, event_sp);
+ StateType state = WaitForProcessStopPrivate(nullptr, event_sp);
if (state == eStateStopped || state == eStateCrashed)
{
@@ -3525,7 +3513,6 @@ Process::ConnectRemote (Stream *strm, const char *remote_url)
// This delays passing the stopped event to listeners till
// CompleteAttach gets a chance to complete...
HandlePrivateEvent (event_sp);
-
}
}
@@ -3607,8 +3594,8 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock)
// own.
m_clear_thread_plans_on_stop |= clear_thread_plans;
- Listener halt_listener ("lldb.process.halt_listener");
- HijackProcessEvents(&halt_listener);
+ ListenerSP halt_listener_sp (Listener::MakeListener("lldb.process.halt_listener"));
+ HijackProcessEvents(halt_listener_sp);
EventSP event_sp;
@@ -3628,7 +3615,7 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock)
TimeValue timeout_time;
timeout_time = TimeValue::Now();
timeout_time.OffsetWithSeconds(10);
- StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, &halt_listener,
+ StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, halt_listener_sp,
nullptr, use_run_lock);
RestoreProcessEvents();
@@ -3653,8 +3640,8 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
if (log)
log->Printf("Process::%s() About to stop.", __FUNCTION__);
- ListenerSP listener_sp (new Listener("lldb.Process.StopForDestroyOrDetach.hijack"));
- HijackProcessEvents(listener_sp.get());
+ ListenerSP listener_sp (Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack"));
+ HijackProcessEvents(listener_sp);
SendAsyncInterrupt();
@@ -3662,7 +3649,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
TimeValue timeout (TimeValue::Now());
timeout.OffsetWithSeconds(10);
- StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp.get());
+ StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp);
RestoreProcessEvents();
@@ -3688,7 +3675,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
StateType private_state = m_private_state.GetValue();
if (private_state != eStateStopped)
{
- return error;
+ return Error("Attempt to stop the target in order to detach timed out. State = %s", StateAsCString(GetState()));
}
}
}
@@ -3888,7 +3875,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
m_stdio_communication.StopReadThread();
m_stdin_forward = false;
- // fall-through
+ LLVM_FALLTHROUGH;
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
@@ -3945,7 +3932,6 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
case eStateStopped:
case eStateCrashed:
case eStateSuspended:
- {
// We've stopped. First see if we're going to restart the target.
// If we are going to stop, then we always broadcast the event.
// If we aren't going to stop, let the thread plans decide if we're going to report this event.
@@ -3974,7 +3960,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
// So in that case just report the event.
if (!was_restarted)
- should_resume = m_thread_list.ShouldStop (event_ptr) == false;
+ should_resume = !m_thread_list.ShouldStop(event_ptr);
if (was_restarted || should_resume || m_resume_requested)
{
@@ -4011,8 +3997,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
SynchronouslyNotifyStateChanged (state);
}
}
- }
- break;
+ break;
}
// Forcing the next event delivery is a one shot deal. So reset it here.
@@ -4069,8 +4054,8 @@ Process::StartPrivateStateThread (bool is_secondary_thread)
}
// Create the private state thread, and start it running.
- PrivateStateThreadArgs args = {this, is_secondary_thread};
- m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) &args, NULL, 8 * 1024 * 1024);
+ PrivateStateThreadArgs *args_ptr = new PrivateStateThreadArgs(this, is_secondary_thread);
+ m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) args_ptr, nullptr, 8 * 1024 * 1024);
if (m_private_state_thread.IsJoinable())
{
ResumePrivateStateThread();
@@ -4095,7 +4080,7 @@ Process::ResumePrivateStateThread ()
void
Process::StopPrivateStateThread ()
{
- if (PrivateStateThreadIsValid ())
+ if (m_private_state_thread.IsJoinable ())
ControlPrivateStateThread (eBroadcastInternalStateControlStop);
else
{
@@ -4117,47 +4102,52 @@ Process::ControlPrivateStateThread (uint32_t signal)
if (log)
log->Printf ("Process::%s (signal = %d)", __FUNCTION__, signal);
- // Signal the private state thread. First we should copy this is case the
- // thread starts exiting since the private state thread will NULL this out
- // when it exits
- HostThread private_state_thread(m_private_state_thread);
- if (private_state_thread.IsJoinable())
+ // Signal the private state thread
+ if (m_private_state_thread.IsJoinable())
{
- TimeValue timeout_time;
- bool timed_out;
-
- m_private_state_control_broadcaster.BroadcastEvent (signal, NULL);
-
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(2);
+ // Broadcast the event.
+ // It is important to do this outside of the if below, because
+ // it's possible that the thread state is invalid but that the
+ // thread is waiting on a control event instead of simply being
+ // on its way out (this should not happen, but it apparently can).
if (log)
log->Printf ("Sending control event of type: %d.", signal);
- m_private_state_control_wait.WaitForValueEqualTo (true, &timeout_time, &timed_out);
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
+ std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt());
+ m_private_state_control_broadcaster.BroadcastEvent(signal, event_receipt_sp);
- if (signal == eBroadcastInternalStateControlStop)
+ // Wait for the event receipt or for the private state thread to exit
+ bool receipt_received = false;
+ if (PrivateStateThreadIsValid())
{
- if (timed_out)
- {
- Error error = private_state_thread.Cancel();
- if (log)
- log->Printf ("Timed out responding to the control event, cancel got error: \"%s\".", error.AsCString());
- }
- else
+ while (!receipt_received)
{
- if (log)
- log->Printf ("The control event killed the private state thread without having to cancel.");
+ bool timed_out = false;
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds(2);
+ // Check for a receipt for 2 seconds and then check if the private state
+ // thread is still around.
+ receipt_received = event_receipt_sp->WaitForEventReceived (&timeout_time, &timed_out);
+ if (!receipt_received)
+ {
+ // Check if the private state thread is still around. If it isn't then we are done waiting
+ if (!PrivateStateThreadIsValid())
+ break; // Private state thread exited or is exiting, we are done
+ }
}
+ }
+ if (signal == eBroadcastInternalStateControlStop)
+ {
thread_result_t result = NULL;
- private_state_thread.Join(&result);
+ m_private_state_thread.Join(&result);
m_private_state_thread.Reset();
}
}
else
{
if (log)
- log->Printf ("Private state thread already dead, no need to signal it to stop.");
+ log->Printf("Private state thread already dead, no need to signal it to stop.");
}
}
@@ -4165,9 +4155,9 @@ void
Process::SendAsyncInterrupt ()
{
if (PrivateStateThreadIsValid())
- m_private_state_broadcaster.BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
+ m_private_state_broadcaster.BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr);
else
- BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
+ BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr);
}
void
@@ -4179,7 +4169,7 @@ Process::HandlePrivateEvent (EventSP &event_sp)
const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
// First check to see if anybody wants a shot at this event:
- if (m_next_event_action_ap.get() != NULL)
+ if (m_next_event_action_ap)
{
NextEventAction::EventActionResult action_result = m_next_event_action_ap->PerformAction(event_sp);
if (log)
@@ -4188,7 +4178,7 @@ Process::HandlePrivateEvent (EventSP &event_sp)
switch (action_result)
{
case NextEventAction::eEventActionSuccess:
- SetNextEventAction(NULL);
+ SetNextEventAction(nullptr);
break;
case NextEventAction::eEventActionRetry:
@@ -4202,10 +4192,10 @@ Process::HandlePrivateEvent (EventSP &event_sp)
{
// FIXME: should cons up an exited event, and discard this one.
SetExitStatus(0, m_next_event_action_ap->GetExitString());
- SetNextEventAction(NULL);
+ SetNextEventAction(nullptr);
return;
}
- SetNextEventAction(NULL);
+ SetNextEventAction(nullptr);
break;
}
}
@@ -4273,7 +4263,7 @@ Process::HandlePrivateEvent (EventSP &event_sp)
// events) and we do need the IO handler to be pushed and popped
// correctly.
- if (is_hijacked || GetTarget().GetDebugger().IsHandlingEvents() == false)
+ if (is_hijacked || !GetTarget().GetDebugger().IsHandlingEvents())
PopProcessIOHandler ();
}
}
@@ -4312,8 +4302,9 @@ Process::HaltPrivate()
thread_result_t
Process::PrivateStateThread (void *arg)
{
- PrivateStateThreadArgs *real_args = static_cast<PrivateStateThreadArgs *> (arg);
- thread_result_t result = real_args->process->RunPrivateStateThread(real_args->is_secondary_thread);
+ PrivateStateThreadArgs real_args = *static_cast<PrivateStateThreadArgs *> (arg);
+ free (arg);
+ thread_result_t result = real_args.process->RunPrivateStateThread(real_args.is_secondary_thread);
return result;
}
@@ -4321,7 +4312,6 @@ thread_result_t
Process::RunPrivateStateThread (bool is_secondary_thread)
{
bool control_only = true;
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
@@ -4333,7 +4323,7 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
while (!exit_now)
{
EventSP event_sp;
- WaitForEventsPrivate (NULL, event_sp, control_only);
+ WaitForEventsPrivate(nullptr, event_sp, control_only);
if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster))
{
if (log)
@@ -4356,7 +4346,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
break;
}
- m_private_state_control_wait.SetValue (true, eBroadcastAlways);
continue;
}
else if (event_sp->GetType() == eBroadcastBitInterrupt)
@@ -4367,7 +4356,7 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt while attaching - forwarding interrupt.",
__FUNCTION__, static_cast<void*>(this),
GetID());
- BroadcastEvent (eBroadcastBitInterrupt, NULL);
+ BroadcastEvent(eBroadcastBitInterrupt, nullptr);
}
else if(StateIsRunningState(m_last_broadcast_state))
{
@@ -4452,8 +4441,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
// try to change it on the way out.
if (!is_secondary_thread)
m_public_run_lock.SetStopped();
- m_private_state_control_wait.SetValue (true, eBroadcastAlways);
- m_private_state_thread.Reset();
return NULL;
}
@@ -4610,7 +4597,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
}
- if (still_should_stop == false)
+ if (!still_should_stop)
still_should_stop = this_thread_wants_to_stop;
}
}
@@ -4660,7 +4647,7 @@ Process::ProcessEventData::GetEventDataFromEvent (const Event *event_ptr)
if (event_data && event_data->GetFlavor() == ProcessEventData::GetFlavorString())
return static_cast <const ProcessEventData *> (event_ptr->GetData());
}
- return NULL;
+ return nullptr;
}
ProcessSP
@@ -4677,7 +4664,7 @@ StateType
Process::ProcessEventData::GetStateFromEvent (const Event *event_ptr)
{
const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
- if (data == NULL)
+ if (data == nullptr)
return eStateInvalid;
else
return data->GetState();
@@ -4687,7 +4674,7 @@ bool
Process::ProcessEventData::GetRestartedFromEvent (const Event *event_ptr)
{
const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
- if (data == NULL)
+ if (data == nullptr)
return false;
else
return data->GetRestarted();
@@ -4697,7 +4684,7 @@ void
Process::ProcessEventData::SetRestartedInEvent (Event *event_ptr, bool new_value)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
data->SetRestarted(new_value);
}
@@ -4705,7 +4692,7 @@ size_t
Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
return data->GetNumRestartedReasons();
else
return 0;
@@ -4715,17 +4702,17 @@ const char *
Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
return data->GetRestartedReasonAtIndex(idx);
else
- return NULL;
+ return nullptr;
}
void
Process::ProcessEventData::AddRestartedReason (Event *event_ptr, const char *reason)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
data->AddRestartedReason(reason);
}
@@ -4733,7 +4720,7 @@ bool
Process::ProcessEventData::GetInterruptedFromEvent (const Event *event_ptr)
{
const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
- if (data == NULL)
+ if (data == nullptr)
return false;
else
return data->GetInterrupted ();
@@ -4743,7 +4730,7 @@ void
Process::ProcessEventData::SetInterruptedInEvent (Event *event_ptr, bool new_value)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
data->SetInterrupted(new_value);
}
@@ -4770,8 +4757,8 @@ Process::CalculateExecutionContext (ExecutionContext &exe_ctx)
{
exe_ctx.SetTargetPtr (&GetTarget());
exe_ctx.SetProcessPtr (this);
- exe_ctx.SetThreadPtr(NULL);
- exe_ctx.SetFramePtr (NULL);
+ exe_ctx.SetThreadPtr(nullptr);
+ exe_ctx.SetFramePtr(nullptr);
}
//uint32_t
@@ -4791,11 +4778,11 @@ Process::CalculateExecutionContext (ExecutionContext &exe_ctx)
//{
// return Host::GetArchSpecForExistingProcess (process_name);
//}
-//
+
void
Process::AppendSTDOUT (const char * s, size_t len)
{
- Mutex::Locker locker (m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
m_stdout_data.append (s, len);
BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (shared_from_this(), GetState()));
}
@@ -4803,7 +4790,7 @@ Process::AppendSTDOUT (const char * s, size_t len)
void
Process::AppendSTDERR (const char * s, size_t len)
{
- Mutex::Locker locker (m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
m_stderr_data.append (s, len);
BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState()));
}
@@ -4811,7 +4798,7 @@ Process::AppendSTDERR (const char * s, size_t len)
void
Process::BroadcastAsyncProfileData(const std::string &one_profile_data)
{
- Mutex::Locker locker (m_profile_data_comm_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex);
m_profile_data.push_back(one_profile_data);
BroadcastEventIfUnique (eBroadcastBitProfileData, new ProcessEventData (shared_from_this(), GetState()));
}
@@ -4819,7 +4806,7 @@ Process::BroadcastAsyncProfileData(const std::string &one_profile_data)
size_t
Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
{
- Mutex::Locker locker(m_profile_data_comm_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex);
if (m_profile_data.empty())
return 0;
@@ -4854,7 +4841,7 @@ Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
size_t
Process::GetSTDOUT (char *buf, size_t buf_size, Error &error)
{
- Mutex::Locker locker(m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
size_t bytes_available = m_stdout_data.size();
if (bytes_available > 0)
{
@@ -4881,7 +4868,7 @@ Process::GetSTDOUT (char *buf, size_t buf_size, Error &error)
size_t
Process::GetSTDERR (char *buf, size_t buf_size, Error &error)
{
- Mutex::Locker locker(m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex);
size_t bytes_available = m_stderr_data.size();
if (bytes_available > 0)
{
@@ -4952,6 +4939,7 @@ public:
// FD_ZERO, FD_SET are not supported on windows
#ifndef _WIN32
const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
+ m_is_running = true;
while (!GetIsDone())
{
fd_set read_fdset;
@@ -4959,7 +4947,8 @@ public:
FD_SET (read_fd, &read_fdset);
FD_SET (pipe_read_fd, &read_fdset);
const int nfds = std::max<int>(read_fd, pipe_read_fd) + 1;
- int num_set_fds = select (nfds, &read_fdset, NULL, NULL, NULL);
+ int num_set_fds = select(nfds, &read_fdset, nullptr, nullptr, nullptr);
+
if (num_set_fds < 0)
{
const int select_errno = errno;
@@ -5003,6 +4992,7 @@ public:
}
}
}
+ m_is_running = false;
#endif
terminal_state.Restore();
}
@@ -5010,9 +5000,24 @@ public:
void
Cancel () override
{
- char ch = 'q'; // Send 'q' for quit
- size_t bytes_written = 0;
- m_pipe.Write(&ch, 1, bytes_written);
+ SetIsDone(true);
+ // Only write to our pipe to cancel if we are in IOHandlerProcessSTDIO::Run().
+ // We can end up with a python command that is being run from the command
+ // interpreter:
+ //
+ // (lldb) step_process_thousands_of_times
+ //
+ // In this case the command interpreter will be in the middle of handling
+ // the command and if the process pushes and pops the IOHandler thousands
+ // of times, we can end up writing to m_pipe without ever consuming the
+ // bytes from the pipe in IOHandlerProcessSTDIO::Run() and end up
+ // deadlocking when the pipe gets fed up and blocks until data is consumed.
+ if (m_is_running)
+ {
+ char ch = 'q'; // Send 'q' for quit
+ size_t bytes_written = 0;
+ m_pipe.Write(&ch, 1, bytes_written);
+ }
}
bool
@@ -5059,6 +5064,7 @@ protected:
File m_read_file; // Read from this file (usually actual STDIN for LLDB
File m_write_file; // Write to this file (usually the master pty for getting io to debuggee)
Pipe m_pipe;
+ std::atomic<bool> m_is_running;
};
void
@@ -5068,7 +5074,7 @@ Process::SetSTDIOFileDescriptor (int fd)
std::unique_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (fd, true));
- if (conn_ap.get())
+ if (conn_ap)
{
m_stdio_communication.SetConnection (conn_ap.release());
if (m_stdio_communication.IsConnected())
@@ -5078,7 +5084,7 @@ Process::SetSTDIOFileDescriptor (int fd)
// Now read thread is set up, set up input reader.
- if (!m_process_input_reader.get())
+ if (!m_process_input_reader)
m_process_input_reader.reset (new IOHandlerProcessSTDIO (this, fd));
}
}
@@ -5180,41 +5186,41 @@ namespace
} // anonymous namespace
ExpressionResults
-Process::RunThreadPlan (ExecutionContext &exe_ctx,
- lldb::ThreadPlanSP &thread_plan_sp,
- const EvaluateExpressionOptions &options,
- Stream &errors)
+Process::RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp,
+ const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager)
{
ExpressionResults return_value = eExpressionSetupError;
+
+ std::lock_guard<std::mutex> run_thread_plan_locker(m_run_thread_plan_lock);
- if (thread_plan_sp.get() == NULL)
+ if (!thread_plan_sp)
{
- errors.Printf("RunThreadPlan called with empty thread plan.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with empty thread plan.");
return eExpressionSetupError;
}
- if (!thread_plan_sp->ValidatePlan(NULL))
+ if (!thread_plan_sp->ValidatePlan(nullptr))
{
- errors.Printf ("RunThreadPlan called with an invalid thread plan.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with an invalid thread plan.");
return eExpressionSetupError;
}
if (exe_ctx.GetProcessPtr() != this)
{
- errors.Printf("RunThreadPlan called on wrong process.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called on wrong process.");
return eExpressionSetupError;
}
Thread *thread = exe_ctx.GetThreadPtr();
- if (thread == NULL)
+ if (thread == nullptr)
{
- errors.Printf("RunThreadPlan called with invalid thread.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with invalid thread.");
return eExpressionSetupError;
}
// We need to change some of the thread plan attributes for the thread plan runner. This will restore them
// when we are done:
-
+
RestorePlanState thread_plan_restorer(thread_plan_sp);
// We rely on the thread plan we are running returning "PlanCompleted" if when it successfully completes.
@@ -5231,7 +5237,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (m_private_state.GetValue() != eStateStopped)
{
- errors.Printf ("RunThreadPlan called while the private state was not stopped.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "RunThreadPlan called while the private state was not stopped.");
return eExpressionSetupError;
}
@@ -5240,11 +5247,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
StackFrameSP selected_frame_sp = thread->GetSelectedFrame();
if (!selected_frame_sp)
{
- thread->SetSelectedFrame(0);
+ thread->SetSelectedFrame(nullptr);
selected_frame_sp = thread->GetSelectedFrame();
if (!selected_frame_sp)
{
- errors.Printf("RunThreadPlan called without a selected frame on thread %d", thread_idx_id);
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "RunThreadPlan called without a selected frame on thread %d", thread_idx_id);
return eExpressionSetupError;
}
}
@@ -5313,7 +5321,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
return eExpressionStoppedForDebug;
}
- Listener listener("lldb.process.listener.run-thread-plan");
+ ListenerSP listener_sp(Listener::MakeListener("lldb.process.listener.run-thread-plan"));
lldb::EventSP event_to_broadcast_sp;
@@ -5324,7 +5332,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
// If the event needs to propagate beyond the hijacker (e.g., the process exits during execution), then the event
// is put into event_to_broadcast_sp for rebroadcasting.
- ProcessEventHijacker run_thread_plan_hijacker (*this, &listener);
+ ProcessEventHijacker run_thread_plan_hijacker (*this, listener_sp);
if (log)
{
@@ -5340,7 +5348,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
lldb::EventSP event_sp;
lldb::StateType stop_state = lldb::eStateInvalid;
- TimeValue* timeout_ptr = NULL;
+ TimeValue* timeout_ptr = nullptr;
TimeValue real_timeout;
bool before_first_timeout = true; // This is set to false the first time that we have to halt the target.
@@ -5386,7 +5394,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
{
if (timeout_usec < option_one_thread_timeout)
{
- errors.Printf("RunThreadPlan called without one thread timeout greater than total timeout");
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "RunThreadPlan called without one thread timeout greater than total timeout");
return eExpressionSetupError;
}
computed_one_thread_timeout = option_one_thread_timeout;
@@ -5414,10 +5424,11 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
// Are there cases where we might want to run the remaining events here, and then try to
// call the function? That's probably being too tricky for our own good.
- Event *other_events = listener.PeekAtNextEvent();
- if (other_events != NULL)
+ Event *other_events = listener_sp->PeekAtNextEvent();
+ if (other_events != nullptr)
{
- errors.Printf("Calling RunThreadPlan with pending events on the queue.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "RunThreadPlan called with pending events on the queue.");
return eExpressionSetupError;
}
@@ -5441,7 +5452,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
TimeValue one_thread_timeout;
TimeValue final_timeout;
- while (1)
+ while (true)
{
// We usually want to resume the process if we get to the top of the loop.
// The only exception is if we get two running events with no intervening
@@ -5459,12 +5470,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (do_resume)
{
num_resumes++;
- Error resume_error = PrivateResume ();
+ Error resume_error = PrivateResume();
if (!resume_error.Success())
{
- errors.Printf("Error resuming inferior the %d time: \"%s\".\n",
- num_resumes,
- resume_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "couldn't resume inferior the %d time: \"%s\".", num_resumes,
+ resume_error.AsCString());
return_value = eExpressionSetupError;
break;
}
@@ -5473,14 +5484,15 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
TimeValue resume_timeout = TimeValue::Now();
resume_timeout.OffsetWithMicroSeconds(500000);
- got_event = listener.WaitForEvent(&resume_timeout, event_sp);
+ got_event = listener_sp->WaitForEvent(&resume_timeout, event_sp);
if (!got_event)
{
if (log)
- log->Printf ("Process::RunThreadPlan(): didn't get any event after resume %d, exiting.",
- num_resumes);
+ log->Printf("Process::RunThreadPlan(): didn't get any event after resume %" PRIu32 ", exiting.",
+ num_resumes);
- errors.Printf("Didn't get any event after resume %d, exiting.", num_resumes);
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "didn't get any event after resume %" PRIu32 ", exiting.", num_resumes);
return_value = eExpressionSetupError;
break;
}
@@ -5513,8 +5525,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
Halt(clear_thread_plans, use_run_lock);
}
- errors.Printf("Didn't get running event after initial resume, got %s instead.",
- StateAsCString(stop_state));
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "didn't get running event after initial resume, got %s instead.",
+ StateAsCString(stop_state));
return_value = eExpressionSetupError;
break;
}
@@ -5544,7 +5557,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
else
{
if (timeout_usec == 0)
- timeout_ptr = NULL;
+ timeout_ptr = nullptr;
else
{
final_timeout = TimeValue::Now();
@@ -5556,7 +5569,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
else
{
if (timeout_usec == 0)
- timeout_ptr = NULL;
+ timeout_ptr = nullptr;
else
{
final_timeout = TimeValue::Now();
@@ -5595,11 +5608,11 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
}
else
#endif
- got_event = listener.WaitForEvent (timeout_ptr, event_sp);
+ got_event = listener_sp->WaitForEvent (timeout_ptr, event_sp);
if (got_event)
{
- if (event_sp.get())
+ if (event_sp)
{
bool keep_going = false;
if (event_sp->GetType() == eBroadcastBitInterrupt)
@@ -5608,9 +5621,10 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
const bool use_run_lock = false;
Halt(clear_thread_plans, use_run_lock);
return_value = eExpressionInterrupted;
- errors.Printf ("Execution halted by user interrupt.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityRemark, "execution halted by user interrupt.");
if (log)
- log->Printf ("Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting.");
+ log->Printf(
+ "Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting.");
break;
}
else
@@ -5713,7 +5727,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (stop_state == eStateExited)
event_to_broadcast_sp = event_sp;
- errors.Printf ("Execution stopped with unexpected state.\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "execution stopped with unexpected state.");
return_value = eExpressionInterrupted;
break;
}
@@ -5795,7 +5810,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
real_timeout = TimeValue::Now();
real_timeout.OffsetWithMicroSeconds(500000);
- got_event = listener.WaitForEvent(&real_timeout, event_sp);
+ got_event = listener_sp->WaitForEvent(&real_timeout, event_sp);
if (got_event)
{
@@ -5943,7 +5958,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
StreamString ts;
- const char *event_explanation = NULL;
+ const char *event_explanation = nullptr;
do
{
@@ -6091,7 +6106,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (GetThreadList().SetSelectedThreadByIndexID (selected_tid) && selected_stack_id.IsValid())
{
// We were able to restore the selected thread, now restore the frame:
- Mutex::Locker lock(GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex());
StackFrameSP old_frame_sp = GetThreadList().GetSelectedThread()->GetFrameWithStackID(selected_stack_id);
if (old_frame_sp)
GetThreadList().GetSelectedThread()->SetSelectedFrame(old_frame_sp.get());
@@ -6196,7 +6211,7 @@ Process::GetThreadStatus (Stream &strm,
std::vector<lldb::tid_t> thread_id_array;
//Scope for thread list locker;
{
- Mutex::Locker locker (GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex());
ThreadList &curr_thread_list = GetThreadList();
num_threads = curr_thread_list.GetSize();
uint32_t idx;
@@ -6213,7 +6228,7 @@ Process::GetThreadStatus (Stream &strm,
if (only_threads_with_stop_reason)
{
StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
- if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid())
+ if (!stop_info_sp || !stop_info_sp->IsValid())
continue;
}
thread_sp->GetStatus (strm,
@@ -6259,7 +6274,7 @@ Process::RunPreResumeActions ()
struct PreResumeCallbackAndBaton action = m_pre_resume_actions.back();
m_pre_resume_actions.pop_back();
bool this_result = action.callback (action.baton);
- if (result == true)
+ if (result)
result = this_result;
}
return result;
@@ -6312,7 +6327,7 @@ Process::DidExec ()
m_instrumentation_runtimes.clear();
m_thread_list.DiscardThreadPlans();
m_memory_cache.Clear(true);
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
DoDidExec();
CompleteAttach ();
// Flush the process (threads and all stack frames) after running CompleteAttach()
@@ -6389,14 +6404,17 @@ Process::ModulesDidLoad (ModuleList &module_list)
for (const auto &pair: language_runtimes)
{
// We must check language_runtime_sp to make sure it is not
- // NULL as we might cache the fact that we didn't have a
+ // nullptr as we might cache the fact that we didn't have a
// language runtime for a language.
LanguageRuntimeSP language_runtime_sp = pair.second;
if (language_runtime_sp)
language_runtime_sp->ModulesDidLoad(module_list);
}
- LoadOperatingSystemPlugin(false);
+ // If we don't have an operating system plug-in, try to load one since
+ // loading shared libraries might cause a new one to try and load
+ if (!m_os_ap)
+ LoadOperatingSystemPlugin(false);
}
void
@@ -6405,10 +6423,10 @@ Process::PrintWarning (uint64_t warning_type, const void *repeat_key, const char
bool print_warning = true;
StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
- if (stream_sp.get() == nullptr)
+ if (!stream_sp)
return;
if (warning_type == eWarningsOptimization
- && GetWarningsOptimization() == false)
+ && !GetWarningsOptimization())
{
return;
}
@@ -6446,16 +6464,28 @@ Process::PrintWarning (uint64_t warning_type, const void *repeat_key, const char
void
Process::PrintWarningOptimization (const SymbolContext &sc)
{
- if (GetWarningsOptimization() == true
- && sc.module_sp.get()
- && sc.module_sp->GetFileSpec().GetFilename().IsEmpty() == false
+ if (GetWarningsOptimization()
+ && sc.module_sp
+ && !sc.module_sp->GetFileSpec().GetFilename().IsEmpty()
&& sc.function
- && sc.function->GetIsOptimized() == true)
+ && sc.function->GetIsOptimized())
{
PrintWarning (Process::Warnings::eWarningsOptimization, sc.module_sp.get(), "%s was compiled with optimization - stepping may behave oddly; variables may not be available.\n", sc.module_sp->GetFileSpec().GetFilename().GetCString());
}
}
+bool
+Process::GetProcessInfo(ProcessInstanceInfo &info)
+{
+ info.Clear();
+
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (! platform_sp)
+ return false;
+
+ return platform_sp->GetProcessInfo(GetID(), info);
+}
+
ThreadCollectionSP
Process::GetHistoryThreads(lldb::addr_t addr)
{
@@ -6463,7 +6493,7 @@ Process::GetHistoryThreads(lldb::addr_t addr)
const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(shared_from_this());
- if (! memory_history.get()) {
+ if (!memory_history) {
return threads;
}
@@ -6521,13 +6551,13 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre
{
Target &target = GetTarget();
DisassemblerSP disassembler_sp;
- InstructionList *insn_list = NULL;
+ InstructionList *insn_list = nullptr;
Address retval = default_stop_addr;
- if (target.GetUseFastStepping() == false)
+ if (!target.GetUseFastStepping())
return retval;
- if (default_stop_addr.IsValid() == false)
+ if (!default_stop_addr.IsValid())
return retval;
ExecutionContext exe_ctx (this);
@@ -6540,10 +6570,10 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre
exe_ctx,
range_bounds,
prefer_file_cache);
- if (disassembler_sp.get())
+ if (disassembler_sp)
insn_list = &disassembler_sp->GetInstructionList();
- if (insn_list == NULL)
+ if (insn_list == nullptr)
{
return retval;
}
@@ -6569,11 +6599,38 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre
}
}
- if (disassembler_sp.get())
+ return retval;
+}
+
+Error
+Process::GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list)
+{
+
+ Error error;
+
+ lldb::addr_t range_base = 0;
+ lldb::addr_t range_end = 0;
+
+ region_list.clear();
+ do
{
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- disassembler_sp->GetInstructionList().Clear();
- }
+ lldb::MemoryRegionInfoSP region_info( new lldb_private::MemoryRegionInfo() );
+ error = GetMemoryRegionInfo (range_end, *region_info);
+ // GetMemoryRegionInfo should only return an error if it is unimplemented.
+ if (error.Fail())
+ {
+ region_list.clear();
+ break;
+ }
+
+ range_base = region_info->GetRange().GetRangeBase();
+ range_end = region_info->GetRange().GetRangeEnd();
+ if( region_info->GetMapped() == MemoryRegionInfo::eYes )
+ {
+ region_list.push_back(region_info);
+ }
+ } while (range_end != LLDB_INVALID_ADDRESS);
+
+ return error;
- return retval;
}