summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-04-12 05:54:46 +0000
committerGreg Clayton <gclayton@apple.com>2011-04-12 05:54:46 +0000
commit8b82f087a0499319640f5d06498f965fa0214c72 (patch)
tree561c493dbe3e1a176d4c1b4ddd0c0afb396d3bea /lldb/source/Target/Process.cpp
parentf52718899fa93f19403336355bca8117321ee834 (diff)
downloadbcm5719-llvm-8b82f087a0499319640f5d06498f965fa0214c72.tar.gz
bcm5719-llvm-8b82f087a0499319640f5d06498f965fa0214c72.zip
Moved the execution context that was in the Debugger into
the CommandInterpreter where it was always being used. Make sure that Modules can track their object file offsets correctly to allow opening of sub object files (like the "__commpage" on darwin). Modified the Platforms to be able to launch processes. The first part of this move is the platform soon will become the entity that launches your program and when it does, it uses a new ProcessLaunchInfo class which encapsulates all process launching settings. This simplifies the internal APIs needed for launching. I want to slowly phase out process launching from the process classes, so for now we can still launch just as we used to, but eventually the platform is the object that should do the launching. Modified the Host::LaunchProcess in the MacOSX Host.mm to correctly be able to launch processes with all of the new eLaunchFlag settings. Modified any code that was manually launching processes to use the Host::LaunchProcess functions. Fixed an issue where lldb_private::Args had implicitly defined copy constructors that could do the wrong thing. This has now been fixed by adding an appropriate copy constructor and assignment operator. Make sure we don't add empty ModuleSP entries to a module list. Fixed the commpage module creation on MacOSX, but we still need to train the MacOSX dynamic loader to not get rid of it when it doesn't have an entry in the all image infos. Abstracted many more calls from in ProcessGDBRemote down into the GDBRemoteCommunicationClient subclass to make the classes cleaner and more efficient. Fixed the default iOS ARM register context to be correct and also added support for targets that don't support the qThreadStopInfo packet by selecting the current thread (only if needed) and then sending a stop reply packet. Debugserver can now start up with a --unix-socket (-u for short) and can then bind to port zero and send the port it bound to to a listening process on the other end. This allows the GDB remote platform to spawn new GDB server instances (debugserver) to allow platform debugging. llvm-svn: 129351
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r--lldb/source/Target/Process.cpp429
1 files changed, 377 insertions, 52 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 940ff2bd949..c33dd183ec9 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -40,7 +40,7 @@ using namespace lldb;
using namespace lldb_private;
void
-ProcessInfo::Dump (Stream &s, Platform *platform) const
+ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
{
const char *cstr;
if (m_pid != LLDB_INVALID_PROCESS_ID)
@@ -56,59 +56,80 @@ ProcessInfo::Dump (Stream &s, Platform *platform) const
m_executable.Dump(&s);
s.EOL();
}
- const uint32_t argc = m_args.GetSize();
+ const uint32_t argc = m_arguments.GetArgumentCount();
if (argc > 0)
{
for (uint32_t i=0; i<argc; i++)
{
+ const char *arg = m_arguments.GetArgumentAtIndex(i);
if (i < 10)
- s.Printf (" arg[%u] = %s\n", i, m_args.GetStringAtIndex(i));
+ s.Printf (" arg[%u] = %s\n", i, arg);
else
- s.Printf ("arg[%u] = %s\n", i, m_args.GetStringAtIndex(i));
+ s.Printf ("arg[%u] = %s\n", i, arg);
}
}
+
+ const uint32_t envc = m_environment.GetArgumentCount();
+ if (envc > 0)
+ {
+ for (uint32_t i=0; i<envc; i++)
+ {
+ const char *env = m_environment.GetArgumentAtIndex(i);
+ if (i < 10)
+ s.Printf (" env[%u] = %s\n", i, env);
+ else
+ s.Printf ("env[%u] = %s\n", i, env);
+ }
+ }
+
if (m_arch.IsValid())
s.Printf (" arch = %s\n", m_arch.GetTriple().str().c_str());
- if (m_real_uid != UINT32_MAX)
+ if (m_uid != UINT32_MAX)
{
- cstr = platform->GetUserName (m_real_uid);
- s.Printf (" uid = %-5u (%s)\n", m_real_uid, cstr ? cstr : "");
+ cstr = platform->GetUserName (m_uid);
+ s.Printf (" uid = %-5u (%s)\n", m_uid, cstr ? cstr : "");
}
- if (m_real_gid != UINT32_MAX)
+ if (m_gid != UINT32_MAX)
{
- cstr = platform->GetGroupName (m_real_gid);
- s.Printf (" gid = %-5u (%s)\n", m_real_gid, cstr ? cstr : "");
+ cstr = platform->GetGroupName (m_gid);
+ s.Printf (" gid = %-5u (%s)\n", m_gid, cstr ? cstr : "");
}
- if (m_effective_uid != UINT32_MAX)
+ if (m_euid != UINT32_MAX)
{
- cstr = platform->GetUserName (m_effective_uid);
- s.Printf (" euid = %-5u (%s)\n", m_effective_uid, cstr ? cstr : "");
+ cstr = platform->GetUserName (m_euid);
+ s.Printf (" euid = %-5u (%s)\n", m_euid, cstr ? cstr : "");
}
- if (m_effective_gid != UINT32_MAX)
+ if (m_egid != UINT32_MAX)
{
- cstr = platform->GetGroupName (m_effective_gid);
- s.Printf (" egid = %-5u (%s)\n", m_effective_gid, cstr ? cstr : "");
+ cstr = platform->GetGroupName (m_egid);
+ s.Printf (" egid = %-5u (%s)\n", m_egid, cstr ? cstr : "");
}
}
void
-ProcessInfo::DumpTableHeader (Stream &s, Platform *platform, bool verbose)
+ProcessInstanceInfo::DumpTableHeader (Stream &s, Platform *platform, bool show_args, bool verbose)
{
+ const char *label;
+ if (show_args || verbose)
+ label = "ARGUMENTS";
+ else
+ label = "NAME";
+
if (verbose)
{
- s.PutCString ("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME\n");
+ s.Printf ("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE %s\n", label);
s.PutCString ("====== ====== ========== ========== ========== ========== ======================== ============================\n");
}
else
{
- s.PutCString ("PID PARENT USER ARCH NAME\n");
+ s.Printf ("PID PARENT USER ARCH %s\n", label);
s.PutCString ("====== ====== ========== ======= ============================\n");
}
}
void
-ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform, bool verbose) const
+ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_args, bool verbose) const
{
if (m_pid != LLDB_INVALID_PROCESS_ID)
{
@@ -118,49 +139,49 @@ ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform, bool verbose) const
if (verbose)
{
- cstr = platform->GetUserName (m_real_uid);
+ cstr = platform->GetUserName (m_uid);
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
s.Printf ("%-10s ", cstr);
else
- s.Printf ("%-10u ", m_real_uid);
+ s.Printf ("%-10u ", m_uid);
- cstr = platform->GetGroupName (m_real_gid);
+ cstr = platform->GetGroupName (m_gid);
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
s.Printf ("%-10s ", cstr);
else
- s.Printf ("%-10u ", m_real_gid);
+ s.Printf ("%-10u ", m_gid);
- cstr = platform->GetUserName (m_effective_uid);
+ cstr = platform->GetUserName (m_euid);
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
s.Printf ("%-10s ", cstr);
else
- s.Printf ("%-10u ", m_effective_uid);
+ s.Printf ("%-10u ", m_euid);
- cstr = platform->GetGroupName (m_effective_gid);
+ cstr = platform->GetGroupName (m_egid);
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
s.Printf ("%-10s ", cstr);
else
- s.Printf ("%-10u ", m_effective_gid);
+ s.Printf ("%-10u ", m_egid);
s.Printf ("%-24s ", m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "");
}
else
{
s.Printf ("%-10s %.*-7s ",
- platform->GetUserName (m_effective_uid),
+ platform->GetUserName (m_euid),
(int)m_arch.GetTriple().getArchName().size(),
m_arch.GetTriple().getArchName().data());
}
- if (verbose)
+ if (verbose || show_args)
{
- const uint32_t argc = m_args.GetSize();
+ const uint32_t argc = m_arguments.GetArgumentCount();
if (argc > 0)
{
for (uint32_t i=0; i<argc; i++)
{
if (i > 0)
s.PutChar (' ');
- s.PutCString (m_args.GetStringAtIndex(i));
+ s.PutCString (m_arguments.GetArgumentAtIndex(i));
}
}
}
@@ -173,8 +194,263 @@ ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform, bool verbose) const
}
}
+
+void
+ProcessInfo::SetArgumentsFromArgs (const Args& args,
+ bool first_arg_is_executable,
+ bool first_arg_is_executable_and_argument)
+{
+ // Copy all arguments
+ m_arguments = args;
+
+ // Is the first argument the executable?
+ if (first_arg_is_executable)
+ {
+ const char *first_arg = args.GetArgumentAtIndex (0);
+ if (first_arg)
+ {
+ // Yes the first argument is an executable, set it as the executable
+ // in the launch options. Don't resolve the file path as the path
+ // could be a remote platform path
+ const bool resolve = false;
+ m_executable.SetFile(first_arg, resolve);
+
+ // If argument zero is an executable and shouldn't be included
+ // in the arguments, remove it from the front of the arguments
+ if (first_arg_is_executable_and_argument == false)
+ m_arguments.DeleteArgumentAtIndex (0);
+ }
+ }
+}
+
+bool
+ProcessLaunchInfo::FileAction::Open (int fd, const char *path, bool read, bool write)
+{
+ if ((read || write) && fd >= 0 && path && path[0])
+ {
+ m_action = eFileActionOpen;
+ m_fd = fd;
+ if (read && write)
+ m_arg = O_RDWR;
+ else if (read)
+ m_arg = O_RDONLY;
+ else
+ m_arg = O_WRONLY;
+ m_path.assign (path);
+ return true;
+ }
+ else
+ {
+ Clear();
+ }
+ return false;
+}
+
bool
-ProcessInfoMatch::NameMatches (const char *process_name) const
+ProcessLaunchInfo::FileAction::Close (int fd)
+{
+ Clear();
+ if (fd >= 0)
+ {
+ m_action = eFileActionClose;
+ m_fd = fd;
+ }
+ return m_fd >= 0;
+}
+
+
+bool
+ProcessLaunchInfo::FileAction::Duplicate (int fd, int dup_fd)
+{
+ Clear();
+ if (fd >= 0 && dup_fd >= 0)
+ {
+ m_action = eFileActionDuplicate;
+ m_fd = fd;
+ m_arg = dup_fd;
+ }
+ return m_fd >= 0;
+}
+
+
+
+bool
+ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (posix_spawn_file_actions_t *file_actions,
+ const FileAction *info,
+ Log *log,
+ Error& error)
+{
+ if (info == NULL)
+ return false;
+
+ switch (info->m_action)
+ {
+ case eFileActionNone:
+ error.Clear();
+ break;
+
+ case eFileActionClose:
+ if (info->m_fd == -1)
+ error.SetErrorString ("invalid fd for posix_spawn_file_actions_addclose(...)");
+ else
+ {
+ error.SetError (::posix_spawn_file_actions_addclose (file_actions, info->m_fd),
+ eErrorTypePOSIX);
+ if (log && (error.Fail() || log))
+ error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)",
+ file_actions, info->m_fd);
+ }
+ break;
+
+ case eFileActionDuplicate:
+ if (info->m_fd == -1)
+ error.SetErrorString ("invalid fd for posix_spawn_file_actions_adddup2(...)");
+ else if (info->m_arg == -1)
+ error.SetErrorString ("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
+ else
+ {
+ error.SetError (::posix_spawn_file_actions_adddup2 (file_actions, info->m_fd, info->m_arg),
+ eErrorTypePOSIX);
+ if (log && (error.Fail() || log))
+ error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)",
+ file_actions, info->m_fd, info->m_arg);
+ }
+ break;
+
+ case eFileActionOpen:
+ if (info->m_fd == -1)
+ error.SetErrorString ("invalid fd in posix_spawn_file_actions_addopen(...)");
+ else
+ {
+ int oflag = info->m_arg;
+ mode_t mode = 0;
+
+ error.SetError (::posix_spawn_file_actions_addopen (file_actions,
+ info->m_fd,
+ info->m_path.c_str(),
+ oflag,
+ mode),
+ eErrorTypePOSIX);
+ if (error.Fail() || log)
+ error.PutToLog(log,
+ "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)",
+ file_actions, info->m_fd, info->m_path.c_str(), oflag, mode);
+ }
+ break;
+
+ default:
+ error.SetErrorStringWithFormat ("invalid file action: %i", info->m_action);
+ break;
+ }
+ return error.Success();
+}
+
+Error
+ProcessLaunchCommandOptions::SetOptionValue (int option_idx, const char *option_arg)
+{
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 's': // Stop at program entry point
+ launch_info.GetFlags().Set (eLaunchFlagStopAtEntry);
+ break;
+
+ case 'e': // STDERR for read + write
+ {
+ ProcessLaunchInfo::FileAction action;
+ if (action.Open(STDERR_FILENO, option_arg, true, true))
+ launch_info.AppendFileAction (action);
+ }
+ break;
+
+ case 'i': // STDIN for read only
+ {
+ ProcessLaunchInfo::FileAction action;
+ if (action.Open(STDIN_FILENO, option_arg, true, false))
+ launch_info.AppendFileAction (action);
+ }
+ break;
+
+ case 'o': // Open STDOUT for write only
+ {
+ ProcessLaunchInfo::FileAction action;
+ if (action.Open(STDOUT_FILENO, option_arg, false, true))
+ launch_info.AppendFileAction (action);
+ }
+ break;
+
+ case 'p': // Process plug-in name
+ launch_info.SetProcessPluginName (option_arg);
+ break;
+
+ case 'n': // Disable STDIO
+ {
+ ProcessLaunchInfo::FileAction action;
+ if (action.Open(STDERR_FILENO, "/dev/null", true, true))
+ launch_info.AppendFileAction (action);
+ if (action.Open(STDOUT_FILENO, "/dev/null", false, true))
+ launch_info.AppendFileAction (action);
+ if (action.Open(STDIN_FILENO, "/dev/null", true, false))
+ launch_info.AppendFileAction (action);
+ }
+ break;
+
+ case 'w':
+ launch_info.SetWorkingDirectory (option_arg);
+ break;
+
+ case 't': // Open process in new terminal window
+ launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
+ break;
+
+ case 'a':
+ launch_info.GetArchitecture().SetTriple (option_arg,
+ m_interpreter.GetPlatform(true).get());
+ break;
+
+ case 'A':
+ launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
+ break;
+
+ case 'v':
+ launch_info.GetEnvironmentEntries().AppendArgument(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+ break;
+
+ }
+ return error;
+}
+
+OptionDefinition
+ProcessLaunchCommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
+{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', no_argument, NULL, 0, eArgTypeNone, "Disable address space layout randomization when launching a process."},
+{ LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
+{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."},
+{ LLDB_OPT_SET_ALL, false, "arch", 'a', required_argument, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."},
+{ LLDB_OPT_SET_ALL, false, "environment", 'v', required_argument, NULL, 0, eArgTypeNone, "Specify an environment variable name/value stirng (--environement NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
+
+{ LLDB_OPT_SET_1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."},
+{ LLDB_OPT_SET_1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."},
+{ LLDB_OPT_SET_1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."},
+
+{ LLDB_OPT_SET_2 , false, "tty", 't', no_argument, NULL, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."},
+
+{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
+
+{ 0 , false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+
+
+bool
+ProcessInstanceInfoMatch::NameMatches (const char *process_name) const
{
if (m_name_match_type == eNameMatchIgnore || process_name == NULL)
return true;
@@ -186,7 +462,7 @@ ProcessInfoMatch::NameMatches (const char *process_name) const
}
bool
-ProcessInfoMatch::Matches (const ProcessInfo &proc_info) const
+ProcessInstanceInfoMatch::Matches (const ProcessInstanceInfo &proc_info) const
{
if (!NameMatches (proc_info.GetName()))
return false;
@@ -199,12 +475,12 @@ ProcessInfoMatch::Matches (const ProcessInfo &proc_info) const
m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
return false;
- if (m_match_info.RealUserIDIsValid () &&
- m_match_info.GetRealUserID() != proc_info.GetRealUserID())
+ if (m_match_info.UserIDIsValid () &&
+ m_match_info.GetUserID() != proc_info.GetUserID())
return false;
- if (m_match_info.RealGroupIDIsValid () &&
- m_match_info.GetRealGroupID() != proc_info.GetRealGroupID())
+ if (m_match_info.GroupIDIsValid () &&
+ m_match_info.GetGroupID() != proc_info.GetGroupID())
return false;
if (m_match_info.EffectiveUserIDIsValid () &&
@@ -222,7 +498,7 @@ ProcessInfoMatch::Matches (const ProcessInfo &proc_info) const
}
bool
-ProcessInfoMatch::MatchAllProcesses () const
+ProcessInstanceInfoMatch::MatchAllProcesses () const
{
if (m_name_match_type != eNameMatchIgnore)
return false;
@@ -233,10 +509,10 @@ ProcessInfoMatch::MatchAllProcesses () const
if (m_match_info.ParentProcessIDIsValid())
return false;
- if (m_match_info.RealUserIDIsValid ())
+ if (m_match_info.UserIDIsValid ())
return false;
- if (m_match_info.RealGroupIDIsValid ())
+ if (m_match_info.GroupIDIsValid ())
return false;
if (m_match_info.EffectiveUserIDIsValid ())
@@ -256,7 +532,7 @@ ProcessInfoMatch::MatchAllProcesses () const
}
void
-ProcessInfoMatch::Clear()
+ProcessInstanceInfoMatch::Clear()
{
m_match_info.Clear();
m_name_match_type = eNameMatchIgnore;
@@ -1504,6 +1780,46 @@ Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
size_t
+Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len)
+{
+ size_t total_cstr_len = 0;
+ if (dst && dst_max_len)
+ {
+ // NULL out everything just to be safe
+ memset (dst, 0, dst_max_len);
+ Error error;
+ addr_t curr_addr = addr;
+ const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize();
+ size_t bytes_left = dst_max_len - 1;
+ char *curr_dst = dst;
+
+ while (bytes_left > 0)
+ {
+ addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
+ addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+ size_t bytes_read = ReadMemory (curr_addr, curr_dst, bytes_to_read, error);
+
+ if (bytes_read == 0)
+ {
+ dst[total_cstr_len] = '\0';
+ break;
+ }
+ const size_t len = strlen(curr_dst);
+
+ total_cstr_len += len;
+
+ if (len < bytes_to_read)
+ break;
+
+ curr_dst += bytes_read;
+ curr_addr += bytes_read;
+ bytes_left -= bytes_read;
+ }
+ }
+ return total_cstr_len;
+}
+
+size_t
Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &error)
{
if (buf == NULL || size == 0)
@@ -1894,7 +2210,7 @@ Process::Attach (lldb::pid_t attach_pid)
// Find the process and its architecture. Make sure it matches the architecture
// of the current Target, and if not adjust it.
- ProcessInfo process_info;
+ ProcessInstanceInfo process_info;
PlatformSP platform_sp (m_target.GetDebugger().GetPlatformList().GetSelectedPlatform ());
if (platform_sp)
{
@@ -1947,11 +2263,11 @@ Process::Attach (const char *process_name, bool wait_for_launch)
if (!wait_for_launch)
{
- ProcessInfoList process_infos;
+ ProcessInstanceInfoList process_infos;
PlatformSP platform_sp (m_target.GetDebugger().GetPlatformList().GetSelectedPlatform ());
if (platform_sp)
{
- ProcessInfoMatch match_info;
+ ProcessInstanceInfoMatch match_info;
match_info.GetProcessInfo().SetName(process_name);
match_info.SetNameMatchType (eNameMatchEquals);
platform_sp->FindProcesses (match_info, process_infos);
@@ -1965,7 +2281,7 @@ Process::Attach (const char *process_name, bool wait_for_launch)
}
else
{
- ProcessInfo process_info;
+ ProcessInstanceInfo process_info;
if (process_infos.GetInfoAtIndex (0, process_info))
{
const ArchSpec &process_arch = process_info.GetArchitecture();
@@ -2034,7 +2350,7 @@ Process::CompleteAttach ()
for (int i = 0; i < num_modules; i++)
{
ModuleSP module_sp (modules.GetModuleAtIndex(i));
- if (module_sp->IsExecutable())
+ if (module_sp && module_sp->IsExecutable())
{
ModuleSP target_exe_module_sp (m_target.GetExecutableModule());
if (target_exe_module_sp != module_sp)
@@ -2391,8 +2707,12 @@ Process::StartPrivateStateThread ()
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ bool already_running = PrivateStateThreadIsValid ();
if (log)
- log->Printf ("Process::%s ( )", __FUNCTION__);
+ log->Printf ("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread");
+
+ if (already_running)
+ return true;
// Create a thread that watches our internal state and controls which
// events make it to clients (into the DCProcess event queue).
@@ -2417,7 +2737,8 @@ Process::ResumePrivateStateThread ()
void
Process::StopPrivateStateThread ()
{
- ControlPrivateStateThread (eBroadcastInternalStateControlStop);
+ if (PrivateStateThreadIsValid ())
+ ControlPrivateStateThread (eBroadcastInternalStateControlStop);
}
void
@@ -2702,7 +3023,7 @@ Process::ProcessEventData::Dump (Stream *s) const
if (m_process_sp)
s->Printf(" process = %p (pid = %u), ", m_process_sp.get(), m_process_sp->GetID());
- s->Printf("state = %s", StateAsCString(GetState()));;
+ s->Printf("state = %s", StateAsCString(GetState()));
}
const Process::ProcessEventData *
@@ -3005,7 +3326,7 @@ Process::UpdateInstanceName ()
sstr.Printf ("%s", module_sp->GetFileSpec().GetFilename().AsCString());
GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(),
- sstr.GetData());
+ sstr.GetData());
}
}
@@ -3661,7 +3982,11 @@ ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_
UserSettingsController::UpdateStringArrayVariable (op, index_value, m_run_args, value, err);
else if (var_name == EnvVarsVarName())
{
- GetHostEnvironmentIfNeeded ();
+ // This is nice for local debugging, but it is isn't correct for
+ // remote debugging. We need to stop process.env-vars from being
+ // populated with the host environment and add this as a launch option
+ // and get the correct environment from the Target's platform.
+ // GetHostEnvironmentIfNeeded ();
UserSettingsController::UpdateDictionaryVariable (op, index_value, m_env_vars, value, err);
}
else if (var_name == InputPathVarName())
OpenPOWER on IntegriCloud