diff options
Diffstat (limited to 'include')
169 files changed, 5783 insertions, 1842 deletions
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h index b9c3198b73e5..4026b2b61ba8 100644 --- a/include/lldb/API/LLDB.h +++ b/include/lldb/API/LLDB.h @@ -29,6 +29,7 @@ #include "lldb/API/SBDeclaration.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" +#include "lldb/API/SBExecutionContext.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" diff --git a/include/lldb/API/SBAddress.h b/include/lldb/API/SBAddress.h index 58a7d2bfb1da..c2d07b6e9bcc 100644 --- a/include/lldb/API/SBAddress.h +++ b/include/lldb/API/SBAddress.h @@ -117,6 +117,7 @@ protected: friend class SBSymbolContext; friend class SBTarget; friend class SBThread; + friend class SBThreadPlan; friend class SBValue; friend class SBQueueItem; diff --git a/include/lldb/API/SBBreakpoint.h b/include/lldb/API/SBBreakpoint.h index 86d49c29a821..20a97a1fb5a0 100644 --- a/include/lldb/API/SBBreakpoint.h +++ b/include/lldb/API/SBBreakpoint.h @@ -123,6 +123,18 @@ public: SBError SetScriptCallbackBody (const char *script_body_text); + + bool + AddName (const char *new_name); + + void + RemoveName (const char *name_to_remove); + + bool + MatchesName (const char *name); + + void + GetNames (SBStringList &names); size_t GetNumResolvedLocations() const; diff --git a/include/lldb/API/SBCommandInterpreter.h b/include/lldb/API/SBCommandInterpreter.h index 184a6b473126..947e39164140 100644 --- a/include/lldb/API/SBCommandInterpreter.h +++ b/include/lldb/API/SBCommandInterpreter.h @@ -15,6 +15,61 @@ namespace lldb { +class SBCommandInterpreterRunOptions +{ +friend class SBDebugger; +friend class SBCommandInterpreter; + +public: + SBCommandInterpreterRunOptions(); + ~SBCommandInterpreterRunOptions(); + + bool + GetStopOnContinue () const; + + void + SetStopOnContinue (bool); + + bool + GetStopOnError () const; + + void + SetStopOnError (bool); + + bool + GetStopOnCrash () const; + + void + SetStopOnCrash (bool); + + bool + GetEchoCommands () const; + + void + SetEchoCommands (bool); + + bool + GetPrintResults () const; + + void + SetPrintResults (bool); + + bool + GetAddToHistory () const; + + void + SetAddToHistory (bool); +private: + lldb_private::CommandInterpreterRunOptions * + get () const; + + lldb_private::CommandInterpreterRunOptions & + ref () const; + + // This is set in the constructor and will always be valid. + mutable std::unique_ptr<lldb_private::CommandInterpreterRunOptions> m_opaque_up; +}; + class SBCommandInterpreter { public: @@ -85,6 +140,15 @@ public: lldb::ReturnStatus HandleCommand (const char *command_line, lldb::SBCommandReturnObject &result, bool add_to_history = false); + lldb::ReturnStatus + HandleCommand (const char *command_line, SBExecutionContext &exe_ctx, SBCommandReturnObject &result, bool add_to_history = false); + + void + HandleCommandsFromFile (lldb::SBFileSpec &file, + lldb::SBExecutionContext &override_context, + lldb::SBCommandInterpreterRunOptions &options, + lldb::SBCommandReturnObject result); + // The pointer based interface is not useful in SWIG, since the cursor & last_char arguments are string pointers INTO current_line // and you can't do that in a scripting language interface in general... @@ -175,9 +239,9 @@ class SBCommandPluginInterface { public: virtual bool - DoExecute (lldb::SBDebugger debugger, - char** command, - lldb::SBCommandReturnObject &result) + DoExecute (lldb::SBDebugger /*debugger*/, + char** /*command*/, + lldb::SBCommandReturnObject & /*result*/) { return false; } diff --git a/include/lldb/API/SBCompileUnit.h b/include/lldb/API/SBCompileUnit.h index 95af3d4722ce..e2c216445d94 100644 --- a/include/lldb/API/SBCompileUnit.h +++ b/include/lldb/API/SBCompileUnit.h @@ -78,6 +78,9 @@ public: lldb::SBTypeList GetTypes (uint32_t type_mask = lldb::eTypeClassAny); + lldb::LanguageType + GetLanguage (); + bool operator == (const lldb::SBCompileUnit &rhs) const; diff --git a/include/lldb/API/SBData.h b/include/lldb/API/SBData.h index 10c002247271..e7656a52d9c2 100644 --- a/include/lldb/API/SBData.h +++ b/include/lldb/API/SBData.h @@ -169,6 +169,7 @@ private: friend class SBInstruction; friend class SBProcess; friend class SBSection; + friend class SBTarget; friend class SBValue; lldb::DataExtractorSP m_opaque_sp; diff --git a/include/lldb/API/SBDebugger.h b/include/lldb/API/SBDebugger.h index 2386ffc968de..6e43e12f7b16 100644 --- a/include/lldb/API/SBDebugger.h +++ b/include/lldb/API/SBDebugger.h @@ -27,6 +27,7 @@ public: void SetIsDone(bool); bool IsActive() const; }; + class SBDebugger { public: @@ -321,6 +322,13 @@ public: RunCommandInterpreter (bool auto_handle_events, bool spawn_thread); + void + RunCommandInterpreter (bool auto_handle_events, + bool spawn_thread, + SBCommandInterpreterRunOptions &options, + int &num_errors, + bool &quit_requested, + bool &stopped_for_crash); private: friend class SBCommandInterpreter; diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index 30ea0dfda56e..b59b79580910 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -35,6 +35,7 @@ class LLDB_API SBBreakpointLocation; class LLDB_API SBBroadcaster; class LLDB_API SBCommand; class LLDB_API SBCommandInterpreter; +class LLDB_API SBCommandInterpreterRunOptions; class LLDB_API SBCommandPluginInterface; class LLDB_API SBCommandReturnObject; class LLDB_API SBCommunication; @@ -45,6 +46,7 @@ class LLDB_API SBDeclaration; class LLDB_API SBError; class LLDB_API SBEvent; class LLDB_API SBEventList; +class LLDB_API SBExecutionContext; class LLDB_API SBExpressionOptions; class LLDB_API SBFileSpec; class LLDB_API SBFileSpecList; @@ -70,14 +72,18 @@ class LLDB_API SBSymbolContext; class LLDB_API SBSymbolContextList; class LLDB_API SBTarget; class LLDB_API SBThread; +class LLDB_API SBThreadCollection; +class LLDB_API SBThreadPlan; class LLDB_API SBType; class LLDB_API SBTypeCategory; class LLDB_API SBTypeEnumMember; class LLDB_API SBTypeEnumMemberList; class LLDB_API SBTypeFilter; class LLDB_API SBTypeFormat; +class LLDB_API SBTypeMemberFunction; class LLDB_API SBTypeNameSpecifier; class LLDB_API SBTypeSummary; +class LLDB_API SBTypeSummaryOptions; #ifndef LLDB_DISABLE_PYTHON class LLDB_API SBTypeSynthetic; #endif diff --git a/include/lldb/API/SBEvent.h b/include/lldb/API/SBEvent.h index 6cb975a1ff7b..1706d0c009b9 100644 --- a/include/lldb/API/SBEvent.h +++ b/include/lldb/API/SBEvent.h @@ -30,6 +30,10 @@ public: // Make an event that contains a C string. SBEvent (uint32_t event, const char *cstr, uint32_t cstr_len); + SBEvent (lldb::EventSP &event_sp); + + SBEvent (lldb_private::Event *event_sp); + ~SBEvent(); const SBEvent & @@ -77,8 +81,6 @@ protected: friend class SBThread; friend class SBWatchpoint; - SBEvent (lldb::EventSP &event_sp); - lldb::EventSP & GetSP () const; diff --git a/include/lldb/API/SBExecutionContext.h b/include/lldb/API/SBExecutionContext.h new file mode 100644 index 000000000000..9d889139f5cb --- /dev/null +++ b/include/lldb/API/SBExecutionContext.h @@ -0,0 +1,74 @@ +//===-- SBExecutionContext.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBExecutionContext_h_ +#define LLDB_SBExecutionContext_h_ + +#include "lldb/API/SBDefines.h" + +#include <stdio.h> +#include <vector> + + +namespace lldb { + +class SBExecutionContext +{ +friend class SBCommandInterpreter; + +public: + SBExecutionContext(); + + SBExecutionContext (const lldb::SBExecutionContext &rhs); + + SBExecutionContext (lldb::ExecutionContextRefSP exe_ctx_ref_sp); + + SBExecutionContext (const lldb::SBTarget &target); + + SBExecutionContext (const lldb::SBProcess &process); + + SBExecutionContext (lldb::SBThread thread); // can't be a const& because SBThread::get() isn't itself a const function + + SBExecutionContext (const lldb::SBFrame &frame); + + ~SBExecutionContext(); + + const SBExecutionContext & + operator = (const lldb::SBExecutionContext &rhs); + + SBTarget + GetTarget () const; + + SBProcess + GetProcess () const; + + SBThread + GetThread () const; + + SBFrame + GetFrame () const; + +protected: + ExecutionContextRefSP & + GetSP () const; + + void + reset (lldb::ExecutionContextRefSP &event_sp); + + lldb_private::ExecutionContextRef * + get () const; + +private: + + mutable lldb::ExecutionContextRefSP m_exe_ctx_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBExecutionContext_h_ diff --git a/include/lldb/API/SBFileSpec.h b/include/lldb/API/SBFileSpec.h index d262b98d0fd7..1eee3d10367c 100644 --- a/include/lldb/API/SBFileSpec.h +++ b/include/lldb/API/SBFileSpec.h @@ -63,6 +63,7 @@ public: private: friend class SBAttachInfo; friend class SBBlock; + friend class SBCommandInterpreter; friend class SBCompileUnit; friend class SBDeclaration; friend class SBFileSpecList; diff --git a/include/lldb/API/SBFrame.h b/include/lldb/API/SBFrame.h index f6b84ab1ddac..b93e36afecdf 100644 --- a/include/lldb/API/SBFrame.h +++ b/include/lldb/API/SBFrame.h @@ -198,21 +198,6 @@ public: lldb::SBValue FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic); - /// Find and watch a variable using the frame as the scope. - /// It returns an SBValue, similar to FindValue() method, if find-and-watch - /// operation succeeds. Otherwise, an invalid SBValue is returned. - /// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch. - lldb::SBValue - WatchValue (const char *name, ValueType value_type, uint32_t watch_type); - - /// Find and watch the location pointed to by a variable using the frame as - /// the scope. - /// It returns an SBValue, similar to FindValue() method, if find-and-watch - /// operation succeeds. Otherwise, an invalid SBValue is returned. - /// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch. - lldb::SBValue - WatchLocation (const char *name, ValueType value_type, uint32_t watch_type, size_t size); - bool GetDescription (lldb::SBStream &description); @@ -221,6 +206,7 @@ public: protected: friend class SBBlock; + friend class SBExecutionContext; friend class SBInstruction; friend class SBThread; friend class SBValue; diff --git a/include/lldb/API/SBFunction.h b/include/lldb/API/SBFunction.h index 49a3847efbec..1b0d53d11736 100644 --- a/include/lldb/API/SBFunction.h +++ b/include/lldb/API/SBFunction.h @@ -58,6 +58,9 @@ public: lldb::SBBlock GetBlock (); + + lldb::LanguageType + GetLanguage (); bool operator == (const lldb::SBFunction &rhs) const; diff --git a/include/lldb/API/SBListener.h b/include/lldb/API/SBListener.h index 4a11ec1072f1..58a8fe9a55b7 100644 --- a/include/lldb/API/SBListener.h +++ b/include/lldb/API/SBListener.h @@ -99,13 +99,23 @@ public: HandleBroadcastEvent (const lldb::SBEvent &event); protected: + friend class SBAttachInfo; friend class SBBroadcaster; friend class SBCommandInterpreter; friend class SBDebugger; + friend class SBLaunchInfo; friend class SBTarget; SBListener (lldb_private::Listener &listener); + SBListener (const lldb::ListenerSP &listener_sp); + + lldb::ListenerSP + GetSP () + { + return m_opaque_sp; + } + private: lldb_private::Listener * diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index 4b59462ca3f1..3d6e49c4821d 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -316,6 +316,12 @@ public: //------------------------------------------------------------------ const char * GetExtendedBacktraceTypeAtIndex (uint32_t idx); + + lldb::SBThreadCollection + GetHistoryThreads (addr_t addr); + + bool + IsInstrumentationRuntimePresent(InstrumentationRuntimeType type); protected: friend class SBAddress; @@ -323,6 +329,7 @@ protected: friend class SBBreakpointLocation; friend class SBCommandInterpreter; friend class SBDebugger; + friend class SBExecutionContext; friend class SBFunction; friend class SBModule; friend class SBTarget; diff --git a/include/lldb/API/SBSection.h b/include/lldb/API/SBSection.h index 3386484f6496..5a49049502fd 100644 --- a/include/lldb/API/SBSection.h +++ b/include/lldb/API/SBSection.h @@ -71,6 +71,18 @@ public: SectionType GetSectionType (); + //------------------------------------------------------------------ + /// Return the size of a target's byte represented by this section + /// in numbers of host bytes. Note that certain architectures have + /// varying minimum addressable unit (i.e. byte) size for their + /// CODE or DATA buses. + /// + /// @return + /// The number of host (8-bit) bytes needed to hold a target byte + //------------------------------------------------------------------ + uint32_t + GetTargetByteSize (); + bool operator == (const lldb::SBSection &rhs); diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h index fb69c12f0a91..cd33bfda32ba 100644 --- a/include/lldb/API/SBStream.h +++ b/include/lldb/API/SBStream.h @@ -85,8 +85,10 @@ protected: friend class SBSymbolContextList; friend class SBTarget; friend class SBThread; + friend class SBThreadPlan; friend class SBType; friend class SBTypeEnumMember; + friend class SBTypeMemberFunction; friend class SBTypeMember; friend class SBValue; friend class SBWatchpoint; diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index 370d40d0454a..a628467caa43 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -22,6 +22,8 @@ namespace lldb { +class SBPlatform; + class SBLaunchInfo { public: @@ -49,7 +51,7 @@ public: SBFileSpec GetExecutableFile (); - + //---------------------------------------------------------------------- /// Set the executable file that will be used to launch the process and /// optionally set it as the first argument in the argument vector. @@ -75,7 +77,29 @@ public: //---------------------------------------------------------------------- void SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg); - + + + //---------------------------------------------------------------------- + /// Get the listener that will be used to receive process events. + /// + /// If no listener has been set via a call to + /// SBLaunchInfo::SetListener(), then an invalid SBListener will be + /// returned (SBListener::IsValid() will return false). If a listener + /// has been set, then the valid listener object will be returned. + //---------------------------------------------------------------------- + SBListener + GetListener (); + + //---------------------------------------------------------------------- + /// Set the listener that will be used to receive process events. + /// + /// By default the SBDebugger, which has a listener, that the SBTarget + /// belongs to will listen for the process events. Calling this function + /// allows a different listener to be used to listen for process events. + //---------------------------------------------------------------------- + void + SetListener (SBListener &listener); + uint32_t GetNumArguments (); @@ -256,7 +280,28 @@ public: bool ParentProcessIDIsValid(); - + + //---------------------------------------------------------------------- + /// Get the listener that will be used to receive process events. + /// + /// If no listener has been set via a call to + /// SBLaunchInfo::SetListener(), then an invalid SBListener will be + /// returned (SBListener::IsValid() will return false). If a listener + /// has been set, then the valid listener object will be returned. + //---------------------------------------------------------------------- + SBListener + GetListener (); + + //---------------------------------------------------------------------- + /// Set the listener that will be used to receive process events. + /// + /// By default the SBDebugger, which has a listener, that the SBTarget + /// belongs to will listen for the process events. Calling this function + /// allows a different listener to be used to listen for process events. + //---------------------------------------------------------------------- + void + SetListener (SBListener &listener); + protected: friend class SBTarget; @@ -309,6 +354,18 @@ public: GetProcess (); //------------------------------------------------------------------ + /// Return the platform object associated with the target. + /// + /// After return, the platform object should be checked for + /// validity. + /// + /// @return + /// A platform object. + //------------------------------------------------------------------ + lldb::SBPlatform + GetPlatform (); + + //------------------------------------------------------------------ /// Install any binaries that need to be installed. /// /// This function does nothing when debugging on the host system. @@ -564,6 +621,26 @@ public: GetTriple (); //------------------------------------------------------------------ + /// Architecture data byte width accessor + /// + /// @return + /// The size in 8-bit (host) bytes of a minimum addressable + /// unit from the Architecture's data bus + //------------------------------------------------------------------ + uint32_t + GetDataByteSize (); + + //------------------------------------------------------------------ + /// Architecture code byte width accessor + /// + /// @return + /// The size in 8-bit (host) bytes of a minimum addressable + /// unit from the Architecture's code bus + //------------------------------------------------------------------ + uint32_t + GetCodeByteSize (); + + //------------------------------------------------------------------ /// Set the base load address for a module section. /// /// @param[in] section @@ -683,11 +760,62 @@ public: //------------------------------------------------------------------ lldb::SBValue FindFirstGlobalVariable (const char* name); + + //------------------------------------------------------------------ + /// Find global and static variables by pattern. + /// + /// @param[in] name + /// The pattern to search for global or static variables + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a max_matches. + /// + /// @param[in] matchtype + /// The match type to use. + /// + /// @return + /// A list of matched variables in an SBValueList. + //------------------------------------------------------------------ + lldb::SBValueList + FindGlobalVariables(const char *name, + uint32_t max_matches, + MatchType matchtype); + //------------------------------------------------------------------ + /// Find global functions by their name with pattern matching. + /// + /// @param[in] name + /// The pattern to search for global or static variables + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a max_matches. + /// + /// @param[in] matchtype + /// The match type to use. + /// + /// @return + /// A list of matched variables in an SBValueList. + //------------------------------------------------------------------ + lldb::SBSymbolContextList + FindGlobalFunctions(const char *name, + uint32_t max_matches, + MatchType matchtype); + void Clear (); //------------------------------------------------------------------ + /// Resolve a current file address into a section offset address. + /// + /// @param[in] file_addr + /// + /// @return + /// An SBAddress which will be valid if... + //------------------------------------------------------------------ + lldb::SBAddress + ResolveFileAddress (lldb::addr_t file_addr); + + //------------------------------------------------------------------ /// Resolve a current load address into a section offset address. /// /// @param[in] vm_addr @@ -732,6 +860,31 @@ public: ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope); + //------------------------------------------------------------------ + /// Read target memory. If a target process is running then memory + /// is read from here. Otherwise the memory is read from the object + /// files. For a target whose bytes are sized as a multiple of host + /// bytes, the data read back will preserve the target's byte order. + /// + /// @param[in] addr + /// A target address to read from. + /// + /// @param[out] buf + /// The buffer to read memory into. + /// + /// @param[in] size + /// The maximum number of host bytes to read in the buffer passed + /// into this call + /// + /// @param[out] error + /// Error information is written here if the memory read fails. + /// + /// @return + /// The amount of data read in host bytes. + //------------------------------------------------------------------ + size_t + ReadMemory (const SBAddress addr, void *buf, size_t size, lldb::SBError &error); + lldb::SBBreakpoint BreakpointCreateByLocation (const char *file, uint32_t line); @@ -845,6 +998,12 @@ public: lldb::SBValue CreateValueFromAddress (const char *name, lldb::SBAddress addr, lldb::SBType type); + + lldb::SBValue + CreateValueFromData (const char *name, lldb::SBData data, lldb::SBType type); + + lldb::SBValue + CreateValueFromExpression (const char *name, const char* expr); SBSourceManager GetSourceManager(); @@ -893,6 +1052,7 @@ protected: friend class SBAddress; friend class SBBlock; friend class SBDebugger; + friend class SBExecutionContext; friend class SBFunction; friend class SBInstruction; friend class SBModule; diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h index 07a43ebee7ce..db15f651f2d5 100644 --- a/include/lldb/API/SBThread.h +++ b/include/lldb/API/SBThread.h @@ -78,7 +78,10 @@ public: //-------------------------------------------------------------------------- uint64_t GetStopReasonDataAtIndex(uint32_t idx); - + + bool + GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream); + size_t GetStopDescription (char *dst, size_t dst_len); @@ -127,6 +130,9 @@ public: uint32_t line); SBError + StepUsingScriptedThreadPlan (const char *script_class_name); + + SBError JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line); void @@ -216,9 +222,19 @@ public: bool SafeToCallFunctions (); +#ifndef SWIG + lldb_private::Thread * + operator->(); + + lldb_private::Thread * + get(); + +#endif + protected: friend class SBBreakpoint; friend class SBBreakpointLocation; + friend class SBExecutionContext; friend class SBFrame; friend class SBProcess; friend class SBDebugger; diff --git a/include/lldb/API/SBThreadCollection.h b/include/lldb/API/SBThreadCollection.h new file mode 100644 index 000000000000..b13cbd938e28 --- /dev/null +++ b/include/lldb/API/SBThreadCollection.h @@ -0,0 +1,68 @@ +//===-- SBThreadCollection.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBThreadCollection_h_ +#define LLDB_SBThreadCollection_h_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class SBThreadCollection +{ +public: + + SBThreadCollection (); + + SBThreadCollection (const SBThreadCollection &rhs); + + const SBThreadCollection & + operator = (const SBThreadCollection &rhs); + + ~SBThreadCollection (); + + bool + IsValid () const; + + size_t + GetSize (); + + lldb::SBThread + GetThreadAtIndex (size_t idx); + +protected: + + // Mimic shared pointer... + lldb_private::ThreadCollection * + get() const; + + lldb_private::ThreadCollection * + operator->() const; + + lldb::ThreadCollectionSP & + operator*(); + + const lldb::ThreadCollectionSP & + operator*() const; + + SBThreadCollection (const lldb::ThreadCollectionSP &threads); + + void + SetOpaque (const lldb::ThreadCollectionSP &threads); + +private: + friend class SBProcess; + + lldb::ThreadCollectionSP m_opaque_sp; +}; + + +} // namespace lldb + +#endif // LLDB_SBThreadCollection_h_ diff --git a/include/lldb/API/SBThreadPlan.h b/include/lldb/API/SBThreadPlan.h new file mode 100644 index 000000000000..e53942d65fa8 --- /dev/null +++ b/include/lldb/API/SBThreadPlan.h @@ -0,0 +1,129 @@ +//===-- SBThread.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBThreadPlan_h_ +#define LLDB_SBThreadPlan_h_ + +#include "lldb/API/SBDefines.h" + +#include <stdio.h> + +namespace lldb { + +class SBThreadPlan +{ + +friend class lldb_private::ThreadPlan; + +public: + SBThreadPlan (); + + SBThreadPlan (const lldb::SBThreadPlan &threadPlan); + + SBThreadPlan (const lldb::ThreadPlanSP& lldb_object_sp); + + SBThreadPlan (lldb::SBThread &thread, const char *class_name); + + ~SBThreadPlan (); + + bool + IsValid() const; + + void + Clear (); + + lldb::StopReason + GetStopReason(); + + /// Get the number of words associated with the stop reason. + /// See also GetStopReasonDataAtIndex(). + size_t + GetStopReasonDataCount(); + + //-------------------------------------------------------------------------- + /// Get information associated with a stop reason. + /// + /// Breakpoint stop reasons will have data that consists of pairs of + /// breakpoint IDs followed by the breakpoint location IDs (they always come + /// in pairs). + /// + /// Stop Reason Count Data Type + /// ======================== ===== ========================================= + /// eStopReasonNone 0 + /// eStopReasonTrace 0 + /// eStopReasonBreakpoint N duple: {breakpoint id, location id} + /// eStopReasonWatchpoint 1 watchpoint id + /// eStopReasonSignal 1 unix signal number + /// eStopReasonException N exception data + /// eStopReasonExec 0 + /// eStopReasonPlanComplete 0 + //-------------------------------------------------------------------------- + uint64_t + GetStopReasonDataAtIndex(uint32_t idx); + + SBThread + GetThread () const; + + const lldb::SBThreadPlan & + operator = (const lldb::SBThreadPlan &rhs); + + bool + GetDescription (lldb::SBStream &description) const; + + void + SetPlanComplete (bool success); + + bool + IsPlanComplete(); + + bool + IsValid(); + + // This section allows an SBThreadPlan to push another of the common types of plans... + SBThreadPlan + QueueThreadPlanForStepOverRange (SBAddress &start_address, + lldb::addr_t range_size); + + SBThreadPlan + QueueThreadPlanForStepInRange (SBAddress &start_address, + lldb::addr_t range_size); + + SBThreadPlan + QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn = false); + + SBThreadPlan + QueueThreadPlanForRunToAddress (SBAddress address); + +#ifndef SWIG + lldb_private::ThreadPlan * + get(); +#endif + +protected: + friend class SBBreakpoint; + friend class SBBreakpointLocation; + friend class SBFrame; + friend class SBProcess; + friend class SBDebugger; + friend class SBValue; + friend class lldb_private::QueueImpl; + friend class SBQueueItem; + +#ifndef SWIG + void + SetThreadPlan (const lldb::ThreadPlanSP& lldb_object_sp); +#endif + +private: + lldb::ThreadPlanSP m_opaque_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBThreadPlan_h_ diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h index 363aa59e35aa..303ddff6dc09 100644 --- a/include/lldb/API/SBType.h +++ b/include/lldb/API/SBType.h @@ -67,6 +67,59 @@ protected: std::unique_ptr<lldb_private::TypeMemberImpl> m_opaque_ap; }; + +class SBTypeMemberFunction +{ +public: + SBTypeMemberFunction (); + + SBTypeMemberFunction (const lldb::SBTypeMemberFunction& rhs); + + ~SBTypeMemberFunction(); + + lldb::SBTypeMemberFunction& + operator = (const lldb::SBTypeMemberFunction& rhs); + + bool + IsValid() const; + + const char * + GetName (); + + lldb::SBType + GetType (); + + lldb::SBType + GetReturnType (); + + uint32_t + GetNumberOfArguments (); + + lldb::SBType + GetArgumentTypeAtIndex (uint32_t); + + lldb::MemberFunctionKind + GetKind(); + + bool + GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level); + +protected: + friend class SBType; + + void + reset (lldb_private::TypeMemberFunctionImpl *); + + lldb_private::TypeMemberFunctionImpl & + ref (); + + const lldb_private::TypeMemberFunctionImpl & + ref () const; + + lldb::TypeMemberFunctionImplSP m_opaque_sp; +}; + class SBType { @@ -96,6 +149,12 @@ public: bool IsPolymorphicClass (); + bool + IsArrayType (); + + bool + IsTypedefType (); + lldb::SBType GetPointerType(); @@ -113,6 +172,9 @@ public: lldb::SBType GetUnqualifiedType(); + + lldb::SBType + GetArrayElementType (); lldb::SBType GetCanonicalType(); @@ -160,6 +222,12 @@ public: lldb::SBTypeList GetFunctionArgumentTypes (); + + uint32_t + GetNumberOfMemberFunctions (); + + lldb::SBTypeMemberFunction + GetMemberFunctionAtIndex (uint32_t idx); const char* GetName(); @@ -172,6 +240,9 @@ public: bool IsTypeComplete (); + + uint32_t + GetTypeFlags (); bool GetDescription (lldb::SBStream &description, @@ -209,6 +280,7 @@ protected: friend class SBTypeEnumMemberList; friend class SBTypeNameSpecifier; friend class SBTypeMember; + friend class SBTypeMemberFunction; friend class SBTypeList; friend class SBValue; diff --git a/include/lldb/API/SBTypeSummary.h b/include/lldb/API/SBTypeSummary.h index 67a8607511cc..220451e6d70b 100644 --- a/include/lldb/API/SBTypeSummary.h +++ b/include/lldb/API/SBTypeSummary.h @@ -15,6 +15,56 @@ #ifndef LLDB_DISABLE_PYTHON namespace lldb { + class SBTypeSummaryOptions + { + public: + SBTypeSummaryOptions(); + + SBTypeSummaryOptions (const lldb::SBTypeSummaryOptions &rhs); + + SBTypeSummaryOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr); + + ~SBTypeSummaryOptions (); + + bool + IsValid (); + + lldb::LanguageType + GetLanguage (); + + lldb::TypeSummaryCapping + GetCapping (); + + void + SetLanguage (lldb::LanguageType); + + void + SetCapping (lldb::TypeSummaryCapping); + + protected: + friend class SBValue; + + lldb_private::TypeSummaryOptions * + operator->(); + + const lldb_private::TypeSummaryOptions * + operator->() const; + + lldb_private::TypeSummaryOptions * + get (); + + lldb_private::TypeSummaryOptions & + ref(); + + const lldb_private::TypeSummaryOptions & + ref() const; + + void + SetOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr); + + private: + std::unique_ptr<lldb_private::TypeSummaryOptions> m_opaque_ap; + }; class SBTypeSummary { diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h index 93b869ba9c5c..bedac4ef1d2d 100644 --- a/include/lldb/API/SBValue.h +++ b/include/lldb/API/SBValue.h @@ -91,8 +91,15 @@ public: GetSummary (); const char * + GetSummary (lldb::SBStream& stream, + lldb::SBTypeSummaryOptions& options); + + const char * GetObjectDescription (); + const char * + GetTypeValidatorResult (); + lldb::SBValue GetDynamicValue (lldb::DynamicValueType use_dynamic); @@ -152,6 +159,7 @@ public: lldb::SBValue CreateChildAtOffset (const char *name, uint32_t offset, lldb::SBType type); + // Deprecated - use the expression evaluator to perform type casting lldb::SBValue Cast (lldb::SBType type); @@ -345,6 +353,9 @@ public: lldb::SBType GetType(); + + lldb::SBValue + Persist (); bool GetDescription (lldb::SBStream &description); diff --git a/include/lldb/API/SBValueList.h b/include/lldb/API/SBValueList.h index b9a6aedea3cb..812fdac91c11 100644 --- a/include/lldb/API/SBValueList.h +++ b/include/lldb/API/SBValueList.h @@ -43,6 +43,9 @@ public: lldb::SBValue GetValueAtIndex (uint32_t idx) const; + + lldb::SBValue + GetFirstValueByName (const char* name) const; lldb::SBValue FindValueObjectByUID (lldb::user_id_t uid); diff --git a/include/lldb/Breakpoint/Breakpoint.h b/include/lldb/Breakpoint/Breakpoint.h index 15693f86e382..61acc061aebc 100644 --- a/include/lldb/Breakpoint/Breakpoint.h +++ b/include/lldb/Breakpoint/Breakpoint.h @@ -12,8 +12,11 @@ // C Includes // C++ Includes +#include <unordered_set> + // Other libraries and framework includes // Project includes +#include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/BreakpointLocationList.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" @@ -203,14 +206,29 @@ public: /// Tell this breakpoint to scan a given module list and resolve any /// new locations that match the breakpoint's specifications. /// - /// @param[in] changed_modules + /// @param[in] module_list /// The list of modules to look in for new locations. + /// + /// @param[in] send_event + /// If \b true, send a breakpoint location added event for non-internal breakpoints. //------------------------------------------------------------------ void - ResolveBreakpointInModules (ModuleList &changed_modules); - + ResolveBreakpointInModules (ModuleList &module_list, bool send_event = true); //------------------------------------------------------------------ + /// Tell this breakpoint to scan a given module list and resolve any + /// new locations that match the breakpoint's specifications. + /// + /// @param[in] changed_modules + /// The list of modules to look in for new locations. + /// + /// @param[in] new_locations + /// Fills new_locations with the new locations that were made. + //------------------------------------------------------------------ + void + ResolveBreakpointInModules (ModuleList &module_list, BreakpointLocationCollection &new_locations); + + //------------------------------------------------------------------ /// Like ResolveBreakpointInModules, but allows for "unload" events, in /// which case we will remove any locations that are in modules that got /// unloaded. @@ -538,10 +556,19 @@ public: /// This breakpoint's Target. //------------------------------------------------------------------ Target & - GetTarget (); + GetTarget () + { + return m_target; + } const Target & - GetTarget () const; + GetTarget () const + { + return m_target; + } + + const lldb::TargetSP + GetTargetSP (); void GetResolverDescription (Stream *s); @@ -600,6 +627,44 @@ public: return m_hardware; } + lldb::BreakpointResolverSP + GetResolver() + { + return m_resolver_sp; + } + + lldb::SearchFilterSP + GetSearchFilter() + { + return m_filter_sp; + } + + bool + AddName (const char *new_name, Error &error); + + void + RemoveName (const char *name_to_remove) + { + if (name_to_remove) + m_name_list.erase(name_to_remove); + } + + bool + MatchesName (const char *name) + { + return m_name_list.find(name) != m_name_list.end(); + } + + void + GetNames (std::vector<std::string> &names) + { + names.clear(); + for (auto name : m_name_list) + { + names.push_back(name); + } + } + protected: friend class Target; //------------------------------------------------------------------ @@ -650,12 +715,18 @@ protected: IgnoreCountShouldStop (); private: + // This one should only be used by Target to copy breakpoints from target to target - primarily from the dummy + // target to prime new targets. + Breakpoint (Target &new_target, + Breakpoint &bp_to_copy_from); + //------------------------------------------------------------------ // For Breakpoint only //------------------------------------------------------------------ bool m_being_created; bool m_hardware; // If this breakpoint is required to use a hardware breakpoint Target &m_target; // The target that holds this breakpoint. + std::unordered_set<std::string> m_name_list; // If not empty, this is the name of this breakpoint (many breakpoints can share the same name.) lldb::SearchFilterSP m_filter_sp; // The filter that constrains the breakpoint's domain. lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines this breakpoint. BreakpointOptions m_options; // Settable breakpoint options diff --git a/include/lldb/Breakpoint/BreakpointID.h b/include/lldb/Breakpoint/BreakpointID.h index 9e352100b9e1..5ca09634ee09 100644 --- a/include/lldb/Breakpoint/BreakpointID.h +++ b/include/lldb/Breakpoint/BreakpointID.h @@ -93,6 +93,21 @@ public: //------------------------------------------------------------------ + /// Takes an input string and checks to see whether it is a breakpoint name. + /// If it is a mal-formed breakpoint name, error will be set to an appropriate + /// error string. + /// + /// @param[in] input + /// A string containing JUST the breakpoint description. + /// @param[out] error + /// If the name is a well-formed breakpoint name, set to success, otherwise set to an error. + /// @return + /// \b true if the name is a breakpoint name (as opposed to an ID or range) false otherwise. + //------------------------------------------------------------------ + static bool + StringIsBreakpointName (const char *name, Error &error); + + //------------------------------------------------------------------ /// Takes a breakpoint ID and the breakpoint location id and returns /// a string containing the canonical description for the breakpoint /// or breakpoint location. diff --git a/include/lldb/Breakpoint/BreakpointIDList.h b/include/lldb/Breakpoint/BreakpointIDList.h index c9fcef0a783c..c42787066617 100644 --- a/include/lldb/Breakpoint/BreakpointIDList.h +++ b/include/lldb/Breakpoint/BreakpointIDList.h @@ -68,7 +68,7 @@ public: StringContainsIDRangeExpression (const char *in_string, size_t *range_start_len, size_t *range_end_pos); static void - FindAndReplaceIDRanges (Args &old_args, Target *target, CommandReturnObject &result, Args &new_args); + FindAndReplaceIDRanges (Args &old_args, Target *target, bool allow_locations, CommandReturnObject &result, Args &new_args); private: BreakpointIDArray m_breakpoint_ids; diff --git a/include/lldb/Breakpoint/BreakpointList.h b/include/lldb/Breakpoint/BreakpointList.h index 27f80d0ffe09..f4837e1ce956 100644 --- a/include/lldb/Breakpoint/BreakpointList.h +++ b/include/lldb/Breakpoint/BreakpointList.h @@ -204,11 +204,25 @@ protected: bp_collection::const_iterator GetBreakpointIDConstIterator(lldb::break_id_t breakID) const; + Mutex & + GetMutex () const + { + return m_mutex; + } + mutable Mutex m_mutex; bp_collection m_breakpoints; // The breakpoint list, currently a list. lldb::break_id_t m_next_break_id; bool m_is_internal; +public: + typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter> BreakpointIterable; + BreakpointIterable + Breakpoints() + { + return BreakpointIterable(m_breakpoints, GetMutex()); + } + private: DISALLOW_COPY_AND_ASSIGN (BreakpointList); }; diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h index ac4c28bb6e5f..8d5ebce411df 100644 --- a/include/lldb/Breakpoint/BreakpointLocation.h +++ b/include/lldb/Breakpoint/BreakpointLocation.h @@ -52,7 +52,6 @@ class BreakpointLocation : public StoppointLocation { public: - ~BreakpointLocation (); //------------------------------------------------------------------ @@ -374,7 +373,21 @@ public: m_is_reexported = is_reexported; } + //------------------------------------------------------------------ + /// Returns whether the two breakpoint locations might represent "equivalent locations". + /// This is used when modules changed to determine if a Location in the old module might + /// be the "same as" the input location. + /// + /// @param[in] location + /// The location to compare against. + /// + /// @return + /// \b true or \b false as given in the description above. + //------------------------------------------------------------------ + bool EquivalentToLocation(BreakpointLocation &location); + protected: + friend class BreakpointSite; friend class BreakpointLocationList; friend class Process; @@ -396,8 +409,14 @@ protected: bool IgnoreCountShouldStop(); - + private: + void + SwapLocation (lldb::BreakpointLocationSP swap_from); + + void + BumpHitCount(); + //------------------------------------------------------------------ // Constructors and Destructors diff --git a/include/lldb/Breakpoint/BreakpointLocationCollection.h b/include/lldb/Breakpoint/BreakpointLocationCollection.h index 7f6a659323be..004f8395122b 100644 --- a/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -16,6 +16,7 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" +#include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -202,6 +203,14 @@ private: collection m_break_loc_collection; +public: + typedef AdaptedIterable<collection, lldb::BreakpointLocationSP, vector_adapter> BreakpointLocationCollectionIterable; + BreakpointLocationCollectionIterable + BreakpointLocations() + { + return BreakpointLocationCollectionIterable(m_break_loc_collection); + } + }; } // namespace lldb_private diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h index 0d8062eb644c..f67ef89ad705 100644 --- a/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/include/lldb/Breakpoint/BreakpointLocationList.h @@ -19,6 +19,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/Address.h" #include "lldb/Host/Mutex.h" +#include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -248,12 +249,18 @@ protected: AddLocation (const Address &addr, bool resolve_indirect_symbols, bool *new_location = NULL); + + void + SwapLocation (lldb::BreakpointLocationSP to_location_sp, lldb::BreakpointLocationSP from_location_sp); bool RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp); void RemoveInvalidLocations (const ArchSpec &arch); + + void + Compact(); typedef std::vector<lldb::BreakpointLocationSP> collection; typedef std::map<lldb_private::Address, @@ -266,6 +273,14 @@ protected: mutable Mutex m_mutex; lldb::break_id_t m_next_id; BreakpointLocationCollection *m_new_location_recorder; +public: + typedef AdaptedIterable<collection, lldb::BreakpointLocationSP, vector_adapter> BreakpointLocationIterable; + BreakpointLocationIterable + BreakpointLocations() + { + return BreakpointLocationIterable(m_locations); + } + }; } // namespace lldb_private diff --git a/include/lldb/Breakpoint/BreakpointResolver.h b/include/lldb/Breakpoint/BreakpointResolver.h index 184bdc950cbc..6ba53ea92f36 100644 --- a/include/lldb/Breakpoint/BreakpointResolver.h +++ b/include/lldb/Breakpoint/BreakpointResolver.h @@ -44,6 +44,8 @@ namespace lldb_private { class BreakpointResolver : public Searcher { +friend class Breakpoint; + public: //------------------------------------------------------------------ /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint @@ -122,7 +124,8 @@ public: AddressResolver, // This is an instance of BreakpointResolverAddress NameResolver, // This is an instance of BreakpointResolverName FileRegexResolver, - ExceptionResolver + ExceptionResolver, + LastKnownResolverType = ExceptionResolver }; //------------------------------------------------------------------ @@ -133,6 +136,9 @@ public: return SubclassID; } + virtual lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) = 0; + protected: //------------------------------------------------------------------ /// SetSCMatchesByLine - Takes a symbol context list of matches which supposedly represent the same file and diff --git a/include/lldb/Breakpoint/BreakpointResolverAddress.h b/include/lldb/Breakpoint/BreakpointResolverAddress.h index 4ca4a405957e..c8f034d7345b 100644 --- a/include/lldb/Breakpoint/BreakpointResolverAddress.h +++ b/include/lldb/Breakpoint/BreakpointResolverAddress.h @@ -34,27 +34,27 @@ public: virtual ~BreakpointResolverAddress (); - virtual void - ResolveBreakpoint (SearchFilter &filter); + void + ResolveBreakpoint (SearchFilter &filter) override; - virtual void + void ResolveBreakpointInModules (SearchFilter &filter, - ModuleList &modules); + ModuleList &modules) override; - virtual Searcher::CallbackReturn + Searcher::CallbackReturn SearchCallback (SearchFilter &filter, SymbolContext &context, Address *addr, - bool containing); + bool containing) override; - virtual Searcher::Depth - GetDepth (); + Searcher::Depth + GetDepth () override; - virtual void - GetDescription (Stream *s); + void + GetDescription (Stream *s) override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverAddress *) { return true; } @@ -62,6 +62,9 @@ public: return V->getResolverID() == BreakpointResolver::AddressResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: Address m_addr; diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h index cc1633ce1705..cd62bcd032b0 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -37,20 +37,20 @@ public: virtual ~BreakpointResolverFileLine (); - virtual Searcher::CallbackReturn + Searcher::CallbackReturn SearchCallback (SearchFilter &filter, SymbolContext &context, Address *addr, - bool containing); + bool containing) override; - virtual Searcher::Depth - GetDepth (); + Searcher::Depth + GetDepth () override; - virtual void - GetDescription (Stream *s); + void + GetDescription (Stream *s) override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverFileLine *) { return true; } @@ -58,6 +58,9 @@ public: return V->getResolverID() == BreakpointResolver::FileLineResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: friend class Breakpoint; FileSpec m_file_spec; // This is the file spec we are looking for. diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index f1c2b1409e92..2c05ac1c87da 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -34,20 +34,20 @@ public: virtual ~BreakpointResolverFileRegex (); - virtual Searcher::CallbackReturn + Searcher::CallbackReturn SearchCallback (SearchFilter &filter, SymbolContext &context, Address *addr, - bool containing); + bool containing) override; - virtual Searcher::Depth - GetDepth (); + Searcher::Depth + GetDepth () override; - virtual void - GetDescription (Stream *s); + void + GetDescription (Stream *s) override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverFileRegex *) { return true; } @@ -55,6 +55,9 @@ public: return V->getResolverID() == BreakpointResolver::FileRegexResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: friend class Breakpoint; RegularExpression m_regex; // This is the line expression that we are looking for. diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h index f481aa9c5338..c2a5b180f289 100644 --- a/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/include/lldb/Breakpoint/BreakpointResolverName.h @@ -64,20 +64,20 @@ public: virtual ~BreakpointResolverName (); - virtual Searcher::CallbackReturn + Searcher::CallbackReturn SearchCallback (SearchFilter &filter, SymbolContext &context, Address *addr, - bool containing); + bool containing) override; - virtual Searcher::Depth - GetDepth (); + Searcher::Depth + GetDepth () override; - virtual void - GetDescription (Stream *s); + void + GetDescription (Stream *s) override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverName *) { return true; } @@ -85,7 +85,12 @@ public: return V->getResolverID() == BreakpointResolver::NameResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: + BreakpointResolverName(const BreakpointResolverName &rhs); + struct LookupInfo { ConstString name; @@ -113,8 +118,6 @@ protected: void AddNameLookup (const ConstString &name, uint32_t name_type_mask); -private: - DISALLOW_COPY_AND_ASSIGN(BreakpointResolverName); }; } // namespace lldb_private diff --git a/include/lldb/Breakpoint/BreakpointSite.h b/include/lldb/Breakpoint/BreakpointSite.h index 1d2cbea18f9f..c6dbef781f22 100644 --- a/include/lldb/Breakpoint/BreakpointSite.h +++ b/include/lldb/Breakpoint/BreakpointSite.h @@ -259,6 +259,12 @@ public: private: friend class Process; friend class BreakpointLocation; + // The StopInfoBreakpoint knows when it is processing a hit for a thread for a site, so let it be the + // one to manage setting the location hit count once and only once. + friend class StopInfoBreakpoint; + + void + BumpHitCounts(); //------------------------------------------------------------------ /// The method removes the owner at \a break_loc_id from this breakpoint list. diff --git a/include/lldb/Core/Address.h b/include/lldb/Core/Address.h index 8dd2339f9207..b430ef7cec21 100644 --- a/include/lldb/Core/Address.h +++ b/include/lldb/Core/Address.h @@ -87,6 +87,7 @@ public: ///< and file and line), to information about what the pointer points to ///< if the address is in a section (section of pointers, c strings, etc). DumpStyleResolvedDescriptionNoModule, + DumpStyleResolvedDescriptionNoFunctionArguments, DumpStyleDetailedSymbolContext, ///< Detailed symbol context information for an address for all symbol ///< context members. DumpStyleResolvedPointerDescription ///< Dereference a pointer at the current address and then lookup the diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h index 255beee573b6..694e204cdc0d 100644 --- a/include/lldb/Core/ArchSpec.h +++ b/include/lldb/Core/ArchSpec.h @@ -104,7 +104,6 @@ public: eCore_uknownMach32, eCore_uknownMach64, - eCore_kalimba, eCore_kalimba3, eCore_kalimba4, eCore_kalimba5, @@ -142,10 +141,12 @@ public: kCore_hexagon_first = eCore_hexagon_generic, kCore_hexagon_last = eCore_hexagon_hexagonv5, - kCore_kalimba_first = eCore_kalimba, + kCore_kalimba_first = eCore_kalimba3, kCore_kalimba_last = eCore_kalimba5 }; + typedef void (* StopInfoOverrideCallbackType)(lldb_private::Thread &thread); + //------------------------------------------------------------------ /// Default constructor. /// @@ -459,6 +460,30 @@ public: bool IsCompatibleMatch (const ArchSpec& rhs) const; + //------------------------------------------------------------------ + /// Get a stop info override callback for the current architecture. + /// + /// Most platform specific code should go in lldb_private::Platform, + /// but there are cases where no matter which platform you are on + /// certain things hold true. + /// + /// This callback is currently intended to handle cases where a + /// program stops at an instruction that won't get executed and it + /// allows the stop reasonm, like "breakpoint hit", to be replaced + /// with a different stop reason like "no stop reason". + /// + /// This is specifically used for ARM in Thumb code when we stop in + /// an IT instruction (if/then/else) where the instruction won't get + /// executed and therefore it wouldn't be correct to show the program + /// stopped at the current PC. The code is generic and applies to all + /// ARM CPUs. + /// + /// @return NULL or a valid stop info override callback for the + /// current architecture. + //------------------------------------------------------------------ + StopInfoOverrideCallbackType + GetStopInfoOverrideCallback () const; + protected: bool IsEqualTo (const ArchSpec& rhs, bool exact_match) const; diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h index 7e8209d7d9c6..49532fe123c5 100644 --- a/include/lldb/Core/Communication.h +++ b/include/lldb/Core/Communication.h @@ -12,6 +12,7 @@ // C Includes // C++ Includes +#include <atomic> #include <string> // Other libraries and framework includes @@ -19,6 +20,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" +#include "lldb/Host/HostThread.h" #include "lldb/Host/Mutex.h" #include "lldb/lldb-private.h" @@ -350,8 +352,8 @@ private: protected: lldb::ConnectionSP m_connection_sp; ///< The connection that is current in use by this communications class. - lldb::thread_t m_read_thread; ///< The read thread handle in case we need to cancel the thread. - bool m_read_thread_enabled; + HostThread m_read_thread; ///< The read thread handle in case we need to cancel the thread. + std::atomic<bool> m_read_thread_enabled; std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes. Mutex m_write_mutex; ///< Don't let multiple threads write at the same time... diff --git a/include/lldb/Core/Connection.h b/include/lldb/Core/Connection.h index dde3c4b1022c..775e0c846f85 100644 --- a/include/lldb/Core/Connection.h +++ b/include/lldb/Core/Connection.h @@ -46,6 +46,8 @@ public: virtual ~Connection (); + static Connection *CreateDefaultConnection(const char *url); + //------------------------------------------------------------------ /// Connect using the connect string \a url. /// diff --git a/include/lldb/Core/ConnectionFileDescriptor.h b/include/lldb/Core/ConnectionFileDescriptor.h deleted file mode 100644 index 75d0202fcf6c..000000000000 --- a/include/lldb/Core/ConnectionFileDescriptor.h +++ /dev/null @@ -1,118 +0,0 @@ -//===-- ConnectionFileDescriptor.h ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ConnectionFileDescriptor_h_ -#define liblldb_ConnectionFileDescriptor_h_ - -// C++ Includes -#include <memory> - -#include "lldb/lldb-forward.h" - -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Connection.h" -#include "lldb/Host/Mutex.h" -#include "lldb/Host/Pipe.h" -#include "lldb/Host/Predicate.h" -#include "lldb/Host/IOObject.h" - -namespace lldb_private { - -class Error; -class Socket; -class SocketAddress; - -class ConnectionFileDescriptor : - public Connection -{ -public: - - ConnectionFileDescriptor (); - - ConnectionFileDescriptor (int fd, bool owns_fd); - - virtual - ~ConnectionFileDescriptor (); - - virtual bool - IsConnected () const; - - virtual lldb::ConnectionStatus - Connect (const char *s, Error *error_ptr); - - virtual lldb::ConnectionStatus - Disconnect (Error *error_ptr); - - virtual size_t - Read (void *dst, - size_t dst_len, - uint32_t timeout_usec, - lldb::ConnectionStatus &status, - Error *error_ptr); - - virtual size_t - Write (const void *src, - size_t src_len, - lldb::ConnectionStatus &status, - Error *error_ptr); - - lldb::ConnectionStatus - BytesAvailable (uint32_t timeout_usec, Error *error_ptr); - - bool - InterruptRead (); - - lldb::IOObjectSP GetReadObject() { return m_read_sp; } - const lldb::IOObjectSP GetReadObject() const { return m_read_sp; } - - uint16_t GetListeningPort(uint32_t timeout_sec); - -protected: - - void - OpenCommandPipe (); - - void - CloseCommandPipe (); - - lldb::ConnectionStatus - SocketListen (const char *host_and_port, Error *error_ptr); - - lldb::ConnectionStatus - ConnectTCP (const char *host_and_port, Error *error_ptr); - - lldb::ConnectionStatus - ConnectUDP (const char *args, Error *error_ptr); - - lldb::ConnectionStatus - NamedSocketConnect (const char *socket_name, Error *error_ptr); - - lldb::ConnectionStatus - NamedSocketAccept (const char *socket_name, Error *error_ptr); - - lldb::IOObjectSP m_read_sp; - lldb::IOObjectSP m_write_sp; - - Predicate<uint16_t> m_port_predicate; // Used when binding to port zero to wait for the thread - // that creates the socket, binds and listens to resolve - // the port number. - - Pipe m_pipe; - Mutex m_mutex; - 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; -private: - DISALLOW_COPY_AND_ASSIGN (ConnectionFileDescriptor); -}; - -} // namespace lldb_private - -#endif // liblldb_ConnectionFileDescriptor_h_ diff --git a/include/lldb/Core/DataBuffer.h b/include/lldb/Core/DataBuffer.h index 64e2a8857837..da4934457233 100644 --- a/include/lldb/Core/DataBuffer.h +++ b/include/lldb/Core/DataBuffer.h @@ -14,6 +14,8 @@ #include <stdint.h> #include <string.h> +#include "lldb/lldb-types.h" + namespace lldb_private { //---------------------------------------------------------------------- diff --git a/include/lldb/Core/DataExtractor.h b/include/lldb/Core/DataExtractor.h index c9db2dab73d2..516953b00c33 100644 --- a/include/lldb/Core/DataExtractor.h +++ b/include/lldb/Core/DataExtractor.h @@ -13,9 +13,13 @@ #include "lldb/lldb-private.h" + +#include "llvm/ADT/SmallVector.h" + #include <limits.h> #include <stdint.h> #include <string.h> +#include <vector> namespace lldb_private { @@ -85,8 +89,11 @@ public: /// /// @param[in] addr_size /// A new address byte size value. + /// + /// @param[in] target_byte_size + /// A size of a target byte in 8-bit host bytes //------------------------------------------------------------------ - DataExtractor (const void* data, lldb::offset_t data_length, lldb::ByteOrder byte_order, uint32_t addr_size); + DataExtractor (const void* data, lldb::offset_t data_length, lldb::ByteOrder byte_order, uint32_t addr_size, uint32_t target_byte_size = 1); //------------------------------------------------------------------ /// Construct with shared data. @@ -104,8 +111,11 @@ public: /// /// @param[in] addr_size /// A new address byte size value. + /// + /// @param[in] target_byte_size + /// A size of a target byte in 8-bit host bytes //------------------------------------------------------------------ - DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint32_t addr_size); + DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint32_t addr_size, uint32_t target_byte_size = 1); //------------------------------------------------------------------ /// Construct with a subset of \a data. @@ -129,8 +139,11 @@ public: /// /// @param[in] length /// The length in bytes of the subset of data. + /// + /// @param[in] target_byte_size + /// A size of a target byte in 8-bit host bytes //------------------------------------------------------------------ - DataExtractor (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length); + DataExtractor (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length, uint32_t target_byte_size = 1); DataExtractor (const DataExtractor& rhs); //------------------------------------------------------------------ @@ -863,7 +876,7 @@ public: *offset_ptr += 1; return val; } - + uint16_t GetU16_unchecked (lldb::offset_t *offset_ptr) const; @@ -1300,6 +1313,11 @@ public: return size - offset; return 0; } + + void + Checksum (llvm::SmallVectorImpl<uint8_t> &dest, + uint64_t max_data = 0); + protected: @@ -1311,6 +1329,7 @@ protected: 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 pointers or addresses mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multilple instances + const uint32_t m_target_byte_size; }; } // namespace lldb_private diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index 7ab62e5b7f3a..15c832f4bf66 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -25,6 +25,7 @@ #include "lldb/Core/UserID.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Host/HostThread.h" #include "lldb/Host/Terminal.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Target/ExecutionContext.h" @@ -249,6 +250,13 @@ public: Stream &s, ValueObject* valobj = NULL); + static bool + FormatDisassemblerAddress (const char *format, + const SymbolContext *sc, + const SymbolContext *prev_sc, + const ExecutionContext *exe_ctx, + const Address *addr, + Stream &s); void ClearIOHandlers (); @@ -287,10 +295,13 @@ public: bool GetAutoConfirm () const; - + + const char * + GetDisassemblyFormat() const; + const char * GetFrameFormat() const; - + const char * GetThreadFormat() const; @@ -337,6 +348,9 @@ public: GetAutoOneLineSummaries () const; bool + GetEscapeNonPrintables () const; + + bool GetNotifyVoid () const; @@ -364,9 +378,14 @@ public: bool IsHandlingEvents () const { - return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread); + return m_event_handler_thread.IsJoinable(); } + // This is for use in the command interpreter, when you either want the selected target, or if no target + // is present you want to prime the dummy target with entities that will be copied over to new targets. + Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); + Target *GetDummyTarget(); + protected: friend class CommandInterpreter; @@ -412,11 +431,16 @@ protected: { return m_source_file_cache; } + + void + InstanceInitialize (); + lldb::StreamFileSP m_input_file_sp; lldb::StreamFileSP m_output_file_sp; lldb::StreamFileSP m_error_file_sp; TerminalState m_terminal_state; TargetList m_target_list; + PlatformList m_platform_list; Listener m_listener; std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets. @@ -432,12 +456,19 @@ protected: static LoadPluginCallbackType g_load_plugin_callback; typedef std::vector<llvm::sys::DynamicLibrary> LoadedPluginsList; LoadedPluginsList m_loaded_plugins; - lldb::thread_t m_event_handler_thread; - lldb::thread_t m_io_handler_thread; + HostThread m_event_handler_thread; + HostThread m_io_handler_thread; + Broadcaster m_sync_broadcaster; lldb::ListenerSP m_forward_listener_sp; - void - InstanceInitialize (); - + + //---------------------------------------------------------------------- + // Events for m_sync_broadcaster + //---------------------------------------------------------------------- + enum + { + eBroadcastBitEventThreadIsListening = (1 << 0), + }; + private: // Use Debugger::CreateInstance() to get a shared pointer to a new diff --git a/include/lldb/Core/Disassembler.h b/include/lldb/Core/Disassembler.h index 06a703b4c1aa..b0b841b0a925 100644 --- a/include/lldb/Core/Disassembler.h +++ b/include/lldb/Core/Disassembler.h @@ -77,12 +77,60 @@ public: m_address = addr; } + //------------------------------------------------------------------ + /// Dump the text representation of this Instruction to a Stream + /// + /// Print the (optional) address, (optional) bytes, opcode, + /// operands, and instruction comments to a stream. + /// + /// @param[in] s + /// The Stream to add the text to. + /// + /// @param[in] show_address + /// Whether the address (using disassembly_addr_format_spec formatting) + /// should be printed. + /// + /// @param[in] show_bytes + /// Whether the bytes of the assembly instruction should be printed. + /// + /// @param[in] max_opcode_byte_size + /// The size (in bytes) of the largest instruction in the list that + /// we are printing (for text justification/alignment purposes) + /// Only needed if show_bytes is true. + /// + /// @param[in] exe_ctx + /// The current execution context, if available. May be used in + /// the assembling of the operands+comments for this instruction. + /// Pass NULL if not applicable. + /// + /// @param[in] sym_ctx + /// The SymbolContext for this instruction. + /// Pass NULL if not available/computed. + /// Only needed if show_address is true. + /// + /// @param[in] prev_sym_ctx + /// The SymbolContext for the previous instruction. Depending on + /// the disassembly address format specification, a change in + /// Symbol / Function may mean that a line is printed with the new + /// symbol/function name. + /// Pass NULL if unavailable, or if this is the first instruction of + /// the InstructionList. + /// Only needed if show_address is true. + /// + /// @param[in] disassembly_addr_format_spec + /// The format specification for how addresses are printed. + /// Only needed if show_address is true. + //------------------------------------------------------------------ + virtual void Dump (Stream *s, uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, - const ExecutionContext* exe_ctx); + const ExecutionContext* exe_ctx, + const SymbolContext *sym_ctx, + const SymbolContext *prev_sym_ctx, + const char *disassembly_addr_format_spec); virtual bool DoesBranch () = 0; diff --git a/include/lldb/Core/FileSpecList.h b/include/lldb/Core/FileSpecList.h index f94bdae83c01..7730690ca5b7 100644 --- a/include/lldb/Core/FileSpecList.h +++ b/include/lldb/Core/FileSpecList.h @@ -119,12 +119,15 @@ public: /// @param[in] full /// Should FileSpec::Equal be called with "full" true or false. /// + /// @param[in] remove_backup_dots + /// Should FileSpec::Equal be called with "remove_backup_dots" true or false. + /// /// @return /// The index of the file that matches \a file if it is found, /// else UINT32_MAX is returned. //------------------------------------------------------------------ size_t - FindFileIndex (size_t idx, const FileSpec &file, bool full) const; + FindFileIndex (size_t idx, const FileSpec &file, bool full, bool remove_backup_dots = false) const; //------------------------------------------------------------------ /// Get file at index. diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h index f477ebd48007..02e6bde1edb6 100644 --- a/include/lldb/Core/IOHandler.h +++ b/include/lldb/Core/IOHandler.h @@ -19,9 +19,11 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/Error.h" #include "lldb/Core/Flags.h" +#include "lldb/Core/Stream.h" #include "lldb/Core/StringList.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Host/Mutex.h" +#include "lldb/Host/Predicate.h" namespace curses { @@ -34,9 +36,23 @@ namespace lldb_private { class IOHandler { public: - IOHandler (Debugger &debugger); + enum class Type { + CommandInterpreter, + CommandList, + Confirm, + Curses, + Expression, + ProcessIO, + PythonInterpreter, + PythonCode, + Other + }; + + IOHandler (Debugger &debugger, + IOHandler::Type type); IOHandler (Debugger &debugger, + IOHandler::Type type, const lldb::StreamFileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, @@ -97,6 +113,12 @@ namespace lldb_private { return m_done; } + Type + GetType () const + { + return m_type; + } + virtual void Activate () { @@ -128,7 +150,19 @@ namespace lldb_private { { return ConstString(); } + + virtual const char * + GetCommandPrefix () + { + return NULL; + } + virtual const char * + GetHelpPrologue() + { + return NULL; + } + int GetInputFD(); @@ -206,13 +240,21 @@ namespace lldb_private { //------------------------------------------------------------------ bool GetIsRealTerminal (); - + + void + SetPopped (bool b); + + void + WaitForPop (); + protected: Debugger &m_debugger; lldb::StreamFileSP m_input_sp; lldb::StreamFileSP m_output_sp; lldb::StreamFileSP m_error_sp; + Predicate<bool> m_popped; Flags m_flags; + Type m_type; void *m_user_data; bool m_done; bool m_active; @@ -254,7 +296,12 @@ namespace lldb_private { IOHandlerActivated (IOHandler &io_handler) { } - + + virtual void + IOHandlerDeactivated (IOHandler &io_handler) + { + } + virtual int IOHandlerComplete (IOHandler &io_handler, const char *current_line, @@ -264,6 +311,44 @@ namespace lldb_private { int max_matches, StringList &matches); + virtual const char * + IOHandlerGetFixIndentationCharacters () + { + return NULL; + } + + //------------------------------------------------------------------ + /// Called when a new line is created or one of an identifed set of + /// indentation characters is typed. + /// + /// This function determines how much indentation should be added + /// or removed to match the recommended amount for the final line. + /// + /// @param[in] io_handler + /// The IOHandler that responsible for input. + /// + /// @param[in] lines + /// The current input up to the line to be corrected. Lines + /// following the line containing the cursor are not included. + /// + /// @param[in] cursor_position + /// The number of characters preceeding the cursor on the final + /// line at the time. + /// + /// @return + /// Returns an integer describing the number of spaces needed + /// to correct the indentation level. Positive values indicate + /// that spaces should be added, while negative values represent + /// spaces that should be removed. + //------------------------------------------------------------------ + virtual int + IOHandlerFixIndentation (IOHandler &io_handler, + const StringList &lines, + int cursor_position) + { + return 0; + } + //------------------------------------------------------------------ /// Called when a line or lines have been retrieved. /// @@ -275,40 +360,55 @@ namespace lldb_private { //------------------------------------------------------------------ virtual void IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0; - + + virtual void + IOHandlerInputInterrupted (IOHandler &io_handler, std::string &data) + { + } + //------------------------------------------------------------------ - /// Called when a line in \a lines has been updated when doing - /// multi-line input. + /// Called to determine whether typing enter after the last line in + /// \a lines should end input. This function will not be called on + /// IOHandler objects that are getting single lines. + /// @param[in] io_handler + /// The IOHandler that responsible for updating the lines. + /// + /// @param[in] lines + /// The current multi-line content. May be altered to provide + /// alternative input when complete. /// /// @return - /// Return an enumeration to indicate the status of the current - /// line: - /// Success - The line is good and should be added to the - /// multiple lines - /// Error - There is an error with the current line and it - /// need to be re-edited before it is acceptable - /// Done - The lines collection is complete and ready to be - /// returned. + /// Return an boolean to indicate whether input is complete, + /// true indicates that no additional input is necessary, while + /// false indicates that more input is required. //------------------------------------------------------------------ - virtual LineStatus - IOHandlerLinesUpdated (IOHandler &io_handler, - StringList &lines, - uint32_t line_idx, - Error &error) + virtual bool + IOHandlerIsInputComplete (IOHandler &io_handler, + StringList &lines) { - return LineStatus::Done; // Stop getting lines on the first line that is updated - // subclasses should do something more intelligent here. - // This function will not be called on IOHandler objects - // that are getting single lines. + // Impose no requirements for input to be considered + // complete. subclasses should do something more intelligent. + return true; } - virtual ConstString IOHandlerGetControlSequence (char ch) { return ConstString(); } + virtual const char * + IOHandlerGetCommandPrefix () + { + return NULL; + } + + virtual const char * + IOHandlerGetHelpPrologue () + { + return NULL; + } + //------------------------------------------------------------------ // Intercept the IOHandler::Interrupt() calls and do something. // @@ -356,30 +456,21 @@ namespace lldb_private { return ConstString(); } - virtual LineStatus - IOHandlerLinesUpdated (IOHandler &io_handler, - StringList &lines, - uint32_t line_idx, - Error &error) + virtual bool + IOHandlerIsInputComplete (IOHandler &io_handler, + StringList &lines) { - if (line_idx == UINT32_MAX) + // Determine whether the end of input signal has been entered + const size_t num_lines = lines.GetSize(); + if (num_lines > 0 && lines[num_lines - 1] == m_end_line) { - // Remove the last empty line from "lines" so it doesn't appear - // in our final expression and return true to indicate we are done + // Remove the terminal line from "lines" so it doesn't appear in + // the resulting input and return true to indicate we are done // getting lines lines.PopBack(); - return LineStatus::Done; - } - else if (line_idx + 1 == lines.GetSize()) - { - // The last line was edited, if this line is empty, then we are done - // getting our multiple lines. - if (lines[line_idx] == m_end_line) - { - return LineStatus::Done; - } + return true; } - return LineStatus::Success; + return false; } protected: const std::string m_end_line; @@ -390,20 +481,26 @@ namespace lldb_private { { public: IOHandlerEditline (Debugger &debugger, + IOHandler::Type type, const char *editline_name, // Used for saving history files const char *prompt, + const char *continuation_prompt, bool multi_line, + bool color_prompts, uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start' IOHandlerDelegate &delegate); IOHandlerEditline (Debugger &debugger, + IOHandler::Type type, const lldb::StreamFileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, uint32_t flags, const char *editline_name, // Used for saving history files const char *prompt, + const char *continuation_prompt, bool multi_line, + bool color_prompts, uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start' IOHandlerDelegate &delegate); @@ -429,11 +526,10 @@ namespace lldb_private { GotEOF(); virtual void - Activate () - { - IOHandler::Activate(); - m_delegate.IOHandlerActivated(*this); - } + Activate (); + + virtual void + Deactivate (); virtual ConstString GetControlSequence (char ch) @@ -442,11 +538,29 @@ namespace lldb_private { } virtual const char * + GetCommandPrefix () + { + return m_delegate.IOHandlerGetCommandPrefix (); + } + + virtual const char * + GetHelpPrologue () + { + return m_delegate.IOHandlerGetHelpPrologue (); + } + + virtual const char * GetPrompt (); virtual bool SetPrompt (const char *prompt); - + + const char * + GetContinuationPrompt (); + + void + SetContinuationPrompt (const char *prompt); + bool GetLine (std::string &line, bool &interrupted); @@ -456,14 +570,40 @@ namespace lldb_private { void SetBaseLineNumber (uint32_t line); - private: - static LineStatus - LineCompletedCallback (Editline *editline, - StringList &lines, - uint32_t line_idx, - Error &error, - void *baton); + bool + GetInterruptExits () + { + return m_interrupt_exits; + } + void + SetInterruptExits (bool b) + { + m_interrupt_exits = b; + } + + const StringList * + GetCurrentLines () const + { + return m_current_lines_ptr; + } + + uint32_t + GetCurrentLineIndex () const; + + private: +#ifndef LLDB_DISABLE_LIBEDIT + static bool + IsInputCompleteCallback (Editline *editline, + StringList &lines, + void *baton); + + static int + FixIndentationCallback (Editline *editline, + const StringList &lines, + int cursor_position, + void *baton); + static int AutoCompleteCallback (const char *current_line, const char *cursor, const char *last_char, @@ -471,18 +611,28 @@ namespace lldb_private { int max_matches, StringList &matches, void *baton); +#endif protected: +#ifndef LLDB_DISABLE_LIBEDIT std::unique_ptr<Editline> m_editline_ap; +#endif IOHandlerDelegate &m_delegate; std::string m_prompt; + std::string m_continuation_prompt; + StringList *m_current_lines_ptr; uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt - bool m_multi_line; + uint32_t m_curr_line_idx; + bool m_multi_line; + bool m_color_prompts; + bool m_interrupt_exits; }; + // The order of base classes is important. Look at the constructor of IOHandlerConfirm + // to see how. class IOHandlerConfirm : - public IOHandlerEditline, - public IOHandlerDelegate + public IOHandlerDelegate, + public IOHandlerEditline { public: IOHandlerConfirm (Debugger &debugger, @@ -607,7 +757,8 @@ namespace lldb_private { if (sp) { Mutex::Locker locker (m_mutex); - m_stack.push (sp); + sp->SetPopped (false); + m_stack.push_back (sp); // Set m_top the non-locking IsTop() call m_top = sp.get(); } @@ -627,7 +778,7 @@ namespace lldb_private { { Mutex::Locker locker (m_mutex); if (!m_stack.empty()) - sp = m_stack.top(); + sp = m_stack.back(); } return sp; } @@ -637,12 +788,16 @@ namespace lldb_private { { Mutex::Locker locker (m_mutex); if (!m_stack.empty()) - m_stack.pop(); + { + lldb::IOHandlerSP sp (m_stack.back()); + m_stack.pop_back(); + sp->SetPopped (true); + } // Set m_top the non-locking IsTop() call if (m_stack.empty()) m_top = NULL; else - m_top = m_stack.top().get(); + m_top = m_stack.back().get(); } Mutex & @@ -657,6 +812,19 @@ namespace lldb_private { return m_top == io_handler_sp.get(); } + bool + CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type) + { + Mutex::Locker locker (m_mutex); + const size_t num_io_handlers = m_stack.size(); + if (num_io_handlers >= 2 && + m_stack[num_io_handlers-1]->GetType() == top_type && + m_stack[num_io_handlers-2]->GetType() == second_top_type) + { + return true; + } + return false; + } ConstString GetTopIOHandlerControlSequence (char ch) { @@ -665,9 +833,26 @@ namespace lldb_private { return ConstString(); } - protected: + const char * + GetTopIOHandlerCommandPrefix() + { + if (m_top) + return m_top->GetCommandPrefix(); + return NULL; + } + + const char * + GetTopIOHandlerHelpPrologue() + { + if (m_top) + return m_top->GetHelpPrologue(); + return NULL; + } + + protected: - std::stack<lldb::IOHandlerSP> m_stack; + typedef std::vector<lldb::IOHandlerSP> collection; + collection m_stack; mutable Mutex m_mutex; IOHandler *m_top; diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h index 7dc0eca3e8db..2f3df6afd8dc 100644 --- a/include/lldb/Core/Mangled.h +++ b/include/lldb/Core/Mangled.h @@ -37,7 +37,8 @@ public: enum NamePreference { ePreferMangled, - ePreferDemangled + ePreferDemangled, + ePreferDemangledWithoutArguments }; //---------------------------------------------------------------------- diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h index c3074d4d6510..a46e212da9bb 100644 --- a/include/lldb/Core/ModuleList.h +++ b/include/lldb/Core/ModuleList.h @@ -279,6 +279,16 @@ public: SymbolContextList& sc_list); //------------------------------------------------------------------ + /// @see Module::FindFunctions () + //------------------------------------------------------------------ + size_t + FindFunctions(const RegularExpression &name, + bool include_symbols, + bool include_inlines, + bool append, + SymbolContextList& sc_list); + + //------------------------------------------------------------------ /// Find global and static variables by name. /// /// @param[in] name @@ -586,6 +596,13 @@ public: return ModuleIterable(m_modules, GetMutex()); } + typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter> ModuleIterableNoLocking; + ModuleIterableNoLocking + ModulesNoLocking () + { + return ModuleIterableNoLocking(m_modules); + } + }; } // namespace lldb_private diff --git a/include/lldb/Core/PluginManager.h b/include/lldb/Core/PluginManager.h index a2ac67bf9f25..55e6df06d842 100644 --- a/include/lldb/Core/PluginManager.h +++ b/include/lldb/Core/PluginManager.h @@ -342,7 +342,46 @@ public: static UnwindAssemblyCreateInstance GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name); + + //------------------------------------------------------------------ + // MemoryHistory + //------------------------------------------------------------------ + static bool + RegisterPlugin (const ConstString &name, + const char *description, + MemoryHistoryCreateInstance create_callback); + + static bool + UnregisterPlugin (MemoryHistoryCreateInstance create_callback); + + static MemoryHistoryCreateInstance + GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx); + + static MemoryHistoryCreateInstance + GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name); + + //------------------------------------------------------------------ + // InstrumentationRuntime + //------------------------------------------------------------------ + static bool + RegisterPlugin (const ConstString &name, + const char *description, + InstrumentationRuntimeCreateInstance create_callback, + InstrumentationRuntimeGetType get_type_callback); + + static bool + UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback); + static InstrumentationRuntimeGetType + GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx); + + static InstrumentationRuntimeCreateInstance + GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx); + + static InstrumentationRuntimeCreateInstance + GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name); + + //------------------------------------------------------------------ // Some plug-ins might register a DebuggerInitializeCallback // callback when registering the plug-in. After a new Debugger diff --git a/include/lldb/Core/RegularExpression.h b/include/lldb/Core/RegularExpression.h index 8e36811fa750..00d8310b4806 100644 --- a/include/lldb/Core/RegularExpression.h +++ b/include/lldb/Core/RegularExpression.h @@ -39,6 +39,9 @@ inline void regfree(llvm_regex_t * a) } #else +#if __ANDROID_NDK__ +#include <regex> +#endif #include <regex.h> #endif #include <stdint.h> diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h index 57f1b9c1a0a5..bbb7509cedb2 100644 --- a/include/lldb/Core/SearchFilter.h +++ b/include/lldb/Core/SearchFilter.h @@ -225,8 +225,10 @@ public: virtual void Dump (Stream *s) const; -protected: + lldb::SearchFilterSP + CopyForBreakpoint (Breakpoint &breakpoint); +protected: // These are utility functions to assist with the search iteration. They are used by the // default Search method. @@ -248,26 +250,40 @@ protected: const SymbolContext &context, Searcher &searcher); + virtual lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) = 0; + + void + SetTarget(lldb::TargetSP &target_sp) + { + m_target_sp = target_sp; + } + lldb::TargetSP m_target_sp; // Every filter has to be associated with a target for // now since you need a starting place for the search. }; //---------------------------------------------------------------------- -/// @class SearchFilterForNonModuleSpecificSearches SearchFilter.h "lldb/Core/SearchFilter.h" -/// @brief This is a SearchFilter that searches through all modules. It also consults the Target::ModuleIsExcludedForNonModuleSpecificSearches. +/// @class SearchFilterForUnconstrainedSearches SearchFilter.h "lldb/Core/SearchFilter.h" +/// @brief This is a SearchFilter that searches through all modules. It also consults the Target::ModuleIsExcludedForUnconstrainedSearches. //---------------------------------------------------------------------- -class SearchFilterForNonModuleSpecificSearches : +class SearchFilterForUnconstrainedSearches : public SearchFilter { public: - SearchFilterForNonModuleSpecificSearches (const lldb::TargetSP &targetSP) : SearchFilter(targetSP) {} - ~SearchFilterForNonModuleSpecificSearches () {} + SearchFilterForUnconstrainedSearches (const lldb::TargetSP &target_sp) : SearchFilter(target_sp) {} + ~SearchFilterForUnconstrainedSearches () {} - virtual bool - ModulePasses (const FileSpec &module_spec); + bool + ModulePasses (const FileSpec &module_spec) override; - virtual bool - ModulePasses (const lldb::ModuleSP &module_sp); + bool + ModulePasses (const lldb::ModuleSP &module_sp) override; + +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; + }; //---------------------------------------------------------------------- @@ -301,32 +317,36 @@ public: const SearchFilterByModule& operator=(const SearchFilterByModule& rhs); - virtual bool - ModulePasses (const lldb::ModuleSP &module_sp); + bool + ModulePasses (const lldb::ModuleSP &module_sp) override; - virtual bool - ModulePasses (const FileSpec &spec); + bool + ModulePasses (const FileSpec &spec) override; - virtual bool - AddressPasses (Address &address); + bool + AddressPasses (Address &address) override; - virtual bool - CompUnitPasses (FileSpec &fileSpec); + bool + CompUnitPasses (FileSpec &fileSpec) override; - virtual bool - CompUnitPasses (CompileUnit &compUnit); + bool + CompUnitPasses (CompileUnit &compUnit) override; - virtual void - GetDescription(Stream *s); + void + GetDescription(Stream *s) override; - virtual uint32_t - GetFilterRequiredItems (); + uint32_t + GetFilterRequiredItems () override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; - virtual void - Search (Searcher &searcher); + void + Search (Searcher &searcher) override; + +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; private: FileSpec m_module_spec; @@ -358,32 +378,36 @@ public: const SearchFilterByModuleList& operator=(const SearchFilterByModuleList& rhs); - virtual bool - ModulePasses (const lldb::ModuleSP &module_sp); + bool + ModulePasses (const lldb::ModuleSP &module_sp) override; - virtual bool - ModulePasses (const FileSpec &spec); + bool + ModulePasses (const FileSpec &spec) override; - virtual bool - AddressPasses (Address &address); + bool + AddressPasses (Address &address) override; - virtual bool - CompUnitPasses (FileSpec &fileSpec); + bool + CompUnitPasses (FileSpec &fileSpec) override; - virtual bool - CompUnitPasses (CompileUnit &compUnit); + bool + CompUnitPasses (CompileUnit &compUnit) override; - virtual void - GetDescription(Stream *s); + void + GetDescription(Stream *s) override; - virtual uint32_t - GetFilterRequiredItems (); + uint32_t + GetFilterRequiredItems () override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; - virtual void - Search (Searcher &searcher); + void + Search (Searcher &searcher) override; + +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; private: FileSpecList m_module_spec_list; @@ -416,26 +440,30 @@ public: const SearchFilterByModuleListAndCU& operator=(const SearchFilterByModuleListAndCU& rhs); - virtual bool - AddressPasses (Address &address); + bool + AddressPasses (Address &address) override; - virtual bool - CompUnitPasses (FileSpec &fileSpec); + bool + CompUnitPasses (FileSpec &fileSpec) override; - virtual bool - CompUnitPasses (CompileUnit &compUnit); + bool + CompUnitPasses (CompileUnit &compUnit) override; - virtual void - GetDescription(Stream *s); + void + GetDescription(Stream *s) override; - virtual uint32_t - GetFilterRequiredItems (); + uint32_t + GetFilterRequiredItems () override; - virtual void - Dump (Stream *s) const; + void + Dump (Stream *s) const override; - virtual void - Search (Searcher &searcher); + void + Search (Searcher &searcher) override; + +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; private: FileSpecList m_module_spec_list; diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h index 32dac5f35b84..65d408e29867 100644 --- a/include/lldb/Core/Section.h +++ b/include/lldb/Core/Section.h @@ -120,7 +120,8 @@ public: lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, - uint32_t flags); + uint32_t flags, + uint32_t target_byte_size = 1); // Create a section that is a child of parent_section_sp Section (const lldb::SectionSP &parent_section_sp, // NULL for top level sections, non-NULL for child sections @@ -134,7 +135,8 @@ public: lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, - uint32_t flags); + uint32_t flags, + uint32_t target_byte_size = 1); ~Section (); @@ -297,6 +299,12 @@ public: m_log2align = align; } + // Get the number of host bytes required to hold a target byte + uint32_t + GetTargetByteSize() const + { + return m_target_byte_size; + } protected: @@ -317,6 +325,8 @@ protected: // hits unless the children contain the address. m_encrypted:1, // Set to true if the contents are encrypted m_thread_specific:1;// This section is thread specific + uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size. This is specified as + // as a multiple number of a host bytes private: DISALLOW_COPY_AND_ASSIGN (Section); }; diff --git a/include/lldb/Core/StreamString.h b/include/lldb/Core/StreamString.h index a26ad2d16a05..1aa46dd80a68 100644 --- a/include/lldb/Core/StreamString.h +++ b/include/lldb/Core/StreamString.h @@ -46,6 +46,9 @@ public: size_t GetSize() const; + size_t + GetSizeOfLastLine () const; + std::string & GetString(); diff --git a/include/lldb/Core/ThreadSafeDenseMap.h b/include/lldb/Core/ThreadSafeDenseMap.h new file mode 100644 index 000000000000..f5a7ccfb2ffa --- /dev/null +++ b/include/lldb/Core/ThreadSafeDenseMap.h @@ -0,0 +1,65 @@ +//===-- ThreadSafeDenseMap.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadSafeDenseMap_h_ +#define liblldb_ThreadSafeDenseMap_h_ + +// C Includes +// C++ Includes + +// Other libraries and framework includes +#include "llvm/ADT/DenseMap.h" + +// Project includes +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +template <typename _KeyType, typename _ValueType> +class ThreadSafeDenseMap +{ +public: + typedef llvm::DenseMap<_KeyType,_ValueType> LLVMMapType; + + ThreadSafeDenseMap(unsigned map_initial_capacity = 0, + Mutex::Type mutex_type = Mutex::eMutexTypeNormal) : + m_map(map_initial_capacity), + m_mutex(mutex_type) + { + } + + void + Insert (_KeyType k, _ValueType v) + { + Mutex::Locker locker(m_mutex); + m_map.insert(std::make_pair(k,v)); + } + + void + Erase (_KeyType k) + { + Mutex::Locker locker(m_mutex); + m_map.erase(k); + } + + _ValueType + Lookup (_KeyType k) + { + Mutex::Locker locker(m_mutex); + return m_map.lookup(k); + } + +protected: + LLVMMapType m_map; + Mutex m_mutex; +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadSafeSTLMap_h_ diff --git a/include/lldb/Core/ThreadSafeSTLMap.h b/include/lldb/Core/ThreadSafeSTLMap.h index 703ce481f637..4235edc92ade 100644 --- a/include/lldb/Core/ThreadSafeSTLMap.h +++ b/include/lldb/Core/ThreadSafeSTLMap.h @@ -16,6 +16,7 @@ // Other libraries and framework includes // Project includes +#include "lldb/lldb-defines.h" #include "lldb/Host/Mutex.h" namespace lldb_private { diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h index 6a08ec6507f9..fa96c8989913 100644 --- a/include/lldb/Core/ValueObject.h +++ b/include/lldb/Core/ValueObject.h @@ -14,9 +14,11 @@ // C++ Includes #include <map> #include <vector> + // Other libraries and framework includes -// Project includes +#include "llvm/ADT/SmallVector.h" +// Project includes #include "lldb/lldb-private.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" @@ -88,6 +90,7 @@ public: { 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 @@ -129,6 +132,7 @@ public: eClearUserVisibleDataItemsLocation = 1u << 3, eClearUserVisibleDataItemsDescription = 1u << 4, eClearUserVisibleDataItemsSyntheticChildren = 1u << 5, + eClearUserVisibleDataItemsValidator = 1u << 6, eClearUserVisibleDataItemsAllStrings = eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | eClearUserVisibleDataItemsLocation | eClearUserVisibleDataItemsDescription, eClearUserVisibleDataItemsAll = 0xFFFF }; @@ -268,12 +272,6 @@ public: m_mod_id = new_id; } - bool - IsFirstEvaluation () const - { - return m_first_update; - } - void SetNeedsUpdate () { @@ -322,7 +320,6 @@ 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_first_update; }; const EvaluationPoint & @@ -378,6 +375,9 @@ public: // this vends a TypeImpl that is useful at the SB API layer virtual TypeImpl GetTypeImpl (); + + virtual bool + CanProvideValue (); //------------------------------------------------------------------ // Subclasses must implement the functions below. @@ -607,6 +607,18 @@ public: GetSummaryAsCString (TypeSummaryImpl* summary_ptr, std::string& destination); + bool + GetSummaryAsCString (std::string& destination, + const TypeSummaryOptions& options); + + bool + GetSummaryAsCString (TypeSummaryImpl* summary_ptr, + std::string& destination, + const TypeSummaryOptions& options); + + std::pair<TypeValidatorResult, std::string> + GetValidationStatus (); + const char * GetObjectDescription (); @@ -700,6 +712,10 @@ public: virtual bool IsSynthetic() { return false; } + lldb::ValueObjectSP + GetQualifiedRepresentationIfAvailable (lldb::DynamicValueType dynValue, + bool synthValue); + virtual lldb::ValueObjectSP CreateConstantValue (const ConstString &name); @@ -752,6 +768,18 @@ public: return false; } + virtual bool + DoesProvideSyntheticValue () + { + return false; + } + + bool + IsSyntheticChildrenGenerated (); + + void + SetSyntheticChildrenGenerated (bool b); + virtual SymbolContextScope * GetSymbolContextScope(); @@ -768,11 +796,17 @@ public: const ExecutionContext& exe_ctx); static lldb::ValueObjectSP + CreateValueObjectFromExpression (const char* name, + const char* expression, + const ExecutionContext& exe_ctx, + const EvaluateExpressionOptions& options); + + static lldb::ValueObjectSP CreateValueObjectFromAddress (const char* name, uint64_t address, const ExecutionContext& exe_ctx, ClangASTType type); - + static lldb::ValueObjectSP CreateValueObjectFromData (const char* name, const DataExtractor& data, @@ -787,6 +821,9 @@ public: 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 @@ -794,7 +831,7 @@ public: IsCStringContainer (bool check_pointer = false); size_t - ReadPointedString (Stream& s, + ReadPointedString (lldb::DataBufferSP& buffer_sp, Error& error, uint32_t max_length = 0, bool honor_array = true, @@ -834,6 +871,10 @@ public: m_format = format; } + + virtual lldb::LanguageType + GetPreferredDisplayLanguage (); + lldb::TypeSummaryImplSP GetSummaryFormat() { @@ -848,6 +889,20 @@ public: ClearUserVisibleData(eClearUserVisibleDataItemsSummary); } + lldb::TypeValidatorImplSP + GetValidator() + { + UpdateFormatsIfNeeded(); + return m_type_validator_sp; + } + + void + SetValidator(lldb::TypeValidatorImplSP format) + { + m_type_validator_sp = format; + ClearUserVisibleData(eClearUserVisibleDataItemsValidator); + } + void SetValueFormat(lldb::TypeFormatImplSP format) { @@ -1018,7 +1073,9 @@ protected: 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. - + + llvm::Optional<std::pair<TypeValidatorResult, std::string>> m_validation_result; + ClangASTType 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 @@ -1043,9 +1100,12 @@ protected: lldb::TypeSummaryImplSP m_type_summary_sp; lldb::TypeFormatImplSP m_type_format_sp; lldb::SyntheticChildrenSP m_synthetic_children_sp; + lldb::TypeValidatorImplSP m_type_validator_sp; ProcessModID m_user_id_of_forced_summary; AddressType m_address_type_of_ptr_or_ref_children; + llvm::SmallVector<uint8_t, 16> m_value_checksum; + bool m_value_is_valid:1, m_value_did_change:1, m_children_count_valid:1, @@ -1055,7 +1115,8 @@ protected: 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_did_calculate_complete_objc_class_type:1, + m_is_synthetic_children_generated:1; friend class ClangExpressionDeclMap; // For GetValue friend class ClangExpressionVariable; // For SetName @@ -1150,6 +1211,9 @@ protected: GetLocationAsCStringImpl (const Value& value, const DataExtractor& data); + bool + IsChecksumEmpty (); + private: //------------------------------------------------------------------ // For ValueObject only diff --git a/include/lldb/Core/ValueObjectChild.h b/include/lldb/Core/ValueObjectChild.h index 07d1f294bd80..7bbfe8a662d1 100644 --- a/include/lldb/Core/ValueObjectChild.h +++ b/include/lldb/Core/ValueObjectChild.h @@ -106,6 +106,7 @@ protected: protected: friend class ValueObject; friend class ValueObjectConstResult; + friend class ValueObjectConstResultImpl; ValueObjectChild (ValueObject &parent, const ClangASTType &clang_type, const ConstString &name, diff --git a/include/lldb/Core/ValueObjectConstResult.h b/include/lldb/Core/ValueObjectConstResult.h index dd87fc848ae8..4e05d50132ec 100644 --- a/include/lldb/Core/ValueObjectConstResult.h +++ b/include/lldb/Core/ValueObjectConstResult.h @@ -59,7 +59,8 @@ public: static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, Value &value, - const ConstString &name); + const ConstString &name, + Module* module = nullptr); // When an expression fails to evaluate, we return an error static lldb::ValueObjectSP @@ -126,6 +127,9 @@ public: virtual lldb::ValueObjectSP GetDynamicValue (lldb::DynamicValueType valueType); + + virtual lldb::LanguageType + GetPreferredDisplayLanguage (); protected: virtual bool @@ -169,7 +173,8 @@ private: ValueObjectConstResult (ExecutionContextScope *exe_scope, const Value &value, - const ConstString &name); + const ConstString &name, + Module* module = nullptr); ValueObjectConstResult (ExecutionContextScope *exe_scope, const Error& error); diff --git a/include/lldb/Core/ValueObjectConstResultImpl.h b/include/lldb/Core/ValueObjectConstResultImpl.h index 271b93823569..e3574e8a4d4e 100644 --- a/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/include/lldb/Core/ValueObjectConstResultImpl.h @@ -47,13 +47,6 @@ public: lldb::ValueObjectSP AddressOf (Error &error); - bool - NeedsDerefOnTarget() - { - m_impl_backend->UpdateValueIfNeeded(false); - return (m_impl_backend->GetValue().GetValueType() == Value::eValueTypeHostAddress); - } - lldb::addr_t GetLiveAddress() { @@ -68,9 +61,6 @@ public: m_live_address_type = address_type; } - lldb::ValueObjectSP - DerefOnTarget(); - virtual lldb::addr_t GetAddressOf (bool scalar_is_load_address = true, AddressType *address_type = NULL); diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h index e12698f49bb1..49c5601dc0e5 100644 --- a/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -12,10 +12,10 @@ // C Includes // C++ Includes -#include <map> #include <vector> // Other libraries and framework includes // Project includes +#include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/ValueObject.h" namespace lldb_private { @@ -132,11 +132,12 @@ public: GetNonSyntheticValue (); virtual bool - ResolveValue (Scalar &scalar) + CanProvideValue (); + + virtual bool + DoesProvideSyntheticValue () { - if (m_parent) - return m_parent->ResolveValue(scalar); - return false; + return (UpdateValueIfNeeded(), m_provides_value == eLazyBoolYes); } protected: @@ -153,8 +154,8 @@ protected: lldb::SyntheticChildrenSP m_synth_sp; std::unique_ptr<SyntheticChildrenFrontEnd> m_synth_filter_ap; - typedef std::map<uint32_t, ValueObject*> ByIndexMap; - typedef std::map<const char*, uint32_t> NameToIndexMap; + typedef ThreadSafeSTLMap<uint32_t, ValueObject*> ByIndexMap; + typedef ThreadSafeSTLMap<const char*, uint32_t> NameToIndexMap; typedef ByIndexMap::iterator ByIndexIterator; typedef NameToIndexMap::iterator NameToIndexIterator; @@ -167,12 +168,14 @@ protected: LazyBool m_might_have_children; + LazyBool m_provides_value; + private: friend class ValueObject; ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter); void - CopyParentData (); + CopyValueData (ValueObject *source); //------------------------------------------------------------------ // For ValueObject only diff --git a/include/lldb/DataFormatters/CXXFormatterFunctions.h b/include/lldb/DataFormatters/CXXFormatterFunctions.h index 753ffa1bae1b..53b7468bb13c 100644 --- a/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -61,419 +61,139 @@ namespace lldb_private { GetOSXEpoch (); bool - Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* and unichar* + FunctionPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // C++ function pointer bool - Char32StringSummaryProvider (ValueObject& valobj, Stream& stream); // char32_t* + Char16StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char16_t* and unichar* bool - WCharStringSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t* + Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char32_t* bool - Char16SummaryProvider (ValueObject& valobj, Stream& stream); // char16_t and unichar + WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // wchar_t* bool - Char32SummaryProvider (ValueObject& valobj, Stream& stream); // char32_t + Char16SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char16_t and unichar bool - WCharSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t + Char32SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char32_t bool - LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::string + WCharSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // wchar_t + + bool + LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::string bool - LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::wstring + LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::wstring bool - LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::shared_ptr<> and std::weak_ptr<> + LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::shared_ptr<> and std::weak_ptr<> bool - ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream); + ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); SyntheticChildrenFrontEnd* ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); template<bool name_entries> bool - NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream); + NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream); + NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSArraySummaryProvider (ValueObject& valobj, Stream& stream); + NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); template<bool cf_style> bool - NSSetSummaryProvider (ValueObject& valobj, Stream& stream); + NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); template<bool needs_at> bool - NSDataSummaryProvider (ValueObject& valobj, Stream& stream); + NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSNumberSummaryProvider (ValueObject& valobj, Stream& stream); + NSNumberSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream); + NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream); + NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream); + NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - CFBagSummaryProvider (ValueObject& valobj, Stream& stream); + CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream); + CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream); + CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSDateSummaryProvider (ValueObject& valobj, Stream& stream); + NSDateSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream); + CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSBundleSummaryProvider (ValueObject& valobj, Stream& stream); + NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSStringSummaryProvider (ValueObject& valobj, Stream& stream); + NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream); bool - NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream); + NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream); + NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSURLSummaryProvider (ValueObject& valobj, Stream& stream); + NSURLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream); + ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); template <bool is_sel_ptr> bool - ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream); + ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream); + RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); extern template bool - NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ; + NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ; extern template bool - NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ; + NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ; extern template bool - NSDataSummaryProvider<true> (ValueObject&, Stream&) ; + NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ; extern template bool - NSDataSummaryProvider<false> (ValueObject&, Stream&) ; + NSDataSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ; extern template bool - ObjCSELSummaryProvider<true> (ValueObject&, Stream&); + ObjCSELSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&); extern template bool - ObjCSELSummaryProvider<false> (ValueObject&, Stream&); + ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&); SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - private: - struct DataDescriptor_32 - { - uint32_t _used : 26; - uint32_t _szidx : 6; - }; - struct DataDescriptor_64 - { - uint64_t _used : 58; - uint32_t _szidx : 6; - }; - - struct DictionaryItemDescriptor - { - lldb::addr_t key_ptr; - lldb::addr_t val_ptr; - lldb::ValueObjectSP valobj_sp; - }; - - public: - NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSDictionaryISyntheticFrontEnd (); - private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - lldb::addr_t m_data_ptr; - ClangASTType m_pair_type; - std::vector<DictionaryItemDescriptor> m_children; - }; - - class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - private: - struct DataDescriptor_32 - { - uint32_t _used : 26; - uint32_t _kvo : 1; - uint32_t _size; - uint32_t _mutations; - uint32_t _objs_addr; - uint32_t _keys_addr; - }; - struct DataDescriptor_64 - { - uint64_t _used : 58; - uint32_t _kvo : 1; - uint64_t _size; - uint64_t _mutations; - uint64_t _objs_addr; - uint64_t _keys_addr; - }; - struct DictionaryItemDescriptor - { - lldb::addr_t key_ptr; - lldb::addr_t val_ptr; - lldb::ValueObjectSP valobj_sp; - }; - public: - NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSDictionaryMSyntheticFrontEnd (); - private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - ClangASTType m_pair_type; - std::vector<DictionaryItemDescriptor> m_children; - }; - - class NSDictionaryCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSDictionaryCodeRunningSyntheticFrontEnd (); - }; - SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - private: - struct DataDescriptor_32 - { - uint32_t _used : 26; - uint32_t _szidx : 6; - }; - struct DataDescriptor_64 - { - uint64_t _used : 58; - uint32_t _szidx : 6; - }; - - struct SetItemDescriptor - { - lldb::addr_t item_ptr; - lldb::ValueObjectSP valobj_sp; - }; - - public: - NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSSetISyntheticFrontEnd (); - private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - lldb::addr_t m_data_ptr; - std::vector<SetItemDescriptor> m_children; - }; - - class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - private: - - public: - NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSOrderedSetSyntheticFrontEnd (); - private: - uint32_t m_count; - std::map<uint32_t,lldb::ValueObjectSP> m_children; - }; - - class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - private: - struct DataDescriptor_32 - { - uint32_t _used : 26; - uint32_t _size; - uint32_t _mutations; - uint32_t _objs_addr; - }; - struct DataDescriptor_64 - { - uint64_t _used : 58; - uint64_t _size; - uint64_t _mutations; - uint64_t _objs_addr; - }; - struct SetItemDescriptor - { - lldb::addr_t item_ptr; - lldb::ValueObjectSP valobj_sp; - }; - public: - NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSSetMSyntheticFrontEnd (); - private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - std::vector<SetItemDescriptor> m_children; - }; - - class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSSetCodeRunningSyntheticFrontEnd (); - }; - SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: @@ -507,7 +227,7 @@ namespace lldb_private { SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); bool - LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream); + LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); class LibstdcppVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd { @@ -665,148 +385,16 @@ namespace lldb_private { SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdVectorSyntheticFrontEnd (); - private: - ValueObject* m_start; - ValueObject* m_finish; - ClangASTType m_element_type; - uint32_t m_element_size; - std::map<size_t,lldb::ValueObjectSP> m_children; - }; - SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdListSyntheticFrontEnd (); - private: - bool - HasLoop(); - - size_t m_list_capping_size; - static const bool g_use_loop_detect = true; - lldb::addr_t m_node_address; - ValueObject* m_head; - ValueObject* m_tail; - ClangASTType m_element_type; - size_t m_count; - std::map<size_t,lldb::ValueObjectSP> m_children; - }; - SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdMapSyntheticFrontEnd (); - private: - bool - GetDataType(); - - void - GetValueOffset (const lldb::ValueObjectSP& node); - - ValueObject* m_tree; - ValueObject* m_root_node; - ClangASTType m_element_type; - uint32_t m_skip_size; - size_t m_count; - std::map<size_t,lldb::ValueObjectSP> m_children; - }; - SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~LibcxxStdUnorderedMapSyntheticFrontEnd (); - private: - - ValueObject* m_tree; - size_t m_num_elements; - ValueObject* m_next_element; - std::map<size_t,lldb::ValueObjectSP> m_children; - std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache; - }; - SyntheticChildrenFrontEnd* LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + } // namespace formatters } // namespace lldb_private diff --git a/include/lldb/DataFormatters/DataVisualization.h b/include/lldb/DataFormatters/DataVisualization.h index ca0714c29f84..a0b2e58bba28 100644 --- a/include/lldb/DataFormatters/DataVisualization.h +++ b/include/lldb/DataFormatters/DataVisualization.h @@ -72,6 +72,13 @@ public: lldb::DynamicValueType use_dynamic); #endif + static lldb::TypeValidatorImplSP + GetValidator (ValueObject& valobj, + lldb::DynamicValueType use_dynamic); + + static lldb::TypeValidatorImplSP + GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp); + static bool AnyMatches(ConstString type_name, TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES, @@ -137,6 +144,12 @@ public: Disable (const lldb::TypeCategoryImplSP& category); static void + EnableStar (); + + static void + DisableStar (); + + static void LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton); static uint32_t diff --git a/include/lldb/DataFormatters/FormatCache.h b/include/lldb/DataFormatters/FormatCache.h index 1505d7c46189..fa46306e5404 100644 --- a/include/lldb/DataFormatters/FormatCache.h +++ b/include/lldb/DataFormatters/FormatCache.h @@ -31,16 +31,19 @@ private: bool m_format_cached : 1; bool m_summary_cached : 1; bool m_synthetic_cached : 1; + bool m_validator_cached : 1; lldb::TypeFormatImplSP m_format_sp; lldb::TypeSummaryImplSP m_summary_sp; lldb::SyntheticChildrenSP m_synthetic_sp; + lldb::TypeValidatorImplSP m_validator_sp; public: Entry (); Entry (lldb::TypeFormatImplSP); Entry (lldb::TypeSummaryImplSP); Entry (lldb::SyntheticChildrenSP); - Entry (lldb::TypeFormatImplSP,lldb::TypeSummaryImplSP,lldb::SyntheticChildrenSP); + Entry (lldb::TypeValidatorImplSP); + Entry (lldb::TypeFormatImplSP,lldb::TypeSummaryImplSP,lldb::SyntheticChildrenSP,lldb::TypeValidatorImplSP); bool IsFormatCached (); @@ -51,6 +54,9 @@ private: bool IsSyntheticCached (); + bool + IsValidatorCached (); + lldb::TypeFormatImplSP GetFormat (); @@ -60,6 +66,9 @@ private: lldb::SyntheticChildrenSP GetSynthetic (); + lldb::TypeValidatorImplSP + GetValidator (); + void SetFormat (lldb::TypeFormatImplSP); @@ -68,6 +77,9 @@ private: void SetSynthetic (lldb::SyntheticChildrenSP); + + void + SetValidator (lldb::TypeValidatorImplSP); }; typedef std::map<ConstString,Entry> CacheMap; CacheMap m_map; @@ -91,6 +103,9 @@ public: bool GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp); + bool + GetValidator (const ConstString& type,lldb::TypeValidatorImplSP& summary_sp); + void SetFormat (const ConstString& type,lldb::TypeFormatImplSP& format_sp); @@ -101,6 +116,9 @@ public: SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp); void + SetValidator (const ConstString& type,lldb::TypeValidatorImplSP& synthetic_sp); + + void Clear (); uint64_t diff --git a/include/lldb/DataFormatters/FormatManager.h b/include/lldb/DataFormatters/FormatManager.h index 0b9144dffa17..37dae6536761 100644 --- a/include/lldb/DataFormatters/FormatManager.h +++ b/include/lldb/DataFormatters/FormatManager.h @@ -86,6 +86,18 @@ public: m_categories_map.Disable(category); } + void + EnableAllCategories () + { + m_categories_map.EnableAllCategories (); + } + + void + DisableAllCategories () + { + m_categories_map.DisableAllCategories (); + } + bool DeleteCategory (const ConstString& category_name) { @@ -148,6 +160,9 @@ public: GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp); #endif + lldb::TypeValidatorImplSP + GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp); + lldb::TypeFormatImplSP GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic); @@ -162,6 +177,10 @@ public: lldb::DynamicValueType use_dynamic); #endif + lldb::TypeValidatorImplSP + GetValidator (ValueObject& valobj, + lldb::DynamicValueType use_dynamic); + bool AnyMatches (ConstString type_name, TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES, @@ -272,6 +291,7 @@ private: HardcodedFormatterFinders<TypeFormatImpl> m_hardcoded_formats; HardcodedFormatterFinders<TypeSummaryImpl> m_hardcoded_summaries; HardcodedFormatterFinders<SyntheticChildren> m_hardcoded_synthetics; + HardcodedFormatterFinders<TypeValidatorImpl> m_hardcoded_validators; lldb::TypeFormatImplSP GetHardcodedFormat (ValueObject&,lldb::DynamicValueType); @@ -282,6 +302,9 @@ private: lldb::SyntheticChildrenSP GetHardcodedSyntheticChildren (ValueObject&,lldb::DynamicValueType); + lldb::TypeValidatorImplSP + GetHardcodedValidator (ValueObject&,lldb::DynamicValueType); + TypeCategoryMap& GetCategories () { diff --git a/include/lldb/DataFormatters/FormattersContainer.h b/include/lldb/DataFormatters/FormattersContainer.h index de838d1ab9c1..daf2f24ae3e5 100644 --- a/include/lldb/DataFormatters/FormattersContainer.h +++ b/include/lldb/DataFormatters/FormattersContainer.h @@ -29,6 +29,7 @@ #include "lldb/DataFormatters/TypeFormat.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/TypeSynthetic.h" +#include "lldb/DataFormatters/TypeValidator.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTType.h" @@ -38,6 +39,8 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/TargetList.h" +#include "lldb/Utility/StringLexer.h" + namespace lldb_private { // this file (and its. cpp) contain the low-level implementation of LLDB Data Visualization @@ -58,18 +61,6 @@ public: }; -static inline bool -IsWhitespace (char c) -{ - return ( (c == ' ') || (c == '\t') || (c == '\v') || (c == '\f') ); -} - -static inline bool -HasPrefix (const char* str1, const char* str2) -{ - return ( ::strstr(str1, str2) == str1 ); -} - // if the user tries to add formatters for, say, "struct Foo" // those will not match any type because of the way we strip qualifiers from typenames // this method looks for the case where the user is adding a "class","struct","enum" or "union" Foo @@ -77,32 +68,23 @@ HasPrefix (const char* str1, const char* str2) static inline ConstString GetValidTypeName_Impl (const ConstString& type) { - int strip_len = 0; - - if ((bool)type == false) + if (type.IsEmpty()) return type; - const char* type_cstr = type.AsCString(); - - if ( HasPrefix(type_cstr, "class ") ) - strip_len = 6; - else if ( HasPrefix(type_cstr, "enum ") ) - strip_len = 5; - else if ( HasPrefix(type_cstr, "struct ") ) - strip_len = 7; - else if ( HasPrefix(type_cstr, "union ") ) - strip_len = 6; + std::string type_cstr(type.AsCString()); + lldb_utility::StringLexer type_lexer(type_cstr); - if (strip_len == 0) - return type; + type_lexer.AdvanceIf("class "); + type_lexer.AdvanceIf("enum "); + type_lexer.AdvanceIf("struct "); + type_lexer.AdvanceIf("union "); - type_cstr += strip_len; - while (IsWhitespace(*type_cstr) && ++type_cstr) + while (type_lexer.NextIf({' ','\t','\v','\f'}).first) ; - return ConstString(type_cstr); + return ConstString(type_lexer.GetUnlexed()); } - + template<typename KeyType, typename ValueType> class FormattersContainer; @@ -267,8 +249,7 @@ public: FormattersContainer(std::string name, IFormatChangeListener* lst) : m_format_map(lst), - m_name(name), - m_id_cs(ConstString("id")) + m_name(name) { } @@ -345,15 +326,11 @@ public: } protected: - BackEndType m_format_map; - std::string m_name; DISALLOW_COPY_AND_ASSIGN(FormattersContainer); - ConstString m_id_cs; - void Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy) { diff --git a/include/lldb/DataFormatters/StringPrinter.h b/include/lldb/DataFormatters/StringPrinter.h new file mode 100644 index 000000000000..48e27ace5d92 --- /dev/null +++ b/include/lldb/DataFormatters/StringPrinter.h @@ -0,0 +1,290 @@ +//===-- StringPrinter.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StringPrinter_h_ +#define liblldb_StringPrinter_h_ + +#include "lldb/lldb-forward.h" + +#include "lldb/Core/DataExtractor.h" + +namespace lldb_private { + namespace formatters + { + + enum class StringElementType { + ASCII, + UTF8, + UTF16, + UTF32 + }; + + class ReadStringAndDumpToStreamOptions + { + public: + + ReadStringAndDumpToStreamOptions () : + m_location(0), + m_process_sp(), + m_stream(NULL), + m_prefix_token(0), + m_quote('"'), + m_source_size(0), + m_needs_zero_termination(true), + m_escape_non_printables(true), + m_ignore_max_length(false) + { + } + + ReadStringAndDumpToStreamOptions (ValueObject& valobj); + + ReadStringAndDumpToStreamOptions& + SetLocation (uint64_t l) + { + m_location = l; + return *this; + } + + uint64_t + GetLocation () const + { + return m_location; + } + + ReadStringAndDumpToStreamOptions& + SetProcessSP (lldb::ProcessSP p) + { + m_process_sp = p; + return *this; + } + + lldb::ProcessSP + GetProcessSP () const + { + return m_process_sp; + } + + ReadStringAndDumpToStreamOptions& + SetStream (Stream* s) + { + m_stream = s; + return *this; + } + + Stream* + GetStream () const + { + return m_stream; + } + + ReadStringAndDumpToStreamOptions& + SetPrefixToken (char p) + { + m_prefix_token = p; + return *this; + } + + char + GetPrefixToken () const + { + return m_prefix_token; + } + + ReadStringAndDumpToStreamOptions& + SetQuote (char q) + { + m_quote = q; + return *this; + } + + char + GetQuote () const + { + return m_quote; + } + + ReadStringAndDumpToStreamOptions& + SetSourceSize (uint32_t s) + { + m_source_size = s; + return *this; + } + + uint32_t + GetSourceSize () const + { + return m_source_size; + } + + ReadStringAndDumpToStreamOptions& + SetNeedsZeroTermination (bool z) + { + m_needs_zero_termination = z; + return *this; + } + + bool + GetNeedsZeroTermination () const + { + return m_needs_zero_termination; + } + + ReadStringAndDumpToStreamOptions& + SetEscapeNonPrintables (bool e) + { + m_escape_non_printables = e; + return *this; + } + + bool + GetEscapeNonPrintables () const + { + return m_escape_non_printables; + } + + ReadStringAndDumpToStreamOptions& + SetIgnoreMaxLength (bool e) + { + m_ignore_max_length = e; + return *this; + } + + bool + GetIgnoreMaxLength () const + { + return m_ignore_max_length; + } + + private: + uint64_t m_location; + lldb::ProcessSP m_process_sp; + Stream* m_stream; + char m_prefix_token; + char m_quote; + uint32_t m_source_size; + bool m_needs_zero_termination; + bool m_escape_non_printables; + bool m_ignore_max_length; + }; + + class ReadBufferAndDumpToStreamOptions + { + public: + + ReadBufferAndDumpToStreamOptions () : + m_data(), + m_stream(NULL), + m_prefix_token(0), + m_quote('"'), + m_source_size(0), + m_escape_non_printables(true) + { + } + + ReadBufferAndDumpToStreamOptions (ValueObject& valobj); + + ReadBufferAndDumpToStreamOptions& + SetData (DataExtractor d) + { + m_data = d; + return *this; + } + + lldb_private::DataExtractor + GetData () const + { + return m_data; + } + + ReadBufferAndDumpToStreamOptions& + SetStream (Stream* s) + { + m_stream = s; + return *this; + } + + Stream* + GetStream () const + { + return m_stream; + } + + ReadBufferAndDumpToStreamOptions& + SetPrefixToken (char p) + { + m_prefix_token = p; + return *this; + } + + char + GetPrefixToken () const + { + return m_prefix_token; + } + + ReadBufferAndDumpToStreamOptions& + SetQuote (char q) + { + m_quote = q; + return *this; + } + + char + GetQuote () const + { + return m_quote; + } + + ReadBufferAndDumpToStreamOptions& + SetSourceSize (uint32_t s) + { + m_source_size = s; + return *this; + } + + uint32_t + GetSourceSize () const + { + return m_source_size; + } + + ReadBufferAndDumpToStreamOptions& + SetEscapeNonPrintables (bool e) + { + m_escape_non_printables = e; + return *this; + } + + bool + GetEscapeNonPrintables () const + { + return m_escape_non_printables; + } + + private: + DataExtractor m_data; + Stream* m_stream; + char m_prefix_token; + char m_quote; + uint32_t m_source_size; + bool m_escape_non_printables; + }; + + template <StringElementType element_type> + bool + ReadStringAndDumpToStream (ReadStringAndDumpToStreamOptions options); + + template <StringElementType element_type> + bool + ReadBufferAndDumpToStream (ReadBufferAndDumpToStreamOptions options); + + } // namespace formatters +} // namespace lldb_private + +#endif // liblldb_StringPrinter_h_ diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h index 491fef29b5c5..e32efa420a55 100644 --- a/include/lldb/DataFormatters/TypeCategory.h +++ b/include/lldb/DataFormatters/TypeCategory.h @@ -71,6 +71,7 @@ namespace lldb_private { typedef FormatterContainerPair<TypeFormatImpl> FormatContainer; typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer; typedef FormatterContainerPair<TypeFilterImpl> FilterContainer; + typedef FormatterContainerPair<TypeValidatorImpl> ValidatorContainer; #ifndef LLDB_DISABLE_PYTHON typedef FormatterContainerPair<ScriptedSyntheticChildren> SynthContainer; @@ -94,6 +95,9 @@ namespace lldb_private { typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP; #endif // #ifndef LLDB_DISABLE_PYTHON + typedef ValidatorContainer::ExactMatchContainerSP ValidatorContainerSP; + typedef ValidatorContainer::RegexMatchContainerSP RegexValidatorContainerSP; + TypeCategoryImpl (IFormatChangeListener* clist, ConstString name); @@ -147,6 +151,9 @@ namespace lldb_private { GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp); #endif + ValidatorContainer::MapValueType + GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp); + lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForFormatAtIndex (size_t index); @@ -183,9 +190,26 @@ namespace lldb_private { lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForSyntheticAtIndex (size_t index); - #endif // #ifndef LLDB_DISABLE_PYTHON + ValidatorContainerSP + GetTypeValidatorsContainer () + { + return m_validator_cont.GetExactMatch(); + } + + RegexValidatorContainerSP + GetRegexTypeValidatorsContainer () + { + return m_validator_cont.GetRegexMatch(); + } + + ValidatorContainer::MapValueType + GetValidatorAtIndex (size_t index); + + lldb::TypeNameSpecifierImplSP + GetTypeNameSpecifierForValidatorAtIndex (size_t index); + bool IsEnabled () const { @@ -219,6 +243,12 @@ namespace lldb_private { lldb::SyntheticChildrenSP& entry, uint32_t* reason = NULL); + bool + Get (ValueObject& valobj, + const FormattersMatchVector& candidates, + lldb::TypeValidatorImplSP& entry, + uint32_t* reason = NULL); + void Clear (FormatCategoryItems items = ALL_ITEM_TYPES); @@ -246,14 +276,12 @@ namespace lldb_private { private: FormatContainer m_format_cont; - SummaryContainer m_summary_cont; - FilterContainer m_filter_cont; - #ifndef LLDB_DISABLE_PYTHON SynthContainer m_synth_cont; #endif // #ifndef LLDB_DISABLE_PYTHON + ValidatorContainer m_validator_cont; bool m_enabled; @@ -274,6 +302,18 @@ namespace lldb_private { Enable(false, UINT32_MAX); } + uint32_t + GetLastEnabledPosition () + { + return m_enabled_position; + } + + void + SetEnabledPosition (uint32_t p) + { + m_enabled_position = p; + } + friend class TypeCategoryMap; friend class FormattersContainer<ConstString, TypeFormatImpl>; @@ -289,6 +329,9 @@ namespace lldb_private { friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>; friend class FormattersContainer<lldb::RegularExpressionSP, ScriptedSyntheticChildren>; #endif // #ifndef LLDB_DISABLE_PYTHON + + friend class FormattersContainer<ConstString, TypeValidatorImpl>; + friend class FormattersContainer<lldb::RegularExpressionSP, TypeValidatorImpl>; }; } // namespace lldb_private diff --git a/include/lldb/DataFormatters/TypeCategoryMap.h b/include/lldb/DataFormatters/TypeCategoryMap.h index 88aaeb23bfd8..41b170d5335e 100644 --- a/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/include/lldb/DataFormatters/TypeCategoryMap.h @@ -63,6 +63,12 @@ namespace lldb_private { bool Disable (ValueSP category); + + void + EnableAllCategories (); + + void + DisableAllCategories (); void Clear (); @@ -108,6 +114,10 @@ namespace lldb_private { lldb::DynamicValueType use_dynamic); #endif + lldb::TypeValidatorImplSP + GetValidator (ValueObject& valobj, + lldb::DynamicValueType use_dynamic); + private: class delete_matching_categories diff --git a/include/lldb/DataFormatters/TypeSummary.h b/include/lldb/DataFormatters/TypeSummary.h index 699494336cc6..2d4e03ad9b5d 100644 --- a/include/lldb/DataFormatters/TypeSummary.h +++ b/include/lldb/DataFormatters/TypeSummary.h @@ -28,6 +28,32 @@ #include "lldb/Symbol/Type.h" namespace lldb_private { + class TypeSummaryOptions + { + public: + TypeSummaryOptions (); + TypeSummaryOptions (const TypeSummaryOptions& rhs); + + TypeSummaryOptions& + operator = (const TypeSummaryOptions& rhs); + + lldb::LanguageType + GetLanguage () const; + + lldb::TypeSummaryCapping + GetCapping () const; + + TypeSummaryOptions& + SetLanguage (lldb::LanguageType); + + TypeSummaryOptions& + SetCapping (lldb::TypeSummaryCapping); + + ~TypeSummaryOptions() = default; + private: + lldb::LanguageType m_lang; + lldb::TypeSummaryCapping m_capping; + }; class TypeSummaryImpl { @@ -313,7 +339,8 @@ namespace lldb_private { // for us to generate its summary virtual bool FormatObject (ValueObject *valobj, - std::string& dest) = 0; + std::string& dest, + const TypeSummaryOptions& options) = 0; virtual std::string GetDescription () = 0; @@ -372,7 +399,8 @@ namespace lldb_private { virtual bool FormatObject(ValueObject *valobj, - std::string& dest); + std::string& dest, + const TypeSummaryOptions& options); virtual std::string GetDescription(); @@ -397,10 +425,11 @@ namespace lldb_private { // summaries implemented via a C++ function struct CXXFunctionSummaryFormat : public TypeSummaryImpl { - // we should convert these to SBValue and SBStream if we ever cross // the boundary towards the external world - typedef bool (*Callback)(ValueObject& valobj, Stream& dest); + typedef bool (*Callback)(ValueObject&, + Stream&, + const TypeSummaryOptions&); Callback m_impl; std::string m_description; @@ -443,7 +472,8 @@ namespace lldb_private { virtual bool FormatObject (ValueObject *valobj, - std::string& dest); + std::string& dest, + const TypeSummaryOptions& options); virtual std::string GetDescription (); @@ -517,7 +547,8 @@ namespace lldb_private { virtual bool FormatObject (ValueObject *valobj, - std::string& dest); + std::string& dest, + const TypeSummaryOptions& options); virtual std::string GetDescription (); diff --git a/include/lldb/DataFormatters/TypeSynthetic.h b/include/lldb/DataFormatters/TypeSynthetic.h index a25f11d64392..675c43b1f311 100644 --- a/include/lldb/DataFormatters/TypeSynthetic.h +++ b/include/lldb/DataFormatters/TypeSynthetic.h @@ -24,8 +24,6 @@ #include "lldb/lldb-enumerations.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" -#include "lldb/Symbol/Type.h" namespace lldb_private { class SyntheticChildrenFrontEnd @@ -81,14 +79,71 @@ namespace lldb_private { virtual bool MightHaveChildren () = 0; + // if this function returns a non-null ValueObject, then the returned ValueObject will stand + // for this ValueObject whenever a "value" request is made to this ValueObject + virtual lldb::ValueObjectSP + GetSyntheticValue () { return nullptr; } + typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer; typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer; + protected: + lldb::ValueObjectSP + CreateValueObjectFromExpression (const char* name, + const char* expression, + const ExecutionContext& exe_ctx); + + lldb::ValueObjectSP + CreateValueObjectFromAddress (const char* name, + uint64_t address, + const ExecutionContext& exe_ctx, + ClangASTType type); + + lldb::ValueObjectSP + CreateValueObjectFromData (const char* name, + const DataExtractor& data, + const ExecutionContext& exe_ctx, + ClangASTType type); + private: bool m_valid; DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd); }; + class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd + { + public: + SyntheticValueProviderFrontEnd (ValueObject &backend) : + SyntheticChildrenFrontEnd(backend) + {} + + virtual + ~SyntheticValueProviderFrontEnd () + { + } + + virtual size_t + CalculateNumChildren () { return 0; } + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx) { return nullptr; } + + virtual size_t + GetIndexOfChildWithName (const ConstString &name) { return UINT32_MAX; } + + virtual bool + Update () { return false; } + + virtual bool + MightHaveChildren () { return false; } + + virtual lldb::ValueObjectSP + GetSyntheticValue () = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd); + }; + class SyntheticChildren { public: @@ -328,37 +383,10 @@ namespace lldb_private { } void - AddExpressionPath (const std::string& path) - { - bool need_add_dot = true; - if (path[0] == '.' || - (path[0] == '-' && path[1] == '>') || - path[0] == '[') - need_add_dot = false; - // add a '.' symbol to help forgetful users - if(!need_add_dot) - m_expression_paths.push_back(path); - else - m_expression_paths.push_back(std::string(".") + path); - } + AddExpressionPath (const std::string& path); bool - SetExpressionPathAtIndex (size_t i, const std::string& path) - { - if (i >= GetCount()) - return false; - bool need_add_dot = true; - if (path[0] == '.' || - (path[0] == '-' && path[1] == '>') || - path[0] == '[') - need_add_dot = false; - // add a '.' symbol to help forgetful users - if(!need_add_dot) - m_expression_paths[i] = path; - else - m_expression_paths[i] = std::string(".") + path; - return true; - } + SetExpressionPathAtIndex (size_t i, const std::string& path); bool IsScripted () @@ -410,24 +438,7 @@ namespace lldb_private { } virtual size_t - GetIndexOfChildWithName (const ConstString &name) - { - const char* name_cstr = name.GetCString(); - for (size_t i = 0; i < filter->GetCount(); i++) - { - const char* expr_cstr = filter->GetExpressionPathAtIndex(i); - if (expr_cstr) - { - if (*expr_cstr == '.') - expr_cstr++; - else if (*expr_cstr == '-' && *(expr_cstr+1) == '>') - expr_cstr += 2; - } - if (!::strcmp(name_cstr, expr_cstr)) - return i; - } - return UINT32_MAX; - } + GetIndexOfChildWithName (const ConstString &name); typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer; @@ -548,50 +559,28 @@ namespace lldb_private { ValueObject &backend); bool - IsValid () - { - return m_wrapper_sp.get() != nullptr && m_wrapper_sp->operator bool() && m_interpreter != nullptr; - } + IsValid (); virtual ~FrontEnd (); virtual size_t - CalculateNumChildren () - { - if (!m_wrapper_sp || m_interpreter == NULL) - return 0; - return m_interpreter->CalculateNumChildren(m_wrapper_sp); - } + CalculateNumChildren (); virtual lldb::ValueObjectSP GetChildAtIndex (size_t idx); virtual bool - Update () - { - if (!m_wrapper_sp || m_interpreter == NULL) - return false; - - return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp); - } + Update (); virtual bool - MightHaveChildren () - { - if (!m_wrapper_sp || m_interpreter == NULL) - return false; - - return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp); - } + MightHaveChildren (); virtual size_t - GetIndexOfChildWithName (const ConstString &name) - { - if (!m_wrapper_sp || m_interpreter == NULL) - return UINT32_MAX; - return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString()); - } + GetIndexOfChildWithName (const ConstString &name); + + virtual lldb::ValueObjectSP + GetSyntheticValue (); typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer; diff --git a/include/lldb/DataFormatters/TypeValidator.h b/include/lldb/DataFormatters/TypeValidator.h new file mode 100644 index 000000000000..b501e47943fa --- /dev/null +++ b/include/lldb/DataFormatters/TypeValidator.h @@ -0,0 +1,280 @@ +//===-- TypeValidator.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_TypeValidator_h_ +#define lldb_TypeValidator_h_ + +// C Includes + +// C++ Includes +#include <string> +#include <functional> + +// Other libraries and framework includes + +// Project includes +#include "lldb/lldb-public.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-enumerations.h" + +namespace lldb_private { + +class TypeValidatorImpl +{ +public: + class Flags + { + public: + + Flags () : + m_flags (lldb::eTypeOptionCascade) + {} + + Flags (const Flags& other) : + m_flags (other.m_flags) + {} + + Flags (uint32_t value) : + m_flags (value) + {} + + Flags& + operator = (const Flags& rhs) + { + if (&rhs != this) + m_flags = rhs.m_flags; + + return *this; + } + + Flags& + operator = (const uint32_t& rhs) + { + m_flags = rhs; + return *this; + } + + Flags& + Clear() + { + m_flags = 0; + return *this; + } + + bool + GetCascades () const + { + return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade; + } + + Flags& + SetCascades (bool value = true) + { + if (value) + m_flags |= lldb::eTypeOptionCascade; + else + m_flags &= ~lldb::eTypeOptionCascade; + return *this; + } + + bool + GetSkipPointers () const + { + return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers; + } + + Flags& + SetSkipPointers (bool value = true) + { + if (value) + m_flags |= lldb::eTypeOptionSkipPointers; + else + m_flags &= ~lldb::eTypeOptionSkipPointers; + return *this; + } + + bool + GetSkipReferences () const + { + return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences; + } + + Flags& + SetSkipReferences (bool value = true) + { + if (value) + m_flags |= lldb::eTypeOptionSkipReferences; + else + m_flags &= ~lldb::eTypeOptionSkipReferences; + return *this; + } + + uint32_t + GetValue () + { + return m_flags; + } + + void + SetValue (uint32_t value) + { + m_flags = value; + } + + private: + uint32_t m_flags; + }; + + TypeValidatorImpl (const Flags& flags = Flags()); + + typedef std::shared_ptr<TypeValidatorImpl> SharedPointer; + typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeValidatorImplSP&); + + virtual ~TypeValidatorImpl (); + + bool + Cascades () const + { + return m_flags.GetCascades(); + } + bool + SkipsPointers () const + { + return m_flags.GetSkipPointers(); + } + bool + SkipsReferences () const + { + return m_flags.GetSkipReferences(); + } + + void + SetCascades (bool value) + { + m_flags.SetCascades(value); + } + + void + SetSkipsPointers (bool value) + { + m_flags.SetSkipPointers(value); + } + + void + SetSkipsReferences (bool value) + { + m_flags.SetSkipReferences(value); + } + + uint32_t + GetOptions () + { + return m_flags.GetValue(); + } + + void + SetOptions (uint32_t value) + { + m_flags.SetValue(value); + } + + uint32_t& + GetRevision () + { + return m_my_revision; + } + + enum class Type + { + eTypeUnknown, + eTypeCXX + }; + + struct ValidationResult { + TypeValidatorResult m_result; + std::string m_message; + }; + + virtual Type + GetType () + { + return Type::eTypeUnknown; + } + + // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for + // extended periods of time and we trust the ValueObject to stay around for as long as it is required + // for us to generate its value + virtual ValidationResult + FormatObject (ValueObject *valobj) const = 0; + + virtual std::string + GetDescription() = 0; + + static ValidationResult + Success (); + + static ValidationResult + Failure (std::string message); + +protected: + Flags m_flags; + uint32_t m_my_revision; + +private: + DISALLOW_COPY_AND_ASSIGN(TypeValidatorImpl); +}; + +class TypeValidatorImpl_CXX : public TypeValidatorImpl +{ +public: + typedef std::function<TypeValidatorImpl::ValidationResult(ValueObject* valobj)> ValidatorFunction; + + TypeValidatorImpl_CXX (ValidatorFunction f, std::string d, const TypeValidatorImpl::Flags& flags = Flags()); + + typedef std::shared_ptr<TypeValidatorImpl_CXX> SharedPointer; + typedef bool(*ValueCallback)(void*, ConstString, const TypeValidatorImpl_CXX::SharedPointer&); + + virtual ~TypeValidatorImpl_CXX (); + + ValidatorFunction + GetValidatorFunction () const + { + return m_validator_function; + } + + void + SetValidatorFunction (ValidatorFunction f) + { + m_validator_function = f; + } + + virtual TypeValidatorImpl::Type + GetType () + { + return TypeValidatorImpl::Type::eTypeCXX; + } + + virtual ValidationResult + FormatObject (ValueObject *valobj) const; + + virtual std::string + GetDescription(); + +protected: + std::string m_description; + ValidatorFunction m_validator_function; + +private: + DISALLOW_COPY_AND_ASSIGN(TypeValidatorImpl_CXX); +}; + + +} // namespace lldb_private + +#endif // lldb_TypeValidator_h_ diff --git a/include/lldb/DataFormatters/ValueObjectPrinter.h b/include/lldb/DataFormatters/ValueObjectPrinter.h index bfe2d9c402d3..235d5389ee75 100644 --- a/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -26,44 +26,43 @@ namespace lldb_private { struct DumpValueObjectOptions { - uint32_t m_max_ptr_depth; - uint32_t m_max_depth; - bool m_show_types; - bool m_show_location; - bool m_use_objc; - lldb::DynamicValueType m_use_dynamic; - bool m_use_synthetic; - bool m_scope_already_checked; - bool m_flat_output; - uint32_t m_omit_summary_depth; - bool m_ignore_cap; - lldb::Format m_format; + uint32_t m_max_ptr_depth = 0; + uint32_t m_max_depth = UINT32_MAX; + lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues; + uint32_t m_omit_summary_depth = 0; + lldb::Format m_format = lldb::eFormatDefault; lldb::TypeSummaryImplSP m_summary_sp; std::string m_root_valobj_name; - bool m_hide_root_type; - bool m_hide_name; - bool m_hide_value; - bool m_be_raw; + bool m_use_synthetic : 1; + bool m_scope_already_checked : 1; + bool m_flat_output : 1; + bool m_ignore_cap : 1; + bool m_show_types : 1; + bool m_show_location : 1; + bool m_use_objc : 1; + bool m_hide_root_type : 1; + bool m_hide_name : 1; + bool m_hide_value : 1; + bool m_run_validator : 1; + bool m_use_type_display_name : 1; + bool m_allow_oneliner_mode : 1; DumpValueObjectOptions() : - m_max_ptr_depth(0), - m_max_depth(UINT32_MAX), - m_show_types(false), - m_show_location(false), - m_use_objc(false), - m_use_dynamic(lldb::eNoDynamicValues), + m_summary_sp(), + m_root_valobj_name(), m_use_synthetic(true), m_scope_already_checked(false), m_flat_output(false), - m_omit_summary_depth(0), m_ignore_cap(false), - m_format (lldb::eFormatDefault), - m_summary_sp(), - m_root_valobj_name(), - m_hide_root_type(false), // provide a special compact display for "po" - m_hide_name(false), // provide a special compact display for "po" - m_hide_value(false), // provide a special compact display for "po" - m_be_raw(false) + m_show_types(false), + m_show_location(false), + m_use_objc(false), + m_hide_root_type(false), + m_hide_name(false), + m_hide_value(false), + m_run_validator(false), + m_use_type_display_name(true), + m_allow_oneliner_mode(true) {} static const DumpValueObjectOptions @@ -74,26 +73,7 @@ struct DumpValueObjectOptions return g_default_options; } - DumpValueObjectOptions (const DumpValueObjectOptions& rhs) : - m_max_ptr_depth(rhs.m_max_ptr_depth), - m_max_depth(rhs.m_max_depth), - m_show_types(rhs.m_show_types), - m_show_location(rhs.m_show_location), - m_use_objc(rhs.m_use_objc), - m_use_dynamic(rhs.m_use_dynamic), - m_use_synthetic(rhs.m_use_synthetic), - m_scope_already_checked(rhs.m_scope_already_checked), - m_flat_output(rhs.m_flat_output), - m_omit_summary_depth(rhs.m_omit_summary_depth), - m_ignore_cap(rhs.m_ignore_cap), - m_format(rhs.m_format), - m_summary_sp(rhs.m_summary_sp), - m_root_valobj_name(rhs.m_root_valobj_name), - m_hide_root_type(rhs.m_hide_root_type), - m_hide_name(rhs.m_hide_name), - m_hide_value(rhs.m_hide_value), - m_be_raw(rhs.m_be_raw) - {} + DumpValueObjectOptions (const DumpValueObjectOptions& rhs) = default; DumpValueObjectOptions& SetMaximumPointerDepth(uint32_t depth = 0) @@ -183,26 +163,15 @@ struct DumpValueObjectOptions } DumpValueObjectOptions& - SetRawDisplay(bool raw = false) + SetRawDisplay() { - if (raw) - { - SetUseSyntheticValue(false); - SetOmitSummaryDepth(UINT32_MAX); - SetIgnoreCap(true); - SetHideName(false); - SetHideValue(false); - m_be_raw = true; - } - else - { - SetUseSyntheticValue(true); - SetOmitSummaryDepth(0); - SetIgnoreCap(false); - SetHideName(false); - SetHideValue(false); - m_be_raw = false; - } + SetUseSyntheticValue(false); + SetOmitSummaryDepth(UINT32_MAX); + SetIgnoreCap(true); + SetHideName(false); + SetHideValue(false); + SetUseTypeDisplayName(false); + SetAllowOnelinerMode(false); return *this; } @@ -250,8 +219,30 @@ struct DumpValueObjectOptions m_hide_value = hide_value; return *this; } -}; + DumpValueObjectOptions& + SetRunValidator (bool run = true) + { + m_run_validator = run; + return *this; + } + + DumpValueObjectOptions& + SetUseTypeDisplayName (bool dis = false) + { + m_use_type_display_name = dis; + return *this; + } + + DumpValueObjectOptions& + SetAllowOnelinerMode (bool oneliner = false) + { + m_allow_oneliner_mode = oneliner; + return *this; + } + +}; + class ValueObjectPrinter { public: @@ -285,7 +276,7 @@ protected: uint32_t curr_depth); bool - GetDynamicValueIfNeeded (); + GetMostSpecializedValue (); const char* GetDescriptionForDisplay (); @@ -297,6 +288,9 @@ protected: ShouldPrintValueObject (); bool + ShouldPrintValidation (); + + bool IsNil (); bool @@ -309,6 +303,12 @@ protected: IsAggregate (); bool + PrintValidationMarkerIfNeeded (); + + bool + PrintValidationErrorIfNeeded (); + + bool PrintLocationIfNeeded (); bool @@ -385,6 +385,7 @@ private: std::string m_value; std::string m_summary; std::string m_error; + std::pair<TypeValidatorResult,std::string> m_validation; friend struct StringSummaryFormat; diff --git a/include/lldb/Expression/ClangExpressionParser.h b/include/lldb/Expression/ClangExpressionParser.h index c79494d1a521..0f578c55942e 100644 --- a/include/lldb/Expression/ClangExpressionParser.h +++ b/include/lldb/Expression/ClangExpressionParser.h @@ -147,6 +147,9 @@ private: std::unique_ptr<clang::SelectorTable> m_selector_table; ///< Selector table for Objective-C methods std::unique_ptr<clang::ASTContext> m_ast_context; ///< The AST context used to hold types and names for the parser std::unique_ptr<clang::CodeGenerator> m_code_generator; ///< The Clang object that generates IR + + class LLDBPreprocessorCallbacks; + LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor encounters module imports }; } diff --git a/include/lldb/Expression/ClangExpressionVariable.h b/include/lldb/Expression/ClangExpressionVariable.h index 5ee7a3058946..6c210106d51e 100644 --- a/include/lldb/Expression/ClangExpressionVariable.h +++ b/include/lldb/Expression/ClangExpressionVariable.h @@ -65,6 +65,11 @@ class ClangExpressionVariable public: ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size); + ClangExpressionVariable (ExecutionContextScope *exe_scope, + Value &value, + const ConstString &name, + uint16_t flags = EVNone); + ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp); //---------------------------------------------------------------------- diff --git a/include/lldb/Expression/ClangFunction.h b/include/lldb/Expression/ClangFunction.h index 61d56729f93d..c122b21be279 100644 --- a/include/lldb/Expression/ClangFunction.h +++ b/include/lldb/Expression/ClangFunction.h @@ -285,9 +285,9 @@ public: /// True if the thread plan may simply be discarded if an error occurs. /// /// @return - /// A ThreadPlan for executing the function. + /// A ThreadPlan shared pointer for executing the function. //------------------------------------------------------------------ - ThreadPlan * + lldb::ThreadPlanSP GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t args_addr, const EvaluateExpressionOptions &options, @@ -411,8 +411,10 @@ private: // For ClangFunction only //------------------------------------------------------------------ - std::unique_ptr<ClangExpressionParser> m_parser; ///< The parser responsible for compiling the function. + // Note: the parser needs to be destructed before the execution unit, so + // declare the the execution unit first. std::shared_ptr<IRExecutionUnit> m_execution_unit_sp; + std::unique_ptr<ClangExpressionParser> m_parser; ///< The parser responsible for compiling the function. lldb::ModuleWP m_jit_module_wp; std::string m_name; ///< The name of this clang function - for debugging purposes. diff --git a/include/lldb/Expression/ClangModulesDeclVendor.h b/include/lldb/Expression/ClangModulesDeclVendor.h new file mode 100644 index 000000000000..a35b86a665ff --- /dev/null +++ b/include/lldb/Expression/ClangModulesDeclVendor.h @@ -0,0 +1,58 @@ +//===-- ClangModulesDeclVendor.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _liblldb_ClangModulesDeclVendor_ +#define _liblldb_ClangModulesDeclVendor_ + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Symbol/DeclVendor.h" +#include "lldb/Target/Platform.h" + +#include <vector> + +namespace lldb_private +{ + +class ClangModulesDeclVendor : public DeclVendor +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ClangModulesDeclVendor(); + + virtual + ~ClangModulesDeclVendor(); + + static ClangModulesDeclVendor * + Create(Target &target); + + //------------------------------------------------------------------ + /// Add a module to the list of modules to search. + /// + /// @param[in] path + /// The path to the exact module to be loaded. E.g., if the desired + /// module is std.io, then this should be { "std", "io" }. + /// + /// @param[in] error_stream + /// A stream to populate with the output of the Clang parser when + /// it tries to load the module. + /// + /// @return + /// True if the module could be loaded; false if not. If the + /// compiler encountered a fatal error during a previous module + /// load, then this will always return false for this ModuleImporter. + //------------------------------------------------------------------ + virtual bool + AddModule(std::vector<llvm::StringRef> &path, Stream &error_stream) = 0; +}; + +} +#endif /* defined(_lldb_ClangModulesDeclVendor_) */ diff --git a/include/lldb/Expression/ClangUserExpression.h b/include/lldb/Expression/ClangUserExpression.h index 9d2e9093c0bd..f51c9851789a 100644 --- a/include/lldb/Expression/ClangUserExpression.h +++ b/include/lldb/Expression/ClangUserExpression.h @@ -30,8 +30,6 @@ #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/ExecutionContext.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" - namespace lldb_private { diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h index 3f28351a6928..c15c65c92a3b 100644 --- a/include/lldb/Expression/IRExecutionUnit.h +++ b/include/lldb/Expression/IRExecutionUnit.h @@ -25,7 +25,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" #include "lldb/Core/DataBufferHeap.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangExpressionParser.h" #include "lldb/Expression/IRMemoryMap.h" @@ -56,7 +56,7 @@ class Error; /// then be used as input to the IR interpreter, or the address of the /// executable code can be passed to a thread plan to run in the target. /// -/// This class creates a subclass of LLVM's JITMemoryManager, because that is +/// This class creates a subclass of LLVM's SectionMemoryManager, because that is /// how the JIT emits code. Because LLDB needs to move JIT-compiled code /// into the target process, the IRExecutionUnit knows how to copy the /// emitted code into the target process. @@ -207,101 +207,12 @@ private: DisassembleFunction (Stream &stream, lldb::ProcessSP &process_sp); - class MemoryManager : public llvm::JITMemoryManager + class MemoryManager : public llvm::SectionMemoryManager { public: MemoryManager (IRExecutionUnit &parent); virtual ~MemoryManager(); - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual void setMemoryWritable (); - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual void setMemoryExecutable (); - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual void setPoisonMemory (bool poison) - { - m_default_mm_ap->setPoisonMemory (poison); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual void AllocateGOT() - { - m_default_mm_ap->AllocateGOT(); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual uint8_t *getGOTBase() const - { - return m_default_mm_ap->getGOTBase(); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual uint8_t *startFunctionBody(const llvm::Function *F, - uintptr_t &ActualSize); - - //------------------------------------------------------------------ - /// Allocate room for a dyld stub for a lazy-referenced function, - /// and add it to the m_stubs map - /// - /// @param[in] F - /// The function being referenced. - /// - /// @param[in] StubSize - /// The size of the stub. - /// - /// @param[in] Alignment - /// The required alignment of the stub. - /// - /// @return - /// Allocated space for the stub. - //------------------------------------------------------------------ - virtual uint8_t *allocateStub(const llvm::GlobalValue* F, - unsigned StubSize, - unsigned Alignment); - - //------------------------------------------------------------------ - /// Complete the body of a function, and add it to the m_functions map - /// - /// @param[in] F - /// The function being completed. - /// - /// @param[in] FunctionStart - /// The first instruction of the function. - /// - /// @param[in] FunctionEnd - /// The last byte of the last instruction of the function. - //------------------------------------------------------------------ - virtual void endFunctionBody(const llvm::Function *F, - uint8_t *FunctionStart, - uint8_t *FunctionEnd); - //------------------------------------------------------------------ - /// Allocate space for an unspecified purpose, and add it to the - /// m_spaceBlocks map - /// - /// @param[in] Size - /// The size of the area. - /// - /// @param[in] Alignment - /// The required alignment of the area. - /// - /// @return - /// Allocated space. - //------------------------------------------------------------------ - virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); //------------------------------------------------------------------ /// Allocate space for executable code, and add it to the @@ -347,22 +258,6 @@ private: bool IsReadOnly); //------------------------------------------------------------------ - /// Allocate space for a global variable, and add it to the - /// m_spaceBlocks map - /// - /// @param[in] Size - /// The size of the variable. - /// - /// @param[in] Alignment - /// The required alignment of the variable. - /// - /// @return - /// Allocated space for the global. - //------------------------------------------------------------------ - virtual uint8_t *allocateGlobal(uintptr_t Size, - unsigned Alignment); - - //------------------------------------------------------------------ /// Called when object loading is complete and section page /// permissions can be applied. Currently unimplemented for LLDB. /// @@ -380,52 +275,8 @@ private: return false; } - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual void deallocateFunctionBody(void *Body); - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual size_t GetDefaultCodeSlabSize() { - return m_default_mm_ap->GetDefaultCodeSlabSize(); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual size_t GetDefaultDataSlabSize() { - return m_default_mm_ap->GetDefaultDataSlabSize(); - } - - virtual size_t GetDefaultStubSlabSize() { - return m_default_mm_ap->GetDefaultStubSlabSize(); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual unsigned GetNumCodeSlabs() { - return m_default_mm_ap->GetNumCodeSlabs(); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual unsigned GetNumDataSlabs() { - return m_default_mm_ap->GetNumDataSlabs(); - } - - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ - virtual unsigned GetNumStubSlabs() { - return m_default_mm_ap->GetNumStubSlabs(); - } - virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { - return m_default_mm_ap->registerEHFrames(Addr, LoadAddr, Size); + return; } //------------------------------------------------------------------ @@ -436,7 +287,7 @@ private: return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure); } private: - std::unique_ptr<JITMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it. + std::unique_ptr<SectionMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it. IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for. }; diff --git a/include/lldb/Host/Config.h b/include/lldb/Host/Config.h index af6b98a7912a..7872eb95aab6 100644 --- a/include/lldb/Host/Config.h +++ b/include/lldb/Host/Config.h @@ -14,6 +14,10 @@ #include "lldb/Host/macosx/Config.h" +#elif defined(__ANDROID_NDK__) + +#include "lldb/Host/android/Config.h" + #elif defined(__linux__) || defined(__GNU__) #include "lldb/Host/linux/Config.h" diff --git a/include/lldb/Host/ConnectionFileDescriptor.h b/include/lldb/Host/ConnectionFileDescriptor.h new file mode 100644 index 000000000000..0d486a34c8d0 --- /dev/null +++ b/include/lldb/Host/ConnectionFileDescriptor.h @@ -0,0 +1,15 @@ +//===-- ConnectionFileDescriptor.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Host_ConnectionFileDescriptor_h_ +#define liblldb_Host_ConnectionFileDescriptor_h_ + +#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" + +#endif diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h index 5cba8465d654..9fce193efc9f 100644 --- a/include/lldb/Host/Editline.h +++ b/include/lldb/Host/Editline.h @@ -7,202 +7,360 @@ // //===----------------------------------------------------------------------===// +//TODO: wire up window size changes + +// If we ever get a private copy of libedit, there are a number of defects that would be nice to fix; +// a) Sometimes text just disappears while editing. In an 80-column editor paste the following text, without +// the quotes: +// "This is a test of the input system missing Hello, World! Do you disappear when it gets to a particular length?" +// Now press ^A to move to the start and type 3 characters, and you'll see a good amount of the text will +// disappear. It's still in the buffer, just invisible. +// b) The prompt printing logic for dealing with ANSI formatting characters is broken, which is why we're +// working around it here. +// c) When resizing the terminal window, if the cursor moves between rows libedit will get confused. +// d) The incremental search uses escape to cancel input, so it's confused by ANSI sequences starting with escape. +// e) Emoji support is fairly terrible, presumably it doesn't understand composed characters? + #ifndef liblldb_Editline_h_ #define liblldb_Editline_h_ #if defined(__cplusplus) +#include <sstream> +#include <vector> + +// components needed to handle wide characters ( <codecvt>, codecvt_utf8, libedit built with '--enable-widec' ) +// are not consistenly available on non-OSX platforms. The wchar_t versions of libedit functions will only be +// used in cases where this is true. This is a compile time dependecy, for now selected per target Platform +#if defined (__APPLE__) +#define LLDB_EDITLINE_USE_WCHAR 1 +#include <codecvt> +#else +#define LLDB_EDITLINE_USE_WCHAR 0 +#endif + #include "lldb/lldb-private.h" +#include "lldb/Host/ConnectionFileDescriptor.h" -#include <stdio.h> -#ifdef _WIN32 +#if defined(_WIN32) #include "lldb/Host/windows/editlinewin.h" #else +#if !defined(__ANDROID_NDK__) #include <histedit.h> #endif +#endif #include <string> #include <vector> -#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Host/Condition.h" +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/Predicate.h" namespace lldb_private { + namespace line_editor { -//---------------------------------------------------------------------- -/// @class Editline Editline.h "lldb/Host/Editline.h" -/// @brief A class that encapsulates editline functionality. -//---------------------------------------------------------------------- -class EditlineHistory; - -typedef std::shared_ptr<EditlineHistory> EditlineHistorySP; - -class Editline -{ -public: - typedef LineStatus (*LineCompletedCallbackType) ( - Editline *editline, - StringList &lines, - uint32_t line_idx, - Error &error, - void *baton); - - typedef int (*CompleteCallbackType) ( - const char *current_line, - const char *cursor, - const char *last_char, - int skip_first_n_matches, - int max_matches, - StringList &matches, - void *baton); - - typedef int (*GetCharCallbackType) ( - ::EditLine *, - char *c); - - Editline(const char *prog, // Used for the history file and for editrc program name - const char *prompt, - bool configure_for_multiline, - FILE *fin, - FILE *fout, - FILE *ferr); - - ~Editline(); - - Error - GetLine (std::string &line, - bool &interrupted); - - Error - GetLines (const std::string &end_line, - StringList &lines, - bool &interrupted); - - bool - LoadHistory (); - - bool - SaveHistory (); - - FILE * - GetInputFile (); - - FILE * - GetOutputFile (); - - FILE * - GetErrorFile (); - - bool - GettingLine () const - { - return m_getting_line; - } - - void - Hide (); + // type alias's to help manage 8 bit and wide character versions of libedit +#if LLDB_EDITLINE_USE_WCHAR + using EditLineStringType = std::wstring; + using EditLineStringStreamType = std::wstringstream; + using EditLineCharType = wchar_t; +#else + using EditLineStringType=std::string; + using EditLineStringStreamType = std::stringstream; + using EditLineCharType = char; +#endif - void - Refresh(); + typedef int (* EditlineGetCharCallbackType)(::EditLine * editline, EditLineCharType * c); + typedef unsigned char (* EditlineCommandCallbackType)(::EditLine * editline, int ch); + typedef const char * (* EditlinePromptCallbackType)(::EditLine * editline); - bool - Interrupt (); + class EditlineHistory; + + typedef std::shared_ptr<EditlineHistory> EditlineHistorySP; - void - SetAutoCompleteCallback (CompleteCallbackType callback, - void *baton) - { - m_completion_callback = callback; - m_completion_callback_baton = baton; - } + typedef bool (* IsInputCompleteCallbackType) ( + Editline * editline, + StringList & lines, + void * baton); + + typedef int (* FixIndentationCallbackType) ( + Editline * editline, + const StringList & lines, + int cursor_position, + void * baton); + + typedef int (* CompleteCallbackType) ( + const char * current_line, + const char * cursor, + const char * last_char, + int skip_first_n_matches, + int max_matches, + StringList & matches, + void * baton); + + /// Status used to decide when and how to start editing another line in multi-line sessions + enum class EditorStatus + { + + /// The default state proceeds to edit the current line + Editing, + + /// Editing complete, returns the complete set of edited lines + Complete, + + /// End of input reported + EndOfInput, - void - SetLineCompleteCallback (LineCompletedCallbackType callback, - void *baton) - { - m_line_complete_callback = callback; - m_line_complete_callback_baton = baton; + /// Editing interrupted + Interrupted + }; + + /// Established locations that can be easily moved among with MoveCursor + enum class CursorLocation + { + /// The start of the first line in a multi-line edit session + BlockStart, + + /// The start of the current line in a multi-line edit session + EditingPrompt, + + /// The location of the cursor on the current line in a multi-line edit session + EditingCursor, + + /// The location immediately after the last character in a multi-line edit session + BlockEnd + }; } - - size_t - Push (const char *bytes, size_t len); - - static int - GetCharFromInputFileCallback (::EditLine *e, char *c); - - void - SetGetCharCallback (GetCharCallbackType callback); - const char * - GetPrompt(); + using namespace line_editor; - void - SetPrompt (const char *p); - - void - ShowLineNumbers (bool enable, uint32_t line_offset) + /// Instances of Editline provide an abstraction over libedit's EditLine facility. Both + /// single- and multi-line editing are supported. + class Editline { - m_prompt_with_line_numbers = enable; - m_line_offset = line_offset; - } - -private: + public: + Editline (const char * editor_name, FILE * input_file, FILE * output_file, FILE * error_file, bool color_prompts); + + ~Editline(); + + /// Uses the user data storage of EditLine to retrieve an associated instance of Editline. + static Editline * + InstanceFor (::EditLine * editline); + + /// Sets a string to be used as a prompt, or combined with a line number to form a prompt. + void + SetPrompt (const char * prompt); + + /// Sets an alternate string to be used as a prompt for the second line and beyond in multi-line + /// editing scenarios. + void + SetContinuationPrompt (const char * continuation_prompt); + + /// Required to update the width of the terminal registered for I/O. It is critical that this + /// be correct at all times. + void + TerminalSizeChanged(); + + /// Returns the prompt established by SetPrompt() + const char * + GetPrompt(); + + /// Returns the index of the line currently being edited + uint32_t + GetCurrentLine(); - Error - PrivateGetLine(std::string &line); - - unsigned char - HandleCompletion (int ch); + /// Hides the current input session in preparation for output + void + Hide(); + + /// Prepare to return to editing after a call to Hide() + void + Refresh(); - static unsigned char - CallbackEditPrevLine (::EditLine *e, int ch); - - static unsigned char - CallbackEditNextLine (::EditLine *e, int ch); - - static unsigned char - CallbackComplete (::EditLine *e, int ch); + /// Interrupt the current edit as if ^C was pressed + bool + Interrupt(); + + /// Register a callback for the tab key + void + SetAutoCompleteCallback (CompleteCallbackType callback, void * baton); + + /// Register a callback for testing whether multi-line input is complete + void + SetIsInputCompleteCallback (IsInputCompleteCallbackType callback, void * baton); + + /// 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); - static const char * - GetPromptCallback (::EditLine *e); + /// Prompts for and reads a single line of user input. + bool + GetLine (std::string &line, bool &interrupted); + + /// Prompts for and reads a multi-line batch of user input. + bool + GetLines (int first_line_number, StringList &lines, bool &interrupted); + + private: + + /// Sets the lowest line number for multi-line editing sessions. A value of zero suppresses + /// line number printing in the prompt. + void + SetBaseLineNumber (int line_number); + + /// Returns the complete prompt by combining the prompt or continuation prompt with line numbers + /// as appropriate. The line index is a zero-based index into the current multi-line session. + std::string + PromptForIndex (int line_index); + + /// Sets the current line index between line edits to allow free movement between lines. Updates + /// the prompt to match. + void + SetCurrentLine (int line_index); + + /// Determines the width of the prompt in characters. The width is guaranteed to be the same for + /// all lines of the current multi-line session. + int + GetPromptWidth(); + + /// Returns true if the underlying EditLine session's keybindings are Emacs-based, or false if + /// they are VI-based. + bool + IsEmacs(); + + /// Returns true if the current EditLine buffer contains nothing but spaces, or is empty. + bool + IsOnlySpaces(); + + /// Helper method used by MoveCursor to determine relative line position. + int + GetLineIndexForLocation (CursorLocation location, int cursor_row); + + /// Move the cursor from one well-established location to another using relative line positioning + /// and absolute column positioning. + void + MoveCursor (CursorLocation from, CursorLocation to); + + /// Clear from cursor position to bottom of screen and print input lines including prompts, optionally + /// starting from a specific line. Lines are drawn with an extra space at the end to reserve room for + /// the rightmost cursor position. + void + DisplayInput (int firstIndex = 0); + + /// Counts the number of rows a given line of content will end up occupying, taking into account both + /// the preceding prompt and a single trailing space occupied by a cursor when at the end of the line. + int + CountRowsForLine (const EditLineStringType & content); + + /// Save the line currently being edited + void + SaveEditedLine(); + + /// Convert the current input lines into a UTF8 StringList + StringList + GetInputAsStringList(int line_count = UINT32_MAX); + + /// Replaces the current multi-line session with the next entry from history. When the parameter is + /// true it will take the next earlier entry from history, when it is false it takes the next most + /// recent. + unsigned char + RecallHistory (bool earlier); + + /// Character reading implementation for EditLine that supports our multi-line editing trickery. + int + GetCharacter (EditLineCharType * c); + + /// Prompt implementation for EditLine. + const char * + Prompt(); + + /// Line break command used when return is pressed in multi-line mode. + unsigned char + BreakLineCommand (int ch); + + /// Delete command used when delete is pressed in multi-line mode. + unsigned char + DeleteNextCharCommand (int ch); + + /// Delete command used when backspace is pressed in multi-line mode. + unsigned char + DeletePreviousCharCommand (int ch); + + /// Line navigation command used when ^P or up arrow are pressed in multi-line mode. + unsigned char + PreviousLineCommand (int ch); + + /// Line navigation command used when ^N or down arrow are pressed in multi-line mode. + unsigned char + NextLineCommand (int ch); + + /// Buffer start command used when Esc < is typed in multi-line emacs mode. + unsigned char + BufferStartCommand (int ch); + + /// Buffer end command used when Esc > is typed in multi-line emacs mode. + unsigned char + BufferEndCommand (int ch); - static Editline * - GetClientData (::EditLine *e); - - static FILE * - GetFilePointer (::EditLine *e, int fd); + /// Context-sensitive tab insertion or code completion command used when the tab key is typed. + unsigned char + TabCommand (int ch); + + /// Respond to normal character insertion by fixing line indentation + unsigned char + FixIndentationCommand (int ch); - enum class Command - { - None = 0, - EditPrevLine, - EditNextLine, - }; - ::EditLine *m_editline; - EditlineHistorySP m_history_sp; - std::string m_prompt; - std::string m_lines_prompt; - lldb_private::Predicate<bool> m_getting_char; - CompleteCallbackType m_completion_callback; - void *m_completion_callback_baton; - LineCompletedCallbackType m_line_complete_callback; - void *m_line_complete_callback_baton; - Command m_lines_command; - uint32_t m_line_offset; - uint32_t m_lines_curr_line; - uint32_t m_lines_max_line; - ConnectionFileDescriptor m_file; - bool m_prompt_with_line_numbers; - bool m_getting_line; - bool m_got_eof; // Set to true when we detect EOF - bool m_interrupted; - - DISALLOW_COPY_AND_ASSIGN(Editline); -}; + /// Revert line command used when moving between lines. + unsigned char + RevertLineCommand (int ch); -} // namespace lldb_private + /// Ensures that the current EditLine instance is properly configured for single or multi-line editing. + void + ConfigureEditor (bool multiline); + + private: +#if LLDB_EDITLINE_USE_WCHAR + std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv; +#endif + ::EditLine * m_editline = nullptr; + EditlineHistorySP m_history_sp; + bool m_in_history = false; + std::vector<EditLineStringType> m_live_history_lines; + bool m_multiline_enabled = false; + std::vector<EditLineStringType> m_input_lines; + EditorStatus m_editor_status; + bool m_editor_getting_char = false; + bool m_color_prompts = true; + int m_terminal_width = 0; + int m_base_line_number = 0; + unsigned m_current_line_index = 0; + int m_current_line_rows = -1; + int m_revert_cursor_index = 0; + int m_line_number_digits = 3; + std::string m_set_prompt; + std::string m_set_continuation_prompt; + std::string m_current_prompt; + bool m_needs_prompt_repaint = false; + std::string m_editor_name; + FILE * m_input_file; + 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; + const char * m_fix_indentation_callback_chars = nullptr; + CompleteCallbackType m_completion_callback = nullptr; + void * m_completion_callback_baton = nullptr; + }; +} #endif // #if defined(__cplusplus) -#endif // liblldb_Host_h_ +#endif // liblldb_Editline_h_ diff --git a/include/lldb/Host/FileSpec.h b/include/lldb/Host/FileSpec.h index ef73bb2ede0f..173d948e687b 100644 --- a/include/lldb/Host/FileSpec.h +++ b/include/lldb/Host/FileSpec.h @@ -246,7 +246,7 @@ public: Compare (const FileSpec& lhs, const FileSpec& rhs, bool full); static bool - Equal (const FileSpec& a, const FileSpec& b, bool full); + Equal (const FileSpec& a, const FileSpec& b, bool full, bool remove_backups = false); //------------------------------------------------------------------ /// Dump this object to a Stream. @@ -582,6 +582,20 @@ public: static void Normalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax = ePathSyntaxHostNative); static void DeNormalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax = ePathSyntaxHostNative); + + //------------------------------------------------------------------ + /// Run through the input string, replaying the effect of any ".." and produce + /// the resultant path. The input path is not required to be in the host file system + /// format, but it is required to be normalized to that system. + /// + /// @param[in] input + /// The input path to analyze. + /// + /// @param[out] result + /// The backup-resolved path will be written here. + //------------------------------------------------------------------ + static void RemoveBackupDots (const ConstString &input_const_str, ConstString &result_const_str); + //------------------------------------------------------------------ /// Change the file specified with a new path. /// diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h index 19ed7b01e80f..ce12689fc047 100644 --- a/include/lldb/Host/Host.h +++ b/include/lldb/Host/Host.h @@ -21,6 +21,7 @@ #include "lldb/Core/StringList.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/HostThread.h" namespace lldb_private { @@ -38,9 +39,6 @@ class Host { public: - /// A value of std::numeric_limits<uint32_t>::max() is used if there is no practical limit. - static const uint32_t MAX_THREAD_NAME_LENGTH; - typedef bool (*MonitorChildProcessCallback) (void *callback_baton, lldb::pid_t pid, bool exited, @@ -86,11 +84,8 @@ public: /// /// @see static void Host::StopMonitoringChildProcess (uint32_t) //------------------------------------------------------------------ - static lldb::thread_t - StartMonitoringChildProcess (MonitorChildProcessCallback callback, - void *callback_baton, - lldb::pid_t pid, - bool monitor_signals); + static HostThread StartMonitoringChildProcess(MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, + bool monitor_signals); enum SystemLogType { @@ -140,36 +135,6 @@ public: static void WillTerminate (); - //------------------------------------------------------------------ - /// Host specific thread created function call. - /// - /// This function call lets the current host OS do any thread - /// specific initialization that it needs, including naming the - /// thread. No cleanup routine is expected to be called - /// - /// @param[in] name - /// The current thread's name in the current process. - //------------------------------------------------------------------ - static void - ThreadCreated (const char *name); - - static lldb::thread_t - ThreadCreate (const char *name, - lldb::thread_func_t function, - lldb::thread_arg_t thread_arg, - Error *err); - - static bool - ThreadCancel (lldb::thread_t thread, - Error *error); - - static bool - ThreadDetach (lldb::thread_t thread, - Error *error); - static bool - ThreadJoin (lldb::thread_t thread, - lldb::thread_result_t *thread_result_ptr, - Error *error); typedef void (*ThreadLocalStorageCleanupCallback) (void *p); @@ -182,65 +147,6 @@ public: static void ThreadLocalStorageSet(lldb::thread_key_t key, void *value); - //------------------------------------------------------------------ - /// Gets the name of a thread in a process. - /// - /// This function will name a thread in a process using it's own - /// thread name pool, and also will attempt to set a thread name - /// using any supported host OS APIs. - /// - /// @param[in] pid - /// The process ID in which we are trying to get the name of - /// a thread. - /// - /// @param[in] tid - /// The thread ID for which we are trying retrieve the name of. - /// - /// @return - /// A std::string containing the thread name. - //------------------------------------------------------------------ - static std::string - GetThreadName (lldb::pid_t pid, lldb::tid_t tid); - - //------------------------------------------------------------------ - /// Sets the name of a thread in the current process. - /// - /// @param[in] pid - /// The process ID in which we are trying to name a thread. - /// - /// @param[in] tid - /// The thread ID which we are trying to name. - /// - /// @param[in] name - /// The current thread's name in the current process to \a name. - /// - /// @return - /// \b true if the thread name was able to be set, \b false - /// otherwise. - //------------------------------------------------------------------ - static bool - SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name); - - //------------------------------------------------------------------ - /// Sets a shortened name of a thread in the current process. - /// - /// @param[in] pid - /// The process ID in which we are trying to name a thread. - /// - /// @param[in] tid - /// The thread ID which we are trying to name. - /// - /// @param[in] name - /// The current thread's name in the current process to \a name. - /// - /// @param[in] len - /// The maximum length for the thread's shortened name. - /// - /// @return - /// \b true if the thread name was able to be set, \b false - /// otherwise. - static bool - SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name, size_t len); //------------------------------------------------------------------ /// Given an address in the current process (the process that @@ -330,11 +236,9 @@ public: GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info); #if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined (__NetBSD__) - static short - GetPosixspawnFlags (ProcessLaunchInfo &launch_info); + static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info); - static Error - LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid); + static Error LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid); static bool AddPosixSpawnFileAction(void *file_actions, const FileAction *info, Log *log, Error &error); #endif @@ -355,7 +259,7 @@ public: int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit std::string *command_output, // Pass NULL if you don't want the command output uint32_t timeout_sec, - const char *shell = LLDB_DEFAULT_SHELL); + bool run_in_default_shell = true); static lldb::DataBufferSP GetAuxvData (lldb_private::Process *process); @@ -363,9 +267,6 @@ public: static lldb::DataBufferSP GetAuxvData (lldb::pid_t pid); - static lldb::TargetSP - GetDummyTarget (Debugger &debugger); - static bool OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no); diff --git a/include/lldb/Host/HostInfoBase.h b/include/lldb/Host/HostInfoBase.h index f890dbc0b01b..5a8a06329500 100644 --- a/include/lldb/Host/HostInfoBase.h +++ b/include/lldb/Host/HostInfoBase.h @@ -45,6 +45,14 @@ class HostInfoBase static uint32_t GetNumberCPUS(); //------------------------------------------------------------------ + /// Returns the maximum length of a thread name on this platform. + /// + /// @return + /// Maximum length of a thread name on this platform. + //------------------------------------------------------------------ + static uint32_t GetMaxThreadNameLength(); + + //------------------------------------------------------------------ /// Gets the host vendor string. /// /// @return @@ -110,6 +118,7 @@ class HostInfoBase static bool ComputeTempFileDirectory(FileSpec &file_spec); static bool ComputeHeaderDirectory(FileSpec &file_spec); static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); + static bool ComputeClangDirectory(FileSpec &file_spec); static bool ComputeUserPluginsDirectory(FileSpec &file_spec); static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); diff --git a/include/lldb/Host/HostNativeProcess.h b/include/lldb/Host/HostNativeProcess.h new file mode 100644 index 000000000000..b48956436116 --- /dev/null +++ b/include/lldb/Host/HostNativeProcess.h @@ -0,0 +1,27 @@ +//===-- HostNativeProcess.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_HostNativeProcess_h_ +#define lldb_Host_HostNativeProcess_h_ + +#if defined(_WIN32) +#include "lldb/Host/windows/HostProcessWindows.h" +namespace lldb_private +{ +typedef HostProcessWindows HostNativeProcess; +} +#else +#include "lldb/Host/posix/HostProcessPosix.h" +namespace lldb_private +{ +typedef HostProcessPosix HostNativeProcess; +} +#endif + +#endif diff --git a/include/lldb/Host/HostNativeProcessBase.h b/include/lldb/Host/HostNativeProcessBase.h new file mode 100644 index 000000000000..ba16bf2b876f --- /dev/null +++ b/include/lldb/Host/HostNativeProcessBase.h @@ -0,0 +1,57 @@ +//===-- HostNativeProcessBase.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_HostNativeProcessBase_h_ +#define lldb_Host_HostNativeProcessBase_h_ + +#include "lldb/Core/Error.h" +#include "lldb/Host/HostProcess.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" + +namespace lldb_private +{ + +class HostThread; + +class HostNativeProcessBase +{ + DISALLOW_COPY_AND_ASSIGN(HostNativeProcessBase); + + public: + HostNativeProcessBase() + : m_process(LLDB_INVALID_PROCESS) + { + } + explicit HostNativeProcessBase(lldb::process_t process) + : m_process(process) + {} + virtual ~HostNativeProcessBase() {} + + virtual Error Terminate() = 0; + virtual Error GetMainModule(FileSpec &file_spec) const = 0; + + virtual lldb::pid_t GetProcessId() const = 0; + virtual bool IsRunning() const = 0; + + lldb::process_t + GetSystemHandle() const + { + return m_process; + } + + virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals) = 0; + + protected: + lldb::process_t m_process; +}; + +} + +#endif diff --git a/include/lldb/Host/HostNativeThread.h b/include/lldb/Host/HostNativeThread.h new file mode 100644 index 000000000000..f39c775df8e3 --- /dev/null +++ b/include/lldb/Host/HostNativeThread.h @@ -0,0 +1,25 @@ +//===-- HostNativeThread.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_HostNativeThread_h_ +#define lldb_Host_HostNativeThread_h_ + +#include "HostNativeThreadForward.h" + +#if defined(_WIN32) +#include "lldb/Host/windows/HostThreadWindows.h" +#elif defined(__linux__) +#include "lldb/Host/linux/HostThreadLinux.h" +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include "lldb/Host/freebsd/HostThreadFreeBSD.h" +#elif defined(__APPLE__) +#include "lldb/Host/macosx/HostThreadMacOSX.h" +#endif + +#endif diff --git a/include/lldb/Host/HostNativeThreadBase.h b/include/lldb/Host/HostNativeThreadBase.h new file mode 100644 index 000000000000..c89c6e16533e --- /dev/null +++ b/include/lldb/Host/HostNativeThreadBase.h @@ -0,0 +1,53 @@ +//===-- HostNativeThreadBase.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_HostNativeThreadBase_h_ +#define lldb_Host_HostNativeThreadBase_h_ + +#include "lldb/Core/Error.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" + +namespace lldb_private +{ + +#if defined(_WIN32) +#define THREAD_ROUTINE __stdcall +#else +#define THREAD_ROUTINE +#endif + +class HostNativeThreadBase +{ + friend class ThreadLauncher; + DISALLOW_COPY_AND_ASSIGN(HostNativeThreadBase); + + public: + HostNativeThreadBase(); + explicit HostNativeThreadBase(lldb::thread_t thread); + virtual ~HostNativeThreadBase() {} + + virtual Error Join(lldb::thread_result_t *result) = 0; + virtual Error Cancel() = 0; + virtual bool IsJoinable() const; + virtual void Reset(); + lldb::thread_t Release(); + + lldb::thread_t GetSystemHandle() const; + lldb::thread_result_t GetResult() const; + + 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; +}; +} + +#endif diff --git a/include/lldb/Host/HostNativeThreadForward.h b/include/lldb/Host/HostNativeThreadForward.h new file mode 100644 index 000000000000..e6bd426673b3 --- /dev/null +++ b/include/lldb/Host/HostNativeThreadForward.h @@ -0,0 +1,30 @@ +//===-- HostNativeThreadForward.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_HostNativeThreadForward_h_ +#define lldb_Host_HostNativeThreadForward_h_ + +namespace lldb_private +{ +#if defined(_WIN32) +class HostThreadWindows; +typedef HostThreadWindows HostNativeThread; +#elif defined(__linux__) +class HostThreadLinux; +typedef HostThreadLinux HostNativeThread; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +class HostThreadFreeBSD; +typedef HostThreadFreeBSD HostNativeThread; +#elif defined(__APPLE__) +class HostThreadMacOSX; +typedef HostThreadMacOSX HostNativeThread; +#endif +} + +#endif diff --git a/include/lldb/Host/HostProcess.h b/include/lldb/Host/HostProcess.h index 2c10709ce942..aff779aee219 100644 --- a/include/lldb/Host/HostProcess.h +++ b/include/lldb/Host/HostProcess.h @@ -10,6 +10,8 @@ #ifndef lldb_Host_HostProcess_h_ #define lldb_Host_HostProcess_h_ +#include "lldb/lldb-types.h" + //---------------------------------------------------------------------- /// @class HostInfo HostInfo.h "lldb/Host/HostProcess.h" /// @brief A class that represents a running process on the host machine. @@ -26,19 +28,36 @@ /// //---------------------------------------------------------------------- -#if defined(_WIN32) -#include "lldb/Host/windows/HostProcessWindows.h" -#define HOST_PROCESS_TYPE HostProcessWindows -#else -#include "lldb/Host/posix/HostProcessPosix.h" -#define HOST_PROCESS_TYPE HostProcessPosix -#endif - namespace lldb_private { - typedef HOST_PROCESS_TYPE HostProcess; -} -#undef HOST_PROCESS_TYPE +class HostNativeProcessBase; +class HostThread; + +class HostProcess +{ + public: + typedef bool (*MonitorCallback)(void *callback_baton, lldb::pid_t process, bool exited, int signal, int status); + + HostProcess(); + HostProcess(lldb::process_t process); + ~HostProcess(); + + Error Terminate(); + Error GetMainModule(FileSpec &file_spec) const; + + lldb::pid_t GetProcessId() const; + bool IsRunning() const; + + HostThread StartMonitoring(MonitorCallback callback, void *callback_baton, bool monitor_signals); + + HostNativeProcessBase &GetNativeProcess(); + const HostNativeProcessBase &GetNativeProcess() const; + + private: + std::shared_ptr<HostNativeProcessBase> m_native_process; +}; + +} #endif diff --git a/include/lldb/Host/HostThread.h b/include/lldb/Host/HostThread.h new file mode 100644 index 000000000000..9fdf9f9618b5 --- /dev/null +++ b/include/lldb/Host/HostThread.h @@ -0,0 +1,56 @@ +//===-- HostThread.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_HostThread_h_ +#define lldb_Host_HostThread_h_ + +#include "lldb/Core/Error.h" +#include "lldb/Host/HostNativeThreadForward.h" +#include "lldb/lldb-types.h" + +#include <memory> + +namespace lldb_private +{ + +class HostNativeThreadBase; + +//---------------------------------------------------------------------- +/// @class HostInfo HostInfo.h "lldb/Host/HostThread.h" +/// @brief A class that represents a thread running inside of a process on the +/// local machine. +/// +/// HostThread allows querying and manipulation of threads running on the host +/// machine. +/// +//---------------------------------------------------------------------- +class HostThread +{ + public: + HostThread(); + HostThread(lldb::thread_t thread); + + Error Join(lldb::thread_result_t *result); + Error Cancel(); + void Reset(); + lldb::thread_t Release(); + + bool IsJoinable() const; + HostNativeThread &GetNativeThread(); + const HostNativeThread &GetNativeThread() const; + lldb::thread_result_t GetResult() const; + + bool EqualsThread(lldb::thread_t thread) const; + + private: + std::shared_ptr<HostNativeThreadBase> m_native_thread; +}; +} + +#endif diff --git a/include/lldb/Host/MonitoringProcessLauncher.h b/include/lldb/Host/MonitoringProcessLauncher.h new file mode 100644 index 000000000000..3c3e66108f8a --- /dev/null +++ b/include/lldb/Host/MonitoringProcessLauncher.h @@ -0,0 +1,30 @@ +//===-- MonitoringProcessLauncher.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_MonitoringProcessLauncher_h_ +#define lldb_Host_MonitoringProcessLauncher_h_ + +#include "lldb/Host/ProcessLauncher.h" + +namespace lldb_private +{ + +class MonitoringProcessLauncher : public ProcessLauncher +{ + public: + explicit MonitoringProcessLauncher(std::unique_ptr<ProcessLauncher> delegate_launcher); + + virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error); + + private: + std::unique_ptr<ProcessLauncher> m_delegate_launcher; +}; +} + +#endif diff --git a/include/lldb/Host/Pipe.h b/include/lldb/Host/Pipe.h index b36c85cfbe87..a5502efa78ed 100644 --- a/include/lldb/Host/Pipe.h +++ b/include/lldb/Host/Pipe.h @@ -7,77 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Pipe_h_ -#define liblldb_Pipe_h_ -#if defined(__cplusplus) +#ifndef liblldb_Host_Pipe_h_ +#define liblldb_Host_Pipe_h_ -#include <stdarg.h> -#include <stdio.h> -#include <sys/types.h> - -#include "lldb/lldb-private.h" - -namespace lldb_private { - -//---------------------------------------------------------------------- -/// @class Pipe Pipe.h "lldb/Host/Pipe.h" -/// @brief A class that abtracts unix style pipes. -/// -/// A class that abstracts the LLDB core from host pipe functionality. -//---------------------------------------------------------------------- -class Pipe +#if defined(_WIN32) +#include "lldb/Host/windows/PipeWindows.h" +namespace lldb_private { -public: - static int kInvalidDescriptor; - - Pipe(); - - ~Pipe(); - - bool - Open(); - - bool - IsValid() const; - - bool - ReadDescriptorIsValid() const; - - bool - WriteDescriptorIsValid() const; - - int - GetReadFileDescriptor() const; - - int - GetWriteFileDescriptor() const; - - // Close both descriptors - void - Close(); - - bool - CloseReadFileDescriptor(); - - bool - CloseWriteFileDescriptor(); - - int - ReleaseReadFileDescriptor(); - - int - ReleaseWriteFileDescriptor(); - - size_t - Read (void *buf, size_t size); - - size_t - Write (const void *buf, size_t size); -private: - int m_fds[2]; -}; - -} // namespace lldb_private +typedef PipeWindows Pipe; +} +#else +#include "lldb/Host/posix/PipePosix.h" +namespace lldb_private +{ +typedef PipePosix Pipe; +} +#endif -#endif // #if defined(__cplusplus) -#endif // liblldb_Pipe_h_ +#endif // liblldb_Host_Pipe_h_ diff --git a/include/lldb/Host/PipeBase.h b/include/lldb/Host/PipeBase.h new file mode 100644 index 000000000000..8cad2507d32c --- /dev/null +++ b/include/lldb/Host/PipeBase.h @@ -0,0 +1,54 @@ +//===-- PipeBase.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Host_PipeBase_h_ +#define liblldb_Host_PipeBase_h_ + +#include <chrono> +#include <string> + +#include "lldb/Core/Error.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private +{ +class PipeBase +{ + public: + virtual ~PipeBase(); + + virtual Error CreateNew(bool child_process_inherit) = 0; + virtual Error CreateNew(llvm::StringRef name, bool child_process_inherit) = 0; + + virtual Error OpenAsReader(llvm::StringRef name, bool child_process_inherit) = 0; + + Error OpenAsWriter(llvm::StringRef name, bool child_process_inherit); + virtual Error OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout) = 0; + + virtual bool CanRead() const = 0; + virtual bool CanWrite() const = 0; + + virtual int GetReadFileDescriptor() const = 0; + virtual int GetWriteFileDescriptor() const = 0; + virtual int ReleaseReadFileDescriptor() = 0; + virtual int ReleaseWriteFileDescriptor() = 0; + + // Close both descriptors + virtual void Close() = 0; + + // Delete named pipe. + virtual Error Delete(llvm::StringRef name) = 0; + + virtual Error Write(const void *buf, size_t size, size_t &bytes_written) = 0; + virtual Error ReadWithTimeout(void *buf, size_t size, const std::chrono::microseconds &timeout, size_t &bytes_read) = 0; + Error Read(void *buf, size_t size, size_t &bytes_read); +}; +} + +#endif diff --git a/include/lldb/Host/Predicate.h b/include/lldb/Host/Predicate.h index f0e83ea5894b..ae6c99155fe0 100644 --- a/include/lldb/Host/Predicate.h +++ b/include/lldb/Host/Predicate.h @@ -11,6 +11,7 @@ #define liblldb_Predicate_h_ #if defined(__cplusplus) +#include "lldb/lldb-defines.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/Condition.h" #include <stdint.h> diff --git a/include/lldb/Host/ProcessLauncher.h b/include/lldb/Host/ProcessLauncher.h new file mode 100644 index 000000000000..14685fd3c53a --- /dev/null +++ b/include/lldb/Host/ProcessLauncher.h @@ -0,0 +1,28 @@ +//===-- ProcessLauncher.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_ProcessLauncher_h_ +#define lldb_Host_ProcessLauncher_h_ + +namespace lldb_private +{ + +class ProcessLaunchInfo; +class Error; +class HostProcess; + +class ProcessLauncher +{ + public: + virtual ~ProcessLauncher() {} + virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error) = 0; +}; +} + +#endif diff --git a/include/lldb/Host/Socket.h b/include/lldb/Host/Socket.h index 0f3aa073001c..77069ae35f79 100644 --- a/include/lldb/Host/Socket.h +++ b/include/lldb/Host/Socket.h @@ -56,16 +56,16 @@ public: // Initialize a Tcp Socket object in listening mode. listen and accept are implemented // separately because the caller may wish to manipulate or query the socket after it is // initialized, but before entering a blocking accept. - static Error TcpListen(llvm::StringRef host_and_port, Socket *&socket, Predicate<uint16_t>* predicate); - static Error TcpConnect(llvm::StringRef host_and_port, Socket *&socket); - static Error UdpConnect(llvm::StringRef host_and_port, Socket *&send_socket, Socket *&recv_socket); - static Error UnixDomainConnect(llvm::StringRef host_and_port, Socket *&socket); - static Error UnixDomainAccept(llvm::StringRef host_and_port, Socket *&socket); + static Error TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket, Predicate<uint16_t>* predicate); + static Error TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket); + static Error UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket); + static Error UnixDomainConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket); + static Error UnixDomainAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket); // Blocks on a listening socket until a connection is received. This method assumes that // |this->m_socket| is a listening socket, created via either TcpListen() or via the native // constructor that takes a NativeSocket, which itself was created via a call to |listen()| - Error BlockingAccept(llvm::StringRef host_and_port, Socket *&socket); + Error BlockingAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket); int GetOption (int level, int option_name, int &option_value); int SetOption (int level, int option_name, int option_value); diff --git a/include/lldb/Host/ThisThread.h b/include/lldb/Host/ThisThread.h new file mode 100644 index 000000000000..23acee9d3fc1 --- /dev/null +++ b/include/lldb/Host/ThisThread.h @@ -0,0 +1,40 @@ +//===-- ThisThread.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_ThisThread_h_ +#define lldb_Host_ThisThread_h_ + +#include "llvm/ADT/StringRef.h" + +#include <string> + +namespace llvm +{ +template <class T> class SmallVectorImpl; +} + +namespace lldb_private +{ + +class ThisThread +{ + private: + ThisThread(); + + public: + // ThisThread common functions. + static void SetName(llvm::StringRef name, int max_length); + + // ThisThread platform-specific functions. + static void SetName(llvm::StringRef name); + static void GetName(llvm::SmallVectorImpl<char> &name); +}; +} + +#endif diff --git a/include/lldb/Host/ThreadLauncher.h b/include/lldb/Host/ThreadLauncher.h new file mode 100644 index 000000000000..b4e4cae4b763 --- /dev/null +++ b/include/lldb/Host/ThreadLauncher.h @@ -0,0 +1,47 @@ +//===-- ThreadLauncher.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_ThreadLauncher_h_ +#define lldb_Host_ThreadLauncher_h_ + +#include "lldb/Core/Error.h" +#include "lldb/Host/HostThread.h" +#include "lldb/lldb-types.h" + +#include "llvm/ADT/StringRef.h" + +namespace lldb_private +{ + +class ThreadLauncher +{ + public: + static HostThread LaunchThread(llvm::StringRef name, + lldb::thread_func_t thread_function, + lldb::thread_arg_t thread_arg, + Error *error_ptr, + size_t min_stack_byte_size = 0); // Minimum stack size in bytes, set stack size to zero for default platform thread stack size + + struct HostThreadCreateInfo + { + std::string thread_name; + lldb::thread_func_t thread_fptr; + lldb::thread_arg_t thread_arg; + + HostThreadCreateInfo(const char *name, lldb::thread_func_t fptr, lldb::thread_arg_t arg) + : thread_name(name ? name : "") + , thread_fptr(fptr) + , thread_arg(arg) + { + } + }; +}; +} + +#endif diff --git a/include/lldb/Host/TimeValue.h b/include/lldb/Host/TimeValue.h index 1792d343a6a6..6de2bfd16a0a 100644 --- a/include/lldb/Host/TimeValue.h +++ b/include/lldb/Host/TimeValue.h @@ -31,6 +31,7 @@ public: static const uint64_t MicroSecPerSec = 1000000UL; static const uint64_t NanoSecPerSec = 1000000000UL; static const uint64_t NanoSecPerMicroSec = 1000U; + static const uint64_t NanoSecPerMilliSec = 1000000UL; //------------------------------------------------------------------ // Constructors and Destructors @@ -97,6 +98,15 @@ public: return (m_nano_seconds % NanoSecPerSec) / NanoSecPerMicroSec; } + /// Returns only the fractional portion of the TimeValue rounded down to the + /// nearest millisecond (divide by one million). + /// @brief Retrieve the milliseconds component; + uint32_t + milliseconds() const + { + return m_nano_seconds / NanoSecPerMilliSec; + } + protected: //------------------------------------------------------------------ // Classes that inherit from TimeValue can see and modify these diff --git a/include/lldb/Host/freebsd/HostInfoFreeBSD.h b/include/lldb/Host/freebsd/HostInfoFreeBSD.h index 1404a4b1525c..01dd99586f01 100644 --- a/include/lldb/Host/freebsd/HostInfoFreeBSD.h +++ b/include/lldb/Host/freebsd/HostInfoFreeBSD.h @@ -19,6 +19,7 @@ namespace lldb_private class HostInfoFreeBSD : public HostInfoPosix { public: + static uint32_t GetMaxThreadNameLength(); static bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update); static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); diff --git a/include/lldb/Host/freebsd/HostThreadFreeBSD.h b/include/lldb/Host/freebsd/HostThreadFreeBSD.h new file mode 100644 index 000000000000..056957607af4 --- /dev/null +++ b/include/lldb/Host/freebsd/HostThreadFreeBSD.h @@ -0,0 +1,31 @@ +//===-- HostThreadFreeBSD.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_freebsd_HostThreadFreeBSD_h_ +#define lldb_Host_freebsd_HostThreadFreeBSD_h_ + +#include "lldb/Host/posix/HostThreadPosix.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h" + +namespace lldb_private +{ + +class HostThreadFreeBSD : public HostThreadPosix +{ + public: + HostThreadFreeBSD(); + HostThreadFreeBSD(lldb::thread_t thread); + + static void GetName(lldb::tid_t tid, llvm::SmallVectorImpl<char> &name); +}; +} + +#endif diff --git a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h new file mode 100644 index 000000000000..4d326d71fa75 --- /dev/null +++ b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -0,0 +1,108 @@ +//===-- ConnectionFileDescriptorPosix.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Host_posix_ConnectionFileDescriptorPosix_h_ +#define liblldb_Host_posix_ConnectionFileDescriptorPosix_h_ + +// C++ Includes +#include <atomic> +#include <memory> + +#include "lldb/lldb-forward.h" + +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Connection.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Host/Pipe.h" +#include "lldb/Host/Predicate.h" +#include "lldb/Host/IOObject.h" + +namespace lldb_private +{ + +class Error; +class Socket; +class SocketAddress; + +class ConnectionFileDescriptor : public Connection +{ + public: + ConnectionFileDescriptor(bool child_processes_inherit = false); + + ConnectionFileDescriptor(int fd, bool owns_fd); + + virtual ~ConnectionFileDescriptor(); + + virtual bool IsConnected() const; + + virtual lldb::ConnectionStatus Connect(const char *s, Error *error_ptr); + + virtual lldb::ConnectionStatus Disconnect(Error *error_ptr); + + virtual size_t Read(void *dst, size_t dst_len, uint32_t timeout_usec, lldb::ConnectionStatus &status, Error *error_ptr); + + virtual size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr); + + lldb::ConnectionStatus BytesAvailable(uint32_t timeout_usec, Error *error_ptr); + + bool InterruptRead(); + + lldb::IOObjectSP + GetReadObject() + { + return m_read_sp; + } + const lldb::IOObjectSP + GetReadObject() const + { + return m_read_sp; + } + + uint16_t GetListeningPort(uint32_t timeout_sec); + + bool GetChildProcessesInherit() const; + void SetChildProcessesInherit(bool child_processes_inherit); + + protected: + void OpenCommandPipe(); + + void CloseCommandPipe(); + + lldb::ConnectionStatus SocketListen(const char *host_and_port, Error *error_ptr); + + lldb::ConnectionStatus ConnectTCP(const char *host_and_port, Error *error_ptr); + + lldb::ConnectionStatus ConnectUDP(const char *args, Error *error_ptr); + + lldb::ConnectionStatus NamedSocketConnect(const char *socket_name, Error *error_ptr); + + lldb::ConnectionStatus NamedSocketAccept(const char *socket_name, Error *error_ptr); + + lldb::IOObjectSP m_read_sp; + lldb::IOObjectSP m_write_sp; + + Predicate<uint16_t> m_port_predicate; // Used when binding to port zero to wait for the thread + // that creates the socket, binds and listens to resolve + // the port number. + + Pipe m_pipe; + Mutex m_mutex; + 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_child_processes_inherit; + + private: + DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor); +}; + +} // namespace lldb_private + +#endif // liblldb_ConnectionFileDescriptor_h_ diff --git a/include/lldb/Host/posix/HostInfoPosix.h b/include/lldb/Host/posix/HostInfoPosix.h index 6e0dcbe48021..9524a2a2481d 100644 --- a/include/lldb/Host/posix/HostInfoPosix.h +++ b/include/lldb/Host/posix/HostInfoPosix.h @@ -10,6 +10,7 @@ #ifndef lldb_Host_posix_HostInfoPosix_h_ #define lldb_Host_posix_HostInfoPosix_h_ +#include "lldb/Host/FileSpec.h" #include "lldb/Host/HostInfoBase.h" namespace lldb_private @@ -30,6 +31,8 @@ class HostInfoPosix : public HostInfoBase static uint32_t GetEffectiveUserID(); static uint32_t GetEffectiveGroupID(); + static FileSpec GetDefaultShell(); + protected: static bool ComputeSupportExeDirectory(FileSpec &file_spec); static bool ComputeHeaderDirectory(FileSpec &file_spec); diff --git a/include/lldb/Host/posix/HostProcessPosix.h b/include/lldb/Host/posix/HostProcessPosix.h index aa003ee4845e..8c1b0599e114 100644 --- a/include/lldb/Host/posix/HostProcessPosix.h +++ b/include/lldb/Host/posix/HostProcessPosix.h @@ -12,34 +12,30 @@ #include "lldb/lldb-types.h" #include "lldb/Core/Error.h" -#include "lldb/Target/ProcessLaunchInfo.h" +#include "lldb/Host/HostNativeProcessBase.h" namespace lldb_private { class FileSpec; -class HostProcessPosix +class HostProcessPosix : public HostNativeProcessBase { public: - static const lldb::pid_t kInvalidProcessId; - HostProcessPosix(); - ~HostProcessPosix(); - - Error Signal(int signo) const; - static Error Signal(lldb::pid_t pid, int signo); + HostProcessPosix(lldb::process_t process); + virtual ~HostProcessPosix(); - Error Create(lldb::pid_t pid); - Error Terminate(int signo); - Error GetMainModule(FileSpec &file_spec) const; + virtual Error Signal(int signo) const; + static Error Signal(lldb::process_t process, int signo); - lldb::pid_t GetProcessId() const; - bool IsRunning() const; + virtual Error Terminate(); + virtual Error GetMainModule(FileSpec &file_spec) const; - private: + virtual lldb::pid_t GetProcessId() const; + virtual bool IsRunning() const; - lldb::pid_t m_pid; + virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals); }; } diff --git a/include/lldb/Host/posix/HostThreadPosix.h b/include/lldb/Host/posix/HostThreadPosix.h new file mode 100644 index 000000000000..e0eaedf73be2 --- /dev/null +++ b/include/lldb/Host/posix/HostThreadPosix.h @@ -0,0 +1,34 @@ +//===-- HostThreadPosix.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_posix_HostThreadPosix_h_ +#define lldb_Host_posix_HostThreadPosix_h_ + +#include "lldb/Host/HostNativeThreadBase.h" + +namespace lldb_private +{ + +class HostThreadPosix : public HostNativeThreadBase +{ + DISALLOW_COPY_AND_ASSIGN(HostThreadPosix); + + public: + HostThreadPosix(); + HostThreadPosix(lldb::thread_t thread); + virtual ~HostThreadPosix(); + + virtual Error Join(lldb::thread_result_t *result); + virtual Error Cancel(); + + Error Detach(); +}; +} + +#endif diff --git a/include/lldb/Host/posix/PipePosix.h b/include/lldb/Host/posix/PipePosix.h new file mode 100644 index 000000000000..0ab3ff7f6775 --- /dev/null +++ b/include/lldb/Host/posix/PipePosix.h @@ -0,0 +1,81 @@ +//===-- PipePosix.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Host_posix_PipePosix_h_ +#define liblldb_Host_posix_PipePosix_h_ +#if defined(__cplusplus) + +#include "lldb/Host/PipeBase.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class PipePosix PipePosix .h "lldb/Host/posix/PipePosix.h" +/// @brief A posix-based implementation of Pipe, a class that abtracts +/// unix style pipes. +/// +/// A class that abstracts the LLDB core from host pipe functionality. +//---------------------------------------------------------------------- +class PipePosix : public PipeBase +{ +public: + static int kInvalidDescriptor; + + PipePosix(); + + ~PipePosix() override; + + Error + CreateNew(bool child_process_inherit) override; + Error + CreateNew(llvm::StringRef name, bool child_process_inherit) override; + Error + OpenAsReader(llvm::StringRef name, bool child_process_inherit) override; + Error + OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout) override; + + bool + CanRead() const override; + bool + CanWrite() const override; + + int + GetReadFileDescriptor() const override; + int + GetWriteFileDescriptor() const override; + int + ReleaseReadFileDescriptor() override; + int + ReleaseWriteFileDescriptor() override; + + // Close both descriptors + void + Close() override; + + Error + Delete(llvm::StringRef name) override; + + Error + Write(const void *buf, size_t size, size_t &bytes_written) override; + Error + ReadWithTimeout(void *buf, size_t size, const std::chrono::microseconds &timeout, size_t &bytes_read) override; + +private: + void + CloseReadFileDescriptor(); + void + CloseWriteFileDescriptor(); + + int m_fds[2]; +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Host_posix_PipePosix_h_ diff --git a/include/lldb/Host/posix/ProcessLauncherPosix.h b/include/lldb/Host/posix/ProcessLauncherPosix.h new file mode 100644 index 000000000000..c0e2a36e4e5e --- /dev/null +++ b/include/lldb/Host/posix/ProcessLauncherPosix.h @@ -0,0 +1,25 @@ +//===-- ProcessLauncherPosix.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_posix_ProcessLauncherPosix_h_ +#define lldb_Host_posix_ProcessLauncherPosix_h_ + +#include "lldb/Host/ProcessLauncher.h" + +namespace lldb_private +{ + +class ProcessLauncherPosix : public ProcessLauncher +{ + public: + virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error); +}; +} + +#endif diff --git a/include/lldb/Interpreter/Args.h b/include/lldb/Interpreter/Args.h index 06617f1e5926..1071bd6fd047 100644 --- a/include/lldb/Interpreter/Args.h +++ b/include/lldb/Interpreter/Args.h @@ -394,7 +394,9 @@ public: static bool StringToBoolean (const char *s, bool fail_value, bool *success_ptr); - + + static char StringToChar(const char *s, char fail_value, bool *success_ptr); + static int64_t StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error); diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h index c33d71a6dbbb..baaa271a4285 100644 --- a/include/lldb/Interpreter/CommandInterpreter.h +++ b/include/lldb/Interpreter/CommandInterpreter.h @@ -28,12 +28,179 @@ namespace lldb_private { +class CommandInterpreterRunOptions +{ +public: + //------------------------------------------------------------------ + /// Construct a CommandInterpreterRunOptions object. + /// This class is used to control all the instances where we run multiple commands, e.g. + /// HandleCommands, HandleCommandsFromFile, RunCommandInterpreter. + /// The meanings of the options in this object are: + /// + /// @param[in] stop_on_continue + /// If \b true execution will end on the first command that causes the process in the + /// execution context to continue. If \false, we won't check the execution status. + /// @param[in] stop_on_error + /// If \b true execution will end on the first command that causes an error. + /// @param[in] stop_on_crash + /// If \b true when a command causes the target to run, and the end of the run is a + /// signal or exception, stop executing the commands. + /// @param[in] echo_commands + /// If \b true echo the command before executing it. If \false, execute silently. + /// @param[in] print_results + /// If \b true print the results of the command after executing it. If \false, execute silently. + /// @param[in] add_to_history + /// If \b true add the commands to the command history. If \false, don't add them. + //------------------------------------------------------------------ + CommandInterpreterRunOptions (LazyBool stop_on_continue, + LazyBool stop_on_error, + LazyBool stop_on_crash, + LazyBool echo_commands, + LazyBool print_results, + LazyBool add_to_history) : + m_stop_on_continue(stop_on_continue), + m_stop_on_error(stop_on_error), + m_stop_on_crash(stop_on_crash), + m_echo_commands(echo_commands), + m_print_results(print_results), + 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_print_results(eLazyBoolCalculate), + m_add_to_history(eLazyBoolCalculate) + {} + + void + SetSilent (bool silent) + { + LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes; + + m_echo_commands = value; + m_print_results = value; + m_add_to_history = value; + } + // These return the default behaviors if the behavior is not eLazyBoolCalculate. + // But I've also left the ivars public since for different ways of running the + // interpreter you might want to force different defaults... In that case, just grab + // the LazyBool ivars directly and do what you want with eLazyBoolCalculate. + bool + GetStopOnContinue () const + { + return DefaultToNo (m_stop_on_continue); + } + + void + SetStopOnContinue (bool stop_on_continue) + { + m_stop_on_continue = stop_on_continue ? eLazyBoolYes : eLazyBoolNo; + } + + bool + GetStopOnError () const + { + return DefaultToNo (m_stop_on_continue); + } + + void + SetStopOnError (bool stop_on_error) + { + m_stop_on_error = stop_on_error ? eLazyBoolYes : eLazyBoolNo; + } + + bool + GetStopOnCrash () const + { + return DefaultToNo (m_stop_on_crash); + } + + void + SetStopOnCrash (bool stop_on_crash) + { + m_stop_on_crash = stop_on_crash ? eLazyBoolYes : eLazyBoolNo; + } + + bool + GetEchoCommands () const + { + return DefaultToYes (m_echo_commands); + } + + void + SetEchoCommands (bool echo_commands) + { + m_echo_commands = echo_commands ? eLazyBoolYes : eLazyBoolNo; + } + + bool + GetPrintResults () const + { + return DefaultToYes (m_print_results); + } + + void + SetPrintResults (bool print_results) + { + m_print_results = print_results ? eLazyBoolYes : eLazyBoolNo; + } + + bool + GetAddToHistory () const + { + return DefaultToYes (m_add_to_history); + } + + void + SetAddToHistory (bool add_to_history) + { + m_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo; + } + + LazyBool m_stop_on_continue; + LazyBool m_stop_on_error; + LazyBool m_stop_on_crash; + LazyBool m_echo_commands; + LazyBool m_print_results; + LazyBool m_add_to_history; + + private: + static bool + DefaultToYes (LazyBool flag) + { + switch (flag) + { + case eLazyBoolNo: + return false; + default: + return true; + } + } + + static bool + DefaultToNo (LazyBool flag) + { + switch (flag) + { + case eLazyBoolYes: + return true; + default: + return false; + } + } +}; + class CommandInterpreter : public Broadcaster, public Properties, public IOHandlerDelegate { public: + + typedef std::map<std::string, OptionArgVectorSP> OptionArgMap; enum @@ -115,6 +282,10 @@ public: AddAlias (const char *alias_name, lldb::CommandObjectSP& command_obj_sp); + // Remove a command if it is removable (python or regex command) + bool + RemoveCommand (const char *cmd); + bool RemoveAlias (const char *alias_name); @@ -168,27 +339,17 @@ public: /// @param[in/out] context /// The execution context in which to run the commands. Can be NULL in which case the default /// context will be used. - /// @param[in] stop_on_continue - /// If \b true execution will end on the first command that causes the process in the - /// execution context to continue. If \false, we won't check the execution status. - /// @param[in] stop_on_error - /// If \b true execution will end on the first command that causes an error. - /// @param[in] echo_commands - /// If \b true echo the command before executing it. If \false, execute silently. - /// @param[in] print_results - /// If \b true print the results of the command after executing it. If \false, execute silently. - /// @param[out] result + /// @param[in] options + /// This object holds the options used to control when to stop, whether to execute commands, + /// etc. + /// @param[out] result /// This is marked as succeeding with no output if all commands execute safely, /// and failed with some explanation if we aborted executing the commands at some point. //------------------------------------------------------------------ void HandleCommands (const StringList &commands, - ExecutionContext *context, - bool stop_on_continue, - bool stop_on_error, - bool echo_commands, - bool print_results, - LazyBool add_to_history, + ExecutionContext *context, + CommandInterpreterRunOptions &options, CommandReturnObject &result); //------------------------------------------------------------------ @@ -199,27 +360,17 @@ public: /// @param[in/out] context /// The execution context in which to run the commands. Can be NULL in which case the default /// context will be used. - /// @param[in] stop_on_continue - /// If \b true execution will end on the first command that causes the process in the - /// execution context to continue. If \false, we won't check the execution status. - /// @param[in] stop_on_error - /// If \b true execution will end on the first command that causes an error. - /// @param[in] echo_commands - /// If \b true echo the command before executing it. If \false, execute silently. - /// @param[in] print_results - /// If \b true print the results of the command after executing it. If \false, execute silently. - /// @param[out] result + /// @param[in] options + /// This object holds the options used to control when to stop, whether to execute commands, + /// etc. + /// @param[out] result /// This is marked as succeeding with no output if all commands execute safely, /// and failed with some explanation if we aborted executing the commands at some point. //------------------------------------------------------------------ void HandleCommandsFromFile (FileSpec &file, - ExecutionContext *context, - LazyBool stop_on_continue, - LazyBool stop_on_error, - LazyBool echo_commands, - LazyBool print_results, - LazyBool add_to_history, + ExecutionContext *context, + CommandInterpreterRunOptions &options, CommandReturnObject &result); CommandObject * @@ -442,8 +593,8 @@ public: void RunCommandInterpreter (bool auto_handle_events, - bool spawn_thread); - + bool spawn_thread, + CommandInterpreterRunOptions &options); void GetLLDBCommandsFromIOHandler (const char *prompt, IOHandlerDelegate &delegate, @@ -467,6 +618,27 @@ public: bool GetStopCmdSourceOnError () const; + + uint32_t + GetNumErrors() const + { + return m_num_errors; + } + + bool + GetQuitRequested () const + { + return m_quit_requested; + } + + lldb::IOHandlerSP + GetIOHandler(bool force_create = false, CommandInterpreterRunOptions *options = NULL); + + bool + GetStoppedForCrash () const + { + return m_stopped_for_crash; + } protected: friend class Debugger; @@ -522,6 +694,9 @@ private: ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told uint32_t m_command_source_depth; std::vector<uint32_t> m_command_source_flags; + uint32_t m_num_errors; + bool m_quit_requested; + bool m_stopped_for_crash; }; diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h index 7bdf55a393d7..bace3264dafa 100644 --- a/include/lldb/Interpreter/CommandObject.h +++ b/include/lldb/Interpreter/CommandObject.h @@ -525,6 +525,11 @@ protected: return "invalid frame, no registers"; } + // This is for use in the command interpreter, when you either want the selected target, or if no target + // is present you want to prime the dummy target with entities that will be copied over to new targets. + Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); + Target *GetDummyTarget(); + //------------------------------------------------------------------ /// Check the command to make sure anything required by this /// command is available. @@ -605,7 +610,7 @@ public: virtual bool Execute (const char *args_string, CommandReturnObject &result); - + protected: virtual bool DoExecute (const char *command, CommandReturnObject &result) = 0; diff --git a/include/lldb/Interpreter/CommandObjectRegexCommand.h b/include/lldb/Interpreter/CommandObjectRegexCommand.h index 8855680d5f8b..d86544638776 100644 --- a/include/lldb/Interpreter/CommandObjectRegexCommand.h +++ b/include/lldb/Interpreter/CommandObjectRegexCommand.h @@ -34,12 +34,16 @@ public: const char *help, const char *syntax, uint32_t max_matches, - uint32_t completion_type_mask = 0); + uint32_t completion_type_mask, + bool is_removable); virtual ~CommandObjectRegexCommand (); bool + IsRemovable () const override { return m_is_removable; } + + bool AddRegexCommand (const char *re_cstr, const char *command_cstr); bool @@ -48,18 +52,18 @@ public: return !m_entries.empty(); } - virtual int + int HandleCompletion (Args &input, int &cursor_index, int &cursor_char_position, int match_start_point, int max_return_elements, bool &word_complete, - StringList &matches); + StringList &matches) override; protected: - virtual bool - DoExecute (const char *command, CommandReturnObject &result); + bool + DoExecute (const char *command, CommandReturnObject &result) override; struct Entry { @@ -71,6 +75,7 @@ protected: const uint32_t m_max_matches; const uint32_t m_completion_type_mask; EntryCollection m_entries; + bool m_is_removable; private: DISALLOW_COPY_AND_ASSIGN (CommandObjectRegexCommand); diff --git a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index c09528f9f514..5cce126f89bf 100644 --- a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -59,7 +59,8 @@ public: ptr_depth != 0 || use_synth == false || be_raw == true || - ignore_cap == true; + ignore_cap == true || + run_validator == true; } DumpValueObjectOptions @@ -67,17 +68,19 @@ public: lldb::Format format = lldb::eFormatDefault, lldb::TypeSummaryImplSP summary_sp = lldb::TypeSummaryImplSP()); - bool show_types; + bool show_types : 1, + show_location : 1, + flat_output : 1, + use_objc : 1, + use_synth : 1, + be_raw : 1, + ignore_cap : 1, + run_validator : 1; + uint32_t no_summary_depth; - bool show_location; - bool flat_output; - bool use_objc; uint32_t max_depth; uint32_t ptr_depth; lldb::DynamicValueType use_dynamic; - bool use_synth; - bool be_raw; - bool ignore_cap; }; } // namespace lldb_private diff --git a/include/lldb/Interpreter/OptionValue.h b/include/lldb/Interpreter/OptionValue.h index 33e7fc5f818b..0e8f23453a8a 100644 --- a/include/lldb/Interpreter/OptionValue.h +++ b/include/lldb/Interpreter/OptionValue.h @@ -26,12 +26,14 @@ namespace lldb_private { class OptionValue { public: - typedef enum { + typedef enum + { eTypeInvalid = 0, eTypeArch, eTypeArgs, eTypeArray, eTypeBoolean, + eTypeChar, eTypeDictionary, eTypeEnum, eTypeFileSpec, @@ -41,11 +43,11 @@ namespace lldb_private { eTypeProperties, eTypeRegex, eTypeSInt64, - eTypeString, + eTypeString, eTypeUInt64, eTypeUUID } Type; - + enum { eDumpOptionName = (1u << 0), eDumpOptionType = (1u << 1), @@ -58,11 +60,15 @@ namespace lldb_private { OptionValue () : + m_callback (nullptr), + m_baton(nullptr), m_value_was_set (false) { } OptionValue (const OptionValue &rhs) : + m_callback (rhs.m_callback), + m_baton (rhs.m_baton), m_value_was_set (rhs.m_value_was_set) { } @@ -173,6 +179,7 @@ namespace lldb_private { case 1u << eTypeArgs: return eTypeArgs; case 1u << eTypeArray: return eTypeArray; case 1u << eTypeBoolean: return eTypeBoolean; + case 1u << eTypeChar: return eTypeChar; case 1u << eTypeDictionary: return eTypeDictionary; case 1u << eTypeEnum: return eTypeEnum; case 1u << eTypeFileSpec: return eTypeFileSpec; @@ -221,10 +228,16 @@ namespace lldb_private { OptionValueBoolean * GetAsBoolean (); - + + OptionValueChar * + GetAsChar (); + const OptionValueBoolean * GetAsBoolean () const; - + + const OptionValueChar * + GetAsChar () const; + OptionValueDictionary * GetAsDictionary (); @@ -302,7 +315,11 @@ namespace lldb_private { bool SetBooleanValue (bool new_value); - + + char GetCharValue(char fail_value) const; + + char SetCharValue(char new_value); + int64_t GetEnumerationValue (int64_t fail_value = -1) const; @@ -368,8 +385,26 @@ namespace lldb_private { { m_parent_wp = parent_sp; } + + void + SetValueChangedCallback (OptionValueChangedCallback callback, + void *baton) + { + assert (m_callback == NULL); + m_callback = callback; + m_baton = baton; + } + + void + NotifyValueChanged () + { + if (m_callback) + m_callback (m_baton, this); + } protected: lldb::OptionValueWP m_parent_wp; + OptionValueChangedCallback m_callback; + void *m_baton; 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 diff --git a/include/lldb/Interpreter/OptionValueChar.h b/include/lldb/Interpreter/OptionValueChar.h new file mode 100644 index 000000000000..55f4b63538ea --- /dev/null +++ b/include/lldb/Interpreter/OptionValueChar.h @@ -0,0 +1,113 @@ +//===-- OptionValueBoolean.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_OptionValueChar_h_ +#define liblldb_OptionValueChar_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/OptionValue.h" + +namespace lldb_private { + +class OptionValueChar : public OptionValue +{ +public: + OptionValueChar (char value) : + OptionValue(), + 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) + { + } + + virtual + ~OptionValueChar() + { + } + + //--------------------------------------------------------------------- + // Virtual subclass pure virtual overrides + //--------------------------------------------------------------------- + + virtual OptionValue::Type + GetType () const + { + return eTypeChar; + } + + virtual void + DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask); + + virtual Error + SetValueFromCString (const char *value, + VarSetOperationType op = eVarSetOperationAssign); + + virtual bool + Clear () + { + m_current_value = m_default_value; + m_value_was_set = false; + return true; + } + + //--------------------------------------------------------------------- + // Subclass specific functions + //--------------------------------------------------------------------- + + const char & + operator = (char c) + { + m_current_value = c; + return m_current_value; + } + + char + GetCurrentValue() const + { + return m_current_value; + } + + char + GetDefaultValue() const + { + return m_default_value; + } + + void + SetCurrentValue (char value) + { + m_current_value = value; + } + + void + SetDefaultValue (char value) + { + m_default_value = value; + } + + virtual lldb::OptionValueSP + DeepCopy () const; + +protected: + char m_current_value; + char m_default_value; +}; + +} // namespace lldb_private + +#endif // liblldb_OptionValueChar_h_ diff --git a/include/lldb/Interpreter/OptionValueProperties.h b/include/lldb/Interpreter/OptionValueProperties.h index 0024f20e2ff6..a67ea5d66e54 100644 --- a/include/lldb/Interpreter/OptionValueProperties.h +++ b/include/lldb/Interpreter/OptionValueProperties.h @@ -243,8 +243,20 @@ public: GetSubProperty (const ExecutionContext *exe_ctx, const ConstString &name); + void + SetValueChangedCallback (uint32_t property_idx, + OptionValueChangedCallback callback, + void *baton); protected: - + + Property * + ProtectedGetPropertyAtIndex (uint32_t idx) + { + if (idx < m_properties.size()) + return &m_properties[idx]; + return NULL; + } + const Property * ProtectedGetPropertyAtIndex (uint32_t idx) const { diff --git a/include/lldb/Interpreter/OptionValues.h b/include/lldb/Interpreter/OptionValues.h index 41b9d2e351f4..c66fc4dab2f6 100644 --- a/include/lldb/Interpreter/OptionValues.h +++ b/include/lldb/Interpreter/OptionValues.h @@ -15,6 +15,7 @@ #include "lldb/Interpreter/OptionValueArgs.h" #include "lldb/Interpreter/OptionValueArray.h" #include "lldb/Interpreter/OptionValueBoolean.h" +#include "lldb/Interpreter/OptionValueChar.h" #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Interpreter/OptionValueEnumeration.h" #include "lldb/Interpreter/OptionValueFileSpec.h" diff --git a/include/lldb/Interpreter/Property.h b/include/lldb/Interpreter/Property.h index b192758cbc41..cb4c827ded06 100644 --- a/include/lldb/Interpreter/Property.h +++ b/include/lldb/Interpreter/Property.h @@ -29,7 +29,7 @@ namespace lldb_private { { const char *name; OptionValue::Type type; - bool global; + bool global; // false == this setting is a global setting by default uintptr_t default_uint_value; const char *default_cstr_value; OptionEnumValueElement *enum_values; @@ -97,6 +97,9 @@ namespace lldb_private { uint32_t output_width, bool display_qualified_name) const; + void + SetValueChangedCallback (OptionValueChangedCallback callback, void *baton); + protected: ConstString m_name; ConstString m_description; diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h index 5a8322f8eb4f..35ba9491ded0 100644 --- a/include/lldb/Interpreter/ScriptInterpreter.h +++ b/include/lldb/Interpreter/ScriptInterpreter.h @@ -98,12 +98,19 @@ public: void *session_dictionary, const lldb::ValueObjectSP& valobj_sp, void** pyfunct_wrapper, + const lldb::TypeSummaryOptionsSP& options, std::string& retval); typedef void* (*SWIGPythonCreateSyntheticProvider) (const char *python_class_name, const char *session_dictionary_name, const lldb::ValueObjectSP& valobj_sp); + typedef void* (*SWIGPythonCreateScriptedThreadPlan) (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ThreadPlanSP& thread_plan_sp); + + typedef bool (*SWIGPythonCallThreadPlan) (void *implementor, const char *method_name, Event *event_sp, bool &got_error); + typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name, const char *session_dictionary_name, const lldb::ProcessSP& process_sp); @@ -115,13 +122,14 @@ public: typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue) (void* data); typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data); typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data); - + typedef void* (*SWIGPythonGetValueSynthProviderInstance) (void *implementor); typedef bool (*SWIGPythonCallCommand) (const char *python_function_name, const char *session_dictionary_name, lldb::DebuggerSP& debugger, const char* args, - lldb_private::CommandReturnObject& cmd_retobj); + lldb_private::CommandReturnObject& cmd_retobj, + lldb::ExecutionContextRefSP exe_ctx_ref_sp); typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name, const char *session_dictionary_name, @@ -145,6 +153,11 @@ public: const char* session_dictionary_name, lldb::StackFrameSP& frame, std::string& output); + + typedef bool (*SWIGPythonScriptKeyword_Value) (const char* python_function_name, + const char* session_dictionary_name, + lldb::ValueObjectSP& value, + std::string& output); typedef void* (*SWIGPython_GetDynamicSetting) (void* module, const char* setting, @@ -348,6 +361,39 @@ public: } virtual lldb::ScriptInterpreterObjectSP + CreateScriptedThreadPlan (const char *class_name, + lldb::ThreadPlanSP thread_plan_sp) + { + return lldb::ScriptInterpreterObjectSP(); + } + + virtual bool + ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp, + Event *event, + bool &script_error) + { + script_error = true; + return true; + } + + virtual bool + ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp, + Event *event, + bool &script_error) + { + script_error = true; + return true; + } + + virtual lldb::StateType + ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp, + bool &script_error) + { + script_error = true; + return lldb::eStateStepping; + } + + virtual lldb::ScriptInterpreterObjectSP LoadPluginModule (const FileSpec& file_spec, lldb_private::Error& error) { @@ -417,6 +463,7 @@ public: GetScriptedSummary (const char *function_name, lldb::ValueObjectSP valobj, lldb::ScriptInterpreterObjectSP& callee_wrapper_sp, + const TypeSummaryOptions& options, std::string& retval) { return false; @@ -458,12 +505,19 @@ public: return true; } + virtual lldb::ValueObjectSP + GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor) + { + return nullptr; + } + virtual bool RunScriptBasedCommand (const char* impl_function, const char* args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject& cmd_retobj, - Error& error) + Error& error, + const lldb_private::ExecutionContext& exe_ctx) { return false; } @@ -509,6 +563,16 @@ public: } virtual bool + RunScriptFormatKeyword (const char* impl_function, + ValueObject* value, + std::string& output, + Error& error) + { + error.SetErrorString("unimplemented"); + return false; + } + + virtual bool GetDocumentationForItem (const char* item, std::string& dest) { dest.clear(); @@ -566,6 +630,7 @@ public: SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue, SWIGPythonUpdateSynthProviderInstance swig_update_provider, SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider, + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider, SWIGPythonCallCommand swig_call_command, SWIGPythonCallModuleInit swig_call_module_init, SWIGPythonCreateOSPlugin swig_create_os_plugin, @@ -573,7 +638,10 @@ public: SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread, SWIGPythonScriptKeyword_Target swig_run_script_keyword_target, SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame, - SWIGPython_GetDynamicSetting swig_plugin_get); + SWIGPythonScriptKeyword_Value swig_run_script_keyword_value, + SWIGPython_GetDynamicSetting swig_plugin_get, + SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script, + SWIGPythonCallThreadPlan swig_call_thread_plan); virtual void ResetOutputFileHandle (FILE *new_fh) { } //By default, do nothing. diff --git a/include/lldb/Interpreter/ScriptInterpreterPython.h b/include/lldb/Interpreter/ScriptInterpreterPython.h index 14a62d67fde6..edcc4c44facb 100644 --- a/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -80,6 +80,22 @@ public: lldb::ScriptInterpreterObjectSP CreateSyntheticScriptedProvider (const char *class_name, lldb::ValueObjectSP valobj); + + lldb::ScriptInterpreterObjectSP + virtual CreateScriptedThreadPlan (const char *class_name, + lldb::ThreadPlanSP thread_plan); + + virtual bool + ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp, + Event *event, + bool &script_error); + virtual bool + ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp, + Event *event, + bool &script_error); + virtual lldb::StateType + ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp, + bool &script_error); virtual lldb::ScriptInterpreterObjectSP OSPlugin_CreatePluginObject (const char *class_name, @@ -125,12 +141,16 @@ public: virtual bool MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor); + virtual lldb::ValueObjectSP + GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor); + virtual bool RunScriptBasedCommand(const char* impl_function, const char* args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject& cmd_retobj, - Error& error); + Error& error, + const lldb_private::ExecutionContext& exe_ctx); Error GenerateFunction(const char *signature, const StringList &input); @@ -170,6 +190,7 @@ public: GetScriptedSummary (const char *function_name, lldb::ValueObjectSP valobj, lldb::ScriptInterpreterObjectSP& callee_wrapper_sp, + const TypeSummaryOptions& options, std::string& retval); virtual void @@ -212,6 +233,12 @@ public: Error& error); virtual bool + RunScriptFormatKeyword (const char* impl_function, + ValueObject* value, + std::string& output, + Error& error); + + virtual bool LoadScriptingModule (const char* filename, bool can_reload, bool init_session, @@ -268,6 +295,7 @@ public: SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue, SWIGPythonUpdateSynthProviderInstance swig_update_provider, SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider, + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider, SWIGPythonCallCommand swig_call_command, SWIGPythonCallModuleInit swig_call_module_init, SWIGPythonCreateOSPlugin swig_create_os_plugin, @@ -275,7 +303,10 @@ public: SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread, SWIGPythonScriptKeyword_Target swig_run_script_keyword_target, SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame, - SWIGPython_GetDynamicSetting swig_plugin_get); + SWIGPythonScriptKeyword_Value swig_run_script_keyword_value, + SWIGPython_GetDynamicSetting swig_plugin_get, + SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script, + SWIGPythonCallThreadPlan swig_call_thread_plan); const char * GetDictionaryName () diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index 2bb911c6e566..a9096fe66151 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -14,17 +14,21 @@ #include <stdint.h> // C++ Includes +#include <initializer_list> #include <string> #include <vector> +#include <utility> // Other libraries and framework includes #include "llvm/ADT/SmallVector.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/TemplateBase.h" // Project includes #include "lldb/lldb-enumerations.h" #include "lldb/Core/ClangForward.h" +#include "lldb/Core/ConstString.h" #include "lldb/Symbol/ClangASTType.h" namespace lldb_private { @@ -208,11 +212,47 @@ public: ClangASTType type2, bool ignore_qualifiers = false); - ClangASTType + static ClangASTType + GetTypeForDecl (clang::NamedDecl *decl); + + static ClangASTType GetTypeForDecl (clang::TagDecl *decl); - ClangASTType + static ClangASTType GetTypeForDecl (clang::ObjCInterfaceDecl *objc_decl); + + template <typename RecordDeclType> + ClangASTType + GetTypeForIdentifier (const ConstString &type_name) + { + ClangASTType clang_type; + + if (type_name.GetLength()) + { + clang::ASTContext *ast = getASTContext(); + if (ast) + { + clang::IdentifierInfo &myIdent = ast->Idents.get(type_name.GetCString()); + clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent); + + clang::DeclContext::lookup_const_result result = ast->getTranslationUnitDecl()->lookup(myName); + + if (!result.empty()) + { + clang::NamedDecl *named_decl = result[0]; + if (const RecordDeclType *record_decl = llvm::dyn_cast<RecordDeclType>(named_decl)) + clang_type.SetClangType(ast, clang::QualType(record_decl->getTypeForDecl(), 0)); + } + } + } + + return clang_type; + } + + ClangASTType + GetOrCreateStructForIdentifier (const ConstString &type_name, + const std::initializer_list< std::pair < const char *, ClangASTType > >& type_fields, + bool packed = false); //------------------------------------------------------------------ // Structure, Unions, Classes diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h index 4dd17031e568..ef23a8be645b 100644 --- a/include/lldb/Symbol/ClangASTType.h +++ b/include/lldb/Symbol/ClangASTType.h @@ -30,32 +30,6 @@ namespace lldb_private { class ClangASTType { public: - enum { - eTypeHasChildren = (1u << 0), - eTypeHasValue = (1u << 1), - eTypeIsArray = (1u << 2), - eTypeIsBlock = (1u << 3), - eTypeIsBuiltIn = (1u << 4), - eTypeIsClass = (1u << 5), - eTypeIsCPlusPlus = (1u << 6), - eTypeIsEnumeration = (1u << 7), - eTypeIsFuncPrototype = (1u << 8), - eTypeIsMember = (1u << 9), - eTypeIsObjC = (1u << 10), - eTypeIsPointer = (1u << 11), - eTypeIsReference = (1u << 12), - eTypeIsStructUnion = (1u << 13), - eTypeIsTemplate = (1u << 14), - eTypeIsTypedef = (1u << 15), - eTypeIsVector = (1u << 16), - eTypeIsScalar = (1u << 17), - eTypeIsInteger = (1u << 18), - eTypeIsFloat = (1u << 19), - eTypeIsComplex = (1u << 20), - eTypeIsSigned = (1u << 21) - }; - - //---------------------------------------------------------------------- // Constructors and Destructors //---------------------------------------------------------------------- @@ -162,7 +136,7 @@ public: GetNumberOfFunctionArguments () const; ClangASTType - GetFunctionArgumentAtIndex (const size_t index); + GetFunctionArgumentAtIndex (const size_t index) const; bool IsVariadicFunctionType () const; @@ -329,11 +303,17 @@ public: GetFunctionArgumentCount () const; ClangASTType - GetFunctionArgumentTypeAtIndex (size_t idx); + GetFunctionArgumentTypeAtIndex (size_t idx) const; ClangASTType GetFunctionReturnType () const; + size_t + GetNumMemberFunctions () const; + + TypeMemberFunctionImpl + GetMemberFunctionAtIndex (size_t idx); + ClangASTType GetLValueReferenceType () const; @@ -475,6 +455,9 @@ public: void BuildIndirectFields (); + void + SetIsPacked (); + clang::VarDecl * AddVariableToRecordType (const char *name, const ClangASTType &var_type, diff --git a/include/lldb/Symbol/ClangExternalASTSourceCommon.h b/include/lldb/Symbol/ClangExternalASTSourceCommon.h index 20c4b4354367..17650f7f14fd 100644 --- a/include/lldb/Symbol/ClangExternalASTSourceCommon.h +++ b/include/lldb/Symbol/ClangExternalASTSourceCommon.h @@ -169,18 +169,16 @@ public: ClangExternalASTSourceCommon(); ~ClangExternalASTSourceCommon(); - virtual ClangASTMetadata *GetMetadata(const void *object); - virtual void SetMetadata(const void *object, ClangASTMetadata &metadata); - virtual bool HasMetadata(const void *object); -private: + ClangASTMetadata *GetMetadata(const void *object); + void SetMetadata(const void *object, ClangASTMetadata &metadata); + bool HasMetadata(const void *object); + + static ClangExternalASTSourceCommon * + Lookup(clang::ExternalASTSource *source); +private: typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap; MetadataMap m_metadata; - uint64_t m_magic; ///< Because we don't have RTTI, we must take it - ///< on faith that any valid ExternalASTSource that - ///< we try to use the *Metadata APIs on inherits - ///< from ClangExternalASTSourceCommon. This magic - ///< number exists to enforce that. }; } diff --git a/include/lldb/Symbol/CompactUnwindInfo.h b/include/lldb/Symbol/CompactUnwindInfo.h new file mode 100644 index 000000000000..239eb3ac77ad --- /dev/null +++ b/include/lldb/Symbol/CompactUnwindInfo.h @@ -0,0 +1,155 @@ +//===-- CompactUnwindInfo.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CompactUnwindInfo_h_ +#define liblldb_CompactUnwindInfo_h_ + +#include <vector> + +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RangeMap.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +// Compact Unwind info is an unwind format used on Darwin. The unwind instructions +// for typical compiler-generated functions can be expressed in a 32-bit encoding. +// The format includes a two-level index so the unwind information for a function +// can be found by two binary searches in the section. It can represent both +// stack frames that use a frame-pointer register and frameless functions, on +// i386/x86_64 for instance. When a function is too complex to be represented in +// the compact unwind format, it calls out to eh_frame unwind instructions. + +// On Mac OS X / iOS, a function will have either a compact unwind representation +// or an eh_frame representation. If lldb is going to benefit from the compiler's +// description about saved register locations, it must be able to read both +// sources of information. + +class CompactUnwindInfo +{ +public: + + CompactUnwindInfo (ObjectFile& objfile, + lldb::SectionSP& section); + + ~CompactUnwindInfo(); + + bool + GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwind_plan); + + bool + IsValid (const lldb::ProcessSP &process_sp); + +private: + + + // The top level index entries of the compact unwind info + // (internal representation of struct unwind_info_section_header_index_entry) + // 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 + // (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 + // function addresses that are described + + UnwindIndex() : + function_offset (0), + second_level (0), + lsda_array_start(0), + lsda_array_end(0), + sentinal_entry (false) + { } + + bool + operator< (const CompactUnwindInfo::UnwindIndex& rhs) const + { + return function_offset < rhs.function_offset; + } + + bool + operator== (const CompactUnwindInfo::UnwindIndex& rhs) const + { + return function_offset == rhs.function_offset; + } + + }; + + // 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 + 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) { } + }; + + 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) { } + }; + + void + ScanIndex(const lldb::ProcessSP &process_sp); + + bool + GetCompactUnwindInfoForFunction (Target &target, Address address, FunctionInfo &unwind_info); + + lldb::offset_t + BinarySearchRegularSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset); + + uint32_t + BinarySearchCompressedSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset_to_find, uint32_t function_offset_base, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset); + + uint32_t + GetLSDAForFunctionOffset (uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset); + + bool + CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); + + bool + CreateUnwindPlan_i386 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); + + ObjectFile &m_objfile; + lldb::SectionSP m_section_sp; + lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is encrypted, read the sect contents + // out of live memory and cache them here + Mutex m_mutex; + std::vector<UnwindIndex> m_indexes; + + LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the unwind info + // eLazyBoolNo means we cannot parse the unwind info & should not retry + // eLazyBoolCalculate means we haven't tried to parse it yet + + DataExtractor m_unwindinfo_data; + bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo data + + UnwindHeader m_unwind_header; +}; + +} // namespace lldb_private + +#endif // liblldb_CompactUnwindInfo_h_ diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h index e67a5a2a8e2c..27d1a52b49f8 100644 --- a/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -91,11 +91,17 @@ private: dw_offset_t inst_offset; // offset of CIE instructions in mCFIData uint32_t inst_length; // length of CIE instructions in mCFIData uint8_t ptr_encoding; + uint8_t lsda_addr_encoding; // The encoding of the LSDA address in the FDE augmentation data + lldb::addr_t personality_loc; // (file) address of the pointer to the personality routine lldb_private::UnwindPlan::Row initial_row; CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0), data_align (0), return_addr_reg_num (LLDB_INVALID_REGNUM), inst_offset (0), - inst_length (0), ptr_encoding (0), initial_row() {} + inst_length (0), ptr_encoding (0), + lsda_addr_encoding (DW_EH_PE_omit), personality_loc (LLDB_INVALID_ADDRESS), + initial_row () + { + } }; typedef std::shared_ptr<CIE> CIESP; diff --git a/include/lldb/Symbol/TypeVendor.h b/include/lldb/Symbol/DeclVendor.h index 559b21eeb95a..ffba71c9299f 100644 --- a/include/lldb/Symbol/TypeVendor.h +++ b/include/lldb/Symbol/DeclVendor.h @@ -1,4 +1,4 @@ -//===-- TypeVendor.h --------------------------------------------*- C++ -*-===// +//===-- DeclVendor.h --------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,52 +7,64 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TypeVendor_h_ -#define liblldb_TypeVendor_h_ +#ifndef liblldb_DeclVendor_h_ +#define liblldb_DeclVendor_h_ #include "lldb/Core/ClangForward.h" +#include <vector> + namespace lldb_private { //---------------------------------------------------------------------- -// The type vendor class is intended as a generic interface to search -// for Clang types that are not necessarily backed by a specific symbol -// file. +// The Decl vendor class is intended as a generic interface to search +// for named declarations that are not necessarily backed by a specific +// symbol file. //---------------------------------------------------------------------- -class TypeVendor +class DeclVendor { public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - TypeVendor() + DeclVendor() { } virtual - ~TypeVendor() + ~DeclVendor() { } + //------------------------------------------------------------------ + /// Look up the set of Decls that the DeclVendor currently knows about + /// matching a given name. + /// + /// @param[in] name + /// The name to look for. + /// + /// @param[in] append + /// If true, FindDecls will clear "decls" when it starts. + /// + /// @param[in] max_matches + /// The maximum number of Decls to return. UINT32_MAX means "as + /// many as possible." + /// + /// @return + /// The number of Decls added to decls; will not exceed + /// max_matches. + //------------------------------------------------------------------ virtual uint32_t - FindTypes (const ConstString &name, + FindDecls (const ConstString &name, bool append, uint32_t max_matches, - std::vector <ClangASTType> &types) = 0; - - virtual clang::ASTContext * - GetClangASTContext () = 0; - -protected: - //------------------------------------------------------------------ - // Classes that inherit from TypeVendor can see and modify these - //------------------------------------------------------------------ + std::vector <clang::NamedDecl*> &decls) = 0; private: //------------------------------------------------------------------ - // For TypeVendor only + // For DeclVendor only //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (TypeVendor); + DISALLOW_COPY_AND_ASSIGN (DeclVendor); }; diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index 0cf584239f95..1e579c42acb8 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -1,6 +1,8 @@ #ifndef liblldb_FuncUnwinders_h #define liblldb_FuncUnwinders_h +#include <vector> + #include "lldb/Core/AddressRange.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/AddressRange.h" @@ -16,7 +18,8 @@ public: // FuncUnwinders objects are used to track UnwindPlans for a function // (named or not - really just an address range) - // We'll record three different UnwindPlans for each address range: + // We'll record four different UnwindPlans for each address range: + // // 1. Unwinding from a call site (a valid exception throw location) // This is often sourced from the eh_frame exception handling info // 2. Unwinding from a non-call site (any location in the function) @@ -41,7 +44,7 @@ public: // offset value will have already been decremented by 1 to stay within the bounds of the // correct function body. lldb::UnwindPlanSP - GetUnwindPlanAtCallSite (int current_offset); + GetUnwindPlanAtCallSite (Target &target, int current_offset); lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite (Target& target, lldb_private::Thread& thread, int current_offset); @@ -67,13 +70,43 @@ public: return m_range.ContainsFileAddress (addr); } - // When we're doing an unwind using the UnwindPlanAtNonCallSite and we find an - // impossible unwind condition, we know that the UnwindPlan is invalid. Calling - // this method on the FuncUnwinder will tell it to replace that UnwindPlan with - // the architectural default UnwindPlan so hopefully our stack walk will get past - // this frame. - void - InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread); + // A function may have a Language Specific Data Area specified -- a block of data in + // the object file which is used in the processing of an exception throw / catch. + // If any of the UnwindPlans have the address of the LSDA region for this function, + // this will return it. + Address + GetLSDAAddress (Target &target); + + // A function may have a Personality Routine associated with it -- used in the + // processing of throwing an exception. If any of the UnwindPlans have the + // address of the personality routine, this will return it. Read the target-pointer + // at this address to get the personality function address. + Address + GetPersonalityRoutinePtrAddress (Target &target); + + + + // The following methods to retrieve specific unwind plans should rarely be used. + // Instead, clients should ask for the *behavior* they are looking for, using one + // of the above UnwindPlan retrieval methods. + + lldb::UnwindPlanSP + GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset); + + lldb::UnwindPlanSP + GetEHFrameUnwindPlan (Target &target, int current_offset); + + lldb::UnwindPlanSP + GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, int current_offset); + + lldb::UnwindPlanSP + GetCompactUnwindUnwindPlan (Target &target, int current_offset); + + lldb::UnwindPlanSP + GetArchDefaultUnwindPlan (Thread &thread); + + lldb::UnwindPlanSP + GetArchDefaultAtFuncEntryUnwindPlan (Thread &thread); private: @@ -84,19 +117,25 @@ private: AddressRange m_range; Mutex m_mutex; - lldb::UnwindPlanSP m_unwind_plan_call_site_sp; - lldb::UnwindPlanSP m_unwind_plan_non_call_site_sp; - lldb::UnwindPlanSP m_unwind_plan_fast_sp; - lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; - lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp; - - bool m_tried_unwind_at_call_site:1, - m_tried_unwind_at_non_call_site:1, + + lldb::UnwindPlanSP m_unwind_plan_assembly_sp; + lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; + lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp; // augmented by assembly inspection so it's valid everywhere + std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind; + lldb::UnwindPlanSP m_unwind_plan_fast_sp; + lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; + lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp; + + // Fetching the UnwindPlans can be expensive - if we've already attempted + // to get one & failed, don't try again. + bool m_tried_unwind_plan_assembly:1, + m_tried_unwind_plan_eh_frame:1, + m_tried_unwind_plan_eh_frame_augmented:1, + m_tried_unwind_plan_compact_unwind:1, m_tried_unwind_fast:1, m_tried_unwind_arch_default:1, m_tried_unwind_arch_default_at_func_entry:1; - - + Address m_first_non_prologue_insn; DISALLOW_COPY_AND_ASSIGN (FuncUnwinders); diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index c26b7a0b9a10..d40d1453cb17 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -168,7 +168,8 @@ public: const Address &so_addr, bool show_fullpaths, bool show_module, - bool show_inlined_frames) const; + bool show_inlined_frames, + bool show_function_arguments) const; //------------------------------------------------------------------ /// Get the address range contained within a symbol context. diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index eaa150e78ace..51bd3dd82c92 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -810,6 +810,83 @@ private: TypePair m_type_pair; ConstString m_type_name; }; + +class TypeMemberFunctionImpl +{ +public: + TypeMemberFunctionImpl() : + m_type(), + m_objc_method_decl(nullptr), + m_name(), + m_kind(lldb::eMemberFunctionKindUnknown) + { + } + + TypeMemberFunctionImpl (const ClangASTType& type, + const std::string& name, + const lldb::MemberFunctionKind& kind) : + m_type(type), + m_objc_method_decl(nullptr), + m_name(name), + m_kind(kind) + { + } + + TypeMemberFunctionImpl (clang::ObjCMethodDecl *method, + const std::string& name, + const lldb::MemberFunctionKind& kind) : + m_type(), + m_objc_method_decl(method), + m_name(name), + m_kind(kind) + { + } + + TypeMemberFunctionImpl (const TypeMemberFunctionImpl& rhs) : + m_type(rhs.m_type), + m_objc_method_decl(rhs.m_objc_method_decl), + m_name(rhs.m_name), + m_kind(rhs.m_kind) + { + } + + TypeMemberFunctionImpl& + operator = (const TypeMemberFunctionImpl& rhs); + + bool + IsValid (); + + ConstString + GetName () const; + + ClangASTType + GetType () const; + + ClangASTType + GetReturnType () const; + + size_t + GetNumArguments () const; + + ClangASTType + GetArgumentAtIndex (size_t idx) const; + + lldb::MemberFunctionKind + GetKind () const; + + bool + GetDescription (Stream& stream); + +protected: + std::string + GetPrintableTypeName (); + +private: + ClangASTType m_type; + clang::ObjCMethodDecl *m_objc_method_decl; + ConstString m_name; + lldb::MemberFunctionKind m_kind; +}; class TypeEnumMemberImpl { diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h index e1b146fe219e..c482739cb8f6 100644 --- a/include/lldb/Symbol/UnwindPlan.h +++ b/include/lldb/Symbol/UnwindPlan.h @@ -58,13 +58,13 @@ public: atDWARFExpression, // reg = deref(eval(dwarf_expr)) isDWARFExpression // reg = eval(dwarf_expr) }; - + RegisterLocation() : m_type(unspecified), m_location() { } - + bool operator == (const RegisterLocation& rhs) const; @@ -242,6 +242,7 @@ public: Row (const UnwindPlan::Row& rhs) : m_offset (rhs.m_offset), + m_cfa_type (rhs.m_cfa_type), m_cfa_reg_num (rhs.m_cfa_reg_num), m_cfa_offset (rhs.m_cfa_offset), m_register_locations (rhs.m_register_locations) @@ -256,7 +257,10 @@ public: void SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location); - + + void + RemoveRegisterInfo (uint32_t reg_num); + lldb::addr_t GetOffset() const { @@ -275,12 +279,49 @@ public: m_offset += offset; } + // How we can reconstruct the CFA address for this stack frame, at this location + enum CFAType + { + CFAIsRegisterPlusOffset, // the CFA value in a register plus (or minus) an offset + CFAIsRegisterDereferenced // the address in a register is dereferenced to get CFA value + }; + + CFAType + GetCFAType () const + { + return m_cfa_type; + } + + void + SetCFAType (CFAType cfa_type) + { + m_cfa_type = cfa_type; + } + + // If GetCFAType() is CFAIsRegisterPlusOffset, add GetCFAOffset to the reg value to get CFA value + // If GetCFAType() is CFAIsRegisterDereferenced, dereference the addr in the reg to get CFA value uint32_t GetCFARegister () const { return m_cfa_reg_num; } + void + SetCFARegister (uint32_t reg_num); + + // This should not be used when GetCFAType() is CFAIsRegisterDereferenced; will return 0 in that case. + int32_t + GetCFAOffset () const + { + return m_cfa_offset; + } + + void + SetCFAOffset (int32_t offset) + { + m_cfa_offset = offset; + } + bool SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, int32_t offset, @@ -309,23 +350,6 @@ public: SetRegisterLocationToSame (uint32_t reg_num, bool must_replace); - - - void - SetCFARegister (uint32_t reg_num); - - int32_t - GetCFAOffset () const - { - return m_cfa_offset; - } - - void - SetCFAOffset (int32_t offset) - { - m_cfa_offset = offset; - } - void Clear (); @@ -335,8 +359,15 @@ public: protected: typedef std::map<uint32_t, RegisterLocation> collection; lldb::addr_t m_offset; // Offset into the function for this row + + CFAType m_cfa_type; + + // If m_cfa_type == CFAIsRegisterPlusOffset, the CFA address is computed as m_cfa_reg_num + m_cfa_offset + // If m_cfa_type == CFAIsRegisterDereferenced, the CFA address is computed as *(m_cfa_reg_num) - i.e. the + // address in m_cfa_reg_num is dereferenced and the pointer value read is the CFA addr. uint32_t m_cfa_reg_num; // The Call Frame Address register number int32_t m_cfa_offset; // The offset from the CFA for this row + collection m_register_locations; }; // class Row @@ -351,7 +382,9 @@ public: m_return_addr_register (LLDB_INVALID_REGNUM), m_source_name (), m_plan_is_sourced_from_compiler (eLazyBoolCalculate), - m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate) + m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate), + m_lsda_address (), + m_personality_func_addr () { } @@ -477,11 +510,39 @@ public: m_plan_valid_address_range.Clear(); m_register_kind = lldb::eRegisterKindDWARF; m_source_name.Clear(); + m_plan_is_sourced_from_compiler = eLazyBoolCalculate; + m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate; + m_lsda_address.Clear(); + m_personality_func_addr.Clear(); } const RegisterInfo * GetRegisterInfo (Thread* thread, uint32_t reg_num) const; + Address + GetLSDAAddress () const + { + return m_lsda_address; + } + + void + SetLSDAAddress (Address lsda_addr) + { + m_lsda_address = lsda_addr; + } + + Address + GetPersonalityFunctionPtr () const + { + return m_personality_func_addr; + } + + void + SetPersonalityFunctionPtr (Address presonality_func_ptr) + { + m_personality_func_addr = presonality_func_ptr; + } + private: @@ -495,6 +556,11 @@ private: lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from lldb_private::LazyBool m_plan_is_sourced_from_compiler; lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations; + + Address m_lsda_address; // Where the language specific data area exists in the module - used + // in exception handling. + Address m_personality_func_addr; // The address of a pointer to the personality function - used in + // exception handling. }; // class UnwindPlan } // namespace lldb_private diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h index 3a89f9f1f3c6..38d3ff6dd3c9 100644 --- a/include/lldb/Symbol/UnwindTable.h +++ b/include/lldb/Symbol/UnwindTable.h @@ -31,6 +31,9 @@ public: lldb_private::DWARFCallFrameInfo * GetEHFrameInfo (); + lldb_private::CompactUnwindInfo * + GetCompactUnwindInfo (); + lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); @@ -63,6 +66,7 @@ private: Mutex m_mutex; DWARFCallFrameInfo* m_eh_frame; + CompactUnwindInfo *m_compact_unwind; DISALLOW_COPY_AND_ASSIGN (UnwindTable); }; diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h index 8809c0047fa0..cfd214d28874 100644 --- a/include/lldb/Target/ABI.h +++ b/include/lldb/Target/ABI.h @@ -112,12 +112,6 @@ public: virtual bool RegisterIsVolatile (const RegisterInfo *reg_info) = 0; - // Should return true if your ABI uses frames when doing stack backtraces. This - // means a frame pointer is used that points to the previous stack frame in some - // way or another. - virtual bool - StackUsesFrames () = 0; - // Should take a look at a call frame address (CFA) which is just the stack // pointer value upon entry to a function. ABIs usually impose alignment // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed. @@ -143,15 +137,6 @@ public: virtual const RegisterInfo * GetRegisterInfoArray (uint32_t &count) = 0; - // Some architectures (e.g. x86) will push the return address on the stack and decrement - // the stack pointer when making a function call. This means that every stack frame will - // have a unique CFA. - // Other architectures (e.g. arm) pass the return address in a register so it is possible - // to have a frame on a backtrace that does not push anything on the stack or change the - // CFA. - virtual bool - FunctionCallsChangeCFA () = 0; - bool GetRegisterInfoByName (const ConstString &name, RegisterInfo &info); diff --git a/include/lldb/Target/CPPLanguageRuntime.h b/include/lldb/Target/CPPLanguageRuntime.h index daf8a67d2a9d..43df9e67add0 100644 --- a/include/lldb/Target/CPPLanguageRuntime.h +++ b/include/lldb/Target/CPPLanguageRuntime.h @@ -65,8 +65,10 @@ public: Clear(); bool - IsValid () const + IsValid () { + if (!m_parsed) + Parse(); if (m_parse_error) return false; if (m_type == eTypeInvalid) @@ -132,9 +134,16 @@ public: static bool IsCPPMangledName(const char *name); - + + // Extract C++ context and identifier from a string using heuristic matching (as opposed to + // CPPLanguageRuntime::MethodName which has to have a fully qualified C++ name with parens and arguments. + // If the name is a lone C identifier (e.g. C) or a qualified C identifier (e.g. A::B::C) it will return true, + // and identifier will be the identifier (C and C respectively) and the context will be "" and "A::B::" respectively. + // If the name fails the heuristic matching for a qualified or unqualified C/C++ identifier, then it will return false + // and identifier and context will be unchanged. + static bool - StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end); + ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier); // in some cases, compilers will output different names for one same type. when that happens, it might be impossible // to construct SBType objects for a valid type, because the name that is available is not the same as the name that diff --git a/include/lldb/Target/FileAction.h b/include/lldb/Target/FileAction.h index db84c0ef468c..228a9e6098c1 100644 --- a/include/lldb/Target/FileAction.h +++ b/include/lldb/Target/FileAction.h @@ -56,6 +56,9 @@ class FileAction const char *GetPath() const; + void + Dump (Stream &stream) const; + protected: Action m_action; // The action for this file int m_fd; // An existing file descriptor diff --git a/include/lldb/Target/InstrumentationRuntime.h b/include/lldb/Target/InstrumentationRuntime.h new file mode 100644 index 000000000000..70aa62908406 --- /dev/null +++ b/include/lldb/Target/InstrumentationRuntime.h @@ -0,0 +1,47 @@ +//===-- InstrumentationRuntime.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_InstrumentationRuntime_h_ +#define liblldb_InstrumentationRuntime_h_ + +// C Includes +// C++ Includes +#include <vector> +#include <map> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/lldb-types.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +typedef std::map<lldb::InstrumentationRuntimeType, lldb::InstrumentationRuntimeSP> InstrumentationRuntimeCollection; + +class InstrumentationRuntime : + public std::enable_shared_from_this<InstrumentationRuntime>, + public PluginInterface +{ +public: + + static void + ModulesDidLoad(lldb_private::ModuleList &module_list, Process *process, InstrumentationRuntimeCollection &runtimes); + + virtual void + ModulesDidLoad(lldb_private::ModuleList &module_list); + + virtual bool + IsActive(); + +}; + +} // namespace lldb_private + +#endif // liblldb_InstrumentationRuntime_h_ diff --git a/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/include/lldb/Target/InstrumentationRuntimeStopInfo.h new file mode 100644 index 000000000000..624267ce8221 --- /dev/null +++ b/include/lldb/Target/InstrumentationRuntimeStopInfo.h @@ -0,0 +1,52 @@ +//===-- InstrumentationRuntimeStopInfo.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_InstrumentationRuntimeStopInfo_h_ +#define liblldb_InstrumentationRuntimeStopInfo_h_ + +// C Includes +// C++ Includes +#include <string> + +// Other libraries and framework includes +// Project includes +#include "lldb/Target/StopInfo.h" +#include "lldb/Core/StructuredData.h" + +namespace lldb_private { + +class InstrumentationRuntimeStopInfo : public StopInfo +{ +public: + + virtual ~InstrumentationRuntimeStopInfo() + { + } + + virtual lldb::StopReason + GetStopReason () const + { + return lldb::eStopReasonInstrumentation; + } + + virtual const char * + GetDescription (); + + static lldb::StopInfoSP + CreateStopReasonWithInstrumentationData (Thread &thread, std::string description, StructuredData::ObjectSP additional_data); + +private: + + InstrumentationRuntimeStopInfo(Thread &thread, std::string description, StructuredData::ObjectSP additional_data); + +}; + +} // namespace lldb_private + +#endif // liblldb_InstrumentationRuntimeStopInfo_h_ diff --git a/include/lldb/Target/MemoryHistory.h b/include/lldb/Target/MemoryHistory.h new file mode 100644 index 000000000000..b3bd62d6547c --- /dev/null +++ b/include/lldb/Target/MemoryHistory.h @@ -0,0 +1,42 @@ +//===-- MemoryHistory.h ---------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_MemoryHistory_h_ +#define liblldb_MemoryHistory_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/lldb-types.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +typedef std::vector<lldb::ThreadSP> HistoryThreads; + +class MemoryHistory : + public std::enable_shared_from_this<MemoryHistory>, + public PluginInterface +{ +public: + + static lldb::MemoryHistorySP + FindPlugin (const lldb::ProcessSP process); + + virtual HistoryThreads + GetHistoryThreads(lldb::addr_t address) = 0; +}; + +} // namespace lldb_private + +#endif // liblldb_MemoryHistory_h_ diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h index 12254f942e42..a3fee91428fa 100644 --- a/include/lldb/Target/ObjCLanguageRuntime.h +++ b/include/lldb/Target/ObjCLanguageRuntime.h @@ -21,8 +21,8 @@ #include "lldb/lldb-private.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/DeclVendor.h" #include "lldb/Symbol/Type.h" -#include "lldb/Symbol/TypeVendor.h" #include "lldb/Target/LanguageRuntime.h" namespace lldb_private { @@ -166,6 +166,9 @@ public: virtual ClassDescriptorSP GetSuperclass () = 0; + virtual ClassDescriptorSP + GetMetaclass () const = 0; + // virtual if any implementation has some other version-specific rules // but for the known v1/v2 this is all that needs to be done virtual bool @@ -275,10 +278,10 @@ public: class EncodingToType { public: - virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const char* name, bool allow_unknownanytype); - virtual ClangASTType RealizeType (const char* name, bool allow_unknownanytype); + virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const char* name, bool for_expression); + virtual ClangASTType RealizeType (const char* name, bool for_expression); - virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool allow_unknownanytype) = 0; + virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool for_expression) = 0; virtual ~EncodingToType(); @@ -382,8 +385,8 @@ public: virtual ObjCISA GetParentClass(ObjCISA isa); - virtual TypeVendor * - GetTypeVendor() + virtual DeclVendor * + GetDeclVendor() { return NULL; } diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h index e3d6abe3f398..8b14cc2a0ece 100644 --- a/include/lldb/Target/Platform.h +++ b/include/lldb/Target/Platform.h @@ -62,7 +62,7 @@ namespace lldb_private { /// or attaching to processes unless another platform is specified. //------------------------------------------------------------------ static lldb::PlatformSP - GetDefaultPlatform (); + GetHostPlatform (); static lldb::PlatformSP GetPlatformForArchitecture (const ArchSpec &arch, @@ -72,10 +72,14 @@ namespace lldb_private { GetHostPlatformName (); static void - SetDefaultPlatform (const lldb::PlatformSP &platform_sp); + SetHostPlatform (const lldb::PlatformSP &platform_sp); + // Find an existing platform plug-in by name static lldb::PlatformSP - Create (const char *platform_name, Error &error); + Find (const ConstString &name); + + static lldb::PlatformSP + Create (const ConstString &name, Error &error); static lldb::PlatformSP Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error); @@ -114,8 +118,8 @@ namespace lldb_private { /// An optional name of a specific platform plug-in that /// should be used. If NULL, pick the best plug-in. //------------------------------------------------------------------ - static Platform* - FindPlugin (Process *process, const ConstString &plugin_name); +// static lldb::PlatformSP +// FindPlugin (Process *process, const ConstString &plugin_name); //------------------------------------------------------------------ /// Set the target's executable based off of the existing @@ -137,8 +141,7 @@ namespace lldb_private { /// a suitable executable, \b false otherwise. //------------------------------------------------------------------ virtual Error - ResolveExecutable (const FileSpec &exe_file, - const ArchSpec &arch, + ResolveExecutable (const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr); @@ -409,7 +412,6 @@ namespace lldb_private { DebugProcess (ProcessLaunchInfo &launch_info, Debugger &debugger, Target *target, // Can be NULL, if NULL create a new target, else use existing one - Listener &listener, Error &error); //------------------------------------------------------------------ @@ -434,7 +436,6 @@ namespace lldb_private { Attach (ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, // Can be NULL, if NULL create a new target, else use existing one - Listener &listener, Error &error) = 0; //------------------------------------------------------------------ @@ -559,7 +560,16 @@ namespace lldb_private { SetSDKBuild (const ConstString &sdk_build) { m_sdk_build = sdk_build; - } + } + + // Override this to return true if your platform supports Clang modules. + // You may also need to override AddClangModuleCompilationOptions to pass the right Clang flags for your platform. + virtual bool + SupportsModules () { return false; } + + // Appends the platform-specific options required to find the modules for the current platform. + virtual void + AddClangModuleCompilationOptions (std::vector<std::string> &options); ConstString GetWorkingDirectory (); @@ -571,7 +581,7 @@ namespace lldb_private { // The platform will return "true" from this call if the passed in module happens to be one of these. virtual bool - ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp) + ModuleIsExcludedForUnconstrainedSearches (Target &target, const lldb::ModuleSP &module_sp) { return false; } diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index 641707c58deb..e04de511c797 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -38,6 +38,7 @@ #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostThread.h" #include "lldb/Host/ProcessRunLock.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/Options.h" @@ -51,6 +52,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/PseudoTerminal.h" +#include "lldb/Target/InstrumentationRuntime.h" namespace lldb_private { @@ -60,7 +62,8 @@ namespace lldb_private { class ProcessProperties : public Properties { public: - ProcessProperties(bool is_global); + // Pass NULL for "process" if the ProcessProperties are to be the global copy + ProcessProperties (lldb_private::Process *process); virtual ~ProcessProperties(); @@ -68,6 +71,9 @@ public: bool GetDisableMemoryCache() const; + uint64_t + GetMemoryCacheLineSize () const; + Args GetExtraStartupCommands () const; @@ -103,6 +109,13 @@ public: void SetDetachKeepsStopped (bool keep_stopped); + +protected: + + static void + OptionValueChangedCallback (void *baton, OptionValue *option_value); + + Process * m_process; // Can be NULL for global ProcessProperties }; typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP; @@ -223,6 +236,8 @@ 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), @@ -234,6 +249,8 @@ public: ProcessAttachInfo (const ProcessLaunchInfo &launch_info) : ProcessInstanceInfo(), + m_listener_sp(), + m_hijack_listener_sp(), m_plugin_name (), m_resume_count (0), m_wait_for_launch (false), @@ -244,6 +261,7 @@ public: ProcessInfo::operator= (launch_info); SetProcessPluginName (launch_info.GetProcessPluginName()); SetResumeCount (launch_info.GetResumeCount()); + SetListener(launch_info.GetListener()); SetHijackListener(launch_info.GetHijackListener()); m_detach_on_error = launch_info.GetDetachOnError(); } @@ -359,8 +377,26 @@ public: { m_detach_on_error = enable; } - + + // Get and set the actual listener that will be used for the process events + lldb::ListenerSP + GetListener () const + { + return m_listener_sp; + } + + void + SetListener (const lldb::ListenerSP &listener_sp) + { + m_listener_sp = listener_sp; + } + + + Listener & + GetListenerForProcess (Debugger &debugger); + 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 @@ -1268,7 +1304,9 @@ public: //------------------------------------------------------------------ Error Resume(); - + + Error + ResumeSynchronous (Stream *stream); //------------------------------------------------------------------ /// Halts a running process. /// @@ -2447,17 +2485,26 @@ public: //------------------------------------------------------------------ /// Get any available STDOUT. /// - /// If the process was launched without supplying valid file paths - /// for stdin, stdout, and stderr, then the Process class might - /// try to cache the STDOUT for the process if it is able. Events - /// will be queued indicating that there is STDOUT available that - /// can be retrieved using this function. + /// Calling this method is a valid operation only if all of the + /// following conditions are true: + /// 1) The process was launched, and not attached to. + /// 2) The process was not launched with eLaunchFlagDisableSTDIO. + /// 3) The process was launched without supplying a valid file path + /// for STDOUT. + /// + /// Note that the implementation will probably need to start a read + /// thread in the background to make sure that the pipe is drained + /// and the STDOUT buffered appropriately, to prevent the process + /// from deadlocking trying to write to a full buffer. + /// + /// Events will be queued indicating that there is STDOUT available + /// that can be retrieved using this function. /// /// @param[out] buf /// A buffer that will receive any STDOUT bytes that are /// currently available. /// - /// @param[out] buf_size + /// @param[in] buf_size /// The size in bytes for the buffer \a buf. /// /// @return @@ -2471,13 +2518,22 @@ public: //------------------------------------------------------------------ /// Get any available STDERR. /// - /// If the process was launched without supplying valid file paths - /// for stdin, stdout, and stderr, then the Process class might - /// try to cache the STDERR for the process if it is able. Events - /// will be queued indicating that there is STDERR available that - /// can be retrieved using this function. + /// Calling this method is a valid operation only if all of the + /// following conditions are true: + /// 1) The process was launched, and not attached to. + /// 2) The process was not launched with eLaunchFlagDisableSTDIO. + /// 3) The process was launched without supplying a valid file path + /// for STDERR. /// - /// @param[out] buf + /// Note that the implementation will probably need to start a read + /// thread in the background to make sure that the pipe is drained + /// and the STDERR buffered appropriately, to prevent the process + /// from deadlocking trying to write to a full buffer. + /// + /// Events will be queued indicating that there is STDERR available + /// that can be retrieved using this function. + /// + /// @param[in] buf /// A buffer that will receive any STDERR bytes that are /// currently available. /// @@ -2492,6 +2548,27 @@ public: virtual size_t GetSTDERR (char *buf, size_t buf_size, Error &error); + //------------------------------------------------------------------ + /// Puts data into this process's STDIN. + /// + /// Calling this method is a valid operation only if all of the + /// following conditions are true: + /// 1) The process was launched, and not attached to. + /// 2) The process was not launched with eLaunchFlagDisableSTDIO. + /// 3) The process was launched without supplying a valid file path + /// for STDIN. + /// + /// @param[in] buf + /// A buffer that contains the data to write to the process's STDIN. + /// + /// @param[in] buf_size + /// The size in bytes for the buffer \a buf. + /// + /// @return + /// The number of bytes written into \a buf. If this value is + /// less than \a buf_size, another call to this function should + /// be made to write the rest of the data. + //------------------------------------------------------------------ virtual size_t PutSTDIN (const char *buf, size_t buf_size, Error &error) { @@ -2675,7 +2752,8 @@ public: WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr = NULL, bool wait_always = true, - Listener *hijack_listener = NULL); + Listener *hijack_listener = NULL, + Stream *stream = NULL); //-------------------------------------------------------------------------------------- @@ -2700,7 +2778,28 @@ public: WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp, Listener *hijack_listener); // Pass NULL to use builtin listener - + + //-------------------------------------------------------------------------------------- + /// Centralize the code that handles and prints descriptions for process state changes. + /// + /// @param[in] event_sp + /// The process state changed event + /// + /// @param[in] stream + /// The output stream to get the state change description + /// + /// @param[inout] pop_process_io_handler + /// If this value comes in set to \b true, then pop the Process IOHandler if needed. + /// Else this variable will be set to \b true or \b false to indicate if the process + /// needs to have its process IOHandler popped. + /// + /// @return + /// \b true if the event describes a process state changed event, \b false otherwise. + //-------------------------------------------------------------------------------------- + static bool + HandleProcessStateChangedEvent (const lldb::EventSP &event_sp, + Stream *stream, + bool &pop_process_io_handler); Event * PeekAtStateChangedEvents (); @@ -2723,6 +2822,7 @@ public: Process &m_process; }; friend class ProcessEventHijacker; + friend class ProcessProperties; //------------------------------------------------------------------ /// If you need to ensure that you and only you will hear about some public /// event, then make a new listener, set to listen to process events, and @@ -2776,7 +2876,12 @@ public: { return m_os_ap.get(); } - + + ArchSpec::StopInfoOverrideCallbackType + GetStopInfoOverrideCallback () const + { + return m_stop_info_override_callback; + } virtual LanguageRuntime * GetLanguageRuntime (lldb::LanguageType language, bool retry_if_null = true); @@ -2906,7 +3011,7 @@ public: ProcessRunLock & GetRunLock () { - if (Host::GetCurrentThread() == m_private_state_thread) + if (m_private_state_thread.EqualsThread(Host::GetCurrentThread())) return m_private_run_lock; else return m_public_run_lock; @@ -2919,6 +3024,12 @@ public: Error return_error ("Sending an event is not supported for this process."); return return_error; } + + lldb::ThreadCollectionSP + GetHistoryThreads(lldb::addr_t addr); + + lldb::InstrumentationRuntimeSP + GetInstrumentationRuntime(lldb::InstrumentationRuntimeType type); protected: @@ -3001,7 +3112,7 @@ protected: bool PrivateStateThreadIsValid () const { - return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread); + return m_private_state_thread.IsJoinable(); } void @@ -3036,13 +3147,14 @@ protected: Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread. Listener m_private_state_listener; // This is the listener for the private state thread. Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete. - lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches internal state events + HostThread m_private_state_thread; // Thread ID for the thread that watches internal state events ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used. std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map; int m_exit_status; ///< The exit status of the process, or -1 if not set. std::string m_exit_string; ///< A textual description of why a process exited. + Mutex m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can be safely accessed from multiple threads Mutex m_thread_mutex; ThreadList m_thread_list_real; ///< The threads for this process as are known to the protocol we are debugging with ThreadList m_thread_list; ///< The threads for this process as the user will see them. This is usually the same as @@ -3074,11 +3186,13 @@ protected: AllocatedMemoryCache m_allocated_memory_cache; bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach? LanguageRuntimeCollection m_language_runtimes; + InstrumentationRuntimeCollection m_instrumentation_runtimes; std::unique_ptr<NextEventAction> m_next_event_action_ap; std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions; ProcessRunLock m_public_run_lock; ProcessRunLock m_private_run_lock; Predicate<bool> m_currently_handling_event; // This predicate is set in HandlePrivateEvent while all its business is being done. + ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback; bool m_currently_handling_do_on_removals; bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check. bool m_finalize_called; @@ -3170,7 +3284,12 @@ protected: Error HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp); - + + bool + StateChangedIsExternallyHijacked(); + + void + LoadOperatingSystemPlugin(bool flush); private: //------------------------------------------------------------------ // For Process only diff --git a/include/lldb/Target/ProcessLaunchInfo.h b/include/lldb/Target/ProcessLaunchInfo.h index 77d829a7e476..897704488e5f 100644 --- a/include/lldb/Target/ProcessLaunchInfo.h +++ b/include/lldb/Target/ProcessLaunchInfo.h @@ -15,6 +15,7 @@ // LLDB Headers #include "lldb/Core/Flags.h" +#include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/ProcessInfo.h" @@ -105,11 +106,11 @@ namespace lldb_private void SetProcessPluginName (const char *plugin); - const char * + const FileSpec & GetShell () const; void - SetShell (const char * path); + SetShell (const FileSpec &shell); uint32_t GetResumeCount () const @@ -124,7 +125,7 @@ namespace lldb_private } bool - GetLaunchInSeparateProcessGroup () + GetLaunchInSeparateProcessGroup() const { return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup); } @@ -148,17 +149,23 @@ namespace lldb_private bool monitor_signals); Host::MonitorChildProcessCallback - GetMonitorProcessCallback () + GetMonitorProcessCallback() const { return m_monitor_callback; } - const void* - GetMonitorProcessBaton () const + void * + GetMonitorProcessBaton() const { return m_monitor_callback_baton; } + bool + GetMonitorSignals() const + { + return m_monitor_signals; + } + // If the LaunchInfo has a monitor callback, then arrange to monitor the process. // Return true if the LaunchInfo has taken care of monitoring the process, and false if the // caller might want to monitor the process themselves. @@ -169,9 +176,25 @@ namespace lldb_private lldb_utility::PseudoTerminal & GetPTY () { - return m_pty; + return *m_pty; } + // Get and set the actual listener that will be used for the process events + lldb::ListenerSP + GetListener () const + { + return m_listener_sp; + } + + void + SetListener (const lldb::ListenerSP &listener_sp) + { + m_listener_sp = listener_sp; + } + + Listener & + GetListenerForProcess (Debugger &debugger); + lldb::ListenerSP GetHijackListener () const { @@ -184,7 +207,6 @@ namespace lldb_private m_hijack_listener_sp = listener_sp; } - void SetLaunchEventData (const char *data) { @@ -209,15 +231,16 @@ namespace lldb_private protected: std::string m_working_dir; std::string m_plugin_name; - std::string m_shell; + FileSpec m_shell; Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags std::vector<FileAction> m_file_actions; // File actions for any other files - lldb_utility::PseudoTerminal m_pty; + std::shared_ptr<lldb_utility::PseudoTerminal> m_pty; uint32_t m_resume_count; // How many times do we resume after launching Host::MonitorChildProcessCallback m_monitor_callback; void *m_monitor_callback_baton; bool m_monitor_signals; std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb. + lldb::ListenerSP m_listener_sp; lldb::ListenerSP m_hijack_listener_sp; }; } diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h index 1274dcc64bd3..95e21445be04 100644 --- a/include/lldb/Target/StackFrame.h +++ b/include/lldb/Target/StackFrame.h @@ -519,6 +519,7 @@ private: lldb::VariableListSP m_variable_list_sp; ValueObjectList m_variable_list_value_objects; // Value objects for each variable in m_variable_list_sp StreamString m_disassembly; + Mutex m_mutex; DISALLOW_COPY_AND_ASSIGN (StackFrame); }; diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h index 8de40e852f4c..e0d029bcc956 100644 --- a/include/lldb/Target/StopInfo.h +++ b/include/lldb/Target/StopInfo.h @@ -18,6 +18,7 @@ // Project includes #include "lldb/lldb-public.h" #include "lldb/Target/Process.h" +#include "lldb/Core/StructuredData.h" namespace lldb_private { @@ -140,6 +141,12 @@ public: return m_override_should_stop == eLazyBoolYes; } + StructuredData::ObjectSP + GetExtendedInfo () + { + return m_extended_info; + } + static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id); @@ -211,6 +218,8 @@ protected: LazyBool m_override_should_notify; LazyBool m_override_should_stop; + StructuredData::ObjectSP m_extended_info; // The extended info for this stop info + // This determines whether the target has run since this stop info. // N.B. running to evaluate a user expression does not count. bool HasTargetRunSinceMe (); diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index 64f3edf0fc4f..a33734fd5b63 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -26,6 +26,7 @@ #include "lldb/Core/Event.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/UserSettingsController.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/OptionValueBoolean.h" @@ -554,12 +555,20 @@ private: //------------------------------------------------------------------ Target (Debugger &debugger, const ArchSpec &target_arch, - const lldb::PlatformSP &platform_sp); + const lldb::PlatformSP &platform_sp, + bool is_dummy_target); // Helper function. bool ProcessIsValid (); + // Copy breakpoints, stop hooks and so forth from the dummy target: + void + PrimeFromDummyTarget(Target *dummy_target); + + void + AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal); + public: ~Target(); @@ -607,8 +616,8 @@ public: Destroy(); Error - Launch (Listener &listener, - ProcessLaunchInfo &launch_info); + Launch (ProcessLaunchInfo &launch_info, + Stream *stream); // Optional stream to receive first stop info //------------------------------------------------------------------ // This part handles the breakpoints. @@ -954,9 +963,9 @@ public: //------------------------------------------------------------------ /// Return whether this FileSpec corresponds to a module that should be considered for general searches. /// - /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches + /// This API will be consulted by the SearchFilterForUnconstrainedSearches /// and any module that returns \b true will not be searched. Note the - /// SearchFilterForNonModuleSpecificSearches is the search filter that + /// SearchFilterForUnconstrainedSearches is the search filter that /// gets used in the CreateBreakpoint calls when no modules is provided. /// /// The target call at present just consults the Platform's call of the @@ -968,14 +977,14 @@ public: /// @return \b true if the module should be excluded, \b false otherwise. //------------------------------------------------------------------ bool - ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_spec); + ModuleIsExcludedForUnconstrainedSearches (const FileSpec &module_spec); //------------------------------------------------------------------ /// Return whether this module should be considered for general searches. /// - /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches + /// This API will be consulted by the SearchFilterForUnconstrainedSearches /// and any module that returns \b true will not be searched. Note the - /// SearchFilterForNonModuleSpecificSearches is the search filter that + /// SearchFilterForUnconstrainedSearches is the search filter that /// gets used in the CreateBreakpoint calls when no modules is provided. /// /// The target call at present just consults the Platform's call of the @@ -990,7 +999,7 @@ public: /// @return \b true if the module should be excluded, \b false otherwise. //------------------------------------------------------------------ bool - ModuleIsExcludedForNonModuleSpecificSearches (const lldb::ModuleSP &module_sp); + ModuleIsExcludedForUnconstrainedSearches (const lldb::ModuleSP &module_sp); ArchSpec & GetArchitecture () @@ -1132,6 +1141,9 @@ public: Error Install(ProcessLaunchInfo *launch_info); + bool + ResolveFileAddress (lldb::addr_t load_addr, + Address &so_addr); bool ResolveLoadAddress (lldb::addr_t load_addr, @@ -1143,6 +1155,12 @@ public: lldb::addr_t load_addr, bool warn_multiple = false); + size_t + UnloadModuleSections (const lldb::ModuleSP &module_sp); + + size_t + UnloadModuleSections (const ModuleList &module_list); + bool SetSectionUnloaded (const lldb::SectionSP §ion_sp); @@ -1332,6 +1350,9 @@ public: SourceManager & GetSourceManager (); + + ClangModulesDeclVendor * + GetClangModulesDeclVendor (); //------------------------------------------------------------------ // Methods. @@ -1369,6 +1390,7 @@ protected: std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap; std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap; std::unique_ptr<ClangASTImporter> m_ast_importer_ap; + std::unique_ptr<ClangModulesDeclVendor> m_clang_modules_decl_vendor_ap; ClangPersistentVariables m_persistent_variables; ///< These are the persistent variables associated with this process for the expression parser. std::unique_ptr<SourceManager> m_source_manager_ap; @@ -1378,6 +1400,7 @@ protected: lldb::user_id_t m_stop_hook_next_id; bool m_valid; bool m_suppress_stop_hooks; + bool m_is_dummy_target; static void ImageSearchPathsChanged (const PathMappingList &path_list, diff --git a/include/lldb/Target/TargetList.h b/include/lldb/Target/TargetList.h index 6abf13e8704c..27e46ba81a70 100644 --- a/include/lldb/Target/TargetList.h +++ b/include/lldb/Target/TargetList.h @@ -221,16 +221,42 @@ public: lldb::TargetSP GetSelectedTarget (); - protected: typedef std::vector<lldb::TargetSP> collection; //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ collection m_target_list; + lldb::TargetSP m_dummy_target_sp; mutable Mutex m_target_list_mutex; uint32_t m_selected_target_idx; private: + lldb::TargetSP + GetDummyTarget (lldb_private::Debugger &debugger); + + Error + CreateDummyTarget (Debugger &debugger, + const char *specified_arch_name, + lldb::TargetSP &target_sp); + + Error + CreateTargetInternal (Debugger &debugger, + const char *user_exe_path, + const char *triple_cstr, + bool get_dependent_files, + const OptionGroupPlatform *platform_options, + lldb::TargetSP &target_sp, + bool is_dummy_target); + + Error + CreateTargetInternal (Debugger &debugger, + const char *user_exe_path, + const ArchSpec& arch, + bool get_dependent_modules, + lldb::PlatformSP &platform_sp, + lldb::TargetSP &target_sp, + bool is_dummy_target); + DISALLOW_COPY_AND_ASSIGN (TargetList); }; diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h index cba09e164105..25c0c0e92bec 100644 --- a/include/lldb/Target/Thread.h +++ b/include/lldb/Target/Thread.h @@ -535,7 +535,7 @@ public: DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx); bool - GetDescription (Stream &s, lldb::DescriptionLevel level, bool json_output); + GetDescription (Stream &s, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo); //------------------------------------------------------------------ /// Default implementation for stepping into. @@ -912,6 +912,11 @@ public: bool stop_others, uint32_t frame_idx); + virtual lldb::ThreadPlanSP + QueueThreadPlanForStepScripted (bool abort_other_plans, + const char *class_name, + bool stop_other_threads); + //------------------------------------------------------------------ // Thread Plan accessors: //------------------------------------------------------------------ @@ -1041,6 +1046,20 @@ public: void DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr); + + //------------------------------------------------------------------ + /// Discards the plans queued on the plan stack of the current thread up to and + /// including the plan in that matches \a thread_index counting only + /// the non-Private plans. + /// + /// @param[in] up_to_plan_sp + /// Discard all plans up to and including this user plan given by this index. + /// + /// @return + /// \b true if there was a thread plan with that user index, \b false otherwise. + //------------------------------------------------------------------ + bool + DiscardUserThreadPlansUpToIndex (uint32_t thread_index); //------------------------------------------------------------------ /// Prints the current plan stack. @@ -1050,7 +1069,10 @@ public: /// //------------------------------------------------------------------ void - DumpThreadPlans (Stream *s) const; + DumpThreadPlans (Stream *s, + lldb::DescriptionLevel desc_level = lldb::eDescriptionLevelVerbose, + bool include_internal = true, + bool ignore_boring = false) const; virtual bool CheckpointThreadState (ThreadStateCheckpoint &saved_state); @@ -1293,6 +1315,7 @@ protected: lldb::ProcessWP m_process_wp; ///< The process that owns this thread. lldb::StopInfoSP m_stop_info_sp; ///< The private stop reason for this thread uint32_t m_stop_info_stop_id; // This is the stop id for which the StopInfo is valid. Can use this so you know that + uint32_t m_stop_info_override_stop_id; // The stop ID containing the last time the stop info was checked against the stop info override // the thread's m_stop_info_sp is current and you don't have to fetch it again const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access. lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state. diff --git a/include/lldb/Target/ThreadCollection.h b/include/lldb/Target/ThreadCollection.h new file mode 100644 index 000000000000..0c2b41cc0ca4 --- /dev/null +++ b/include/lldb/Target/ThreadCollection.h @@ -0,0 +1,70 @@ +//===-- ThreadCollection.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadCollection_h_ +#define liblldb_ThreadCollection_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Utility/Iterable.h" + +namespace lldb_private { + +class ThreadCollection +{ +public: + typedef std::vector<lldb::ThreadSP> collection; + typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable; + + ThreadCollection(); + + ThreadCollection(collection threads); + + virtual + ~ThreadCollection() + { + } + + uint32_t + GetSize(); + + void + AddThread (const lldb::ThreadSP &thread_sp); + + void + InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx); + + // Note that "idx" is not the same as the "thread_index". It is a zero + // based index to accessing the current threads, whereas "thread_index" + // is a unique index assigned + lldb::ThreadSP + GetThreadAtIndex (uint32_t idx); + + virtual ThreadIterable + Threads () + { + return ThreadIterable(m_threads, GetMutex()); + } + + virtual Mutex & + GetMutex() + { + return m_mutex; + } + +protected: + collection m_threads; + Mutex m_mutex; +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadCollection_h_ diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h index 65d9b74098a6..12c430c9c8d8 100644 --- a/include/lldb/Target/ThreadList.h +++ b/include/lldb/Target/ThreadList.h @@ -15,16 +15,14 @@ #include "lldb/lldb-private.h" #include "lldb/Core/UserID.h" #include "lldb/Utility/Iterable.h" +#include "lldb/Target/ThreadCollection.h" - -// FIXME: Currently this is a thread list with lots of functionality for use only by -// the process for which this is the thread list. If we ever want a container class -// to hand out that is just a random subset of threads, with iterator functionality, -// then we should make that part a base class, and make a ProcessThreadList for the -// process. namespace lldb_private { -class ThreadList +// This is a thread list with lots of functionality for use only by the process +// for which this is the thread list. A generic container class with iterator +// functionality is ThreadCollection. +class ThreadList : public ThreadCollection { friend class Process; @@ -34,6 +32,7 @@ public: ThreadList (const ThreadList &rhs); + virtual ~ThreadList (); const ThreadList& @@ -42,11 +41,6 @@ public: uint32_t GetSize(bool can_update = true); - void - AddThread (const lldb::ThreadSP &thread_sp); - - void - InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx); // Return the selected thread if there is one. Otherwise, return the thread // selected at index 0. lldb::ThreadSP @@ -72,15 +66,6 @@ public: // is a unique index assigned lldb::ThreadSP GetThreadAtIndex (uint32_t idx, bool can_update = true); - - typedef std::vector<lldb::ThreadSP> collection; - typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable; - - ThreadIterable - Threads () - { - return ThreadIterable(m_threads, GetMutex()); - } lldb::ThreadSP FindThreadByID (lldb::tid_t tid, bool can_update = true); @@ -143,7 +128,7 @@ public: void SetStopID (uint32_t stop_id); - Mutex & + virtual Mutex & GetMutex (); void @@ -162,7 +147,6 @@ protected: //------------------------------------------------------------------ Process *m_process; ///< The process that manages this thread list. uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for. - collection m_threads; ///< The threads for this process. lldb::tid_t m_selected_tid; ///< For targets that need the notion of a current thread. private: diff --git a/include/lldb/Target/ThreadPlan.h b/include/lldb/Target/ThreadPlan.h index 1f20841906d3..db2e79894057 100644 --- a/include/lldb/Target/ThreadPlan.h +++ b/include/lldb/Target/ThreadPlan.h @@ -223,6 +223,7 @@ namespace lldb_private { //------------------------------------------------------------------ class ThreadPlan : + public std::enable_shared_from_this<ThreadPlan>, public UserID { public: @@ -241,6 +242,7 @@ public: eKindNull, eKindBase, eKindCallFunction, + eKindPython, eKindStepInstruction, eKindStepOut, eKindStepOverBreakpoint, @@ -687,7 +689,8 @@ protected: virtual lldb::StateType GetPlanRunState (); - + + DISALLOW_COPY_AND_ASSIGN(ThreadPlanNull); }; diff --git a/include/lldb/Target/ThreadPlanPython.h b/include/lldb/Target/ThreadPlanPython.h new file mode 100644 index 000000000000..fa41af1915cd --- /dev/null +++ b/include/lldb/Target/ThreadPlanPython.h @@ -0,0 +1,80 @@ +//===-- ThreadPlanPython.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlan_Python_h_ +#define liblldb_ThreadPlan_Python_h_ + +// C Includes +// C++ Includes +#include <string> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanTracer.h" +#include "lldb/Target/StopInfo.h" + +namespace lldb_private { + +//------------------------------------------------------------------ +// ThreadPlanPython: +// +//------------------------------------------------------------------ + +class ThreadPlanPython : public ThreadPlan +{ +public: + ThreadPlanPython (Thread &thread, const char *class_name); + virtual ~ThreadPlanPython (); + + virtual void + GetDescription (Stream *s, + lldb::DescriptionLevel level); + + virtual bool + ValidatePlan (Stream *error); + + virtual bool + ShouldStop (Event *event_ptr); + + virtual bool + MischiefManaged (); + + virtual bool + WillStop (); + + virtual bool + StopOthers (); + + virtual void + DidPush (); + +protected: + virtual bool + DoPlanExplainsStop (Event *event_ptr); + + virtual lldb::StateType + GetPlanRunState (); + +private: + std::string m_class_name; + lldb::ScriptInterpreterObjectSP m_implementation_sp; + + DISALLOW_COPY_AND_ASSIGN(ThreadPlanPython); +}; + + +} // namespace lldb_private + +#endif // liblldb_ThreadPlan_Python_h_ diff --git a/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/include/lldb/Target/ThreadPlanStepOverBreakpoint.h index 41cac5c9b0b4..a4806056afb9 100644 --- a/include/lldb/Target/ThreadPlanStepOverBreakpoint.h +++ b/include/lldb/Target/ThreadPlanStepOverBreakpoint.h @@ -35,7 +35,13 @@ public: virtual void ThreadDestroyed (); void SetAutoContinue (bool do_it); virtual bool ShouldAutoContinue(Event *event_ptr); + virtual bool IsPlanStale(); + lldb::addr_t + GetBreakpointLoadAddress() const + { + return m_breakpoint_addr; + } protected: virtual bool DoPlanExplainsStop (Event *event_ptr); virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); diff --git a/include/lldb/Target/ThreadPlanStepRange.h b/include/lldb/Target/ThreadPlanStepRange.h index 3487e9ad66cb..43c55c2aa411 100644 --- a/include/lldb/Target/ThreadPlanStepRange.h +++ b/include/lldb/Target/ThreadPlanStepRange.h @@ -30,7 +30,8 @@ public: Thread &thread, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others); + lldb::RunMode stop_others, + bool given_ranges_only = false); virtual ~ThreadPlanStepRange (); @@ -83,6 +84,7 @@ protected: bool m_first_run_event; // We want to broadcast only one running event, our first. lldb::BreakpointSP m_next_branch_bp_sp; bool m_use_fast_step; + bool m_given_ranges_only; private: std::vector<lldb::DisassemblerSP> m_instruction_ranges; diff --git a/include/lldb/Target/Unwind.h b/include/lldb/Target/Unwind.h index 7cda4aeb2e18..17c6c0df8207 100644 --- a/include/lldb/Target/Unwind.h +++ b/include/lldb/Target/Unwind.h @@ -27,7 +27,7 @@ protected: //------------------------------------------------------------------ Unwind(Thread &thread) : m_thread (thread), - m_unwind_mutex() + m_unwind_mutex(Mutex::eMutexTypeRecursive) { } diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h index 9dd3ca5fe12b..9ffe5de27df1 100644 --- a/include/lldb/Utility/CleanUp.h +++ b/include/lldb/Utility/CleanUp.h @@ -11,6 +11,7 @@ #define liblldb_CleanUp_h_ #include "lldb/lldb-public.h" +#include <functional> namespace lldb_utility { @@ -57,7 +58,7 @@ class CleanUp { public: typedef T value_type; - typedef R (*CallbackType)(value_type); + typedef std::function<R(value_type)> CallbackType; //---------------------------------------------------------------------- // Constructor that sets the current value only. No values are @@ -188,7 +189,7 @@ class CleanUp2 { public: typedef T value_type; - typedef R (*CallbackType)(value_type, A0); + typedef std::function<R(value_type,A0)> CallbackType; //---------------------------------------------------------------------- // Constructor that sets the current value only. No values are diff --git a/include/lldb/Utility/Iterable.h b/include/lldb/Utility/Iterable.h index 17335373e72d..17c8cf4d2319 100644 --- a/include/lldb/Utility/Iterable.h +++ b/include/lldb/Utility/Iterable.h @@ -25,6 +25,11 @@ template <typename I, typename E> E vector_adapter(I &iter) return *iter; } +template <typename I, typename E> E list_adapter(I &iter) +{ + return *iter; +} + template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator { public: diff --git a/include/lldb/Utility/ProcessStructReader.h b/include/lldb/Utility/ProcessStructReader.h new file mode 100644 index 000000000000..7b05d93151aa --- /dev/null +++ b/include/lldb/Utility/ProcessStructReader.h @@ -0,0 +1,100 @@ +//===---------------------ProcessStructReader.h ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_ProcessStructReader_h_ +#define utility_ProcessStructReader_h_ + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Error.h" +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Target/Process.h" + +#include <initializer_list> +#include <map> +#include <string> + +namespace lldb_private { + class ProcessStructReader + { + protected: + struct FieldImpl + { + ClangASTType type; + size_t offset; + size_t size; + }; + + std::map<ConstString, FieldImpl> m_fields; + DataExtractor m_data; + lldb::ByteOrder m_byte_order; + size_t m_addr_byte_size; + + public: + ProcessStructReader (Process *process, lldb::addr_t base_addr, ClangASTType struct_type) + { + if (!process) + return; + if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS) + return; + m_byte_order = process->GetByteOrder(); + m_addr_byte_size = process->GetAddressByteSize(); + + for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) + { + std::string name; + uint64_t bit_offset; + uint32_t bitfield_bit_size; + bool is_bitfield; + ClangASTType field_type = struct_type.GetFieldAtIndex(idx,name,&bit_offset,&bitfield_bit_size,&is_bitfield); + // no support for bitfields in here (yet) + if (is_bitfield) + return; + auto size = field_type.GetByteSize(); + // no support for things larger than a uint64_t (yet) + if (size > 8) + return; + ConstString const_name = ConstString(name.c_str()); + size_t byte_index = static_cast<size_t>(bit_offset / 8); + m_fields[const_name] = FieldImpl{field_type, byte_index, static_cast<size_t>(size)}; + } + size_t total_size = struct_type.GetByteSize(); + lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size,0)); + Error error; + process->ReadMemoryFromInferior(base_addr, + buffer_sp->GetBytes(), + total_size, + error); + if (error.Fail()) + return; + m_data = DataExtractor(buffer_sp,m_byte_order,m_addr_byte_size); + } + + template<typename RetType> + RetType + GetField (ConstString name, RetType fail_value = RetType()) + { + auto iter = m_fields.find(name), end = m_fields.end(); + if (iter == end) + return fail_value; + auto size = iter->second.size; + if (sizeof(RetType) < size) + return fail_value; + lldb::offset_t offset = iter->second.offset; + if (offset + size > m_data.GetByteSize()) + return fail_value; + return (RetType)(m_data.GetMaxU64(&offset, size)); + } + }; +} + +#endif // utility_ProcessStructReader_h_ diff --git a/include/lldb/Utility/RegisterNumber.h b/include/lldb/Utility/RegisterNumber.h new file mode 100644 index 000000000000..89d52fd4a967 --- /dev/null +++ b/include/lldb/Utility/RegisterNumber.h @@ -0,0 +1,69 @@ +//===-- RegisterNumber.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterNumber_h +#define liblldb_RegisterNumber_h + +#include "lldb/lldb-private.h" +#include <map> + +//-------------------------------------------------------------------- +/// A class to represent register numbers, and able to convert between +/// different register numbering schemes that may be used in a single +/// debug session. +//-------------------------------------------------------------------- + +class RegisterNumber { +public: + RegisterNumber (lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num); + + // This constructor plus the init() method below allow for the placeholder + // creation of an invalid object initially, possibly to be filled in. It + // would be more consistent to have three Set* methods to set the three + // data that the object needs. + RegisterNumber (); + + void + init (lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num); + + const RegisterNumber & + operator = (const RegisterNumber &rhs); + + bool + operator == (RegisterNumber &rhs); + + bool + operator != (RegisterNumber &rhs); + + bool + IsValid () const; + + uint32_t + GetAsKind (lldb::RegisterKind kind); + + uint32_t + GetRegisterNumber () const; + + lldb::RegisterKind + GetRegisterKind () const; + + const char * + GetName (); + +private: + typedef std::map<lldb::RegisterKind, uint32_t> Collection; + + lldb::RegisterContextSP m_reg_ctx_sp; + uint32_t m_regnum; + lldb::RegisterKind m_kind; + Collection m_kind_regnum_map; + const char *m_name; +}; + +#endif // liblldb_RegisterNumber_h diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h index 42c169c5cf94..ae6b393b0eb6 100644 --- a/include/lldb/Utility/StringLexer.h +++ b/include/lldb/Utility/StringLexer.h @@ -10,8 +10,9 @@ #ifndef utility_StringLexer_h_ #define utility_StringLexer_h_ -#include <string> +#include <initializer_list> #include <list> +#include <string> namespace lldb_utility { @@ -27,12 +28,19 @@ public: StringLexer (const StringLexer& rhs); + // These APIs are not bounds-checked. Use HasAtLeast() if you're not sure. Character Peek (); bool NextIf (Character c); + std::pair<bool, Character> + NextIf (std::initializer_list<Character> cs); + + bool + AdvanceIf (const std::string& token); + Character Next (); @@ -42,8 +50,12 @@ public: bool HasAny (Character c); + std::string + GetUnlexed (); + + // This will assert if there are less than s characters preceding the cursor. void - PutBack (Character c); + PutBack (Size s); StringLexer& operator = (const StringLexer& rhs); @@ -51,7 +63,6 @@ public: private: std::string m_data; Position m_position; - std::list<Character> m_putback_data; void Consume(); diff --git a/include/lldb/lldb-defines.h b/include/lldb/lldb-defines.h index f8028c793233..add182c13ecb 100644 --- a/include/lldb/lldb-defines.h +++ b/include/lldb/lldb-defines.h @@ -49,7 +49,6 @@ // LLDB defines //---------------------------------------------------------------------- #define LLDB_GENERIC_ERROR UINT32_MAX -#define LLDB_DEFAULT_SHELL "/bin/sh" //---------------------------------------------------------------------- // Breakpoints diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index 612487fd4fad..87ee14875734 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -185,7 +185,8 @@ namespace lldb { eStopReasonException, eStopReasonExec, // Program was re-exec'ed eStopReasonPlanComplete, - eStopReasonThreadExiting + eStopReasonThreadExiting, + eStopReasonInstrumentation } StopReason; //---------------------------------------------------------------------- @@ -387,6 +388,11 @@ namespace lldb { eLanguageTypeDylan = 0x0020, ///< Dylan. eNumLanguageTypes } LanguageType; + + typedef enum InstrumentationRuntimeType { + eInstrumentationRuntimeTypeAddressSanitizer = 0x0000, + eNumInstrumentationRuntimeTypes + } InstrumentationRuntimeType; typedef enum DynamicValueType { @@ -414,6 +420,7 @@ namespace lldb { eArgTypeBoolean, eArgTypeBreakpointID, eArgTypeBreakpointIDRange, + eArgTypeBreakpointName, eArgTypeByteSize, eArgTypeClassName, eArgTypeCommandName, @@ -432,6 +439,7 @@ namespace lldb { eArgTypeFunctionName, eArgTypeFunctionOrSymbol, eArgTypeGDBFormat, + eArgTypeHelpText, eArgTypeIndex, eArgTypeLanguage, eArgTypeLineNum, @@ -563,6 +571,7 @@ namespace lldb { eSectionTypeELFRelocationEntries, // Elf SHT_REL or SHT_REL section eSectionTypeELFDynamicLinkInfo, // Elf SHT_DYNAMIC section eSectionTypeEHFrame, + eSectionTypeCompactUnwind, // compact unwind section in Mach-O, __TEXT,__unwind_info eSectionTypeOther } SectionType; @@ -846,9 +855,68 @@ namespace lldb { ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory ePathTypeLLDBSystemPlugins, // System plug-ins directory ePathTypeLLDBUserPlugins, // User plug-ins directory - ePathTypeLLDBTempSystemDir // The LLDB temp directory for this system that will be cleaned up on exit - + ePathTypeLLDBTempSystemDir, // The LLDB temp directory for this system that will be cleaned up on exit + ePathTypeClangDir // Find path to Clang builtin headers } PathType; + + //---------------------------------------------------------------------- + // Kind of member function + // Used by the type system + //---------------------------------------------------------------------- + typedef enum MemberFunctionKind + { + eMemberFunctionKindUnknown = 0, // Not sure what the type of this is + eMemberFunctionKindConstructor, // A function used to create instances + eMemberFunctionKindDestructor, // A function used to tear down existing instances + eMemberFunctionKindInstanceMethod, // A function that applies to a specific instance + eMemberFunctionKindStaticMethod // A function that applies to a type rather than any instance + } MemberFunctionKind; + + + //---------------------------------------------------------------------- + // String matching algorithm used by SBTarget + //---------------------------------------------------------------------- + typedef enum MatchType { + eMatchTypeNormal, + eMatchTypeRegex, + eMatchTypeStartsWith + } MatchType; + + //---------------------------------------------------------------------- + // Bitmask that describes details about a type + //---------------------------------------------------------------------- + typedef enum TypeFlags { + eTypeHasChildren = (1u << 0), + eTypeHasValue = (1u << 1), + eTypeIsArray = (1u << 2), + eTypeIsBlock = (1u << 3), + eTypeIsBuiltIn = (1u << 4), + eTypeIsClass = (1u << 5), + eTypeIsCPlusPlus = (1u << 6), + eTypeIsEnumeration = (1u << 7), + eTypeIsFuncPrototype = (1u << 8), + eTypeIsMember = (1u << 9), + eTypeIsObjC = (1u << 10), + eTypeIsPointer = (1u << 11), + eTypeIsReference = (1u << 12), + eTypeIsStructUnion = (1u << 13), + eTypeIsTemplate = (1u << 14), + eTypeIsTypedef = (1u << 15), + eTypeIsVector = (1u << 16), + eTypeIsScalar = (1u << 17), + eTypeIsInteger = (1u << 18), + eTypeIsFloat = (1u << 19), + eTypeIsComplex = (1u << 20), + eTypeIsSigned = (1u << 21) + } TypeFlags; + + //---------------------------------------------------------------------- + // Whether a summary should cap how much data it returns to users or not + //---------------------------------------------------------------------- + typedef enum TypeSummaryCapping { + eTypeSummaryCapped = true, + eTypeSummaryUncapped = false + } TypeSummaryCapping; } // namespace lldb diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index b3d15224acb5..1ecb2f179bb2 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -62,9 +62,11 @@ class ClangPersistentVariables; class ClangUserExpression; class ClangUtilityFunction; class CommandInterpreter; +class CommandInterpreterRunOptions; class CommandObject; class CommandReturnObject; class Communication; +class CompactUnwindInfo; class CompileUnit; class Condition; class Connection; @@ -104,6 +106,7 @@ class FunctionInfo; class InlineFunctionInfo; class Instruction; class InstructionList; +class InstrumentationRuntime; class IOHandler; class IOObject; class IRExecutionUnit; @@ -116,6 +119,7 @@ class Log; class LogChannel; class Mangled; class Materializer; +class MemoryHistory; class Module; class ModuleList; class ModuleSpec; @@ -136,6 +140,7 @@ class OptionValueArch; class OptionValueArgs; class OptionValueArray; class OptionValueBoolean; +class OptionValueChar; class OptionValueDictionary; class OptionValueEnumeration; class OptionValueFileSpec; @@ -204,6 +209,7 @@ class StreamString; class StringList; struct StringSummaryFormat; class TypeSummaryImpl; +class TypeSummaryOptions; class Symbol; class SymbolContext; class SymbolContextList; @@ -225,6 +231,7 @@ class QueueImpl; class Target; class TargetList; class Thread; +class ThreadCollection; class ThreadList; class ThreadPlan; class ThreadPlanBase; @@ -244,10 +251,13 @@ class TypeImpl; class TypeList; class TypeListImpl; class TypeMemberImpl; +class TypeMemberFunctionImpl; class TypeEnumMemberImpl; class TypeEnumMemberListImpl; +class TypeFormatImpl; class TypeNameSpecifierImpl; class TypePair; +class TypeValidatorImpl; class UUID; class UnixSignals; class Unwind; @@ -256,7 +266,6 @@ class UnwindPlan; class UnwindTable; class VMRange; class Value; -class TypeFormatImpl; class ValueList; class ValueObject; class ValueObjectChild; @@ -308,6 +317,7 @@ namespace lldb { typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP; typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP; typedef std::shared_ptr<lldb_private::Instruction> InstructionSP; + typedef std::shared_ptr<lldb_private::InstrumentationRuntime> InstrumentationRuntimeSP; typedef std::shared_ptr<lldb_private::IOHandler> IOHandlerSP; typedef std::shared_ptr<lldb_private::IOObject> IOObjectSP; typedef std::shared_ptr<lldb_private::JITLoader> JITLoaderSP; @@ -316,6 +326,7 @@ namespace lldb { typedef std::shared_ptr<lldb_private::LineTable> LineTableSP; typedef std::shared_ptr<lldb_private::Listener> ListenerSP; typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP; + typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP; typedef std::shared_ptr<lldb_private::Module> ModuleSP; typedef std::weak_ptr<lldb_private::Module> ModuleWP; typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP; @@ -361,6 +372,7 @@ namespace lldb { typedef std::shared_ptr<lldb_private::SearchFilter> SearchFilterSP; typedef std::shared_ptr<lldb_private::Settings> SettingsSP; typedef std::shared_ptr<lldb_private::StackFrame> StackFrameSP; + typedef std::unique_ptr<lldb_private::StackFrame> StackFrameUP; typedef std::weak_ptr<lldb_private::StackFrame> StackFrameWP; typedef std::shared_ptr<lldb_private::StackFrameList> StackFrameListSP; typedef std::shared_ptr<lldb_private::StopInfo> StopInfoSP; @@ -379,17 +391,21 @@ namespace lldb { typedef std::weak_ptr<lldb_private::Target> TargetWP; 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::ThreadPlanTracer> ThreadPlanTracerSP; typedef std::shared_ptr<lldb_private::Type> TypeSP; typedef std::weak_ptr<lldb_private::Type> TypeWP; typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP; typedef std::shared_ptr<lldb_private::TypeImpl> TypeImplSP; + typedef std::shared_ptr<lldb_private::TypeMemberFunctionImpl> TypeMemberFunctionImplSP; typedef std::shared_ptr<lldb_private::TypeEnumMemberImpl> TypeEnumMemberImplSP; typedef std::shared_ptr<lldb_private::TypeFilterImpl> TypeFilterImplSP; typedef std::shared_ptr<lldb_private::TypeFormatImpl> TypeFormatImplSP; typedef std::shared_ptr<lldb_private::TypeNameSpecifierImpl> TypeNameSpecifierImplSP; typedef std::shared_ptr<lldb_private::TypeSummaryImpl> TypeSummaryImplSP; + typedef std::shared_ptr<lldb_private::TypeSummaryOptions> TypeSummaryOptionsSP; + typedef std::shared_ptr<lldb_private::TypeValidatorImpl> TypeValidatorImplSP; #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildren> ScriptedSyntheticChildrenSP; #endif diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h index ee1589fe24ed..c62863d744c7 100644 --- a/include/lldb/lldb-private-enumerations.h +++ b/include/lldb/lldb-private-enumerations.h @@ -22,7 +22,8 @@ typedef enum StepType eStepTypeTraceOver, ///< Single step one instruction, stepping over. eStepTypeInto, ///< Single step into a specified context. eStepTypeOver, ///< Single step over a specified context. - eStepTypeOut ///< Single step out a specified context. + eStepTypeOut, ///< Single step out a specified context. + eStepTypeScripted ///< A step type implemented by the script interpreter. } StepType; //---------------------------------------------------------------------- @@ -163,7 +164,9 @@ typedef enum FormatCategoryItem eFormatCategoryItemSynth = 0x0010, eFormatCategoryItemRegexSynth = 0x0020, eFormatCategoryItemValue = 0x0040, - eFormatCategoryItemRegexValue = 0x0080 + eFormatCategoryItemRegexValue = 0x0080, + eFormatCategoryItemValidator = 0x0100, + eFormatCategoryItemRegexValidator = 0x0200 } FormatCategoryItem; //------------------------------------------------------------------ @@ -238,6 +241,14 @@ typedef enum ExitType { eExitTypeStop, // The exit status represents the stop signal that caused the program to exit (i.e. WIFSTOPPED() was true) } ExitType; +//---------------------------------------------------------------------- +// Boolean result of running a Type Validator +//---------------------------------------------------------------------- +enum class TypeValidatorResult : bool { + Success = true, + Failure = false +}; + } // namespace lldb_private diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h index 3251d6a9fe6c..f35938ce17b7 100644 --- a/include/lldb/lldb-private-interfaces.h +++ b/include/lldb/lldb-private-interfaces.h @@ -30,15 +30,19 @@ namespace lldb_private typedef OperatingSystem* (*OperatingSystemCreateInstance) (Process *process, bool force); typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language); typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process); - typedef Platform* (*PlatformCreateInstance) (bool force, const ArchSpec *arch); + typedef lldb::PlatformSP (*PlatformCreateInstance) (bool force, const ArchSpec *arch); typedef lldb::ProcessSP (*ProcessCreateInstance) (Target &target, Listener &listener, const FileSpec *crash_file_path); typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file); typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id); typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id); + typedef void (*OptionValueChangedCallback) (void *baton, OptionValue *option_value); typedef bool (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); typedef lldb::ThreadPlanSP (*ThreadPlanStepFromHereCallback) (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); typedef UnwindAssembly* (*UnwindAssemblyCreateInstance) (const ArchSpec &arch); + typedef lldb::MemoryHistorySP (*MemoryHistoryCreateInstance) (const lldb::ProcessSP &process_sp); + typedef lldb::InstrumentationRuntimeType (*InstrumentationRuntimeGetType) (); + typedef lldb::InstrumentationRuntimeSP (*InstrumentationRuntimeCreateInstance) (const lldb::ProcessSP &process_sp); typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); diff --git a/include/lldb/lldb-private-types.h b/include/lldb/lldb-private-types.h index 12a9324008d8..cd4867238ef9 100644 --- a/include/lldb/lldb-private-types.h +++ b/include/lldb/lldb-private-types.h @@ -29,12 +29,20 @@ namespace lldb_private const char *name; // Name of this register, can't be NULL const char *alt_name; // Alternate name of this register, can be NULL uint32_t byte_size; // Size in bytes of the register - uint32_t byte_offset; // The byte offset in the register context data where this register's value is found + uint32_t byte_offset; // The byte offset in the register context data where this register's value is found. + // This is optional, and can be 0 if a particular RegisterContext does not need to + // address its registers by byte offset. lldb::Encoding encoding; // Encoding of the register bits lldb::Format format; // Default display format uint32_t kinds[lldb::kNumRegisterKinds]; // Holds all of the various register numbers for all register kinds - uint32_t *value_regs; // List of registers that must be terminated with LLDB_INVALID_REGNUM - uint32_t *invalidate_regs; // List of registers that must be invalidated when this register is modified, list must be terminated with LLDB_INVALID_REGNUM + uint32_t *value_regs; // List of registers (terminated with LLDB_INVALID_REGNUM). If this value is not + // null, all registers in this list will be read first, at which point the value + // for this register will be valid. For example, the value list for ah + // would be eax (x86) or rax (x64). + uint32_t *invalidate_regs; // List of registers (terminated with LLDB_INVALID_REGNUM). If this value is not + // null, all registers in this list will be invalidateed when the value of this + // register changes. For example, the invalidate list for eax would be rax + // ax, ah, and al. } RegisterInfo; //---------------------------------------------------------------------- @@ -45,7 +53,11 @@ namespace lldb_private const char *name; // Name of this register set const char *short_name; // A short name for this register set size_t num_registers; // The number of registers in REGISTERS array below - const uint32_t *registers; // An array of register numbers in this set + const uint32_t *registers; // An array of register indices in this set. The values in this array are + // *indices* (not register numbers) into a particular RegisterContext's + // register array. For example, if eax is defined at index 4 for a + // particular RegisterContext, eax would be included in this RegisterSet + // by adding the value 4. Not by adding the value lldb_eax_i386. } RegisterSet; typedef struct diff --git a/include/lldb/lldb-private.h b/include/lldb/lldb-private.h index 05b2c4fd6381..bbd974303f1f 100644 --- a/include/lldb/lldb-private.h +++ b/include/lldb/lldb-private.h @@ -16,6 +16,10 @@ #include "lldb/Host/windows/win32.h" #endif +#ifdef __ANDROID_NDK__ +#include "lldb/Host/android/Android.h" +#endif + #include "lldb/lldb-public.h" #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-private-interfaces.h" diff --git a/include/lldb/lldb-types.h b/include/lldb/lldb-types.h index fee920f5b198..fe902073698d 100644 --- a/include/lldb/lldb-types.h +++ b/include/lldb/lldb-types.h @@ -50,9 +50,12 @@ namespace lldb typedef void* condition_t; typedef void* rwlock_t; typedef void* process_t; // Process type is HANDLE - typedef uintptr_t thread_t; // Host thread type + typedef void* thread_t; // Host thread type + typedef void* file_t; // Host file type + typedef void* pipe_t; // Host pipe type + typedef unsigned int __w64 socket_t; // Host socket type typedef uint32_t thread_key_t; - typedef void * thread_arg_t; // Host thread argument type + typedef void* thread_arg_t; // Host thread argument type typedef unsigned thread_result_t; // Host thread result type typedef thread_result_t (*thread_func_t)(void *); // Host thread function type } @@ -71,6 +74,9 @@ namespace lldb typedef pthread_rwlock_t rwlock_t; typedef uint64_t process_t; // Process type is just a pid. typedef pthread_t thread_t; // Host thread type + typedef int file_t; // Host file type + typedef int pipe_t; // Host pipe type + typedef int socket_t; // Host socket type typedef pthread_key_t thread_key_t; typedef void * thread_arg_t; // Host thread argument type typedef void * thread_result_t; // Host thread result type @@ -89,6 +95,7 @@ namespace lldb typedef bool (*ExpressionCancelCallback) (ExpressionEvaluationPhase phase, void *baton); } +#define LLDB_INVALID_PROCESS ((lldb::process_t)-1) #define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL) #define IS_VALID_LLDB_HOST_THREAD(t) ((t) != LLDB_INVALID_HOST_THREAD) |