diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /lldb/include/lldb | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
download | src-344a3780b2e33f6ca763666c380202b18aab72a3.tar.gz src-344a3780b2e33f6ca763666c380202b18aab72a3.zip |
Vendor import of llvm-project main 88e66fa60ae5, the last commit beforevendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
the upstream release/13.x branch was created.
Diffstat (limited to 'lldb/include/lldb')
281 files changed, 3982 insertions, 2443 deletions
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index f7390cfabf01..eacbbeafcf1c 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -65,7 +65,6 @@ #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBThreadPlan.h" #include "lldb/API/SBTrace.h" -#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBType.h" #include "lldb/API/SBTypeCategory.h" #include "lldb/API/SBTypeEnumMember.h" diff --git a/lldb/include/lldb/API/SBBlock.h b/lldb/include/lldb/API/SBBlock.h index be1ae18e9db5..2570099f7652 100644 --- a/lldb/include/lldb/API/SBBlock.h +++ b/lldb/include/lldb/API/SBBlock.h @@ -87,7 +87,7 @@ private: void AppendVariables(bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list); - lldb_private::Block *m_opaque_ptr; + lldb_private::Block *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBBroadcaster.h b/lldb/include/lldb/API/SBBroadcaster.h index 69a516a8bfb1..046473d4223b 100644 --- a/lldb/include/lldb/API/SBBroadcaster.h +++ b/lldb/include/lldb/API/SBBroadcaster.h @@ -63,6 +63,7 @@ public: protected: friend class SBCommandInterpreter; friend class SBCommunication; + friend class SBDebugger; friend class SBEvent; friend class SBListener; friend class SBProcess; @@ -76,7 +77,7 @@ protected: private: lldb::BroadcasterSP m_opaque_sp; - lldb_private::Broadcaster *m_opaque_ptr; + lldb_private::Broadcaster *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h b/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h index 3c00513faaa7..efaacd39eb0f 100644 --- a/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h +++ b/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h @@ -56,6 +56,10 @@ public: void SetPrintResults(bool); + bool GetPrintErrors() const; + + void SetPrintErrors(bool); + bool GetAddToHistory() const; void SetAddToHistory(bool); diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h index 4ee296eb1797..5738c911ae12 100644 --- a/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/lldb/include/lldb/API/SBCommandReturnObject.h @@ -9,7 +9,7 @@ #ifndef LLDB_API_SBCOMMANDRETURNOBJECT_H #define LLDB_API_SBCOMMANDRETURNOBJECT_H -#include <stdio.h> +#include <cstdio> #include <memory> @@ -105,9 +105,6 @@ public: void SetError(const char *error_cstr); - // ref() is internal for LLDB only. - lldb_private::CommandReturnObject &ref() const; - protected: friend class SBCommandInterpreter; friend class SBOptions; @@ -119,6 +116,8 @@ protected: lldb_private::CommandReturnObject &operator*() const; private: + lldb_private::CommandReturnObject &ref() const; + std::unique_ptr<lldb_private::SBCommandReturnObjectImpl> m_opaque_up; }; diff --git a/lldb/include/lldb/API/SBCommunication.h b/lldb/include/lldb/API/SBCommunication.h index 84c341c0dfef..e407d859d885 100644 --- a/lldb/include/lldb/API/SBCommunication.h +++ b/lldb/include/lldb/API/SBCommunication.h @@ -75,8 +75,8 @@ private: SBCommunication(const SBCommunication &) = delete; const SBCommunication &operator=(const SBCommunication &) = delete; - lldb_private::Communication *m_opaque; - bool m_opaque_owned; + lldb_private::Communication *m_opaque = nullptr; + bool m_opaque_owned = false; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBCompileUnit.h b/lldb/include/lldb/API/SBCompileUnit.h index 0c05ef44e31c..d965b9d966b9 100644 --- a/lldb/include/lldb/API/SBCompileUnit.h +++ b/lldb/include/lldb/API/SBCompileUnit.h @@ -87,7 +87,7 @@ private: void reset(lldb_private::CompileUnit *lldb_object_ptr); - lldb_private::CompileUnit *m_opaque_ptr; + lldb_private::CompileUnit *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBData.h b/lldb/include/lldb/API/SBData.h index 95c8086d5d47..85c8110e181c 100644 --- a/lldb/include/lldb/API/SBData.h +++ b/lldb/include/lldb/API/SBData.h @@ -11,6 +11,10 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class ScriptInterpreter; +} // namespace lldb_private + namespace lldb { class LLDB_API SBData { @@ -147,6 +151,8 @@ private: friend class SBTarget; friend class SBValue; + friend class lldb_private::ScriptInterpreter; + lldb::DataExtractorSP m_opaque_sp; }; diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index b3bfa230139c..ef62141f579d 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -9,7 +9,7 @@ #ifndef LLDB_API_SBDEBUGGER_H #define LLDB_API_SBDEBUGGER_H -#include <stdio.h> +#include <cstdio> #include "lldb/API/SBDefines.h" #include "lldb/API/SBPlatform.h" @@ -33,6 +33,8 @@ public: class LLDB_API SBDebugger { public: + FLAGS_ANONYMOUS_ENUM(){eBroadcastBitProgress = (1 << 0)}; + SBDebugger(); SBDebugger(const lldb::SBDebugger &rhs); @@ -41,6 +43,42 @@ public: ~SBDebugger(); + static const char *GetBroadcasterClass(); + + lldb::SBBroadcaster GetBroadcaster(); + + /// Get progress data from a SBEvent whose type is eBroadcastBitProgress. + /// + /// \param [in] event + /// The event to extract the progress information from. + /// + /// \param [out] progress_id + /// The unique integer identifier for the progress to report. + /// + /// \param [out] completed + /// The amount of work completed. If \a completed is zero, then this event + /// is a progress started event. If \a completed is equal to \a total, then + /// this event is a progress end event. Otherwise completed indicates the + /// current progress update. + /// + /// \param [out] total + /// The total amount of work units that need to be completed. If this value + /// is UINT64_MAX, then an indeterminate progress indicator should be + /// displayed. + /// + /// \param [out] is_debugger_specific + /// Set to true if this progress is specific to this debugger only. Many + /// progress events are not specific to a debugger instance, like any + /// progress events for loading information in modules since LLDB has a + /// global module cache that all debuggers use. + /// + /// \return The message for the progress. If the returned value is NULL, then + /// \a event was not a eBroadcastBitProgress event. + static const char *GetProgressFromEvent(const lldb::SBEvent &event, + uint64_t &progress_id, + uint64_t &completed, uint64_t &total, + bool &is_debugger_specific); + lldb::SBDebugger &operator=(const lldb::SBDebugger &rhs); static void Initialize(); diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index a5b639c6dc73..3ab10ad8e061 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -76,7 +76,6 @@ class LLDB_API SBThread; class LLDB_API SBThreadCollection; class LLDB_API SBThreadPlan; class LLDB_API SBTrace; -class LLDB_API SBTraceOptions; class LLDB_API SBType; class LLDB_API SBTypeCategory; class LLDB_API SBTypeEnumMember; diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h index e1960ef9a983..f8289e2fcbb3 100644 --- a/lldb/include/lldb/API/SBError.h +++ b/lldb/include/lldb/API/SBError.h @@ -11,6 +11,10 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class ScriptInterpreter; +} // namespace lldb_private + namespace lldb { class LLDB_API SBError { @@ -72,6 +76,8 @@ protected: friend class SBWatchpoint; friend class SBFile; + friend class lldb_private::ScriptInterpreter; + lldb_private::Status *get(); lldb_private::Status *operator->(); diff --git a/lldb/include/lldb/API/SBEvent.h b/lldb/include/lldb/API/SBEvent.h index a7975bf9abae..2ce1b60372b7 100644 --- a/lldb/include/lldb/API/SBEvent.h +++ b/lldb/include/lldb/API/SBEvent.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> #include <vector> namespace lldb { @@ -79,7 +79,7 @@ protected: private: mutable lldb::EventSP m_event_sp; - mutable lldb_private::Event *m_opaque_ptr; + mutable lldb_private::Event *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBExecutionContext.h b/lldb/include/lldb/API/SBExecutionContext.h index d8447aeb1a2f..06ece6fbc0fa 100644 --- a/lldb/include/lldb/API/SBExecutionContext.h +++ b/lldb/include/lldb/API/SBExecutionContext.h @@ -12,7 +12,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> #include <vector> namespace lldb { diff --git a/lldb/include/lldb/API/SBFunction.h b/lldb/include/lldb/API/SBFunction.h index bd643a62206f..71b372a818e4 100644 --- a/lldb/include/lldb/API/SBFunction.h +++ b/lldb/include/lldb/API/SBFunction.h @@ -74,7 +74,7 @@ private: SBFunction(lldb_private::Function *lldb_object_ptr); - lldb_private::Function *m_opaque_ptr; + lldb_private::Function *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h index 7d07e168cf03..b9d781550b5d 100644 --- a/lldb/include/lldb/API/SBInstruction.h +++ b/lldb/include/lldb/API/SBInstruction.h @@ -12,7 +12,7 @@ #include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> // There's a lot to be fixed here, but need to wait for underlying insn // implementation to be revised & settle down first. diff --git a/lldb/include/lldb/API/SBInstructionList.h b/lldb/include/lldb/API/SBInstructionList.h index ae8988004e26..b9c6c66ebd85 100644 --- a/lldb/include/lldb/API/SBInstructionList.h +++ b/lldb/include/lldb/API/SBInstructionList.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { diff --git a/lldb/include/lldb/API/SBLaunchInfo.h b/lldb/include/lldb/API/SBLaunchInfo.h index 04ebb5707688..eb4f4a65833c 100644 --- a/lldb/include/lldb/API/SBLaunchInfo.h +++ b/lldb/include/lldb/API/SBLaunchInfo.h @@ -171,6 +171,14 @@ public: void SetDetachOnError(bool enable); + const char *GetScriptedProcessClassName() const; + + void SetScriptedProcessClassName(const char *class_name); + + lldb::SBStructuredData GetScriptedProcessDictionary() const; + + void SetScriptedProcessDictionary(lldb::SBStructuredData dict); + protected: friend class SBPlatform; friend class SBTarget; diff --git a/lldb/include/lldb/API/SBListener.h b/lldb/include/lldb/API/SBListener.h index 2144e7956b13..eaa8b59d0c49 100644 --- a/lldb/include/lldb/API/SBListener.h +++ b/lldb/include/lldb/API/SBListener.h @@ -100,7 +100,7 @@ private: void reset(lldb::ListenerSP listener_sp); lldb::ListenerSP m_opaque_sp; - lldb_private::Listener *m_unused_ptr; + lldb_private::Listener *m_unused_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBMemoryRegionInfo.h b/lldb/include/lldb/API/SBMemoryRegionInfo.h index d82c70606559..122226b9a0c5 100644 --- a/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -73,6 +73,40 @@ public: /// region. If no name can be determined the returns nullptr. const char *GetName(); + /// Returns whether this memory region has a list of memory pages + /// that have been modified -- that are dirty. + /// + /// \return + /// True if the dirty page list is available. + bool HasDirtyMemoryPageList(); + + /// Returns the number of modified pages -- dirty pages -- in this + /// memory region. + /// + /// \return + /// The number of dirty page entries will be returned. If + /// there are no dirty pages in this memory region, 0 will + /// be returned. 0 will also be returned if the dirty page + /// list is not available for this memory region -- you must + /// use HasDirtyMemoryPageList() to check for that. + uint32_t GetNumDirtyPages(); + + /// Returns the address of a memory page that has been modified in + /// this region. + /// + /// \return + /// Returns the address for his dirty page in the list. + /// If this memory region does not have a dirty page list, + /// LLDB_INVALID_ADDRESS is returned. + addr_t GetDirtyPageAddressAtIndex(uint32_t idx); + + /// Returns the size of a memory page in this region. + /// + /// \return + /// Returns the size of the memory pages in this region, + /// or 0 if this information is unavailable. + int GetPageSize(); + bool operator==(const lldb::SBMemoryRegionInfo &rhs) const; bool operator!=(const lldb::SBMemoryRegionInfo &rhs) const; diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index a90ec2a29a39..73a8d918f4d6 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -14,7 +14,7 @@ #include "lldb/API/SBProcessInfo.h" #include "lldb/API/SBQueue.h" #include "lldb/API/SBTarget.h" -#include <stdio.h> +#include <cstdio> namespace lldb { @@ -224,31 +224,6 @@ public: SBStructuredData GetExtendedCrashInformation(); - /// Start Tracing with the given SBTraceOptions. - /// - /// \param[in] options - /// Class containing trace options like trace buffer size, meta - /// data buffer size, TraceType and any custom parameters - /// {formatted as a JSON Dictionary}. In case of errors in - /// formatting, an error would be reported. - /// It must be noted that tracing options such as buffer sizes - /// or other custom parameters passed maybe invalid for some - /// trace technologies. In such cases the trace implementations - /// could choose to either throw an error or could round off to - /// the nearest valid options to start tracing if the passed - /// value is not supported. To obtain the actual used trace - /// options please use the GetTraceConfig API. For the custom - /// parameters, only the parameters recognized by the target - /// would be used and others would be ignored. - /// - /// \param[out] error - /// An error explaining what went wrong. - /// - /// \return - /// A SBTrace instance, which should be used - /// to get the trace data or other trace related operations. - lldb::SBTrace StartTrace(SBTraceOptions &options, lldb::SBError &error); - uint32_t GetNumSupportedHardwareWatchpoints(lldb::SBError &error) const; /// Load a shared library into this process. @@ -301,13 +276,13 @@ public: /// paths till you find a matching library. /// /// \param[in] image_spec - /// The name of the shared library that you want to load. + /// The name of the shared library that you want to load. /// If image_spec is a relative path, the relative path will be /// appended to the search paths. /// If the image_spec is an absolute path, just the basename is used. /// /// \param[in] paths - /// A list of paths to search for the library whose basename is + /// A list of paths to search for the library whose basename is /// local_spec. /// /// \param[out] loaded_path @@ -325,7 +300,7 @@ public: /// library can't be opened. uint32_t LoadImageUsingPaths(const lldb::SBFileSpec &image_spec, SBStringList &paths, - lldb::SBFileSpec &loaded_path, + lldb::SBFileSpec &loaded_path, lldb::SBError &error); lldb::SBError UnloadImage(uint32_t image_token); @@ -395,6 +370,45 @@ public: /// valid. lldb::SBProcessInfo GetProcessInfo(); + /// Allocate memory within the process. + /// + /// This function will allocate memory in the process's address space. + /// + /// \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 from lldb, just not by the process + /// itself. + /// + /// \param[out] error + /// An error object that gets filled in with any errors that + /// might occur when trying allocate. + /// + /// \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, + lldb::SBError &error); + + /// Deallocate memory in the process. + /// + /// This function will deallocate memory in the process's address + /// space that was allocated with AllocateMemory. + /// + /// \param[in] ptr + /// A return value from AllocateMemory, pointing to the memory you + /// want to deallocate. + /// + /// \return + /// An error object describes any errors that occurred while + /// deallocating. + /// + lldb::SBError DeallocateMemory(lldb::addr_t ptr); + protected: friend class SBAddress; friend class SBBreakpoint; diff --git a/lldb/include/lldb/API/SBProcessInfo.h b/lldb/include/lldb/API/SBProcessInfo.h index 0cc5f6a2f9f6..36fae9e842a6 100644 --- a/lldb/include/lldb/API/SBProcessInfo.h +++ b/lldb/include/lldb/API/SBProcessInfo.h @@ -50,6 +50,9 @@ public: lldb::pid_t GetParentProcessID(); + /// Return the target triple (arch-vendor-os) for the described process. + const char *GetTriple(); + private: friend class SBProcess; diff --git a/lldb/include/lldb/API/SBSourceManager.h b/lldb/include/lldb/API/SBSourceManager.h index c8302dbda3c0..e95cfa66e1c5 100644 --- a/lldb/include/lldb/API/SBSourceManager.h +++ b/lldb/include/lldb/API/SBSourceManager.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index f44b87bb4c98..291109cbe93c 100644 --- a/lldb/include/lldb/API/SBStream.h +++ b/lldb/include/lldb/API/SBStream.h @@ -9,7 +9,7 @@ #ifndef LLDB_API_SBSTREAM_H #define LLDB_API_SBSTREAM_H -#include <stdio.h> +#include <cstdio> #include "lldb/API/SBDefines.h" @@ -72,6 +72,7 @@ protected: friend class SBFunction; friend class SBInstruction; friend class SBInstructionList; + friend class SBLaunchInfo; friend class SBLineEntry; friend class SBMemoryRegionInfo; friend class SBModule; @@ -104,7 +105,7 @@ private: SBStream(const SBStream &) = delete; const SBStream &operator=(const SBStream &) = delete; std::unique_ptr<lldb_private::Stream> m_opaque_up; - bool m_is_file; + bool m_is_file = false; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h index 44a86bdabe25..07075abbf1d0 100644 --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -21,7 +21,7 @@ public: SBStructuredData(const lldb::SBStructuredData &rhs); SBStructuredData(const lldb::EventSP &event_sp); - + SBStructuredData(lldb_private::StructuredDataImpl *impl); ~SBStructuredData(); @@ -34,6 +34,8 @@ public: lldb::SBError SetFromJSON(lldb::SBStream &stream); + lldb::SBError SetFromJSON(const char *json); + void Clear(); lldb::SBError GetAsJSON(lldb::SBStream &stream) const; @@ -42,7 +44,7 @@ public: /// Return the type of data in this data structure lldb::StructuredDataType GetType() const; - + /// Return the size (i.e. number of elements) in this data structure /// if it is an array or dictionary type. For other types, 0 will be // returned. @@ -51,7 +53,7 @@ public: /// Fill keys with the keys in this object and return true if this data /// structure is a dictionary. Returns false otherwise. bool GetKeys(lldb::SBStringList &keys) const; - + /// Return the value corresponding to a key if this data structure /// is a dictionary type. lldb::SBStructuredData GetValueForKey(const char *key) const; @@ -88,7 +90,7 @@ public: size_t GetStringValue(char *dst, size_t dst_len) const; protected: - friend class SBTraceOptions; + friend class SBLaunchInfo; friend class SBDebugger; friend class SBTarget; friend class SBProcess; @@ -97,6 +99,7 @@ protected: friend class SBBreakpoint; friend class SBBreakpointLocation; friend class SBBreakpointName; + friend class SBTrace; StructuredDataImplUP m_impl_up; }; diff --git a/lldb/include/lldb/API/SBSymbol.h b/lldb/include/lldb/API/SBSymbol.h index 66f73c82a73a..5935ccfed024 100644 --- a/lldb/include/lldb/API/SBSymbol.h +++ b/lldb/include/lldb/API/SBSymbol.h @@ -78,7 +78,7 @@ private: void SetSymbol(lldb_private::Symbol *lldb_object_ptr); - lldb_private::Symbol *m_opaque_ptr; + lldb_private::Symbol *m_opaque_ptr = nullptr; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 30f4005dfc0f..5a6908f040b1 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -643,7 +643,7 @@ public: lldb::SBBreakpoint BreakpointCreateByAddress(addr_t address); lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address); - + /// Create a breakpoint using a scripted resolver. /// /// \param[in] class_name @@ -651,16 +651,16 @@ public: /// /// \param[in] extra_args /// This is an SBStructuredData object that will get passed to the - /// constructor of the class in class_name. You can use this to - /// reuse the same class, parametrizing with entries from this + /// constructor of the class in class_name. You can use this to + /// reuse the same class, parametrizing with entries from this /// dictionary. /// /// \param module_list - /// If this is non-empty, this will be used as the module filter in the + /// If this is non-empty, this will be used as the module filter in the /// SearchFilter created for this breakpoint. /// /// \param file_list - /// If this is non-empty, this will be used as the comp unit filter in the + /// If this is non-empty, this will be used as the comp unit filter in the /// SearchFilter created for this breakpoint. /// /// \return @@ -834,10 +834,27 @@ public: lldb::addr_t GetStackRedZoneSize(); + bool IsLoaded(const lldb::SBModule &module) const; + lldb::SBLaunchInfo GetLaunchInfo() const; void SetLaunchInfo(const lldb::SBLaunchInfo &launch_info); + /// Get a \a SBTrace object the can manage the processor trace information of + /// this target. + /// + /// \return + /// The trace object. The returned SBTrace object might not be valid, so it + /// should be checked with a call to "bool SBTrace::IsValid()". + lldb::SBTrace GetTrace(); + + /// Create a \a Trace object for the current target using the using the + /// default supported tracing technology for this process. + /// + /// \param[out] error + /// An error if a Trace already exists or the trace couldn't be created. + lldb::SBTrace CreateTrace(SBError &error); + protected: friend class SBAddress; friend class SBBlock; diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index 894120c6d986..ac1b8407a220 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -11,7 +11,7 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { @@ -66,6 +66,9 @@ public: /// eStopReasonSignal 1 unix signal number /// eStopReasonException N exception data /// eStopReasonExec 0 + /// eStopReasonFork 1 pid of the child process + /// eStopReasonVFork 1 pid of the child process + /// eStopReasonVForkDone 0 /// eStopReasonPlanComplete 0 uint64_t GetStopReasonDataAtIndex(uint32_t idx); @@ -217,6 +220,7 @@ private: friend class lldb_private::QueueImpl; friend class SBQueueItem; friend class SBThreadPlan; + friend class SBTrace; void SetThread(const lldb::ThreadSP &lldb_object_sp); diff --git a/lldb/include/lldb/API/SBThreadPlan.h b/lldb/include/lldb/API/SBThreadPlan.h index 0dc48437a668..0d166b35ae4a 100644 --- a/lldb/include/lldb/API/SBThreadPlan.h +++ b/lldb/include/lldb/API/SBThreadPlan.h @@ -11,14 +11,12 @@ #include "lldb/API/SBDefines.h" -#include <stdio.h> +#include <cstdio> namespace lldb { class LLDB_API SBThreadPlan { - friend class lldb_private::ThreadPlan; - public: SBThreadPlan(); @@ -60,6 +58,9 @@ public: /// eStopReasonSignal 1 unix signal number /// eStopReasonException N exception data /// eStopReasonExec 0 + /// eStopReasonFork 1 pid of the child process + /// eStopReasonVFork 1 pid of the child process + /// eStopReasonVForkDone 0 /// eStopReasonPlanComplete 0 uint64_t GetStopReasonDataAtIndex(uint32_t idx); diff --git a/lldb/include/lldb/API/SBTrace.h b/lldb/include/lldb/API/SBTrace.h index 053abaeada19..1685caaf4efa 100644 --- a/lldb/include/lldb/API/SBTrace.h +++ b/lldb/include/lldb/API/SBTrace.h @@ -18,97 +18,88 @@ namespace lldb { class LLDB_API SBTrace { public: + /// Default constructor for an invalid Trace object. SBTrace(); - /// Obtain the trace data as raw bytes. + + SBTrace(const lldb::TraceSP &trace_sp); + + /// \return + /// A description of the parameters to use for the \a SBTrace::Start + /// method, or \b null if the object is invalid. + const char *GetStartConfigurationHelp(); + + /// Start tracing all current and future threads in a live process using a + /// provided configuration. This is referred as "process tracing" in the + /// documentation. /// - /// \param[out] error - /// An error explaining what went wrong. + /// This is equivalent to the command "process trace start". /// - /// \param[in] buf - /// Buffer to write the trace data to. + /// This operation fails if it is invoked twice in a row without + /// first stopping the process trace with \a SBTrace::Stop(). /// - /// \param[in] size - /// The size of the buffer used to read the data. This is - /// also the size of the data intended to read. It is also - /// possible to partially read the trace data for some trace - /// technologies by specifying a smaller buffer. + /// If a thread is already being traced explicitly, e.g. with \a + /// SBTrace::Start(const SBThread &thread, const SBStructuredData + /// &configuration), it is left unaffected by this operation. /// - /// \param[in] offset - /// The start offset to begin reading the trace data. + /// \param[in] configuration + /// Dictionary object with custom fields for the corresponding trace + /// technology. /// - /// \param[in] thread_id - /// Tracing could be started for the complete process or a - /// single thread, in the first case the traceid obtained would - /// map to all the threads existing within the process and the - /// ones spawning later. The thread_id parameter can be used in - /// such a scenario to select the trace data for a specific - /// thread. + /// Full details for the trace start parameters that can be set can be + /// retrieved by calling \a SBTrace::GetStartConfigurationHelp(). /// /// \return - /// The size of the trace data effectively read by the API call. - size_t GetTraceData(SBError &error, void *buf, size_t size, size_t offset = 0, - lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); - - /// Obtain any meta data as raw bytes for the tracing instance. - /// The input parameter definition is similar to the previous - /// function. - size_t GetMetaData(SBError &error, void *buf, size_t size, size_t offset = 0, - lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + /// An error explaining any failures. + SBError Start(const SBStructuredData &configuration); - /// Stop the tracing instance. Stopping the trace will also - /// lead to deletion of any gathered trace data. - /// - /// \param[out] error - /// An error explaining what went wrong. - /// - /// \param[in] thread_id - /// The trace id could map to a tracing instance for a thread - /// or could also map to a group of threads being traced with - /// the same trace options. A thread_id is normally optional - /// except in the case of tracing a complete process and tracing - /// needs to switched off on a particular thread. - /// A situation could occur where initially a thread (lets say - /// thread A) is being individually traced with a particular - /// trace id and then tracing is started on the complete - /// process, in this case thread A will continue without any - /// change. All newly spawned threads would be traced with the - /// trace id of the process. - /// Now if the StopTrace API is called for the whole process, - /// thread A will not be stopped and must be stopped separately. - void StopTrace(SBError &error, - lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + /// Start tracing a specific thread in a live process using a provided + /// configuration. This is referred as "thread tracing" in the documentation. + /// + /// This is equivalent to the command "thread trace start". + /// + /// If the thread is already being traced by a "process tracing" operation, + /// e.g. with \a SBTrace::Start(const SBStructuredData &configuration), this + /// operation fails. + /// + /// \param[in] configuration + /// Dictionary object with custom fields for the corresponding trace + /// technology. + /// + /// Full details for the trace start parameters that can be set can be + /// retrieved by calling \a SBTrace::GetStartConfigurationHelp(). + /// + /// \return + /// An error explaining any failures. + SBError Start(const SBThread &thread, const SBStructuredData &configuration); - /// Get the trace configuration being used for the trace instance. - /// The threadid in the SBTraceOptions needs to be set when the - /// configuration used by a specific thread is being requested. + /// Stop tracing all threads in a live process. /// - /// \param[out] options - /// The trace options actually used by the trace instance - /// would be filled by the API. + /// If a "process tracing" operation is active, e.g. \a SBTrace::Start(const + /// SBStructuredData &configuration), this effectively prevents future threads + /// from being traced. /// - /// \param[out] error - /// An error explaining what went wrong. - void GetTraceConfig(SBTraceOptions &options, SBError &error); + /// This is equivalent to the command "process trace stop". + /// + /// \return + /// An error explaining any failures. + SBError Stop(); - lldb::user_id_t GetTraceUID(); + /// Stop tracing a specific thread in a live process regardless of whether the + /// thread was traced explicitly or as part of a "process tracing" operation. + /// + /// This is equivalent to the command "thread trace stop". + /// + /// \return + /// An error explaining any failures. + SBError Stop(const SBThread &thread); explicit operator bool() const; bool IsValid(); protected: - typedef std::shared_ptr<TraceImpl> TraceImplSP; - - friend class SBProcess; - - void SetTraceUID(lldb::user_id_t uid); - - TraceImplSP m_trace_impl_sp; - - lldb::ProcessSP GetSP() const; - - void SetSP(const ProcessSP &process_sp); - + lldb::TraceSP m_opaque_sp; + /// deprecated lldb::ProcessWP m_opaque_wp; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBTraceOptions.h b/lldb/include/lldb/API/SBTraceOptions.h deleted file mode 100644 index 22d71fbd3828..000000000000 --- a/lldb/include/lldb/API/SBTraceOptions.h +++ /dev/null @@ -1,59 +0,0 @@ -//===-- SBTraceOptions ------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_API_SBTRACEOPTIONS_H -#define LLDB_API_SBTRACEOPTIONS_H - -#include "lldb/API/SBDefines.h" - -namespace lldb { - -class LLDB_API SBTraceOptions { -public: - SBTraceOptions(); - - lldb::TraceType getType() const; - - uint64_t getTraceBufferSize() const; - - /// The trace parameters consist of any custom parameters - /// apart from the generic parameters such as - /// TraceType, trace_buffer_size and meta_data_buffer_size. - /// The returned parameters would be formatted as a JSON Dictionary. - lldb::SBStructuredData getTraceParams(lldb::SBError &error); - - uint64_t getMetaDataBufferSize() const; - - /// SBStructuredData is meant to hold any custom parameters - /// apart from meta buffer size and trace size. They should - /// be formatted as a JSON Dictionary. - void setTraceParams(lldb::SBStructuredData ¶ms); - - void setType(lldb::TraceType type); - - void setTraceBufferSize(uint64_t size); - - void setMetaDataBufferSize(uint64_t size); - - void setThreadID(lldb::tid_t thread_id); - - lldb::tid_t getThreadID(); - - explicit operator bool() const; - - bool IsValid(); - -protected: - friend class SBProcess; - friend class SBTrace; - - lldb::TraceOptionsSP m_traceoptions_sp; -}; -} - -#endif // LLDB_API_SBTRACEOPTIONS_H diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h index ddb70b719d6e..f2e2a0d22784 100644 --- a/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -481,16 +481,16 @@ public: /// Meant to be used by the BreakpointLocation class. /// /// \return - /// A pointer to this breakpoint's BreakpointOptions. - BreakpointOptions *GetOptions(); + /// A reference to this breakpoint's BreakpointOptions. + BreakpointOptions &GetOptions(); /// Returns the BreakpointOptions structure set at the breakpoint level. /// /// Meant to be used by the BreakpointLocation class. /// /// \return - /// A pointer to this breakpoint's BreakpointOptions. - const BreakpointOptions *GetOptions() const; + /// A reference to this breakpoint's BreakpointOptions. + const BreakpointOptions &GetOptions() const; /// Invoke the callback action when the breakpoint is hit. /// @@ -617,14 +617,6 @@ protected: void DecrementIgnoreCount(); - // BreakpointLocation::IgnoreCountShouldStop & - // Breakpoint::IgnoreCountShouldStop can only be called once per stop, and - // BreakpointLocation::IgnoreCountShouldStop should be tested first, and if - // it returns false we should continue, otherwise we should test - // Breakpoint::IgnoreCountShouldStop. - - bool IgnoreCountShouldStop(); - private: // To call from CopyFromBreakpoint. Breakpoint(Target &new_target, const Breakpoint &bp_to_copy_from); @@ -648,8 +640,7 @@ private: // to skip certain breakpoint hits. For instance, exception breakpoints use // this to limit the stop to certain exception classes, while leaving the // condition & callback free for user specification. - std::unique_ptr<BreakpointOptions> - m_options_up; // Settable breakpoint options + BreakpointOptions m_options; // Settable breakpoint options BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint. std::string m_kind_description; diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h index 4e1c57a40435..a6d1232162fc 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h +++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -202,8 +202,8 @@ public: /// hasn't been done already /// /// \return - /// A pointer to the breakpoint options. - BreakpointOptions *GetLocationOptions(); + /// A reference to the breakpoint options. + BreakpointOptions &GetLocationOptions(); /// Use this to access breakpoint options from this breakpoint location. /// This will return the options that have a setting for the specified @@ -214,10 +214,10 @@ public: /// \return /// A pointer to the containing breakpoint's options if this /// location doesn't have its own copy. - const BreakpointOptions *GetOptionsSpecifyingKind( - BreakpointOptions::OptionKind kind) const; + const BreakpointOptions & + GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind) const; - bool ValidForThisThread(Thread *thread); + bool ValidForThisThread(Thread &thread); /// Invoke the callback action when the breakpoint is hit. /// @@ -230,6 +230,12 @@ public: /// \b true if the target should stop at this breakpoint and \b /// false not. bool InvokeCallback(StoppointCallbackContext *context); + + /// Report whether the callback for this location is synchronous or not. + /// + /// \return + /// \b true if the callback is synchronous and \b false if not. + bool IsCallbackSynchronous(); /// Returns whether we should resolve Indirect functions in setting the /// breakpoint site for this location. @@ -291,6 +297,10 @@ protected: void DecrementIgnoreCount(); + /// BreakpointLocation::IgnoreCountShouldStop can only be called once + /// per stop. This method checks first against the loc and then the owner. + /// It also takes care of decrementing the ignore counters. + /// If it returns false we should continue, otherwise stop. bool IgnoreCountShouldStop(); private: diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h index ffdb81e363e0..34bd30986487 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -136,7 +136,7 @@ public: /// return /// \b true if the collection contains at least one location that /// would be valid for this thread, false otherwise. - bool ValidForThisThread(Thread *thread); + bool ValidForThisThread(Thread &thread); /// Tell whether ALL the breakpoints in the location collection are internal. /// diff --git a/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/lldb/include/lldb/Breakpoint/BreakpointOptions.h index 85b8e025a8e5..7b78265920a2 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -43,9 +43,7 @@ public: | eCondition | eAutoContinue) }; struct CommandData { - CommandData() - : user_source(), script_source(), - interpreter(lldb::eScriptLanguageNone), stop_on_error(true) {} + CommandData() : user_source(), script_source() {} CommandData(const StringList &user_source, lldb::ScriptLanguage interp) : user_source(user_source), script_source(), interpreter(interp), @@ -63,9 +61,10 @@ public: StringList user_source; std::string script_source; - enum lldb::ScriptLanguage - interpreter; // eScriptLanguageNone means command interpreter. - bool stop_on_error; + enum lldb::ScriptLanguage interpreter = + lldb::eScriptLanguageNone; // eScriptLanguageNone means command + // interpreter. + bool stop_on_error = true; private: enum class OptionNames : uint32_t { diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/lldb/include/lldb/Breakpoint/BreakpointResolver.h index d067b1eea6ff..7aa43b9f45df 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -204,7 +204,8 @@ protected: /// filter the results to find the first breakpoint >= (line, column). void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, llvm::StringRef log_ident, - uint32_t line = 0, uint32_t column = 0); + uint32_t line = 0, + llvm::Optional<uint16_t> column = llvm::None); void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool, const char *) = delete; diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h index 222fc6fcd45d..bd8d0394d4d2 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -10,6 +10,7 @@ #define LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILELINE_H #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/SourceLocationSpec.h" namespace lldb_private { @@ -21,10 +22,8 @@ namespace lldb_private { class BreakpointResolverFileLine : public BreakpointResolver { public: BreakpointResolverFileLine(const lldb::BreakpointSP &bkpt, - const FileSpec &resolver, - uint32_t line_no, uint32_t column, - lldb::addr_t m_offset, bool check_inlines, - bool skip_prologue, bool exact_match); + lldb::addr_t offset, bool skip_prologue, + const SourceLocationSpec &location_spec); static BreakpointResolver * CreateFromStructuredData(const lldb::BreakpointSP &bkpt, @@ -60,13 +59,8 @@ protected: void FilterContexts(SymbolContextList &sc_list, bool is_relative); friend class Breakpoint; - FileSpec m_file_spec; ///< This is the file spec we are looking for. - uint32_t m_line_number; ///< This is the line number that we are looking for. - uint32_t m_column; ///< This is the column that we are looking for. - bool m_inlines; ///< This determines whether the resolver looks for inlined - ///< functions or not. + SourceLocationSpec m_location_spec; bool m_skip_prologue; - bool m_exact_match; private: BreakpointResolverFileLine(const BreakpointResolverFileLine &) = delete; diff --git a/lldb/include/lldb/Breakpoint/BreakpointSite.h b/lldb/include/lldb/Breakpoint/BreakpointSite.h index fc32c04ffe35..e4c850206fd8 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointSite.h +++ b/lldb/include/lldb/Breakpoint/BreakpointSite.h @@ -148,7 +148,7 @@ public: /// return /// \b true if the collection contains at least one location that /// would be valid for this thread, false otherwise. - bool ValidForThisThread(Thread *thread); + bool ValidForThisThread(Thread &thread); /// Print a description of this breakpoint site to the stream \a s. /// GetDescription tells you about the breakpoint site's owners. Use diff --git a/lldb/include/lldb/Breakpoint/Stoppoint.h b/lldb/include/lldb/Breakpoint/Stoppoint.h index 36df77c4e91a..6bb1b6a705bc 100644 --- a/lldb/include/lldb/Breakpoint/Stoppoint.h +++ b/lldb/include/lldb/Breakpoint/Stoppoint.h @@ -33,7 +33,7 @@ public: void SetID(lldb::break_id_t bid); protected: - lldb::break_id_t m_bid; + lldb::break_id_t m_bid = LLDB_INVALID_BREAK_ID; private: // For Stoppoint only diff --git a/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h b/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h index db02ddd494fb..6da8d10d3f33 100644 --- a/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h +++ b/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h @@ -37,13 +37,14 @@ public: void Clear(); // Member variables - Event *event; // This is the event, the callback can modify this to indicate - // the meaning of the breakpoint hit + Event *event = nullptr; // This is the event, the callback can modify this to + // indicate the meaning of the breakpoint hit ExecutionContextRef exe_ctx_ref; // This tells us where we have stopped, what thread. - bool is_synchronous; // Is the callback being executed synchronously with the - // breakpoint, - // or asynchronously as the event is retrieved? + bool is_synchronous = + false; // Is the callback being executed synchronously with the + // breakpoint, + // or asynchronously as the event is retrieved? }; } // namespace lldb_private diff --git a/lldb/include/lldb/Breakpoint/StoppointHitCounter.h b/lldb/include/lldb/Breakpoint/StoppointHitCounter.h index 26f816da6430..ae9ec6b3c807 100644 --- a/lldb/include/lldb/Breakpoint/StoppointHitCounter.h +++ b/lldb/include/lldb/Breakpoint/StoppointHitCounter.h @@ -9,7 +9,7 @@ #ifndef LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H #define LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H -#include <assert.h> +#include <cassert> #include <cstdint> #include <limits> diff --git a/lldb/include/lldb/Breakpoint/WatchpointList.h b/lldb/include/lldb/Breakpoint/WatchpointList.h index 283f991b178a..bf87495d79db 100644 --- a/lldb/include/lldb/Breakpoint/WatchpointList.h +++ b/lldb/include/lldb/Breakpoint/WatchpointList.h @@ -14,6 +14,7 @@ #include <vector> #include "lldb/Core/Address.h" +#include "lldb/Utility/Iterable.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -37,6 +38,11 @@ public: /// Destructor, currently does nothing. ~WatchpointList(); + typedef std::list<lldb::WatchpointSP> wp_collection; + typedef LockingAdaptedIterable<wp_collection, lldb::WatchpointSP, + vector_adapter, std::recursive_mutex> + WatchpointIterable; + /// Add a Watchpoint to the list. /// /// \param[in] wp_sp @@ -184,8 +190,11 @@ public: /// The locker object that is set. void GetListMutex(std::unique_lock<std::recursive_mutex> &lock); + WatchpointIterable Watchpoints() const { + return WatchpointIterable(m_watchpoints, m_mutex); + } + protected: - typedef std::list<lldb::WatchpointSP> wp_collection; typedef std::vector<lldb::watch_id_t> id_vector; id_vector GetWatchpointIDs() const; @@ -198,7 +207,7 @@ protected: wp_collection m_watchpoints; mutable std::recursive_mutex m_mutex; - lldb::watch_id_t m_next_wp_id; + lldb::watch_id_t m_next_wp_id = 0; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Breakpoint/WatchpointOptions.h b/lldb/include/lldb/Breakpoint/WatchpointOptions.h index 0a18c52d36d0..fbfcb91c4249 100644 --- a/lldb/include/lldb/Breakpoint/WatchpointOptions.h +++ b/lldb/include/lldb/Breakpoint/WatchpointOptions.h @@ -166,13 +166,13 @@ public: lldb::user_id_t watch_id); struct CommandData { - CommandData() : user_source(), script_source(), stop_on_error(true) {} + CommandData() : user_source(), script_source() {} ~CommandData() = default; StringList user_source; std::string script_source; - bool stop_on_error; + bool stop_on_error = true; }; class CommandBaton : public TypedBaton<CommandData> { @@ -191,7 +191,7 @@ private: // For WatchpointOptions only WatchpointHitCallback m_callback; // This is the callback function pointer lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback - bool m_callback_is_synchronous; + bool m_callback_is_synchronous = false; std::unique_ptr<ThreadSpec> m_thread_spec_up; // Thread for which this watchpoint will take }; diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 71e50b91d68e..ec393a1871e3 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -14,8 +14,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Block; @@ -116,7 +116,7 @@ public: /// /// Initialize with a invalid section (NULL) and an invalid offset /// (LLDB_INVALID_ADDRESS). - Address() : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {} + Address() : m_section_wp() {} /// Copy constructor /// @@ -487,7 +487,8 @@ public: protected: // Member variables. lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL. - lldb::addr_t m_offset; ///< Offset into section if \a m_section_wp is valid... + lldb::addr_t m_offset = LLDB_INVALID_ADDRESS; ///< Offset into section if \a + ///< m_section_wp is valid... // Returns true if the m_section_wp once had a reference to a valid section // shared pointer, but no longer does. This can happen if we have an address diff --git a/lldb/include/lldb/Core/AddressRange.h b/lldb/include/lldb/Core/AddressRange.h index 8ccf96a436a1..6fbdc35c9168 100644 --- a/lldb/include/lldb/Core/AddressRange.h +++ b/lldb/include/lldb/Core/AddressRange.h @@ -13,7 +13,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> +#include <cstddef> namespace lldb_private { class SectionList; @@ -94,8 +94,7 @@ public: /// \return /// Returns \b true if \a so_addr is contained in this range, /// \b false otherwise. - // bool - // Contains (const Address &so_addr) const; + bool Contains(const Address &so_addr) const; /// Check if a section offset address is contained in this range. /// @@ -240,7 +239,7 @@ public: protected: // Member variables Address m_base_addr; ///< The section offset base address of this range. - lldb::addr_t m_byte_size; ///< The size in bytes of this address range. + lldb::addr_t m_byte_size = 0; ///< The size in bytes of this address range. }; // bool operator== (const AddressRange& lhs, const AddressRange& rhs); diff --git a/lldb/include/lldb/Core/AddressResolver.h b/lldb/include/lldb/Core/AddressResolver.h index 9ac058a97cd9..cb571bb5cb60 100644 --- a/lldb/include/lldb/Core/AddressResolver.h +++ b/lldb/include/lldb/Core/AddressResolver.h @@ -13,7 +13,7 @@ #include "lldb/Core/SearchFilter.h" #include "lldb/lldb-defines.h" -#include <stddef.h> +#include <cstddef> #include <vector> namespace lldb_private { diff --git a/lldb/include/lldb/Core/AddressResolverFileLine.h b/lldb/include/lldb/Core/AddressResolverFileLine.h index 46bf4155e865..e768256bf618 100644 --- a/lldb/include/lldb/Core/AddressResolverFileLine.h +++ b/lldb/include/lldb/Core/AddressResolverFileLine.h @@ -11,10 +11,10 @@ #include "lldb/Core/AddressResolver.h" #include "lldb/Core/SearchFilter.h" -#include "lldb/Utility/FileSpec.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/lldb-defines.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { class Address; @@ -28,8 +28,7 @@ class SymbolContext; class AddressResolverFileLine : public AddressResolver { public: - AddressResolverFileLine(const FileSpec &resolver, uint32_t line_no, - bool check_inlines); + AddressResolverFileLine(SourceLocationSpec location_spec); ~AddressResolverFileLine() override; @@ -42,10 +41,7 @@ public: void GetDescription(Stream *s) override; protected: - FileSpec m_file_spec; // This is the file spec we are looking for. - uint32_t m_line_number; // This is the line number that we are looking for. - bool m_inlines; // This determines whether the resolver looks for inlined - // functions or not. + SourceLocationSpec m_src_location_spec; private: AddressResolverFileLine(const AddressResolverFileLine &) = delete; diff --git a/lldb/include/lldb/Core/AddressResolverName.h b/lldb/include/lldb/Core/AddressResolverName.h deleted file mode 100644 index 0ec1ef05b0ec..000000000000 --- a/lldb/include/lldb/Core/AddressResolverName.h +++ /dev/null @@ -1,63 +0,0 @@ -//===-- AddressResolverName.h -----------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_CORE_ADDRESSRESOLVERNAME_H -#define LLDB_CORE_ADDRESSRESOLVERNAME_H - -#include "lldb/Core/AddressResolver.h" -#include "lldb/Core/SearchFilter.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/RegularExpression.h" -#include "lldb/lldb-defines.h" - -namespace lldb_private { -class Address; -class Stream; -class SymbolContext; - -/// \class AddressResolverName AddressResolverName.h -/// "lldb/Core/AddressResolverName.h" This class finds addresses for a given -/// function name, either by exact match or by regular expression. - -class AddressResolverName : public AddressResolver { -public: - AddressResolverName(const char *func_name, - AddressResolver::MatchType type = Exact); - - // Creates a function breakpoint by regular expression. Takes over control - // of the lifespan of func_regex. - AddressResolverName(RegularExpression func_regex); - - AddressResolverName(const char *class_name, const char *method, - AddressResolver::MatchType type); - - ~AddressResolverName() override; - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - lldb::SearchDepth GetDepth() override; - - void GetDescription(Stream *s) override; - -protected: - ConstString m_func_name; - ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop - // on methods of this class. - RegularExpression m_regex; - AddressResolver::MatchType m_match_type; - -private: - AddressResolverName(const AddressResolverName &) = delete; - const AddressResolverName &operator=(const AddressResolverName &) = delete; -}; - -} // namespace lldb_private - -#endif // LLDB_CORE_ADDRESSRESOLVERNAME_H diff --git a/lldb/include/lldb/Core/Architecture.h b/lldb/include/lldb/Core/Architecture.h index 2ea8bd31ebf4..b68bf27ae0df 100644 --- a/lldb/include/lldb/Core/Architecture.h +++ b/lldb/include/lldb/Core/Architecture.h @@ -10,6 +10,7 @@ #define LLDB_CORE_ARCHITECTURE_H #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/MemoryTagManager.h" namespace lldb_private { @@ -97,6 +98,17 @@ public: Target &target) const { return addr; } + + // Returns a pointer to an object that can manage memory tags for this + // Architecture E.g. masking out tags, unpacking tag streams etc. Returns + // nullptr if the architecture does not have a memory tagging extension. + // + // The return pointer being valid does not mean that the current process has + // memory tagging enabled, just that a tagging technology exists for this + // architecture. + virtual const MemoryTagManager *GetMemoryTagManager() const { + return nullptr; + } }; } // namespace lldb_private diff --git a/lldb/include/lldb/Core/Communication.h b/lldb/include/lldb/Core/Communication.h index 354c4bbcc283..930e927f6783 100644 --- a/lldb/include/lldb/Core/Communication.h +++ b/lldb/include/lldb/Core/Communication.h @@ -22,8 +22,8 @@ #include <ratio> #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Connection; diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 68daae1a3710..f0849c9ac950 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -9,7 +9,7 @@ #ifndef LLDB_CORE_DEBUGGER_H #define LLDB_CORE_DEBUGGER_H -#include <stdint.h> +#include <cstdint> #include <memory> #include <vector> @@ -42,9 +42,9 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Threading.h" -#include <assert.h> -#include <stddef.h> -#include <stdio.h> +#include <cassert> +#include <cstddef> +#include <cstdio> namespace llvm { class raw_ostream; @@ -73,6 +73,50 @@ class Debugger : public std::enable_shared_from_this<Debugger>, friend class SourceManager; // For GetSourceFileCache. public: + /// Broadcaster event bits definitions. + enum { + eBroadcastBitProgress = (1 << 0), + }; + + static ConstString GetStaticBroadcasterClass(); + + /// Get the public broadcaster for this debugger. + Broadcaster &GetBroadcaster() { return m_broadcaster; } + const Broadcaster &GetBroadcaster() const { return m_broadcaster; } + + class ProgressEventData : public EventData { + + public: + ProgressEventData(uint64_t progress_id, const std::string &message, + uint64_t completed, uint64_t total, + bool debugger_specific) + : m_message(message), m_id(progress_id), m_completed(completed), + m_total(total), m_debugger_specific(debugger_specific) {} + + static ConstString GetFlavorString(); + + ConstString GetFlavor() const override; + + void Dump(Stream *s) const override; + + static const ProgressEventData * + GetEventDataFromEvent(const Event *event_ptr); + uint64_t GetID() const { return m_id; } + uint64_t GetCompleted() const { return m_completed; } + uint64_t GetTotal() const { return m_total; } + const std::string &GetMessage() const { return m_message; } + bool IsDebuggerSpecific() const { return m_debugger_specific; } + + private: + std::string m_message; + const uint64_t m_id; + uint64_t m_completed; + const uint64_t m_total; + const bool m_debugger_specific; + ProgressEventData(const ProgressEventData &) = delete; + const ProgressEventData &operator=(const ProgressEventData &) = delete; + }; + ~Debugger() override; static lldb::DebuggerSP @@ -246,6 +290,8 @@ public: const FormatEntity::Entry *GetFrameFormatUnique() const; + uint32_t GetStopDisassemblyMaxSize() const; + const FormatEntity::Entry *GetThreadFormat() const; const FormatEntity::Entry *GetThreadStopFormat() const; @@ -344,6 +390,40 @@ public: protected: friend class CommandInterpreter; friend class REPL; + friend class Progress; + + /// Report progress events. + /// + /// Progress events will be delivered to any debuggers that have listeners + /// for the eBroadcastBitProgress. This function is called by the + /// lldb_private::Progress class to deliver the events to any debuggers that + /// qualify. + /// + /// \param [in] progress_id + /// The unique integer identifier for the progress to report. + /// + /// \param[in] message + /// The title of the progress dialog to display in the UI. + /// + /// \param [in] completed + /// The amount of work completed. If \a completed is zero, then this event + /// is a progress started event. If \a completed is equal to \a total, then + /// this event is a progress end event. Otherwise completed indicates the + /// current progress compare to the total value. + /// + /// \param [in] total + /// The total amount of work units that need to be completed. If this value + /// is UINT64_MAX, then an indeterminate progress indicator should be + /// displayed. + /// + /// \param [in] debugger_id + /// If this optional parameter has a value, it indicates the unique + /// debugger identifier that this progress should be delivered to. If this + /// optional parameter does not have a value, the progress will be + /// delivered to all debuggers. + static void ReportProgress(uint64_t progress_id, const std::string &message, + uint64_t completed, uint64_t total, + llvm::Optional<lldb::user_id_t> debugger_id); bool StartEventHandlerThread(); @@ -430,7 +510,8 @@ protected: LoadedPluginsList m_loaded_plugins; HostThread m_event_handler_thread; HostThread m_io_handler_thread; - Broadcaster m_sync_broadcaster; + Broadcaster m_sync_broadcaster; ///< Private debugger synchronization. + Broadcaster m_broadcaster; ///< Public Debugger event broadcaster. lldb::ListenerSP m_forward_listener_sp; llvm::once_flag m_clear_once; lldb::TargetSP m_dummy_target_sp; diff --git a/lldb/include/lldb/Symbol/Declaration.h b/lldb/include/lldb/Core/Declaration.h index 7f19f45411a0..f81de21bc8f8 100644 --- a/lldb/include/lldb/Symbol/Declaration.h +++ b/lldb/include/lldb/Core/Declaration.h @@ -14,7 +14,7 @@ namespace lldb_private { -/// \class Declaration Declaration.h "lldb/Symbol/Declaration.h" +/// \class Declaration Declaration.h "lldb/Core/Declaration.h" /// A class that describes the declaration location of a /// lldb object. /// @@ -24,14 +24,7 @@ namespace lldb_private { class Declaration { public: /// Default constructor. - Declaration() - : m_file(), m_line(0) -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - , - m_column(0) -#endif - { - } + Declaration() : m_file() {} /// Construct with file specification, and optional line and column. /// @@ -46,23 +39,13 @@ public: /// \param[in] column /// The column number that describes where this was declared. /// Set to zero if there is no column number information. - Declaration(const FileSpec &file_spec, uint32_t line = 0, uint32_t column = 0) - : m_file(file_spec), m_line(line) -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - , - m_column(column) -#endif - { - } + Declaration(const FileSpec &file_spec, uint32_t line = 0, + uint16_t column = LLDB_INVALID_COLUMN_NUMBER) + : m_file(file_spec), m_line(line), m_column(column) {} /// Construct with a pointer to another Declaration object. Declaration(const Declaration *decl_ptr) - : m_file(), m_line(0) -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - , - m_column(0) -#endif - { + : m_file(), m_line(0), m_column(LLDB_INVALID_COLUMN_NUMBER) { if (decl_ptr) *this = *decl_ptr; } @@ -74,9 +57,7 @@ public: void Clear() { m_file.Clear(); m_line = 0; -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS m_column = 0; -#endif } /// Compare two declaration objects. @@ -118,18 +99,6 @@ public: void Dump(Stream *s, bool show_fullpaths) const; bool DumpStopContext(Stream *s, bool show_fullpaths) const; - /// Get accessor for the declaration column number. - /// - /// \return - /// Non-zero indicates a valid column number, zero indicates no - /// column information is available. - uint32_t GetColumn() const { -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - return m_column; -#else - return 0; -#endif - } /// Get accessor for file specification. /// @@ -150,7 +119,32 @@ public: /// line information is available. uint32_t GetLine() const { return m_line; } - bool IsValid() const { return m_file && m_line != 0; } + /// Get accessor for the declaration column number. + /// + /// \return + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + uint16_t GetColumn() const { return m_column; } + + /// Convert to boolean operator. + /// + /// This allows code to check a Declaration object to see if it + /// contains anything valid using code such as: + /// + /// \code + /// Declaration decl(...); + /// if (decl) + /// { ... + /// \endcode + /// + /// \return + /// A \b true if both the file_spec and the line are valid, + /// \b false otherwise. + explicit operator bool() const { return IsValid(); } + + bool IsValid() const { + return m_file && m_line != 0 && m_line != LLDB_INVALID_LINE_NUMBER; + } /// Get the memory cost of this object. /// @@ -162,17 +156,6 @@ public: /// \see ConstString::StaticMemorySize () size_t MemorySize() const; - /// Set accessor for the declaration column number. - /// - /// \param[in] column - /// Non-zero indicates a valid column number, zero indicates no - /// column information is available. - void SetColumn(uint32_t column) { -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - m_column = col; -#endif - } - /// Set accessor for the declaration file specification. /// /// \param[in] file_spec @@ -186,16 +169,23 @@ public: /// line information is available. void SetLine(uint32_t line) { m_line = line; } + /// Set accessor for the declaration column number. + /// + /// \param[in] column + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + void SetColumn(uint16_t column) { m_column = column; } + protected: - /// Member variables. - FileSpec m_file; ///< The file specification that points to the - ///< source file where the declaration occurred. - uint32_t m_line; ///< Non-zero values indicates a valid line number, - ///< zero indicates no line number information is available. -#ifdef LLDB_ENABLE_DECLARATION_COLUMNS - uint32_t m_column; ///< Non-zero values indicates a valid column number, - ///< zero indicates no column information is available. -#endif + /// The file specification that points to the source file where the + /// declaration occurred. + FileSpec m_file; + /// Non-zero values indicates a valid line number, zero indicates no line + /// number information is available. + uint32_t m_line = 0; + /// Non-zero values indicates a valid column number, zero indicates no column + /// information is available. + uint16_t m_column = LLDB_INVALID_COLUMN_NUMBER; }; bool operator==(const Declaration &lhs, const Declaration &rhs); diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index 9a694de0f60a..622c23ff6492 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -34,9 +34,9 @@ #include <string> #include <vector> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> +#include <cstddef> +#include <cstdint> +#include <cstdio> namespace llvm { template <typename T> class SmallVectorImpl; @@ -394,10 +394,12 @@ public: lldb::addr_t value; }; - static lldb::DisassemblerSP - DisassembleRange(const ArchSpec &arch, const char *plugin_name, - const char *flavor, Target &target, - const AddressRange &disasm_range, bool prefer_file_cache); + static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, + const char *plugin_name, + const char *flavor, + Target &target, + const AddressRange &disasm_range, + bool force_live_memory = false); static lldb::DisassemblerSP DisassembleBytes(const ArchSpec &arch, const char *plugin_name, @@ -426,7 +428,8 @@ public: Stream &strm); size_t ParseInstructions(Target &target, Address address, Limit limit, - Stream *error_strm_ptr, bool prefer_file_cache); + Stream *error_strm_ptr, + bool force_live_memory = false); virtual size_t DecodeInstructions(const Address &base_addr, const DataExtractor &data, @@ -451,10 +454,10 @@ protected: struct SourceLine { FileSpec file; - uint32_t line; - uint32_t column; + uint32_t line = LLDB_INVALID_LINE_NUMBER; + uint32_t column = 0; - SourceLine() : file(), line(LLDB_INVALID_LINE_NUMBER), column(0) {} + SourceLine() : file() {} bool operator==(const SourceLine &rhs) const { return file == rhs.file && line == rhs.line && rhs.column == column; @@ -473,14 +476,12 @@ protected: // index of the "current" source line, if we want to highlight that when // displaying the source lines. (as opposed to the surrounding source // lines provided to give context) - size_t current_source_line; + size_t current_source_line = -1; // Whether to print a blank line at the end of the source lines. - bool print_source_context_end_eol; + bool print_source_context_end_eol = true; - SourceLinesToDisplay() - : lines(), current_source_line(-1), print_source_context_end_eol(true) { - } + SourceLinesToDisplay() : lines() {} }; // Get the function's declaration line number, hopefully a line number diff --git a/lldb/include/lldb/Core/DumpDataExtractor.h b/lldb/include/lldb/Core/DumpDataExtractor.h index 2a9d778e0a6a..12188609e8c0 100644 --- a/lldb/include/lldb/Core/DumpDataExtractor.h +++ b/lldb/include/lldb/Core/DumpDataExtractor.h @@ -12,8 +12,8 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/lldb/include/lldb/Core/EmulateInstruction.h b/lldb/include/lldb/Core/EmulateInstruction.h index a575488ba966..f50fee095a8b 100644 --- a/lldb/include/lldb/Core/EmulateInstruction.h +++ b/lldb/include/lldb/Core/EmulateInstruction.h @@ -21,8 +21,8 @@ #include "lldb/lldb-private-types.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class OptionValueDictionary; @@ -182,8 +182,8 @@ public: } InfoType; struct Context { - ContextType type; - enum InfoType info_type; + ContextType type = eContextInvalid; + enum InfoType info_type = eInfoTypeNoArgs; union { struct RegisterPlusOffset { RegisterInfo reg; // base register @@ -237,7 +237,7 @@ public: uint32_t isa; } info; - Context() : type(eContextInvalid), info_type(eInfoTypeNoArgs) {} + Context() = default; void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) { info_type = eInfoTypeRegisterPlusOffset; diff --git a/lldb/include/lldb/Core/FileLineResolver.h b/lldb/include/lldb/Core/FileLineResolver.h index 68e252e93bc9..16b1db1b50c4 100644 --- a/lldb/include/lldb/Core/FileLineResolver.h +++ b/lldb/include/lldb/Core/FileLineResolver.h @@ -14,7 +14,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-defines.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { class Address; @@ -28,8 +28,8 @@ class FileLineResolver : public Searcher { public: FileLineResolver() : m_file_spec(), - m_line_number(UINT32_MAX), // Set this to zero for all lines in a file - m_sc_list(), m_inlines(true) {} + // Set this to zero for all lines in a file + m_sc_list() {} FileLineResolver(const FileSpec &resolver, uint32_t line_no, bool check_inlines); @@ -52,10 +52,11 @@ public: protected: FileSpec m_file_spec; // This is the file spec we are looking for. - uint32_t m_line_number; // This is the line number that we are looking for. + uint32_t m_line_number = + UINT32_MAX; // This is the line number that we are looking for. SymbolContextList m_sc_list; - bool m_inlines; // This determines whether the resolver looks for inlined - // functions or not. + bool m_inlines = true; // This determines whether the resolver looks for + // inlined functions or not. private: FileLineResolver(const FileLineResolver &) = delete; diff --git a/lldb/include/lldb/Core/FileSpecList.h b/lldb/include/lldb/Core/FileSpecList.h index 3e412a7e1a32..cab8e9b9b43f 100644 --- a/lldb/include/lldb/Core/FileSpecList.h +++ b/lldb/include/lldb/Core/FileSpecList.h @@ -14,7 +14,7 @@ #include <vector> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Stream; diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h index 91999f64ab5f..ecae8500df40 100644 --- a/lldb/include/lldb/Core/FormatEntity.h +++ b/lldb/include/lldb/Core/FormatEntity.h @@ -9,26 +9,27 @@ #ifndef LLDB_CORE_FORMATENTITY_H #define LLDB_CORE_FORMATENTITY_H -#include "lldb/Utility/CompletionRequest.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" #include <algorithm> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> #include <vector> namespace lldb_private { class Address; +class CompletionRequest; class ExecutionContext; +class FileSpec; +class Status; class Stream; class StringList; class SymbolContext; class ValueObject; } + namespace llvm { class StringRef; } @@ -103,20 +104,51 @@ public: }; struct Definition { + /// The name/string placeholder that corresponds to this definition. const char *name; - const char *string; // Insert this exact string into the output - Entry::Type type; - uint64_t data; - uint32_t num_children; - Definition *children; // An array of "num_children" Definition entries, - bool keep_separator; + /// Insert this exact string into the output + const char *string = nullptr; + /// Entry::Type corresponding to this definition. + const Entry::Type type; + /// Data that is returned as the value of the format string. + const uint64_t data = 0; + /// The number of children of this node in the tree of format strings. + const uint32_t num_children = 0; + /// An array of "num_children" Definition entries. + const Definition *children = nullptr; + /// Whether the separator is kept during parsing or not. It's used + /// for entries with parameters. + const bool keep_separator = false; + + constexpr Definition(const char *name, const FormatEntity::Entry::Type t) + : name(name), type(t) {} + + constexpr Definition(const char *name, const char *string) + : name(name), string(string), type(Entry::Type::EscapeCode) {} + + constexpr Definition(const char *name, const FormatEntity::Entry::Type t, + const uint64_t data) + : name(name), type(t), data(data) {} + + constexpr Definition(const char *name, const FormatEntity::Entry::Type t, + const uint64_t num_children, + const Definition *children, + const bool keep_separator = false) + : name(name), type(t), num_children(num_children), children(children), + keep_separator(keep_separator) {} }; + template <size_t N> + static constexpr Definition + DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t, + const Definition (&children)[N], + bool keep_separator = false) { + return Definition(name, t, N, children, keep_separator); + } + Entry(Type t = Type::Invalid, const char *s = nullptr, const char *f = nullptr) - : string(s ? s : ""), printf_format(f ? f : ""), children(), - definition(nullptr), type(t), fmt(lldb::eFormatDefault), number(0), - deref(false) {} + : string(s ? s : ""), printf_format(f ? f : ""), children(), type(t) {} Entry(llvm::StringRef s); Entry(char ch); @@ -133,7 +165,6 @@ public: string.clear(); printf_format.clear(); children.clear(); - definition = nullptr; type = Type::Invalid; fmt = lldb::eFormatDefault; number = 0; @@ -157,8 +188,6 @@ public: } if (children != rhs.children) return false; - if (definition != rhs.definition) - return false; if (type != rhs.type) return false; if (fmt != rhs.fmt) @@ -171,11 +200,10 @@ public: std::string string; std::string printf_format; std::vector<Entry> children; - Definition *definition; Type type; - lldb::Format fmt; - lldb::addr_t number; - bool deref; + lldb::Format fmt = lldb::eFormatDefault; + lldb::addr_t number = 0; + bool deref = false; }; static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, diff --git a/lldb/include/lldb/Core/IOHandler.h b/lldb/include/lldb/Core/IOHandler.h index 2e8f3225fd5f..4a3b788e3ea1 100644 --- a/lldb/include/lldb/Core/IOHandler.h +++ b/lldb/include/lldb/Core/IOHandler.h @@ -26,8 +26,8 @@ #include <string> #include <vector> -#include <stdint.h> -#include <stdio.h> +#include <cstdint> +#include <cstdio> namespace lldb_private { class Debugger; @@ -419,16 +419,14 @@ public: private: #if LLDB_ENABLE_LIBEDIT - static bool IsInputCompleteCallback(Editline *editline, StringList &lines, - void *baton); + bool IsInputCompleteCallback(Editline *editline, StringList &lines); - static int FixIndentationCallback(Editline *editline, const StringList &lines, - int cursor_position, void *baton); + int FixIndentationCallback(Editline *editline, const StringList &lines, + int cursor_position); - static llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line, - void *baton); + llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line); - static void AutoCompleteCallback(CompletionRequest &request, void *baton); + void AutoCompleteCallback(CompletionRequest &request); #endif protected: diff --git a/lldb/include/lldb/Core/LoadedModuleInfoList.h b/lldb/include/lldb/Core/LoadedModuleInfoList.h index 49400f7f4908..ad6da2bd7559 100644 --- a/lldb/include/lldb/Core/LoadedModuleInfoList.h +++ b/lldb/include/lldb/Core/LoadedModuleInfoList.h @@ -101,14 +101,14 @@ public: lldb::addr_t m_dynamic; }; - LoadedModuleInfoList() : m_list(), m_link_map(LLDB_INVALID_ADDRESS) {} + LoadedModuleInfoList() : m_list() {} void add(const LoadedModuleInfo &mod) { m_list.push_back(mod); } void clear() { m_list.clear(); } std::vector<LoadedModuleInfo> m_list; - lldb::addr_t m_link_map; + lldb::addr_t m_link_map = LLDB_INVALID_ADDRESS; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h index c03fc1eb7599..d11d13b63cfc 100644 --- a/lldb/include/lldb/Core/Mangled.h +++ b/lldb/include/lldb/Core/Mangled.h @@ -17,8 +17,8 @@ #include "llvm/ADT/StringRef.h" +#include <cstddef> #include <memory> -#include <stddef.h> namespace lldb_private { @@ -43,7 +43,8 @@ public: enum ManglingScheme { eManglingSchemeNone = 0, eManglingSchemeMSVC, - eManglingSchemeItanium + eManglingSchemeItanium, + eManglingSchemeRustV0 }; /// Default constructor. diff --git a/lldb/include/lldb/Core/MappedHash.h b/lldb/include/lldb/Core/MappedHash.h index a27ec82b9b86..7bd3c3a78449 100644 --- a/lldb/include/lldb/Core/MappedHash.h +++ b/lldb/include/lldb/Core/MappedHash.h @@ -9,8 +9,8 @@ #ifndef LLDB_CORE_MAPPEDHASH_H #define LLDB_CORE_MAPPEDHASH_H -#include <assert.h> -#include <stdint.h> +#include <cassert> +#include <cstdint> #include <algorithm> #include <functional> @@ -47,19 +47,17 @@ public: uint32_t magic; // HASH_MAGIC or HASH_CIGAM magic value to allow endian detection - uint16_t version; // Version number - uint16_t hash_function; // The hash function enumeration that was used - uint32_t bucket_count; // The number of buckets in this hash table - uint32_t hashes_count; // The total number of unique hash values and hash - // data offsets in this table + uint16_t version = 1; // Version number + uint16_t hash_function = + eHashFunctionDJB; // The hash function enumeration that was used + uint32_t bucket_count = 0; // The number of buckets in this hash table + uint32_t hashes_count = 0; // The total number of unique hash values and + // hash data offsets in this table uint32_t header_data_len; // The size in bytes of the "header_data" template // member below HeaderData header_data; // - Header() - : magic(HASH_MAGIC), version(1), hash_function(eHashFunctionDJB), - bucket_count(0), hashes_count(0), header_data_len(sizeof(T)), - header_data() {} + Header() : magic(HASH_MAGIC), header_data_len(sizeof(T)), header_data() {} virtual ~Header() = default; diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h index 9eb7477730c1..dd7100c4616c 100644 --- a/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h @@ -32,10 +32,10 @@ #include "llvm/Support/Chrono.h" #include <atomic> +#include <cstddef> +#include <cstdint> #include <memory> #include <mutex> -#include <stddef.h> -#include <stdint.h> #include <string> #include <vector> @@ -850,13 +850,10 @@ public: /// \param[in] path /// The original source file path to try and remap. /// - /// \param[out] new_path - /// The newly remapped filespec that is may or may not exist. - /// /// \return - /// /b true if \a path was successfully located and \a new_path - /// is filled in with a new source path, \b false otherwise. - bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const; + /// The newly remapped filespec that is may or may not exist if + /// \a path was successfully located. + llvm::Optional<std::string> RemapSourceFile(llvm::StringRef path) const; bool RemapSourceFile(const char *, std::string &) const = delete; /// Update the ArchSpec to a more specific variant. @@ -885,10 +882,7 @@ public: /// correctly. class LookupInfo { public: - LookupInfo() - : m_name(), m_lookup_name(), m_language(lldb::eLanguageTypeUnknown), - m_name_type_mask(lldb::eFunctionNameTypeNone), - m_match_name_after_lookup(false) {} + LookupInfo() : m_name(), m_lookup_name() {} LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask, lldb::LanguageType language); @@ -917,15 +911,15 @@ public: ConstString m_lookup_name; /// Limit matches to only be for this language - lldb::LanguageType m_language; + lldb::LanguageType m_language = lldb::eLanguageTypeUnknown; /// One or more bits from lldb::FunctionNameType that indicate what kind of /// names we are looking for - lldb::FunctionNameType m_name_type_mask; + lldb::FunctionNameType m_name_type_mask = lldb::eFunctionNameTypeNone; ///< If \b true, then demangled names that match will need to contain ///< "m_name" in order to be considered a match - bool m_match_name_after_lookup; + bool m_match_name_after_lookup = false; }; protected: @@ -952,7 +946,7 @@ protected: ConstString m_object_name; ///< The name an object within this module that is ///selected, or empty of the module is represented ///by \a m_file. - uint64_t m_object_offset; + uint64_t m_object_offset = 0; llvm::sys::TimePoint<> m_object_mod_time; /// DataBuffer containing the module image, if it was provided at diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 46a718f08f04..07dddd18357b 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -27,8 +27,8 @@ #include <mutex> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ConstString; @@ -471,7 +471,7 @@ protected: collection m_modules; ///< The collection of modules. mutable std::recursive_mutex m_modules_mutex; - Notifier *m_notifier; + Notifier *m_notifier = nullptr; public: typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter, diff --git a/lldb/include/lldb/Core/ModuleSpec.h b/lldb/include/lldb/Core/ModuleSpec.h index 9dd398a05291..8e5deebbab9a 100644 --- a/lldb/include/lldb/Core/ModuleSpec.h +++ b/lldb/include/lldb/Core/ModuleSpec.h @@ -27,12 +27,11 @@ class ModuleSpec { public: ModuleSpec() : m_file(), m_platform_file(), m_symbol_file(), m_arch(), m_uuid(), - m_object_name(), m_object_offset(0), m_object_size(0), - m_source_mappings() {} + m_object_name(), m_source_mappings() {} - /// If the \param data argument is passed, its contents will be used + /// If the \c data argument is passed, its contents will be used /// as the module contents instead of trying to read them from - /// \param file_spec. + /// \c file_spec . ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID(), lldb::DataBufferSP data = lldb::DataBufferSP()) : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(), @@ -271,8 +270,8 @@ protected: ArchSpec m_arch; UUID m_uuid; ConstString m_object_name; - uint64_t m_object_offset; - uint64_t m_object_size; + uint64_t m_object_offset = 0; + uint64_t m_object_size = 0; llvm::sys::TimePoint<> m_object_mod_time; mutable PathMappingList m_source_mappings; lldb::DataBufferSP m_data = {}; diff --git a/lldb/include/lldb/Core/Opcode.h b/lldb/include/lldb/Core/Opcode.h index a812ae23f6b7..70f2dbdf639f 100644 --- a/lldb/include/lldb/Core/Opcode.h +++ b/lldb/include/lldb/Core/Opcode.h @@ -14,9 +14,9 @@ #include "llvm/Support/SwapByteOrder.h" -#include <assert.h> -#include <stdint.h> -#include <string.h> +#include <cassert> +#include <cstdint> +#include <cstring> namespace lldb { class SBInstruction; @@ -38,7 +38,7 @@ public: eTypeBytes }; - Opcode() : m_byte_order(lldb::eByteOrderInvalid), m_type(eTypeInvalid) {} + Opcode() = default; Opcode(uint8_t inst, lldb::ByteOrder order) : m_byte_order(order), m_type(eType8) { @@ -252,9 +252,9 @@ protected: endian::InlHostByteOrder() == lldb::eByteOrderBig); } - lldb::ByteOrder m_byte_order; + lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; - Opcode::Type m_type; + Opcode::Type m_type = eTypeInvalid; union { uint8_t inst8; uint16_t inst16; diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index 0ac8308d1758..be91929c62e1 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -19,8 +19,8 @@ #include "lldb/lldb-private-interfaces.h" #include "llvm/ADT/StringRef.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName) \ namespace lldb_private { \ @@ -191,7 +191,8 @@ public: GetObjectFileCreateMemoryCallbackForPluginName(ConstString name); static Status SaveCore(const lldb::ProcessSP &process_sp, - const FileSpec &outfile); + const FileSpec &outfile, + lldb::SaveCoreStyle &core_style); // ObjectContainer static bool @@ -331,18 +332,20 @@ public: GetSymbolVendorCreateCallbackAtIndex(uint32_t idx); // Trace - static bool RegisterPlugin(ConstString name, const char *description, - TraceCreateInstance create_callback, - llvm::StringRef schema, - TraceGetStartCommand get_start_command); + static bool RegisterPlugin( + ConstString name, const char *description, + TraceCreateInstanceForSessionFile create_callback_for_session_file, + TraceCreateInstanceForLiveProcess create_callback_for_live_process, + llvm::StringRef schema); - static bool UnregisterPlugin(TraceCreateInstance create_callback); + static bool + UnregisterPlugin(TraceCreateInstanceForSessionFile create_callback); - static TraceCreateInstance GetTraceCreateCallback(ConstString plugin_name); + static TraceCreateInstanceForSessionFile + GetTraceCreateCallback(ConstString plugin_name); - static lldb::CommandObjectSP - GetTraceStartCommand(llvm::StringRef plugin_name, - CommandInterpreter &interpreter); + static TraceCreateInstanceForLiveProcess + GetTraceCreateCallbackForLiveProcess(ConstString plugin_name); /// Get the JSON schema for a trace session file corresponding to the given /// plugin. @@ -366,6 +369,28 @@ public: /// number plugins, otherwise the actual schema is returned. static llvm::StringRef GetTraceSchema(size_t index); + // TraceExporter + + /// \param[in] create_thread_trace_export_command + /// This callback is used to create a CommandObject that will be listed + /// under "thread trace export". Can be \b null. + static bool RegisterPlugin( + ConstString name, const char *description, + TraceExporterCreateInstance create_callback, + ThreadTraceExportCommandCreator create_thread_trace_export_command); + + static TraceExporterCreateInstance + GetTraceExporterCreateCallback(ConstString plugin_name); + + static bool UnregisterPlugin(TraceExporterCreateInstance create_callback); + + static const char *GetTraceExporterPluginNameAtIndex(uint32_t index); + + /// Return the callback used to create the CommandObject that will be listed + /// under "thread trace export". Can be \b null. + static ThreadTraceExportCommandCreator + GetThreadTraceExportCommandCreatorAtIndex(uint32_t index); + // UnwindAssembly static bool RegisterPlugin(ConstString name, const char *description, UnwindAssemblyCreateInstance create_callback); diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h new file mode 100644 index 000000000000..f625d014f268 --- /dev/null +++ b/lldb/include/lldb/Core/Progress.h @@ -0,0 +1,114 @@ +//===-- Progress.h ----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_CORE_PROGRESS_H +#define LLDB_CORE_PROGRESS_H + +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-types.h" +#include <atomic> +#include <mutex> + +namespace lldb_private { + +/// A Progress indicator helper class. +/// +/// Any potentially long running sections of code in LLDB should report +/// progress so that clients are aware of delays that might appear during +/// debugging. Delays commonly include indexing debug information, parsing +/// symbol tables for object files, downloading symbols from remote +/// repositories, and many more things. +/// +/// The Progress class helps make sure that progress is correctly reported +/// and will always send an initial progress update, updates when +/// Progress::Increment() is called, and also will make sure that a progress +/// completed update is reported even if the user doesn't explicitly cause one +/// to be sent. +/// +/// The progress is reported via a callback whose type is ProgressCallback: +/// +/// typedef void (*ProgressCallback)(uint64_t progress_id, +/// const char *message, +/// uint64_t completed, +/// uint64_t total, +/// void *baton); +/// +/// This callback will always initially be called with "completed" set to zero +/// and "total" set to the total amount specified in the contructor. This is +/// considered the progress start event. As Progress::Increment() is called, +/// the callback will be called as long as the Progress::m_completed has not +/// yet exceeded the Progress::m_total. When the callback is called with +/// Progress::m_completed == Progress::m_total, that is considered a progress +/// completed event. If Progress::m_completed is non-zero and less than +/// Progress::m_total, then this is considered a progress update event. +/// +/// This callback will be called in the destructor if Progress::m_completed is +/// not equal to Progress::m_total with the "completed" set to +/// Progress::m_total. This ensures we always send a progress completed update +/// even if the user does not. + +class Progress { +public: + /// Construct a progress object that will report information. + /// + /// The constructor will create a unique progress reporting object and + /// immediately send out a progress update by calling the installed callback + /// with completed set to zero out of the specified total. + /// + /// @param [in] title The title of this progress activity. + /// + /// @param [in] total The total units of work to be done if specified, if + /// set to UINT64_MAX then an indeterminate progress indicator should be + /// displayed. + /// + /// @param [in] debugger An optional debugger pointer to specify that this + /// progress is to be reported only to specific debuggers. + Progress(std::string title, uint64_t total = UINT64_MAX, + lldb_private::Debugger *debugger = nullptr); + + /// Destroy the progress object. + /// + /// If the progress has not yet sent a completion update, the destructor + /// will send out a notification where the completed == m_total. This ensures + /// that we always send out a progress complete notification. + ~Progress(); + + /// Increment the progress and send a notification to the intalled callback. + /// + /// If incrementing ends up exceeding m_total, m_completed will be updated + /// to match m_total and no subsequent progress notifications will be sent. + /// If no total was specified in the constructor, this function will not do + /// anything nor send any progress updates. + /// + /// @param [in] amount The amount to increment m_completed by. + void Increment(uint64_t amount = 1); + +private: + void ReportProgress(); + static std::atomic<uint64_t> g_id; + /// The title of the progress activity. + std::string m_title; + std::mutex m_mutex; + /// A unique integer identifier for progress reporting. + const uint64_t m_id; + /// How much work ([0...m_total]) that has been completed. + uint64_t m_completed; + /// Total amount of work, UINT64_MAX for non deterministic progress. + const uint64_t m_total; + /// The optional debugger ID to report progress to. If this has no value then + /// all debuggers will receive this event. + llvm::Optional<lldb::user_id_t> m_debugger_id; + /// Set to true when progress has been reported where m_completed == m_total + /// to ensure that we don't send progress updates after progress has + /// completed. + bool m_complete = false; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_PROGRESS_H diff --git a/lldb/include/lldb/Core/RichManglingContext.h b/lldb/include/lldb/Core/RichManglingContext.h index 68f80e73b724..48102ec0b1cf 100644 --- a/lldb/include/lldb/Core/RichManglingContext.h +++ b/lldb/include/lldb/Core/RichManglingContext.h @@ -24,12 +24,12 @@ namespace lldb_private { /// providers. See Mangled::DemangleWithRichManglingInfo() class RichManglingContext { public: - RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) { + RichManglingContext() { m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size)); m_ipd_buf[0] = '\0'; } - ~RichManglingContext() { std::free(m_ipd_buf); } + ~RichManglingContext(); /// Use the ItaniumPartialDemangler to obtain rich mangling information from /// the given mangled name. @@ -70,15 +70,18 @@ private: enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage }; /// Selects the rich mangling info provider. - InfoProvider m_provider; + InfoProvider m_provider = None; /// Reference to the buffer used for results of ParseXy() operations. llvm::StringRef m_buffer; /// Members for ItaniumPartialDemangler llvm::ItaniumPartialDemangler m_ipd; + /// Note: m_ipd_buf is a raw pointer due to being resized by realloc via + /// ItaniumPartialDemangler. It should be managed with malloc/free, not + /// new/delete. char *m_ipd_buf; - size_t m_ipd_buf_size; + size_t m_ipd_buf_size = 2048; /// Members for PluginCxxLanguage /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The @@ -86,6 +89,9 @@ private: /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. llvm::Any m_cxx_method_parser; + /// Clean up memory when using PluginCxxLanguage + void ResetCxxMethodParser(); + /// Clean up memory and set a new info provider for this instance. void ResetProvider(InfoProvider new_provider); diff --git a/lldb/include/lldb/Core/SearchFilter.h b/lldb/include/lldb/Core/SearchFilter.h index 54dc65e4410f..491e3ddc5985 100644 --- a/lldb/include/lldb/Core/SearchFilter.h +++ b/lldb/include/lldb/Core/SearchFilter.h @@ -15,7 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-forward.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { class Address; diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h index af2bb7896a5b..3d4ab154e743 100644 --- a/lldb/include/lldb/Core/Section.h +++ b/lldb/include/lldb/Core/Section.h @@ -21,8 +21,8 @@ #include <memory> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Address; diff --git a/lldb/include/lldb/Core/SourceLocationSpec.h b/lldb/include/lldb/Core/SourceLocationSpec.h new file mode 100644 index 000000000000..808931186dba --- /dev/null +++ b/lldb/include/lldb/Core/SourceLocationSpec.h @@ -0,0 +1,188 @@ +//===-- SourceLocationSpec.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UTILITY_SOURCELOCATIONSPEC_H +#define LLDB_UTILITY_SOURCELOCATIONSPEC_H + +#include "lldb/Core/Declaration.h" +#include "lldb/lldb-defines.h" +#include "llvm/ADT/Optional.h" + +#include <string> + +namespace lldb_private { + +/// \class SourceLocationSpec SourceLocationSpec.h +/// "lldb/Core/SourceLocationSpec.h" A source location specifier class. +/// +/// A source location specifier class that holds a Declaration object containing +/// a FileSpec with line and column information. The column line is optional. +/// It also holds search flags that can be fetched by resolvers to look inlined +/// declarations and/or exact matches. +class SourceLocationSpec { +public: + /// Constructor. + /// + /// Takes a \a file_spec with a \a line number and a \a column number. If + /// \a column is null or not provided, it is set to llvm::None. + /// + /// \param[in] file_spec + /// The full or partial path to a file. + /// + /// \param[in] line + /// The line number in the source file. + /// + /// \param[in] column + /// The column number in the line of the source file. + /// + /// \param[in] check_inlines + /// Whether to look for a match in inlined declaration. + /// + /// \param[in] exact_match + /// Whether to look for an exact match. + /// + explicit SourceLocationSpec(FileSpec file_spec, uint32_t line, + llvm::Optional<uint16_t> column = llvm::None, + bool check_inlines = false, + bool exact_match = false); + + SourceLocationSpec() = delete; + + /// Convert to boolean operator. + /// + /// This allows code to check a SourceLocationSpec object to see if it + /// contains anything valid using code such as: + /// + /// \code + /// SourceLocationSpec location_spec(...); + /// if (location_spec) + /// { ... + /// \endcode + /// + /// \return + /// A pointer to this object if both the file_spec and the line are valid, + /// nullptr otherwise. + explicit operator bool() const; + + /// Logical NOT operator. + /// + /// This allows code to check a SourceLocationSpec object to see if it is + /// invalid using code such as: + /// + /// \code + /// SourceLocationSpec location_spec(...); + /// if (!location_spec) + /// { ... + /// \endcode + /// + /// \return + /// Returns \b true if the object has an invalid file_spec or line number, + /// \b false otherwise. + bool operator!() const; + + /// Equal to operator + /// + /// Tests if this object is equal to \a rhs. + /// + /// \param[in] rhs + /// A const SourceLocationSpec object reference to compare this object + /// to. + /// + /// \return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + bool operator==(const SourceLocationSpec &rhs) const; + + /// Not equal to operator + /// + /// Tests if this object is not equal to \a rhs. + /// + /// \param[in] rhs + /// A const SourceLocationSpec object reference to compare this object + /// to. + /// + /// \return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + bool operator!=(const SourceLocationSpec &rhs) const; + + /// Less than to operator + /// + /// Tests if this object is less than \a rhs. + /// + /// \param[in] rhs + /// A const SourceLocationSpec object reference to compare this object + /// to. + /// + /// \return + /// \b true if this object is less than \a rhs, \b false + /// otherwise. + bool operator<(const SourceLocationSpec &rhs) const; + + /// Compare two SourceLocationSpec objects. + /// + /// If \a full is true, then the file_spec, the line and column must match. + /// If \a full is false, then only the file_spec and line number for \a lhs + /// and \a rhs are compared. This allows a SourceLocationSpec object that have + /// no column information to match a SourceLocationSpec objects that have + /// column information with matching file_spec and line component. + /// + /// \param[in] lhs + /// A const reference to the Left Hand Side object to compare. + /// + /// \param[in] rhs + /// A const reference to the Right Hand Side object to compare. + /// + /// \param[in] full + /// If true, then the file_spec, the line and column must match for a + /// compare to return zero (equal to). If false, then only the file_spec + /// and line number for \a lhs and \a rhs are compared, else a full + /// comparison is done. + /// + /// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs, + /// 1 if \a lhs is greater than \a rhs + static int Compare(const SourceLocationSpec &lhs, + const SourceLocationSpec &rhs); + + static bool Equal(const SourceLocationSpec &lhs, + const SourceLocationSpec &rhs, bool full); + + /// Dump this object to a Stream. + /// + /// Dump the object to the supplied stream \a s, starting with the file name, + /// then the line number and if available the column number. + /// + /// \param[in] s + /// The stream to which to dump the object description. + void Dump(Stream &s) const; + + std::string GetString() const; + + FileSpec GetFileSpec() const { return m_declaration.GetFile(); } + + llvm::Optional<uint32_t> GetLine() const; + + llvm::Optional<uint16_t> GetColumn() const; + + bool GetCheckInlines() const { return m_check_inlines; } + + bool GetExactMatch() const { return m_exact_match; } + +protected: + Declaration m_declaration; + /// Tells if the resolver should look in inlined declaration. + bool m_check_inlines; + /// Tells if the resolver should look for an exact match. + bool m_exact_match; +}; + +/// Dump a SourceLocationSpec object to a stream +Stream &operator<<(Stream &s, const SourceLocationSpec &loc); +} // namespace lldb_private + +#endif // LLDB_UTILITY_SOURCELOCATIONSPEC_H diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h index 7549c308f33a..5f2c1de84652 100644 --- a/lldb/include/lldb/Core/SourceManager.h +++ b/lldb/include/lldb/Core/SourceManager.h @@ -15,10 +15,10 @@ #include "llvm/Support/Chrono.h" +#include <cstddef> #include <cstdint> #include <map> #include <memory> -#include <stddef.h> #include <string> #include <vector> diff --git a/lldb/include/lldb/Core/StreamAsynchronousIO.h b/lldb/include/lldb/Core/StreamAsynchronousIO.h index 949a798955d1..30eff55b2e51 100644 --- a/lldb/include/lldb/Core/StreamAsynchronousIO.h +++ b/lldb/include/lldb/Core/StreamAsynchronousIO.h @@ -13,7 +13,7 @@ #include <string> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Debugger; diff --git a/lldb/include/lldb/Core/StreamBuffer.h b/lldb/include/lldb/Core/StreamBuffer.h index 9c48ddb44d71..2e61a214302b 100644 --- a/lldb/include/lldb/Core/StreamBuffer.h +++ b/lldb/include/lldb/Core/StreamBuffer.h @@ -11,7 +11,7 @@ #include "lldb/Utility/Stream.h" #include "llvm/ADT/SmallVector.h" -#include <stdio.h> +#include <cstdio> #include <string> namespace lldb_private { @@ -23,7 +23,7 @@ public: StreamBuffer(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order) : Stream(flags, addr_size, byte_order), m_packet() {} - ~StreamBuffer() override {} + ~StreamBuffer() override = default; void Flush() override { // Nothing to do when flushing a buffer based stream... diff --git a/lldb/include/lldb/Core/StreamFile.h b/lldb/include/lldb/Core/StreamFile.h index e71e31eb1d04..dba4042b6ec9 100644 --- a/lldb/include/lldb/Core/StreamFile.h +++ b/lldb/include/lldb/Core/StreamFile.h @@ -14,8 +14,8 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" -#include <stdint.h> -#include <stdio.h> +#include <cstdint> +#include <cstdio> namespace lldb_private { diff --git a/lldb/include/lldb/Core/ThreadSafeValue.h b/lldb/include/lldb/Core/ThreadSafeValue.h index 38b8034fad53..51820ec9cd9d 100644 --- a/lldb/include/lldb/Core/ThreadSafeValue.h +++ b/lldb/include/lldb/Core/ThreadSafeValue.h @@ -17,12 +17,10 @@ namespace lldb_private { template <class T> class ThreadSafeValue { public: - // Constructors and Destructors - ThreadSafeValue() : m_value(), m_mutex() {} - + ThreadSafeValue() = default; ThreadSafeValue(const T &value) : m_value(value), m_mutex() {} - ~ThreadSafeValue() {} + ~ThreadSafeValue() = default; T GetValue() const { T value; diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h index f40ad54ac4d6..35555f08c351 100644 --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -17,8 +17,8 @@ #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class CommandInterpreter; @@ -32,12 +32,12 @@ namespace lldb_private { class Properties { public: - Properties() : m_collection_sp() {} + Properties() = default; Properties(const lldb::OptionValuePropertiesSP &collection_sp) : m_collection_sp(collection_sp) {} - virtual ~Properties() {} + virtual ~Properties() = default; virtual lldb::OptionValuePropertiesSP GetValueProperties() const { // This function is virtual in case subclasses want to lazily implement diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h index 0ff773e59911..1ee4fe639e6e 100644 --- a/lldb/include/lldb/Core/Value.h +++ b/lldb/include/lldb/Core/Value.h @@ -21,8 +21,8 @@ #include <vector> -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> namespace lldb_private { class DataExtractor; @@ -37,27 +37,32 @@ namespace lldb_private { class Value { public: - // Values Less than zero are an error, greater than or equal to zero returns - // what the Scalar result is. - enum ValueType { - // m_value contains... - // ============================ - eValueTypeScalar, // raw scalar value - eValueTypeFileAddress, // file address value - eValueTypeLoadAddress, // load address value - eValueTypeHostAddress // host address value (for memory in the process that - // is using liblldb) + /// Type that describes Value::m_value. + enum class ValueType { + Invalid = -1, + // m_value contains: + /// A raw scalar value. + Scalar = 0, + /// A file address value. + FileAddress, + /// A load address value. + LoadAddress, + /// A host address value (for memory in the process that < A is + /// using liblldb). + HostAddress }; - enum ContextType // Type that describes Value::m_context - { - // m_context contains... - // ==================== - eContextTypeInvalid, // undefined - eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector - // register) - eContextTypeLLDBType, // lldb_private::Type * - eContextTypeVariable // lldb_private::Variable * + /// Type that describes Value::m_context. + enum class ContextType { + // m_context contains: + /// Undefined. + Invalid = -1, + /// RegisterInfo * (can be a scalar or a vector register). + RegisterInfo = 0, + /// lldb_private::Type *. + LLDBType, + /// lldb_private::Variable *. + Variable }; Value(); @@ -85,16 +90,16 @@ public: void ClearContext() { m_context = nullptr; - m_context_type = eContextTypeInvalid; + m_context_type = ContextType::Invalid; } void SetContext(ContextType context_type, void *p) { m_context_type = context_type; m_context = p; - if (m_context_type == eContextTypeRegisterInfo) { + if (m_context_type == ContextType::RegisterInfo) { RegisterInfo *reg_info = GetRegisterInfo(); if (reg_info->encoding == lldb::eEncodingVector) - SetValueType(eValueTypeScalar); + SetValueType(ValueType::Scalar); } } @@ -143,9 +148,9 @@ public: protected: Scalar m_value; CompilerType m_compiler_type; - void *m_context; - ValueType m_value_type; - ContextType m_context_type; + void *m_context = nullptr; + ValueType m_value_type = ValueType::Scalar; + ContextType m_context_type = ContextType::Invalid; DataBufferHeap m_data_buffer; }; diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index a665e7afa0ca..5f1cbc65b320 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -37,8 +37,8 @@ #include <string> #include <utility> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Declaration; @@ -102,7 +102,7 @@ class TypeSummaryOptions; /// Shared Pointer to the contained ValueObject, /// just do so by calling GetSP() on the contained object. -class ValueObject : public UserID { +class ValueObject { public: enum GetExpressionPathFormat { eGetExpressionPathFormatDereferencePointers = 1, @@ -121,55 +121,62 @@ public: }; enum ExpressionPathScanEndReason { - eExpressionPathScanEndReasonEndOfString = 1, // out of data to parse - eExpressionPathScanEndReasonNoSuchChild, // child element not found - eExpressionPathScanEndReasonNoSuchSyntheticChild, // (synthetic) child - // element not found - eExpressionPathScanEndReasonEmptyRangeNotAllowed, // [] only allowed for - // arrays - eExpressionPathScanEndReasonDotInsteadOfArrow, // . used when -> should be - // used - eExpressionPathScanEndReasonArrowInsteadOfDot, // -> used when . should be - // used - eExpressionPathScanEndReasonFragileIVarNotAllowed, // ObjC ivar expansion - // not allowed - eExpressionPathScanEndReasonRangeOperatorNotAllowed, // [] not allowed by - // options - eExpressionPathScanEndReasonRangeOperatorInvalid, // [] not valid on objects - // other than scalars, - // pointers or arrays - eExpressionPathScanEndReasonArrayRangeOperatorMet, // [] is good for arrays, - // but I cannot parse it - eExpressionPathScanEndReasonBitfieldRangeOperatorMet, // [] is good for - // bitfields, but I - // cannot parse after - // it - eExpressionPathScanEndReasonUnexpectedSymbol, // something is malformed in - // the expression - eExpressionPathScanEndReasonTakingAddressFailed, // impossible to apply & - // operator - eExpressionPathScanEndReasonDereferencingFailed, // impossible to apply * - // operator - eExpressionPathScanEndReasonRangeOperatorExpanded, // [] was expanded into a - // VOList - eExpressionPathScanEndReasonSyntheticValueMissing, // getting the synthetic - // children failed + /// Out of data to parse. + eExpressionPathScanEndReasonEndOfString = 1, + /// Child element not found. + eExpressionPathScanEndReasonNoSuchChild, + /// (Synthetic) child element not found. + eExpressionPathScanEndReasonNoSuchSyntheticChild, + /// [] only allowed for arrays. + eExpressionPathScanEndReasonEmptyRangeNotAllowed, + /// . used when -> should be used. + eExpressionPathScanEndReasonDotInsteadOfArrow, + /// -> used when . should be used. + eExpressionPathScanEndReasonArrowInsteadOfDot, + /// ObjC ivar expansion not allowed. + eExpressionPathScanEndReasonFragileIVarNotAllowed, + /// [] not allowed by options. + eExpressionPathScanEndReasonRangeOperatorNotAllowed, + /// [] not valid on objects other than scalars, pointers or arrays. + eExpressionPathScanEndReasonRangeOperatorInvalid, + /// [] is good for arrays, but I cannot parse it. + eExpressionPathScanEndReasonArrayRangeOperatorMet, + /// [] is good for bitfields, but I cannot parse after it. + eExpressionPathScanEndReasonBitfieldRangeOperatorMet, + /// Something is malformed in he expression. + eExpressionPathScanEndReasonUnexpectedSymbol, + /// Impossible to apply & operator. + eExpressionPathScanEndReasonTakingAddressFailed, + /// Impossible to apply * operator. + eExpressionPathScanEndReasonDereferencingFailed, + /// [] was expanded into a VOList. + eExpressionPathScanEndReasonRangeOperatorExpanded, + /// getting the synthetic children failed. + eExpressionPathScanEndReasonSyntheticValueMissing, eExpressionPathScanEndReasonUnknown = 0xFFFF }; enum ExpressionPathEndResultType { - eExpressionPathEndResultTypePlain = 1, // anything but... - eExpressionPathEndResultTypeBitfield, // a bitfield - eExpressionPathEndResultTypeBoundedRange, // a range [low-high] - eExpressionPathEndResultTypeUnboundedRange, // a range [] - eExpressionPathEndResultTypeValueObjectList, // several items in a VOList + /// Anything but... + eExpressionPathEndResultTypePlain = 1, + /// A bitfield. + eExpressionPathEndResultTypeBitfield, + /// A range [low-high]. + eExpressionPathEndResultTypeBoundedRange, + /// A range []. + eExpressionPathEndResultTypeUnboundedRange, + /// Several items in a VOList. + eExpressionPathEndResultTypeValueObjectList, eExpressionPathEndResultTypeInvalid = 0xFFFF }; enum ExpressionPathAftermath { - eExpressionPathAftermathNothing = 1, // just return it - eExpressionPathAftermathDereference, // dereference the target - eExpressionPathAftermathTakeAddress // take target's address + /// Just return it. + eExpressionPathAftermathNothing = 1, + /// Dereference the target. + eExpressionPathAftermathDereference, + /// Take target's address. + eExpressionPathAftermathTakeAddress }; enum ClearUserVisibleDataItems { @@ -265,14 +272,6 @@ public: return m_exe_ctx_ref; } - // Set the EvaluationPoint to the values in exe_scope, Return true if the - // Evaluation Point changed. Since the ExecutionContextScope is always - // going to be valid currently, the Updated Context will also always be - // valid. - - // bool - // SetContext (ExecutionContextScope *exe_scope); - void SetIsConstant() { SetUpdated(); m_mod_id.SetInvalid(); @@ -319,7 +318,7 @@ public: ProcessModID m_mod_id; // This is the stop id when this ValueObject was last // evaluated. ExecutionContextRef m_exe_ctx_ref; - bool m_needs_update; + bool m_needs_update = true; }; virtual ~ValueObject(); @@ -350,10 +349,10 @@ public: void SetNeedsUpdate(); - CompilerType GetCompilerType(); + CompilerType GetCompilerType() { return MaybeCalculateCompleteType(); } // this vends a TypeImpl that is useful at the SB API layer - virtual TypeImpl GetTypeImpl(); + virtual TypeImpl GetTypeImpl() { return TypeImpl(GetCompilerType()); } virtual bool CanProvideValue(); @@ -363,24 +362,32 @@ public: virtual lldb::ValueType GetValueType() const = 0; // Subclasses can implement the functions below. - virtual ConstString GetTypeName(); + virtual ConstString GetTypeName() { return GetCompilerType().GetTypeName(); } - virtual ConstString GetDisplayTypeName(); + virtual ConstString GetDisplayTypeName() { return GetTypeName(); } - virtual ConstString GetQualifiedTypeName(); + virtual ConstString GetQualifiedTypeName() { + return GetCompilerType().GetTypeName(); + } - virtual lldb::LanguageType GetObjectRuntimeLanguage(); + virtual lldb::LanguageType GetObjectRuntimeLanguage() { + return GetCompilerType().GetMinimumLanguage(); + } virtual uint32_t - GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr); + GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) { + return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type); + } - virtual bool IsPointerType(); + virtual bool IsPointerType() { return GetCompilerType().IsPointerType(); } - virtual bool IsArrayType(); + virtual bool IsArrayType() { return GetCompilerType().IsArrayType(); } - virtual bool IsScalarType(); + virtual bool IsScalarType() { return GetCompilerType().IsScalarType(); } - virtual bool IsPointerOrReferenceType(); + virtual bool IsPointerOrReferenceType() { + return GetCompilerType().IsPointerOrReferenceType(); + } virtual bool IsPossibleDynamicType(); @@ -394,7 +401,9 @@ public: virtual bool IsDereferenceOfParent() { return false; } - bool IsIntegerType(bool &is_signed); + bool IsIntegerType(bool &is_signed) { + return GetCompilerType().IsIntegerType(is_signed); + } virtual void GetExpressionPath( Stream &s, @@ -420,7 +429,9 @@ public: return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0); } - virtual bool IsArrayItemForPointer() { return m_is_array_item_for_pointer; } + virtual bool IsArrayItemForPointer() { + return m_flags.m_is_array_item_for_pointer; + } virtual const char *GetValueAsCString(); @@ -436,16 +447,16 @@ public: virtual bool SetValueFromCString(const char *value_str, Status &error); - // Return the module associated with this value object in case the value is - // from an executable file and might have its data in sections of the file. - // This can be used for variables. + /// Return the module associated with this value object in case the value is + /// from an executable file and might have its data in sections of the file. + /// This can be used for variables. virtual lldb::ModuleSP GetModule(); ValueObject *GetRoot(); - // Given a ValueObject, loop over itself and its parent, and its parent's - // parent, .. until either the given callback returns false, or you end up at - // a null pointer + /// Given a ValueObject, loop over itself and its parent, and its parent's + /// parent, .. until either the given callback returns false, or you end up at + /// a null pointer ValueObject *FollowParentChain(std::function<bool(ValueObject *)>); virtual bool GetDeclaration(Declaration &decl); @@ -453,7 +464,10 @@ public: // The functions below should NOT be modified by subclasses const Status &GetError(); - ConstString GetName() const; + ConstString GetName() const { return m_name; } + + /// Returns a unique id for this ValueObject. + lldb::user_id_t GetID() const { return m_id.GetID(); } virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create); @@ -480,9 +494,9 @@ public: size_t GetNumChildren(uint32_t max = UINT32_MAX); - const Value &GetValue() const; + const Value &GetValue() const { return m_value; } - Value &GetValue(); + Value &GetValue() { return m_value; } virtual bool ResolveValue(Scalar &scalar); @@ -491,7 +505,9 @@ public: // potentially a few others virtual bool IsLogicalTrue(Status &error); - virtual const char *GetLocationAsCString(); + virtual const char *GetLocationAsCString() { + return GetLocationAsCStringImpl(m_value, m_data); + } const char * GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown); @@ -526,11 +542,11 @@ public: PrintableRepresentationSpecialCases special = PrintableRepresentationSpecialCases::eAllow, bool do_dump_error = true); - bool GetValueIsValid() const; + bool GetValueIsValid() const { return m_flags.m_value_is_valid; } // If you call this on a newly created ValueObject, it will always return // false. - bool GetValueDidChange(); + bool GetValueDidChange() { return m_flags.m_value_did_change; } bool UpdateValueIfNeeded(bool update_format = true); @@ -538,10 +554,10 @@ public: lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(this); } - // Change the name of the current ValueObject. Should *not* be used from a - // synthetic child provider as it would change the name of the non synthetic - // child as well. - void SetName(ConstString name); + /// Change the name of the current ValueObject. Should *not* be used from a + /// synthetic child provider as it would change the name of the non synthetic + /// child as well. + void SetName(ConstString name) { m_name = name; } virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true, AddressType *address_type = nullptr); @@ -571,9 +587,9 @@ public: lldb::DynamicValueType GetDynamicValueType(); - virtual lldb::ValueObjectSP GetStaticValue(); + virtual lldb::ValueObjectSP GetStaticValue() { return GetSP(); } - virtual lldb::ValueObjectSP GetNonSyntheticValue(); + virtual lldb::ValueObjectSP GetNonSyntheticValue() { return GetSP(); } lldb::ValueObjectSP GetSyntheticValue(); @@ -589,10 +605,10 @@ public: virtual lldb::ValueObjectSP Dereference(Status &error); - // Creates a copy of the ValueObject with a new name and setting the current - // ValueObject as its parent. It should be used when we want to change the - // name of a ValueObject without modifying the actual ValueObject itself - // (e.g. sythetic child provider). + /// Creates a copy of the ValueObject with a new name and setting the current + /// ValueObject as its parent. It should be used when we want to change the + /// name of a ValueObject without modifying the actual ValueObject itself + /// (e.g. sythetic child provider). virtual lldb::ValueObjectSP Clone(ConstString new_name); virtual lldb::ValueObjectSP AddressOf(Status &error); @@ -611,7 +627,7 @@ public: lldb::TypeSP &type_sp); // The backing bits of this value object were updated, clear any descriptive - // string, so we know we have to refetch them + // string, so we know we have to refetch them. virtual void ValueUpdated() { ClearUserVisibleData(eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | @@ -622,9 +638,13 @@ public: virtual bool DoesProvideSyntheticValue() { return false; } - virtual bool IsSyntheticChildrenGenerated(); + virtual bool IsSyntheticChildrenGenerated() { + return m_flags.m_is_synthetic_children_generated; + } - virtual void SetSyntheticChildrenGenerated(bool b); + virtual void SetSyntheticChildrenGenerated(bool b) { + m_flags.m_is_synthetic_children_generated = b; + } virtual SymbolContextScope *GetSymbolContextScope(); @@ -652,14 +672,10 @@ public: CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type); - void LogValueObject(Log *log); - - void LogValueObject(Log *log, const DumpValueObjectOptions &options); - lldb::ValueObjectSP Persist(); - // returns true if this is a char* or a char[] if it is a char* and - // check_pointer is true, it also checks that the pointer is valid + /// Returns true if this is a char* or a char[] if it is a char* and + /// check_pointer is true, it also checks that the pointer is valid. bool IsCStringContainer(bool check_pointer = false); std::pair<size_t, bool> @@ -694,7 +710,9 @@ public: virtual lldb::LanguageType GetPreferredDisplayLanguage(); - void SetPreferredDisplayLanguage(lldb::LanguageType); + void SetPreferredDisplayLanguage(lldb::LanguageType lt) { + m_preferred_display_language = lt; + } lldb::TypeSummaryImplSP GetSummaryFormat() { UpdateFormatsIfNeeded(); @@ -744,7 +762,9 @@ public: AddressType GetAddressTypeOfChildren(); - void SetHasCompleteType() { m_did_calculate_complete_objc_class_type = true; } + void SetHasCompleteType() { + m_flags.m_did_calculate_complete_objc_class_type = true; + } /// Find out if a ValueObject might have children. /// @@ -766,16 +786,16 @@ public: virtual bool IsRuntimeSupportValue(); - virtual uint64_t GetLanguageFlags(); + virtual uint64_t GetLanguageFlags() { return m_language_flags; } - virtual void SetLanguageFlags(uint64_t flags); + virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; } protected: typedef ClusterManager<ValueObject> ValueObjectManager; class ChildrenManager { public: - ChildrenManager() : m_mutex(), m_children(), m_children_count(0) {} + ChildrenManager() : m_mutex(), m_children() {} bool HasChildAtIndex(size_t idx) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -811,80 +831,102 @@ protected: typedef ChildrenMap::value_type ChildrenPair; std::recursive_mutex m_mutex; ChildrenMap m_children; - size_t m_children_count; + size_t m_children_count = 0; }; // Classes that inherit from ValueObject can see and modify these - ValueObject - *m_parent; // The parent value object, or nullptr if this has no parent - ValueObject *m_root; // The root of the hierarchy for this ValueObject (or - // nullptr if never calculated) - EvaluationPoint m_update_point; // Stores both the stop id and the full - // context at which this value was last - // updated. When we are asked to update the value object, we check whether - // the context & stop id are the same before updating. - ConstString m_name; // The name of this object - DataExtractor - m_data; // A data extractor that can be used to extract the value. + + /// The parent value object, or nullptr if this has no parent. + ValueObject *m_parent = nullptr; + /// The root of the hierarchy for this ValueObject (or nullptr if never + /// calculated). + ValueObject *m_root = nullptr; + /// Stores both the stop id and the full context at which this value was last + /// updated. When we are asked to update the value object, we check whether + /// the context & stop id are the same before updating. + EvaluationPoint m_update_point; + /// The name of this object. + ConstString m_name; + /// A data extractor that can be used to extract the value. + DataExtractor m_data; Value m_value; - Status - m_error; // An error object that can describe any errors that occur when - // updating values. - std::string m_value_str; // Cached value string that will get cleared if/when - // the value is updated. - std::string m_old_value_str; // Cached old value string from the last time the - // value was gotten - std::string m_location_str; // Cached location string that will get cleared - // if/when the value is updated. - std::string m_summary_str; // Cached summary string that will get cleared - // if/when the value is updated. - std::string m_object_desc_str; // Cached result of the "object printer". This - // differs from the summary - // in that the summary is consed up by us, the object_desc_string is builtin. - - CompilerType m_override_type; // If the type of the value object should be - // overridden, the type to impose. - - ValueObjectManager *m_manager; // This object is managed by the root object - // (any ValueObject that gets created - // without a parent.) The manager gets passed through all the generations of - // dependent objects, and will keep the whole cluster of objects alive as - // long as a shared pointer to any of them has been handed out. Shared - // pointers to value objects must always be made with the GetSP method. + /// An error object that can describe any errors that occur when updating + /// values. + Status m_error; + /// Cached value string that will get cleared if/when the value is updated. + std::string m_value_str; + /// Cached old value string from the last time the value was gotten + std::string m_old_value_str; + /// Cached location string that will get cleared if/when the value is updated. + std::string m_location_str; + /// Cached summary string that will get cleared if/when the value is updated. + std::string m_summary_str; + /// Cached result of the "object printer". This differs from the summary + /// in that the summary is consed up by us, the object_desc_string is builtin. + std::string m_object_desc_str; + /// If the type of the value object should be overridden, the type to impose. + CompilerType m_override_type; + + /// This object is managed by the root object (any ValueObject that gets + /// created without a parent.) The manager gets passed through all the + /// generations of dependent objects, and will keep the whole cluster of + /// objects alive as long as a shared pointer to any of them has been handed + /// out. Shared pointers to value objects must always be made with the GetSP + /// method. + ValueObjectManager *m_manager = nullptr; ChildrenManager m_children; std::map<ConstString, ValueObject *> m_synthetic_children; - ValueObject *m_dynamic_value; - ValueObject *m_synthetic_value; - ValueObject *m_deref_valobj; + ValueObject *m_dynamic_value = nullptr; + ValueObject *m_synthetic_value = nullptr; + ValueObject *m_deref_valobj = nullptr; - lldb::ValueObjectSP m_addr_of_valobj_sp; // We have to hold onto a shared - // pointer to this one because it is - // created - // as an independent ValueObjectConstResult, which isn't managed by us. + /// We have to hold onto a shared pointer to this one because it is created + /// as an independent ValueObjectConstResult, which isn't managed by us. + lldb::ValueObjectSP m_addr_of_valobj_sp; - lldb::Format m_format; - lldb::Format m_last_format; - uint32_t m_last_format_mgr_revision; + lldb::Format m_format = lldb::eFormatDefault; + lldb::Format m_last_format = lldb::eFormatDefault; + uint32_t m_last_format_mgr_revision = 0; lldb::TypeSummaryImplSP m_type_summary_sp; lldb::TypeFormatImplSP m_type_format_sp; lldb::SyntheticChildrenSP m_synthetic_children_sp; ProcessModID m_user_id_of_forced_summary; - AddressType m_address_type_of_ptr_or_ref_children; + AddressType m_address_type_of_ptr_or_ref_children = eAddressTypeInvalid; llvm::SmallVector<uint8_t, 16> m_value_checksum; - lldb::LanguageType m_preferred_display_language; - - uint64_t m_language_flags; - - bool m_value_is_valid : 1, m_value_did_change : 1, m_children_count_valid : 1, - m_old_value_valid : 1, m_is_deref_of_parent : 1, - m_is_array_item_for_pointer : 1, m_is_bitfield_for_scalar : 1, - m_is_child_at_offset : 1, m_is_getting_summary : 1, - m_did_calculate_complete_objc_class_type : 1, - m_is_synthetic_children_generated : 1; + lldb::LanguageType m_preferred_display_language = lldb::eLanguageTypeUnknown; + + uint64_t m_language_flags = 0; + + /// Unique identifier for every value object. + UserID m_id; + + // Utility class for initializing all bitfields in ValueObject's constructors. + // FIXME: This could be done via default initializers once we have C++20. + struct Bitflags { + bool m_value_is_valid : 1, m_value_did_change : 1, + m_children_count_valid : 1, m_old_value_valid : 1, + m_is_deref_of_parent : 1, m_is_array_item_for_pointer : 1, + m_is_bitfield_for_scalar : 1, m_is_child_at_offset : 1, + m_is_getting_summary : 1, m_did_calculate_complete_objc_class_type : 1, + m_is_synthetic_children_generated : 1; + Bitflags() { + m_value_is_valid = false; + m_value_did_change = false; + m_children_count_valid = false; + m_old_value_valid = false; + m_is_deref_of_parent = false; + m_is_array_item_for_pointer = false; + m_is_bitfield_for_scalar = false; + m_is_child_at_offset = false; + m_is_getting_summary = false; + m_did_calculate_complete_objc_class_type = false; + m_is_synthetic_children_generated = false; + } + } m_flags; friend class ValueObjectChild; friend class ExpressionVariable; // For SetName @@ -892,22 +934,13 @@ protected: friend class ValueObjectConstResultImpl; friend class ValueObjectSynthetic; // For ClearUserVisibleData - // Constructors and Destructors - - // Use the no-argument constructor to make a constant variable object (with - // no ExecutionContextScope.) - - ValueObject(); - - // Use this constructor to create a "root variable object". The ValueObject - // will be locked to this context through-out its lifespan. - + /// Use this constructor to create a "root variable object". The ValueObject + /// will be locked to this context through-out its lifespan. ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad); - // Use this constructor to create a ValueObject owned by another ValueObject. - // It will inherit the ExecutionContext of its parent. - + /// Use this constructor to create a ValueObject owned by another ValueObject. + /// It will inherit the ExecutionContext of its parent. ValueObject(ValueObject &parent); ValueObjectManager *GetManager() { return m_manager; } @@ -928,20 +961,23 @@ protected: virtual void CalculateSyntheticValue(); - // Should only be called by ValueObject::GetChildAtIndex() Returns a - // ValueObject managed by this ValueObject's manager. + /// Should only be called by ValueObject::GetChildAtIndex(). + /// + /// \return A ValueObject managed by this ValueObject's manager. virtual ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index); - // Should only be called by ValueObject::GetNumChildren() + /// Should only be called by ValueObject::GetNumChildren(). virtual size_t CalculateNumChildren(uint32_t max = UINT32_MAX) = 0; void SetNumChildren(size_t num_children); - void SetValueDidChange(bool value_changed); + void SetValueDidChange(bool value_changed) { + m_flags.m_value_did_change = value_changed; + } - void SetValueIsValid(bool valid); + void SetValueIsValid(bool valid) { m_flags.m_value_is_valid = valid; } void ClearUserVisibleData( uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings); @@ -959,7 +995,7 @@ protected: const char *GetLocationAsCStringImpl(const Value &value, const DataExtractor &data); - bool IsChecksumEmpty(); + bool IsChecksumEmpty() { return m_value_checksum.empty(); } void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType); @@ -983,47 +1019,6 @@ private: const ValueObject &operator=(const ValueObject &) = delete; }; -// A value object manager class that is seeded with the static variable value -// and it vends the user facing value object. If the type is dynamic it can -// vend the dynamic type. If this user type also has a synthetic type -// associated with it, it will vend the synthetic type. The class watches the -// process' stop -// ID and will update the user type when needed. -class ValueObjectManager { - // The root value object is the static typed variable object. - lldb::ValueObjectSP m_root_valobj_sp; - // The user value object is the value object the user wants to see. - lldb::ValueObjectSP m_user_valobj_sp; - lldb::DynamicValueType m_use_dynamic; - uint32_t m_stop_id; // The stop ID that m_user_valobj_sp is valid for. - bool m_use_synthetic; - -public: - ValueObjectManager() {} - - ValueObjectManager(lldb::ValueObjectSP in_valobj_sp, - lldb::DynamicValueType use_dynamic, bool use_synthetic); - - bool IsValid() const; - - lldb::ValueObjectSP GetRootSP() const { return m_root_valobj_sp; } - - // Gets the correct value object from the root object for a given process - // stop ID. If dynamic values are enabled, or if synthetic children are - // enabled, the value object that the user wants to see might change while - // debugging. - lldb::ValueObjectSP GetSP(); - - void SetUseDynamic(lldb::DynamicValueType use_dynamic); - void SetUseSynthetic(bool use_synthetic); - lldb::DynamicValueType GetUseDynamic() const { return m_use_dynamic; } - bool GetUseSynthetic() const { return m_use_synthetic; } - lldb::TargetSP GetTargetSP() const; - lldb::ProcessSP GetProcessSP() const; - lldb::ThreadSP GetThreadSP() const; - lldb::StackFrameSP GetFrameSP() const; -}; - } // namespace lldb_private #endif // LLDB_CORE_VALUEOBJECT_H diff --git a/lldb/include/lldb/Core/ValueObjectCast.h b/lldb/include/lldb/Core/ValueObjectCast.h index 342803f8ca63..84cf13353aee 100644 --- a/lldb/include/lldb/Core/ValueObjectCast.h +++ b/lldb/include/lldb/Core/ValueObjectCast.h @@ -15,13 +15,13 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ConstString; -// A ValueObject that represents a given value represented as a different type. +/// A ValueObject that represents a given value represented as a different type. class ValueObjectCast : public ValueObject { public: ~ValueObjectCast() override; diff --git a/lldb/include/lldb/Core/ValueObjectChild.h b/lldb/include/lldb/Core/ValueObjectChild.h index 9a9fd9294261..8a7a7f17bc76 100644 --- a/lldb/include/lldb/Core/ValueObjectChild.h +++ b/lldb/include/lldb/Core/ValueObjectChild.h @@ -20,12 +20,12 @@ #include "llvm/ADT/Optional.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { -// A child of another ValueObject. +/// A child of another ValueObject. class ValueObjectChild : public ValueObject { public: ~ValueObjectChild() override; @@ -71,10 +71,6 @@ protected: bool m_is_deref_of_parent; llvm::Optional<LazyBool> m_can_update_with_invalid_exe_ctx; - // - // void - // ReadValueFromMemory (ValueObject* parent, lldb::addr_t address); - friend class ValueObject; friend class ValueObjectConstResult; friend class ValueObjectConstResultImpl; diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h index 8d823baa0b7b..58cda6fd6196 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -21,15 +21,15 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; class ExecutionContextScope; class Module; -// A frozen ValueObject copied into host memory +/// A frozen ValueObject copied into host memory. class ValueObjectConstResult : public ValueObject { public: ~ValueObjectConstResult() override; diff --git a/lldb/include/lldb/Core/ValueObjectConstResultCast.h b/lldb/include/lldb/Core/ValueObjectConstResultCast.h index ba81785866c3..5467ce3db403 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultCast.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultCast.h @@ -17,8 +17,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/lldb/include/lldb/Core/ValueObjectConstResultChild.h index b3606bfde0ef..26bd9f337a59 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultChild.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultChild.h @@ -17,8 +17,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/lldb/include/lldb/Core/ValueObjectConstResultImpl.h index 1316bf66dfdb..2536c51fa574 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultImpl.h @@ -15,8 +15,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class CompilerType; class DataExtractor; @@ -26,9 +26,9 @@ class ValueObject; namespace lldb_private { -// A class wrapping common implementation details for operations in -// ValueObjectConstResult ( & Child ) that may need to jump from the host -// memory space into the target's memory space +/// A class wrapping common implementation details for operations in +/// ValueObjectConstResult ( & Child ) that may need to jump from the host +/// memory space into the target's memory space. class ValueObjectConstResultImpl { public: ValueObjectConstResultImpl(ValueObject *valobj, diff --git a/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 2806857339ef..8822a1d39249 100644 --- a/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -19,17 +19,17 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-private-enumerations.h" -#include <assert.h> -#include <stddef.h> -#include <stdint.h> +#include <cassert> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; class Declaration; class Status; -// A ValueObject that represents memory at a given address, viewed as some -// set lldb type. +/// A ValueObject that represents memory at a given address, viewed as some +/// set lldb type. class ValueObjectDynamicValue : public ValueObject { public: ~ValueObjectDynamicValue() override; diff --git a/lldb/include/lldb/Core/ValueObjectList.h b/lldb/include/lldb/Core/ValueObjectList.h index f99fba41aa26..fcb358e21a26 100644 --- a/lldb/include/lldb/Core/ValueObjectList.h +++ b/lldb/include/lldb/Core/ValueObjectList.h @@ -14,12 +14,12 @@ #include <vector> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class ValueObject; -// A collection of ValueObject values that +/// A collection of ValueObject values that. class ValueObjectList { public: const ValueObjectList &operator=(const ValueObjectList &rhs); diff --git a/lldb/include/lldb/Core/ValueObjectMemory.h b/lldb/include/lldb/Core/ValueObjectMemory.h index b5d5e6ecf4c0..83671a794b5f 100644 --- a/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/lldb/include/lldb/Core/ValueObjectMemory.h @@ -18,14 +18,14 @@ #include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ExecutionContextScope; -// A ValueObject that represents memory at a given address, viewed as some -// set lldb type. +/// A ValueObject that represents memory at a given address, viewed as some +/// set lldb type. class ValueObjectMemory : public ValueObject { public: ~ValueObjectMemory() override; diff --git a/lldb/include/lldb/Core/ValueObjectRegister.h b/lldb/include/lldb/Core/ValueObjectRegister.h index 3968584ad518..e210b36d2a45 100644 --- a/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/lldb/include/lldb/Core/ValueObjectRegister.h @@ -18,8 +18,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-private-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index 41c461ce13f0..f7a233047cc1 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -20,18 +20,18 @@ #include <cstdint> #include <memory> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Declaration; class Status; class SyntheticChildrenFrontEnd; -// A ValueObject that obtains its children from some source other than -// real information -// This is currently used to implement Python-based children and filters but -// you can bind it to any source of synthetic information and have it behave -// accordingly +/// A ValueObject that obtains its children from some source other than +/// real information. +/// This is currently used to implement Python-based children and filters but +/// you can bind it to any source of synthetic information and have it behave +/// accordingly. class ValueObjectSynthetic : public ValueObject { public: ~ValueObjectSynthetic() override; @@ -148,9 +148,9 @@ protected: /// Guarded by m_child_mutex; SyntheticChildrenCache m_synthetic_children_cache; - uint32_t m_synthetic_children_count; // FIXME use the ValueObject's - // ChildrenManager instead of a special - // purpose solution + // FIXME: use the ValueObject's ChildrenManager instead of a special purpose + // solution. + uint32_t m_synthetic_children_count; ConstString m_parent_type_name; diff --git a/lldb/include/lldb/Core/ValueObjectUpdater.h b/lldb/include/lldb/Core/ValueObjectUpdater.h new file mode 100644 index 000000000000..54fcb31076ad --- /dev/null +++ b/lldb/include/lldb/Core/ValueObjectUpdater.h @@ -0,0 +1,43 @@ +//===-- ValueObjectUpdater.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_CORE_VALUEOBJECTUPDATER_H +#define LLDB_CORE_VALUEOBJECTUPDATER_H + +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +/// A value object class that is seeded with the static variable value +/// and it vends the user facing value object. If the type is dynamic it can +/// vend the dynamic type. If this user type also has a synthetic type +/// associated with it, it will vend the synthetic type. The class watches the +/// process' stop ID and will update the user type when needed. +class ValueObjectUpdater { + /// The root value object is the static typed variable object. + lldb::ValueObjectSP m_root_valobj_sp; + /// The user value object is the value object the user wants to see. + lldb::ValueObjectSP m_user_valobj_sp; + /// The stop ID that m_user_valobj_sp is valid for. + uint32_t m_stop_id = UINT32_MAX; + +public: + ValueObjectUpdater(lldb::ValueObjectSP in_valobj_sp); + + /// Gets the correct value object from the root object for a given process + /// stop ID. If dynamic values are enabled, or if synthetic children are + /// enabled, the value object that the user wants to see might change while + /// debugging. + lldb::ValueObjectSP GetSP(); + + lldb::ProcessSP GetProcessSP() const; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_VALUEOBJECTUPDATER_H diff --git a/lldb/include/lldb/Core/ValueObjectVariable.h b/lldb/include/lldb/Core/ValueObjectVariable.h index 23fdedbf5a4a..cbf7e5b52ced 100644 --- a/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/lldb/include/lldb/Core/ValueObjectVariable.h @@ -18,8 +18,8 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class DataExtractor; @@ -28,8 +28,8 @@ class Status; class ExecutionContextScope; class SymbolContextScope; -// A ValueObject that contains a root variable that may or may not -// have children. +/// A ValueObject that contains a root variable that may or may not +/// have children. class ValueObjectVariable : public ValueObject { public: ~ValueObjectVariable() override; @@ -72,10 +72,11 @@ protected: CompilerType GetCompilerTypeImpl() override; - lldb::VariableSP - m_variable_sp; ///< The variable that this value object is based upon - Value m_resolved_value; ///< The value that DWARFExpression resolves this - ///variable to before we patch it up + /// The variable that this value object is based upon. + lldb::VariableSP m_variable_sp; + ///< The value that DWARFExpression resolves this variable to before we patch + ///< it up. + Value m_resolved_value; private: ValueObjectVariable(ExecutionContextScope *exe_scope, diff --git a/lldb/include/lldb/Core/dwarf.h b/lldb/include/lldb/Core/dwarf.h index cd9cf249bc63..968418e71c2f 100644 --- a/lldb/include/lldb/Core/dwarf.h +++ b/lldb/include/lldb/Core/dwarf.h @@ -10,7 +10,7 @@ #define LLDB_CORE_DWARF_H #include "lldb/Utility/RangeMap.h" -#include <stdint.h> +#include <cstdint> // Get the DWARF constant definitions from llvm #include "llvm/BinaryFormat/Dwarf.h" @@ -38,39 +38,6 @@ typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any #define DW_EH_PE_MASK_ENCODING 0x0F -//// The following are used only internally within lldb - don't -//// document them in the llvm Dwarf.h header file, we won't see -//// them in executable files anywhere. -//// These constants fit between DW_OP_lo_user (0xe0) and DW_OP_hi_user (0xff). -// -//#define DW_OP_APPLE_array_ref 0xEE // first pops index, then pops array; -//pushes array[index] -//#define DW_OP_APPLE_extern 0xEF // ULEB128 index of external object -//(i.e., an entity from the program that was used in the expression) -#define DW_OP_APPLE_uninit \ - 0xF0 // This is actually generated by some apple compilers in locations lists -//#define DW_OP_APPLE_assign 0xF1 // pops value off and assigns it to -//second item on stack (2nd item must have assignable context) -//#define DW_OP_APPLE_address_of 0xF2 // gets the address of the top stack -//item (top item must be a variable, or have value_type that is an address -//already) -//#define DW_OP_APPLE_value_of 0xF3 // pops the value off the stack and -//pushes the value of that object (top item must be a variable, or expression -//local) -//#define DW_OP_APPLE_deref_type 0xF4 // gets the address of the top stack -//item (top item must be a variable, or a clang type) -//#define DW_OP_APPLE_expr_local 0xF5 // ULEB128 expression local index -//#define DW_OP_APPLE_constf 0xF6 // 1 byte float size, followed by -//constant float data -//#define DW_OP_APPLE_scalar_cast 0xF7 // Cast top of stack to 2nd in stack's -//type leaving all items in place -//#define DW_OP_APPLE_clang_cast 0xF8 // pointer size clang::Type * off the -//stack and cast top stack item to this type -//#define DW_OP_APPLE_clear 0xFE // clears the entire expression stack, -//ok if the stack is empty -//#define DW_OP_APPLE_error 0xFF // Stops expression evaluation and -//returns an error (no args) - typedef lldb_private::RangeVector<dw_addr_t, dw_addr_t, 2> DWARFRangeList; #endif // LLDB_CORE_DWARF_H diff --git a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h index 2f3bdf80a6f1..cef43f45b8e4 100644 --- a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h +++ b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h @@ -35,12 +35,11 @@ public: }; struct PointerAsArraySettings { - size_t m_element_count; - size_t m_base_element; - size_t m_stride; + size_t m_element_count = 0; + size_t m_base_element = 0; + size_t m_stride = 0; - PointerAsArraySettings() - : m_element_count(0), m_base_element(0), m_stride() {} + PointerAsArraySettings() = default; PointerAsArraySettings(size_t elem_count, size_t base_elem = 0, size_t stride = 1) @@ -62,8 +61,6 @@ public: DumpValueObjectOptions(); - DumpValueObjectOptions(const DumpValueObjectOptions &rhs) = default; - DumpValueObjectOptions(ValueObject &valobj); DumpValueObjectOptions & diff --git a/lldb/include/lldb/DataFormatters/FormatClasses.h b/lldb/include/lldb/DataFormatters/FormatClasses.h index e3989133a602..b8540de3d740 100644 --- a/lldb/include/lldb/DataFormatters/FormatClasses.h +++ b/lldb/include/lldb/DataFormatters/FormatClasses.h @@ -105,7 +105,7 @@ private: class TypeNameSpecifierImpl { public: - TypeNameSpecifierImpl() : m_is_regex(false), m_type() {} + TypeNameSpecifierImpl() : m_type() {} TypeNameSpecifierImpl(llvm::StringRef name, bool is_regex) : m_is_regex(is_regex), m_type() { @@ -143,7 +143,7 @@ public: bool IsRegex() { return m_is_regex; } private: - bool m_is_regex; + bool m_is_regex = false; // TODO: Replace this with TypeAndOrName. struct TypeOrName { std::string m_type_name; diff --git a/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/lldb/include/lldb/DataFormatters/FormattersHelpers.h index a5b0da57e5d8..892807063b9c 100644 --- a/lldb/include/lldb/DataFormatters/FormattersHelpers.h +++ b/lldb/include/lldb/DataFormatters/FormattersHelpers.h @@ -36,11 +36,13 @@ void AddOneLineSummary(TypeCategoryImpl::SharedPointer category_sp, ConstString type_name, TypeSummaryImpl::Flags flags, bool regex = false); +/// Add a summary that is implemented by a C++ callback. void AddCXXSummary(TypeCategoryImpl::SharedPointer category_sp, CXXFunctionSummaryFormat::Callback funct, const char *description, ConstString type_name, TypeSummaryImpl::Flags flags, bool regex = false); +/// Add a synthetic that is implemented by a C++ callback. void AddCXXSynthetic(TypeCategoryImpl::SharedPointer category_sp, CXXSyntheticChildren::CreateFrontEndCallback generator, const char *description, ConstString type_name, diff --git a/lldb/include/lldb/DataFormatters/TypeFormat.h b/lldb/include/lldb/DataFormatters/TypeFormat.h index b8ed6a3443b3..4e19d4cb14a1 100644 --- a/lldb/include/lldb/DataFormatters/TypeFormat.h +++ b/lldb/include/lldb/DataFormatters/TypeFormat.h @@ -25,7 +25,7 @@ class TypeFormatImpl { public: class Flags { public: - Flags() : m_flags(lldb::eTypeOptionCascade) {} + Flags() {} Flags(const Flags &other) : m_flags(other.m_flags) {} @@ -104,7 +104,7 @@ public: void SetValue(uint32_t value) { m_flags = value; } private: - uint32_t m_flags; + uint32_t m_flags = lldb::eTypeOptionCascade; }; TypeFormatImpl(const Flags &flags = Flags()); @@ -149,7 +149,7 @@ public: protected: Flags m_flags; - uint32_t m_my_revision; + uint32_t m_my_revision = 0; private: TypeFormatImpl(const TypeFormatImpl &) = delete; diff --git a/lldb/include/lldb/DataFormatters/TypeSummary.h b/lldb/include/lldb/DataFormatters/TypeSummary.h index ce3195dbb693..30bc8cbf3feb 100644 --- a/lldb/include/lldb/DataFormatters/TypeSummary.h +++ b/lldb/include/lldb/DataFormatters/TypeSummary.h @@ -9,7 +9,7 @@ #ifndef LLDB_DATAFORMATTERS_TYPESUMMARY_H #define LLDB_DATAFORMATTERS_TYPESUMMARY_H -#include <stdint.h> +#include <cstdint> #include <functional> #include <memory> @@ -38,8 +38,8 @@ public: TypeSummaryOptions &SetCapping(lldb::TypeSummaryCapping); private: - lldb::LanguageType m_lang; - lldb::TypeSummaryCapping m_capping; + lldb::LanguageType m_lang = lldb::eLanguageTypeUnknown; + lldb::TypeSummaryCapping m_capping = lldb::eTypeSummaryCapped; }; class TypeSummaryImpl { @@ -52,7 +52,7 @@ public: class Flags { public: - Flags() : m_flags(lldb::eTypeOptionCascade) {} + Flags() = default; Flags(const Flags &other) : m_flags(other.m_flags) {} @@ -196,7 +196,7 @@ public: void SetValue(uint32_t value) { m_flags = value; } private: - uint32_t m_flags; + uint32_t m_flags = lldb::eTypeOptionCascade; }; bool Cascades() const { return m_flags.GetCascades(); } diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/lldb/include/lldb/DataFormatters/TypeSynthetic.h index fa1458281f1e..24322bd51a0c 100644 --- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -9,7 +9,7 @@ #ifndef LLDB_DATAFORMATTERS_TYPESYNTHETIC_H #define LLDB_DATAFORMATTERS_TYPESYNTHETIC_H -#include <stdint.h> +#include <cstdint> #include <functional> #include <initializer_list> @@ -133,7 +133,7 @@ class SyntheticChildren { public: class Flags { public: - Flags() : m_flags(lldb::eTypeOptionCascade) {} + Flags() = default; Flags(const Flags &other) : m_flags(other.m_flags) {} @@ -225,7 +225,7 @@ public: void SetValue(uint32_t value) { m_flags = value; } private: - uint32_t m_flags; + uint32_t m_flags = lldb::eTypeOptionCascade; }; SyntheticChildren(const Flags &flags) : m_flags(flags) {} diff --git a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h index f1301d8595b1..833cd5eea356 100644 --- a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -27,7 +27,7 @@ public: ValueObjectPrinter(ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options); - ~ValueObjectPrinter() {} + ~ValueObjectPrinter() = default; bool PrintValueObject(); diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h index c7d4e4b1882f..1490ac2d614a 100644 --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -250,10 +250,10 @@ private: /// The DWARF compile unit this expression belongs to. It is used to evaluate /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index, /// DW_OP_GNU_const_index) - const DWARFUnit *m_dwarf_cu; + const DWARFUnit *m_dwarf_cu = nullptr; /// One of the defines that starts with LLDB_REGKIND_ - lldb::RegisterKind m_reg_kind; + lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF; struct LoclistAddresses { lldb::addr_t cu_file_addr; diff --git a/lldb/include/lldb/Expression/Expression.h b/lldb/include/lldb/Expression/Expression.h index aaac889e6ed2..b4207de958e9 100644 --- a/lldb/include/lldb/Expression/Expression.h +++ b/lldb/include/lldb/Expression/Expression.h @@ -39,7 +39,7 @@ public: Expression(ExecutionContextScope &exe_scope); /// Destructor - virtual ~Expression() {} + virtual ~Expression() = default; /// Return the string that the parser should parse. Must be a full /// translation unit. diff --git a/lldb/include/lldb/Expression/ExpressionParser.h b/lldb/include/lldb/Expression/ExpressionParser.h index 71d2410ea7c3..ab5223c91553 100644 --- a/lldb/include/lldb/Expression/ExpressionParser.h +++ b/lldb/include/lldb/Expression/ExpressionParser.h @@ -41,7 +41,7 @@ public: : m_expr(expr), m_generate_debug_info(generate_debug_info) {} /// Destructor - virtual ~ExpressionParser(){}; + virtual ~ExpressionParser() = default; /// Attempts to find possible command line completions for the given /// expression. diff --git a/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h b/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h index 1bba30ad8620..2ba675db8662 100644 --- a/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h +++ b/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h @@ -36,7 +36,7 @@ public: ExpressionTypeSystemHelper(LLVMCastKind kind) : m_kind(kind) {} - ~ExpressionTypeSystemHelper() {} + ~ExpressionTypeSystemHelper() = default; protected: LLVMCastKind m_kind; diff --git a/lldb/include/lldb/Expression/ExpressionVariable.h b/lldb/include/lldb/Expression/ExpressionVariable.h index 4259e6395da4..de700b676611 100644 --- a/lldb/include/lldb/Expression/ExpressionVariable.h +++ b/lldb/include/lldb/Expression/ExpressionVariable.h @@ -48,7 +48,7 @@ public: void SetRegisterInfo(const RegisterInfo *reg_info) { return m_frozen_sp->GetValue().SetContext( - Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info)); + Value::ContextType::RegisterInfo, const_cast<RegisterInfo *>(reg_info)); } CompilerType GetCompilerType() { return m_frozen_sp->GetCompilerType(); } diff --git a/lldb/include/lldb/Expression/Materializer.h b/lldb/include/lldb/Expression/Materializer.h index 754e67c5dfa7..25cf22a8b5b0 100644 --- a/lldb/include/lldb/Expression/Materializer.h +++ b/lldb/include/lldb/Expression/Materializer.h @@ -90,7 +90,7 @@ public: class Entity { public: - Entity() : m_alignment(1), m_size(0), m_offset(0) {} + Entity() = default; virtual ~Entity() = default; @@ -113,9 +113,9 @@ public: void SetOffset(uint32_t offset) { m_offset = offset; } protected: - uint32_t m_alignment; - uint32_t m_size; - uint32_t m_offset; + uint32_t m_alignment = 1; + uint32_t m_size = 0; + uint32_t m_offset = 0; }; private: diff --git a/lldb/include/lldb/Expression/UtilityFunction.h b/lldb/include/lldb/Expression/UtilityFunction.h index 99fb32153aa2..6b558b20e212 100644 --- a/lldb/include/lldb/Expression/UtilityFunction.h +++ b/lldb/include/lldb/Expression/UtilityFunction.h @@ -42,8 +42,11 @@ public: /// /// \param[in] name /// The name of the function, as used in the text. + /// + /// \param[in] enable_debugging + /// Enable debugging of this function. UtilityFunction(ExecutionContextScope &exe_scope, std::string text, - std::string name); + std::string name, bool enable_debugging); ~UtilityFunction() override; diff --git a/lldb/include/lldb/Host/Debug.h b/lldb/include/lldb/Host/Debug.h index 402325c4c166..7da59dd04a66 100644 --- a/lldb/include/lldb/Host/Debug.h +++ b/lldb/include/lldb/Host/Debug.h @@ -144,6 +144,12 @@ struct ThreadStopInfo { uint32_t data_count; lldb::addr_t data[8]; } exception; + + // eStopReasonFork / eStopReasonVFork + struct { + lldb::pid_t child_pid; + lldb::tid_t child_tid; + } fork; } details; }; } diff --git a/lldb/include/lldb/Host/Editline.h b/lldb/include/lldb/Host/Editline.h index a37ad1b9d106..876f6052311e 100644 --- a/lldb/include/lldb/Host/Editline.h +++ b/lldb/include/lldb/Host/Editline.h @@ -38,12 +38,9 @@ #include <sstream> #include <vector> -#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/lldb-private.h" -#if defined(_WIN32) -#include "lldb/Host/windows/editlinewin.h" -#elif !defined(__ANDROID__) +#if !defined(_WIN32) && !defined(__ANDROID__) #include <histedit.h> #endif @@ -56,6 +53,9 @@ #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Predicate.h" +#include "lldb/Utility/StringList.h" + +#include "llvm/ADT/FunctionExtras.h" namespace lldb_private { namespace line_editor { @@ -81,27 +81,26 @@ using EditLineGetCharType = wchar_t; using EditLineGetCharType = char; #endif -typedef int (*EditlineGetCharCallbackType)(::EditLine *editline, - EditLineGetCharType *c); -typedef unsigned char (*EditlineCommandCallbackType)(::EditLine *editline, - int ch); -typedef const char *(*EditlinePromptCallbackType)(::EditLine *editline); +using EditlineGetCharCallbackType = int (*)(::EditLine *editline, + EditLineGetCharType *c); +using EditlineCommandCallbackType = unsigned char (*)(::EditLine *editline, + int ch); +using EditlinePromptCallbackType = const char *(*)(::EditLine *editline); class EditlineHistory; -typedef std::shared_ptr<EditlineHistory> EditlineHistorySP; +using EditlineHistorySP = std::shared_ptr<EditlineHistory>; -typedef bool (*IsInputCompleteCallbackType)(Editline *editline, - StringList &lines, void *baton); +using IsInputCompleteCallbackType = + llvm::unique_function<bool(Editline *, StringList &)>; -typedef int (*FixIndentationCallbackType)(Editline *editline, - const StringList &lines, - int cursor_position, void *baton); +using FixIndentationCallbackType = + llvm::unique_function<int(Editline *, StringList &, int)>; -typedef llvm::Optional<std::string> (*SuggestionCallbackType)( - llvm::StringRef line, void *baton); +using SuggestionCallbackType = + llvm::unique_function<llvm::Optional<std::string>(llvm::StringRef)>; -typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton); +using CompleteCallbackType = llvm::unique_function<void(CompletionRequest &)>; /// Status used to decide when and how to start editing another line in /// multi-line sessions @@ -188,21 +187,28 @@ public: bool Cancel(); /// Register a callback for autosuggestion. - void SetSuggestionCallback(SuggestionCallbackType callback, void *baton); + void SetSuggestionCallback(SuggestionCallbackType callback) { + m_suggestion_callback = std::move(callback); + } /// Register a callback for the tab key - void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton); + void SetAutoCompleteCallback(CompleteCallbackType callback) { + m_completion_callback = std::move(callback); + } /// Register a callback for testing whether multi-line input is complete - void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback, - void *baton); + void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback) { + m_is_input_complete_callback = std::move(callback); + } /// Register a callback for determining the appropriate indentation for a line /// when creating a newline. An optional set of insertable characters can - /// also - /// trigger the callback. - bool SetFixIndentationCallback(FixIndentationCallbackType callback, - void *baton, const char *indent_chars); + /// also trigger the callback. + void SetFixIndentationCallback(FixIndentationCallbackType callback, + const char *indent_chars) { + m_fix_indentation_callback = std::move(callback); + m_fix_indentation_callback_chars = indent_chars; + } /// Prompts for and reads a single line of user input. bool GetLine(std::string &line, bool &interrupted); @@ -338,6 +344,16 @@ private: void ApplyTerminalSizeChange(); + // The following set various editline parameters. It's not any less + // verbose to put the editline calls into a function, but it + // provides type safety, since the editline functions take varargs + // parameters. + void AddFunctionToEditLine(const EditLineCharType *command, + const EditLineCharType *helptext, + EditlineCommandCallbackType callbackFn); + void SetEditLinePromptCallback(EditlinePromptCallbackType callbackFn); + void SetGetCharacterFunction(EditlineGetCharCallbackType callbackFn); + #if LLDB_EDITLINE_USE_WCHAR std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv; #endif @@ -365,15 +381,16 @@ private: FILE *m_output_file; FILE *m_error_file; ConnectionFileDescriptor m_input_connection; - IsInputCompleteCallbackType m_is_input_complete_callback = nullptr; - void *m_is_input_complete_callback_baton = nullptr; - FixIndentationCallbackType m_fix_indentation_callback = nullptr; - void *m_fix_indentation_callback_baton = nullptr; + + IsInputCompleteCallbackType m_is_input_complete_callback; + + FixIndentationCallbackType m_fix_indentation_callback; const char *m_fix_indentation_callback_chars = nullptr; - CompleteCallbackType m_completion_callback = nullptr; - void *m_completion_callback_baton = nullptr; - SuggestionCallbackType m_suggestion_callback = nullptr; - void *m_suggestion_callback_baton = nullptr; + + CompleteCallbackType m_completion_callback; + + SuggestionCallbackType m_suggestion_callback; + std::size_t m_previous_autosuggestion_size = 0; std::mutex m_output_mutex; }; diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h index d205a3fe6911..d364d954a1c1 100644 --- a/lldb/include/lldb/Host/File.h +++ b/lldb/include/lldb/Host/File.h @@ -15,9 +15,9 @@ #include "lldb/lldb-private.h" #include "llvm/ADT/BitmaskEnum.h" +#include <cstdarg> +#include <cstdio> #include <mutex> -#include <stdarg.h> -#include <stdio.h> #include <sys/types.h> namespace lldb_private { @@ -65,10 +65,7 @@ public: static llvm::Expected<const char *> GetStreamOpenModeFromOptions(OpenOptions options); - File() - : IOObject(eFDTypeFile), m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate), - m_supports_colors(eLazyBoolCalculate){}; + File() : IOObject(eFDTypeFile){}; /// Read bytes from a file from the current file position into buf. /// @@ -360,9 +357,9 @@ public: static bool classof(const File *file) { return file->isA(&ID); } protected: - LazyBool m_is_interactive; - LazyBool m_is_real_terminal; - LazyBool m_supports_colors; + LazyBool m_is_interactive = eLazyBoolCalculate; + LazyBool m_is_real_terminal = eLazyBoolCalculate; + LazyBool m_supports_colors = eLazyBoolCalculate; void CalculateInteractiveAndTerminal(); @@ -373,9 +370,7 @@ private: class NativeFile : public File { public: - NativeFile() - : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), - m_stream(kInvalidStream), m_options(), m_own_stream(false) {} + NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {} NativeFile(FILE *fh, bool transfer_ownership) : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh), @@ -422,10 +417,10 @@ protected: // Member variables int m_descriptor; - bool m_own_descriptor; + bool m_own_descriptor = false; FILE *m_stream; - OpenOptions m_options; - bool m_own_stream; + OpenOptions m_options{}; + bool m_own_stream = false; std::mutex offset_access_mutex; private: diff --git a/lldb/include/lldb/Host/FileAction.h b/lldb/include/lldb/Host/FileAction.h index 4d333bb327a5..d3166c16a585 100644 --- a/lldb/include/lldb/Host/FileAction.h +++ b/lldb/include/lldb/Host/FileAction.h @@ -46,9 +46,9 @@ public: void Dump(Stream &stream) 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 + Action m_action = eFileActionNone; // The action for this file + int m_fd = -1; // An existing file descriptor + int m_arg = -1; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate FileSpec m_file_spec; // A file spec to use for opening after fork or posix_spawn }; diff --git a/lldb/include/lldb/Host/FileCache.h b/lldb/include/lldb/Host/FileCache.h index df0d9a88c6df..1bf5f0ca80e2 100644 --- a/lldb/include/lldb/Host/FileCache.h +++ b/lldb/include/lldb/Host/FileCache.h @@ -8,8 +8,8 @@ #ifndef LLDB_HOST_FILECACHE_H #define LLDB_HOST_FILECACHE_H +#include <cstdint> #include <map> -#include <stdint.h> #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" @@ -21,7 +21,7 @@ namespace lldb_private { class FileCache { private: - FileCache() {} + FileCache() = default; typedef std::map<lldb::user_id_t, lldb::FileUP> FDToFileMap; diff --git a/lldb/include/lldb/Host/FileSystem.h b/lldb/include/lldb/Host/FileSystem.h index 02ff5f301336..93563d4d26e3 100644 --- a/lldb/include/lldb/Host/FileSystem.h +++ b/lldb/include/lldb/Host/FileSystem.h @@ -21,8 +21,8 @@ #include "lldb/lldb-types.h" -#include <stdint.h> -#include <stdio.h> +#include <cstdint> +#include <cstdio> #include <sys/stat.h> namespace lldb_private { @@ -33,7 +33,7 @@ public: FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr), - m_home_directory(), m_mapped(false) {} + m_home_directory() {} FileSystem(std::shared_ptr<llvm::FileCollectorBase> collector) : m_fs(llvm::vfs::getRealFileSystem()), m_collector(std::move(collector)), m_home_directory(), m_mapped(false) {} @@ -201,7 +201,7 @@ private: llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; std::shared_ptr<llvm::FileCollectorBase> m_collector; std::string m_home_directory; - bool m_mapped; + bool m_mapped = false; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h index 76792cc6eab5..1fdf7eab7eb8 100644 --- a/lldb/include/lldb/Host/Host.h +++ b/lldb/include/lldb/Host/Host.h @@ -17,8 +17,8 @@ #include "lldb/lldb-private-forward.h" #include "lldb/lldb-private.h" #include <cerrno> +#include <cstdarg> #include <map> -#include <stdarg.h> #include <string> #include <type_traits> diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index 15bb168aad97..eeed881101d0 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -17,7 +17,7 @@ #include "lldb/lldb-enumerations.h" #include "llvm/ADT/StringRef.h" -#include <stdint.h> +#include <cstdint> #include <string> @@ -33,11 +33,17 @@ struct SharedCacheImageInfo { class HostInfoBase { private: // Static class, unconstructable. - HostInfoBase() {} - ~HostInfoBase() {} + HostInfoBase() = default; + ~HostInfoBase() = default; public: - static void Initialize(); + /// A helper function for determining the liblldb location. It receives a + /// FileSpec with the location of file containing _this_ code. It can + /// (optionally) replace it with a file spec pointing to a more canonical + /// copy. + using SharedLibraryDirectoryHelper = void(FileSpec &this_file); + + static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr); static void Terminate(); /// Gets the host target triple. diff --git a/lldb/include/lldb/Host/HostNativeProcessBase.h b/lldb/include/lldb/Host/HostNativeProcessBase.h index 642c63443c20..5469f8a50e26 100644 --- a/lldb/include/lldb/Host/HostNativeProcessBase.h +++ b/lldb/include/lldb/Host/HostNativeProcessBase.h @@ -27,7 +27,7 @@ public: HostNativeProcessBase() : m_process(LLDB_INVALID_PROCESS) {} explicit HostNativeProcessBase(lldb::process_t process) : m_process(process) {} - virtual ~HostNativeProcessBase() {} + virtual ~HostNativeProcessBase() = default; virtual Status Terminate() = 0; virtual Status GetMainModule(FileSpec &file_spec) const = 0; diff --git a/lldb/include/lldb/Host/HostNativeThreadBase.h b/lldb/include/lldb/Host/HostNativeThreadBase.h index 0dfd363cc8fb..bfd70d745593 100644 --- a/lldb/include/lldb/Host/HostNativeThreadBase.h +++ b/lldb/include/lldb/Host/HostNativeThreadBase.h @@ -27,9 +27,9 @@ class HostNativeThreadBase { const HostNativeThreadBase &operator=(const HostNativeThreadBase &) = delete; public: - HostNativeThreadBase(); + HostNativeThreadBase() = default; explicit HostNativeThreadBase(lldb::thread_t thread); - virtual ~HostNativeThreadBase() {} + virtual ~HostNativeThreadBase() = default; virtual Status Join(lldb::thread_result_t *result) = 0; virtual Status Cancel() = 0; @@ -45,8 +45,8 @@ protected: static lldb::thread_result_t THREAD_ROUTINE ThreadCreateTrampoline(lldb::thread_arg_t arg); - lldb::thread_t m_thread; - lldb::thread_result_t m_result; + lldb::thread_t m_thread = LLDB_INVALID_HOST_THREAD; + lldb::thread_result_t m_result = 0; }; } diff --git a/lldb/include/lldb/Host/MainLoop.h b/lldb/include/lldb/Host/MainLoop.h index 9ca5040b60a8..06785bbdbe24 100644 --- a/lldb/include/lldb/Host/MainLoop.h +++ b/lldb/include/lldb/Host/MainLoop.h @@ -13,6 +13,7 @@ #include "lldb/Host/MainLoopBase.h" #include "llvm/ADT/DenseMap.h" #include <csignal> +#include <list> #if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) #define SIGNAL_POLLING_UNSUPPORTED 1 @@ -68,7 +69,7 @@ public: protected: void UnregisterReadObject(IOObject::WaitableHandle handle) override; - void UnregisterSignal(int signo); + void UnregisterSignal(int signo, std::list<Callback>::iterator callback_it); private: void ProcessReadObject(IOObject::WaitableHandle handle); @@ -76,14 +77,16 @@ private: class SignalHandle { public: - ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); } + ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo, m_callback_it); } private: - SignalHandle(MainLoop &mainloop, int signo) - : m_mainloop(mainloop), m_signo(signo) {} + SignalHandle(MainLoop &mainloop, int signo, + std::list<Callback>::iterator callback_it) + : m_mainloop(mainloop), m_signo(signo), m_callback_it(callback_it) {} MainLoop &m_mainloop; int m_signo; + std::list<Callback>::iterator m_callback_it; friend class MainLoop; SignalHandle(const SignalHandle &) = delete; @@ -91,7 +94,7 @@ private: }; struct SignalInfo { - Callback callback; + std::list<Callback> callbacks; #if HAVE_SIGACTION struct sigaction old_action; #endif diff --git a/lldb/include/lldb/Host/MainLoopBase.h b/lldb/include/lldb/Host/MainLoopBase.h index fa8cc77a94ba..67857b26ac70 100644 --- a/lldb/include/lldb/Host/MainLoopBase.h +++ b/lldb/include/lldb/Host/MainLoopBase.h @@ -33,8 +33,8 @@ private: class ReadHandle; public: - MainLoopBase() {} - virtual ~MainLoopBase() {} + MainLoopBase() = default; + virtual ~MainLoopBase() = default; typedef std::unique_ptr<ReadHandle> ReadHandleUP; diff --git a/lldb/include/lldb/Host/ProcessLaunchInfo.h b/lldb/include/lldb/Host/ProcessLaunchInfo.h index ee9755580825..3ed21637de7f 100644 --- a/lldb/include/lldb/Host/ProcessLaunchInfo.h +++ b/lldb/include/lldb/Host/ProcessLaunchInfo.h @@ -20,6 +20,7 @@ #include "lldb/Host/PseudoTerminal.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/ProcessInfo.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { @@ -146,6 +147,28 @@ public: return m_flags.Test(lldb::eLaunchFlagDetachOnError); } + bool IsScriptedProcess() const { + return !m_scripted_process_class_name.empty(); + } + + std::string GetScriptedProcessClassName() const { + return m_scripted_process_class_name; + } + + void SetScriptedProcessClassName(std::string name) { + m_scripted_process_class_name = name; + } + + lldb_private::StructuredData::DictionarySP + GetScriptedProcessDictionarySP() const { + return m_scripted_process_dictionary_sp; + } + + void SetScriptedProcessDictionarySP( + lldb_private::StructuredData::DictionarySP dictionary_sp) { + m_scripted_process_dictionary_sp = dictionary_sp; + } + protected: FileSpec m_working_dir; std::string m_plugin_name; @@ -153,14 +176,19 @@ protected: Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags std::vector<FileAction> m_file_actions; // File actions for any other files std::shared_ptr<PseudoTerminal> m_pty; - uint32_t m_resume_count; // How many times do we resume after launching + uint32_t m_resume_count = 0; // How many times do we resume after launching Host::MonitorChildProcessCallback m_monitor_callback; - void *m_monitor_callback_baton; - bool m_monitor_signals; + void *m_monitor_callback_baton = nullptr; + bool m_monitor_signals = false; std::string m_event_data; // A string passed to the plugin launch, having no // meaning to the upper levels of lldb. lldb::ListenerSP m_listener_sp; lldb::ListenerSP m_hijack_listener_sp; + std::string m_scripted_process_class_name; // The name of the class that will + // manage a scripted process. + StructuredData::DictionarySP + m_scripted_process_dictionary_sp; // A dictionary that holds key/value + // pairs passed to the scripted process. }; } diff --git a/lldb/include/lldb/Host/ProcessLauncher.h b/lldb/include/lldb/Host/ProcessLauncher.h index 9467b2c009b7..33dbfd72d1e5 100644 --- a/lldb/include/lldb/Host/ProcessLauncher.h +++ b/lldb/include/lldb/Host/ProcessLauncher.h @@ -17,7 +17,7 @@ class HostProcess; class ProcessLauncher { public: - virtual ~ProcessLauncher() {} + virtual ~ProcessLauncher() = default; virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) = 0; }; diff --git a/lldb/include/lldb/Host/ProcessRunLock.h b/lldb/include/lldb/Host/ProcessRunLock.h index 43463d144de3..b5b5328b4a33 100644 --- a/lldb/include/lldb/Host/ProcessRunLock.h +++ b/lldb/include/lldb/Host/ProcessRunLock.h @@ -9,8 +9,8 @@ #ifndef LLDB_HOST_PROCESSRUNLOCK_H #define LLDB_HOST_PROCESSRUNLOCK_H -#include <stdint.h> -#include <time.h> +#include <cstdint> +#include <ctime> #include "lldb/lldb-defines.h" @@ -35,7 +35,7 @@ public: class ProcessRunLocker { public: - ProcessRunLocker() : m_lock(nullptr) {} + ProcessRunLocker() = default; ~ProcessRunLocker() { Unlock(); } @@ -64,7 +64,7 @@ public: } } - ProcessRunLock *m_lock; + ProcessRunLock *m_lock = nullptr; private: ProcessRunLocker(const ProcessRunLocker &) = delete; @@ -73,7 +73,7 @@ public: protected: lldb::rwlock_t m_rwlock; - bool m_running; + bool m_running = false; private: ProcessRunLock(const ProcessRunLock &) = delete; diff --git a/lldb/include/lldb/Host/PseudoTerminal.h b/lldb/include/lldb/Host/PseudoTerminal.h index 350f926dcac1..bd1e2f56241b 100644 --- a/lldb/include/lldb/Host/PseudoTerminal.h +++ b/lldb/include/lldb/Host/PseudoTerminal.h @@ -175,8 +175,8 @@ public: protected: // Member variables - int m_primary_fd; ///< The file descriptor for the primary. - int m_secondary_fd; ///< The file descriptor for the secondary. + int m_primary_fd = invalid_fd; ///< The file descriptor for the primary. + int m_secondary_fd = invalid_fd; ///< The file descriptor for the secondary. private: PseudoTerminal(const PseudoTerminal &) = delete; diff --git a/lldb/include/lldb/Host/SafeMachO.h b/lldb/include/lldb/Host/SafeMachO.h index d7c376d23a4a..0540383b8c52 100644 --- a/lldb/include/lldb/Host/SafeMachO.h +++ b/lldb/include/lldb/Host/SafeMachO.h @@ -23,6 +23,7 @@ #undef CPU_ARCH_MASK #undef CPU_ARCH_ABI64 +#undef CPU_ARCH_ABI64_32 #undef CPU_TYPE_ANY #undef CPU_TYPE_X86 @@ -31,12 +32,13 @@ #undef CPU_TYPE_MC98000 #undef CPU_TYPE_ARM #undef CPU_TYPE_ARM64 +#undef CPU_TYPE_ARM64_32 #undef CPU_TYPE_SPARC #undef CPU_TYPE_POWERPC #undef CPU_TYPE_POWERPC64 -#undef CPU_SUB_TYPE_MASK -#undef CPU_SUB_TYPE_LIB64 +#undef CPU_SUBTYPE_MASK +#undef CPU_SUBTYPE_LIB64 #undef CPU_SUBTYPE_MULTIPLE @@ -88,6 +90,9 @@ #undef CPU_SUBTYPE_ARM_V7M #undef CPU_SUBTYPE_ARM_V7EM +#undef CPU_SUBTYPE_ARM64E +#undef CPU_SUBTYPE_ARM64_32_V8 +#undef CPU_SUBTYPE_ARM64_V8 #undef CPU_SUBTYPE_ARM64_ALL #undef CPU_SUBTYPE_SPARC_ALL @@ -110,6 +115,47 @@ #undef CPU_SUBTYPE_MC980000_ALL #undef CPU_SUBTYPE_MC98601 +#undef VM_PROT_READ +#undef VM_PROT_WRITE +#undef VM_PROT_EXECUTE + +#undef ARM_DEBUG_STATE +#undef ARM_EXCEPTION_STATE +#undef ARM_EXCEPTION_STATE64 +#undef ARM_EXCEPTION_STATE64_COUNT +#undef ARM_THREAD_STATE +#undef ARM_THREAD_STATE64 +#undef ARM_THREAD_STATE64_COUNT +#undef ARM_THREAD_STATE_COUNT +#undef ARM_VFP_STATE +#undef ARN_THREAD_STATE_NONE +#undef PPC_EXCEPTION_STATE +#undef PPC_EXCEPTION_STATE64 +#undef PPC_FLOAT_STATE +#undef PPC_THREAD_STATE +#undef PPC_THREAD_STATE64 +#undef PPC_THREAD_STATE_NONE +#undef PPC_VECTOR_STATE +#undef x86_DEBUG_STATE +#undef x86_DEBUG_STATE32 +#undef x86_DEBUG_STATE64 +#undef x86_EXCEPTION_STATE +#undef x86_EXCEPTION_STATE32 +#undef x86_EXCEPTION_STATE64 +#undef x86_EXCEPTION_STATE64_COUNT +#undef x86_EXCEPTION_STATE_COUNT +#undef x86_FLOAT_STATE +#undef x86_FLOAT_STATE32 +#undef x86_FLOAT_STATE64 +#undef x86_FLOAT_STATE64_COUNT +#undef x86_FLOAT_STATE_COUNT +#undef x86_THREAD_STATE +#undef x86_THREAD_STATE32 +#undef x86_THREAD_STATE32_COUNT +#undef x86_THREAD_STATE64 +#undef x86_THREAD_STATE64_COUNT +#undef x86_THREAD_STATE_COUNT + #include "llvm/BinaryFormat/MachO.h" #endif // LLDB_HOST_SAFEMACHO_H diff --git a/lldb/include/lldb/Host/SocketAddress.h b/lldb/include/lldb/Host/SocketAddress.h index 862e1104a084..c88cc1260654 100644 --- a/lldb/include/lldb/Host/SocketAddress.h +++ b/lldb/include/lldb/Host/SocketAddress.h @@ -9,7 +9,7 @@ #ifndef LLDB_HOST_SOCKETADDRESS_H #define LLDB_HOST_SOCKETADDRESS_H -#include <stdint.h> +#include <cstdint> #ifdef _WIN32 #include "lldb/Host/windows/windows.h" diff --git a/lldb/include/lldb/Host/StringConvert.h b/lldb/include/lldb/Host/StringConvert.h index ad629ff30429..33608a85ff42 100644 --- a/lldb/include/lldb/Host/StringConvert.h +++ b/lldb/include/lldb/Host/StringConvert.h @@ -9,9 +9,7 @@ #ifndef LLDB_HOST_STRINGCONVERT_H #define LLDB_HOST_STRINGCONVERT_H -#include <stdint.h> - - +#include <cstdint> namespace lldb_private { diff --git a/lldb/include/lldb/Host/Terminal.h b/lldb/include/lldb/Host/Terminal.h index 61993223ea06..ca91d6b59720 100644 --- a/lldb/include/lldb/Host/Terminal.h +++ b/lldb/include/lldb/Host/Terminal.h @@ -21,7 +21,7 @@ class Terminal { public: Terminal(int fd = -1) : m_fd(fd) {} - ~Terminal() {} + ~Terminal() = default; bool IsATerminal() const; @@ -116,12 +116,12 @@ protected: // Member variables Terminal m_tty; ///< A terminal - int m_tflags; ///< Cached tflags information. + int m_tflags = -1; ///< Cached tflags information. #if LLDB_ENABLE_TERMIOS std::unique_ptr<struct termios> m_termios_up; ///< Cached terminal state information. #endif - lldb::pid_t m_process_group; ///< Cached process group information. + lldb::pid_t m_process_group = -1; ///< Cached process group information. }; /// \class TerminalStateSwitcher Terminal.h "lldb/Host/Terminal.h" @@ -171,7 +171,8 @@ public: protected: // Member variables - mutable uint32_t m_currentState; ///< The currently active TTY state index. + mutable uint32_t m_currentState = + UINT32_MAX; ///< The currently active TTY state index. TerminalState m_ttystates[2]; ///< The array of TTY states that holds saved TTY info. }; diff --git a/lldb/include/lldb/Host/Time.h b/lldb/include/lldb/Host/Time.h index 83b76ec0f9d1..aee4c43247c5 100644 --- a/lldb/include/lldb/Host/Time.h +++ b/lldb/include/lldb/Host/Time.h @@ -19,7 +19,7 @@ #include <time64.h> extern time_t timegm(struct tm *t); #else -#include <time.h> +#include <ctime> #endif #endif // LLDB_HOST_TIME_H diff --git a/lldb/include/lldb/Host/XML.h b/lldb/include/lldb/Host/XML.h index a80f1e9e4d26..9edf46bf09df 100644 --- a/lldb/include/lldb/Host/XML.h +++ b/lldb/include/lldb/Host/XML.h @@ -107,7 +107,7 @@ public: void ForEachAttribute(AttributeCallback const &callback) const; protected: - XMLNodeImpl m_node; + XMLNodeImpl m_node = nullptr; }; class XMLDocument { @@ -138,7 +138,7 @@ public: static bool XMLEnabled(); protected: - XMLDocumentImpl m_document; + XMLDocumentImpl m_document = nullptr; StreamString m_errors; }; diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 5be9cb657382..770149e3fb28 100644 --- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -16,7 +16,7 @@ #include "lldb/Host/MainLoop.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-types.h" @@ -30,6 +30,8 @@ #include <vector> namespace lldb_private { +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + class MemoryRegionInfo; class ResumeActionList; @@ -44,7 +46,7 @@ struct SVR4LibraryInfo { // NativeProcessProtocol class NativeProcessProtocol { public: - virtual ~NativeProcessProtocol() {} + virtual ~NativeProcessProtocol() = default; virtual Status Resume(const ResumeActionList &resume_actions) = 0; @@ -85,6 +87,12 @@ public: Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read); + virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len, + std::vector<uint8_t> &tags); + + virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len, + const std::vector<uint8_t> &tags); + /// Reads a null terminated string from memory. /// /// Reads up to \p max_size bytes of memory until it finds a '\0'. @@ -212,7 +220,7 @@ public: // Callbacks for low-level process state changes class NativeDelegate { public: - virtual ~NativeDelegate() {} + virtual ~NativeDelegate() = default; virtual void InitializeDelegate(NativeProcessProtocol *process) = 0; @@ -220,37 +228,11 @@ public: lldb::StateType state) = 0; virtual void DidExec(NativeProcessProtocol *process) = 0; - }; - - /// Register a native delegate. - /// - /// Clients can register nofication callbacks by passing in a - /// NativeDelegate impl and passing it into this function. - /// - /// Note: it is required that the lifetime of the - /// native_delegate outlive the NativeProcessProtocol. - /// - /// \param[in] native_delegate - /// A NativeDelegate impl to be called when certain events - /// happen within the NativeProcessProtocol or related threads. - /// - /// \return - /// true if the delegate was registered successfully; - /// false if the delegate was already registered. - /// - /// \see NativeProcessProtocol::NativeDelegate. - bool RegisterNativeDelegate(NativeDelegate &native_delegate); - /// Unregister a native delegate previously registered. - /// - /// \param[in] native_delegate - /// A NativeDelegate impl previously registered with this process. - /// - /// \return Returns \b true if the NativeDelegate was - /// successfully removed from the process, \b false otherwise. - /// - /// \see NativeProcessProtocol::NativeDelegate - bool UnregisterNativeDelegate(NativeDelegate &native_delegate); + virtual void + NewSubprocess(NativeProcessProtocol *parent_process, + std::unique_ptr<NativeProcessProtocol> child_process) = 0; + }; virtual Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) = 0; @@ -258,6 +240,20 @@ public: virtual Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr) = 0; + /// Extension flag constants, returned by Factory::GetSupportedExtensions() + /// and passed to SetEnabledExtension() + enum class Extension { + multiprocess = (1u << 0), + fork = (1u << 1), + vfork = (1u << 2), + pass_signals = (1u << 3), + auxv = (1u << 4), + libraries_svr4 = (1u << 5), + memory_tagging = (1u << 6), + + LLVM_MARK_AS_BITMASK_ENUM(memory_tagging) + }; + class Factory { public: virtual ~Factory(); @@ -304,99 +300,75 @@ public: virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>> Attach(lldb::pid_t pid, NativeDelegate &native_delegate, MainLoop &mainloop) const = 0; + + /// Get the bitmask of extensions supported by this process plugin. + /// + /// \return + /// A NativeProcessProtocol::Extension bitmask. + virtual Extension GetSupportedExtensions() const { return {}; } }; - /// StartTracing API for starting a tracing instance with the - /// TraceOptions on a specific thread or process. + /// Start tracing a process or its threads. /// - /// \param[in] config - /// The configuration to use when starting tracing. + /// \param[in] json_params + /// JSON object with the information of what and how to trace. + /// In the case of gdb-remote, this object should conform to the + /// jLLDBTraceStart packet. /// - /// \param[out] error - /// Status indicates what went wrong. + /// This object should have a string entry called "type", which is the + /// tracing technology name. /// - /// \return - /// The API returns a user_id which can be used to get trace - /// data, trace configuration or stopping the trace instance. - /// The user_id is a key to identify and operate with a tracing - /// instance. It may refer to the complete process or a single - /// thread. - virtual lldb::user_id_t StartTrace(const TraceOptions &config, - Status &error) { - error.SetErrorString("Not implemented"); - return LLDB_INVALID_UID; - } - - /// StopTracing API as the name suggests stops a tracing instance. - /// - /// \param[in] traceid - /// The user id of the trace intended to be stopped. Now a - /// user_id may map to multiple threads in which case this API - /// could be used to stop the tracing for a specific thread by - /// supplying its thread id. - /// - /// \param[in] thread - /// Thread is needed when the complete process is being traced - /// and the user wishes to stop tracing on a particular thread. + /// \param[in] type + /// Tracing technology type, as described in the \a json_params. /// /// \return - /// Status indicating what went wrong. - virtual Status StopTrace(lldb::user_id_t traceid, - lldb::tid_t thread = LLDB_INVALID_THREAD_ID) { - return Status("Not implemented"); + /// \a llvm::Error::success if the operation was successful, or an + /// \a llvm::Error otherwise. + virtual llvm::Error TraceStart(llvm::StringRef json_params, + llvm::StringRef type) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unsupported tracing type '%s'", + type.data()); } - /// This API provides the trace data collected in the form of raw - /// data. - /// - /// \param[in] traceid thread - /// The traceid and thread provide the context for the trace - /// instance. - /// - /// \param[in] buffer - /// The buffer provides the destination buffer where the trace - /// data would be read to. The buffer should be truncated to the - /// filled length by this function. - /// - /// \param[in] offset - /// There is possibility to read partially the trace data from - /// a specified offset where in such cases the buffer provided - /// may be smaller than the internal trace collection container. - /// - /// \return - /// The size of the data actually read. - virtual Status GetData(lldb::user_id_t traceid, lldb::tid_t thread, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); + /// \copydoc Process::TraceStop(const TraceStopRequest &) + virtual llvm::Error TraceStop(const TraceStopRequest &request) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unsupported tracing type '%s'", + request.type.data()); } - /// Similar API as above except it aims to provide any extra data - /// useful for decoding the actual trace data. - virtual Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); + /// \copydoc Process::TraceGetState(llvm::StringRef type) + virtual llvm::Expected<llvm::json::Value> + TraceGetState(llvm::StringRef type) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unsupported tracing type '%s'", + type.data()); } - /// API to query the TraceOptions for a given user id - /// - /// \param[in] traceid - /// The user id of the tracing instance. - /// - /// \param[out] config - /// The configuration being used for tracing. - /// - /// \return A status indicating what went wrong. - virtual Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) { - return Status("Not implemented"); + /// \copydoc Process::TraceGetBinaryData(const TraceGetBinaryDataRequest &) + virtual llvm::Expected<std::vector<uint8_t>> + TraceGetBinaryData(const TraceGetBinaryDataRequest &request) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Unsupported data kind '%s' for the '%s' tracing technology", + request.kind.c_str(), request.type.c_str()); } - /// \copydoc Process::GetSupportedTraceType() - virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() { + /// \copydoc Process::TraceSupported() + virtual llvm::Expected<TraceSupportedResponse> TraceSupported() { return llvm::make_error<UnimplementedError>(); } + /// Method called in order to propagate the bitmap of protocol + /// extensions supported by the client. + /// + /// \param[in] flags + /// The bitmap of enabled extensions. + virtual void SetEnabledExtensions(Extension flags) { + m_enabled_extensions = flags; + } + protected: struct SoftwareBreakpoint { uint32_t ref_count; @@ -416,8 +388,7 @@ protected: llvm::Optional<WaitStatus> m_exit_status; - std::recursive_mutex m_delegates_mutex; - std::vector<NativeDelegate *> m_delegates; + NativeDelegate &m_delegate; NativeWatchpointList m_watchpoint_list; HardwareBreakpointMap m_hw_breakpoints_map; int m_terminal_fd; @@ -427,6 +398,9 @@ protected: // stopping it. llvm::DenseSet<int> m_signals_to_ignore; + // Extensions enabled per the last SetEnabledExtensions() call. + Extension m_enabled_extensions; + // lldb_private::Host calls should be used to launch a process for debugging, // and then the process should be attached to. When attaching to a process // lldb_private::Host calls should be used to locate the process to attach diff --git a/lldb/include/lldb/Host/common/NativeThreadProtocol.h b/lldb/include/lldb/Host/common/NativeThreadProtocol.h index 8d4c03549bb9..5cf26bd95939 100644 --- a/lldb/include/lldb/Host/common/NativeThreadProtocol.h +++ b/lldb/include/lldb/Host/common/NativeThreadProtocol.h @@ -21,7 +21,7 @@ class NativeThreadProtocol { public: NativeThreadProtocol(NativeProcessProtocol &process, lldb::tid_t tid); - virtual ~NativeThreadProtocol() {} + virtual ~NativeThreadProtocol() = default; virtual std::string GetName() = 0; diff --git a/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index 3ee8f9d9133e..42be989dfa7b 100644 --- a/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -108,7 +108,7 @@ protected: std::atomic<bool> m_shutting_down; // This marks that we are shutting down so // if we get woken up from // BytesAvailable to disconnect, we won't try to read again. - bool m_waiting_for_accept; + bool m_waiting_for_accept = false; bool m_child_processes_inherit; std::string m_uri; diff --git a/lldb/include/lldb/Initialization/SystemInitializerCommon.h b/lldb/include/lldb/Initialization/SystemInitializerCommon.h index 3a5081680879..d918b1125a57 100644 --- a/lldb/include/lldb/Initialization/SystemInitializerCommon.h +++ b/lldb/include/lldb/Initialization/SystemInitializerCommon.h @@ -10,6 +10,7 @@ #define LLDB_INITIALIZATION_SYSTEMINITIALIZERCOMMON_H #include "SystemInitializer.h" +#include "lldb/Host/HostInfo.h" namespace lldb_private { /// Initializes common lldb functionality. @@ -22,11 +23,14 @@ namespace lldb_private { /// the constructor. class SystemInitializerCommon : public SystemInitializer { public: - SystemInitializerCommon(); + SystemInitializerCommon(HostInfo::SharedLibraryDirectoryHelper *helper); ~SystemInitializerCommon() override; llvm::Error Initialize() override; void Terminate() override; + +private: + HostInfo::SharedLibraryDirectoryHelper *m_shlib_dir_helper; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Initialization/SystemLifetimeManager.h b/lldb/include/lldb/Initialization/SystemLifetimeManager.h index 27e1a22b19dd..06328e60133f 100644 --- a/lldb/include/lldb/Initialization/SystemLifetimeManager.h +++ b/lldb/include/lldb/Initialization/SystemLifetimeManager.h @@ -30,7 +30,7 @@ public: private: std::recursive_mutex m_mutex; std::unique_ptr<SystemInitializer> m_initializer; - bool m_initialized; + bool m_initialized = false; // Noncopyable. SystemLifetimeManager(const SystemLifetimeManager &other) = delete; diff --git a/lldb/include/lldb/Interpreter/CommandHistory.h b/lldb/include/lldb/Interpreter/CommandHistory.h index fbb42247f11a..12c170ba5eeb 100644 --- a/lldb/include/lldb/Interpreter/CommandHistory.h +++ b/lldb/include/lldb/Interpreter/CommandHistory.h @@ -20,9 +20,9 @@ namespace lldb_private { class CommandHistory { public: - CommandHistory(); + CommandHistory() = default; - ~CommandHistory(); + ~CommandHistory() = default; size_t GetSize() const; diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index c4f9dd2fdb37..3b3daced3e33 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -24,15 +24,16 @@ #include "lldb/Utility/StringList.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" + #include <mutex> +#include <stack> namespace lldb_private { class CommandInterpreter; class CommandInterpreterRunResult { public: - CommandInterpreterRunResult() - : m_num_errors(0), m_result(lldb::eCommandInterpreterResultSuccess) {} + CommandInterpreterRunResult() = default; uint32_t GetNumErrors() const { return m_num_errors; } @@ -50,8 +51,9 @@ protected: void SetResult(lldb::CommandInterpreterResult result) { m_result = result; } private: - int m_num_errors; - lldb::CommandInterpreterResult m_result; + int m_num_errors = 0; + lldb::CommandInterpreterResult m_result = + lldb::eCommandInterpreterResultSuccess; }; class CommandInterpreterRunOptions { @@ -98,14 +100,7 @@ public: m_echo_comment_commands(echo_comments), m_print_results(print_results), m_print_errors(print_errors), m_add_to_history(add_to_history) {} - CommandInterpreterRunOptions() - : m_stop_on_continue(eLazyBoolCalculate), - m_stop_on_error(eLazyBoolCalculate), - m_stop_on_crash(eLazyBoolCalculate), - m_echo_commands(eLazyBoolCalculate), - m_echo_comment_commands(eLazyBoolCalculate), - m_print_results(eLazyBoolCalculate), m_print_errors(eLazyBoolCalculate), - m_add_to_history(eLazyBoolCalculate) {} + CommandInterpreterRunOptions() = default; void SetSilent(bool silent) { LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes; @@ -185,14 +180,14 @@ public: m_spawn_thread = spawn_thread ? eLazyBoolYes : eLazyBoolNo; } - LazyBool m_stop_on_continue; - LazyBool m_stop_on_error; - LazyBool m_stop_on_crash; - LazyBool m_echo_commands; - LazyBool m_echo_comment_commands; - LazyBool m_print_results; - LazyBool m_print_errors; - LazyBool m_add_to_history; + LazyBool m_stop_on_continue = eLazyBoolCalculate; + LazyBool m_stop_on_error = eLazyBoolCalculate; + LazyBool m_stop_on_crash = eLazyBoolCalculate; + LazyBool m_echo_commands = eLazyBoolCalculate; + LazyBool m_echo_comment_commands = eLazyBoolCalculate; + LazyBool m_print_results = eLazyBoolCalculate; + LazyBool m_print_errors = eLazyBoolCalculate; + LazyBool m_add_to_history = eLazyBoolCalculate; LazyBool m_auto_handle_events; LazyBool m_spawn_thread; @@ -245,7 +240,7 @@ public: CommandInterpreter(Debugger &debugger, bool synchronous_execution); - ~CommandInterpreter() override; + ~CommandInterpreter() override = default; // These two functions fill out the Broadcaster interface: @@ -300,10 +295,11 @@ public: CommandReturnObject &result); bool HandleCommand(const char *command_line, LazyBool add_to_history, - CommandReturnObject &result, - ExecutionContext *override_context = nullptr, - bool repeat_on_empty_command = true, - bool no_context_switching = false); + const ExecutionContext &override_context, + CommandReturnObject &result); + + bool HandleCommand(const char *command_line, LazyBool add_to_history, + CommandReturnObject &result); bool WasInterrupted() const; @@ -312,9 +308,7 @@ public: /// \param[in] commands /// The list of commands to execute. /// \param[in,out] context - /// The execution context in which to run the commands. Can be nullptr in - /// which case the default - /// context will be used. + /// The execution context in which to run the commands. /// \param[in] options /// This object holds the options used to control when to stop, whether to /// execute commands, @@ -324,8 +318,13 @@ public: /// safely, /// and failed with some explanation if we aborted executing the commands /// at some point. - void HandleCommands(const StringList &commands, ExecutionContext *context, - CommandInterpreterRunOptions &options, + void HandleCommands(const StringList &commands, + const ExecutionContext &context, + const CommandInterpreterRunOptions &options, + CommandReturnObject &result); + + void HandleCommands(const StringList &commands, + const CommandInterpreterRunOptions &options, CommandReturnObject &result); /// Execute a list of commands from a file. @@ -333,9 +332,7 @@ public: /// \param[in] file /// The file from which to read in commands. /// \param[in,out] context - /// The execution context in which to run the commands. Can be nullptr in - /// which case the default - /// context will be used. + /// The execution context in which to run the commands. /// \param[in] options /// This object holds the options used to control when to stop, whether to /// execute commands, @@ -345,8 +342,12 @@ public: /// safely, /// and failed with some explanation if we aborted executing the commands /// at some point. - void HandleCommandsFromFile(FileSpec &file, ExecutionContext *context, - CommandInterpreterRunOptions &options, + void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context, + const CommandInterpreterRunOptions &options, + CommandReturnObject &result); + + void HandleCommandsFromFile(FileSpec &file, + const CommandInterpreterRunOptions &options, CommandReturnObject &result); CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line); @@ -391,12 +392,7 @@ public: Debugger &GetDebugger() { return m_debugger; } - ExecutionContext GetExecutionContext() { - const bool thread_and_frame_only_if_stopped = true; - return m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped); - } - - void UpdateExecutionContext(ExecutionContext *override_context); + ExecutionContext GetExecutionContext() const; lldb::PlatformSP GetPlatform(bool prefer_target_platform); @@ -495,12 +491,17 @@ public: bool GetSaveSessionOnQuit() const; void SetSaveSessionOnQuit(bool enable); + FileSpec GetSaveSessionDirectory() const; + void SetSaveSessionDirectory(llvm::StringRef path); + bool GetEchoCommands() const; void SetEchoCommands(bool enable); bool GetEchoCommentCommands() const; void SetEchoCommentCommands(bool enable); + bool GetRepeatPreviousCommand() const; + const CommandObject::CommandMap &GetUserCommands() const { return m_user_dict; } @@ -581,6 +582,10 @@ protected: StringList *descriptions = nullptr) const; private: + void OverrideExecutionContext(const ExecutionContext &override_context); + + void RestoreExecutionContext(); + Status PreprocessCommand(std::string &command); void SourceInitFile(FileSpec file, CommandReturnObject &result); @@ -619,8 +624,9 @@ private: Debugger &m_debugger; // The debugger session that this interpreter is // associated with - ExecutionContextRef m_exe_ctx_ref; // The current execution context to use - // when handling commands + // Execution contexts that were temporarily set by some of HandleCommand* + // overloads. + std::stack<ExecutionContext> m_overriden_exe_contexts; bool m_synchronous_execution; bool m_skip_lldbinit_files; bool m_skip_app_init_files; diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h index d5ad969cda66..8bc5d3e22355 100644 --- a/lldb/include/lldb/Interpreter/CommandObject.h +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -113,7 +113,7 @@ public: llvm::StringRef help = "", llvm::StringRef syntax = "", uint32_t flags = 0); - virtual ~CommandObject(); + virtual ~CommandObject() = default; static const char * GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type); diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h index a7c2eea57663..0c995b73c463 100644 --- a/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -26,7 +26,7 @@ class CommandReturnObject { public: CommandReturnObject(bool colors); - ~CommandReturnObject(); + ~CommandReturnObject() = default; llvm::StringRef GetOutputData() { lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex)); @@ -63,20 +63,28 @@ public: } void SetImmediateOutputFile(lldb::FileSP file_sp) { + if (m_suppress_immediate_output) + return; lldb::StreamSP stream_sp(new StreamFile(file_sp)); m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } void SetImmediateErrorFile(lldb::FileSP file_sp) { + if (m_suppress_immediate_output) + return; lldb::StreamSP stream_sp(new StreamFile(file_sp)); m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } void SetImmediateOutputStream(const lldb::StreamSP &stream_sp) { + if (m_suppress_immediate_output) + return; m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } void SetImmediateErrorStream(const lldb::StreamSP &stream_sp) { + if (m_suppress_immediate_output) + return; m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } @@ -95,8 +103,6 @@ public: void AppendMessageWithFormat(const char *format, ...) __attribute__((format(printf, 2, 3))); - void AppendRawWarning(llvm::StringRef in_string); - void AppendWarning(llvm::StringRef in_string); void AppendWarningWithFormat(const char *format, ...) @@ -126,8 +132,6 @@ public: void SetError(const Status &error, const char *fallback_error_cstr = nullptr); - void SetError(llvm::StringRef error_cstr); - lldb::ReturnStatus GetStatus(); void SetStatus(lldb::ReturnStatus status); @@ -144,16 +148,23 @@ public: void SetInteractive(bool b); + bool GetSuppressImmediateOutput() const; + + void SetSuppressImmediateOutput(bool b); + private: enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 }; StreamTee m_out_stream; StreamTee m_err_stream; - lldb::ReturnStatus m_status; - bool m_did_change_process_state; - bool m_interactive; // If true, then the input handle from the debugger will - // be hooked up + lldb::ReturnStatus m_status = lldb::eReturnStatusStarted; + + bool m_did_change_process_state = false; + bool m_suppress_immediate_output = false; + + /// If true, then the input handle from the debugger will be hooked up. + bool m_interactive = true; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h b/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h index 1eadf45bae47..4655a68f1e4a 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h +++ b/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h @@ -18,9 +18,9 @@ namespace lldb_private { class OptionGroupArchitecture : public OptionGroup { public: - OptionGroupArchitecture(); + OptionGroupArchitecture() = default; - ~OptionGroupArchitecture() override; + ~OptionGroupArchitecture() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupBoolean.h b/lldb/include/lldb/Interpreter/OptionGroupBoolean.h index 061e31340854..9e2dad5d9c2a 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupBoolean.h +++ b/lldb/include/lldb/Interpreter/OptionGroupBoolean.h @@ -25,7 +25,7 @@ public: const char *usage_text, bool default_value, bool no_argument_toggle_default); - ~OptionGroupBoolean() override; + ~OptionGroupBoolean() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -33,7 +33,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupFile.h b/lldb/include/lldb/Interpreter/OptionGroupFile.h index 374cf10ea30a..1e4eb35eade4 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupFile.h +++ b/lldb/include/lldb/Interpreter/OptionGroupFile.h @@ -24,7 +24,7 @@ public: lldb::CommandArgumentType argument_type, const char *usage_text); - ~OptionGroupFile() override; + ~OptionGroupFile() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -32,7 +32,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; @@ -63,7 +62,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupFormat.h b/lldb/include/lldb/Interpreter/OptionGroupFormat.h index 62c6f97c6214..2d445b8a6c20 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupFormat.h +++ b/lldb/include/lldb/Interpreter/OptionGroupFormat.h @@ -32,13 +32,12 @@ public: uint64_t default_count = UINT64_MAX); // Pass UINT64_MAX to disable the "--count" option - ~OptionGroupFormat() override; + ~OptionGroupFormat() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h b/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h index a71998f3bc1a..3902247cfb3e 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h +++ b/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h @@ -20,13 +20,12 @@ class OptionGroupOutputFile : public OptionGroup { public: OptionGroupOutputFile(); - ~OptionGroupOutputFile() override; + ~OptionGroupOutputFile() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupPlatform.h b/lldb/include/lldb/Interpreter/OptionGroupPlatform.h index 99945e5246fd..fed2791a6130 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupPlatform.h +++ b/lldb/include/lldb/Interpreter/OptionGroupPlatform.h @@ -21,8 +21,7 @@ namespace lldb_private { class OptionGroupPlatform : public OptionGroup { public: OptionGroupPlatform(bool include_platform_option) - : OptionGroup(), m_platform_name(), m_sdk_sysroot(), - m_include_platform_option(include_platform_option) {} + : m_include_platform_option(include_platform_option) {} ~OptionGroupPlatform() override = default; diff --git a/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h b/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h index d4c924a44157..a0de1bc8b8a1 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h +++ b/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h @@ -1,4 +1,4 @@ -//===-- OptionGroupPythonClassWithDict.h -------------------------------------*- C++ -*-===// +//===-- OptionGroupPythonClassWithDict.h ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,9 +9,10 @@ #ifndef LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H #define LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H -#include "lldb/lldb-types.h" #include "lldb/Interpreter/Options.h" +#include "lldb/Utility/Flags.h" #include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-types.h" namespace lldb_private { @@ -23,13 +24,21 @@ namespace lldb_private { // StructuredData::Dictionary is constructed with those pairs. class OptionGroupPythonClassWithDict : public OptionGroup { public: - OptionGroupPythonClassWithDict(const char *class_use, - bool is_class = true, - int class_option = 'C', - int key_option = 'k', - int value_option = 'v'); - - ~OptionGroupPythonClassWithDict() override; + enum OptionKind { + eScriptClass = 1 << 0, + eDictKey = 1 << 1, + eDictValue = 1 << 2, + ePythonFunction = 1 << 3, + eAllOptions = (eScriptClass | eDictKey | eDictValue | ePythonFunction) + }; + + OptionGroupPythonClassWithDict(const char *class_use, bool is_class = true, + int class_option = 'C', int key_option = 'k', + int value_option = 'v', + uint16_t required_options = eScriptClass | + ePythonFunction); + + ~OptionGroupPythonClassWithDict() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(m_option_definition); @@ -37,7 +46,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; Status OptionParsingFinished(ExecutionContext *execution_context) override; @@ -56,6 +64,7 @@ protected: std::string m_class_usage_text, m_key_usage_text, m_value_usage_text; bool m_is_class; OptionDefinition m_option_definition[4]; + Flags m_required_options; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionGroupString.h b/lldb/include/lldb/Interpreter/OptionGroupString.h index 1a3b5bdd88ed..aa0225639035 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupString.h +++ b/lldb/include/lldb/Interpreter/OptionGroupString.h @@ -22,7 +22,7 @@ public: lldb::CommandArgumentType argument_type, const char *usage_text, const char *default_value); - ~OptionGroupString() override; + ~OptionGroupString() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -30,7 +30,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupUInt64.h b/lldb/include/lldb/Interpreter/OptionGroupUInt64.h index 783c4b632f00..710591725409 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupUInt64.h +++ b/lldb/include/lldb/Interpreter/OptionGroupUInt64.h @@ -23,7 +23,7 @@ public: lldb::CommandArgumentType argument_type, const char *usage_text, uint64_t default_value); - ~OptionGroupUInt64() override; + ~OptionGroupUInt64() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef<OptionDefinition>(&m_option_definition, 1); @@ -31,7 +31,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupUUID.h b/lldb/include/lldb/Interpreter/OptionGroupUUID.h index b1c779f7b5a4..4ca2a94b7fb3 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupUUID.h +++ b/lldb/include/lldb/Interpreter/OptionGroupUUID.h @@ -18,15 +18,14 @@ namespace lldb_private { class OptionGroupUUID : public OptionGroup { public: - OptionGroupUUID(); + OptionGroupUUID() = default; - ~OptionGroupUUID() override; + ~OptionGroupUUID() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index 1ad53321d26e..56452f4956f2 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -18,15 +18,14 @@ namespace lldb_private { class OptionGroupValueObjectDisplay : public OptionGroup { public: - OptionGroupValueObjectDisplay(); + OptionGroupValueObjectDisplay() = default; - ~OptionGroupValueObjectDisplay() override; + ~OptionGroupValueObjectDisplay() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupVariable.h b/lldb/include/lldb/Interpreter/OptionGroupVariable.h index 252ca3b42c5e..c9f1283d4de2 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupVariable.h +++ b/lldb/include/lldb/Interpreter/OptionGroupVariable.h @@ -20,13 +20,12 @@ class OptionGroupVariable : public OptionGroup { public: OptionGroupVariable(bool show_frame_options); - ~OptionGroupVariable() override; + ~OptionGroupVariable() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override; Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h b/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h index 6a6c8638aede..33818043cf63 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h +++ b/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h @@ -17,9 +17,9 @@ namespace lldb_private { class OptionGroupWatchpoint : public OptionGroup { public: - OptionGroupWatchpoint(); + OptionGroupWatchpoint() = default; - ~OptionGroupWatchpoint() override; + ~OptionGroupWatchpoint() override = default; static bool IsWatchSizeSupported(uint32_t watch_size); @@ -27,7 +27,6 @@ public: Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override; - Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; void OptionParsingStarting(ExecutionContext *execution_context) override; diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h index a8176e39940a..99f52b0411b9 100644 --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/include/lldb/Interpreter/OptionValue.h @@ -10,6 +10,7 @@ #define LLDB_INTERPRETER_OPTIONVALUE_H #include "lldb/Core/FormatEntity.h" +#include "lldb/Utility/Cloneable.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -59,7 +60,7 @@ public: eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue) }; - OptionValue() : m_value_was_set(false) {} + OptionValue() = default; virtual ~OptionValue() = default; @@ -87,7 +88,8 @@ public: virtual void Clear() = 0; - virtual lldb::OptionValueSP DeepCopy() const = 0; + virtual lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const; virtual void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request); @@ -306,6 +308,8 @@ public: m_parent_wp = parent_sp; } + lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); } + void SetValueChangedCallback(std::function<void()> callback) { assert(!m_callback); m_callback = std::move(callback); @@ -317,14 +321,20 @@ public: } protected: + using TopmostBase = OptionValue; + + // Must be overriden by a derived class for correct downcasting the result of + // DeepCopy to it. Inherit from Cloneable to avoid doing this manually. + virtual lldb::OptionValueSP Clone() const = 0; + lldb::OptionValueWP m_parent_wp; std::function<void()> m_callback; - bool m_value_was_set; // This can be used to see if a value has been set - // by a call to SetValueFromCString(). It is often - // handy to know if an option value was set from the - // command line or as a setting, versus if we just have - // the default value that was already populated in the - // option value. + bool m_value_was_set = false; // This can be used to see if a value has been + // set by a call to SetValueFromCString(). It is + // often handy to know if an option value was + // set from the command line or as a setting, + // versus if we just have the default value that + // was already populated in the option value. }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionValueArch.h b/lldb/include/lldb/Interpreter/OptionValueArch.h index 809261ef22c3..e17520879447 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArch.h +++ b/lldb/include/lldb/Interpreter/OptionValueArch.h @@ -15,23 +15,21 @@ namespace lldb_private { -class OptionValueArch : public OptionValue { +class OptionValueArch : public Cloneable<OptionValueArch, OptionValue> { public: - OptionValueArch() : OptionValue(), m_current_value(), m_default_value() {} + OptionValueArch() = default; - OptionValueArch(const char *triple) - : OptionValue(), m_current_value(triple), m_default_value() { + OptionValueArch(const char *triple) : m_current_value(triple) { m_default_value = m_current_value; } OptionValueArch(const ArchSpec &value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueArch(const ArchSpec ¤t_value, const ArchSpec &default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueArch() override {} + ~OptionValueArch() override = default; // Virtual subclass pure virtual overrides @@ -43,17 +41,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, lldb_private::CompletionRequest &request) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueArgs.h b/lldb/include/lldb/Interpreter/OptionValueArgs.h index 25f7fdde0bf3..1e2a1430d0c5 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArgs.h +++ b/lldb/include/lldb/Interpreter/OptionValueArgs.h @@ -13,15 +13,14 @@ namespace lldb_private { -class OptionValueArgs : public OptionValueArray { +class OptionValueArgs : public Cloneable<OptionValueArgs, OptionValueArray> { public: OptionValueArgs() - : OptionValueArray( - OptionValue::ConvertTypeToMask(OptionValue::eTypeString)) {} + : Cloneable(OptionValue::ConvertTypeToMask(OptionValue::eTypeString)) {} - ~OptionValueArgs() override {} + ~OptionValueArgs() override = default; - size_t GetArgs(Args &args); + size_t GetArgs(Args &args) const; Type GetType() const override { return eTypeArgs; } }; diff --git a/lldb/include/lldb/Interpreter/OptionValueArray.h b/lldb/include/lldb/Interpreter/OptionValueArray.h index 4546bbb80394..011eefc34251 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -15,12 +15,12 @@ namespace lldb_private { -class OptionValueArray : public OptionValue { +class OptionValueArray : public Cloneable<OptionValueArray, OptionValue> { public: OptionValueArray(uint32_t type_mask = UINT32_MAX, bool raw_value_dump = false) : m_type_mask(type_mask), m_values(), m_raw_value_dump(raw_value_dump) {} - ~OptionValueArray() override {} + ~OptionValueArray() override = default; // Virtual subclass pure virtual overrides @@ -32,16 +32,14 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_values.clear(); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; + lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const override; bool IsAggregateValue() const override { return true; } diff --git a/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/lldb/include/lldb/Interpreter/OptionValueBoolean.h index 1af14a4980ed..fd15ccb12c40 100644 --- a/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -13,15 +13,14 @@ namespace lldb_private { -class OptionValueBoolean : public OptionValue { +class OptionValueBoolean : public Cloneable<OptionValueBoolean, OptionValue> { public: OptionValueBoolean(bool value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueBoolean(bool current_value, bool default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueBoolean() override {} + ~OptionValueBoolean() override = default; // Virtual subclass pure virtual overrides @@ -33,9 +32,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; @@ -75,8 +71,6 @@ public: void SetDefaultValue(bool value) { m_default_value = value; } - lldb::OptionValueSP DeepCopy() const override; - protected: bool m_current_value; bool m_default_value; diff --git a/lldb/include/lldb/Interpreter/OptionValueChar.h b/lldb/include/lldb/Interpreter/OptionValueChar.h index a8ecf507a4cf..6b8a314a7c99 100644 --- a/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -13,16 +13,15 @@ namespace lldb_private { -class OptionValueChar : public OptionValue { +class OptionValueChar : public Cloneable<OptionValueChar, OptionValue> { public: OptionValueChar(char value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueChar(char current_value, char default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueChar() override {} + ~OptionValueChar() override = default; // Virtual subclass pure virtual overrides @@ -34,9 +33,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; @@ -58,8 +54,6 @@ public: void SetDefaultValue(char value) { m_default_value = value; } - lldb::OptionValueSP DeepCopy() const override; - protected: char m_current_value; char m_default_value; diff --git a/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/lldb/include/lldb/Interpreter/OptionValueDictionary.h index dab1c3ea0c1c..f96cbc9fe9e7 100644 --- a/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -15,14 +15,14 @@ namespace lldb_private { -class OptionValueDictionary : public OptionValue { +class OptionValueDictionary + : public Cloneable<OptionValueDictionary, OptionValue> { public: OptionValueDictionary(uint32_t type_mask = UINT32_MAX, bool raw_value_dump = true) - : OptionValue(), m_type_mask(type_mask), m_values(), - m_raw_value_dump(raw_value_dump) {} + : m_type_mask(type_mask), m_raw_value_dump(raw_value_dump) {} - ~OptionValueDictionary() override {} + ~OptionValueDictionary() override = default; // Virtual subclass pure virtual overrides @@ -40,7 +40,8 @@ public: m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; + lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const override; bool IsAggregateValue() const override { return true; } diff --git a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index 12c6473c7f1c..7dc6eea4e69d 100644 --- a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -19,7 +19,8 @@ namespace lldb_private { -class OptionValueEnumeration : public OptionValue { +class OptionValueEnumeration + : public Cloneable<OptionValueEnumeration, OptionValue> { public: typedef int64_t enum_type; struct EnumeratorInfo { @@ -31,7 +32,7 @@ public: OptionValueEnumeration(const OptionEnumValues &enumerators, enum_type value); - ~OptionValueEnumeration() override; + ~OptionValueEnumeration() override = default; // Virtual subclass pure virtual overrides @@ -43,17 +44,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h index 713deea9e141..83d36edc1e9a 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h @@ -9,19 +9,20 @@ #ifndef LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H #define LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H +#include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/OptionValue.h" - #include "lldb/Utility/FileSpec.h" #include "llvm/Support/Chrono.h" namespace lldb_private { -class OptionValueFileColonLine : public OptionValue { +class OptionValueFileColonLine : + public Cloneable<OptionValueFileColonLine, OptionValue> { public: OptionValueFileColonLine(); OptionValueFileColonLine(const llvm::StringRef input); - ~OptionValueFileColonLine() override {} + ~OptionValueFileColonLine() override = default; OptionValue::Type GetType() const override { return eTypeFileLineColumn; } @@ -31,9 +32,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_file_spec.Clear(); @@ -41,8 +39,6 @@ public: m_column_number = LLDB_INVALID_COLUMN_NUMBER; } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; @@ -54,9 +50,9 @@ public: protected: FileSpec m_file_spec; - uint32_t m_line_number; - uint32_t m_column_number; - uint32_t m_completion_mask; + uint32_t m_line_number = LLDB_INVALID_LINE_NUMBER; + uint32_t m_column_number = LLDB_INVALID_COLUMN_NUMBER; + uint32_t m_completion_mask = CommandCompletions::eSourceFileCompletion; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h index 4fde3f6e3c8a..6648bbac93e3 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -9,6 +9,7 @@ #ifndef LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H #define LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H +#include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/FileSpec.h" @@ -16,7 +17,7 @@ namespace lldb_private { -class OptionValueFileSpec : public OptionValue { +class OptionValueFileSpec : public Cloneable<OptionValueFileSpec, OptionValue> { public: OptionValueFileSpec(bool resolve = true); @@ -25,7 +26,7 @@ public: OptionValueFileSpec(const FileSpec ¤t_value, const FileSpec &default_value, bool resolve = true); - ~OptionValueFileSpec() override {} + ~OptionValueFileSpec() override = default; // Virtual subclass pure virtual overrides @@ -37,9 +38,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; @@ -48,8 +46,6 @@ public: m_data_mod_time = llvm::sys::TimePoint<>(); } - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; @@ -79,7 +75,7 @@ protected: FileSpec m_default_value; lldb::DataBufferSP m_data_sp; llvm::sys::TimePoint<> m_data_mod_time; - uint32_t m_completion_mask; + uint32_t m_completion_mask = CommandCompletions::eDiskFileCompletion; bool m_resolve; }; diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h index 38773525c8db..29641c3a2087 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h @@ -16,14 +16,15 @@ namespace lldb_private { -class OptionValueFileSpecList : public OptionValue { +class OptionValueFileSpecList + : public Cloneable<OptionValueFileSpecList, OptionValue> { public: - OptionValueFileSpecList() : OptionValue(), m_current_value() {} + OptionValueFileSpecList() = default; - OptionValueFileSpecList(const FileSpecList ¤t_value) - : OptionValue(), m_current_value(current_value) {} + OptionValueFileSpecList(const OptionValueFileSpecList &other) + : Cloneable(other), m_current_value(other.GetCurrentValue()) {} - ~OptionValueFileSpecList() override {} + ~OptionValueFileSpecList() override = default; // Virtual subclass pure virtual overrides @@ -35,9 +36,6 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { std::lock_guard<std::recursive_mutex> lock(m_mutex); @@ -45,8 +43,6 @@ public: m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - bool IsAggregateValue() const override { return true; } // Subclass specific functions @@ -67,6 +63,8 @@ public: } protected: + lldb::OptionValueSP Clone() const override; + mutable std::recursive_mutex m_mutex; FileSpecList m_current_value; }; diff --git a/lldb/include/lldb/Interpreter/OptionValueFormat.h b/lldb/include/lldb/Interpreter/OptionValueFormat.h index 5a83ff3b8983..1f2c66b164d5 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -13,16 +13,16 @@ namespace lldb_private { -class OptionValueFormat : public OptionValue { +class OptionValueFormat + : public Cloneable<OptionValueFormat, OptionValue> { public: OptionValueFormat(lldb::Format value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueFormat(lldb::Format current_value, lldb::Format default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueFormat() override {} + ~OptionValueFormat() override = default; // Virtual subclass pure virtual overrides @@ -34,17 +34,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions lldb::Format GetCurrentValue() const { return m_current_value; } diff --git a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index 7c2f9fba0242..cb8b2ef13fa4 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -14,11 +14,12 @@ namespace lldb_private { -class OptionValueFormatEntity : public OptionValue { +class OptionValueFormatEntity + : public Cloneable<OptionValueFormatEntity, OptionValue> { public: OptionValueFormatEntity(const char *default_format); - ~OptionValueFormatEntity() override {} + ~OptionValueFormatEntity() override = default; // Virtual subclass pure virtual overrides @@ -30,14 +31,9 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override; - lldb::OptionValueSP DeepCopy() const override; - void AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/lldb/include/lldb/Interpreter/OptionValueLanguage.h index 129365296759..c00f71ffff33 100644 --- a/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -15,17 +15,16 @@ namespace lldb_private { -class OptionValueLanguage : public OptionValue { +class OptionValueLanguage : public Cloneable<OptionValueLanguage, OptionValue> { public: OptionValueLanguage(lldb::LanguageType value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueLanguage(lldb::LanguageType current_value, lldb::LanguageType default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueLanguage() override {} + ~OptionValueLanguage() override = default; // Virtual subclass pure virtual overrides @@ -37,17 +36,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions lldb::LanguageType GetCurrentValue() const { return m_current_value; } diff --git a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h index 6d1a0816f45b..4bc65ce76c76 100644 --- a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -14,12 +14,13 @@ namespace lldb_private { -class OptionValuePathMappings : public OptionValue { +class OptionValuePathMappings + : public Cloneable<OptionValuePathMappings, OptionValue> { public: OptionValuePathMappings(bool notify_changes) - : OptionValue(), m_path_mappings(), m_notify_changes(notify_changes) {} + : m_notify_changes(notify_changes) {} - ~OptionValuePathMappings() override {} + ~OptionValuePathMappings() override = default; // Virtual subclass pure virtual overrides @@ -31,17 +32,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_path_mappings.Clear(m_notify_changes); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - bool IsAggregateValue() const override { return true; } // Subclass specific functions diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h index d60afdeb46fb..6fa5403ac142 100644 --- a/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -18,25 +18,27 @@ #include "lldb/Utility/ConstString.h" namespace lldb_private { +class Properties; class OptionValueProperties - : public OptionValue, + : public Cloneable<OptionValueProperties, OptionValue>, public std::enable_shared_from_this<OptionValueProperties> { public: - OptionValueProperties() - : OptionValue(), m_name(), m_properties(), m_name_to_index() {} + OptionValueProperties() = default; OptionValueProperties(ConstString name); - OptionValueProperties(const OptionValueProperties &global_properties); - ~OptionValueProperties() override = default; Type GetType() const override { return eTypeProperties; } void Clear() override; - lldb::OptionValueSP DeepCopy() const override; + static lldb::OptionValuePropertiesSP + CreateLocalCopy(const Properties &global_properties); + + lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const override; Status SetValueFromString(llvm::StringRef value, diff --git a/lldb/include/lldb/Interpreter/OptionValueRegex.h b/lldb/include/lldb/Interpreter/OptionValueRegex.h index 4751a1dc27ed..129987484f19 100644 --- a/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -14,11 +14,10 @@ namespace lldb_private { -class OptionValueRegex : public OptionValue { +class OptionValueRegex : public Cloneable<OptionValueRegex, OptionValue> { public: OptionValueRegex(const char *value = nullptr) - : OptionValue(), m_regex(llvm::StringRef::withNullAsEmpty(value)), - m_default_regex_str(llvm::StringRef::withNullAsEmpty(value).str()) {} + : m_regex(value), m_default_regex_str(value) {} ~OptionValueRegex() override = default; @@ -32,17 +31,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_regex = RegularExpression(m_default_regex_str); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions const RegularExpression *GetCurrentValue() const { return (m_regex.IsValid() ? &m_regex : nullptr); diff --git a/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/lldb/include/lldb/Interpreter/OptionValueSInt64.h index 87917c108865..3493eb1037c0 100644 --- a/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -14,27 +14,19 @@ namespace lldb_private { -class OptionValueSInt64 : public OptionValue { +class OptionValueSInt64 : public Cloneable<OptionValueSInt64, OptionValue> { public: - OptionValueSInt64() - : OptionValue(), m_current_value(0), m_default_value(0), - m_min_value(INT64_MIN), m_max_value(INT64_MAX) {} + OptionValueSInt64() = default; OptionValueSInt64(int64_t value) - : OptionValue(), m_current_value(value), m_default_value(value), - m_min_value(INT64_MIN), m_max_value(INT64_MAX) {} + : m_current_value(value), m_default_value(value) {} OptionValueSInt64(int64_t current_value, int64_t default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value), m_min_value(INT64_MIN), - m_max_value(INT64_MAX) {} + : m_current_value(current_value), m_default_value(default_value) {} - OptionValueSInt64(const OptionValueSInt64 &rhs) - : OptionValue(rhs), m_current_value(rhs.m_current_value), - m_default_value(rhs.m_default_value), m_min_value(rhs.m_min_value), - m_max_value(rhs.m_max_value) {} + OptionValueSInt64(const OptionValueSInt64 &rhs) = default; - ~OptionValueSInt64() override {} + ~OptionValueSInt64() override = default; // Virtual subclass pure virtual overrides @@ -46,17 +38,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions const int64_t &operator=(int64_t value) { @@ -93,10 +80,10 @@ public: int64_t GetMaximumValue() const { return m_max_value; } protected: - int64_t m_current_value; - int64_t m_default_value; - int64_t m_min_value; - int64_t m_max_value; + int64_t m_current_value = 0; + int64_t m_default_value = 0; + int64_t m_min_value = INT64_MIN; + int64_t m_max_value = INT64_MAX; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionValueString.h b/lldb/include/lldb/Interpreter/OptionValueString.h index ed44dae67d1d..be42deb80da7 100644 --- a/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/lldb/include/lldb/Interpreter/OptionValueString.h @@ -17,32 +17,25 @@ namespace lldb_private { -class OptionValueString : public OptionValue { +class OptionValueString : public Cloneable<OptionValueString, OptionValue> { public: typedef Status (*ValidatorCallback)(const char *string, void *baton); enum Options { eOptionEncodeCharacterEscapeSequences = (1u << 0) }; - OptionValueString() - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(), m_validator_baton() {} + OptionValueString() = default; OptionValueString(ValidatorCallback validator, void *baton = nullptr) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(validator), m_validator_baton(baton) {} + : m_validator(validator), m_validator_baton(baton) {} - OptionValueString(const char *value) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(), m_validator_baton() { + OptionValueString(const char *value) { if (value && value[0]) { m_current_value.assign(value); m_default_value.assign(value); } } - OptionValueString(const char *current_value, const char *default_value) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(), m_validator_baton() { + OptionValueString(const char *current_value, const char *default_value) { if (current_value && current_value[0]) m_current_value.assign(current_value); if (default_value && default_value[0]) @@ -51,8 +44,7 @@ public: OptionValueString(const char *value, ValidatorCallback validator, void *baton = nullptr) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(validator), m_validator_baton(baton) { + : m_validator(validator), m_validator_baton(baton) { if (value && value[0]) { m_current_value.assign(value); m_default_value.assign(value); @@ -61,8 +53,7 @@ public: OptionValueString(const char *current_value, const char *default_value, ValidatorCallback validator, void *baton = nullptr) - : OptionValue(), m_current_value(), m_default_value(), m_options(), - m_validator(validator), m_validator_baton(baton) { + : m_validator(validator), m_validator_baton(baton) { if (current_value && current_value[0]) m_current_value.assign(current_value); if (default_value && default_value[0]) @@ -81,17 +72,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions Flags &GetOptions() { return m_options; } @@ -99,7 +85,7 @@ public: const Flags &GetOptions() const { return m_options; } const char *operator=(const char *value) { - SetCurrentValue(llvm::StringRef::withNullAsEmpty(value)); + SetCurrentValue(value); return m_current_value.c_str(); } @@ -109,7 +95,6 @@ public: const char *GetDefaultValue() const { return m_default_value.c_str(); } llvm::StringRef GetDefaultValueAsRef() const { return m_default_value; } - Status SetCurrentValue(const char *) = delete; Status SetCurrentValue(llvm::StringRef value); Status AppendToCurrentValue(const char *value); @@ -129,8 +114,8 @@ protected: std::string m_current_value; std::string m_default_value; Flags m_options; - ValidatorCallback m_validator; - void *m_validator_baton; + ValidatorCallback m_validator = nullptr; + void *m_validator_baton = nullptr; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/lldb/include/lldb/Interpreter/OptionValueUInt64.h index 1164fb802f68..f212b2a19def 100644 --- a/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -14,24 +14,22 @@ namespace lldb_private { -class OptionValueUInt64 : public OptionValue { +class OptionValueUInt64 : public Cloneable<OptionValueUInt64, OptionValue> { public: - OptionValueUInt64() : OptionValue(), m_current_value(0), m_default_value(0) {} + OptionValueUInt64() = default; OptionValueUInt64(uint64_t value) - : OptionValue(), m_current_value(value), m_default_value(value) {} + : m_current_value(value), m_default_value(value) {} OptionValueUInt64(uint64_t current_value, uint64_t default_value) - : OptionValue(), m_current_value(current_value), - m_default_value(default_value) {} + : m_current_value(current_value), m_default_value(default_value) {} - ~OptionValueUInt64() override {} + ~OptionValueUInt64() override = default; // Decode a uint64_t from "value_cstr" return a OptionValueUInt64 object // inside of a lldb::OptionValueSP object if all goes well. If the string // isn't a uint64_t value or any other error occurs, return an empty // lldb::OptionValueSP and fill error in with the correct stuff. - static lldb::OptionValueSP Create(const char *, Status &) = delete; static lldb::OptionValueSP Create(llvm::StringRef value_str, Status &error); // Virtual subclass pure virtual overrides @@ -43,17 +41,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_current_value = m_default_value; m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions const uint64_t &operator=(uint64_t value) { @@ -72,8 +65,8 @@ public: void SetDefaultValue(uint64_t value) { m_default_value = value; } protected: - uint64_t m_current_value; - uint64_t m_default_value; + uint64_t m_current_value = 0; + uint64_t m_default_value = 0; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/OptionValueUUID.h b/lldb/include/lldb/Interpreter/OptionValueUUID.h index 1f663e999b9d..0ed490d1811d 100644 --- a/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -14,13 +14,13 @@ namespace lldb_private { -class OptionValueUUID : public OptionValue { +class OptionValueUUID : public Cloneable<OptionValueUUID, OptionValue> { public: - OptionValueUUID() : OptionValue(), m_uuid() {} + OptionValueUUID() = default; - OptionValueUUID(const UUID &uuid) : OptionValue(), m_uuid(uuid) {} + OptionValueUUID(const UUID &uuid) : m_uuid(uuid) {} - ~OptionValueUUID() override {} + ~OptionValueUUID() override = default; // Virtual subclass pure virtual overrides @@ -32,17 +32,12 @@ public: Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Status - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void Clear() override { m_uuid.Clear(); m_value_was_set = false; } - lldb::OptionValueSP DeepCopy() const override; - // Subclass specific functions UUID &GetCurrentValue() { return m_uuid; } diff --git a/lldb/include/lldb/Interpreter/Options.h b/lldb/include/lldb/Interpreter/Options.h index 9738cce2f7a1..6bf5c21fe98e 100644 --- a/lldb/include/lldb/Interpreter/Options.h +++ b/lldb/include/lldb/Interpreter/Options.h @@ -254,8 +254,7 @@ public: class OptionGroupOptions : public Options { public: - OptionGroupOptions() - : Options(), m_option_defs(), m_option_infos(), m_did_finalize(false) {} + OptionGroupOptions() = default; ~OptionGroupOptions() override = default; @@ -318,7 +317,7 @@ public: std::vector<OptionDefinition> m_option_defs; OptionInfos m_option_infos; - bool m_did_finalize; + bool m_did_finalize = false; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 4abd1ca68167..80a054b32ce6 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -9,12 +9,15 @@ #ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H #define LLDB_INTERPRETER_SCRIPTINTERPRETER_H +#include "lldb/API/SBData.h" +#include "lldb/API/SBError.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/Communication.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Core/StreamFile.h" #include "lldb/Host/PseudoTerminal.h" +#include "lldb/Interpreter/ScriptedProcessInterface.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" @@ -34,6 +37,62 @@ private: operator=(const ScriptInterpreterLocker &) = delete; }; +class ExecuteScriptOptions { +public: + ExecuteScriptOptions() = default; + + bool GetEnableIO() const { return m_enable_io; } + + bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } + + // If this is true then any exceptions raised by the script will be + // cleared with PyErr_Clear(). If false then they will be left for + // the caller to clean up + bool GetMaskoutErrors() const { return m_maskout_errors; } + + ExecuteScriptOptions &SetEnableIO(bool enable) { + m_enable_io = enable; + return *this; + } + + ExecuteScriptOptions &SetSetLLDBGlobals(bool set) { + m_set_lldb_globals = set; + return *this; + } + + ExecuteScriptOptions &SetMaskoutErrors(bool maskout) { + m_maskout_errors = maskout; + return *this; + } + +private: + bool m_enable_io = true; + bool m_set_lldb_globals = true; + bool m_maskout_errors = true; +}; + +class LoadScriptOptions { +public: + LoadScriptOptions() = default; + + bool GetInitSession() const { return m_init_session; } + bool GetSilent() const { return m_silent; } + + LoadScriptOptions &SetInitSession(bool b) { + m_init_session = b; + return *this; + } + + LoadScriptOptions &SetSilent(bool b) { + m_silent = b; + return *this; + } + +private: + bool m_init_session = false; + bool m_silent = false; +}; + class ScriptInterpreterIORedirect { public: /// Create an IO redirect. If IO is enabled, this will redirects the output @@ -83,44 +142,12 @@ public: eScriptReturnTypeOpaqueObject }; - ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang); - - ~ScriptInterpreter() override; - - struct ExecuteScriptOptions { - public: - ExecuteScriptOptions() - : m_enable_io(true), m_set_lldb_globals(true), m_maskout_errors(true) {} - - bool GetEnableIO() const { return m_enable_io; } - - bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } + ScriptInterpreter( + Debugger &debugger, lldb::ScriptLanguage script_lang, + lldb::ScriptedProcessInterfaceUP scripted_process_interface_up = + std::make_unique<ScriptedProcessInterface>()); - // If this is true then any exceptions raised by the script will be - // cleared with PyErr_Clear(). If false then they will be left for - // the caller to clean up - bool GetMaskoutErrors() const { return m_maskout_errors; } - - ExecuteScriptOptions &SetEnableIO(bool enable) { - m_enable_io = enable; - return *this; - } - - ExecuteScriptOptions &SetSetLLDBGlobals(bool set) { - m_set_lldb_globals = set; - return *this; - } - - ExecuteScriptOptions &SetMaskoutErrors(bool maskout) { - m_maskout_errors = maskout; - return *this; - } - - private: - bool m_enable_io; - bool m_set_lldb_globals; - bool m_maskout_errors; - }; + ~ScriptInterpreter() override = default; virtual bool Interrupt() { return false; } @@ -334,18 +361,19 @@ public: } virtual void CollectDataForBreakpointCommandCallback( - std::vector<BreakpointOptions *> &options, CommandReturnObject &result); + std::vector<std::reference_wrapper<BreakpointOptions>> &options, + CommandReturnObject &result); virtual void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result); /// Set the specified text as the callback for the breakpoint. - Status - SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec, - const char *callback_text); + Status SetBreakpointCommandCallback( + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, + const char *callback_text); - virtual Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, + virtual Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_text) { Status error; error.SetErrorString("unimplemented"); @@ -354,7 +382,7 @@ public: /// This one is for deserialization: virtual Status SetBreakpointCommandCallback( - BreakpointOptions *bp_options, + BreakpointOptions &bp_options, std::unique_ptr<BreakpointOptions::CommandData> &data_up) { Status error; error.SetErrorString("unimplemented"); @@ -362,15 +390,14 @@ public: } Status SetBreakpointCommandCallbackFunction( - std::vector<BreakpointOptions *> &bp_options_vec, + std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, const char *function_name, StructuredData::ObjectSP extra_args_sp); /// Set a script function as the callback for the breakpoint. virtual Status - SetBreakpointCommandCallbackFunction( - BreakpointOptions *bp_options, - const char *function_name, - StructuredData::ObjectSP extra_args_sp) { + SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, + const char *function_name, + StructuredData::ObjectSP extra_args_sp) { Status error; error.SetErrorString("unimplemented"); return error; @@ -505,7 +532,7 @@ public: virtual bool CheckObjectExists(const char *name) { return false; } virtual bool - LoadScriptingModule(const char *filename, bool init_session, + LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}); @@ -528,9 +555,19 @@ public: lldb::ScriptLanguage GetLanguage() { return m_script_lang; } + ScriptedProcessInterface &GetScriptedProcessInterface() { + return *m_scripted_process_interface_up; + } + + lldb::DataExtractorSP + GetDataExtractorFromSBData(const lldb::SBData &data) const; + + Status GetStatusFromSBError(const lldb::SBError &error) const; + protected: Debugger &m_debugger; lldb::ScriptLanguage m_script_lang; + lldb::ScriptedProcessInterfaceUP m_scripted_process_interface_up; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h new file mode 100644 index 000000000000..223e89be87ee --- /dev/null +++ b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -0,0 +1,68 @@ +//===-- ScriptedProcessInterface.h ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H +#define LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/lldb-private.h" + +#include <string> + +namespace lldb_private { +class ScriptedProcessInterface { +public: + ScriptedProcessInterface() : m_object_instance_sp(nullptr) {} + + virtual ~ScriptedProcessInterface() = default; + + virtual StructuredData::GenericSP + CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp, + StructuredData::DictionarySP args_sp) { + return nullptr; + } + + virtual Status Launch() { return Status("ScriptedProcess did not launch"); } + + virtual Status Resume() { return Status("ScriptedProcess did not resume"); } + + virtual bool ShouldStop() { return true; } + + virtual Status Stop() { return Status("ScriptedProcess did not stop"); } + + virtual lldb::MemoryRegionInfoSP + GetMemoryRegionContainingAddress(lldb::addr_t address) { + return nullptr; + } + + virtual StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) { + return nullptr; + } + + virtual StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) { + return nullptr; + } + + virtual lldb::DataExtractorSP + ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) { + return nullptr; + } + + virtual StructuredData::DictionarySP GetLoadedImages() { return nullptr; } + + virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; } + + virtual bool IsAlive() { return true; } + +private: + StructuredData::ObjectSP m_object_instance_sp; +}; +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H diff --git a/lldb/include/lldb/Symbol/CompactUnwindInfo.h b/lldb/include/lldb/Symbol/CompactUnwindInfo.h index e622c5fde229..ceb501e1c05f 100644 --- a/lldb/include/lldb/Symbol/CompactUnwindInfo.h +++ b/lldb/include/lldb/Symbol/CompactUnwindInfo.h @@ -50,21 +50,20 @@ private: // There are relatively few of these (one per 500/1000 functions, depending // on format) so creating them on first scan will not be too costly. struct UnwindIndex { - uint32_t function_offset; // The offset of the first function covered by - // this index - uint32_t second_level; // The offset (inside unwind_info sect) to the second - // level page for this index + uint32_t function_offset = 0; // The offset of the first function covered by + // this index + uint32_t second_level = 0; // The offset (inside unwind_info sect) to the + // second level page for this index // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED) - uint32_t lsda_array_start; // The offset (inside unwind_info sect) LSDA - // array for this index - uint32_t lsda_array_end; // The offset to the LSDA array for the NEXT index - bool sentinal_entry; // There is an empty index at the end which provides - // the upper bound of + uint32_t lsda_array_start = 0; // The offset (inside unwind_info sect) LSDA + // array for this index + uint32_t lsda_array_end = + 0; // The offset to the LSDA array for the NEXT index + bool sentinal_entry = false; // There is an empty index at the end which + // provides the upper bound of // function addresses that are described - UnwindIndex() - : function_offset(0), second_level(0), lsda_array_start(0), - lsda_array_end(0), sentinal_entry(false) {} + UnwindIndex() = default; bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const { return function_offset < rhs.function_offset; @@ -78,30 +77,26 @@ private: // An internal object used to store the information we retrieve about a // function -- the encoding bits and possibly the LSDA/personality function. struct FunctionInfo { - uint32_t encoding; // compact encoding 32-bit value for this function + uint32_t encoding = 0; // compact encoding 32-bit value for this function Address lsda_address; // the address of the LSDA data for this function Address personality_ptr_address; // the address where the personality // routine addr can be found - uint32_t valid_range_offset_start; // first offset that this encoding is - // valid for (start of the function) - uint32_t - valid_range_offset_end; // the offset of the start of the next function - FunctionInfo() - : encoding(0), lsda_address(), personality_ptr_address(), - valid_range_offset_start(0), valid_range_offset_end(0) {} + uint32_t valid_range_offset_start = 0; // first offset that this encoding is + // valid for (start of the function) + uint32_t valid_range_offset_end = + 0; // the offset of the start of the next function + FunctionInfo() : lsda_address(), personality_ptr_address() {} }; struct UnwindHeader { uint32_t version; - uint32_t common_encodings_array_offset; - uint32_t common_encodings_array_count; - uint32_t personality_array_offset; - uint32_t personality_array_count; - - UnwindHeader() - : common_encodings_array_offset(0), common_encodings_array_count(0), - personality_array_offset(0), personality_array_count(0) {} + uint32_t common_encodings_array_offset = 0; + uint32_t common_encodings_array_count = 0; + uint32_t personality_array_offset = 0; + uint32_t personality_array_count = 0; + + UnwindHeader() = default; }; void ScanIndex(const lldb::ProcessSP &process_sp); diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h index 256148f20d12..2e52bca7097c 100644 --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -11,6 +11,7 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/LineTable.h" @@ -345,29 +346,22 @@ public: /// Resolve symbol contexts by file and line. /// - /// Given a file in \a file_spec, and a line number, find all instances and + /// Given a file in \a src_location_spec, find all instances and /// append them to the supplied symbol context list \a sc_list. /// - /// \param[in] file_spec - /// A file specification. If \a file_spec contains no directory - /// information, only the basename will be used when matching - /// contexts. If the directory in \a file_spec is valid, a - /// complete file specification match will be performed. - /// - /// \param[in] line - /// The line number to match against the compile unit's line - /// tables. + /// \param[in] src_location_spec + /// The \a src_location_spec containing the \a file_spec, the line and the + /// column of the symbol to look for. Also hold the inlines and + /// exact_match flags. /// - /// \param[in] check_inlines - /// If \b true this function will also match any inline + /// If check_inlines is \b true, this function will also match any inline /// file and line matches. If \b false, the compile unit's /// file specification must match \a file_spec for any matches /// to be returned. /// - /// \param[in] exact - /// If true, only resolve the context if \a line exists in the line table. - /// If false, resolve the context to the closest line greater than \a line - /// in the line table. + /// If exact_match is \b true, only resolve the context if \a line and \a + /// column exists in the line table. If \b false, resolve the context to + /// the closest line greater than \a line in the line table. /// /// \param[in] resolve_scope /// For each matching line entry, this bitfield indicates what @@ -382,8 +376,7 @@ public: /// entries appended to. /// /// \see enum SymbolContext::Scope - void ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, bool exact, + void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index 5a0e8e57200d..0ad05a27570e 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -71,10 +71,12 @@ public: bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } - bool IsArrayType(CompilerType *element_type, uint64_t *size, - bool *is_incomplete) const; + bool IsArrayType(CompilerType *element_type = nullptr, + uint64_t *size = nullptr, + bool *is_incomplete = nullptr) const; - bool IsVectorType(CompilerType *element_type, uint64_t *size) const; + bool IsVectorType(CompilerType *element_type = nullptr, + uint64_t *size = nullptr) const; bool IsArrayOfScalarType() const; @@ -110,7 +112,8 @@ public: bool IsFunctionPointerType() const; - bool IsBlockPointerType(CompilerType *function_pointer_type_ptr) const; + bool + IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; bool IsIntegerType(bool &is_signed) const; diff --git a/lldb/include/lldb/Symbol/DeclVendor.h b/lldb/include/lldb/Symbol/DeclVendor.h index 67dcaf1734bd..19ab2bb66e2c 100644 --- a/lldb/include/lldb/Symbol/DeclVendor.h +++ b/lldb/include/lldb/Symbol/DeclVendor.h @@ -28,7 +28,7 @@ public: // Constructors and Destructors DeclVendor(DeclVendorKind kind) : m_kind(kind) {} - virtual ~DeclVendor() {} + virtual ~DeclVendor() = default; DeclVendorKind GetKind() const { return m_kind; } diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h index 300d829219d4..b703617773ff 100644 --- a/lldb/include/lldb/Symbol/Function.h +++ b/lldb/include/lldb/Symbol/Function.h @@ -10,10 +10,10 @@ #define LLDB_SYMBOL_FUNCTION_H #include "lldb/Core/AddressRange.h" +#include "lldb/Core/Declaration.h" #include "lldb/Core/Mangled.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/UserID.h" #include "llvm/ADT/ArrayRef.h" @@ -271,7 +271,7 @@ using CallSiteParameterArray = llvm::SmallVector<CallSiteParameter, 0>; class CallEdge { public: enum class AddrType : uint8_t { Call, AfterCall }; - virtual ~CallEdge() {} + virtual ~CallEdge() = default; /// Get the callee's definition. /// @@ -631,10 +631,10 @@ public: lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, - bool prefer_file_cache); + bool force_live_memory = false); bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, - bool prefer_file_cache, Stream &strm); + Stream &strm, bool force_live_memory = false); protected: enum { diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h index 7e56ef814765..698d89974dc6 100644 --- a/lldb/include/lldb/Symbol/LineEntry.h +++ b/lldb/include/lldb/Symbol/LineEntry.h @@ -140,10 +140,12 @@ struct LineEntry { FileSpec file; ///< The source file, possibly mapped by the target.source-map ///setting FileSpec original_file; ///< The original source file, from debug info. - uint32_t line; ///< The source line number, or zero if there is no line number - ///information. - uint16_t column; ///< The column number of the source line, or zero if there - ///is no column information. + uint32_t line = LLDB_INVALID_LINE_NUMBER; ///< The source line number, or zero + ///< if there is no line number + /// information. + uint16_t column = + 0; ///< The column number of the source line, or zero if there + /// is no column information. uint16_t is_start_of_statement : 1, ///< Indicates this entry is the beginning ///of a statement. is_start_of_basic_block : 1, ///< Indicates this entry is the beginning of diff --git a/lldb/include/lldb/Symbol/LineTable.h b/lldb/include/lldb/Symbol/LineTable.h index b48e82f19ffb..5cd22bd831ee 100644 --- a/lldb/include/lldb/Symbol/LineTable.h +++ b/lldb/include/lldb/Symbol/LineTable.h @@ -12,6 +12,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/Section.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" @@ -137,12 +138,8 @@ public: /// CompileUnit::GetSupportFiles() /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const /// - /// \param[in] line - /// The source line to match. - /// - /// \param[in] exact - /// If true, match only if you find a line entry exactly matching \a line. - /// If false, return the closest line entry greater than \a line. + /// \param[in] src_location_spec + /// The source location specifier to match. /// /// \param[out] line_entry_ptr /// A pointer to a line entry object that will get a copy of @@ -155,13 +152,14 @@ public: /// /// \see CompileUnit::GetSupportFiles() /// \see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const - uint32_t FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, - uint32_t line, bool exact, - LineEntry *line_entry_ptr); + uint32_t + FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, + const SourceLocationSpec &src_location_spec, + LineEntry *line_entry_ptr); uint32_t FindLineEntryIndexByFileIndex( - uint32_t start_idx, const std::vector<uint32_t> &file_indexes, - uint32_t line, bool exact, LineEntry *line_entry_ptr); + uint32_t start_idx, const std::vector<uint32_t> &file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr); size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append, SymbolContextList &sc_list); @@ -211,10 +209,9 @@ public: protected: struct Entry { Entry() - : file_addr(LLDB_INVALID_ADDRESS), line(0), - is_start_of_statement(false), is_start_of_basic_block(false), + : line(0), is_start_of_statement(false), is_start_of_basic_block(false), is_prologue_end(false), is_epilogue_begin(false), - is_terminal_entry(false), column(0), file_idx(0) {} + is_terminal_entry(false) {} Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column, uint16_t _file_idx, bool _is_start_of_statement, @@ -281,7 +278,7 @@ protected: // Member variables. /// The file address for this line entry. - lldb::addr_t file_addr; + lldb::addr_t file_addr = LLDB_INVALID_ADDRESS; /// The source line number, or zero if there is no line number /// information. uint32_t line : 27; @@ -300,10 +297,10 @@ protected: uint32_t is_terminal_entry : 1; /// The column number of the source line, or zero if there is no /// column information. - uint16_t column; + uint16_t column = 0; /// The file index into CompileUnit's file table, or zero if there /// is no file information. - uint16_t file_idx; + uint16_t file_idx = 0; }; struct EntrySearchInfo { @@ -341,6 +338,75 @@ protected: private: LineTable(const LineTable &) = delete; const LineTable &operator=(const LineTable &) = delete; + + template <typename T> + uint32_t FindLineEntryIndexByFileIndexImpl( + uint32_t start_idx, T file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr, + std::function<bool(T, uint16_t)> file_idx_matcher) { + const size_t count = m_entries.size(); + size_t best_match = UINT32_MAX; + + if (!line_entry_ptr) + return best_match; + + const uint32_t line = src_location_spec.GetLine().getValueOr(0); + const uint16_t column = + src_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER); + const bool exact_match = src_location_spec.GetExactMatch(); + + for (size_t idx = start_idx; idx < count; ++idx) { + // Skip line table rows that terminate the previous row (is_terminal_entry + // is non-zero) + if (m_entries[idx].is_terminal_entry) + continue; + + if (!file_idx_matcher(file_idx, m_entries[idx].file_idx)) + continue; + + // Exact match always wins. Otherwise try to find the closest line > the + // desired line. + // FIXME: Maybe want to find the line closest before and the line closest + // after and if they're not in the same function, don't return a match. + + if (column == LLDB_INVALID_COLUMN_NUMBER) { + if (m_entries[idx].line < line) { + continue; + } else if (m_entries[idx].line == line) { + ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); + return idx; + } else if (!exact_match) { + if (best_match == UINT32_MAX || + m_entries[idx].line < m_entries[best_match].line) + best_match = idx; + } + } else { + if (m_entries[idx].line < line) { + continue; + } else if (m_entries[idx].line == line && + m_entries[idx].column == column) { + ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); + return idx; + } else if (!exact_match) { + if (best_match == UINT32_MAX) + best_match = idx; + else if (m_entries[idx].line < m_entries[best_match].line) + best_match = idx; + else if (m_entries[idx].line == m_entries[best_match].line) + if (m_entries[idx].column && + m_entries[idx].column < m_entries[best_match].column) + best_match = idx; + } + } + } + + if (best_match != UINT32_MAX) { + if (line_entry_ptr) + ConvertEntryAtIndexToLineEntry(best_match, *line_entry_ptr); + return best_match; + } + return UINT32_MAX; + } }; } // namespace lldb_private diff --git a/lldb/include/lldb/Symbol/LocateSymbolFile.h b/lldb/include/lldb/Symbol/LocateSymbolFile.h index 93b76e53f41f..2c3f6a7b7b59 100644 --- a/lldb/include/lldb/Symbol/LocateSymbolFile.h +++ b/lldb/include/lldb/Symbol/LocateSymbolFile.h @@ -9,7 +9,7 @@ #ifndef LLDB_SYMBOL_LOCATESYMBOLFILE_H #define LLDB_SYMBOL_LOCATESYMBOLFILE_H -#include <stdint.h> +#include <cstdint> #include "lldb/Core/FileSpecList.h" #include "lldb/Utility/FileSpec.h" diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index 080724cb86bd..4ccd7f92064d 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -25,9 +25,9 @@ namespace lldb_private { class ObjectFileJITDelegate { public: - ObjectFileJITDelegate() {} + ObjectFileJITDelegate() = default; - virtual ~ObjectFileJITDelegate() {} + virtual ~ObjectFileJITDelegate() = default; virtual lldb::ByteOrder GetByteOrder() const = 0; @@ -495,6 +495,16 @@ public: return std::string(); } + /// Some object files may have the number of bits used for addressing + /// embedded in them, e.g. a Mach-O core file using an LC_NOTE. These + /// object files can return the address mask that should be used in + /// the Process. + /// \return + /// The mask will have bits set which aren't used for addressing -- + /// typically, the high bits. + /// Zero is returned when no address bits mask is available. + virtual lldb::addr_t GetAddressMask() { return 0; } + /// When the ObjectFile is a core file, lldb needs to locate the "binary" in /// the core file. lldb can iterate over the pages looking for a valid /// binary, but some core files may have metadata describing where the main @@ -666,6 +676,22 @@ public: /// Creates a plugin-specific call frame info virtual std::unique_ptr<CallFrameInfo> CreateCallFrameInfo(); + /// Load binaries listed in a corefile + /// + /// A corefile may have metadata listing binaries that can be loaded, + /// and the offsets at which they were loaded. This method will try + /// to add them to the Target. If any binaries were loaded, + /// + /// \param[in] process + /// Process where to load binaries. + /// + /// \return + /// Returns true if any binaries were loaded. + + virtual bool LoadCoreFileImages(lldb_private::Process &process) { + return false; + } + protected: // Member variables. FileSpec m_file; @@ -696,8 +722,6 @@ protected: /// false otherwise. bool SetModulesArchitecture(const ArchSpec &new_arch); - ConstString GetNextSyntheticSymbolName(); - static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset); diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index 3a235f260ba5..cb2385468702 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -113,14 +113,20 @@ public: lldb::LanguageType GetLanguage() const { // TODO: See if there is a way to determine the language for a symbol // somehow, for now just return our best guess - return m_mangled.GuessLanguage(); + return GetMangled().GuessLanguage(); } void SetID(uint32_t uid) { m_uid = uid; } - Mangled &GetMangled() { return m_mangled; } + Mangled &GetMangled() { + SynthesizeNameIfNeeded(); + return m_mangled; + } - const Mangled &GetMangled() const { return m_mangled; } + const Mangled &GetMangled() const { + SynthesizeNameIfNeeded(); + return m_mangled; + } ConstString GetReExportedSymbolName() const; @@ -149,6 +155,8 @@ public: bool IsSynthetic() const { return m_is_synthetic; } + bool IsSyntheticWithAutoGeneratedName() const; + void SetIsSynthetic(bool b) { m_is_synthetic = b; } bool GetSizeIsSynthesized() const { return m_size_is_synthesized; } @@ -166,9 +174,9 @@ public: bool IsTrampoline() const; bool IsIndirect() const; - + bool IsWeak() const { return m_is_weak; } - + void SetIsWeak (bool b) { m_is_weak = b; } bool GetByteSizeIsValid() const { return m_size_is_valid; } @@ -223,6 +231,10 @@ public: bool ContainsFileAddress(lldb::addr_t file_addr) const; + static llvm::StringRef GetSyntheticSymbolPrefix() { + return "___lldb_unnamed_symbol"; + } + protected: // This is the internal guts of ResolveReExportedSymbol, it assumes // reexport_name is not null, and that module_spec is valid. We track the @@ -233,8 +245,11 @@ protected: lldb_private::ModuleSpec &module_spec, lldb_private::ModuleList &seen_modules) const; - uint32_t m_uid; // User ID (usually the original symbol table index) - uint16_t m_type_data; // data specific to m_type + void SynthesizeNameIfNeeded() const; + + uint32_t m_uid = + UINT32_MAX; // User ID (usually the original symbol table index) + uint16_t m_type_data = 0; // data specific to m_type uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has // already been calculated m_is_synthetic : 1, // non-zero if this symbol is not actually in the @@ -257,12 +272,12 @@ protected: // doing name lookups m_is_weak : 1, m_type : 6; // Values from the lldb::SymbolType enum. - Mangled m_mangled; // uniqued symbol name/mangled name pair + mutable Mangled m_mangled; // uniqued symbol name/mangled name pair AddressRange m_addr_range; // Contains the value, or the section offset // address when the value is an address in a // section, and the size (if any) - uint32_t m_flags; // A copy of the flags from the original symbol table, the - // ObjectFile plug-in can interpret these + uint32_t m_flags = 0; // A copy of the flags from the original symbol table, + // the ObjectFile plug-in can interpret these }; } // namespace lldb_private diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h index c513dbb447f8..cac951bc19b9 100644 --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -150,8 +150,8 @@ public: bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, - bool show_function_arguments, bool show_function_name, - bool show_inline_callsite_line_info = true) const; + bool show_function_arguments, + bool show_function_name) const; /// Get the address range contained within a symbol context. /// @@ -316,12 +316,13 @@ public: // Member variables lldb::TargetSP target_sp; ///< The Target for a given query lldb::ModuleSP module_sp; ///< The Module for a given query - CompileUnit *comp_unit; ///< The CompileUnit for a given query - Function *function; ///< The Function for a given query - Block *block; ///< The Block for a given query + CompileUnit *comp_unit = nullptr; ///< The CompileUnit for a given query + Function *function = nullptr; ///< The Function for a given query + Block *block = nullptr; ///< The Block for a given query LineEntry line_entry; ///< The LineEntry for a given query - Symbol *symbol; ///< The Symbol for a given query - Variable *variable; ///< The global variable matching the given query + Symbol *symbol = nullptr; ///< The Symbol for a given query + Variable *variable = + nullptr; ///< The global variable matching the given query }; class SymbolContextSpecifier { diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 9f5806915dcb..ffdbdc6853f7 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -10,6 +10,7 @@ #define LLDB_SYMBOL_SYMBOLFILE_H #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/CompilerType.h" @@ -68,7 +69,7 @@ public: : m_objfile_sp(std::move(objfile_sp)), m_abilities(0), m_calculated_abilities(false) {} - ~SymbolFile() override {} + ~SymbolFile() override = default; /// Get a mask of what this symbol file supports for the object file /// that it was constructed with. @@ -209,10 +210,10 @@ public: virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) = 0; - virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - lldb::SymbolContextItem resolve_scope, - SymbolContextList &sc_list); + virtual uint32_t + ResolveSymbolContext(const SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + SymbolContextList &sc_list); virtual void DumpClangAST(Stream &s) {} virtual void FindGlobalVariables(ConstString name, diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h index c232925eec75..e1ad0dfd2eb8 100644 --- a/lldb/include/lldb/Symbol/Symtab.h +++ b/lldb/include/lldb/Symbol/Symtab.h @@ -13,6 +13,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" +#include <map> #include <mutex> #include <vector> @@ -173,15 +174,21 @@ protected: ObjectFile *m_objfile; collection m_symbols; FileRangeToIndexMap m_file_addr_to_index; - UniqueCStringMap<uint32_t> m_name_to_index; - UniqueCStringMap<uint32_t> m_basename_to_index; - UniqueCStringMap<uint32_t> m_method_to_index; - UniqueCStringMap<uint32_t> m_selector_to_index; + + /// Maps function names to symbol indices (grouped by FunctionNameTypes) + std::map<lldb::FunctionNameType, UniqueCStringMap<uint32_t>> + m_name_to_symbol_indices; mutable std::recursive_mutex m_mutex; // Provide thread safety for this symbol table bool m_file_addr_to_index_computed : 1, m_name_indexes_computed : 1; private: + UniqueCStringMap<uint32_t> & + GetNameToSymbolIndexMap(lldb::FunctionNameType type) { + auto map = m_name_to_symbol_indices.find(type); + assert(map != m_name_to_symbol_indices.end()); + return map->second; + } bool CheckSymbolAtIndex(size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const { switch (symbol_debug_type) { @@ -212,6 +219,26 @@ private: return false; } + /// A helper function that looks up full function names. + /// + /// We generate unique names for synthetic symbols so that users can look + /// them up by name when needed. But because doing so is uncommon in normal + /// debugger use, we trade off some performance at lookup time for faster + /// symbol table building by detecting these symbols and generating their + /// names lazily, rather than adding them to the normal symbol indexes. This + /// function does the job of first consulting the name indexes, and if that + /// fails it extracts the information it needs from the synthetic name and + /// locates the symbol. + /// + /// @param[in] symbol_name The symbol name to search for. + /// + /// @param[out] indexes The vector if symbol indexes to update with results. + /// + /// @returns The number of indexes added to the index vector. Zero if no + /// matches were found. + uint32_t GetNameIndexes(ConstString symbol_name, + std::vector<uint32_t> &indexes); + void SymbolIndicesToSymbolContextList(std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list); diff --git a/lldb/include/lldb/Symbol/TaggedASTType.h b/lldb/include/lldb/Symbol/TaggedASTType.h index f02f99258a3f..fe1a2c659d9f 100644 --- a/lldb/include/lldb/Symbol/TaggedASTType.h +++ b/lldb/include/lldb/Symbol/TaggedASTType.h @@ -27,7 +27,7 @@ public: TaggedASTType() : CompilerType() {} - virtual ~TaggedASTType() {} + virtual ~TaggedASTType() = default; TaggedASTType<C> &operator=(const TaggedASTType<C> &tw) { CompilerType::operator=(tw); diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index dd917cfb7ca8..9e671a565dd1 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -9,9 +9,9 @@ #ifndef LLDB_SYMBOL_TYPE_H #define LLDB_SYMBOL_TYPE_H +#include "lldb/Core/Declaration.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" @@ -51,7 +51,7 @@ public: SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp); - ~SymbolFileType() {} + ~SymbolFileType() = default; Type *operator->() { return GetType(); } @@ -213,17 +213,17 @@ public: protected: ConstString m_name; - SymbolFile *m_symbol_file; + SymbolFile *m_symbol_file = nullptr; /// The symbol context in which this type is defined. - SymbolContextScope *m_context; - Type *m_encoding_type; - lldb::user_id_t m_encoding_uid; - EncodingDataType m_encoding_uid_type; + SymbolContextScope *m_context = nullptr; + Type *m_encoding_type = nullptr; + lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID; + EncodingDataType m_encoding_uid_type = eEncodingInvalid; uint64_t m_byte_size : 63; uint64_t m_byte_size_has_value : 1; Declaration m_decl; CompilerType m_compiler_type; - ResolveState m_compiler_type_resolve_state; + ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved; /// Language-specific flags. Payload m_payload; @@ -239,7 +239,7 @@ class TypeImpl { public: TypeImpl() = default; - ~TypeImpl() {} + ~TypeImpl() = default; TypeImpl(const lldb::TypeSP &type_sp); @@ -340,8 +340,7 @@ private: class TypeMemberImpl { public: TypeMemberImpl() - : m_type_impl_sp(), m_bit_offset(0), m_name(), m_bitfield_bit_size(0), - m_is_bitfield(false) + : m_type_impl_sp(), m_name() {} @@ -376,10 +375,10 @@ public: protected: lldb::TypeImplSP m_type_impl_sp; - uint64_t m_bit_offset; + uint64_t m_bit_offset = 0; ConstString m_name; - uint32_t m_bitfield_bit_size; // Bit size for bitfield members only - bool m_is_bitfield; + uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only + bool m_is_bitfield = false; }; /// @@ -435,9 +434,7 @@ private: class TypeMemberFunctionImpl { public: - TypeMemberFunctionImpl() - : m_type(), m_decl(), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) { - } + TypeMemberFunctionImpl() : m_type(), m_decl(), m_name() {} TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, const std::string &name, @@ -469,13 +466,12 @@ private: CompilerType m_type; CompilerDecl m_decl; ConstString m_name; - lldb::MemberFunctionKind m_kind; + lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown; }; class TypeEnumMemberImpl { public: - TypeEnumMemberImpl() - : m_integer_type_sp(), m_name("<invalid>"), m_value(), m_valid(false) {} + TypeEnumMemberImpl() : m_integer_type_sp(), m_name("<invalid>"), m_value() {} TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name, const llvm::APSInt &value); @@ -498,7 +494,7 @@ protected: lldb::TypeImplSP m_integer_type_sp; ConstString m_name; llvm::APSInt m_value; - bool m_valid; + bool m_valid = false; }; class TypeEnumMemberListImpl { diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index 1fad8f61ac37..a37c1040b16e 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -524,7 +524,7 @@ protected: mutable std::mutex m_mutex; ///< A mutex to keep this object happy in ///multi-threaded environments. collection m_map; - bool m_clear_in_progress; + bool m_clear_in_progress = false; private: typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback; diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index 40814da3de4a..cc2302d25831 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -71,7 +71,7 @@ public: isDWARFExpression // reg = eval(dwarf_expr) }; - RegisterLocation() : m_type(unspecified), m_location() {} + RegisterLocation() : m_location() {} bool operator==(const RegisterLocation &rhs) const; @@ -181,7 +181,7 @@ public: const UnwindPlan::Row *row, Thread *thread, bool verbose) const; private: - RestoreType m_type; // How do we locate this register? + RestoreType m_type = unspecified; // How do we locate this register? union { // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset int32_t offset; @@ -205,7 +205,7 @@ public: isRaSearch, // FA = SP + offset + ??? }; - FAValue() : m_type(unspecified), m_value() {} + FAValue() : m_value() {} bool operator==(const FAValue &rhs) const; @@ -301,7 +301,7 @@ public: void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const; private: - ValueType m_type; // How do we compute CFA value? + ValueType m_type = unspecified; // How do we compute CFA value? union { struct { // For m_type == isRegisterPlusOffset or m_type == @@ -322,8 +322,6 @@ public: Row(); - Row(const UnwindPlan::Row &rhs) = default; - bool operator==(const Row &rhs) const; bool GetRegisterInfo(uint32_t reg_num, @@ -360,6 +358,25 @@ public: bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace); + // When this UnspecifiedRegistersAreUndefined mode is + // set, any register that is not specified by this Row will + // be described as Undefined. + // This will prevent the unwinder from iterating down the + // stack looking for a spill location, or a live register value + // at frame 0. + // It would be used for an UnwindPlan row where we can't track + // spilled registers -- for instance a jitted stack frame where + // we have no unwind information or start address -- and registers + // MAY have been spilled and overwritten, so providing the + // spilled/live value from a newer frame may show an incorrect value. + void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef) { + m_unspecified_registers_are_undefined = unspec_is_undef; + } + + bool GetUnspecifiedRegistersAreUndefined() { + return m_unspecified_registers_are_undefined; + } + void Clear(); void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, @@ -367,11 +384,12 @@ public: protected: typedef std::map<uint32_t, RegisterLocation> collection; - lldb::addr_t m_offset; // Offset into the function for this row + lldb::addr_t m_offset = 0; // Offset into the function for this row FAValue m_cfa_value; FAValue m_afa_value; collection m_register_locations; + bool m_unspecified_registers_are_undefined = false; }; // class Row typedef std::shared_ptr<Row> RowSP; diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 0dcbbd8e4c8e..ccd5072c3d23 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -9,9 +9,9 @@ #ifndef LLDB_SYMBOL_VARIABLE_H #define LLDB_SYMBOL_VARIABLE_H +#include "lldb/Core/Declaration.h" #include "lldb/Core/Mangled.h" #include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/Declaration.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/UserID.h" diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h index 131b2eaff765..8fbb6aae68c4 100644 --- a/lldb/include/lldb/Target/ABI.h +++ b/lldb/include/lldb/Target/ABI.h @@ -117,12 +117,13 @@ public: // "pc". virtual bool CodeAddressIsValid(lldb::addr_t pc) = 0; - virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { - // Some targets might use bits in a code address to indicate a mode switch. - // ARM uses bit zero to signify a code address is thumb, so any ARM ABI - // plug-ins would strip those bits. - return pc; - } + /// Some targets might use bits in a code address to indicate a mode switch. + /// ARM uses bit zero to signify a code address is thumb, so any ARM ABI + /// plug-ins would strip those bits. + /// @{ + virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { return pc; } + virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) { return pc; } + /// @} llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } @@ -147,6 +148,10 @@ protected: lldb::ProcessWP m_process_wp; std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up; + virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc, lldb::addr_t mask) { + return pc; + } + private: ABI(const ABI &) = delete; const ABI &operator=(const ABI &) = delete; diff --git a/lldb/include/lldb/Target/DynamicLoader.h b/lldb/include/lldb/Target/DynamicLoader.h index dead3eec7013..a904fac0c779 100644 --- a/lldb/include/lldb/Target/DynamicLoader.h +++ b/lldb/include/lldb/Target/DynamicLoader.h @@ -18,8 +18,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ModuleList; class Process; @@ -251,6 +251,14 @@ public: return false; } + /// Return whether the dynamic loader is fully initialized and it's safe to + /// call its APIs. + /// + /// On some systems (e.g. Darwin based systems), lldb will get notified by + /// the dynamic loader before it itself finished initializing and it's not + /// safe to call certain APIs or SPIs. + virtual bool IsFullyInitialized() { return true; } + protected: // Utility methods for derived classes @@ -294,7 +302,7 @@ protected: // Read a pointer from memory at the given addr. Return LLDB_INVALID_ADDRESS // if the read fails. lldb::addr_t ReadPointer(lldb::addr_t addr); - + // Calls into the Process protected method LoadOperatingSystemPlugin: void LoadOperatingSystemPlugin(bool flush); diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h index 169d56ac9b64..d8c233a666bb 100644 --- a/lldb/include/lldb/Target/ExecutionContext.h +++ b/lldb/include/lldb/Target/ExecutionContext.h @@ -263,8 +263,9 @@ protected: lldb::TargetWP m_target_wp; ///< A weak reference to a target lldb::ProcessWP m_process_wp; ///< A weak reference to a process mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread - lldb::tid_t m_tid; ///< The thread ID that this object refers to in case the - ///backing object changes + lldb::tid_t m_tid = LLDB_INVALID_THREAD_ID; ///< The thread ID that this + ///< object refers to in case the + /// backing object changes StackID m_stack_id; ///< The stack ID that this object refers to in case the ///backing object changes }; diff --git a/lldb/include/lldb/Target/ExecutionContextScope.h b/lldb/include/lldb/Target/ExecutionContextScope.h index d7003e9a572e..4f5b08ed618c 100644 --- a/lldb/include/lldb/Target/ExecutionContextScope.h +++ b/lldb/include/lldb/Target/ExecutionContextScope.h @@ -31,7 +31,7 @@ namespace lldb_private { /// context to allow functions that take a execution contexts to be called. class ExecutionContextScope { public: - virtual ~ExecutionContextScope() {} + virtual ~ExecutionContextScope() = default; virtual lldb::TargetSP CalculateTarget() = 0; diff --git a/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h index 2cbf27d7b343..534516085091 100644 --- a/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h +++ b/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h @@ -18,7 +18,7 @@ namespace lldb_private { class InstrumentationRuntimeStopInfo : public StopInfo { public: - ~InstrumentationRuntimeStopInfo() override {} + ~InstrumentationRuntimeStopInfo() override = default; lldb::StopReason GetStopReason() const override { return lldb::eStopReasonInstrumentation; diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h index 6368828e36da..11b9daa38945 100644 --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -184,14 +184,31 @@ public: virtual const char *GetLanguageSpecificTypeLookupHelp(); + class MethodNameVariant { + ConstString m_name; + lldb::FunctionNameType m_type; + + public: + MethodNameVariant(ConstString name, lldb::FunctionNameType type) + : m_name(name), m_type(type) {} + ConstString GetName() const { return m_name; } + lldb::FunctionNameType GetType() const { return m_type; } + }; // If a language can have more than one possible name for a method, this // function can be used to enumerate them. This is useful when doing name // lookups. - virtual std::vector<ConstString> + virtual std::vector<Language::MethodNameVariant> GetMethodNameVariants(ConstString method_name) const { - return std::vector<ConstString>(); + return std::vector<Language::MethodNameVariant>(); }; + /// Returns true iff the given symbol name is compatible with the mangling + /// scheme of this language. + /// + /// This function should only return true if there is a high confidence + /// that the name actually belongs to this language. + virtual bool SymbolNameFitsToLanguage(Mangled name) const { return false; } + // if an individual data formatter can apply to several types and cross a // language boundary it makes sense for individual languages to want to // customize the printing of values of that type by appending proper diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h index a3897adfe46a..2f95c2643318 100644 --- a/lldb/include/lldb/Target/LanguageRuntime.h +++ b/lldb/include/lldb/Target/LanguageRuntime.h @@ -173,7 +173,51 @@ public: virtual bool isA(const void *ClassID) const { return ClassID == &ID; } static char ID; + /// A language runtime may be able to provide a special UnwindPlan for + /// the frame represented by the register contents \a regctx when that + /// frame is not following the normal ABI conventions. + /// Instead of using the normal UnwindPlan for the function, we will use + /// this special UnwindPlan for this one backtrace. + /// One example of this would be a language that has asynchronous functions, + /// functions that may not be currently-executing, while waiting on other + /// asynchronous calls they made, but are part of a logical backtrace that + /// we want to show the developer because that's how they think of the + /// program flow. + /// + /// \param[in] thread + /// The thread that the unwind is happening on. + /// + /// \param[in] regctx + /// The RegisterContext for the frame we need to create an UnwindPlan. + /// We don't yet have a StackFrame when we're selecting the UnwindPlan. + /// + /// \param[out] behaves_like_zeroth_frame + /// With normal ABI calls, all stack frames except the zeroth frame need + /// to have the return-pc value backed up by 1 for symbolication purposes. + /// For these LanguageRuntime unwind plans, they may not follow normal ABI + /// calling conventions and the return pc may need to be symbolicated + /// as-is. + /// + /// \return + /// Returns an UnwindPlan to find the caller frame if it should be used, + /// instead of the UnwindPlan that would normally be used for this + /// function. + static lldb::UnwindPlanSP + GetRuntimeUnwindPlan(lldb_private::Thread &thread, + lldb_private::RegisterContext *regctx, + bool &behaves_like_zeroth_frame); + protected: + // The static GetRuntimeUnwindPlan method above is only implemented in the + // base class; subclasses may override this protected member if they can + // provide one of these UnwindPlans. + virtual lldb::UnwindPlanSP + GetRuntimeUnwindPlan(lldb::ProcessSP process_sp, + lldb_private::RegisterContext *regctx, + bool &behaves_like_zeroth_frame) { + return lldb::UnwindPlanSP(); + } + LanguageRuntime(Process *process); }; diff --git a/lldb/include/lldb/Target/MemoryRegionInfo.h b/lldb/include/lldb/Target/MemoryRegionInfo.h index 19c6c17ef901..c43f27e0c366 100644 --- a/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -10,8 +10,11 @@ #ifndef LLDB_TARGET_MEMORYREGIONINFO_H #define LLDB_TARGET_MEMORYREGIONINFO_H +#include <vector> + #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RangeMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/FormatProviders.h" namespace lldb_private { @@ -32,10 +35,7 @@ public: RangeType &GetRange() { return m_range; } - void Clear() { - m_range.Clear(); - m_read = m_write = m_execute = m_memory_tagged = eDontKnow; - } + void Clear() { *this = MemoryRegionInfo(); } const RangeType &GetRange() const { return m_range; } @@ -97,11 +97,33 @@ public: m_write == rhs.m_write && m_execute == rhs.m_execute && m_mapped == rhs.m_mapped && m_name == rhs.m_name && m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize && - m_memory_tagged == rhs.m_memory_tagged; + m_memory_tagged == rhs.m_memory_tagged && + m_pagesize == rhs.m_pagesize; } bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); } + /// Get the target system's VM page size in bytes. + /// \return + /// 0 is returned if this information is unavailable. + int GetPageSize() { return m_pagesize; } + + /// Get a vector of target VM pages that are dirty -- that have been + /// modified -- within this memory region. This is an Optional return + /// value; it will only be available if the remote stub was able to + /// detail this. + llvm::Optional<std::vector<lldb::addr_t>> &GetDirtyPageList() { + return m_dirty_pages; + } + + void SetPageSize(int pagesize) { m_pagesize = pagesize; } + + void SetDirtyPageList(std::vector<lldb::addr_t> pagelist) { + if (m_dirty_pages.hasValue()) + m_dirty_pages.getValue().clear(); + m_dirty_pages = std::move(pagelist); + } + protected: RangeType m_range; OptionalBool m_read = eDontKnow; @@ -112,6 +134,8 @@ protected: OptionalBool m_flash = eDontKnow; lldb::offset_t m_blocksize = 0; OptionalBool m_memory_tagged = eDontKnow; + int m_pagesize = 0; + llvm::Optional<std::vector<lldb::addr_t>> m_dirty_pages; }; inline bool operator<(const MemoryRegionInfo &lhs, diff --git a/lldb/include/lldb/Target/MemoryTagManager.h b/lldb/include/lldb/Target/MemoryTagManager.h new file mode 100644 index 000000000000..a5e0deba14a9 --- /dev/null +++ b/lldb/include/lldb/Target/MemoryTagManager.h @@ -0,0 +1,135 @@ +//===-- MemoryTagManager.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_MEMORYTAGMANAGER_H +#define LLDB_TARGET_MEMORYTAGMANAGER_H + +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/RangeMap.h" +#include "lldb/lldb-private.h" +#include "llvm/Support/Error.h" + +namespace lldb_private { + +// This interface allows high level commands to handle memory tags +// in a generic way. +// +// Definitions: +// logical tag - the tag stored in a pointer +// allocation tag - the tag stored in hardware +// (e.g. special memory, cache line bits) +// granule - number of bytes of memory a single tag applies to + +class MemoryTagManager { +public: + typedef Range<lldb::addr_t, lldb::addr_t> TagRange; + + // Extract the logical tag from a pointer + // The tag is returned as a plain value, with any shifts removed. + // For example if your tags are stored in bits 56-60 then the logical tag + // you get will have been shifted down 56 before being returned. + virtual lldb::addr_t GetLogicalTag(lldb::addr_t addr) const = 0; + + // Remove non address bits from a pointer + virtual lldb::addr_t RemoveNonAddressBits(lldb::addr_t addr) const = 0; + + // Return the difference between two addresses, ignoring any logical tags they + // have. If your tags are just part of a larger set of ignored bits, this + // should ignore all those bits. + virtual ptrdiff_t AddressDiff(lldb::addr_t addr1, + lldb::addr_t addr2) const = 0; + + // Return the number of bytes a single tag covers + virtual lldb::addr_t GetGranuleSize() const = 0; + + // Align an address range to granule boundaries. + // So that reading memory tags for the new range returns + // tags that will cover the original range. + // + // Say your granules are 16 bytes and you want + // tags for 16 bytes of memory starting from address 8. + // 1 granule isn't enough because it only covers addresses + // 0-16, we want addresses 8-24. So the range must be + // expanded to 2 granules. + virtual TagRange ExpandToGranule(TagRange range) const = 0; + + // Given a range addr to end_addr, check that: + // * end_addr >= addr (when memory tags are removed) + // * the granule aligned range is completely covered by tagged memory + // (which may include one or more memory regions) + // + // If so, return a modified range which will have been expanded + // to be granule aligned. + // + // Tags in the input addresses are ignored and not present + // in the returned range. + virtual llvm::Expected<TagRange> MakeTaggedRange( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const = 0; + + // Return the type value to use in GDB protocol qMemTags packets to read + // allocation tags. This is named "Allocation" specifically because the spec + // allows for logical tags to be read the same way, though we do not use that. + // + // This value is unique within a given architecture. Meaning that different + // tagging schemes within the same architecture should use unique values, + // but other architectures can overlap those values. + virtual int32_t GetAllocationTagType() const = 0; + + // Return the number of bytes a single tag will be packed into during + // transport. For example an MTE tag is 4 bits but occupies 1 byte during + // transport. + virtual size_t GetTagSizeInBytes() const = 0; + + // Unpack tags from their stored format (e.g. gdb qMemTags data) into seperate + // tags. + // + // Checks that each tag is within the expected value range and if granules is + // set to non-zero, that the number of tags found matches the number of + // granules we expected to cover. + virtual llvm::Expected<std::vector<lldb::addr_t>> + UnpackTagsData(const std::vector<uint8_t> &tags, + size_t granules = 0) const = 0; + + // Pack uncompressed tags into their storage format (e.g. for gdb QMemTags). + // Checks that each tag is within the expected value range. + // We do not check the number of tags or range they apply to because + // it is up to the remote to repeat them as needed. + virtual llvm::Expected<std::vector<uint8_t>> + PackTags(const std::vector<lldb::addr_t> &tags) const = 0; + + // Take a set of tags and repeat them as much as needed to cover the given + // range. We assume that this range has been previously expanded/aligned to + // granules. (this method is used by lldb-server to implement QMemTags + // packet handling) + // + // If the range is empty, zero tags are returned. + // If the range is not empty and... + // * there are no tags, an error is returned. + // * there are fewer tags than granules, the tags are repeated to fill the + // range. + // * there are more tags than granules, only the tags required to cover + // the range are returned. + // + // When repeating tags it will not always return a multiple of the original + // list. For example if your range is 3 granules and your tags are 1 and 2. + // You will get tags 1, 2 and 1 returned. Rather than getting 1, 2, 1, 2, + // which would be one too many tags for the range. + // + // A single tag will just be repeated as you'd expected. Tag 1 over 3 granules + // would return 1, 1, 1. + virtual llvm::Expected<std::vector<lldb::addr_t>> + RepeatTagsForRange(const std::vector<lldb::addr_t> &tags, + TagRange range) const = 0; + + virtual ~MemoryTagManager() {} +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_MEMORYTAGMANAGER_H diff --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h index 9e1e6eb26eb9..d788d120c47e 100644 --- a/lldb/include/lldb/Target/PathMappingList.h +++ b/lldb/include/lldb/Target/PathMappingList.h @@ -72,13 +72,19 @@ public: /// \param[in] path /// The original source file path to try and remap. /// - /// \param[out] new_path - /// The newly remapped filespec that is may or may not exist. + /// \param[in] only_if_exists + /// If \b true, besides matching \p path with the remapping rules, this + /// tries to check with the filesystem that the remapped file exists. If + /// no valid file is found, \b None is returned. This might be expensive, + /// specially on a network. + /// + /// If \b false, then the existence of the returned remapping is not + /// checked. /// /// \return - /// /b true if \a path was successfully located and \a new_path - /// is filled in with a new source path, \b false otherwise. - bool RemapPath(llvm::StringRef path, std::string &new_path) const; + /// The remapped filespec that may or may not exist on disk. + llvm::Optional<FileSpec> RemapPath(llvm::StringRef path, + bool only_if_exists = false) const; bool RemapPath(const char *, std::string &) const = delete; bool ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const; @@ -94,14 +100,9 @@ public: /// \param[in] orig_spec /// The original source file path to try and remap. /// - /// \param[out] new_spec - /// The newly remapped filespec that is guaranteed to exist. - /// /// \return - /// /b true if \a orig_spec was successfully located and - /// \a new_spec is filled in with an existing file spec, - /// \b false otherwise. - bool FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const; + /// The newly remapped filespec that is guaranteed to exist. + llvm::Optional<FileSpec> FindFile(const FileSpec &orig_spec) const; uint32_t FindIndexForPath(ConstString path) const; @@ -118,9 +119,9 @@ protected: const_iterator FindIteratorForPath(ConstString path) const; collection m_pairs; - ChangedCallback m_callback; - void *m_callback_baton; - uint32_t m_mod_id; // Incremented anytime anything is added or removed. + ChangedCallback m_callback = nullptr; + void *m_callback_baton = nullptr; + uint32_t m_mod_id = 0; // Incremented anytime anything is added or removed. }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index fbdb5069b39f..aaa2470d2931 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -11,7 +11,7 @@ #include "lldb/Host/Config.h" -#include <limits.h> +#include <climits> #include <chrono> #include <list> @@ -34,6 +34,7 @@ #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Target/Memory.h" +#include "lldb/Target/MemoryTagManager.h" #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlanStack.h" @@ -46,7 +47,7 @@ #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" -#include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/Utility/UserIDResolver.h" #include "lldb/lldb-private.h" @@ -77,6 +78,8 @@ public: Args GetExtraStartupCommands() const; void SetExtraStartupCommands(const Args &args); FileSpec GetPythonOSPluginPath() const; + uint32_t GetVirtualAddressableBits() const; + void SetVirtualAddressableBits(uint32_t bits); void SetPythonOSPluginPath(const FileSpec &file); bool GetIgnoreBreakpointsInExpressions() const; void SetIgnoreBreakpointsInExpressions(bool ignore); @@ -84,12 +87,15 @@ public: void SetUnwindOnErrorInExpressions(bool ignore); bool GetStopOnSharedLibraryEvents() const; void SetStopOnSharedLibraryEvents(bool stop); + bool GetDisableLangRuntimeUnwindPlans() const; + void SetDisableLangRuntimeUnwindPlans(bool disable); bool GetDetachKeepsStopped() const; void SetDetachKeepsStopped(bool keep_stopped); bool GetWarningsOptimization() const; bool GetWarningsUnsupportedLanguage() const; bool GetStopOnExec() const; std::chrono::seconds GetUtilityExpressionTimeout() const; + std::chrono::seconds GetInterruptTimeout() const; bool GetOSPluginReportsAllThreads() const; void SetOSPluginReportsAllThreads(bool does_report); bool GetSteppingRunsAllThreads() const; @@ -109,9 +115,7 @@ class ProcessAttachInfo : public ProcessInstanceInfo { public: ProcessAttachInfo() : ProcessInstanceInfo(), m_listener_sp(), m_hijack_listener_sp(), - m_plugin_name(), m_resume_count(0), m_wait_for_launch(false), - m_ignore_existing(true), m_continue_once_attached(false), - m_detach_on_error(true), m_async(false) {} + m_plugin_name() {} ProcessAttachInfo(const ProcessLaunchInfo &launch_info) : ProcessInstanceInfo(), m_listener_sp(), m_hijack_listener_sp(), @@ -196,17 +200,19 @@ protected: lldb::ListenerSP m_listener_sp; lldb::ListenerSP m_hijack_listener_sp; std::string m_plugin_name; - uint32_t m_resume_count; // How many times do we resume after launching - bool m_wait_for_launch; - 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) + uint32_t m_resume_count = 0; // How many times do we resume after launching + bool m_wait_for_launch = false; + bool m_ignore_existing = true; + bool m_continue_once_attached = false; // Supports the use-case scenario of + // immediately continuing the process + // once attached. + bool m_detach_on_error = + true; // If we are debugging remotely, instruct the stub to + // detach rather than killing the target on error. + bool m_async = + false; // 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) }; // This class tracks the Modification state of the process. Things that can @@ -218,10 +224,7 @@ class ProcessModID { friend bool operator==(const ProcessModID &lhs, const ProcessModID &rhs); public: - ProcessModID() - : m_stop_id(0), m_last_natural_stop_id(0), m_resume_id(0), m_memory_id(0), - m_last_user_expression_resume(0), m_running_user_expression(false), - m_running_utility_function(0) {} + ProcessModID() = default; ProcessModID(const ProcessModID &rhs) : m_stop_id(rhs.m_stop_id), m_memory_id(rhs.m_memory_id) {} @@ -312,13 +315,13 @@ public: } private: - uint32_t m_stop_id; - uint32_t m_last_natural_stop_id; - uint32_t m_resume_id; - uint32_t m_memory_id; - uint32_t m_last_user_expression_resume; - uint32_t m_running_user_expression; - uint32_t m_running_utility_function; + uint32_t m_stop_id = 0; + uint32_t m_last_natural_stop_id = 0; + uint32_t m_resume_id = 0; + uint32_t m_memory_id = 0; + uint32_t m_last_user_expression_resume = 0; + uint32_t m_running_user_expression = false; + uint32_t m_running_utility_function = 0; lldb::EventSP m_last_natural_stop_event; }; @@ -467,12 +470,12 @@ public: } lldb::ProcessWP m_process_wp; - lldb::StateType m_state; + lldb::StateType m_state = lldb::eStateInvalid; std::vector<std::string> m_restarted_reasons; - bool m_restarted; // For "eStateStopped" events, this is true if the target - // was automatically restarted. - int m_update_state; - bool m_interrupted; + bool m_restarted = false; // For "eStateStopped" events, this is true if the + // target was automatically restarted. + int m_update_state = 0; + bool m_interrupted = false; ProcessEventData(const ProcessEventData &) = delete; const ProcessEventData &operator=(const ProcessEventData &) = delete; @@ -1328,6 +1331,17 @@ public: virtual void DidExit() {} + lldb::addr_t GetCodeAddressMask(); + lldb::addr_t GetDataAddressMask(); + + void SetCodeAddressMask(lldb::addr_t code_address_mask) { + m_code_address_mask = code_address_mask; + } + + void SetDataAddressMask(lldb::addr_t data_address_mask) { + m_data_address_mask = data_address_mask; + } + /// Get the Modification ID of the process. /// /// \return @@ -1695,6 +1709,57 @@ public: lldb::addr_t CallocateMemory(size_t size, uint32_t permissions, Status &error); + /// If this architecture and process supports memory tagging, return a tag + /// manager that can be used to maniupulate those memory tags. + /// + /// \return + /// Either a valid pointer to a tag manager or an error describing why one + /// could not be provided. + llvm::Expected<const MemoryTagManager *> GetMemoryTagManager(); + + /// Read memory tags for the range addr to addr+len. It is assumed + /// that this range has already been granule aligned. + /// (see MemoryTagManager::MakeTaggedRange) + /// + /// This calls DoReadMemoryTags to do the target specific operations. + /// + /// \param[in] addr + /// Start of memory range to read tags for. + /// + /// \param[in] len + /// Length of memory range to read tags for (in bytes). + /// + /// \return + /// If this architecture or process does not support memory tagging, + /// an error saying so. + /// If it does, either the memory tags or an error describing a + /// failure to read or unpack them. + llvm::Expected<std::vector<lldb::addr_t>> ReadMemoryTags(lldb::addr_t addr, + size_t len); + + /// Write memory tags for a range of memory. + /// (calls DoWriteMemoryTags to do the target specific work) + /// + /// \param[in] addr + /// The address to start writing tags from. It is assumed that this + /// address is granule aligned. + /// + /// \param[in] len + /// The size of the range to write tags for. It is assumed that this + /// is some multiple of the granule size. This len can be different + /// from (number of tags * granule size) in the case where you want + /// lldb-server to repeat tags across the range. + /// + /// \param[in] tags + /// Allocation tags to be written. Since lldb-server can repeat tags for a + /// range, the number of tags doesn't have to match the number of granules + /// in the range. (though most of the time it will) + /// + /// \return + /// A Status telling you if the write succeeded or not. + Status WriteMemoryTags(lldb::addr_t addr, size_t len, + const std::vector<lldb::addr_t> &tags); + /// Resolve dynamically loaded indirect functions. /// /// \param[in] address @@ -2455,59 +2520,8 @@ void PruneThreadPlans(); lldb::StructuredDataPluginSP GetStructuredDataPlugin(ConstString type_name) const; - /// Starts tracing with the configuration provided in options. To enable - /// tracing on the complete process the thread_id in the options should be - /// set to LLDB_INVALID_THREAD_ID. The API returns a user_id which is needed - /// by other API's that manipulate the trace instance. The handling of - /// erroneous or unsupported configuration is left to the trace technology - /// implementations in the server, as they could be returned as an error, or - /// rounded to a valid configuration to start tracing. In the later case the - /// GetTraceConfig should supply the actual used trace configuration. - virtual lldb::user_id_t StartTrace(const TraceOptions &options, - Status &error) { - error.SetErrorString("Not implemented"); - return LLDB_INVALID_UID; - } - - /// Stops the tracing instance leading to deletion of the trace data. The - /// tracing instance is identified by the user_id which is obtained when - /// tracing was started from the StartTrace. In case tracing of the complete - /// process needs to be stopped the thread_id should be set to - /// LLDB_INVALID_THREAD_ID. In the other case that tracing on an individual - /// thread needs to be stopped a thread_id can be supplied. - virtual Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) { - return Status("Not implemented"); - } - - /// Provides the trace data as raw bytes. A buffer needs to be supplied to - /// copy the trace data. The exact behavior of this API may vary across - /// trace technology, as some may support partial reading of the trace data - /// from a specified offset while some may not. The thread_id should be used - /// to select a particular thread for trace extraction. - virtual Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); - } - - /// Similar API as above except for obtaining meta data - virtual Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id, - llvm::MutableArrayRef<uint8_t> &buffer, - size_t offset = 0) { - return Status("Not implemented"); - } - - /// API to obtain the trace configuration used by a trace instance. - /// Configurations that may be specific to some trace technology should be - /// stored in the custom parameters. The options are transported to the - /// server, which shall interpret accordingly. The thread_id can be - /// specified in the options to obtain the configuration used by a specific - /// thread. The thread_id specified should also match the uid otherwise an - /// error will be returned. - virtual Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) { - return Status("Not implemented"); - } - +protected: + friend class Trace; /// Get the processor tracing type supported for this process. /// Responses might be different depending on the architecture and /// capabilities of the underlying OS. @@ -2515,14 +2529,64 @@ void PruneThreadPlans(); /// \return /// The supported trace type or an \a llvm::Error if tracing is /// not supported for the inferior. - virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType(); + virtual llvm::Expected<TraceSupportedResponse> TraceSupported(); + + /// Start tracing a process or its threads. + /// + /// \param[in] request + /// JSON object with the information necessary to start tracing. In the + /// case of gdb-remote processes, this JSON object should conform to the + /// jLLDBTraceStart packet. + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error TraceStart(const llvm::json::Value &request) { + return llvm::make_error<UnimplementedError>(); + } + + /// Stop tracing a live process or its threads. + /// + /// \param[in] request + /// The information determining which threads or process to stop tracing. + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error TraceStop(const TraceStopRequest &request) { + return llvm::make_error<UnimplementedError>(); + } + + /// Get the current tracing state of the process and its threads. + /// + /// \param[in] type + /// Tracing technology type to consider. + /// + /// \return + /// A JSON object string with custom data depending on the trace + /// technology, or an \a llvm::Error in case of errors. + virtual llvm::Expected<std::string> TraceGetState(llvm::StringRef type) { + return llvm::make_error<UnimplementedError>(); + } + + /// Get binary data given a trace technology and a data identifier. + /// + /// \param[in] request + /// Object with the params of the requested data. + /// + /// \return + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + virtual llvm::Expected<std::vector<uint8_t>> + TraceGetBinaryData(const TraceGetBinaryDataRequest &request) { + return llvm::make_error<UnimplementedError>(); + } // This calls a function of the form "void * (*)(void)". bool CallVoidArgVoidPtrReturn(const Address *address, lldb::addr_t &returned_func, bool trap_exceptions = false); -protected: /// Update the thread list following process plug-in's specific logic. /// /// This method should only be invoked by \a UpdateThreadList. @@ -2561,8 +2625,6 @@ protected: virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error) = 0; - void SetState(lldb::EventSP &event_sp); - lldb::StateType GetPrivateState(); /// The "private" side of resuming a process. This doesn't alter the state @@ -2708,6 +2770,60 @@ protected: /// false. bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp); + /// Check whether the process supports memory tagging. + /// + /// \return + /// true if the process supports memory tagging, + /// false otherwise. + virtual bool SupportsMemoryTagging() { return false; } + + /// Does the final operation to read memory tags. E.g. sending a GDB packet. + /// It assumes that ReadMemoryTags has checked that memory tagging is enabled + /// and has expanded the memory range as needed. + /// + /// \param[in] addr + /// Start of address range to read memory tags for. + /// + /// \param[in] len + /// Length of the memory range to read tags for (in bytes). + /// + /// \param[in] type + /// Type of tags to read (get this from a MemoryTagManager) + /// + /// \return + /// The packed tag data received from the remote or an error + /// if the read failed. + virtual llvm::Expected<std::vector<uint8_t>> + DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "%s does not support reading memory tags", + GetPluginName().GetCString()); + } + + /// Does the final operation to write memory tags. E.g. sending a GDB packet. + /// It assumes that WriteMemoryTags has checked that memory tagging is enabled + /// and has packed the tag data. + /// + /// \param[in] addr + /// Start of address range to write memory tags for. + /// + /// \param[in] len + /// Length of the memory range to write tags for (in bytes). + /// + /// \param[in] type + /// Type of tags to read (get this from a MemoryTagManager) + /// + /// \param[in] tags + /// Packed tags to be written. + /// + /// \return + /// Status telling you whether the write succeeded. + virtual Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, + const std::vector<uint8_t> &tags) { + return Status("%s does not support writing memory tags", + GetPluginName().GetCString()); + } + // Type definitions typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection; @@ -2827,6 +2943,14 @@ protected: /// from looking up or creating things during or after a finalize call. std::atomic<bool> m_finalizing; + /// Mask for code an data addresses. The default value (0) means no mask is + /// set. The bits set to 1 indicate bits that are NOT significant for + /// addressing. + /// @{ + lldb::addr_t m_code_address_mask = 0; + lldb::addr_t m_data_address_mask = 0; + /// @} + bool m_clear_thread_plans_on_stop; bool m_force_next_event_delivery; lldb::StateType m_last_broadcast_state; /// This helps with the Public event diff --git a/lldb/include/lldb/Target/ProcessTrace.h b/lldb/include/lldb/Target/ProcessTrace.h index 55faba1576d0..7b9d6b13dd6f 100644 --- a/lldb/include/lldb/Target/ProcessTrace.h +++ b/lldb/include/lldb/Target/ProcessTrace.h @@ -15,6 +15,8 @@ namespace lldb_private { +/// Class that represents a defunct process loaded on memory via the "trace +/// load" command. class ProcessTrace : public PostMortemProcess { public: static void Initialize(); @@ -54,8 +56,6 @@ public: return error; } - bool IsAlive() override; - bool WarnBeforeDetach() const override { return false; } size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, diff --git a/lldb/include/lldb/Target/RegisterCheckpoint.h b/lldb/include/lldb/Target/RegisterCheckpoint.h index d2bcc614f587..daf20db999b3 100644 --- a/lldb/include/lldb/Target/RegisterCheckpoint.h +++ b/lldb/include/lldb/Target/RegisterCheckpoint.h @@ -34,7 +34,7 @@ public: RegisterCheckpoint(Reason reason) : UserID(0), m_data_sp(), m_reason(reason) {} - ~RegisterCheckpoint() {} + ~RegisterCheckpoint() = default; lldb::DataBufferSP &GetData() { return m_data_sp; } diff --git a/lldb/include/lldb/Target/RegisterContext.h b/lldb/include/lldb/Target/RegisterContext.h index 5e795e59f941..c5068feedd5b 100644 --- a/lldb/include/lldb/Target/RegisterContext.h +++ b/lldb/include/lldb/Target/RegisterContext.h @@ -148,6 +148,31 @@ public: uint64_t GetPC(uint64_t fail_value = LLDB_INVALID_ADDRESS); + /// Get an address suitable for symbolication. + /// When symbolicating -- computing line, block, function -- + /// for a function in the middle of the stack, using the return + /// address can lead to unexpected results for the user. + /// A function that ends in a tail-call may have another function + /// as the "return" address, but it will never actually return. + /// Or a noreturn call in the middle of a function is the end of + /// a block of instructions, and a DWARF location list entry for + /// the return address may be a very different code path with + /// incorrect results when printing variables for this frame. + /// + /// At a source line view, the user expects the current-line indictation + /// to point to the function call they're under, not the next source line. + /// + /// The return address (GetPC()) should always be shown to the user, + /// but when computing context, keeping within the bounds of the + /// call instruction is what the user expects to see. + /// + /// \param [out] address + /// An Address object that will be filled in, if a PC can be retrieved. + /// + /// \return + /// Returns true if the Address param was filled in. + bool GetPCForSymbolication(Address &address); + bool SetPC(uint64_t pc); bool SetPC(Address addr); @@ -196,6 +221,19 @@ public: void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; } protected: + /// Indicates that this frame is currently executing code, + /// that the PC value is not a return-pc but an actual executing + /// instruction. Some places in lldb will treat a return-pc + /// value differently than the currently-executing-pc value, + /// and this method can indicate if that should be done. + /// The base class implementation only uses the frame index, + /// but subclasses may have additional information that they + /// can use to detect frames in this state, for instance a + /// frame above a trap handler (sigtramp etc).. + virtual bool BehavesLikeZerothFrame() const { + return m_concrete_frame_idx == 0; + } + // Classes that inherit from RegisterContext can see and modify these Thread &m_thread; // The thread that this register context belongs to. uint32_t m_concrete_frame_idx; // The concrete frame index for this register diff --git a/lldb/include/lldb/Target/RegisterContextUnwind.h b/lldb/include/lldb/Target/RegisterContextUnwind.h index fa96c3e42c78..edda281d5aa7 100644 --- a/lldb/include/lldb/Target/RegisterContextUnwind.h +++ b/lldb/include/lldb/Target/RegisterContextUnwind.h @@ -67,6 +67,11 @@ public: bool ReadPC(lldb::addr_t &start_pc); + // Indicates whether this frame *behaves* like frame zero -- the currently + // executing frame -- or not. This can be true in the middle of the stack + // above asynchronous trap handlers (sigtramp) for instance. + bool BehavesLikeZerothFrame() const override; + private: enum FrameType { eNormalFrame, @@ -228,14 +233,16 @@ private: // unknown // 0 if no instructions have been executed yet. - int m_current_offset_backed_up_one; // how far into the function we've - // executed; -1 if unknown // 0 if no instructions have been executed yet. // On architectures where the return address on the stack points // to the instruction after the CALL, this value will have 1 // subtracted from it. Else a function that ends in a CALL will // have an offset pointing into the next function's address range. // m_current_pc has the actual address of the "current" pc. + int m_current_offset_backed_up_one; // how far into the function we've + // executed; -1 if unknown + + bool m_behaves_like_zeroth_frame; // this frame behaves like frame zero lldb_private::SymbolContext &m_sym_ctx; bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to diff --git a/lldb/include/lldb/Target/RegisterNumber.h b/lldb/include/lldb/Target/RegisterNumber.h index 362812bcffd0..90f953198969 100644 --- a/lldb/include/lldb/Target/RegisterNumber.h +++ b/lldb/include/lldb/Target/RegisterNumber.h @@ -50,10 +50,10 @@ private: typedef std::map<lldb::RegisterKind, uint32_t> Collection; lldb::RegisterContextSP m_reg_ctx_sp; - uint32_t m_regnum; - lldb::RegisterKind m_kind; + uint32_t m_regnum = LLDB_INVALID_REGNUM; + lldb::RegisterKind m_kind = lldb::kNumRegisterKinds; Collection m_kind_regnum_map; - const char *m_name; + const char *m_name = nullptr; }; #endif // LLDB_TARGET_REGISTERNUMBER_H diff --git a/lldb/include/lldb/Target/RemoteAwarePlatform.h b/lldb/include/lldb/Target/RemoteAwarePlatform.h index 6d6ac99c093f..269d15299889 100644 --- a/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -97,6 +97,9 @@ public: Status KillProcess(const lldb::pid_t pid) override; + size_t ConnectToWaitingProcesses(Debugger &debugger, + Status &error) override; + protected: lldb::PlatformSP m_remote_platform_sp; }; diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h index 905c56c91263..1a9aaad1a4db 100644 --- a/lldb/include/lldb/Target/StackFrame.h +++ b/lldb/include/lldb/Target/StackFrame.h @@ -134,6 +134,24 @@ public: /// The Address object set to the current PC value. const Address &GetFrameCodeAddress(); + /// Get the current code Address suitable for symbolication, + /// may not be the same as GetFrameCodeAddress(). + /// + /// For a frame in the middle of the stack, the return-pc is the + /// current code address, but for symbolication purposes the + /// return address after a noreturn call may point to the next + /// function, a DWARF location list entry that is a completely + /// different code path, or the wrong source line. + /// + /// The address returned should be used for symbolication (source line, + /// block, function, DWARF location entry selection) but should NOT + /// be shown to the user. It may not point to an actual instruction + /// boundary. + /// + /// \return + /// The Address object set to the current PC value. + Address GetFrameCodeAddressForSymbolication(); + /// Change the pc value for a given thread. /// /// Change the current pc value for the frame on this thread. @@ -404,22 +422,6 @@ public: GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic); - /// Add an arbitrary Variable object (e.g. one that specifics a global or - /// static) to a StackFrame's list of ValueObjects. - /// - /// \params [in] variable_sp - /// The Variable to base this ValueObject on - /// - /// \params [in] use_dynamic - /// Whether the correct dynamic type of the variable should be - /// determined before creating the ValueObject, or if the static type - /// is sufficient. One of the DynamicValueType enumerated values. - /// - /// \return - /// A ValueObject for this variable. - lldb::ValueObjectSP TrackGlobalVariable(const lldb::VariableSP &variable_sp, - lldb::DynamicValueType use_dynamic); - /// Query this frame to determine what the default language should be when /// parsing expressions given the execution context. /// diff --git a/lldb/include/lldb/Target/StackFrameList.h b/lldb/include/lldb/Target/StackFrameList.h index 1b0b986d7059..c98995cad36f 100644 --- a/lldb/include/lldb/Target/StackFrameList.h +++ b/lldb/include/lldb/Target/StackFrameList.h @@ -89,9 +89,6 @@ protected: bool SetFrameAtIndex(uint32_t idx, lldb::StackFrameSP &frame_sp); - static void Merge(std::unique_ptr<StackFrameList> &curr_up, - lldb::StackFrameListSP &prev_sp); - void GetFramesUpTo(uint32_t end_idx); void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind &unwinder); diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index baffc890bb06..64be759dc79e 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -37,7 +37,7 @@ public: return lldb::ValueObjectSP(); } virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; }; - virtual ~RecognizedStackFrame(){}; + virtual ~RecognizedStackFrame() = default; std::string GetStopDescription() { return m_stop_desc; } @@ -63,7 +63,7 @@ public: return ""; } - virtual ~StackFrameRecognizer(){}; + virtual ~StackFrameRecognizer() = default; }; /// \class ScriptedStackFrameRecognizer @@ -80,7 +80,7 @@ class ScriptedStackFrameRecognizer : public StackFrameRecognizer { public: ScriptedStackFrameRecognizer(lldb_private::ScriptInterpreter *interpreter, const char *pclass); - ~ScriptedStackFrameRecognizer() override {} + ~ScriptedStackFrameRecognizer() override = default; std::string GetName() override { return GetPythonClassName(); diff --git a/lldb/include/lldb/Target/StackID.h b/lldb/include/lldb/Target/StackID.h index 827ed1be7c0f..95d12df6742c 100644 --- a/lldb/include/lldb/Target/StackID.h +++ b/lldb/include/lldb/Target/StackID.h @@ -18,8 +18,8 @@ class StackID { public: // Constructors and Destructors StackID() - : m_pc(LLDB_INVALID_ADDRESS), m_cfa(LLDB_INVALID_ADDRESS), - m_symbol_scope(nullptr) {} + + {} explicit StackID(lldb::addr_t pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) @@ -69,23 +69,25 @@ protected: void SetCFA(lldb::addr_t cfa) { m_cfa = cfa; } - lldb::addr_t - m_pc; // The pc value for the function/symbol for this frame. This will + lldb::addr_t m_pc = + LLDB_INVALID_ADDRESS; // The pc value for the function/symbol for this + // frame. This will // only get used if the symbol scope is nullptr (the code where we are // stopped is not represented by any function or symbol in any shared // library). - lldb::addr_t m_cfa; // The call frame address (stack pointer) value - // at the beginning of the function that uniquely - // identifies this frame (along with m_symbol_scope - // below) - SymbolContextScope * - m_symbol_scope; // If nullptr, there is no block or symbol for this frame. - // If not nullptr, this will either be the scope for the - // lexical block for the frame, or the scope for the - // symbol. Symbol context scopes are always be unique - // pointers since the are part of the Block and Symbol - // objects and can easily be used to tell if a stack ID - // is the same as another. + lldb::addr_t m_cfa = + LLDB_INVALID_ADDRESS; // The call frame address (stack pointer) value + // at the beginning of the function that uniquely + // identifies this frame (along with m_symbol_scope + // below) + SymbolContextScope *m_symbol_scope = + nullptr; // If nullptr, there is no block or symbol for this frame. + // If not nullptr, this will either be the scope for the + // lexical block for the frame, or the scope for the + // symbol. Symbol context scopes are always be unique + // pointers since the are part of the Block and Symbol + // objects and can easily be used to tell if a stack ID + // is the same as another. }; bool operator==(const StackID &lhs, const StackID &rhs); diff --git a/lldb/include/lldb/Target/StopInfo.h b/lldb/include/lldb/Target/StopInfo.h index 4378d2d63799..0e81e5160846 100644 --- a/lldb/include/lldb/Target/StopInfo.h +++ b/lldb/include/lldb/Target/StopInfo.h @@ -25,7 +25,7 @@ public: // Constructors and Destructors StopInfo(Thread &thread, uint64_t value); - virtual ~StopInfo() {} + virtual ~StopInfo() = default; bool IsValid() const; @@ -129,6 +129,9 @@ public: static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread); + static lldb::StopInfoSP + CreateStopReasonProcessorTrace(Thread &thread, const char *description); + static lldb::ValueObjectSP GetReturnValueObject(lldb::StopInfoSP &stop_info_sp); diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 69baefb964b0..ac8d002b09a1 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -37,8 +37,6 @@ namespace lldb_private { -class ClangModulesDeclVendor; - OptionEnumValues GetDynamicValueTypes(); enum InlineStrategy { @@ -211,7 +209,7 @@ public: void SetDisplayRecognizedArguments(bool b); - const ProcessLaunchInfo &GetProcessLaunchInfo(); + const ProcessLaunchInfo &GetProcessLaunchInfo() const; void SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info); @@ -227,6 +225,10 @@ public: void UpdateLaunchInfoFromProperties(); + void SetDebugUtilityExpression(bool debug); + + bool GetDebugUtilityExpression() const; + private: // Callbacks for m_launch_info. void Arg0ValueChangedCallback(); @@ -1001,11 +1003,12 @@ public: // read from const sections in object files, read from the target. This // version of ReadMemory will try and read memory from the process if the // process is alive. The order is: - // 1 - if (prefer_file_cache == true) then read from object file cache - // 2 - if there is a valid process, try and read from its memory - // 3 - if (prefer_file_cache == false) then read from object file cache - size_t ReadMemory(const Address &addr, bool prefer_file_cache, void *dst, - size_t dst_len, Status &error, + // 1 - if (force_live_memory == false) and the address falls in a read-only + // section, then read from the file cache + // 2 - if there is a process, then read from memory + // 3 - if there is no process, then read from the file cache + size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, + Status &error, bool force_live_memory = false, lldb::addr_t *load_addr_ptr = nullptr); size_t ReadCStringFromMemory(const Address &addr, std::string &out_str, @@ -1014,18 +1017,19 @@ public: size_t ReadCStringFromMemory(const Address &addr, char *dst, size_t dst_max_len, Status &result_error); - size_t ReadScalarIntegerFromMemory(const Address &addr, - bool prefer_file_cache, uint32_t byte_size, + size_t ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size, bool is_signed, Scalar &scalar, - Status &error); + Status &error, + bool force_live_memory = false); uint64_t ReadUnsignedIntegerFromMemory(const Address &addr, - bool prefer_file_cache, size_t integer_byte_size, - uint64_t fail_value, Status &error); + uint64_t fail_value, Status &error, + bool force_live_memory = false); - bool ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, - Status &error, Address &pointer_addr); + bool ReadPointerFromMemory(const Address &addr, Status &error, + Address &pointer_addr, + bool force_live_memory = false); SectionLoadList &GetSectionLoadList() { return m_section_load_history.GetCurrentSectionLoadList(); @@ -1122,7 +1126,19 @@ public: /// /// \return /// The trace object. It might be undefined. - const lldb::TraceSP &GetTrace(); + lldb::TraceSP GetTrace(); + + /// Create a \a Trace object for the current target using the using the + /// default supported tracing technology for this process. + /// + /// \return + /// The new \a Trace or an \a llvm::Error if a \a Trace already exists or + /// the trace couldn't be created. + llvm::Expected<lldb::TraceSP> CreateTrace(); + + /// If a \a Trace object is present, this returns it, otherwise a new Trace is + /// created with \a Trace::CreateTrace. + llvm::Expected<lldb::TraceSP> GetTraceOrCreate(); // Since expressions results can persist beyond the lifetime of a process, // and the const expression results are available after a process is gone, we @@ -1325,8 +1341,6 @@ public: SourceManager &GetSourceManager(); - ClangModulesDeclVendor *GetClangModulesDeclVendor(); - // Methods. lldb::SearchFilterSP GetSearchFilterForModule(const FileSpec *containingModule); @@ -1410,15 +1424,15 @@ protected: typedef std::map<lldb::LanguageType, lldb::REPLSP> REPLMap; REPLMap m_repl_map; - std::unique_ptr<ClangModulesDeclVendor> m_clang_modules_decl_vendor_up; - lldb::SourceManagerUP m_source_manager_up; typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection; StopHookCollection m_stop_hooks; lldb::user_id_t m_stop_hook_next_id; + uint32_t m_latest_stop_hook_id; /// This records the last natural stop at + /// which we ran a stop-hook. bool m_valid; - bool m_suppress_stop_hooks; + bool m_suppress_stop_hooks; /// Used to not run stop hooks for expressions bool m_is_dummy_target; unsigned m_next_persistent_variable_index = 0; /// An optional \a lldb_private::Trace object containing processor trace diff --git a/lldb/include/lldb/Target/TargetList.h b/lldb/include/lldb/Target/TargetList.h index 903ca4bcefbc..65781a4811fd 100644 --- a/lldb/include/lldb/Target/TargetList.h +++ b/lldb/include/lldb/Target/TargetList.h @@ -14,6 +14,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -42,6 +43,11 @@ public: return GetStaticBroadcasterClass(); } + typedef std::vector<lldb::TargetSP> collection; + typedef LockingAdaptedIterable<collection, lldb::TargetSP, vector_adapter, + std::recursive_mutex> + TargetIterable; + /// Create a new Target. /// /// Clients must use this function to create a Target. This allows @@ -179,14 +185,15 @@ public: lldb::TargetSP GetSelectedTarget(); -protected: - typedef std::vector<lldb::TargetSP> collection; - // Member variables. + TargetIterable Targets() { + return TargetIterable(m_target_list, m_target_list_mutex); + } + +private: collection m_target_list; mutable std::recursive_mutex m_target_list_mutex; uint32_t m_selected_target_idx; -private: static Status CreateTargetInternal( Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles load_dependent_files, diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 4b148063ec6e..0f6b5741573e 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -615,7 +615,7 @@ public: /// \return /// A shared pointer to the newly queued thread plan, or nullptr if the /// plan could not be queued. - virtual lldb::ThreadPlanSP QueueFundamentalPlan(bool abort_other_plans); + lldb::ThreadPlanSP QueueBasePlan(bool abort_other_plans); /// Queues the plan used to step one instruction from the current PC of \a /// thread. @@ -781,10 +781,10 @@ public: /// \param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// - /// \param[in] stop_vote + /// \param[in] report_stop_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// - /// \param[in] run_vote + /// \param[in] report_run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// /// \param[out] status @@ -800,7 +800,7 @@ public: /// plan could not be queued. virtual lldb::ThreadPlanSP QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote, + bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, Status &status, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); @@ -830,10 +830,10 @@ public: /// \param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// - /// \param[in] stop_vote + /// \param[in] report_stop_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// - /// \param[in] run_vote + /// \param[in] report_run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// /// \param[in] frame_idx @@ -864,7 +864,7 @@ public: /// plan could not be queued. virtual lldb::ThreadPlanSP QueueThreadPlanForStepOutNoShouldStop( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote, + bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, Status &status, bool continue_to_next_branch = false); /// Gets the plan used to step through the code that steps from a function @@ -1050,12 +1050,7 @@ public: virtual bool RestoreRegisterStateFromCheckpoint(ThreadStateCheckpoint &saved_state); - virtual bool - RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state); - - void EnableTracer(bool value, bool single_step); - - void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp); + void RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state); // Get the thread index ID. The index ID that is guaranteed to not be re-used // by a process. They start at 1 and increase with each new thread. This diff --git a/lldb/include/lldb/Target/ThreadCollection.h b/lldb/include/lldb/Target/ThreadCollection.h index 40dc938976ff..29f5103e7eec 100644 --- a/lldb/include/lldb/Target/ThreadCollection.h +++ b/lldb/include/lldb/Target/ThreadCollection.h @@ -28,7 +28,7 @@ public: ThreadCollection(collection threads); - virtual ~ThreadCollection() {} + virtual ~ThreadCollection() = default; uint32_t GetSize(); diff --git a/lldb/include/lldb/Target/ThreadPlan.h b/lldb/include/lldb/Target/ThreadPlan.h index 242a4d3c2d6c..5e14a1fd6577 100644 --- a/lldb/include/lldb/Target/ThreadPlan.h +++ b/lldb/include/lldb/Target/ThreadPlan.h @@ -260,8 +260,8 @@ namespace lldb_private { // One other little detail here, sometimes a plan will push another plan onto // the plan stack to do some part of the first plan's job, and it would be // convenient to tell that plan how it should respond to ShouldReportStop. -// You can do that by setting the stop_vote in the child plan when you create -// it. +// You can do that by setting the report_stop_vote in the child plan when you +// create it. // // Suppressing the initial eStateRunning event: // @@ -275,14 +275,13 @@ namespace lldb_private { // eVoteNo from ShouldReportStop, to force a running event to be reported // return eVoteYes, in general though you should return eVoteNoOpinion which // will allow the ThreadList to figure out the right thing to do. The -// run_vote argument to the constructor works like stop_vote, and is a way for -// a plan to instruct a sub-plan on how to respond to ShouldReportStop. +// report_run_vote argument to the constructor works like report_stop_vote, and +// is a way for a plan to instruct a sub-plan on how to respond to +// ShouldReportStop. class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>, public UserID { public: - enum ThreadScope { eAllThreads, eSomeThreads, eThisThread }; - // We use these enums so that we can cast a base thread plan to it's real // type without having to resort to dynamic casting. enum ThreadPlanKind { @@ -298,15 +297,9 @@ public: eKindStepInRange, eKindRunToAddress, eKindStepThrough, - eKindStepUntil, - eKindTestCondition - + eKindStepUntil }; - // Constructors and Destructors - ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, - Vote stop_vote, Vote run_vote); - virtual ~ThreadPlan(); /// Returns the name of this thread plan. @@ -368,6 +361,12 @@ public: virtual bool ShouldStop(Event *event_ptr) = 0; + /// Returns whether this thread plan overrides the `ShouldStop` of + /// subsequently processed plans. + /// + /// When processing the thread plan stack, this function gives plans the + /// ability to continue - even when subsequent plans return true from + /// `ShouldStop`. \see Thread::ShouldStop virtual bool ShouldAutoContinue(Event *event_ptr) { return false; } // Whether a "stop class" event should be reported to the "outside world". @@ -375,7 +374,7 @@ public: virtual Vote ShouldReportStop(Event *event_ptr); - virtual Vote ShouldReportRun(Event *event_ptr); + Vote ShouldReportRun(Event *event_ptr); virtual void SetStopOthers(bool new_value); @@ -416,15 +415,6 @@ public: virtual void WillPop(); - // This pushes a plan onto the plan stack of the current plan's thread. - // Also sets the plans to private and not master plans. A plan pushed by - // another thread plan is never either of the above. - void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { - GetThread().PushPlan(thread_plan_sp); - thread_plan_sp->SetPrivate(false); - thread_plan_sp->SetIsMasterPlan(false); - } - ThreadPlanKind GetKind() const { return m_kind; } bool IsPlanComplete(); @@ -448,15 +438,6 @@ public: m_tracer_sp->Log(); } - // Some thread plans hide away the actual stop info which caused any - // particular stop. For instance the ThreadPlanCallFunction restores the - // original stop reason so that stopping and calling a few functions won't - // lose the history of the run. This call can be implemented to get you back - // to the real stop info. - virtual lldb::StopInfoSP GetRealStopInfo() { - return GetThread().GetStopInfo(); - } - // If the completion of the thread plan stepped out of a function, the return // value of the function might have been captured by the thread plan // (currently only ThreadPlanStepOut does this.) If so, the ReturnValueObject @@ -481,14 +462,11 @@ public: // to restore the state when it is done. This will do that job. This is // mostly useful for artificial plans like CallFunction plans. - virtual bool RestoreThreadState() { - // Nothing to do in general. - return true; - } + virtual void RestoreThreadState() {} virtual bool IsVirtualStep() { return false; } - virtual bool SetIterationCount(size_t count) { + bool SetIterationCount(size_t count) { if (m_takes_iteration_count) { // Don't tell me to do something 0 times... if (count == 0) @@ -498,14 +476,11 @@ public: return m_takes_iteration_count; } - virtual size_t GetIterationCount() { - if (!m_takes_iteration_count) - return 0; - else - return m_iteration_count; - } - protected: + // Constructors and Destructors + ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, + Vote report_stop_vote, Vote report_run_vote); + // Classes that inherit from ThreadPlan can see and modify these virtual bool DoWillResume(lldb::StateType resume_state, bool current_plan) { @@ -514,6 +489,15 @@ protected: virtual bool DoPlanExplainsStop(Event *event_ptr) = 0; + // This pushes a plan onto the plan stack of the current plan's thread. + // Also sets the plans to private and not master plans. A plan pushed by + // another thread plan is never either of the above. + void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { + GetThread().PushPlan(thread_plan_sp); + thread_plan_sp->SetPrivate(true); + thread_plan_sp->SetIsMasterPlan(false); + } + // This gets the previous plan to the current plan (for forwarding requests). // This is mostly a formal requirement, it allows us to make the Thread's // GetPreviousPlan protected, but only friend ThreadPlan to thread. @@ -531,14 +515,6 @@ protected: GetThread().SetStopInfo(stop_reason_sp); } - void CachePlanExplainsStop(bool does_explain) { - m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo; - } - - LazyBool GetCachedPlanExplainsStop() const { - return m_cached_plan_explains_stop; - } - virtual lldb::StateType GetPlanRunState() = 0; bool IsUsuallyUnexplainedStopReason(lldb::StopReason); @@ -546,13 +522,17 @@ protected: Status m_status; Process &m_process; lldb::tid_t m_tid; - Vote m_stop_vote; - Vote m_run_vote; + Vote m_report_stop_vote; + Vote m_report_run_vote; bool m_takes_iteration_count; bool m_could_not_resolve_hw_bp; int32_t m_iteration_count = 1; private: + void CachePlanExplainsStop(bool does_explain) { + m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo; + } + // For ThreadPlan only static lldb::user_id_t GetNextID(); diff --git a/lldb/include/lldb/Target/ThreadPlanBase.h b/lldb/include/lldb/Target/ThreadPlanBase.h index 48058a9b40ab..5c44b9fb17b2 100644 --- a/lldb/include/lldb/Target/ThreadPlanBase.h +++ b/lldb/include/lldb/Target/ThreadPlanBase.h @@ -44,8 +44,7 @@ protected: ThreadPlanBase(Thread &thread); private: - friend lldb::ThreadPlanSP - Thread::QueueFundamentalPlan(bool abort_other_plans); + friend lldb::ThreadPlanSP Thread::QueueBasePlan(bool abort_other_plans); ThreadPlanBase(const ThreadPlanBase &) = delete; const ThreadPlanBase &operator=(const ThreadPlanBase &) = delete; diff --git a/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/lldb/include/lldb/Target/ThreadPlanCallFunction.h index 5b432e5e604a..24c5736f44c3 100644 --- a/lldb/include/lldb/Target/ThreadPlanCallFunction.h +++ b/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -81,7 +81,7 @@ public: // stop reason. But if something bad goes wrong, it is nice to be able to // tell the user what really happened. - lldb::StopInfoSP GetRealStopInfo() override { + virtual lldb::StopInfoSP GetRealStopInfo() { if (m_real_stop_info_sp) return m_real_stop_info_sp; else @@ -90,7 +90,7 @@ public: lldb::addr_t GetStopAddress() { return m_stop_address; } - bool RestoreThreadState() override; + void RestoreThreadState() override; void ThreadDestroyed() override { m_takedown_done = true; } diff --git a/lldb/include/lldb/Target/ThreadPlanStack.h b/lldb/include/lldb/Target/ThreadPlanStack.h index 7b2817b2e8fd..e0f76f8e1df5 100644 --- a/lldb/include/lldb/Target/ThreadPlanStack.h +++ b/lldb/include/lldb/Target/ThreadPlanStack.h @@ -33,7 +33,7 @@ class ThreadPlanStack { public: ThreadPlanStack(const Thread &thread, bool make_empty = false); - ~ThreadPlanStack() {} + ~ThreadPlanStack() = default; using PlanStack = std::vector<lldb::ThreadPlanSP>; @@ -48,10 +48,6 @@ public: void ThreadDestroyed(Thread *thread); - void EnableTracer(bool value, bool single_stepping); - - void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp); - void PushPlan(lldb::ThreadPlanSP new_plan_sp); lldb::ThreadPlanSP PopPlan(); @@ -114,12 +110,13 @@ private: size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for // completed plan checkpoints. std::unordered_map<size_t, PlanStack> m_completed_plan_store; + mutable std::recursive_mutex m_stack_mutex; }; class ThreadPlanStackMap { public: ThreadPlanStackMap(Process &process) : m_process(process) {} - ~ThreadPlanStackMap() {} + ~ThreadPlanStackMap() = default; // Prune the map using the current_threads list. void Update(ThreadList ¤t_threads, bool delete_missing, @@ -157,7 +154,7 @@ public: } void Clear() { - for (auto plan : m_plans_list) + for (auto &plan : m_plans_list) plan.second.ThreadDestroyed(nullptr); m_plans_list.clear(); } diff --git a/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/lldb/include/lldb/Target/ThreadPlanStepInRange.h index a26b0fb87b3a..f9ef87942a7c 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -22,7 +22,7 @@ class ThreadPlanStepInRange : public ThreadPlanStepRange, public: ThreadPlanStepInRange(Thread &thread, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others, + const char *step_into_target, lldb::RunMode stop_others, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info); @@ -34,10 +34,6 @@ public: void SetAvoidRegexp(const char *name); - void SetStepInTarget(const char *target) { - m_step_into_target.SetCString(target); - } - static void SetDefaultFlagValue(uint32_t new_value); bool IsVirtualStep() override; diff --git a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h index 760bc4886faa..52a5a2efc0a4 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -18,7 +18,7 @@ namespace lldb_private { class ThreadPlanStepInstruction : public ThreadPlan { public: ThreadPlanStepInstruction(Thread &thread, bool step_over, bool stop_others, - Vote stop_vote, Vote run_vote); + Vote report_stop_vote, Vote report_run_vote); ~ThreadPlanStepInstruction() override; diff --git a/lldb/include/lldb/Target/ThreadPlanStepOut.h b/lldb/include/lldb/Target/ThreadPlanStepOut.h index 5c39232fd2e8..b1d8769f7c54 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -18,8 +18,8 @@ namespace lldb_private { class ThreadPlanStepOut : public ThreadPlan, public ThreadPlanShouldStopHere { public: ThreadPlanStepOut(Thread &thread, SymbolContext *addr_context, - bool first_insn, bool stop_others, Vote stop_vote, - Vote run_vote, uint32_t frame_idx, + bool first_insn, bool stop_others, Vote report_stop_vote, + Vote report_run_vote, uint32_t frame_idx, LazyBool step_out_avoids_code_without_debug_info, bool continue_to_next_branch = false, bool gather_return_value = true); @@ -76,8 +76,9 @@ private: friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_others, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - Status &status, LazyBool step_out_avoids_code_without_debug_info); + bool stop_others, Vote report_stop_vote, Vote report_run_vote, + uint32_t frame_idx, Status &status, + LazyBool step_out_avoids_code_without_debug_info); void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info); // Need an appropriate marker for the current stack so we can tell step out diff --git a/lldb/include/lldb/Target/ThreadPlanTracer.h b/lldb/include/lldb/Target/ThreadPlanTracer.h index 677a2c0dd93c..a6fd2f031dc2 100644 --- a/lldb/include/lldb/Target/ThreadPlanTracer.h +++ b/lldb/include/lldb/Target/ThreadPlanTracer.h @@ -50,14 +50,6 @@ public: bool TracingEnabled() { return m_enabled; } - bool EnableSingleStep(bool value) { - bool old_value = m_single_step; - m_single_step = value; - return old_value; - } - - bool SingleStepEnabled() { return m_single_step; } - Thread &GetThread(); protected: @@ -71,7 +63,6 @@ protected: private: bool TracerExplainsStop(); - bool m_single_step; bool m_enabled; lldb::StreamSP m_stream_sp; Thread *m_thread; diff --git a/lldb/include/lldb/Target/ThreadSpec.h b/lldb/include/lldb/Target/ThreadSpec.h index 8c22d53185ff..7c7c83274119 100644 --- a/lldb/include/lldb/Target/ThreadSpec.h +++ b/lldb/include/lldb/Target/ThreadSpec.h @@ -120,8 +120,8 @@ private: return g_option_names[(size_t) enum_value]; } - uint32_t m_index; - lldb::tid_t m_tid; + uint32_t m_index = UINT32_MAX; + lldb::tid_t m_tid = LLDB_INVALID_THREAD_ID; std::string m_name; std::string m_queue_name; }; diff --git a/lldb/include/lldb/Target/ThreadTrace.h b/lldb/include/lldb/Target/ThreadTrace.h deleted file mode 100644 index a32b33867c26..000000000000 --- a/lldb/include/lldb/Target/ThreadTrace.h +++ /dev/null @@ -1,61 +0,0 @@ -//===-- ThreadTrace.h -------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_TARGET_THREADTRACE_H -#define LLDB_TARGET_THREADTRACE_H - -#include "lldb/Target/Thread.h" - -namespace lldb_private { - -/// \class ThreadTrace ThreadTrace.h -/// -/// Thread implementation used for representing threads gotten from trace -/// session files, which are similar to threads from core files. -/// -/// See \a TraceSessionFileParser for more information regarding trace session -/// files. -class ThreadTrace : public Thread { -public: - /// \param[in] process - /// The process who owns this thread. - /// - /// \param[in] tid - /// The tid of this thread. - /// - /// \param[in] trace_file. - /// The file that contains the list of instructions that were traced when - /// this thread was being executed. - ThreadTrace(Process &process, lldb::tid_t tid, const FileSpec &trace_file) - : Thread(process, tid), m_trace_file(trace_file) {} - - void RefreshStateAfterStop() override; - - lldb::RegisterContextSP GetRegisterContext() override; - - lldb::RegisterContextSP - CreateRegisterContextForFrame(StackFrame *frame) override; - - /// \return - /// The trace file of this thread. - const FileSpec &GetTraceFile() const; - -protected: - bool CalculateStopInfo() override; - - lldb::RegisterContextSP m_thread_reg_ctx_sp; - -private: - FileSpec m_trace_file; -}; - -typedef std::shared_ptr<ThreadTrace> ThreadTraceSP; - -} // namespace lldb_private - -#endif // LLDB_TARGET_THREADTRACE_H diff --git a/lldb/include/lldb/Target/Trace.h b/lldb/include/lldb/Target/Trace.h index 3b127916a917..f5654988b201 100644 --- a/lldb/include/lldb/Target/Trace.h +++ b/lldb/include/lldb/Target/Trace.h @@ -9,10 +9,15 @@ #ifndef LLDB_TARGET_TRACE_H #define LLDB_TARGET_TRACE_H +#include <unordered_map> + #include "llvm/Support/JSON.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/TraceCursor.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-private.h" @@ -36,15 +41,10 @@ namespace lldb_private { /// /// In order to support live tracing, the name of the plug-in should match the /// name of the tracing type returned by the gdb-remote packet -/// \a jLLDBTraceSupportedType. +/// \a jLLDBTraceSupported. class Trace : public PluginInterface, public std::enable_shared_from_this<Trace> { public: - enum class TraceDirection { - Forwards = 0, - Backwards, - }; - /// Dump the trace data that this plug-in has access to. /// /// This function will dump all of the trace data for all threads in a user @@ -94,8 +94,24 @@ public: /// The path to the directory that contains the session file. It's used to /// resolved relative paths in the session file. static llvm::Expected<lldb::TraceSP> - FindPlugin(Debugger &debugger, const llvm::json::Value &trace_session_file, - llvm::StringRef session_file_dir); + FindPluginForPostMortemProcess(Debugger &debugger, + const llvm::json::Value &trace_session_file, + llvm::StringRef session_file_dir); + + /// Find a trace plug-in to trace a live process. + /// + /// \param[in] plugin_name + /// Plug-in name to search. + /// + /// \param[in] process + /// Live process to trace. + /// + /// \return + /// A \a TraceSP instance, or an \a llvm::Error if the plug-in name + /// doesn't match any registered plug-ins or tracing couldn't be + /// started. + static llvm::Expected<lldb::TraceSP> + FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process); /// Get the schema of a Trace plug-in given its name. /// @@ -104,98 +120,189 @@ public: static llvm::Expected<llvm::StringRef> FindPluginSchema(llvm::StringRef plugin_name); + /// Get the command handle for the "process trace start" command. + virtual lldb::CommandObjectSP + GetProcessTraceStartCommand(CommandInterpreter &interpreter) = 0; + + /// Get the command handle for the "thread trace start" command. + virtual lldb::CommandObjectSP + GetThreadTraceStartCommand(CommandInterpreter &interpreter) = 0; + /// \return /// The JSON schema of this Trace plug-in. virtual llvm::StringRef GetSchema() = 0; - /// Each decoded thread contains a cursor to the current position the user is - /// stopped at. When reverse debugging, each operation like reverse-next or - /// reverse-continue will move this cursor, which is then picked by any - /// subsequent dump or reverse operation. - /// - /// The initial position for this cursor is the last element of the thread, - /// which is the most recent chronologically. + /// Get a \a TraceCursor for the given thread's trace. /// /// \return - /// The current position of the thread's trace or \b 0 if empty. - virtual size_t GetCursorPosition(const Thread &thread) = 0; + /// A \a TraceCursorUP. If the thread is not traced or its trace + /// information failed to load, the corresponding error is embedded in the + /// trace. + virtual lldb::TraceCursorUP GetCursor(Thread &thread) = 0; - /// Dump \a count instructions of the given thread's trace ending at the - /// given \a end_position position. - /// - /// The instructions are printed along with their indices or positions, which - /// are increasing chronologically. This means that the \a index 0 represents - /// the oldest instruction of the trace chronologically. + /// Dump general info about a given thread's trace. Each Trace plug-in + /// decides which data to show. /// /// \param[in] thread - /// The thread whose trace will be dumped. + /// The thread that owns the trace in question. /// /// \param[in] s - /// The stream object where the instructions are printed. + /// The stream object where the info will be printed printed. /// - /// \param[in] count - /// The number of instructions to print. + /// \param[in] verbose + /// If \b true, print detailed info + /// If \b false, print compact info + virtual void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) = 0; + + /// Check if a thread is currently traced by this object. + /// + /// \param[in] thread + /// The thread in question. /// - /// \param[in] end_position - /// The position of the last instruction to print. + /// \return + /// \b true if the thread is traced by this instance, \b false otherwise. + virtual bool IsTraced(const Thread &thread) = 0; + + /// \return + /// A description of the parameters to use for the \a Trace::Start method. + virtual const char *GetStartConfigurationHelp() = 0; + + /// Start tracing a live process. /// - /// \param[in] raw - /// Dump only instruction addresses without disassembly nor symbol + /// \param[in] configuration + /// See \a SBTrace::Start(const lldb::SBStructuredData &) for more /// information. - void DumpTraceInstructions(Thread &thread, Stream &s, size_t count, - size_t end_position, bool raw); + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error Start( + StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0; - /// Run the provided callback on the instructions of the trace of the given - /// thread. + /// Start tracing live threads. /// - /// The instructions will be traversed starting at the given \a position - /// sequentially until the callback returns \b false, in which case no more - /// instructions are inspected. + /// \param[in] tids + /// Threads to trace. This method tries to trace as many threads as + /// possible. /// - /// The purpose of this method is to allow inspecting traced instructions - /// without exposing the internal representation of how they are stored on - /// memory. + /// \param[in] configuration + /// See \a SBTrace::Start(const lldb::SBThread &, const + /// lldb::SBStructuredData &) for more information. /// - /// \param[in] thread - /// The thread whose trace will be traversed. + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + virtual llvm::Error Start( + llvm::ArrayRef<lldb::tid_t> tids, + StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0; + + /// Stop tracing live threads. /// - /// \param[in] position - /// The instruction position to start iterating on. + /// \param[in] tids + /// The threads to stop tracing on. /// - /// \param[in] direction - /// If \b TraceDirection::Forwards, then then instructions will be - /// traversed forwards chronologically, i.e. with incrementing indices. If - /// \b TraceDirection::Backwards, the traversal is done backwards - /// chronologically, i.e. with decrementing indices. + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Stop(llvm::ArrayRef<lldb::tid_t> tids); + + /// Stop tracing all current and future threads of a live process. + /// + /// \param[in] request + /// The information determining which threads or process to stop tracing. /// - /// \param[in] callback - /// The callback to execute on each instruction. If it returns \b false, - /// the iteration stops. - virtual void TraverseInstructions( - const Thread &thread, size_t position, TraceDirection direction, - std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)> - callback) = 0; + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Stop(); + + /// Get the trace file of the given post mortem thread. + llvm::Expected<const FileSpec &> GetPostMortemTraceFile(lldb::tid_t tid); - /// Stop tracing a live thread + /// \return + /// The stop ID of the live process being traced, or an invalid stop ID + /// if the trace is in an error or invalid state. + uint32_t GetStopID(); + +protected: + /// Get binary data of a live thread given a data identifier. /// - /// \param[in] thread - /// The thread object to stop tracing. + /// \param[in] tid + /// The thread whose data is requested. + /// + /// \param[in] kind + /// The kind of data requested. /// /// \return - /// An \a llvm::Error if stopping tracing failed, or \b - /// llvm::Error::success() otherwise. - virtual llvm::Error StopTracingThread(const Thread &thread) { - return llvm::make_error<UnimplementedError>(); - } + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<llvm::ArrayRef<uint8_t>> + GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind); - /// Get the number of available instructions in the trace of the given thread. + /// Get binary data of the current process given a data identifier. /// - /// \param[in] thread - /// The thread whose trace will be inspected. + /// \param[in] kind + /// The kind of data requested. /// /// \return - /// The total number of instructions in the trace. - virtual size_t GetInstructionCount(const Thread &thread) = 0; + /// A vector of bytes with the requested data, or an \a llvm::Error in + /// case of failures. + llvm::Expected<llvm::ArrayRef<uint8_t>> + GetLiveProcessBinaryData(llvm::StringRef kind); + + /// Get the size of the data returned by \a GetLiveThreadBinaryData + llvm::Optional<size_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid, + llvm::StringRef kind); + + /// Get the size of the data returned by \a GetLiveProcessBinaryData + llvm::Optional<size_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind); + /// Constructor for post mortem processes + Trace() = default; + + /// Constructor for a live process + Trace(Process &live_process) : m_live_process(&live_process) {} + + /// Start tracing a live process or its threads. + /// + /// \param[in] request + /// JSON object with the information necessary to start tracing. In the + /// case of gdb-remote processes, this JSON object should conform to the + /// jLLDBTraceStart packet. + /// + /// \return + /// \a llvm::Error::success if the operation was successful, or + /// \a llvm::Error otherwise. + llvm::Error Start(const llvm::json::Value &request); + + /// Get the current tracing state of a live process and its threads. + /// + /// \return + /// A JSON object string with custom data depending on the trace + /// technology, or an \a llvm::Error in case of errors. + llvm::Expected<std::string> GetLiveProcessState(); + + /// Method to be overriden by the plug-in to refresh its own state. + /// + /// This is invoked by RefreshLiveProcessState when a new state is found. + /// + /// \param[in] state + /// The jLLDBTraceGetState response. + virtual void + DoRefreshLiveProcessState(llvm::Expected<TraceGetStateResponse> state) = 0; + + /// Method to be invoked by the plug-in to refresh the live process state. + /// + /// The result is cached through the same process stop. + void RefreshLiveProcessState(); + + uint32_t m_stop_id = LLDB_INVALID_STOP_ID; + /// Process traced by this object if doing live tracing. Otherwise it's null. + Process *m_live_process = nullptr; + /// tid -> data kind -> size + std::map<lldb::tid_t, std::unordered_map<std::string, size_t>> + m_live_thread_data; + /// data kind -> size + std::unordered_map<std::string, size_t> m_live_process_data; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/TraceCursor.h b/lldb/include/lldb/Target/TraceCursor.h new file mode 100644 index 000000000000..14fc00d5f95b --- /dev/null +++ b/lldb/include/lldb/Target/TraceCursor.h @@ -0,0 +1,211 @@ +//===-- TraceCursor.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_TRACE_CURSOR_H +#define LLDB_TARGET_TRACE_CURSOR_H + +#include "lldb/lldb-private.h" + +#include "lldb/Target/ExecutionContext.h" + +namespace lldb_private { + +/// Class used for iterating over the instructions of a thread's trace. +/// +/// This class attempts to be a generic interface for accessing the instructions +/// of the trace so that each Trace plug-in can reconstruct, represent and store +/// the instruction data in an flexible way that is efficient for the given +/// technology. +/// +/// Live processes: +/// In the case of a live process trace, an instance of a \a TraceCursor should +/// point to the trace at the moment it was collected. If the process is later +/// resumed and new trace data is collected, that should leave that old cursor +/// unaffected. +/// +/// Errors in the trace: +/// As there could be errors when reconstructing the instructions of a trace, +/// these errors are represented as failed instructions, and the cursor can +/// point at them. The consumer should invoke \a TraceCursor::GetError() to +/// check if the cursor is pointing to either a valid instruction or an error. +/// +/// Instructions: +/// A \a TraceCursor always points to a specific instruction or error in the +/// trace. +/// +/// Defaults: +/// By default, the cursor points at the end item of the trace, moves +/// backwards, has a move granularity of \a +/// eTraceInstructionControlFlowTypeInstruction (i.e. visit every instruction) +/// and stops at every error (the "ignore errors" flag is \b false). See the +/// \a TraceCursor::Next() method for more documentation. +/// +/// Sample usage: +/// +/// TraceCursorUP cursor = trace.GetTrace(thread); +/// +/// cursor->SetGranularity(eTraceInstructionControlFlowTypeCall | +/// eTraceInstructionControlFlowTypeReturn); +/// +/// do { +/// if (llvm::Error error = cursor->GetError()) +/// cout << "error found at: " << llvm::toString(error) << endl; +/// else if (cursor->GetInstructionControlFlowType() & +/// eTraceInstructionControlFlowTypeCall) +/// std::cout << "call found at " << cursor->GetLoadAddress() << +/// std::endl; +/// else if (cursor->GetInstructionControlFlowType() & +/// eTraceInstructionControlFlowTypeReturn) +/// std::cout << "return found at " << cursor->GetLoadAddress() << +/// std::endl; +/// } while(cursor->Next()); +/// +/// Low level traversal: +/// Unlike the \a TraceCursor::Next() API, which uses a given granularity and +/// direction to advance the cursor, the \a TraceCursor::Seek() method can be +/// used to reposition the cursor to an offset of the end, beginning, or +/// current position of the trace. +class TraceCursor { +public: + /// Helper enum to indicate the reference point when invoking + /// \a TraceCursor::Seek(). + enum class SeekType { + /// The beginning of the trace, i.e the oldest item. + Set = 0, + /// The current position in the trace. + Current, + /// The end of the trace, i.e the most recent item. + End + }; + + /// Create a cursor that initially points to the end of the trace, i.e. the + /// most recent item. + TraceCursor(lldb::ThreadSP thread_sp); + + virtual ~TraceCursor() = default; + + /// Set the granularity to use in the \a TraceCursor::Next() method. + void SetGranularity(lldb::TraceInstructionControlFlowType granularity); + + /// Set the "ignore errors" flag to use in the \a TraceCursor::Next() method. + void SetIgnoreErrors(bool ignore_errors); + + /// Set the direction to use in the \a TraceCursor::Next() method. + /// + /// \param[in] forwards + /// If \b true, then the traversal will be forwards, otherwise backwards. + void SetForwards(bool forwards); + + /// Check if the direction to use in the \a TraceCursor::Next() method is + /// forwards. + /// + /// \return + /// \b true if the current direction is forwards, \b false if backwards. + bool IsForwards() const; + + /// Move the cursor to the next instruction that matches the current + /// granularity. + /// + /// Direction: + /// The traversal is done following the current direction of the trace. If + /// it is forwards, the instructions are visited forwards + /// chronologically. Otherwise, the traversal is done in + /// the opposite direction. By default, a cursor moves backwards unless + /// changed with \a TraceCursor::SetForwards(). + /// + /// Granularity: + /// The cursor will traverse the trace looking for the first instruction + /// that matches the current granularity. If there aren't any matching + /// instructions, the cursor won't move, to give the opportunity of + /// changing granularities. + /// + /// Ignore errors: + /// If the "ignore errors" flags is \b false, the traversal will stop as + /// soon as it finds an error in the trace and the cursor will point at + /// it. + /// + /// \return + /// \b true if the cursor effectively moved, \b false otherwise. + virtual bool Next() = 0; + + /// Make the cursor point to an item in the trace based on an origin point and + /// an offset. This API doesn't distinguishes instruction types nor errors in + /// the trace, unlike the \a TraceCursor::Next() method. + /// + /// The resulting position of the trace is + /// origin + offset + /// + /// If this resulting position would be out of bounds, it will be adjusted to + /// the last or first item in the trace correspondingly. + /// + /// \param[in] offset + /// How many items to move forwards (if positive) or backwards (if + /// negative) from the given origin point. + /// + /// \param[in] origin + /// The reference point to use when moving the cursor. + /// + /// \return + /// The number of trace items moved from the origin. + virtual size_t Seek(ssize_t offset, SeekType origin) = 0; + + /// \return + /// The \a ExecutionContextRef of the backing thread from the creation time + /// of this cursor. + ExecutionContextRef &GetExecutionContextRef(); + + /// Instruction or error information + /// \{ + + /// \return + /// Whether the cursor points to an error or not. + virtual bool IsError() = 0; + + /// Get the corresponding error message if the cursor points to an error in + /// the trace. + /// + /// \return + /// \b llvm::Error::success if the cursor is not pointing to an error in + /// the trace. Otherwise return an \a llvm::Error describing the issue. + virtual llvm::Error GetError() = 0; + + /// \return + /// The load address of the instruction the cursor is pointing at. If the + /// cursor points to an error in the trace, return \b + /// LLDB_INVALID_ADDRESS. + virtual lldb::addr_t GetLoadAddress() = 0; + + /// Get the timestamp counter associated with the current instruction. + /// Modern Intel, ARM and AMD processors support this counter. However, a + /// trace plugin might decide to use a different time unit instead of an + /// actual TSC. + /// + /// \return + /// The timestamp or \b llvm::None if not available. + virtual llvm::Optional<uint64_t> GetTimestampCounter() = 0; + + /// \return + /// The \a lldb::TraceInstructionControlFlowType categories the + /// instruction the cursor is pointing at falls into. If the cursor points + /// to an error in the trace, return \b 0. + virtual lldb::TraceInstructionControlFlowType + GetInstructionControlFlowType() = 0; + /// \} + +protected: + ExecutionContextRef m_exe_ctx_ref; + + lldb::TraceInstructionControlFlowType m_granularity = + lldb::eTraceInstructionControlFlowTypeInstruction; + bool m_ignore_errors = false; + bool m_forwards = false; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_CURSOR_H diff --git a/lldb/include/lldb/Target/TraceExporter.h b/lldb/include/lldb/Target/TraceExporter.h new file mode 100644 index 000000000000..6560b39fd42e --- /dev/null +++ b/lldb/include/lldb/Target/TraceExporter.h @@ -0,0 +1,42 @@ +//===-- TraceExporter.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_TRACE_EXPORTER_H +#define LLDB_TARGET_TRACE_EXPORTER_H + +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +/// \class TraceExporter TraceExporter.h "lldb/Target/TraceExporter.h" +/// A plug-in interface definition class for trace exporters. +/// +/// Trace exporter plug-ins operate on traces, converting the trace data +/// provided by an \a lldb_private::TraceCursor into a different format that can +/// be digested by other tools, e.g. Chrome Trace Event Profiler. +/// +/// Trace exporters are supposed to operate on an architecture-agnostic fashion, +/// as a TraceCursor, which feeds the data, hides the actual trace technology +/// being used. +class TraceExporter : public PluginInterface { +public: + /// Create an instance of a trace exporter plugin given its name. + /// + /// \param[in] plugin_Name + /// Plug-in name to search. + /// + /// \return + /// A \a TraceExporterUP instance, or an \a llvm::Error if the plug-in + /// name doesn't match any registered plug-ins. + static llvm::Expected<lldb::TraceExporterUP> + FindPlugin(llvm::StringRef plugin_name); +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_EXPORTER_H diff --git a/lldb/include/lldb/Target/TraceInstructionDumper.h b/lldb/include/lldb/Target/TraceInstructionDumper.h new file mode 100644 index 000000000000..c4878bfd3fd5 --- /dev/null +++ b/lldb/include/lldb/Target/TraceInstructionDumper.h @@ -0,0 +1,77 @@ +//===-- TraceInstructionDumper.h --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/TraceCursor.h" + +#ifndef LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H +#define LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H + +namespace lldb_private { + +/// Class used to dump the instructions of a \a TraceCursor using its current +/// state and granularity. +class TraceInstructionDumper { +public: + /// Create a instruction dumper for the cursor. + /// + /// \param[in] cursor + /// The cursor whose instructions will be dumped. + /// + /// \param[in] initial_index + /// Presentation index to use for referring to the current instruction + /// of the cursor. If the direction is forwards, the index will increase, + /// and if the direction is backwards, the index will decrease. + /// + /// \param[in] raw + /// Dump only instruction addresses without disassembly nor symbol + /// information. + /// + /// \param[in] show_tsc + /// For each instruction, print the corresponding timestamp counter if + /// available. + TraceInstructionDumper(lldb::TraceCursorUP &&cursor_up, int initial_index = 0, + bool raw = false, bool show_tsc = false); + + /// Dump \a count instructions of the thread trace starting at the current + /// cursor position. + /// + /// This effectively moves the cursor to the next unvisited position, so that + /// a subsequent call to this method continues where it left off. + /// + /// \param[in] s + /// The stream object where the instructions are printed. + /// + /// \param[in] count + /// The number of instructions to print. + void DumpInstructions(Stream &s, size_t count); + + /// Indicate the dumper that no more data is available in the trace. + void SetNoMoreData(); + + /// \return + /// \b true if there's still more data to traverse in the trace. + bool HasMoreData(); + +private: + /// Move the cursor one step. + /// + /// \return + /// \b true if the cursor moved. + bool TryMoveOneStep(); + + lldb::TraceCursorUP m_cursor_up; + int m_index; + bool m_raw; + bool m_show_tsc; + /// If \b true, all the instructions have been traversed. + bool m_no_more_data = false; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H diff --git a/lldb/include/lldb/Target/TraceSessionFileParser.h b/lldb/include/lldb/Target/TraceSessionFileParser.h deleted file mode 100644 index 52cc27c1a485..000000000000 --- a/lldb/include/lldb/Target/TraceSessionFileParser.h +++ /dev/null @@ -1,179 +0,0 @@ -//===-- TraceSessionFileParser.h --------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_TARGET_TRACESESSIONPARSER_H -#define LLDB_TARGET_TRACESESSIONPARSER_H - -#include "llvm/Support/JSON.h" - -#include "lldb/Target/ThreadTrace.h" - -namespace lldb_private { - -/// \class TraceSessionFileParser TraceSessionFileParser.h -/// -/// Base class for parsing the common information of JSON trace session files. -/// Contains the basic C++ structs that represent the JSON data, which include -/// \a JSONTraceSession as the root object. -/// -/// See \a Trace::FindPlugin for more information regarding these JSON files. -class TraceSessionFileParser { -public: - /// C++ structs representing the JSON trace session. - /// \{ - struct JSONAddress { - lldb::addr_t value; - }; - - struct JSONModule { - std::string system_path; - llvm::Optional<std::string> file; - JSONAddress load_address; - llvm::Optional<std::string> uuid; - }; - - struct JSONThread { - int64_t tid; - std::string trace_file; - }; - - struct JSONProcess { - int64_t pid; - std::string triple; - std::vector<JSONThread> threads; - std::vector<JSONModule> modules; - }; - - struct JSONTracePluginSettings { - std::string type; - }; - - struct JSONTraceSessionBase { - std::vector<JSONProcess> processes; - }; - - /// The trace plug-in implementation should provide its own TPluginSettings, - /// which corresponds to the "trace" section of the schema. - template <class TPluginSettings> - struct JSONTraceSession : JSONTraceSessionBase { - TPluginSettings trace; - }; - /// \} - - /// Helper struct holding the objects created when parsing a process - struct ParsedProcess { - lldb::TargetSP target_sp; - std::vector<ThreadTraceSP> threads; - }; - - TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir, - llvm::StringRef schema) - : m_debugger(debugger), m_session_file_dir(session_file_dir), - m_schema(schema) {} - - /// Build the full schema for a Trace plug-in. - /// - /// \param[in] plugin_schema - /// The subschema that corresponds to the "trace" section of the schema. - /// - /// \return - /// The full schema containing the common attributes and the plug-in - /// specific attributes. - static std::string BuildSchema(llvm::StringRef plugin_schema); - - /// Parse the fields common to all trace session schemas. - /// - /// \param[in] session - /// The session json objects already deserialized. - /// - /// \return - /// A list of \a ParsedProcess containing all threads and targets created - /// during the parsing, or an error in case of failures. In case of - /// errors, no side effects are produced. - llvm::Expected<std::vector<ParsedProcess>> - ParseCommonSessionFile(const JSONTraceSessionBase &session); - -protected: - /// Resolve non-absolute paths relative to the session file folder. It - /// modifies the given file_spec. - void NormalizePath(lldb_private::FileSpec &file_spec); - - ThreadTraceSP ParseThread(lldb::ProcessSP &process_sp, - const JSONThread &thread); - - llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process); - - llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module); - - /// Create a user-friendly error message upon a JSON-parsing failure using the - /// \a json::ObjectMapper functionality. - /// - /// \param[in] root - /// The \a llvm::json::Path::Root used to parse the JSON \a value. - /// - /// \param[in] value - /// The json value that failed to parse. - /// - /// \return - /// An \a llvm::Error containing the user-friendly error message. - llvm::Error CreateJSONError(llvm::json::Path::Root &root, - const llvm::json::Value &value); - - Debugger &m_debugger; - std::string m_session_file_dir; - llvm::StringRef m_schema; -}; -} // namespace lldb_private - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONAddress &address, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONModule &module, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONThread &thread, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONProcess &process, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONTracePluginSettings - &plugin_settings, - Path path); - -bool fromJSON( - const Value &value, - lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session, - Path path); - -template <class TPluginSettings> -bool fromJSON( - const Value &value, - lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings> - &session, - Path path) { - ObjectMapper o(value, path); - return o && o.map("trace", session.trace) && - fromJSON(value, - (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &) - session, - path); -} - -} // namespace json -} // namespace llvm - -#endif // LLDB_TARGET_TRACESESSIONPARSER_H diff --git a/lldb/include/lldb/Target/UnixSignals.h b/lldb/include/lldb/Target/UnixSignals.h index cc24b76e4c3f..6fecdda12def 100644 --- a/lldb/include/lldb/Target/UnixSignals.h +++ b/lldb/include/lldb/Target/UnixSignals.h @@ -104,7 +104,7 @@ protected: Signal(const char *name, bool default_suppress, bool default_stop, bool default_notify, const char *description, const char *alias); - ~Signal() {} + ~Signal() = default; }; virtual void Reset(); diff --git a/lldb/include/lldb/Target/Unwind.h b/lldb/include/lldb/Target/Unwind.h index 783b7103e8fe..3faef139b00a 100644 --- a/lldb/include/lldb/Target/Unwind.h +++ b/lldb/include/lldb/Target/Unwind.h @@ -21,7 +21,7 @@ protected: Unwind(Thread &thread) : m_thread(thread), m_unwind_mutex() {} public: - virtual ~Unwind() {} + virtual ~Unwind() = default; void Clear() { std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); diff --git a/lldb/include/lldb/Target/UnwindLLDB.h b/lldb/include/lldb/Target/UnwindLLDB.h index c7c9cfbccbad..f6750171c54a 100644 --- a/lldb/include/lldb/Target/UnwindLLDB.h +++ b/lldb/include/lldb/Target/UnwindLLDB.h @@ -109,17 +109,17 @@ protected: private: struct Cursor { - lldb::addr_t start_pc; // The start address of the function/symbol for this - // frame - current pc if unknown - lldb::addr_t cfa; // The canonical frame address for this stack frame + lldb::addr_t start_pc = + LLDB_INVALID_ADDRESS; // The start address of the function/symbol for + // this frame - current pc if unknown + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; // The canonical frame address for + // this stack frame lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & // provide to the StackFrame creation RegisterContextLLDBSP reg_ctx_lldb_sp; // These are all RegisterContextUnwind's - Cursor() - : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(), - reg_ctx_lldb_sp() {} + Cursor() : sctx(), reg_ctx_lldb_sp() {} private: Cursor(const Cursor &) = delete; diff --git a/lldb/include/lldb/Utility/Args.h b/lldb/include/lldb/Utility/Args.h index b93677b53935..cecf6b1502b5 100644 --- a/lldb/include/lldb/Utility/Args.h +++ b/lldb/include/lldb/Utility/Args.h @@ -115,7 +115,8 @@ public: /// /// \return /// The number or arguments in this object. - size_t GetArgumentCount() const; + size_t GetArgumentCount() const { return m_entries.size(); } + bool empty() const { return GetArgumentCount() == 0; } /// Gets the NULL terminated C string argument pointer for the argument at @@ -252,9 +253,9 @@ public: /// If the argument was originally quoted, put in the quote char here. void Unshift(llvm::StringRef arg_str, char quote_char = '\0'); - // Clear the arguments. - // - // For re-setting or blanking out the list of arguments. + /// Clear the arguments. + /// + /// For re-setting or blanking out the list of arguments. void Clear(); static lldb::Encoding @@ -266,21 +267,20 @@ public: static std::string GetShellSafeArgument(const FileSpec &shell, llvm::StringRef unsafe_arg); - // EncodeEscapeSequences will change the textual representation of common - // escape sequences like "\n" (two characters) into a single '\n'. It does - // this for all of the supported escaped sequences and for the \0ooo (octal) - // and \xXX (hex). The resulting "dst" string will contain the character - // versions of all supported escape sequences. The common supported escape - // sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". - + /// EncodeEscapeSequences will change the textual representation of common + /// escape sequences like "\n" (two characters) into a single '\n'. It does + /// this for all of the supported escaped sequences and for the \0ooo (octal) + /// and \xXX (hex). The resulting "dst" string will contain the character + /// versions of all supported escape sequences. The common supported escape + /// sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". static void EncodeEscapeSequences(const char *src, std::string &dst); - // ExpandEscapeSequences will change a string of possibly non-printable - // characters and expand them into text. So '\n' will turn into two - // characters like "\n" which is suitable for human reading. When a character - // is not printable and isn't one of the common in escape sequences listed in - // the help for EncodeEscapeSequences, then it will be encoded as octal. - // Printable characters are left alone. + /// ExpandEscapeSequences will change a string of possibly non-printable + /// characters and expand them into text. So '\n' will turn into two + /// characters like "\n" which is suitable for human reading. When a character + /// is not printable and isn't one of the common in escape sequences listed in + /// the help for EncodeEscapeSequences, then it will be encoded as octal. + /// Printable characters are left alone. static void ExpandEscapedCharacters(const char *src, std::string &dst); static std::string EscapeLLDBCommandArgument(const std::string &arg, @@ -290,6 +290,10 @@ private: friend struct llvm::yaml::MappingTraits<Args>; std::vector<ArgEntry> m_entries; + /// The arguments as C strings with a trailing nullptr element. + /// + /// These strings are owned by the ArgEntry object in m_entries with the + /// same index. std::vector<char *> m_argv; }; diff --git a/lldb/include/lldb/Utility/Baton.h b/lldb/include/lldb/Utility/Baton.h index 010f8da43868..8a2f04163682 100644 --- a/lldb/include/lldb/Utility/Baton.h +++ b/lldb/include/lldb/Utility/Baton.h @@ -34,8 +34,8 @@ namespace lldb_private { /// needed resources in their destructors. class Baton { public: - Baton() {} - virtual ~Baton() {} + Baton() = default; + virtual ~Baton() = default; virtual void *data() = 0; diff --git a/lldb/include/lldb/Utility/Cloneable.h b/lldb/include/lldb/Utility/Cloneable.h new file mode 100644 index 000000000000..4c9b7ae340dc --- /dev/null +++ b/lldb/include/lldb/Utility/Cloneable.h @@ -0,0 +1,56 @@ +//===-- Cloneable.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UTILITY_CLONEABLE_H +#define LLDB_UTILITY_CLONEABLE_H + +#include <memory> +#include <type_traits> + +namespace lldb_private { + +/// \class Cloneable Cloneable.h "lldb/Utility/Cloneable.h" +/// A class that implements CRTP-based "virtual constructor" idiom. +/// +/// Example: +/// @code +/// class Base { +/// using TopmostBase = Base; +/// public: +/// virtual std::shared_ptr<Base> Clone() const = 0; +/// }; +/// @endcode +/// +/// To define a class derived from the Base with overridden Clone: +/// @code +/// class Intermediate : public Cloneable<Intermediate, Base> {}; +/// @endcode +/// +/// To define a class at the next level of inheritance with overridden Clone: +/// @code +/// class Derived : public Cloneable<Derived, Intermediate> {}; +/// @endcode + +template <typename Derived, typename Base> +class Cloneable : public Base { +public: + using Base::Base; + + std::shared_ptr<typename Base::TopmostBase> Clone() const override { + // std::is_base_of requires derived type to be complete, that's why class + // scope static_assert cannot be used. + static_assert(std::is_base_of<Cloneable, Derived>::value, + "Derived class must be derived from this."); + + return std::make_shared<Derived>(static_cast<const Derived &>(*this)); + } +}; + +} // namespace lldb_private + +#endif // LLDB_UTILITY_CLONEABLE_H diff --git a/lldb/include/lldb/Utility/Connection.h b/lldb/include/lldb/Utility/Connection.h index 39e6e40191b0..0b587b81c999 100644 --- a/lldb/include/lldb/Utility/Connection.h +++ b/lldb/include/lldb/Utility/Connection.h @@ -18,7 +18,7 @@ #include <ratio> #include <string> -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Status; diff --git a/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h index 8a67faf5b54a..52d3556418f6 100644 --- a/lldb/include/lldb/Utility/ConstString.h +++ b/lldb/include/lldb/Utility/ConstString.h @@ -14,7 +14,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/YAMLTraits.h" -#include <stddef.h> +#include <cstddef> namespace lldb_private { class Stream; diff --git a/lldb/include/lldb/Utility/DataBuffer.h b/lldb/include/lldb/Utility/DataBuffer.h index 302b13307958..c778299b89ad 100644 --- a/lldb/include/lldb/Utility/DataBuffer.h +++ b/lldb/include/lldb/Utility/DataBuffer.h @@ -10,8 +10,8 @@ #define LLDB_UTILITY_DATABUFFER_H #if defined(__cplusplus) -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> #include "lldb/lldb-types.h" @@ -48,7 +48,7 @@ public: /// and be downcast to the DataBuffer pure virtual interface. The virtual /// destructor ensures that destructing the base class will destruct the /// class that inherited from it correctly. - virtual ~DataBuffer() {} + virtual ~DataBuffer() = default; /// Get a pointer to the data. /// diff --git a/lldb/include/lldb/Utility/DataBufferLLVM.h b/lldb/include/lldb/Utility/DataBufferLLVM.h index 4dc800c348c5..abb1bb40d534 100644 --- a/lldb/include/lldb/Utility/DataBufferLLVM.h +++ b/lldb/include/lldb/Utility/DataBufferLLVM.h @@ -12,8 +12,8 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/lldb-types.h" +#include <cstdint> #include <memory> -#include <stdint.h> namespace llvm { class WritableMemoryBuffer; diff --git a/lldb/include/lldb/Utility/DataEncoder.h b/lldb/include/lldb/Utility/DataEncoder.h index 8edec54c36f5..b944c09d5c47 100644 --- a/lldb/include/lldb/Utility/DataEncoder.h +++ b/lldb/include/lldb/Utility/DataEncoder.h @@ -16,8 +16,8 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { @@ -226,10 +226,10 @@ private: size_t GetByteSize() const { return m_end - m_start; } /// A pointer to the first byte of data. - uint8_t *m_start; + uint8_t *m_start = nullptr; /// A pointer to the byte that is past the end of the data. - uint8_t *m_end; + uint8_t *m_end = nullptr; /// The byte order of the data we are extracting from. lldb::ByteOrder m_byte_order; diff --git a/lldb/include/lldb/Utility/DataExtractor.h b/lldb/include/lldb/Utility/DataExtractor.h index 0210af5cf6d1..0923e5280cba 100644 --- a/lldb/include/lldb/Utility/DataExtractor.h +++ b/lldb/include/lldb/Utility/DataExtractor.h @@ -19,8 +19,8 @@ #include "llvm/Support/SwapByteOrder.h" #include <cassert> -#include <stdint.h> -#include <string.h> +#include <cstdint> +#include <cstring> namespace lldb_private { class Log; @@ -997,15 +997,15 @@ protected: } // Member variables - const uint8_t *m_start; ///< A pointer to the first byte of data. - const uint8_t - *m_end; ///< A pointer to the byte that is past the end of the data. + const uint8_t *m_start = nullptr; ///< A pointer to the first byte of data. + const uint8_t *m_end = + nullptr; ///< A pointer to the byte that is past the end of the data. lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from. uint32_t m_addr_size; ///< The address size to use when extracting addresses. /// The shared pointer to data that can be shared among multiple instances lldb::DataBufferSP m_data_sp; - const uint32_t m_target_byte_size; + const uint32_t m_target_byte_size = 1; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Utility/Endian.h b/lldb/include/lldb/Utility/Endian.h index 1d1f8fa333b8..7822dfa766dc 100644 --- a/lldb/include/lldb/Utility/Endian.h +++ b/lldb/include/lldb/Utility/Endian.h @@ -11,7 +11,7 @@ #include "lldb/lldb-enumerations.h" -#include <stdint.h> +#include <cstdint> namespace lldb_private { diff --git a/lldb/include/lldb/Utility/Event.h b/lldb/include/lldb/Utility/Event.h index 06c02629d448..4e38f98a02f3 100644 --- a/lldb/include/lldb/Utility/Event.h +++ b/lldb/include/lldb/Utility/Event.h @@ -22,8 +22,8 @@ #include <memory> #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Event; @@ -101,7 +101,7 @@ class EventDataReceipt : public EventData { public: EventDataReceipt() : EventData(), m_predicate(false) {} - ~EventDataReceipt() override {} + ~EventDataReceipt() override = default; static ConstString GetFlavorString() { static ConstString g_flavor("Process::ProcessEventData"); diff --git a/lldb/include/lldb/Utility/FileSpec.h b/lldb/include/lldb/Utility/FileSpec.h index f7cbeb247100..0f4e6505e433 100644 --- a/lldb/include/lldb/Utility/FileSpec.h +++ b/lldb/include/lldb/Utility/FileSpec.h @@ -20,8 +20,8 @@ #include "llvm/Support/Path.h" #include "llvm/Support/YAMLTraits.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class Stream; @@ -38,7 +38,7 @@ template <typename T> class SmallVectorImpl; namespace lldb_private { -/// \class FileSpec FileSpec.h "lldb/Host/FileSpec.h" +/// \class FileSpec FileSpec.h "lldb/Utility/FileSpec.h" /// A file utility class. /// /// A file specification class that divides paths up into a directory diff --git a/lldb/include/lldb/Utility/GDBRemote.h b/lldb/include/lldb/Utility/GDBRemote.h index 2ee706efbea2..f658818de806 100644 --- a/lldb/include/lldb/Utility/GDBRemote.h +++ b/lldb/include/lldb/Utility/GDBRemote.h @@ -17,8 +17,8 @@ #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> #include <vector> @@ -55,9 +55,7 @@ struct GDBRemotePacket { enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; - GDBRemotePacket() - : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0), - tid(LLDB_INVALID_THREAD_ID) {} + GDBRemotePacket() : packet() {} void Clear() { packet.data.clear(); @@ -74,10 +72,10 @@ struct GDBRemotePacket { void Dump(Stream &strm) const; BinaryData packet; - Type type; - uint32_t bytes_transmitted; - uint32_t packet_idx; - lldb::tid_t tid; + Type type = ePacketTypeInvalid; + uint32_t bytes_transmitted = 0; + uint32_t packet_idx = 0; + lldb::tid_t tid = LLDB_INVALID_THREAD_ID; private: llvm::StringRef GetTypeStr() const; diff --git a/lldb/include/lldb/Utility/IOObject.h b/lldb/include/lldb/Utility/IOObject.h index 9b2b9cfcfec0..8cf42992e7be 100644 --- a/lldb/include/lldb/Utility/IOObject.h +++ b/lldb/include/lldb/Utility/IOObject.h @@ -9,8 +9,8 @@ #ifndef LLDB_UTILITY_IOOBJECT_H #define LLDB_UTILITY_IOOBJECT_H -#include <stdarg.h> -#include <stdio.h> +#include <cstdarg> +#include <cstdio> #include <sys/types.h> #include "lldb/lldb-private.h" diff --git a/lldb/include/lldb/Utility/LLDBAssert.h b/lldb/include/lldb/Utility/LLDBAssert.h index 845af1d4cc2a..471a2f7e824f 100644 --- a/lldb/include/lldb/Utility/LLDBAssert.h +++ b/lldb/include/lldb/Utility/LLDBAssert.h @@ -20,6 +20,6 @@ namespace lldb_private { void lldb_assert(bool expression, const char *expr_text, const char *func, const char *file, unsigned int line); -} +} // namespace lldb_private #endif // LLDB_UTILITY_LLDBASSERT_H diff --git a/lldb/include/lldb/Utility/Listener.h b/lldb/include/lldb/Utility/Listener.h index 9d96e36c5abc..d70e778c9480 100644 --- a/lldb/include/lldb/Utility/Listener.h +++ b/lldb/include/lldb/Utility/Listener.h @@ -23,8 +23,8 @@ #include <string> #include <vector> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { class ConstString; diff --git a/lldb/include/lldb/Utility/Predicate.h b/lldb/include/lldb/Utility/Predicate.h index a17ac05f6e56..af16abc1a1d3 100644 --- a/lldb/include/lldb/Utility/Predicate.h +++ b/lldb/include/lldb/Utility/Predicate.h @@ -9,8 +9,8 @@ #ifndef LLDB_UTILITY_PREDICATE_H #define LLDB_UTILITY_PREDICATE_H -#include <stdint.h> -#include <time.h> +#include <cstdint> +#include <ctime> #include <condition_variable> #include <mutex> diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 8f5a5f6d21fb..3c5956926391 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -95,10 +95,10 @@ protected: // the resolved platform executable (which is in m_executable) Args m_arguments; // All program arguments except argv[0] Environment m_environment; - uint32_t m_uid; - uint32_t m_gid; + uint32_t m_uid = UINT32_MAX; + uint32_t m_gid = UINT32_MAX; ArchSpec m_arch; - lldb::pid_t m_pid; + lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID; }; // ProcessInstanceInfo @@ -107,9 +107,7 @@ protected: // to that process. class ProcessInstanceInfo : public ProcessInfo { public: - ProcessInstanceInfo() - : ProcessInfo(), m_euid(UINT32_MAX), m_egid(UINT32_MAX), - m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + ProcessInstanceInfo() : ProcessInfo() {} ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), @@ -151,9 +149,9 @@ public: protected: friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>; - uint32_t m_euid; - uint32_t m_egid; - lldb::pid_t m_parent_pid; + uint32_t m_euid = UINT32_MAX; + uint32_t m_egid = UINT32_MAX; + lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; }; typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; @@ -164,9 +162,7 @@ typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; class ProcessInstanceInfoMatch { public: - ProcessInstanceInfoMatch() - : m_match_info(), m_name_match_type(NameMatch::Ignore), - m_match_all_users(false) {} + ProcessInstanceInfoMatch() : m_match_info() {} ProcessInstanceInfoMatch(const char *process_name, NameMatch process_name_match_type) @@ -211,8 +207,8 @@ public: protected: ProcessInstanceInfo m_match_info; - NameMatch m_name_match_type; - bool m_match_all_users; + NameMatch m_name_match_type = NameMatch::Ignore; + bool m_match_all_users = false; }; namespace repro { diff --git a/lldb/include/lldb/Utility/RegisterValue.h b/lldb/include/lldb/Utility/RegisterValue.h index 4211b0a59992..1ece4f0eb79f 100644 --- a/lldb/include/lldb/Utility/RegisterValue.h +++ b/lldb/include/lldb/Utility/RegisterValue.h @@ -43,8 +43,7 @@ public: eTypeBytes }; - RegisterValue() - : m_type(eTypeInvalid), m_scalar(static_cast<unsigned long>(0)) {} + RegisterValue() : m_scalar(static_cast<unsigned long>(0)) {} explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; } @@ -257,7 +256,7 @@ public: void Clear(); protected: - RegisterValue::Type m_type; + RegisterValue::Type m_type = eTypeInvalid; Scalar m_scalar; struct { diff --git a/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/lldb/include/lldb/Utility/ReproducerInstrumentation.h index c8a98adf85c7..2b2d273a17a8 100644 --- a/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ b/lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -469,7 +469,7 @@ template <> struct DeserializationHelper<> { /// The replayer interface. struct Replayer { - virtual ~Replayer() {} + virtual ~Replayer() = default; virtual void operator()(Deserializer &deserializer) const = 0; }; @@ -714,8 +714,7 @@ protected: friend llvm::optional_detail::OptionalStorage<InstrumentationData, true>; friend llvm::Optional<InstrumentationData>; - InstrumentationData() - : m_serializer(nullptr), m_deserializer(nullptr), m_registry(nullptr) {} + InstrumentationData() = default; InstrumentationData(Serializer &serializer, Registry ®istry) : m_serializer(&serializer), m_deserializer(nullptr), m_registry(®istry) {} @@ -726,9 +725,9 @@ protected: private: static llvm::Optional<InstrumentationData> &InstanceImpl(); - Serializer *m_serializer; - Deserializer *m_deserializer; - Registry *m_registry; + Serializer *m_serializer = nullptr; + Deserializer *m_deserializer = nullptr; + Registry *m_registry = nullptr; }; struct EmptyArg {}; @@ -888,17 +887,17 @@ private: } #endif - Serializer *m_serializer; + Serializer *m_serializer = nullptr; /// Pretty function for logging. llvm::StringRef m_pretty_func; std::string m_pretty_args; /// Whether this function call was the one crossing the API boundary. - bool m_local_boundary; + bool m_local_boundary = false; /// Whether the return value was recorded explicitly. - bool m_result_recorded; + bool m_result_recorded = true; /// The sequence number for this pair of function and result. unsigned m_sequence; diff --git a/lldb/include/lldb/Utility/ReproducerProvider.h b/lldb/include/lldb/Utility/ReproducerProvider.h index 221c0eb9c5bb..db7378069a87 100644 --- a/lldb/include/lldb/Utility/ReproducerProvider.h +++ b/lldb/include/lldb/Utility/ReproducerProvider.h @@ -32,7 +32,8 @@ class AbstractRecorder { protected: AbstractRecorder(const FileSpec &filename, std::error_code &ec) : m_filename(filename.GetFilename().GetStringRef()), - m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {} + m_os(filename.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF), + m_record(true) {} public: const FileSpec &GetFilename() { return m_filename; } @@ -168,7 +169,7 @@ public: void Keep() override { FileSpec file = this->GetRoot().CopyByAppendingPathComponent(T::Info::file); std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; os << m_directory << "\n"; @@ -290,7 +291,7 @@ public: FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file); std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); if (ec) return; llvm::yaml::Output yout(os); diff --git a/lldb/include/lldb/Utility/Scalar.h b/lldb/include/lldb/Utility/Scalar.h index f797aaf99626..2801b1bd6326 100644 --- a/lldb/include/lldb/Utility/Scalar.h +++ b/lldb/include/lldb/Utility/Scalar.h @@ -49,7 +49,7 @@ public: }; // Constructors and Destructors - Scalar() : m_type(e_void), m_float(0.0f) {} + Scalar() : m_float(0.0f) {} Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} Scalar(unsigned int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {} @@ -187,7 +187,7 @@ public: size_t byte_size); protected: - Scalar::Type m_type; + Scalar::Type m_type = e_void; llvm::APSInt m_integer; llvm::APFloat m_float; diff --git a/lldb/include/lldb/Utility/Status.h b/lldb/include/lldb/Utility/Status.h index 9babad18edc0..61d663bdccba 100644 --- a/lldb/include/lldb/Utility/Status.h +++ b/lldb/include/lldb/Utility/Status.h @@ -15,7 +15,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include <cstdarg> -#include <stdint.h> +#include <cstdint> #include <string> #include <system_error> #include <type_traits> @@ -196,8 +196,9 @@ public: protected: /// Member variables - ValueType m_code; ///< Status code as an integer value. - lldb::ErrorType m_type; ///< The type of the above error code. + ValueType m_code = 0; ///< Status code as an integer value. + lldb::ErrorType m_type = + lldb::eErrorTypeInvalid; ///< The type of the above error code. mutable std::string m_string; ///< A string representation of the error code. }; diff --git a/lldb/include/lldb/Utility/Stream.h b/lldb/include/lldb/Utility/Stream.h index e7f065a1fc7b..1a5fd343e4df 100644 --- a/lldb/include/lldb/Utility/Stream.h +++ b/lldb/include/lldb/Utility/Stream.h @@ -16,9 +16,9 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" -#include <stdarg.h> -#include <stddef.h> -#include <stdint.h> +#include <cstdarg> +#include <cstddef> +#include <cstdint> #include <type_traits> namespace lldb_private { @@ -361,10 +361,10 @@ public: protected: // Member variables Flags m_flags; ///< Dump flags. - uint32_t m_addr_size; ///< Size of an address in bytes. + uint32_t m_addr_size = 4; ///< Size of an address in bytes. lldb::ByteOrder m_byte_order; ///< Byte order to use when encoding scalar types. - unsigned m_indent_level; ///< Indention level. + unsigned m_indent_level = 0; ///< Indention level. std::size_t m_bytes_written = 0; ///< Number of bytes written so far. void _PutHex8(uint8_t uvalue, bool add_prefix); diff --git a/lldb/include/lldb/Utility/StreamCallback.h b/lldb/include/lldb/Utility/StreamCallback.h index d6d74fb84799..d234cbea85c6 100644 --- a/lldb/include/lldb/Utility/StreamCallback.h +++ b/lldb/include/lldb/Utility/StreamCallback.h @@ -12,8 +12,8 @@ #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { diff --git a/lldb/include/lldb/Utility/StreamString.h b/lldb/include/lldb/Utility/StreamString.h index b0be0f7dd76a..4c568acdcc6f 100644 --- a/lldb/include/lldb/Utility/StreamString.h +++ b/lldb/include/lldb/Utility/StreamString.h @@ -15,8 +15,8 @@ #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> namespace lldb_private { diff --git a/lldb/include/lldb/Utility/StreamTee.h b/lldb/include/lldb/Utility/StreamTee.h index 2995bc07f42a..b5d3b9679e91 100644 --- a/lldb/include/lldb/Utility/StreamTee.h +++ b/lldb/include/lldb/Utility/StreamTee.h @@ -9,7 +9,7 @@ #ifndef LLDB_UTILITY_STREAMTEE_H #define LLDB_UTILITY_STREAMTEE_H -#include <limits.h> +#include <climits> #include <mutex> @@ -45,7 +45,7 @@ public: m_streams = rhs.m_streams; } - ~StreamTee() override {} + ~StreamTee() override = default; StreamTee &operator=(const StreamTee &rhs) { if (this != &rhs) { diff --git a/lldb/include/lldb/Utility/StringExtractor.h b/lldb/include/lldb/Utility/StringExtractor.h index 6a5bb24779a4..a4819378ce32 100644 --- a/lldb/include/lldb/Utility/StringExtractor.h +++ b/lldb/include/lldb/Utility/StringExtractor.h @@ -12,8 +12,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> class StringExtractor { @@ -115,7 +115,7 @@ protected: /// When extracting data from a packet, this index will march along as things /// get extracted. If set to UINT64_MAX the end of the packet data was /// reached when decoding information. - uint64_t m_index; + uint64_t m_index = 0; }; #endif // LLDB_UTILITY_STRINGEXTRACTOR_H diff --git a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index 3b6ed8030985..c67c05bdf182 100644 --- a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -15,15 +15,15 @@ #include <string> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> class StringExtractorGDBRemote : public StringExtractor { public: typedef bool (*ResponseValidatorCallback)( void *baton, const StringExtractorGDBRemote &response); - StringExtractorGDBRemote() : StringExtractor(), m_validator(nullptr) {} + StringExtractorGDBRemote() : StringExtractor() {} StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr) {} @@ -162,13 +162,14 @@ public: eServerPacketType__m, eServerPacketType_notify, // '%' notification - eServerPacketType_jTraceStart, // deprecated - eServerPacketType_jTraceBufferRead, // deprecated - eServerPacketType_jTraceMetaRead, // deprecated - eServerPacketType_jTraceStop, // deprecated - eServerPacketType_jTraceConfigRead, // deprecated + eServerPacketType_jLLDBTraceSupported, + eServerPacketType_jLLDBTraceStart, + eServerPacketType_jLLDBTraceStop, + eServerPacketType_jLLDBTraceGetState, + eServerPacketType_jLLDBTraceGetBinaryData, - eServerPacketType_jLLDBTraceSupportedType, + eServerPacketType_qMemTags, // read memory tags + eServerPacketType_QMemTags, // write memory tags }; ServerPacketType GetServerPacketType() const; @@ -193,8 +194,17 @@ public: size_t GetEscapedBinaryData(std::string &str); + static constexpr lldb::pid_t AllProcesses = UINT64_MAX; + static constexpr lldb::tid_t AllThreads = UINT64_MAX; + + // Read thread-id from the packet. If the packet is valid, returns + // the pair (PID, TID), otherwise returns llvm::None. If the packet + // does not list a PID, default_pid is used. + llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>> + GetPidTid(lldb::pid_t default_pid); + protected: - ResponseValidatorCallback m_validator; + ResponseValidatorCallback m_validator = nullptr; void *m_validator_baton; }; diff --git a/lldb/include/lldb/Utility/StringList.h b/lldb/include/lldb/Utility/StringList.h index 34930abeac3c..70f4654a6ac9 100644 --- a/lldb/include/lldb/Utility/StringList.h +++ b/lldb/include/lldb/Utility/StringList.h @@ -11,7 +11,7 @@ #include "llvm/ADT/StringRef.h" -#include <stddef.h> +#include <cstddef> #include <string> #include <vector> diff --git a/lldb/include/lldb/Utility/Timeout.h b/lldb/include/lldb/Utility/Timeout.h index 80e201515577..29f8c1bbee38 100644 --- a/lldb/include/lldb/Utility/Timeout.h +++ b/lldb/include/lldb/Utility/Timeout.h @@ -37,7 +37,6 @@ private: public: Timeout(llvm::NoneType none) : Base(none) {} - Timeout(const Timeout &other) = default; template <typename Ratio2, typename = typename EnableIf<int64_t, Ratio2>::type> diff --git a/lldb/include/lldb/Utility/Timer.h b/lldb/include/lldb/Utility/Timer.h index edc064b23b57..c70c18049426 100644 --- a/lldb/include/lldb/Utility/Timer.h +++ b/lldb/include/lldb/Utility/Timer.h @@ -9,10 +9,15 @@ #ifndef LLDB_UTILITY_TIMER_H #define LLDB_UTILITY_TIMER_H -#include "lldb/lldb-defines.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Chrono.h" +#include "llvm/Support/Signposts.h" #include <atomic> -#include <stdint.h> +#include <cstdint> + +namespace llvm { + class SignpostEmitter; +} namespace lldb_private { class Stream; @@ -41,7 +46,11 @@ public: /// Default constructor. Timer(Category &category, const char *format, ...) - __attribute__((format(printf, 3, 4))); +#if !defined(_MSC_VER) + // MSVC appears to have trouble recognizing the this argument in the constructor. + __attribute__((format(printf, 3, 4))) +#endif + ; /// Destructor ~Timer(); @@ -72,13 +81,28 @@ private: const Timer &operator=(const Timer &) = delete; }; +llvm::SignpostEmitter &GetSignposts(); + } // namespace lldb_private +// Use a format string because LLVM_PRETTY_FUNCTION might not be a string +// literal. #define LLDB_SCOPED_TIMER() \ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ - ::lldb_private::Timer _scoped_timer(_cat, LLVM_PRETTY_FUNCTION) -#define LLDB_SCOPED_TIMERF(...) \ + ::lldb_private::Timer _scoped_timer(_cat, "%s", LLVM_PRETTY_FUNCTION); \ + SIGNPOST_EMITTER_START_INTERVAL(::lldb_private::GetSignposts(), \ + &_scoped_timer, "%s", LLVM_PRETTY_FUNCTION); \ + auto _scoped_signpost = llvm::make_scope_exit([&_scoped_timer]() { \ + ::lldb_private::GetSignposts().endInterval(&_scoped_timer); \ + }) + +#define LLDB_SCOPED_TIMERF(FMT, ...) \ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ - ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__) + ::lldb_private::Timer _scoped_timer(_cat, FMT, __VA_ARGS__); \ + SIGNPOST_EMITTER_START_INTERVAL(::lldb_private::GetSignposts(), \ + &_scoped_timer, FMT, __VA_ARGS__); \ + auto _scoped_signpost = llvm::make_scope_exit([&_scoped_timer]() { \ + ::lldb_private::GetSignposts().endInterval(&_scoped_timer); \ + }) #endif // LLDB_UTILITY_TIMER_H diff --git a/lldb/include/lldb/Utility/TraceGDBRemotePackets.h b/lldb/include/lldb/Utility/TraceGDBRemotePackets.h new file mode 100644 index 000000000000..1d2448b05f2a --- /dev/null +++ b/lldb/include/lldb/Utility/TraceGDBRemotePackets.h @@ -0,0 +1,154 @@ +//===-- TraceGDBRemotePackets.h ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UTILITY_TRACEGDBREMOTEPACKETS_H +#define LLDB_UTILITY_TRACEGDBREMOTEPACKETS_H + +#include "llvm/Support/JSON.h" + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" + +/// See docs/lldb-gdb-remote.txt for more information. +namespace lldb_private { + +/// jLLDBTraceSupported gdb-remote packet +/// \{ +struct TraceSupportedResponse { + /// The name of the technology, e.g. intel-pt or arm-coresight. + /// + /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the + /// trace technology given by this struct, it should match its name with this + /// field. + std::string name; + /// The description for the technology. + std::string description; +}; + +bool fromJSON(const llvm::json::Value &value, TraceSupportedResponse &info, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceSupportedResponse &packet); +/// \} + +/// jLLDBTraceStart gdb-remote packet +/// \{ +struct TraceStartRequest { + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; + + /// If \a llvm::None, then this starts tracing the whole process. Otherwise, + /// only tracing for the specified threads is enabled. + llvm::Optional<std::vector<int64_t>> tids; + + /// \return + /// \b true if \a tids is \a None, i.e. whole process tracing. + bool IsProcessTracing() const; +}; + +bool fromJSON(const llvm::json::Value &value, TraceStartRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceStartRequest &packet); +/// \} + +/// jLLDBTraceStop gdb-remote packet +/// \{ +struct TraceStopRequest { + TraceStopRequest() = default; + + TraceStopRequest(llvm::StringRef type, const std::vector<lldb::tid_t> &tids); + + TraceStopRequest(llvm::StringRef type) : type(type){}; + + bool IsProcessTracing() const; + + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; + /// If \a llvm::None, then this stops tracing the whole process. Otherwise, + /// only tracing for the specified threads is stopped. + llvm::Optional<std::vector<int64_t>> tids; +}; + +bool fromJSON(const llvm::json::Value &value, TraceStopRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceStopRequest &packet); +///} + +/// jLLDBTraceGetState gdb-remote packet +/// \{ +struct TraceGetStateRequest { + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; +}; + +bool fromJSON(const llvm::json::Value &value, TraceGetStateRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceGetStateRequest &packet); + +struct TraceBinaryData { + /// Identifier of data to fetch with jLLDBTraceGetBinaryData. + std::string kind; + /// Size in bytes for this data. + int64_t size; +}; + +bool fromJSON(const llvm::json::Value &value, TraceBinaryData &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceBinaryData &packet); + +struct TraceThreadState { + int64_t tid; + /// List of binary data objects for this thread. + std::vector<TraceBinaryData> binaryData; +}; + +bool fromJSON(const llvm::json::Value &value, TraceThreadState &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceThreadState &packet); + +struct TraceGetStateResponse { + std::vector<TraceThreadState> tracedThreads; + std::vector<TraceBinaryData> processBinaryData; +}; + +bool fromJSON(const llvm::json::Value &value, TraceGetStateResponse &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceGetStateResponse &packet); +/// \} + +/// jLLDBTraceGetBinaryData gdb-remote packet +/// \{ +struct TraceGetBinaryDataRequest { + /// Tracing technology name, e.g. intel-pt, arm-coresight. + std::string type; + /// Identifier for the data. + std::string kind; + /// Optional tid if the data is related to a thread. + llvm::Optional<int64_t> tid; + /// Offset in bytes from where to start reading the data. + int64_t offset; + /// Number of bytes to read. + int64_t size; +}; + +bool fromJSON(const llvm::json::Value &value, + lldb_private::TraceGetBinaryDataRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const lldb_private::TraceGetBinaryDataRequest &packet); +/// \} + +} // namespace lldb_private + +#endif // LLDB_UTILITY_TRACEGDBREMOTEPACKETS_H diff --git a/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h b/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h new file mode 100644 index 000000000000..8f4947b1f189 --- /dev/null +++ b/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h @@ -0,0 +1,45 @@ +//===-- TraceIntelPTGDBRemotePackets.h --------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H +#define LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H + +#include "lldb/Utility/TraceGDBRemotePackets.h" + +/// See docs/lldb-gdb-remote.txt for more information. +namespace lldb_private { + +/// jLLDBTraceStart gdb-remote packet +/// \{ +struct TraceIntelPTStartRequest : TraceStartRequest { + /// Size in bytes to use for each thread's trace buffer. + int64_t threadBufferSize; + + /// Whether to enable TSC + bool enableTsc; + + /// PSB packet period + llvm::Optional<int64_t> psbPeriod; + + /// Required when doing "process tracing". + /// + /// Limit in bytes on all the thread traces started by this "process trace" + /// instance. When a thread is about to be traced and the limit would be hit, + /// then a "tracing" stop event is triggered. + llvm::Optional<int64_t> processBufferSizeLimit; +}; + +bool fromJSON(const llvm::json::Value &value, TraceIntelPTStartRequest &packet, + llvm::json::Path path); + +llvm::json::Value toJSON(const TraceIntelPTStartRequest &packet); +/// \} + +} // namespace lldb_private + +#endif // LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H diff --git a/lldb/include/lldb/Utility/TraceOptions.h b/lldb/include/lldb/Utility/TraceOptions.h deleted file mode 100644 index c9a8d12ce125..000000000000 --- a/lldb/include/lldb/Utility/TraceOptions.h +++ /dev/null @@ -1,81 +0,0 @@ -//===-- TraceOptions.h ------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UTILITY_TRACEOPTIONS_H -#define LLDB_UTILITY_TRACEOPTIONS_H - -#include "lldb/lldb-defines.h" -#include "lldb/lldb-enumerations.h" - -#include "lldb/Utility/StructuredData.h" - -namespace lldb_private { - -/// This struct represents a tracing technology. -struct TraceTypeInfo { - /// The name of the technology, e.g. intel-pt or arm-coresight. - /// - /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the - /// trace technology given by this struct, it should match its name with this - /// field. - std::string name; - /// A description for the technology. - std::string description; -}; - -class TraceOptions { -public: - TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {} - - const StructuredData::DictionarySP &getTraceParams() const { - return m_trace_params; - } - - lldb::TraceType getType() const { return m_type; } - - uint64_t getTraceBufferSize() const { return m_trace_buffer_size; } - - uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; } - - void setTraceParams(const StructuredData::DictionarySP &dict_obj) { - m_trace_params = dict_obj; - } - - void setType(lldb::TraceType type) { m_type = type; } - - void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; } - - void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; } - - void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; } - - lldb::tid_t getThreadID() const { return m_thread_id; } - -private: - lldb::TraceType m_type; - uint64_t m_trace_buffer_size; - uint64_t m_meta_data_buffer_size; - lldb::tid_t m_thread_id; - - /// m_trace_params is meant to hold any custom parameters - /// apart from meta buffer size and trace size. - /// The interpretation of such parameters is left to - /// the lldb-server. - StructuredData::DictionarySP m_trace_params; -}; -} - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path); - -} // namespace json -} // namespace llvm - -#endif // LLDB_UTILITY_TRACEOPTIONS_H diff --git a/lldb/include/lldb/Utility/UUID.h b/lldb/include/lldb/Utility/UUID.h index f2107d9b135b..1c7c04758da0 100644 --- a/lldb/include/lldb/Utility/UUID.h +++ b/lldb/include/lldb/Utility/UUID.h @@ -12,8 +12,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <string> namespace lldb_private { diff --git a/lldb/include/lldb/Utility/UserID.h b/lldb/include/lldb/Utility/UserID.h index 9fc6985a5a99..19e0052fc51c 100644 --- a/lldb/include/lldb/Utility/UserID.h +++ b/lldb/include/lldb/Utility/UserID.h @@ -33,7 +33,7 @@ struct UserID { UserID(lldb::user_id_t uid = LLDB_INVALID_UID) : m_uid(uid) {} /// Destructor. - ~UserID() {} + ~UserID() = default; /// Clears the object state. /// diff --git a/lldb/include/lldb/Utility/VMRange.h b/lldb/include/lldb/Utility/VMRange.h index 4b01cd86da2c..095092c1a381 100644 --- a/lldb/include/lldb/Utility/VMRange.h +++ b/lldb/include/lldb/Utility/VMRange.h @@ -12,8 +12,8 @@ #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <vector> namespace lldb_private { @@ -26,13 +26,13 @@ public: typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; - VMRange() : m_base_addr(0), m_byte_size(0) {} + VMRange() = default; VMRange(lldb::addr_t start_addr, lldb::addr_t end_addr) : m_base_addr(start_addr), m_byte_size(end_addr > start_addr ? end_addr - start_addr : 0) {} - ~VMRange() {} + ~VMRange() = default; void Clear() { m_base_addr = 0; @@ -88,8 +88,8 @@ public: const VMRange &range); protected: - lldb::addr_t m_base_addr; - lldb::addr_t m_byte_size; + lldb::addr_t m_base_addr = 0; + lldb::addr_t m_byte_size = 0; }; bool operator==(const VMRange &lhs, const VMRange &rhs); diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h index 487cd0b01d5c..4bf01c3f86c6 100644 --- a/lldb/include/lldb/lldb-defines.h +++ b/lldb/include/lldb/lldb-defines.h @@ -82,6 +82,7 @@ #define LLDB_REGNUM_GENERIC_ARG8 \ 12 // The register that would contain pointer size or less argument 8 (if any) /// Invalid value definitions +#define LLDB_INVALID_STOP_ID 0 #define LLDB_INVALID_ADDRESS UINT64_MAX #define LLDB_INVALID_INDEX32 UINT32_MAX #define LLDB_INVALID_IVAR_OFFSET UINT32_MAX diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 8283b14cdee5..81f6be3eec7d 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -160,7 +160,7 @@ enum Format { eFormatBytes, eFormatBytesWithASCII, eFormatChar, - eFormatCharPrintable, ///< Only printable characters, space if not printable + eFormatCharPrintable, ///< Only printable characters, '.' if not printable eFormatComplex, ///< Floating point complex type eFormatComplexFloat = eFormatComplex, eFormatCString, ///< NULL terminated C strings @@ -247,7 +247,11 @@ enum StopReason { eStopReasonExec, ///< Program was re-exec'ed eStopReasonPlanComplete, eStopReasonThreadExiting, - eStopReasonInstrumentation + eStopReasonInstrumentation, + eStopReasonProcessorTrace, + eStopReasonFork, + eStopReasonVFork, + eStopReasonVForkDone, }; /// Command Return Status Types. @@ -597,6 +601,7 @@ enum CommandArgumentType { eArgTypeCommand, eArgTypeColumnNum, eArgTypeModuleUUID, + eArgTypeSaveCoreStyle, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; @@ -954,6 +959,25 @@ enum ExpressionEvaluationPhase { eExpressionEvaluationComplete }; +/// Architecture-agnostic categorization of instructions for traversing the +/// control flow of a trace. +/// +/// A single instruction can match one or more of these categories. +FLAGS_ENUM(TraceInstructionControlFlowType){ + /// Any instruction. + eTraceInstructionControlFlowTypeInstruction = (1u << 1), + /// A conditional or unconditional branch/jump. + eTraceInstructionControlFlowTypeBranch = (1u << 2), + /// A conditional or unconditional branch/jump that changed + /// the control flow of the program. + eTraceInstructionControlFlowTypeTakenBranch = (1u << 3), + /// A call to a function. + eTraceInstructionControlFlowTypeCall = (1u << 4), + /// A return from a function. + eTraceInstructionControlFlowTypeReturn = (1u << 5)}; + +LLDB_MARK_AS_BITMASK_ENUM(TraceInstructionControlFlowType) + /// Watchpoint Kind. /// /// Indicates what types of events cause the watchpoint to fire. Used by Native @@ -1107,6 +1131,14 @@ enum CommandInterpreterResult { /// Stopped because quit was requested. eCommandInterpreterResultQuitRequested, }; + +// Style of core file to create when calling SaveCore. +enum SaveCoreStyle { + eSaveCoreUnspecified = 0, + eSaveCoreFull = 1, + eSaveCoreDirtyOnly = 2, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index a297a928a3f4..ad5298151e4a 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -174,6 +174,7 @@ class RichManglingContext; class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; +class ScriptedProcessInterface; class ScriptedSyntheticChildren; class SearchFilter; class Section; @@ -226,10 +227,10 @@ class ThreadPlanStepRange; class ThreadPlanStepThrough; class ThreadPlanTracer; class ThreadSpec; -class ThreadTrace; +class ThreadPostMortemTrace; class Trace; -class TraceSessionFileParser; -class TraceOptions; +class TraceCursor; +class TraceExporter; class Type; class TypeAndOrName; class TypeCategoryImpl; @@ -341,6 +342,7 @@ typedef std::shared_ptr<lldb_private::Listener> ListenerSP; typedef std::weak_ptr<lldb_private::Listener> ListenerWP; typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP; typedef std::unique_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoUP; +typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP; typedef std::shared_ptr<lldb_private::Module> ModuleSP; typedef std::weak_ptr<lldb_private::Module> ModuleWP; typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP; @@ -391,6 +393,8 @@ typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP; typedef std::shared_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterSP; typedef std::unique_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterUP; +typedef std::unique_ptr<lldb_private::ScriptedProcessInterface> + ScriptedProcessInterfaceUP; typedef std::shared_ptr<lldb_private::Section> SectionSP; typedef std::unique_ptr<lldb_private::SectionList> SectionListUP; typedef std::weak_ptr<lldb_private::Section> SectionWP; @@ -433,10 +437,13 @@ typedef std::shared_ptr<lldb_private::Thread> ThreadSP; typedef std::weak_ptr<lldb_private::Thread> ThreadWP; typedef std::shared_ptr<lldb_private::ThreadCollection> ThreadCollectionSP; typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP; +typedef std::shared_ptr<lldb_private::ThreadPostMortemTrace> + ThreadPostMortemTraceSP; typedef std::weak_ptr<lldb_private::ThreadPlan> ThreadPlanWP; typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP; typedef std::shared_ptr<lldb_private::Trace> TraceSP; -typedef std::shared_ptr<lldb_private::TraceOptions> TraceOptionsSP; +typedef std::unique_ptr<lldb_private::TraceExporter> TraceExporterUP; +typedef std::unique_ptr<lldb_private::TraceCursor> TraceCursorUP; typedef std::shared_ptr<lldb_private::Type> TypeSP; typedef std::weak_ptr<lldb_private::Type> TypeWP; typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index df33f8af0e14..2ed083ec8ae9 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -54,7 +54,9 @@ typedef ObjectFile *(*ObjectFileCreateMemoryInstance)( const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset); typedef bool (*ObjectFileSaveCore)(const lldb::ProcessSP &process_sp, - const FileSpec &outfile, Status &error); + const FileSpec &outfile, + lldb::SaveCoreStyle &core_style, + Status &error); typedef EmulateInstruction *(*EmulateInstructionCreateInstance)( const ArchSpec &arch, InstructionType inst_type); typedef OperatingSystem *(*OperatingSystemCreateInstance)(Process *process, @@ -111,12 +113,17 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error, const char *repl_options); typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); -typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstance)( +/// Trace +/// \{ +typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)( const llvm::json::Value &trace_session_file, llvm::StringRef session_file_dir, lldb_private::Debugger &debugger); -typedef lldb::CommandObjectSP (*TraceGetStartCommand)( +typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForLiveProcess)( + Process &process); +typedef llvm::Expected<lldb::TraceExporterUP> (*TraceExporterCreateInstance)(); +typedef lldb::CommandObjectSP (*ThreadTraceExportCommandCreator)( CommandInterpreter &interpreter); - +/// \} } // namespace lldb_private #endif // #if defined(__cplusplus) diff --git a/lldb/include/lldb/lldb-private-types.h b/lldb/include/lldb/lldb-private-types.h index c7e652650da7..73d618d7069c 100644 --- a/lldb/include/lldb/lldb-private-types.h +++ b/lldb/include/lldb/lldb-private-types.h @@ -100,7 +100,7 @@ struct OptionEnumValueElement { using OptionEnumValues = llvm::ArrayRef<OptionEnumValueElement>; struct OptionValidator { - virtual ~OptionValidator() {} + virtual ~OptionValidator() = default; virtual bool IsValid(Platform &platform, const ExecutionContext &target) const = 0; virtual const char *ShortConditionString() const = 0; diff --git a/lldb/include/lldb/lldb-types.h b/lldb/include/lldb/lldb-types.h index c3e2f07acc45..976da35b11dd 100644 --- a/lldb/include/lldb/lldb-types.h +++ b/lldb/include/lldb/lldb-types.h @@ -12,7 +12,7 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include <stdint.h> +#include <cstdint> // All host systems must define: // lldb::thread_t The native thread type for spawned threads on the |