diff options
Diffstat (limited to 'include/lldb/Target/Process.h')
-rw-r--r-- | include/lldb/Target/Process.h | 550 |
1 files changed, 317 insertions, 233 deletions
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index f75b3cd5683d..2e063c5bbccc 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -17,8 +17,10 @@ // C++ Includes #include <list> -#include <iosfwd> +#include <memory> +#include <string> #include <vector> +#include <unordered_set> // Other libraries and framework includes // Project includes @@ -55,11 +57,10 @@ struct Range; class ProcessProperties : public Properties { public: - // Pass NULL for "process" if the ProcessProperties are to be the global copy + // Pass nullptr for "process" if the ProcessProperties are to be the global copy ProcessProperties (lldb_private::Process *process); - virtual - ~ProcessProperties(); + ~ProcessProperties() override; bool GetDisableMemoryCache() const; @@ -103,12 +104,14 @@ public: void SetDetachKeepsStopped (bool keep_stopped); -protected: + bool + GetWarningsOptimization () const; +protected: static void OptionValueChangedCallback (void *baton, OptionValue *option_value); - Process * m_process; // Can be NULL for global ProcessProperties + Process * m_process; // Can be nullptr for global ProcessProperties }; typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP; @@ -236,7 +239,8 @@ public: m_wait_for_launch (false), m_ignore_existing (true), m_continue_once_attached (false), - m_detach_on_error (true) + m_detach_on_error (true), + m_async (false) { } @@ -249,7 +253,8 @@ public: m_wait_for_launch (false), m_ignore_existing (true), m_continue_once_attached (false), - m_detach_on_error(true) + m_detach_on_error (true), + m_async (false) { ProcessInfo::operator= (launch_info); SetProcessPluginName (launch_info.GetProcessPluginName()); @@ -272,6 +277,18 @@ public: } bool + GetAsync () const + { + return m_async; + } + + void + SetAsync (bool b) + { + m_async = b; + } + + bool GetIgnoreExisting () const { return m_ignore_existing; @@ -310,9 +327,7 @@ public: const char * GetProcessPluginName () const { - if (m_plugin_name.empty()) - return NULL; - return m_plugin_name.c_str(); + return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str()); } void @@ -384,7 +399,6 @@ public: m_listener_sp = listener_sp; } - Listener & GetListenerForProcess (Debugger &debugger); @@ -397,35 +411,33 @@ protected: bool m_ignore_existing; bool m_continue_once_attached; // Supports the use-case scenario of immediately continuing the process once attached. bool m_detach_on_error; // If we are debugging remotely, instruct the stub to detach rather than killing the target on error. + bool m_async; // Use an async attach where we start the attach and return immediately (used by GUI programs with --waitfor so they can call SBProcess::Stop() to cancel attach) }; class ProcessLaunchCommandOptions : public Options { public: - ProcessLaunchCommandOptions (CommandInterpreter &interpreter) : Options(interpreter) { // Keep default values of all options in one place: OptionParsingStarting () OptionParsingStarting (); } - - ~ProcessLaunchCommandOptions () - { - } - + + ~ProcessLaunchCommandOptions() override = default; + Error - SetOptionValue (uint32_t option_idx, const char *option_arg); + SetOptionValue (uint32_t option_idx, const char *option_arg) override; void - OptionParsingStarting () + OptionParsingStarting() override { launch_info.Clear(); disable_aslr = eLazyBoolCalculate; } const OptionDefinition* - GetDefinitions () + GetDefinitions() override { return g_option_table; } @@ -521,11 +533,8 @@ protected: class ProcessInstanceInfoList { public: - ProcessInstanceInfoList () : - m_infos() - { - } - + ProcessInstanceInfoList() = default; + void Clear() { @@ -547,25 +556,19 @@ public: const char * GetProcessNameAtIndex (size_t idx) { - if (idx < m_infos.size()) - return m_infos[idx].GetName(); - return NULL; + return ((idx < m_infos.size()) ? m_infos[idx].GetName() : nullptr); } size_t GetProcessNameLengthAtIndex (size_t idx) { - if (idx < m_infos.size()) - return m_infos[idx].GetNameLength(); - return 0; + return ((idx < m_infos.size()) ? m_infos[idx].GetNameLength() : 0); } lldb::pid_t GetProcessIDAtIndex (size_t idx) { - if (idx < m_infos.size()) - return m_infos[idx].GetProcessID(); - return 0; + return ((idx < m_infos.size()) ? m_infos[idx].GetProcessID() : 0); } bool @@ -592,7 +595,6 @@ protected: collection m_infos; }; - // This class tracks the Modification state of the process. Things that can currently modify // the program are running the program (which will up the StopID) and writing memory (which // will up the MemoryID.) @@ -600,7 +602,7 @@ protected: class ProcessModID { -friend bool operator== (const ProcessModID &lhs, const ProcessModID &rhs); + friend bool operator== (const ProcessModID &lhs, const ProcessModID &rhs); public: ProcessModID () : m_stop_id (0), @@ -626,7 +628,7 @@ public: return *this; } - ~ProcessModID () {} + ~ProcessModID() = default; void BumpStopID () { m_stop_id++; @@ -709,6 +711,7 @@ private: uint32_t m_running_user_expression; lldb::EventSP m_last_natural_stop_event; }; + inline bool operator== (const ProcessModID &lhs, const ProcessModID &rhs) { if (lhs.StopIDEqual (rhs) @@ -720,11 +723,7 @@ inline bool operator== (const ProcessModID &lhs, const ProcessModID &rhs) inline bool operator!= (const ProcessModID &lhs, const ProcessModID &rhs) { - if (!lhs.StopIDEqual (rhs) - || !lhs.MemoryIDEqual (rhs)) - return true; - else - return false; + return (!lhs.StopIDEqual (rhs) || !lhs.MemoryIDEqual (rhs)); } //---------------------------------------------------------------------- @@ -739,7 +738,7 @@ class Process : public ExecutionContextScope, public PluginInterface { - friend class ClangFunction; // For WaitForStateChangeEventsPrivate + friend class FunctionCaller; // For WaitForStateChangeEventsPrivate friend class Debugger; // For PopProcessIOHandler and ProcessIOHandlerIsActive friend class ProcessEventData; friend class StopInfo; @@ -747,7 +746,6 @@ class Process : friend class ThreadList; public: - //------------------------------------------------------------------ /// Broadcaster event bits definitions. //------------------------------------------------------------------ @@ -766,6 +764,14 @@ public: eBroadcastInternalStateControlPause = (1<<1), eBroadcastInternalStateControlResume = (1<<2) }; + + //------------------------------------------------------------------ + /// Process warning types. + //------------------------------------------------------------------ + enum Warnings + { + eWarningsOptimization = 1 + }; typedef Range<lldb::addr_t, lldb::addr_t> LoadRange; // We use a read/write lock to allow on or more clients to @@ -781,12 +787,11 @@ public: static ConstString &GetStaticBroadcasterClass (); - virtual ConstString &GetBroadcasterClass() const + ConstString &GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } - //------------------------------------------------------------------ /// A notification structure that can be used by clients to listen /// for changes in a process's lifetime. @@ -811,13 +816,13 @@ public: ProcessEventData (); ProcessEventData (const lldb::ProcessSP &process, lldb::StateType state); - virtual ~ProcessEventData(); + ~ProcessEventData() override; static const ConstString & GetFlavorString (); - virtual const ConstString & - GetFlavor () const; + const ConstString & + GetFlavor() const override; lldb::ProcessSP GetProcessSP() const @@ -845,10 +850,7 @@ public: const char * GetRestartedReasonAtIndex(size_t idx) { - if (idx > m_restarted_reasons.size()) - return NULL; - else - return m_restarted_reasons[idx].c_str(); + return ((idx < m_restarted_reasons.size()) ? m_restarted_reasons[idx].c_str() : nullptr); } bool @@ -857,11 +859,11 @@ public: return m_interrupted; } - virtual void - Dump (Stream *s) const; + void + Dump(Stream *s) const override; - virtual void - DoOnRemoval (Event *event_ptr); + void + DoOnRemoval(Event *event_ptr) override; static const Process::ProcessEventData * GetEventDataFromEvent (const Event *event_ptr); @@ -897,22 +899,24 @@ public: SetUpdateStateOnRemoval (Event *event_ptr); private: - void SetUpdateStateOnRemoval() { m_update_state++; } + void SetRestarted (bool new_value) { m_restarted = new_value; } + void SetInterrupted (bool new_value) { m_interrupted = new_value; } + void AddRestartedReason (const char *reason) { @@ -925,32 +929,22 @@ public: bool m_restarted; // For "eStateStopped" events, this is true if the target was automatically restarted. int m_update_state; bool m_interrupted; - DISALLOW_COPY_AND_ASSIGN (ProcessEventData); + DISALLOW_COPY_AND_ASSIGN (ProcessEventData); }; - -#endif - - static void - SettingsInitialize (); - - static void - SettingsTerminate (); - - static const ProcessPropertiesSP & - GetGlobalProperties(); +#endif // SWIG //------------------------------------------------------------------ /// Construct with a shared pointer to a target, and the Process listener. /// Uses the Host UnixSignalsSP by default. //------------------------------------------------------------------ - Process(Target &target, Listener &listener); + Process(lldb::TargetSP target_sp, Listener &listener); //------------------------------------------------------------------ /// Construct with a shared pointer to a target, the Process listener, /// and the appropriate UnixSignalsSP for the process. //------------------------------------------------------------------ - Process(Target &target, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp); + Process(lldb::TargetSP target_sp, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp); //------------------------------------------------------------------ /// Destructor. @@ -958,8 +952,16 @@ public: /// The destructor is virtual since this class is designed to be /// inherited from by the plug-in instance. //------------------------------------------------------------------ - virtual - ~Process(); + ~Process() override; + + static void + SettingsInitialize (); + + static void + SettingsTerminate (); + + static const ProcessPropertiesSP & + GetGlobalProperties(); //------------------------------------------------------------------ /// Find a Process plug-in that can debug \a module using the @@ -973,20 +975,18 @@ public: /// The module shared pointer that this process will debug. /// /// @param[in] plugin_name - /// If NULL, select the best plug-in for the binary. If non-NULL + /// If nullptr, select the best plug-in for the binary. If non-nullptr /// then look for a plugin whose PluginInfo's name matches /// this string. /// /// @see Process::CanDebug () //------------------------------------------------------------------ static lldb::ProcessSP - FindPlugin (Target &target, + FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path); - - //------------------------------------------------------------------ /// Static function that can be used with the \b host function /// Host::StartMonitoringChildProcess (). @@ -997,16 +997,16 @@ public: /// Subclasses should call Host::StartMonitoringChildProcess () /// with: /// callback = Process::SetHostProcessExitStatus - /// callback_baton = NULL + /// callback_baton = nullptr /// pid = Process::GetID() /// monitor_signals = false //------------------------------------------------------------------ static bool - SetProcessExitStatus (void *callback_baton, // The callback baton which should be set to NULL - lldb::pid_t pid, // The process ID we want to monitor - bool exited, - int signo, // Zero for no signal - int status); // Exit value of process if signal is zero + SetProcessExitStatus(void *callback_baton, // The callback baton which should be set to nullptr + lldb::pid_t pid, // The process ID we want to monitor + bool exited, + int signo, // Zero for no signal + int status); // Exit value of process if signal is zero lldb::ByteOrder GetByteOrder () const; @@ -1019,6 +1019,7 @@ public: { return m_process_unique_id; } + //------------------------------------------------------------------ /// Check if a plug-in instance can debug the file in \a module. /// @@ -1031,10 +1032,9 @@ public: /// debug the executable, \b false otherwise. //------------------------------------------------------------------ virtual bool - CanDebug (Target &target, + CanDebug (lldb::TargetSP target, bool plugin_specified_by_name) = 0; - //------------------------------------------------------------------ /// This object is about to be destroyed, do any necessary cleanup. /// @@ -1043,8 +1043,7 @@ public: //------------------------------------------------------------------ virtual void Finalize(); - - + //------------------------------------------------------------------ /// Return whether this object is valid (i.e. has not been finalized.) /// @@ -1075,7 +1074,7 @@ public: virtual CommandObject * GetPluginCommandObject() { - return NULL; + return nullptr; } //------------------------------------------------------------------ @@ -1163,7 +1162,7 @@ public: /// /// @return /// Returns a pointer to the SystemRuntime plugin for this Process - /// if one is available. Else returns NULL. + /// if one is available. Else returns nullptr. //------------------------------------------------------------------ virtual SystemRuntime * GetSystemRuntime (); @@ -1194,7 +1193,7 @@ public: /// @param[in] strm /// A stream where output intended for the user /// (if the driver has a way to display that) generated during - /// the connection. This may be NULL if no output is needed.A + /// the connection. This may be nullptr if no output is needed.A /// /// @param[in] remote_url /// The URL format that we are connecting to. @@ -1236,31 +1235,24 @@ public: GetImageInfoAddress (); //------------------------------------------------------------------ - /// Load a shared library into this process. - /// - /// Try and load a shared library into the current process. This - /// call might fail in the dynamic loader plug-in says it isn't safe - /// to try and load shared libraries at the moment. - /// - /// @param[in] image_spec - /// The image file spec that points to the shared library that - /// you want to load. + /// Called when the process is about to broadcast a public stop. /// - /// @param[out] error - /// An error object that gets filled in with any errors that - /// might occur when trying to load the shared library. - /// - /// @return - /// A token that represents the shared library that can be - /// later used to unload the shared library. A value of - /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared - /// library can't be opened. + /// There are public and private stops. Private stops are when the + /// process is doing things like stepping and the client doesn't + /// need to know about starts and stop that implement a thread plan. + /// Single stepping over a source line in code might end up being + /// implemented by one or more process starts and stops. Public stops + /// are when clients will be notified that the process is stopped. + /// These events typically trigger UI updates (thread stack frames to + /// be displayed, variables to be displayed, and more). This function + /// can be overriden and allows process subclasses to do something + /// before the eBroadcastBitStateChanged event is sent to public + /// clients. //------------------------------------------------------------------ - virtual uint32_t - LoadImage (const FileSpec &image_spec, Error &error); - - virtual Error - UnloadImage (uint32_t image_token); + virtual void + WillPublicStop () + { + } //------------------------------------------------------------------ /// Register for process and thread notifications. @@ -1278,6 +1270,7 @@ public: void RegisterNotificationCallbacks (const Process::Notifications& callbacks); #endif + //------------------------------------------------------------------ /// Unregister for process and thread notifications. /// @@ -1298,6 +1291,7 @@ public: bool UnregisterNotificationCallbacks (const Process::Notifications& callbacks); #endif + //================================================================== // Built in Process Control functions //================================================================== @@ -1334,6 +1328,7 @@ public: Error ResumeSynchronous (Stream *stream); + //------------------------------------------------------------------ /// Halts a running process. /// @@ -1346,12 +1341,15 @@ public: /// @param[in] clear_thread_plans /// If true, when the process stops, clear all thread plans. /// + /// @param[in] use_run_lock + /// Whether to release the run lock after the stop. + /// /// @return /// Returns an error object. If the error is empty, the process is halted. /// otherwise the halt has failed. //------------------------------------------------------------------ Error - Halt (bool clear_thread_plans = false); + Halt (bool clear_thread_plans = false, bool use_run_lock = true); //------------------------------------------------------------------ /// Detaches from a running or stopped process. @@ -1402,7 +1400,7 @@ public: Signal (int signal); void - SetUnixSignals(const lldb::UnixSignalsSP &signals_sp); + SetUnixSignals(lldb::UnixSignalsSP &&signals_sp); const lldb::UnixSignalsSP & GetUnixSignals(); @@ -1447,7 +1445,7 @@ public: /// @param[in] strm /// A stream where output intended for the user /// (if the driver has a way to display that) generated during - /// the connection. This may be NULL if no output is needed.A + /// the connection. This may be nullptr if no output is needed.A /// /// @param[in] remote_url /// The URL format that we are connecting to. @@ -1525,7 +1523,6 @@ public: process_arch.Clear(); } - //------------------------------------------------------------------ /// Called after a process re-execs itself. /// @@ -1590,7 +1587,6 @@ public: return error; } - //------------------------------------------------------------------ /// Called after launching a process. /// @@ -1600,8 +1596,6 @@ public: virtual void DidLaunch () {} - - //------------------------------------------------------------------ /// Called before resuming to a process. /// @@ -1639,7 +1633,6 @@ public: return error; } - //------------------------------------------------------------------ /// Called after resuming a process. /// @@ -1649,7 +1642,6 @@ public: virtual void DidResume () {} - //------------------------------------------------------------------ /// Called before halting to a process. /// @@ -1668,9 +1660,8 @@ public: /// DoHalt must produce one and only one stop StateChanged event if it actually /// stops the process. If the stop happens through some natural event (for /// instance a SIGSTOP), then forwarding that event will do. Otherwise, you must - /// generate the event manually. Note also, the private event thread is stopped when - /// DoHalt is run to prevent the events generated while halting to trigger - /// other state changes before the halt is complete. + /// generate the event manually. This function is called from the context of the + /// private state thread. /// /// @param[out] caused_stop /// If true, then this Halt caused the stop, otherwise, the @@ -1688,7 +1679,6 @@ public: return error; } - //------------------------------------------------------------------ /// Called after halting a process. /// @@ -1728,7 +1718,6 @@ public: return error; } - //------------------------------------------------------------------ /// Called after detaching from a process. /// @@ -1781,7 +1770,6 @@ public: virtual bool DestroyRequiresHalt() { return true; } - //------------------------------------------------------------------ /// Called after sending a signal to a process. /// @@ -1808,6 +1796,41 @@ public: RefreshStateAfterStop () = 0; //------------------------------------------------------------------ + /// Sometimes the connection to a process can detect the host OS + /// version that the process is running on. The current platform + /// should be checked first in case the platform is connected, but + /// clients can fall back onto this function if the platform fails + /// to identify the host OS version. The platform should be checked + /// first in case you are running a simulator platform that might + /// itself be running natively, but have different heuristics for + /// figuring out which OS is is emulating. + /// + /// @param[out] major + /// The major OS version, or UINT32_MAX if it can't be determined + /// + /// @param[out] minor + /// The minor OS version, or UINT32_MAX if it can't be determined + /// + /// @param[out] update + /// The update OS version, or UINT32_MAX if it can't be determined + /// + /// @return + /// Returns \b true if the host OS version info was filled in + /// and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + GetHostOSVersion(uint32_t &major, + uint32_t &minor, + uint32_t &update) + { + major = UINT32_MAX; + minor = UINT32_MAX; + update = UINT32_MAX; + return false; + } + + + //------------------------------------------------------------------ /// Get the target object pointer for this module. /// /// @return @@ -1817,7 +1840,7 @@ public: Target & GetTarget () { - return m_target; + return *m_target_sp.lock(); } //------------------------------------------------------------------ @@ -1830,7 +1853,7 @@ public: const Target & GetTarget () const { - return m_target; + return *m_target_sp.lock(); } //------------------------------------------------------------------ @@ -1888,7 +1911,6 @@ public: virtual void ModulesDidLoad (ModuleList &module_list); - //------------------------------------------------------------------ /// Retrieve the list of shared libraries that are loaded for this process /// @@ -1919,30 +1941,20 @@ public: return StructuredData::ObjectSP(); } -protected: - - void - SetState (lldb::EventSP &event_sp); - - lldb::StateType - GetPrivateState (); - //------------------------------------------------------------------ - /// The "private" side of resuming a process. This doesn't alter the - /// state of m_run_lock, but just causes the process to resume. + /// Print a user-visible warning about a module being built with optimization /// - /// @return - /// An Error object describing the success or failure of the resume. - //------------------------------------------------------------------ - Error - PrivateResume (); - - //------------------------------------------------------------------ - // Called internally + /// Prints a async warning message to the user one time per Module + /// where a function is found that was compiled with optimization, per + /// Process. + /// + /// @param [in] sc + /// A SymbolContext with eSymbolContextFunction and eSymbolContextModule + /// pre-computed. //------------------------------------------------------------------ void - CompleteAttach (); - + PrintWarningOptimization (const SymbolContext &sc); + public: //------------------------------------------------------------------ /// Get the exit status for a process. @@ -1958,13 +1970,12 @@ public: /// Get a textual description of what the process exited. /// /// @return - /// The textual description of why the process exited, or NULL + /// The textual description of why the process exited, or nullptr /// if there is no description available. //------------------------------------------------------------------ const char * GetExitDescription (); - virtual void DidExit () { @@ -2045,7 +2056,7 @@ public: /// otherwise. //------------------------------------------------------------------ virtual bool - IsAlive () = 0; + IsAlive (); //------------------------------------------------------------------ /// Before lldb detaches from a process, it warns the user that they are about to lose their debug session. @@ -2255,7 +2266,6 @@ public: return 0; } - //------------------------------------------------------------------ /// Write all or part of a scalar value to memory. /// @@ -2329,7 +2339,6 @@ public: size_t WriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error); - //------------------------------------------------------------------ /// Actually allocate memory in the process. /// @@ -2352,7 +2361,6 @@ public: return LLDB_INVALID_ADDRESS; } - //------------------------------------------------------------------ /// The public interface to allocating memory in the process. /// @@ -2369,16 +2377,41 @@ public: /// that a block that isn't set writable can still be written on from lldb, /// just not by the process itself. /// - /// @param[in/out] error + /// @param[in,out] error /// An error object to fill in if things go wrong. /// @return /// The address of the allocated buffer in the process, or /// LLDB_INVALID_ADDRESS if the allocation failed. //------------------------------------------------------------------ - lldb::addr_t AllocateMemory (size_t size, uint32_t permissions, Error &error); + //------------------------------------------------------------------ + /// The public interface to allocating memory in the process, this also + /// clears the allocated memory. + /// + /// This function will allocate memory in the process's address + /// space. This can't rely on the generic function calling mechanism, + /// since that requires this function. + /// + /// @param[in] size + /// The size of the allocation requested. + /// + /// @param[in] permissions + /// Or together any of the lldb::Permissions bits. The permissions on + /// a given memory allocation can't be changed after allocation. Note + /// that a block that isn't set writable can still be written on from lldb, + /// just not by the process itself. + /// + /// @param[in/out] error + /// An error object to fill in if things go wrong. + /// @return + /// The address of the allocated buffer in the process, or + /// LLDB_INVALID_ADDRESS if the allocation failed. + //------------------------------------------------------------------ + + lldb::addr_t + CallocateMemory (size_t size, uint32_t permissions, Error &error); //------------------------------------------------------------------ /// Resolve dynamically loaded indirect functions. @@ -2393,7 +2426,6 @@ public: /// The address of the resolved function. /// LLDB_INVALID_ADDRESS if the resolution failed. //------------------------------------------------------------------ - virtual lldb::addr_t ResolveIndirectFunction(const Address *address, Error &error); @@ -2518,7 +2550,6 @@ public: /// @return /// \btrue if the memory was deallocated, \bfalse otherwise. //------------------------------------------------------------------ - virtual Error DoDeallocateMemory (lldb::addr_t ptr) { @@ -2527,7 +2558,6 @@ public: return error; } - //------------------------------------------------------------------ /// The public interface to deallocating memory in the process. /// @@ -2541,7 +2571,6 @@ public: /// @return /// \btrue if the memory was deallocated, \bfalse otherwise. //------------------------------------------------------------------ - Error DeallocateMemory (lldb::addr_t ptr); @@ -2671,7 +2700,6 @@ public: return error; } - virtual Error DisableBreakpointSite (BreakpointSite *bp_site) { @@ -2680,7 +2708,6 @@ public: return error; } - // This is implemented completely using the lldb::Process API. Subclasses // don't need to implement this function unless the standard flow of // read existing opcode, write breakpoint opcode, verify breakpoint opcode @@ -2717,7 +2744,6 @@ public: Error EnableBreakpointSiteByID (lldb::user_id_t break_id); - // BreakpointLocations use RemoveOwnerFromBreakpointSite to remove // themselves from the owner's list of this breakpoint sites. void @@ -2811,12 +2837,16 @@ public: // Returns the process state when it is stopped. If specified, event_sp_ptr // is set to the event which triggered the stop. If wait_always = false, // and the process is already stopped, this function returns immediately. + // If the process is hijacked and use_run_lock is true (the default), then this + // function releases the run lock after the stop. Setting use_run_lock to false + // will avoid this behavior. lldb::StateType - WaitForProcessToStop (const TimeValue *timeout, - lldb::EventSP *event_sp_ptr = NULL, - bool wait_always = true, - Listener *hijack_listener = NULL, - Stream *stream = NULL); + WaitForProcessToStop(const TimeValue *timeout, + lldb::EventSP *event_sp_ptr = nullptr, + bool wait_always = true, + Listener *hijack_listener = nullptr, + Stream *stream = nullptr, + bool use_run_lock = true); uint32_t GetIOHandlerID () const @@ -2838,9 +2868,9 @@ public: SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec); lldb::StateType - WaitForStateChangedEvents (const TimeValue *timeout, - lldb::EventSP &event_sp, - Listener *hijack_listener); // Pass NULL to use builtin listener + WaitForStateChangedEvents(const TimeValue *timeout, + lldb::EventSP &event_sp, + Listener *hijack_listener); // Pass nullptr to use builtin listener //-------------------------------------------------------------------------------------- /// Centralize the code that handles and prints descriptions for process state changes. @@ -2851,7 +2881,7 @@ public: /// @param[in] stream /// The output stream to get the state change description /// - /// @param[inout] pop_process_io_handler + /// @param[in,out] pop_process_io_handler /// If this value comes in set to \b true, then pop the Process IOHandler if needed. /// Else this variable will be set to \b true or \b false to indicate if the process /// needs to have its process IOHandler popped. @@ -2863,9 +2893,9 @@ public: HandleProcessStateChangedEvent (const lldb::EventSP &event_sp, Stream *stream, bool &pop_process_io_handler); + Event * PeekAtStateChangedEvents (); - class ProcessEventHijacker @@ -2876,6 +2906,7 @@ public: { m_process.HijackProcessEvents (listener); } + ~ProcessEventHijacker () { m_process.RestoreProcessEvents(); @@ -2884,6 +2915,7 @@ public: private: Process &m_process; }; + friend class ProcessEventHijacker; friend class ProcessProperties; //------------------------------------------------------------------ @@ -2910,27 +2942,6 @@ public: void RestoreProcessEvents (); -private: - //------------------------------------------------------------------ - /// This is the part of the event handling that for a process event. - /// It decides what to do with the event and returns true if the - /// event needs to be propagated to the user, and false otherwise. - /// If the event is not propagated, this call will most likely set - /// the target to executing again. - /// There is only one place where this call should be called, HandlePrivateEvent. - /// Don't call it from anywhere else... - /// - /// @param[in] event_ptr - /// This is the event we are handling. - /// - /// @return - /// Returns \b true if the event should be reported to the - /// user, \b false otherwise. - //------------------------------------------------------------------ - bool - ShouldBroadcastEvent (Event *event_ptr); - -public: const lldb::ABISP & GetABI (); @@ -3004,29 +3015,29 @@ public: //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ - virtual lldb::TargetSP - CalculateTarget (); + lldb::TargetSP + CalculateTarget() override; - virtual lldb::ProcessSP - CalculateProcess () + lldb::ProcessSP + CalculateProcess() override { return shared_from_this(); } - virtual lldb::ThreadSP - CalculateThread () + lldb::ThreadSP + CalculateThread() override { return lldb::ThreadSP(); } - virtual lldb::StackFrameSP - CalculateStackFrame () + lldb::StackFrameSP + CalculateStackFrame() override { return lldb::StackFrameSP(); } - virtual void - CalculateExecutionContext (ExecutionContext &exe_ctx); + void + CalculateExecutionContext(ExecutionContext &exe_ctx) override; void SetSTDIOFileDescriptor (int file_descriptor); @@ -3129,9 +3140,70 @@ public: return Error("Not supported"); } + size_t + AddImageToken(lldb::addr_t image_ptr); + + lldb::addr_t + GetImagePtrFromToken(size_t token) const; + + void + ResetImageToken(size_t token); + protected: + void + SetState (lldb::EventSP &event_sp); + + lldb::StateType + GetPrivateState (); + + //------------------------------------------------------------------ + /// The "private" side of resuming a process. This doesn't alter the + /// state of m_run_lock, but just causes the process to resume. + /// + /// @return + /// An Error object describing the success or failure of the resume. + //------------------------------------------------------------------ + Error + PrivateResume (); //------------------------------------------------------------------ + // Called internally + //------------------------------------------------------------------ + void + CompleteAttach (); + + //------------------------------------------------------------------ + /// Print a user-visible warning one time per Process + /// + /// A facility for printing a warning to the user once per repeat_key. + /// + /// warning_type is from the Process::Warnings enums. + /// repeat_key is a pointer value that will be used to ensure that the + /// warning message is not printed multiple times. For instance, with a + /// warning about a function being optimized, you can pass the CompileUnit + /// pointer to have the warning issued for only the first function in a + /// CU, or the Function pointer to have it issued once for every function, + /// or a Module pointer to have it issued once per Module. + /// + /// Classes outside Process should call a specific PrintWarning method + /// so that the warning strings are all centralized in Process, instead of + /// calling PrintWarning() directly. + /// + /// @param [in] warning_type + /// One of the types defined in Process::Warnings. + /// + /// @param [in] repeat_key + /// A pointer value used to ensure that the warning is only printed once. + /// May be nullptr, indicating that the warning is printed unconditionally + /// every time. + /// + /// @param [in] fmt + /// printf style format string + //------------------------------------------------------------------ + void + PrintWarning (uint64_t warning_type, const void *repeat_key, const char *fmt, ...) __attribute__((format(printf, 4, 5))); + + //------------------------------------------------------------------ // NextEventAction provides a way to register an action on the next // event that is delivered to this process. There is currently only // one next event action allowed in the process at one time. If a @@ -3158,10 +3230,8 @@ protected: } virtual - ~NextEventAction() - { - } - + ~NextEventAction() = default; + virtual EventActionResult PerformAction (lldb::EventSP &event_sp) = 0; virtual void HandleBeingUnshipped () {} virtual EventActionResult HandleBeingInterrupted () = 0; @@ -3170,6 +3240,7 @@ protected: { m_process->m_resume_requested = true; } + protected: Process *m_process; }; @@ -3188,25 +3259,17 @@ protected: public: AttachCompletionHandler (Process *process, uint32_t exec_count); - virtual - ~AttachCompletionHandler() - { - } - - virtual EventActionResult PerformAction (lldb::EventSP &event_sp); - virtual EventActionResult HandleBeingInterrupted (); - virtual const char *GetExitString(); + ~AttachCompletionHandler() override = default; + + EventActionResult PerformAction(lldb::EventSP &event_sp) override; + EventActionResult HandleBeingInterrupted() override; + const char *GetExitString() override; + private: uint32_t m_exec_count; std::string m_exit_string; }; - bool - HijackPrivateProcessEvents (Listener *listener); - - void - RestorePrivateProcessEvents (); - bool PrivateStateThreadIsValid () const { @@ -3223,6 +3286,8 @@ protected: // Type definitions //------------------------------------------------------------------ typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection; + typedef std::unordered_set<const void *> WarningsPointerSet; + typedef std::map<uint64_t, WarningsPointerSet> WarningsCollection; struct PreResumeCallbackAndBaton { @@ -3238,7 +3303,7 @@ protected: //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ - Target & m_target; ///< The target that owns this process. + std::weak_ptr<Target> m_target_sp; ///< The target that owns this process. ThreadSafeValue<lldb::StateType> m_public_state; ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process Broadcaster m_private_state_broadcaster; // This broadcaster feeds state changed events into the private state thread's listener. @@ -3290,7 +3355,6 @@ protected: std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions; ProcessRunLock m_public_run_lock; ProcessRunLock m_private_run_lock; - Predicate<bool> m_currently_handling_event; // This predicate is set in HandlePrivateEvent while all its business is being done. ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback; bool m_currently_handling_do_on_removals; bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check. @@ -3302,6 +3366,7 @@ protected: std::map<lldb::addr_t,lldb::addr_t> m_resolved_indirect_addresses; bool m_destroy_in_process; bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, don't support the ability to modify the stack. + WarningsCollection m_warnings_issued; // A set of object pointers which have already had warnings printed enum { eCanJITDontKnow= 0, @@ -3353,6 +3418,9 @@ protected: void HandlePrivateEvent (lldb::EventSP &event_sp); + Error + HaltPrivate(); + lldb::StateType WaitForProcessStopPrivate (const TimeValue *timeout, lldb::EventSP &event_sp); @@ -3401,23 +3469,39 @@ protected: } Error - HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp); + StopForDestroyOrDetach(lldb::EventSP &exit_event_sp); bool StateChangedIsExternallyHijacked(); void LoadOperatingSystemPlugin(bool flush); + private: //------------------------------------------------------------------ - // For Process only + /// This is the part of the event handling that for a process event. + /// It decides what to do with the event and returns true if the + /// event needs to be propagated to the user, and false otherwise. + /// If the event is not propagated, this call will most likely set + /// the target to executing again. + /// There is only one place where this call should be called, HandlePrivateEvent. + /// Don't call it from anywhere else... + /// + /// @param[in] event_ptr + /// This is the event we are handling. + /// + /// @return + /// Returns \b true if the event should be reported to the + /// user, \b false otherwise. //------------------------------------------------------------------ + bool + ShouldBroadcastEvent (Event *event_ptr); + void ControlPrivateStateThread (uint32_t signal); DISALLOW_COPY_AND_ASSIGN (Process); - }; } // namespace lldb_private -#endif // liblldb_Process_h_ +#endif // liblldb_Process_h_ |