From: Todd Fiala Date: Mon, 30 Jun 2014 00:30:53 +0000 (+0000) Subject: Pull ProcessInfo and ProcessLaunchInfo out of Target/Process. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6d6b55d15376815a38e06545605e6d6acb7cbd4b;p=platform%2Fupstream%2Fllvm.git Pull ProcessInfo and ProcessLaunchInfo out of Target/Process. Elevate ProcessInfo and ProcessLaunchInfo into their own headers. llgs will be using ProcessLaunchInfo but doesn't need to pull in the rest of Process.h. This also moves a bunch of implementation details from the header declarations into ProcessInfo.cpp and ProcessLaunchInfo.cpp. Tested on Ubuntu 14.04 Cmake and MacOSX Xcode. Related to https://github.com/tfiala/lldb/issues/26. llvm-svn: 212005 --- diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 69a2c4e..ea9580a 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -45,6 +45,8 @@ #include "lldb/Target/JITLoaderList.h" #include "lldb/Target/Memory.h" #include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Target/ProcessInfo.h" +#include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" @@ -106,232 +108,6 @@ public: typedef std::shared_ptr ProcessPropertiesSP; //---------------------------------------------------------------------- -// ProcessInfo -// -// A base class for information for a process. This can be used to fill -// out information for a process prior to launching it, or it can be -// used for an instance of a process and can be filled in with the -// existing values for that process. -//---------------------------------------------------------------------- -class ProcessInfo -{ -public: - ProcessInfo () : - m_executable (), - m_arguments (), - m_environment (), - m_uid (UINT32_MAX), - m_gid (UINT32_MAX), - m_arch(), - m_pid (LLDB_INVALID_PROCESS_ID) - { - } - - ProcessInfo (const char *name, - const ArchSpec &arch, - lldb::pid_t pid) : - m_executable (name, false), - m_arguments (), - m_environment(), - m_uid (UINT32_MAX), - m_gid (UINT32_MAX), - m_arch (arch), - m_pid (pid) - { - } - - void - Clear () - { - m_executable.Clear(); - m_arguments.Clear(); - m_environment.Clear(); - m_uid = UINT32_MAX; - m_gid = UINT32_MAX; - m_arch.Clear(); - m_pid = LLDB_INVALID_PROCESS_ID; - } - - const char * - GetName() const - { - return m_executable.GetFilename().GetCString(); - } - - size_t - GetNameLength() const - { - return m_executable.GetFilename().GetLength(); - } - - FileSpec & - GetExecutableFile () - { - return m_executable; - } - - void - SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg) - { - if (exe_file) - { - m_executable = exe_file; - if (add_exe_file_as_first_arg) - { - char filename[PATH_MAX]; - if (exe_file.GetPath(filename, sizeof(filename))) - m_arguments.InsertArgumentAtIndex (0, filename); - } - } - else - { - m_executable.Clear(); - } - } - - const FileSpec & - GetExecutableFile () const - { - return m_executable; - } - - uint32_t - GetUserID() const - { - return m_uid; - } - - uint32_t - GetGroupID() const - { - return m_gid; - } - - bool - UserIDIsValid () const - { - return m_uid != UINT32_MAX; - } - - bool - GroupIDIsValid () const - { - return m_gid != UINT32_MAX; - } - - void - SetUserID (uint32_t uid) - { - m_uid = uid; - } - - void - SetGroupID (uint32_t gid) - { - m_gid = gid; - } - - ArchSpec & - GetArchitecture () - { - return m_arch; - } - - const ArchSpec & - GetArchitecture () const - { - return m_arch; - } - - void - SetArchitecture (ArchSpec arch) - { - m_arch = arch; - } - - lldb::pid_t - GetProcessID () const - { - return m_pid; - } - - void - SetProcessID (lldb::pid_t pid) - { - m_pid = pid; - } - - bool - ProcessIDIsValid() const - { - return m_pid != LLDB_INVALID_PROCESS_ID; - } - - void - Dump (Stream &s, Platform *platform) const; - - Args & - GetArguments () - { - return m_arguments; - } - - const Args & - GetArguments () const - { - return m_arguments; - } - - const char * - GetArg0 () const - { - if (m_arg0.empty()) - return NULL; - return m_arg0.c_str(); - } - - void - SetArg0 (const char *arg) - { - if (arg && arg[0]) - m_arg0 = arg; - else - m_arg0.clear(); - } - - void - SetArguments (const Args& args, bool first_arg_is_executable); - - void - SetArguments (char const **argv, bool first_arg_is_executable); - - Args & - GetEnvironmentEntries () - { - return m_environment; - } - - const Args & - GetEnvironmentEntries () const - { - return m_environment; - } - -protected: - FileSpec m_executable; - std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. - // Not all process plug-ins support specifying an argv[0] - // that differs from the resolved platform executable - // (which is in m_executable) - Args m_arguments; // All program arguments except argv[0] - Args m_environment; - uint32_t m_uid; - uint32_t m_gid; - ArchSpec m_arch; - lldb::pid_t m_pid; -}; - -//---------------------------------------------------------------------- // ProcessInstanceInfo // // Describes an existing process and any discoverable information that @@ -436,466 +212,6 @@ protected: lldb::pid_t m_parent_pid; }; - -//---------------------------------------------------------------------- -// ProcessLaunchInfo -// -// Describes any information that is required to launch a process. -//---------------------------------------------------------------------- - -class ProcessLaunchInfo : public ProcessInfo -{ -public: - - class FileAction - { - public: - enum Action - { - eFileActionNone, - eFileActionClose, - eFileActionDuplicate, - eFileActionOpen - }; - - - FileAction () : - m_action (eFileActionNone), - m_fd (-1), - m_arg (-1), - m_path () - { - } - - void - Clear() - { - m_action = eFileActionNone; - m_fd = -1; - m_arg = -1; - m_path.clear(); - } - - bool - Close (int fd); - - bool - Duplicate (int fd, int dup_fd); - - bool - Open (int fd, const char *path, bool read, bool write); - -#ifndef LLDB_DISABLE_POSIX - static bool - AddPosixSpawnFileAction (void *file_actions, - const FileAction *info, - Log *log, - Error& error); -#endif - - int - GetFD () const - { - return m_fd; - } - - Action - GetAction () const - { - return m_action; - } - - int - GetActionArgument () const - { - return m_arg; - } - - const char * - GetPath () const - { - if (m_path.empty()) - return NULL; - return m_path.c_str(); - } - - protected: - Action m_action; // The action for this file - int m_fd; // An existing file descriptor - int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate - std::string m_path; // A file path to use for opening after fork or posix_spawn - }; - - ProcessLaunchInfo () : - ProcessInfo(), - m_working_dir (), - m_plugin_name (), - m_shell (), - m_flags (0), - m_file_actions (), - m_pty (), - m_resume_count (0), - m_monitor_callback (NULL), - m_monitor_callback_baton (NULL), - m_monitor_signals (false), - m_hijack_listener_sp () - { - } - - ProcessLaunchInfo (const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - const char *working_directory, - uint32_t launch_flags) : - ProcessInfo(), - m_working_dir (), - m_plugin_name (), - m_shell (), - m_flags (launch_flags), - m_file_actions (), - m_pty (), - m_resume_count (0), - m_monitor_callback (NULL), - m_monitor_callback_baton (NULL), - m_monitor_signals (false), - m_hijack_listener_sp () - { - if (stdin_path) - { - ProcessLaunchInfo::FileAction file_action; - const bool read = true; - const bool write = false; - if (file_action.Open(STDIN_FILENO, stdin_path, read, write)) - AppendFileAction (file_action); - } - if (stdout_path) - { - ProcessLaunchInfo::FileAction file_action; - const bool read = false; - const bool write = true; - if (file_action.Open(STDOUT_FILENO, stdout_path, read, write)) - AppendFileAction (file_action); - } - if (stderr_path) - { - ProcessLaunchInfo::FileAction file_action; - const bool read = false; - const bool write = true; - if (file_action.Open(STDERR_FILENO, stderr_path, read, write)) - AppendFileAction (file_action); - } - if (working_directory) - SetWorkingDirectory(working_directory); - } - - void - AppendFileAction (const FileAction &info) - { - m_file_actions.push_back(info); - } - - bool - AppendCloseFileAction (int fd) - { - FileAction file_action; - if (file_action.Close (fd)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - bool - AppendDuplicateFileAction (int fd, int dup_fd) - { - FileAction file_action; - if (file_action.Duplicate (fd, dup_fd)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - bool - AppendOpenFileAction (int fd, const char *path, bool read, bool write) - { - FileAction file_action; - if (file_action.Open (fd, path, read, write)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - bool - AppendSuppressFileAction (int fd, bool read, bool write) - { - FileAction file_action; - if (file_action.Open (fd, "/dev/null", read, write)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - void - FinalizeFileActions (Target *target, - bool default_to_use_pty); - - size_t - GetNumFileActions () const - { - return m_file_actions.size(); - } - - const FileAction * - GetFileActionAtIndex (size_t idx) const - { - if (idx < m_file_actions.size()) - return &m_file_actions[idx]; - return NULL; - } - - const FileAction * - GetFileActionForFD (int fd) const - { - for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx) - { - if (m_file_actions[idx].GetFD () == fd) - return &m_file_actions[idx]; - } - return NULL; - } - - Flags & - GetFlags () - { - return m_flags; - } - - const Flags & - GetFlags () const - { - return m_flags; - } - - const char * - GetWorkingDirectory () const - { - if (m_working_dir.empty()) - return NULL; - return m_working_dir.c_str(); - } - - void - SetWorkingDirectory (const char *working_dir) - { - if (working_dir && working_dir[0]) - m_working_dir.assign (working_dir); - else - m_working_dir.clear(); - } - - void - SwapWorkingDirectory (std::string &working_dir) - { - m_working_dir.swap (working_dir); - } - - - const char * - GetProcessPluginName () const - { - if (m_plugin_name.empty()) - return NULL; - return m_plugin_name.c_str(); - } - - void - SetProcessPluginName (const char *plugin) - { - if (plugin && plugin[0]) - m_plugin_name.assign (plugin); - else - m_plugin_name.clear(); - } - - const char * - GetShell () const - { - if (m_shell.empty()) - return NULL; - return m_shell.c_str(); - } - - void - SetShell (const char * path) - { - if (path && path[0]) - { - m_shell.assign (path); - m_flags.Set (lldb::eLaunchFlagLaunchInShell); - } - else - { - m_shell.clear(); - m_flags.Clear (lldb::eLaunchFlagLaunchInShell); - } - } - - uint32_t - GetResumeCount () const - { - return m_resume_count; - } - - void - SetResumeCount (uint32_t c) - { - m_resume_count = c; - } - - bool - GetLaunchInSeparateProcessGroup () - { - return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup); - } - - void - SetLaunchInSeparateProcessGroup (bool separate) - { - if (separate) - m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup); - else - m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup); - - } - - void - Clear () - { - ProcessInfo::Clear(); - m_working_dir.clear(); - m_plugin_name.clear(); - m_shell.clear(); - m_flags.Clear(); - m_file_actions.clear(); - m_resume_count = 0; - m_hijack_listener_sp.reset(); - } - - bool - ConvertArgumentsForLaunchingInShell (Error &error, - bool localhost, - bool will_debug, - bool first_arg_is_full_shell_command, - int32_t num_resumes); - - void - SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, - void *baton, - bool monitor_signals) - { - m_monitor_callback = callback; - m_monitor_callback_baton = baton; - m_monitor_signals = monitor_signals; - } - - Host::MonitorChildProcessCallback - GetMonitorProcessCallback () - { - return m_monitor_callback; - } - - const void* - GetMonitorProcessBaton () const - { - return m_monitor_callback_baton; - } - - // If the LaunchInfo has a monitor callback, then arrange to monitor the process. - // Return true if the LaunchInfo has taken care of monitoring the process, and false if the - // caller might want to monitor the process themselves. - - bool - MonitorProcess () const - { - if (m_monitor_callback && ProcessIDIsValid()) - { - Host::StartMonitoringChildProcess (m_monitor_callback, - m_monitor_callback_baton, - GetProcessID(), - m_monitor_signals); - return true; - } - return false; - } - - lldb_utility::PseudoTerminal & - GetPTY () - { - return m_pty; - } - - lldb::ListenerSP - GetHijackListener () const - { - return m_hijack_listener_sp; - } - - void - SetHijackListener (const lldb::ListenerSP &listener_sp) - { - m_hijack_listener_sp = listener_sp; - } - - - void - SetLaunchEventData (const char *data) - { - m_event_data.assign (data); - } - - const char * - GetLaunchEventData () const - { - return m_event_data.c_str(); - } - - void - SetDetachOnError (bool enable) - { - if (enable) - m_flags.Set(lldb::eLaunchFlagDetachOnError); - else - m_flags.Clear(lldb::eLaunchFlagDetachOnError); - } - - bool - GetDetachOnError () const - { - return m_flags.Test(lldb::eLaunchFlagDetachOnError); - } - -protected: - std::string m_working_dir; - std::string m_plugin_name; - std::string m_shell; - Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags - std::vector m_file_actions; // File actions for any other files - lldb_utility::PseudoTerminal m_pty; - uint32_t m_resume_count; // How many times do we resume after launching - Host::MonitorChildProcessCallback m_monitor_callback; - void *m_monitor_callback_baton; - bool m_monitor_signals; - std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb. - lldb::ListenerSP m_hijack_listener_sp; -}; - //---------------------------------------------------------------------- // ProcessAttachInfo // diff --git a/lldb/include/lldb/Target/ProcessInfo.h b/lldb/include/lldb/Target/ProcessInfo.h new file mode 100644 index 0000000..0570cfc --- /dev/null +++ b/lldb/include/lldb/Target/ProcessInfo.h @@ -0,0 +1,188 @@ +//===-- ProcessInfo.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ProcessInfo_h_ +#define liblldb_ProcessInfo_h_ + +// LLDB headers +#include "lldb/Core/ArchSpec.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Interpreter/Args.h" + +namespace lldb_private +{ + //---------------------------------------------------------------------- + // ProcessInfo + // + // A base class for information for a process. This can be used to fill + // out information for a process prior to launching it, or it can be + // used for an instance of a process and can be filled in with the + // existing values for that process. + //---------------------------------------------------------------------- + class ProcessInfo + { + public: + ProcessInfo (); + + ProcessInfo (const char *name, + const ArchSpec &arch, + lldb::pid_t pid); + + void + Clear (); + + const char * + GetName() const; + + size_t + GetNameLength() const; + + FileSpec & + GetExecutableFile () + { + return m_executable; + } + + void + SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg); + + const FileSpec & + GetExecutableFile () const + { + return m_executable; + } + + uint32_t + GetUserID() const + { + return m_uid; + } + + uint32_t + GetGroupID() const + { + return m_gid; + } + + bool + UserIDIsValid () const + { + return m_uid != UINT32_MAX; + } + + bool + GroupIDIsValid () const + { + return m_gid != UINT32_MAX; + } + + void + SetUserID (uint32_t uid) + { + m_uid = uid; + } + + void + SetGroupID (uint32_t gid) + { + m_gid = gid; + } + + ArchSpec & + GetArchitecture () + { + return m_arch; + } + + const ArchSpec & + GetArchitecture () const + { + return m_arch; + } + + void + SetArchitecture (ArchSpec arch) + { + m_arch = arch; + } + + lldb::pid_t + GetProcessID () const + { + return m_pid; + } + + void + SetProcessID (lldb::pid_t pid) + { + m_pid = pid; + } + + bool + ProcessIDIsValid() const + { + return m_pid != LLDB_INVALID_PROCESS_ID; + } + + void + Dump (Stream &s, Platform *platform) const; + + Args & + GetArguments () + { + return m_arguments; + } + + const Args & + GetArguments () const + { + return m_arguments; + } + + const char * + GetArg0 () const; + + void + SetArg0 (const char *arg); + + void + SetArguments (const Args& args, bool first_arg_is_executable); + + void + SetArguments (char const **argv, bool first_arg_is_executable); + + Args & + GetEnvironmentEntries () + { + return m_environment; + } + + const Args & + GetEnvironmentEntries () const + { + return m_environment; + } + + protected: + FileSpec m_executable; + std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. + // Not all process plug-ins support specifying an argv[0] + // that differs from the resolved platform executable + // (which is in m_executable) + Args m_arguments; // All program arguments except argv[0] + Args m_environment; + uint32_t m_uid; + uint32_t m_gid; + ArchSpec m_arch; + lldb::pid_t m_pid; + }; +} + +#endif // #ifndef liblldb_ProcessInfo_h_ + diff --git a/lldb/include/lldb/Target/ProcessLaunchInfo.h b/lldb/include/lldb/Target/ProcessLaunchInfo.h new file mode 100644 index 0000000..f098333 --- /dev/null +++ b/lldb/include/lldb/Target/ProcessLaunchInfo.h @@ -0,0 +1,285 @@ +//===-- ProcessLaunchInfo.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ProcessLaunch_Info_h +#define liblldb_ProcessLaunch_Info_h + +// C++ Headers +#include + +// LLDB Headers +#include "lldb/Core/Flags.h" +#include "lldb/Host/Host.h" +#include "lldb/Target/ProcessInfo.h" +#include "lldb/Utility/PseudoTerminal.h" + +namespace lldb_private +{ + + //---------------------------------------------------------------------- + // ProcessLaunchInfo + // + // Describes any information that is required to launch a process. + //---------------------------------------------------------------------- + + class ProcessLaunchInfo : public ProcessInfo + { + public: + + class FileAction + { + public: + enum Action + { + eFileActionNone, + eFileActionClose, + eFileActionDuplicate, + eFileActionOpen + }; + + FileAction (); + + void + Clear(); + + bool + Close (int fd); + + bool + Duplicate (int fd, int dup_fd); + + bool + Open (int fd, const char *path, bool read, bool write); + + #ifndef LLDB_DISABLE_POSIX + static bool + AddPosixSpawnFileAction (void *file_actions, + const FileAction *info, + Log *log, + Error& error); + #endif + + int + GetFD () const + { + return m_fd; + } + + Action + GetAction () const + { + return m_action; + } + + int + GetActionArgument () const + { + return m_arg; + } + + const char * + GetPath () const; + + protected: + Action m_action; // The action for this file + int m_fd; // An existing file descriptor + int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate + std::string m_path; // A file path to use for opening after fork or posix_spawn + }; + + ProcessLaunchInfo (); + + ProcessLaunchInfo (const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags); + + void + AppendFileAction (const FileAction &info) + { + m_file_actions.push_back(info); + } + + bool + AppendCloseFileAction (int fd); + + bool + AppendDuplicateFileAction (int fd, int dup_fd); + + bool + AppendOpenFileAction (int fd, const char *path, bool read, bool write); + + bool + AppendSuppressFileAction (int fd, bool read, bool write); + + void + FinalizeFileActions (Target *target, + bool default_to_use_pty); + + size_t + GetNumFileActions () const + { + return m_file_actions.size(); + } + + const FileAction * + GetFileActionAtIndex (size_t idx) const; + + const FileAction * + GetFileActionForFD (int fd) const; + + Flags & + GetFlags () + { + return m_flags; + } + + const Flags & + GetFlags () const + { + return m_flags; + } + + const char * + GetWorkingDirectory () const; + + void + SetWorkingDirectory (const char *working_dir); + + void + SwapWorkingDirectory (std::string &working_dir) + { + m_working_dir.swap (working_dir); + } + + const char * + GetProcessPluginName () const; + + void + SetProcessPluginName (const char *plugin); + + const char * + GetShell () const; + + void + SetShell (const char * path); + + uint32_t + GetResumeCount () const + { + return m_resume_count; + } + + void + SetResumeCount (uint32_t c) + { + m_resume_count = c; + } + + bool + GetLaunchInSeparateProcessGroup () + { + return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup); + } + + void + SetLaunchInSeparateProcessGroup (bool separate); + + void + Clear (); + + bool + ConvertArgumentsForLaunchingInShell (Error &error, + bool localhost, + bool will_debug, + bool first_arg_is_full_shell_command, + int32_t num_resumes); + + void + SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, + void *baton, + bool monitor_signals); + + Host::MonitorChildProcessCallback + GetMonitorProcessCallback () + { + return m_monitor_callback; + } + + const void* + GetMonitorProcessBaton () const + { + return m_monitor_callback_baton; + } + + // If the LaunchInfo has a monitor callback, then arrange to monitor the process. + // Return true if the LaunchInfo has taken care of monitoring the process, and false if the + // caller might want to monitor the process themselves. + + bool + MonitorProcess () const; + + lldb_utility::PseudoTerminal & + GetPTY () + { + return m_pty; + } + + lldb::ListenerSP + GetHijackListener () const + { + return m_hijack_listener_sp; + } + + void + SetHijackListener (const lldb::ListenerSP &listener_sp) + { + m_hijack_listener_sp = listener_sp; + } + + + void + SetLaunchEventData (const char *data) + { + m_event_data.assign (data); + } + + const char * + GetLaunchEventData () const + { + return m_event_data.c_str(); + } + + void + SetDetachOnError (bool enable); + + bool + GetDetachOnError () const + { + return m_flags.Test(lldb::eLaunchFlagDetachOnError); + } + + protected: + std::string m_working_dir; + std::string m_plugin_name; + std::string m_shell; + Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags + std::vector m_file_actions; // File actions for any other files + lldb_utility::PseudoTerminal m_pty; + uint32_t m_resume_count; // How many times do we resume after launching + Host::MonitorChildProcessCallback m_monitor_callback; + void *m_monitor_callback_baton; + bool m_monitor_signals; + std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb. + lldb::ListenerSP m_hijack_listener_sp; + }; +} + +#endif // liblldb_ProcessLaunch_Info_h diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index b70f854..2e3beeb 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -53,6 +53,8 @@ /* Begin PBXBuildFile section */ 23059A101958B319007B8189 /* SBUnixSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23059A0F1958B319007B8189 /* SBUnixSignals.cpp */; }; 23059A121958B3B2007B8189 /* SBUnixSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = 23059A111958B37B007B8189 /* SBUnixSignals.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 233B007D1960C9F90090E598 /* ProcessInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007B1960C9E60090E598 /* ProcessInfo.cpp */; }; + 233B007F1960CB280090E598 /* ProcessLaunchInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */; }; 23EFE389193D1ABC00E54E54 /* SBTypeEnumMember.h in Headers */ = {isa = PBXBuildFile; fileRef = 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23EFE38B193D1AEC00E54E54 /* SBTypeEnumMember.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23EFE38A193D1AEC00E54E54 /* SBTypeEnumMember.cpp */; }; 260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; }; @@ -875,6 +877,10 @@ /* Begin PBXFileReference section */ 23059A0F1958B319007B8189 /* SBUnixSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBUnixSignals.cpp; path = source/API/SBUnixSignals.cpp; sourceTree = ""; }; 23059A111958B37B007B8189 /* SBUnixSignals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBUnixSignals.h; path = include/lldb/API/SBUnixSignals.h; sourceTree = ""; }; + 233B007919609DB40090E598 /* ProcessLaunchInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessLaunchInfo.h; path = include/lldb/Target/ProcessLaunchInfo.h; sourceTree = ""; }; + 233B007A1960A0440090E598 /* ProcessInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessInfo.h; path = include/lldb/Target/ProcessInfo.h; sourceTree = ""; }; + 233B007B1960C9E60090E598 /* ProcessInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessInfo.cpp; path = source/Target/ProcessInfo.cpp; sourceTree = ""; }; + 233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessLaunchInfo.cpp; path = source/Target/ProcessLaunchInfo.cpp; sourceTree = ""; }; 2360092C193FB21500189DB1 /* MemoryRegionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemoryRegionInfo.h; path = include/lldb/Target/MemoryRegionInfo.h; sourceTree = ""; }; 23EDE3371926AAD500F6A132 /* RegisterInfoInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegisterInfoInterface.h; path = Utility/RegisterInfoInterface.h; sourceTree = ""; }; 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeEnumMember.h; path = include/lldb/API/SBTypeEnumMember.h; sourceTree = ""; }; @@ -3449,6 +3455,10 @@ 495BBACB119A0DBE00418BEA /* PathMappingList.cpp */, 264A43BB1320B3B4005B4096 /* Platform.h */, 264A43BD1320BCEB005B4096 /* Platform.cpp */, + 233B007A1960A0440090E598 /* ProcessInfo.h */, + 233B007B1960C9E60090E598 /* ProcessInfo.cpp */, + 233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */, + 233B007919609DB40090E598 /* ProcessLaunchInfo.h */, 26BC7DF310F1B81A00F91463 /* Process.h */, 26BC7F3610F1B90C00F91463 /* Process.cpp */, 260A63111860FDB600FECF8E /* Queue.h */, @@ -4610,6 +4620,7 @@ 2689005613353E0400698AC0 /* Value.cpp in Sources */, 2689005713353E0400698AC0 /* ValueObject.cpp in Sources */, 2689005813353E0400698AC0 /* ValueObjectChild.cpp in Sources */, + 233B007F1960CB280090E598 /* ProcessLaunchInfo.cpp in Sources */, 2689005913353E0400698AC0 /* ValueObjectConstResult.cpp in Sources */, 2689005A13353E0400698AC0 /* ValueObjectList.cpp in Sources */, 2689005B13353E0400698AC0 /* ValueObjectRegister.cpp in Sources */, @@ -4704,6 +4715,7 @@ 94D0B10C16D5535900EA9C70 /* LibCxx.cpp in Sources */, 268900C513353E5F00698AC0 /* DWARFDIECollection.cpp in Sources */, 268900C613353E5F00698AC0 /* DWARFFormValue.cpp in Sources */, + 233B007D1960C9F90090E598 /* ProcessInfo.cpp in Sources */, 268900C713353E5F00698AC0 /* DWARFLocationDescription.cpp in Sources */, 26BC17B118C7F4CB00D2196D /* ThreadElfCore.cpp in Sources */, 268900C813353E5F00698AC0 /* DWARFLocationList.cpp in Sources */, diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index 3683017..b83cdf5 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -15,6 +15,8 @@ add_lldb_library(lldbTarget PathMappingList.cpp Platform.cpp Process.cpp + ProcessInfo.cpp + ProcessLaunchInfo.cpp Queue.cpp QueueItem.cpp QueueList.cpp diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 5fd73cb..e50cc4a 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -393,369 +393,6 @@ ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_ar } } - -void -ProcessInfo::SetArguments (char const **argv, bool first_arg_is_executable) -{ - m_arguments.SetArguments (argv); - - // Is the first argument the executable? - if (first_arg_is_executable) - { - const char *first_arg = m_arguments.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); - } - } -} -void -ProcessInfo::SetArguments (const Args& args, bool first_arg_is_executable) -{ - // Copy all arguments - m_arguments = args; - - // Is the first argument the executable? - if (first_arg_is_executable) - { - const char *first_arg = m_arguments.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); - } - } -} - -void -ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) -{ - // If nothing for stdin or stdout or stderr was specified, then check the process for any default - // settings that were set with "settings set" - if (GetFileActionForFD(STDIN_FILENO) == NULL || GetFileActionForFD(STDOUT_FILENO) == NULL || - GetFileActionForFD(STDERR_FILENO) == NULL) - { - if (m_flags.Test(eLaunchFlagDisableSTDIO)) - { - AppendSuppressFileAction (STDIN_FILENO , true, false); - AppendSuppressFileAction (STDOUT_FILENO, false, true); - AppendSuppressFileAction (STDERR_FILENO, false, true); - } - else - { - // Check for any values that might have gotten set with any of: - // (lldb) settings set target.input-path - // (lldb) settings set target.output-path - // (lldb) settings set target.error-path - FileSpec in_path; - FileSpec out_path; - FileSpec err_path; - if (target) - { - in_path = target->GetStandardInputPath(); - out_path = target->GetStandardOutputPath(); - err_path = target->GetStandardErrorPath(); - } - - char path[PATH_MAX]; - if (in_path && in_path.GetPath(path, sizeof(path))) - AppendOpenFileAction(STDIN_FILENO, path, true, false); - - if (out_path && out_path.GetPath(path, sizeof(path))) - AppendOpenFileAction(STDOUT_FILENO, path, false, true); - - if (err_path && err_path.GetPath(path, sizeof(path))) - AppendOpenFileAction(STDERR_FILENO, path, false, true); - - if (default_to_use_pty && (!in_path || !out_path || !err_path)) { - if (m_pty.OpenFirstAvailableMaster(O_RDWR| O_NOCTTY, NULL, 0)) { - const char *slave_path = m_pty.GetSlaveName(NULL, 0); - - if (!in_path) { - AppendOpenFileAction(STDIN_FILENO, slave_path, true, false); - } - - if (!out_path) { - AppendOpenFileAction(STDOUT_FILENO, slave_path, false, true); - } - - if (!err_path) { - AppendOpenFileAction(STDERR_FILENO, slave_path, false, true); - } - } - } - } - } -} - - -bool -ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, - bool localhost, - bool will_debug, - bool first_arg_is_full_shell_command, - int32_t num_resumes) -{ - error.Clear(); - - if (GetFlags().Test (eLaunchFlagLaunchInShell)) - { - const char *shell_executable = GetShell(); - if (shell_executable) - { - char shell_resolved_path[PATH_MAX]; - - if (localhost) - { - FileSpec shell_filespec (shell_executable, true); - - if (!shell_filespec.Exists()) - { - // Resolve the path in case we just got "bash", "sh" or "tcsh" - if (!shell_filespec.ResolveExecutableLocation ()) - { - error.SetErrorStringWithFormat("invalid shell path '%s'", shell_executable); - return false; - } - } - shell_filespec.GetPath (shell_resolved_path, sizeof(shell_resolved_path)); - shell_executable = shell_resolved_path; - } - - const char **argv = GetArguments().GetConstArgumentVector (); - if (argv == NULL || argv[0] == NULL) - return false; - Args shell_arguments; - std::string safe_arg; - shell_arguments.AppendArgument (shell_executable); - shell_arguments.AppendArgument ("-c"); - StreamString shell_command; - if (will_debug) - { - // Add a modified PATH environment variable in case argv[0] - // is a relative path - const char *argv0 = argv[0]; - if (argv0 && (argv0[0] != '/' && argv0[0] != '~')) - { - // We have a relative path to our executable which may not work if - // we just try to run "a.out" (without it being converted to "./a.out") - const char *working_dir = GetWorkingDirectory(); - // Be sure to put quotes around PATH's value in case any paths have spaces... - std::string new_path("PATH=\""); - const size_t empty_path_len = new_path.size(); - - if (working_dir && working_dir[0]) - { - new_path += working_dir; - } - else - { - char current_working_dir[PATH_MAX]; - const char *cwd = getcwd(current_working_dir, sizeof(current_working_dir)); - if (cwd && cwd[0]) - new_path += cwd; - } - const char *curr_path = getenv("PATH"); - if (curr_path) - { - if (new_path.size() > empty_path_len) - new_path += ':'; - new_path += curr_path; - } - new_path += "\" "; - shell_command.PutCString(new_path.c_str()); - } - - shell_command.PutCString ("exec"); - - // Only Apple supports /usr/bin/arch being able to specify the architecture - if (GetArchitecture().IsValid()) - { - shell_command.Printf(" /usr/bin/arch -arch %s", GetArchitecture().GetArchitectureName()); - // Set the resume count to 2: - // 1 - stop in shell - // 2 - stop in /usr/bin/arch - // 3 - then we will stop in our program - SetResumeCount(num_resumes + 1); - } - else - { - // Set the resume count to 1: - // 1 - stop in shell - // 2 - then we will stop in our program - SetResumeCount(num_resumes); - } - } - - if (first_arg_is_full_shell_command) - { - // There should only be one argument that is the shell command itself to be used as is - if (argv[0] && !argv[1]) - shell_command.Printf("%s", argv[0]); - else - return false; - } - else - { - for (size_t i=0; argv[i] != NULL; ++i) - { - const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg); - shell_command.Printf(" %s", arg); - } - } - shell_arguments.AppendArgument (shell_command.GetString().c_str()); - m_executable.SetFile(shell_executable, false); - m_arguments = shell_arguments; - return true; - } - else - { - error.SetErrorString ("invalid shell path"); - } - } - else - { - error.SetErrorString ("not launching in shell"); - } - return false; -} - - -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_NOCTTY | O_CREAT | O_RDWR; - else if (read) - m_arg = O_NOCTTY | O_RDONLY; - else - m_arg = O_NOCTTY | O_CREAT | O_WRONLY; - m_path.assign (path); - return true; - } - else - { - Clear(); - } - return false; -} - -bool -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; -} - - - -#ifndef LLDB_DISABLE_POSIX -bool -ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (void *_file_actions, - const FileAction *info, - Log *log, - Error& error) -{ - if (info == NULL) - return false; - - posix_spawn_file_actions_t *file_actions = reinterpret_cast(_file_actions); - - 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)", - static_cast(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)", - static_cast(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; - - if (oflag & O_CREAT) - mode = 0640; - - 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)", - static_cast(file_actions), info->m_fd, - info->m_path.c_str(), oflag, mode); - } - break; - } - return error.Success(); -} -#endif - Error ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) { diff --git a/lldb/source/Target/ProcessInfo.cpp b/lldb/source/Target/ProcessInfo.cpp new file mode 100644 index 0000000..22da2c6 --- /dev/null +++ b/lldb/source/Target/ProcessInfo.cpp @@ -0,0 +1,138 @@ +//===-- ProcessInfo.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ProcessInfo.h" + +// C Includes +#include + +using namespace lldb; +using namespace lldb_private; + +ProcessInfo::ProcessInfo () : + m_executable (), + m_arguments (), + m_environment (), + m_uid (UINT32_MAX), + m_gid (UINT32_MAX), + m_arch(), + m_pid (LLDB_INVALID_PROCESS_ID) +{ +} + +ProcessInfo::ProcessInfo (const char *name, const ArchSpec &arch, lldb::pid_t pid) : + m_executable (name, false), + m_arguments (), + m_environment(), + m_uid (UINT32_MAX), + m_gid (UINT32_MAX), + m_arch (arch), + m_pid (pid) +{ +} + +void +ProcessInfo::Clear () +{ + m_executable.Clear(); + m_arguments.Clear(); + m_environment.Clear(); + m_uid = UINT32_MAX; + m_gid = UINT32_MAX; + m_arch.Clear(); + m_pid = LLDB_INVALID_PROCESS_ID; +} + +const char * +ProcessInfo::GetName() const +{ + return m_executable.GetFilename().GetCString(); +} + +size_t +ProcessInfo::GetNameLength() const +{ + return m_executable.GetFilename().GetLength(); +} + +void +ProcessInfo::SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg) +{ + if (exe_file) + { + m_executable = exe_file; + if (add_exe_file_as_first_arg) + { + char filename[PATH_MAX]; + if (exe_file.GetPath(filename, sizeof(filename))) + m_arguments.InsertArgumentAtIndex (0, filename); + } + } + else + { + m_executable.Clear(); + } +} + +const char * +ProcessInfo::GetArg0 () const +{ + if (m_arg0.empty()) + return NULL; + return m_arg0.c_str(); +} + +void +ProcessInfo::SetArg0 (const char *arg) +{ + if (arg && arg[0]) + m_arg0 = arg; + else + m_arg0.clear(); +} + +void +ProcessInfo::SetArguments (char const **argv, bool first_arg_is_executable) +{ + m_arguments.SetArguments (argv); + + // Is the first argument the executable? + if (first_arg_is_executable) + { + const char *first_arg = m_arguments.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); + } + } +} +void +ProcessInfo::SetArguments (const Args& args, bool first_arg_is_executable) +{ + // Copy all arguments + m_arguments = args; + + // Is the first argument the executable? + if (first_arg_is_executable) + { + const char *first_arg = m_arguments.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); + } + } +} diff --git a/lldb/source/Target/ProcessLaunchInfo.cpp b/lldb/source/Target/ProcessLaunchInfo.cpp new file mode 100644 index 0000000..05d3eb5 --- /dev/null +++ b/lldb/source/Target/ProcessLaunchInfo.cpp @@ -0,0 +1,617 @@ +//===-- ProcessLaunchInfo.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ProcessLaunchInfo.h" + +#ifndef LLDB_DISABLE_POSIX +#include +#endif + +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------------- +// ProcessLaunchInfo::FileAction member functions +//---------------------------------------------------------------------------- + +ProcessLaunchInfo::FileAction::FileAction () : + m_action (eFileActionNone), + m_fd (-1), + m_arg (-1), + m_path () +{ +} + +void +ProcessLaunchInfo::FileAction::Clear() +{ + m_action = eFileActionNone; + m_fd = -1; + m_arg = -1; + m_path.clear(); +} + +const char * +ProcessLaunchInfo::FileAction::GetPath () const +{ + if (m_path.empty()) + return NULL; + return m_path.c_str(); +} + +//---------------------------------------------------------------------------- +// ProcessLaunchInfo member functions +//---------------------------------------------------------------------------- + +ProcessLaunchInfo::ProcessLaunchInfo () : + ProcessInfo(), + m_working_dir (), + m_plugin_name (), + m_shell (), + m_flags (0), + m_file_actions (), + m_pty (), + m_resume_count (0), + m_monitor_callback (NULL), + m_monitor_callback_baton (NULL), + m_monitor_signals (false), + m_hijack_listener_sp () +{ +} + +ProcessLaunchInfo::ProcessLaunchInfo ( + const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags) : + ProcessInfo(), + m_working_dir (), + m_plugin_name (), + m_shell (), + m_flags (launch_flags), + m_file_actions (), + m_pty (), + m_resume_count (0), + m_monitor_callback (NULL), + m_monitor_callback_baton (NULL), + m_monitor_signals (false), + m_hijack_listener_sp () +{ + if (stdin_path) + { + ProcessLaunchInfo::FileAction file_action; + const bool read = true; + const bool write = false; + if (file_action.Open(STDIN_FILENO, stdin_path, read, write)) + AppendFileAction (file_action); + } + if (stdout_path) + { + ProcessLaunchInfo::FileAction file_action; + const bool read = false; + const bool write = true; + if (file_action.Open(STDOUT_FILENO, stdout_path, read, write)) + AppendFileAction (file_action); + } + if (stderr_path) + { + ProcessLaunchInfo::FileAction file_action; + const bool read = false; + const bool write = true; + if (file_action.Open(STDERR_FILENO, stderr_path, read, write)) + AppendFileAction (file_action); + } + if (working_directory) + SetWorkingDirectory(working_directory); +} + +bool +ProcessLaunchInfo::AppendCloseFileAction (int fd) +{ + FileAction file_action; + if (file_action.Close (fd)) + { + AppendFileAction (file_action); + return true; + } + return false; +} + +bool +ProcessLaunchInfo::AppendDuplicateFileAction (int fd, int dup_fd) +{ + FileAction file_action; + if (file_action.Duplicate (fd, dup_fd)) + { + AppendFileAction (file_action); + return true; + } + return false; +} + +bool +ProcessLaunchInfo::AppendOpenFileAction (int fd, const char *path, bool read, bool write) +{ + FileAction file_action; + if (file_action.Open (fd, path, read, write)) + { + AppendFileAction (file_action); + return true; + } + return false; +} + +bool +ProcessLaunchInfo::AppendSuppressFileAction (int fd, bool read, bool write) +{ + FileAction file_action; + if (file_action.Open (fd, "/dev/null", read, write)) + { + AppendFileAction (file_action); + return true; + } + return false; +} + +const ProcessLaunchInfo::FileAction * +ProcessLaunchInfo::GetFileActionAtIndex (size_t idx) const +{ + if (idx < m_file_actions.size()) + return &m_file_actions[idx]; + return NULL; +} + +const ProcessLaunchInfo::FileAction * +ProcessLaunchInfo::GetFileActionForFD (int fd) const +{ + for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx) + { + if (m_file_actions[idx].GetFD () == fd) + return &m_file_actions[idx]; + } + return NULL; +} + +const char * +ProcessLaunchInfo::GetWorkingDirectory () const +{ + if (m_working_dir.empty()) + return NULL; + return m_working_dir.c_str(); +} + +void +ProcessLaunchInfo::SetWorkingDirectory (const char *working_dir) +{ + if (working_dir && working_dir[0]) + m_working_dir.assign (working_dir); + else + m_working_dir.clear(); +} + +const char * +ProcessLaunchInfo::GetProcessPluginName () const +{ + if (m_plugin_name.empty()) + return NULL; + return m_plugin_name.c_str(); +} + +void +ProcessLaunchInfo::SetProcessPluginName (const char *plugin) +{ + if (plugin && plugin[0]) + m_plugin_name.assign (plugin); + else + m_plugin_name.clear(); +} + +const char * +ProcessLaunchInfo::GetShell () const +{ + if (m_shell.empty()) + return NULL; + return m_shell.c_str(); +} + +void +ProcessLaunchInfo::SetShell (const char * path) +{ + if (path && path[0]) + { + m_shell.assign (path); + m_flags.Set (lldb::eLaunchFlagLaunchInShell); + } + else + { + m_shell.clear(); + m_flags.Clear (lldb::eLaunchFlagLaunchInShell); + } +} + +void +ProcessLaunchInfo::SetLaunchInSeparateProcessGroup (bool separate) +{ + if (separate) + m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup); + else + m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup); + +} + +void +ProcessLaunchInfo::Clear () +{ + ProcessInfo::Clear(); + m_working_dir.clear(); + m_plugin_name.clear(); + m_shell.clear(); + m_flags.Clear(); + m_file_actions.clear(); + m_resume_count = 0; + m_hijack_listener_sp.reset(); +} + +void +ProcessLaunchInfo::SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, + void *baton, + bool monitor_signals) +{ + m_monitor_callback = callback; + m_monitor_callback_baton = baton; + m_monitor_signals = monitor_signals; +} + +bool +ProcessLaunchInfo::MonitorProcess () const +{ + if (m_monitor_callback && ProcessIDIsValid()) + { + Host::StartMonitoringChildProcess (m_monitor_callback, + m_monitor_callback_baton, + GetProcessID(), + m_monitor_signals); + return true; + } + return false; +} + +void +ProcessLaunchInfo::SetDetachOnError (bool enable) +{ + if (enable) + m_flags.Set(lldb::eLaunchFlagDetachOnError); + else + m_flags.Clear(lldb::eLaunchFlagDetachOnError); +} + +void +ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) +{ + // If nothing for stdin or stdout or stderr was specified, then check the process for any default + // settings that were set with "settings set" + if (GetFileActionForFD(STDIN_FILENO) == NULL || GetFileActionForFD(STDOUT_FILENO) == NULL || + GetFileActionForFD(STDERR_FILENO) == NULL) + { + if (m_flags.Test(eLaunchFlagDisableSTDIO)) + { + AppendSuppressFileAction (STDIN_FILENO , true, false); + AppendSuppressFileAction (STDOUT_FILENO, false, true); + AppendSuppressFileAction (STDERR_FILENO, false, true); + } + else + { + // Check for any values that might have gotten set with any of: + // (lldb) settings set target.input-path + // (lldb) settings set target.output-path + // (lldb) settings set target.error-path + FileSpec in_path; + FileSpec out_path; + FileSpec err_path; + if (target) + { + in_path = target->GetStandardInputPath(); + out_path = target->GetStandardOutputPath(); + err_path = target->GetStandardErrorPath(); + } + + char path[PATH_MAX]; + if (in_path && in_path.GetPath(path, sizeof(path))) + AppendOpenFileAction(STDIN_FILENO, path, true, false); + + if (out_path && out_path.GetPath(path, sizeof(path))) + AppendOpenFileAction(STDOUT_FILENO, path, false, true); + + if (err_path && err_path.GetPath(path, sizeof(path))) + AppendOpenFileAction(STDERR_FILENO, path, false, true); + + if (default_to_use_pty && (!in_path || !out_path || !err_path)) { + if (m_pty.OpenFirstAvailableMaster(O_RDWR| O_NOCTTY, NULL, 0)) { + const char *slave_path = m_pty.GetSlaveName(NULL, 0); + + if (!in_path) { + AppendOpenFileAction(STDIN_FILENO, slave_path, true, false); + } + + if (!out_path) { + AppendOpenFileAction(STDOUT_FILENO, slave_path, false, true); + } + + if (!err_path) { + AppendOpenFileAction(STDERR_FILENO, slave_path, false, true); + } + } + } + } + } +} + + +bool +ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, + bool localhost, + bool will_debug, + bool first_arg_is_full_shell_command, + int32_t num_resumes) +{ + error.Clear(); + + if (GetFlags().Test (eLaunchFlagLaunchInShell)) + { + const char *shell_executable = GetShell(); + if (shell_executable) + { + char shell_resolved_path[PATH_MAX]; + + if (localhost) + { + FileSpec shell_filespec (shell_executable, true); + + if (!shell_filespec.Exists()) + { + // Resolve the path in case we just got "bash", "sh" or "tcsh" + if (!shell_filespec.ResolveExecutableLocation ()) + { + error.SetErrorStringWithFormat("invalid shell path '%s'", shell_executable); + return false; + } + } + shell_filespec.GetPath (shell_resolved_path, sizeof(shell_resolved_path)); + shell_executable = shell_resolved_path; + } + + const char **argv = GetArguments().GetConstArgumentVector (); + if (argv == NULL || argv[0] == NULL) + return false; + Args shell_arguments; + std::string safe_arg; + shell_arguments.AppendArgument (shell_executable); + shell_arguments.AppendArgument ("-c"); + StreamString shell_command; + if (will_debug) + { + // Add a modified PATH environment variable in case argv[0] + // is a relative path + const char *argv0 = argv[0]; + if (argv0 && (argv0[0] != '/' && argv0[0] != '~')) + { + // We have a relative path to our executable which may not work if + // we just try to run "a.out" (without it being converted to "./a.out") + const char *working_dir = GetWorkingDirectory(); + // Be sure to put quotes around PATH's value in case any paths have spaces... + std::string new_path("PATH=\""); + const size_t empty_path_len = new_path.size(); + + if (working_dir && working_dir[0]) + { + new_path += working_dir; + } + else + { + char current_working_dir[PATH_MAX]; + const char *cwd = getcwd(current_working_dir, sizeof(current_working_dir)); + if (cwd && cwd[0]) + new_path += cwd; + } + const char *curr_path = getenv("PATH"); + if (curr_path) + { + if (new_path.size() > empty_path_len) + new_path += ':'; + new_path += curr_path; + } + new_path += "\" "; + shell_command.PutCString(new_path.c_str()); + } + + shell_command.PutCString ("exec"); + + // Only Apple supports /usr/bin/arch being able to specify the architecture + if (GetArchitecture().IsValid()) + { + shell_command.Printf(" /usr/bin/arch -arch %s", GetArchitecture().GetArchitectureName()); + // Set the resume count to 2: + // 1 - stop in shell + // 2 - stop in /usr/bin/arch + // 3 - then we will stop in our program + SetResumeCount(num_resumes + 1); + } + else + { + // Set the resume count to 1: + // 1 - stop in shell + // 2 - then we will stop in our program + SetResumeCount(num_resumes); + } + } + + if (first_arg_is_full_shell_command) + { + // There should only be one argument that is the shell command itself to be used as is + if (argv[0] && !argv[1]) + shell_command.Printf("%s", argv[0]); + else + return false; + } + else + { + for (size_t i=0; argv[i] != NULL; ++i) + { + const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg); + shell_command.Printf(" %s", arg); + } + } + shell_arguments.AppendArgument (shell_command.GetString().c_str()); + m_executable.SetFile(shell_executable, false); + m_arguments = shell_arguments; + return true; + } + else + { + error.SetErrorString ("invalid shell path"); + } + } + else + { + error.SetErrorString ("not launching in shell"); + } + return false; +} + + +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_NOCTTY | O_CREAT | O_RDWR; + else if (read) + m_arg = O_NOCTTY | O_RDONLY; + else + m_arg = O_NOCTTY | O_CREAT | O_WRONLY; + m_path.assign (path); + return true; + } + else + { + Clear(); + } + return false; +} + +bool +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; +} + + + +#ifndef LLDB_DISABLE_POSIX +bool +ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (void *_file_actions, + const FileAction *info, + Log *log, + Error& error) +{ + if (info == NULL) + return false; + + posix_spawn_file_actions_t *file_actions = reinterpret_cast(_file_actions); + + 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)", + static_cast(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)", + static_cast(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; + + if (oflag & O_CREAT) + mode = 0640; + + 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)", + static_cast(file_actions), info->m_fd, + info->m_path.c_str(), oflag, mode); + } + break; + } + return error.Success(); +} +#endif diff --git a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj index b30eb87..064e9ee 100644 --- a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -658,7 +658,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; @@ -725,7 +725,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; @@ -823,7 +823,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES;