diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 | 
| commit | f3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch) | |
| tree | 48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /source/Target/Process.cpp | |
| parent | 2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff) | |
Notes
Diffstat (limited to 'source/Target/Process.cpp')
| -rw-r--r-- | source/Target/Process.cpp | 951 | 
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;  }  | 
