Host.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //===-- Host.h --------------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLDB_HOST_HOST_H
  9. #define LLDB_HOST_HOST_H
  10. #include "lldb/Host/File.h"
  11. #include "lldb/Host/HostThread.h"
  12. #include "lldb/Utility/Environment.h"
  13. #include "lldb/Utility/FileSpec.h"
  14. #include "lldb/Utility/Timeout.h"
  15. #include "lldb/lldb-private-forward.h"
  16. #include "lldb/lldb-private.h"
  17. #include <cerrno>
  18. #include <cstdarg>
  19. #include <map>
  20. #include <string>
  21. #include <type_traits>
  22. namespace lldb_private {
  23. class FileAction;
  24. class ProcessLaunchInfo;
  25. class ProcessInstanceInfo;
  26. class ProcessInstanceInfoMatch;
  27. typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
  28. // Exit Type for inferior processes
  29. struct WaitStatus {
  30. enum Type : uint8_t {
  31. Exit, // The status represents the return code from normal
  32. // program exit (i.e. WIFEXITED() was true)
  33. Signal, // The status represents the signal number that caused
  34. // the program to exit (i.e. WIFSIGNALED() was true)
  35. Stop, // The status represents the signal number that caused the
  36. // program to stop (i.e. WIFSTOPPED() was true)
  37. };
  38. Type type;
  39. uint8_t status;
  40. WaitStatus(Type type, uint8_t status) : type(type), status(status) {}
  41. static WaitStatus Decode(int wstatus);
  42. };
  43. inline bool operator==(WaitStatus a, WaitStatus b) {
  44. return a.type == b.type && a.status == b.status;
  45. }
  46. inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
  47. /// \class Host Host.h "lldb/Host/Host.h"
  48. /// A class that provides host computer information.
  49. ///
  50. /// Host is a class that answers information about the host operating system.
  51. class Host {
  52. public:
  53. typedef std::function<bool(
  54. lldb::pid_t pid, bool exited,
  55. int signal, // Zero for no signal
  56. int status)> // Exit value of process if signal is zero
  57. MonitorChildProcessCallback;
  58. /// Start monitoring a child process.
  59. ///
  60. /// Allows easy monitoring of child processes. \a callback will be called
  61. /// when the child process exits or if it gets a signal. The callback will
  62. /// only be called with signals if \a monitor_signals is \b true. \a
  63. /// callback will usually be called from another thread so the callback
  64. /// function must be thread safe.
  65. ///
  66. /// When the callback gets called, the return value indicates if monitoring
  67. /// should stop. If \b true is returned from \a callback the information
  68. /// will be removed. If \b false is returned then monitoring will continue.
  69. /// If the child process exits, the monitoring will automatically stop after
  70. /// the callback returned regardless of the callback return value.
  71. ///
  72. /// \param[in] callback
  73. /// A function callback to call when a child receives a signal
  74. /// (if \a monitor_signals is true) or a child exits.
  75. ///
  76. /// \param[in] pid
  77. /// The process ID of a child process to monitor, -1 for all
  78. /// processes.
  79. ///
  80. /// \param[in] monitor_signals
  81. /// If \b true the callback will get called when the child
  82. /// process gets a signal. If \b false, the callback will only
  83. /// get called if the child process exits.
  84. ///
  85. /// \return
  86. /// A thread handle that can be used to cancel the thread that
  87. /// was spawned to monitor \a pid.
  88. ///
  89. /// \see static void Host::StopMonitoringChildProcess (uint32_t)
  90. static llvm::Expected<HostThread>
  91. StartMonitoringChildProcess(const MonitorChildProcessCallback &callback,
  92. lldb::pid_t pid, bool monitor_signals);
  93. enum SystemLogType { eSystemLogWarning, eSystemLogError };
  94. static void SystemLog(SystemLogType type, const char *format, ...)
  95. __attribute__((format(printf, 2, 3)));
  96. static void SystemLog(SystemLogType type, const char *format, va_list args);
  97. /// Get the process ID for the calling process.
  98. ///
  99. /// \return
  100. /// The process ID for the current process.
  101. static lldb::pid_t GetCurrentProcessID();
  102. static void Kill(lldb::pid_t pid, int signo);
  103. /// Get the thread token (the one returned by ThreadCreate when the thread
  104. /// was created) for the calling thread in the current process.
  105. ///
  106. /// \return
  107. /// The thread token for the calling thread in the current process.
  108. static lldb::thread_t GetCurrentThread();
  109. static const char *GetSignalAsCString(int signo);
  110. /// Given an address in the current process (the process that is running the
  111. /// LLDB code), return the name of the module that it comes from. This can
  112. /// be useful when you need to know the path to the shared library that your
  113. /// code is running in for loading resources that are relative to your
  114. /// binary.
  115. ///
  116. /// \param[in] host_addr
  117. /// The pointer to some code in the current process.
  118. ///
  119. /// \return
  120. /// \b A file spec with the module that contains \a host_addr,
  121. /// which may be invalid if \a host_addr doesn't fall into
  122. /// any valid module address range.
  123. static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr);
  124. /// If you have an executable that is in a bundle and want to get back to
  125. /// the bundle directory from the path itself, this function will change a
  126. /// path to a file within a bundle to the bundle directory itself.
  127. ///
  128. /// \param[in] file
  129. /// A file spec that might point to a file in a bundle.
  130. ///
  131. /// \param[out] bundle_directory
  132. /// An object will be filled in with the bundle directory for
  133. /// the bundle when \b true is returned. Otherwise \a file is
  134. /// left untouched and \b false is returned.
  135. ///
  136. /// \return
  137. /// \b true if \a file was resolved in \a bundle_directory,
  138. /// \b false otherwise.
  139. static bool GetBundleDirectory(const FileSpec &file,
  140. FileSpec &bundle_directory);
  141. /// When executable files may live within a directory, where the directory
  142. /// represents an executable bundle (like the MacOSX app bundles), then
  143. /// locate the executable within the containing bundle.
  144. ///
  145. /// \param[in,out] file
  146. /// A file spec that currently points to the bundle that will
  147. /// be filled in with the executable path within the bundle
  148. /// if \b true is returned. Otherwise \a file is left untouched.
  149. ///
  150. /// \return
  151. /// \b true if \a file was resolved, \b false if this function
  152. /// was not able to resolve the path.
  153. static bool ResolveExecutableInBundle(FileSpec &file);
  154. static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
  155. ProcessInstanceInfoList &proc_infos);
  156. typedef std::map<lldb::pid_t, bool> TidMap;
  157. typedef std::pair<lldb::pid_t, bool> TidPair;
  158. static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach);
  159. static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
  160. /// Launch the process specified in launch_info. The monitoring callback in
  161. /// launch_info must be set, and it will be called when the process
  162. /// terminates.
  163. static Status LaunchProcess(ProcessLaunchInfo &launch_info);
  164. /// Perform expansion of the command-line for this launch info This can
  165. /// potentially involve wildcard expansion
  166. /// environment variable replacement, and whatever other
  167. /// argument magic the platform defines as part of its typical
  168. /// user experience
  169. static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
  170. /// Run a shell command.
  171. /// \arg command shouldn't be empty
  172. /// \arg working_dir Pass empty FileSpec to use the current working directory
  173. /// \arg status_ptr Pass NULL if you don't want the process exit status
  174. /// \arg signo_ptr Pass NULL if you don't want the signal that caused the
  175. /// process to exit
  176. /// \arg command_output Pass NULL if you don't want the command output
  177. /// \arg hide_stderr if this is false, redirect stderr to stdout
  178. static Status RunShellCommand(llvm::StringRef command,
  179. const FileSpec &working_dir, int *status_ptr,
  180. int *signo_ptr, std::string *command_output,
  181. const Timeout<std::micro> &timeout,
  182. bool run_in_shell = true,
  183. bool hide_stderr = false);
  184. /// Run a shell command.
  185. /// \arg shell Pass an empty string if you want to use the default shell
  186. /// interpreter \arg command \arg working_dir Pass empty FileSpec to use the
  187. /// current working directory \arg status_ptr Pass NULL if you don't want
  188. /// the process exit status \arg signo_ptr Pass NULL if you don't want the
  189. /// signal that caused
  190. /// the process to exit
  191. /// \arg command_output Pass NULL if you don't want the command output
  192. /// \arg hide_stderr If this is \b false, redirect stderr to stdout
  193. static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
  194. const FileSpec &working_dir, int *status_ptr,
  195. int *signo_ptr, std::string *command_output,
  196. const Timeout<std::micro> &timeout,
  197. bool run_in_shell = true,
  198. bool hide_stderr = false);
  199. /// Run a shell command.
  200. /// \arg working_dir Pass empty FileSpec to use the current working directory
  201. /// \arg status_ptr Pass NULL if you don't want the process exit status
  202. /// \arg signo_ptr Pass NULL if you don't want the signal that caused the
  203. /// process to exit
  204. /// \arg command_output Pass NULL if you don't want the command output
  205. /// \arg hide_stderr if this is false, redirect stderr to stdout
  206. static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
  207. int *status_ptr, int *signo_ptr,
  208. std::string *command_output,
  209. const Timeout<std::micro> &timeout,
  210. bool run_in_shell = true,
  211. bool hide_stderr = false);
  212. /// Run a shell command.
  213. /// \arg shell Pass an empty string if you want to use the default
  214. /// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use
  215. /// the current working directory \arg status_ptr Pass NULL if you don't
  216. /// want the process exit status \arg signo_ptr Pass NULL if you don't
  217. /// want the signal that caused the
  218. /// process to exit
  219. /// \arg command_output Pass NULL if you don't want the command output
  220. /// \arg hide_stderr If this is \b false, redirect stderr to stdout
  221. static Status RunShellCommand(llvm::StringRef shell, const Args &args,
  222. const FileSpec &working_dir, int *status_ptr,
  223. int *signo_ptr, std::string *command_output,
  224. const Timeout<std::micro> &timeout,
  225. bool run_in_shell = true,
  226. bool hide_stderr = false);
  227. static bool OpenFileInExternalEditor(const FileSpec &file_spec,
  228. uint32_t line_no);
  229. static Environment GetEnvironment();
  230. static std::unique_ptr<Connection>
  231. CreateDefaultConnection(llvm::StringRef url);
  232. protected:
  233. static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
  234. ProcessInstanceInfoList &proc_infos);
  235. };
  236. } // namespace lldb_private
  237. namespace llvm {
  238. template <> struct format_provider<lldb_private::WaitStatus> {
  239. /// Options = "" gives a human readable description of the status Options =
  240. /// "g" gives a gdb-remote protocol status (e.g., X09)
  241. static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
  242. llvm::StringRef Options);
  243. };
  244. } // namespace llvm
  245. #endif // LLDB_HOST_HOST_H