diff options
241 files changed, 4793 insertions, 2152 deletions
diff --git a/include/lldb/API/SBFrame.h b/include/lldb/API/SBFrame.h index 2ca9e062490d..3177b0cc5a69 100644 --- a/include/lldb/API/SBFrame.h +++ b/include/lldb/API/SBFrame.h @@ -90,6 +90,10 @@ public: /// See also IsInlined(). const char * GetFunctionName(); + + // Get an appropriate function name for this frame that is suitable for display to a user + const char * + GetDisplayFunctionName (); const char * GetFunctionName() const; diff --git a/include/lldb/API/SBFunction.h b/include/lldb/API/SBFunction.h index 7d578393eb2c..86cfeb49bb58 100644 --- a/include/lldb/API/SBFunction.h +++ b/include/lldb/API/SBFunction.h @@ -36,6 +36,9 @@ public: GetName() const; const char * + GetDisplayName() const; + + const char * GetMangledName () const; lldb::SBInstructionList diff --git a/include/lldb/API/SBPlatform.h b/include/lldb/API/SBPlatform.h index db4a754103ca..80ad1c06e868 100644 --- a/include/lldb/API/SBPlatform.h +++ b/include/lldb/API/SBPlatform.h @@ -189,6 +189,9 @@ namespace lldb { SBError SetFilePermissions (const char *path, uint32_t file_permissions); + SBUnixSignals + GetUnixSignals() const; + protected: friend class SBDebugger; diff --git a/include/lldb/API/SBSymbol.h b/include/lldb/API/SBSymbol.h index 3d259a2c20c6..5acebe975261 100644 --- a/include/lldb/API/SBSymbol.h +++ b/include/lldb/API/SBSymbol.h @@ -38,6 +38,9 @@ public: GetName() const; const char * + GetDisplayName() const; + + const char * GetMangledName () const; lldb::SBInstructionList diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index dcca4e7b3a19..2ca0b124ce0a 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -769,6 +769,9 @@ public: GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level); lldb::SBValue + EvaluateExpression (const char *expr); + + lldb::SBValue EvaluateExpression (const char *expr, const SBExpressionOptions &options); lldb::addr_t diff --git a/include/lldb/API/SBUnixSignals.h b/include/lldb/API/SBUnixSignals.h index 9eae30739bb8..ae48b63e1a2f 100644 --- a/include/lldb/API/SBUnixSignals.h +++ b/include/lldb/API/SBUnixSignals.h @@ -65,17 +65,20 @@ public: protected: friend class SBProcess; + friend class SBPlatform; - SBUnixSignals (lldb::ProcessSP &process_sp); + SBUnixSignals(lldb::ProcessSP &process_sp); - lldb::ProcessSP + SBUnixSignals(lldb::PlatformSP &platform_sp); + + lldb::UnixSignalsSP GetSP() const; void - SetSP (const lldb::ProcessSP &process_sp); + SetSP(const lldb::UnixSignalsSP &signals_sp); private: - lldb::ProcessWP m_opaque_wp; + lldb::UnixSignalsWP m_opaque_wp; }; diff --git a/include/lldb/Core/Connection.h b/include/lldb/Core/Connection.h index c354519a222e..121395c0b23c 100644 --- a/include/lldb/Core/Connection.h +++ b/include/lldb/Core/Connection.h @@ -187,6 +187,20 @@ public: virtual bool InterruptRead() = 0; + //------------------------------------------------------------------ + /// Returns the underlying IOObject used by the Connection. + /// + /// The IOObject can be used to wait for data to become available + /// on the connection. If the Connection does not use IOObjects (and + /// hence does not support waiting) this function should return a + /// null pointer. + /// + /// @return + /// The underlying IOObject used for reading. + //------------------------------------------------------------------ + virtual lldb::IOObjectSP + GetReadObject() { return lldb::IOObjectSP(); } + private: //------------------------------------------------------------------ // For Connection only diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h index a2a2b5591d0f..6d8d8c4a0da7 100644 --- a/include/lldb/Core/Mangled.h +++ b/include/lldb/Core/Mangled.h @@ -182,8 +182,17 @@ public: /// A const reference to the demangled name string object. //---------------------------------------------------------------------- const ConstString& - GetDemangledName () const; + GetDemangledName (lldb::LanguageType language) const; + //---------------------------------------------------------------------- + /// Display demangled name get accessor. + /// + /// @return + /// A const reference to the display demangled name string object. + //---------------------------------------------------------------------- + ConstString + GetDisplayDemangledName (lldb::LanguageType language) const; + void SetDemangledName (const ConstString &name) { @@ -231,8 +240,8 @@ public: /// object has a valid name of that kind, else a const reference to the /// other name is returned. //---------------------------------------------------------------------- - const ConstString& - GetName (NamePreference preference = ePreferDemangled) const; + ConstString + GetName (lldb::LanguageType language, NamePreference preference = ePreferDemangled) const; //---------------------------------------------------------------------- /// Check if "name" matches either the mangled or demangled name. @@ -244,15 +253,15 @@ public: /// \b True if \a name matches either name, \b false otherwise. //---------------------------------------------------------------------- bool - NameMatches (const ConstString &name) const + NameMatches (const ConstString &name, lldb::LanguageType language) const { if (m_mangled == name) return true; - return GetDemangledName () == name; + return GetDemangledName (language) == name; } bool - NameMatches (const RegularExpression& regex) const; + NameMatches (const RegularExpression& regex, lldb::LanguageType language) const; //---------------------------------------------------------------------- /// Get the memory cost of this object. diff --git a/include/lldb/Core/StructuredData.h b/include/lldb/Core/StructuredData.h index 8acfa310deac..7da29e48299d 100644 --- a/include/lldb/Core/StructuredData.h +++ b/include/lldb/Core/StructuredData.h @@ -238,14 +238,15 @@ public: { } - void + bool ForEach (std::function <bool(Object* object)> const &foreach_callback) const { for (const auto &object_sp : m_items) { if (foreach_callback(object_sp.get()) == false) - break; + return false; } + return true; } diff --git a/include/lldb/DataFormatters/CXXFormatterFunctions.h b/include/lldb/DataFormatters/CXXFormatterFunctions.h index 9b1a02ca0a5c..a175e1a4d164 100644 --- a/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -18,6 +18,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/DataFormatters/TypeSynthetic.h" +#include "lldb/DataFormatters/VectorType.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" diff --git a/include/lldb/DataFormatters/VectorType.h b/include/lldb/DataFormatters/VectorType.h index e69de29bb2d1..56d0c6d90ecd 100644 --- a/include/lldb/DataFormatters/VectorType.h +++ b/include/lldb/DataFormatters/VectorType.h @@ -0,0 +1,28 @@ +//===-- VectorType.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_VectorType_h_ +#define liblldb_VectorType_h_ + +#include "lldb/lldb-forward.h" + +namespace lldb_private { + namespace formatters + { + bool + VectorTypeSummaryProvider (ValueObject&, + Stream&, + const TypeSummaryOptions&); + + SyntheticChildrenFrontEnd* + VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + } // namespace formatters +} // namespace lldb_private + +#endif // liblldb_VectorType_h_ diff --git a/include/lldb/Expression/ClangUserExpression.h b/include/lldb/Expression/ClangUserExpression.h index dbea48148e14..a549f5e8a547 100644 --- a/include/lldb/Expression/ClangUserExpression.h +++ b/include/lldb/Expression/ClangUserExpression.h @@ -30,7 +30,7 @@ #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/ExecutionContext.h" -namespace lldb_private +namespace lldb_private { //---------------------------------------------------------------------- @@ -45,7 +45,7 @@ namespace lldb_private class ClangUserExpression : public ClangExpression { public: - + enum { kDefaultTimeout = 500000u }; //------------------------------------------------------------------ /// Constructor @@ -59,7 +59,7 @@ public: /// /// @param[in] language /// If not eLanguageTypeUnknown, a language to use when parsing - /// the expression. Currently restricted to those languages + /// the expression. Currently restricted to those languages /// supported by Clang. /// /// @param[in] desired_type @@ -70,13 +70,13 @@ public: const char *expr_prefix, lldb::LanguageType language, ResultType desired_type); - + //------------------------------------------------------------------ /// Destructor //------------------------------------------------------------------ - virtual + virtual ~ClangUserExpression (); - + //------------------------------------------------------------------ /// Parse the expression /// @@ -92,28 +92,28 @@ public: /// Determines whether interpretation is possible or mandatory. /// /// @param[in] keep_result_in_memory - /// True if the resulting persistent variable should reside in + /// True if the resulting persistent variable should reside in /// target memory, if applicable. /// /// @return /// True on success (no errors); false otherwise. //------------------------------------------------------------------ bool - Parse (Stream &error_stream, + Parse (Stream &error_stream, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info); - + bool CanInterpret () { return m_can_interpret; } - + bool MatchesContext (ExecutionContext &exe_ctx); - + //------------------------------------------------------------------ /// Execute the parsed expression /// @@ -131,9 +131,9 @@ public: /// This is a shared pointer to this ClangUserExpression. This is /// needed because Execute can push a thread plan that will hold onto /// the ClangUserExpression for an unbounded period of time. So you - /// need to give the thread plan a reference to this object that can + /// need to give the thread plan a reference to this object that can /// keep it alive. - /// + /// /// @param[in] result /// A pointer to direct at the persistent variable in which the /// expression's result is stored. @@ -147,7 +147,7 @@ public: const EvaluateExpressionOptions& options, lldb::ClangUserExpressionSP &shared_ptr_to_me, lldb::ClangExpressionVariableSP &result); - + //------------------------------------------------------------------ /// Apply the side effects of the function to program state. /// @@ -157,7 +157,7 @@ public: /// @param[in] exe_ctx /// The execution context to use when looking up entities that /// are needed for parsing (locations of variables, etc.) - /// + /// /// @param[in] result /// A pointer to direct at the persistent variable in which the /// expression's result is stored. @@ -177,7 +177,7 @@ public: lldb::ClangExpressionVariableSP &result, lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS, lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS); - + //------------------------------------------------------------------ /// Return the string that the parser should parse. Must be a full /// translation unit. @@ -187,7 +187,7 @@ public: { return m_transformed_text.c_str(); } - + //------------------------------------------------------------------ /// Return the string that the user typed. //------------------------------------------------------------------ @@ -196,7 +196,7 @@ public: { return m_expr_text.c_str(); } - + //------------------------------------------------------------------ /// Return the function name that should be used for executing the /// expression. Text() should contain the definition of this @@ -207,7 +207,7 @@ public: { return "$__lldb_expr"; } - + //------------------------------------------------------------------ /// Return the language that should be used when parsing. To use /// the default, return eLanguageTypeUnknown. @@ -217,7 +217,7 @@ public: { return m_language; } - + //------------------------------------------------------------------ /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. @@ -227,7 +227,7 @@ public: { return m_expr_decl_map.get(); } - + //------------------------------------------------------------------ /// Return the object that the parser should allow to access ASTs. /// May be NULL if the ASTs do not need to be transformed. @@ -238,9 +238,9 @@ public: //------------------------------------------------------------------ clang::ASTConsumer * ASTTransformer (clang::ASTConsumer *passthrough); - + //------------------------------------------------------------------ - /// Return the desired result type of the function, or + /// Return the desired result type of the function, or /// eResultTypeAny if indifferent. //------------------------------------------------------------------ virtual ResultType @@ -248,7 +248,7 @@ public: { return m_desired_type; } - + //------------------------------------------------------------------ /// Return true if validation code should be inserted into the /// expression. @@ -258,7 +258,7 @@ public: { return true; } - + //------------------------------------------------------------------ /// Return true if external variables in the expression should be /// resolved. @@ -302,15 +302,15 @@ public: const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Error &error); - + static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression. private: //------------------------------------------------------------------ /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment. //------------------------------------------------------------------ - + void - ScanContext (ExecutionContext &exe_ctx, + ScanContext (ExecutionContext &exe_ctx, lldb_private::Error &err); bool @@ -319,21 +319,21 @@ private: lldb::addr_t &struct_address, lldb::addr_t &object_ptr, lldb::addr_t &cmd_ptr); - + void InstallContext (ExecutionContext &exe_ctx); - + bool LockAndCheckContext (ExecutionContext &exe_ctx, lldb::TargetSP &target_sp, lldb::ProcessSP &process_sp, lldb::StackFrameSP &frame_sp); - + lldb::ProcessWP m_process_wp; ///< The process used as the context for the expression. Address m_address; ///< The address the process is stopped in. lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame. lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame. - + std::string m_expr_text; ///< The text of the expression, as typed by the user std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults) @@ -341,7 +341,7 @@ private: bool m_allow_objc; ///< True if the language allows Objective-C. std::string m_transformed_text; ///< The text of the expression, as send to the parser ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression. - + std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing the expression. std::shared_ptr<IRExecutionUnit> m_execution_unit_sp; ///< The execution unit the expression is stored in. std::unique_ptr<Materializer> m_materializer_ap; ///< The materializer to use when running the expression. @@ -354,12 +354,12 @@ private: bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression doesn't really use them and they can be NULL. bool m_const_object; ///< True if "this" is const. Target *m_target; ///< The target for storing persistent data like types and variables. - + bool m_can_interpret; ///< True if the expression could be evaluated statically; false otherwise. lldb::addr_t m_materialized_address; ///< The address at which the arguments to the expression have been materialized. Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer. }; - + } // namespace lldb_private #endif // liblldb_ClangUserExpression_h_ diff --git a/include/lldb/Expression/IRInterpreter.h b/include/lldb/Expression/IRInterpreter.h index 5defa8dd2026..c314bf1099ea 100644 --- a/include/lldb/Expression/IRInterpreter.h +++ b/include/lldb/Expression/IRInterpreter.h @@ -44,7 +44,8 @@ public: static bool CanInterpret (llvm::Module &module, llvm::Function &function, - lldb_private::Error &error); + lldb_private::Error &error, + const bool support_function_calls); static bool Interpret (llvm::Module &module, @@ -53,7 +54,8 @@ public: lldb_private::IRMemoryMap &memory_map, lldb_private::Error &error, lldb::addr_t stack_frame_bottom, - lldb::addr_t stack_frame_top); + lldb::addr_t stack_frame_top, + lldb_private::ExecutionContext &exe_ctx); private: static bool diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h index 0da8384c8e63..80add46ef0da 100644 --- a/include/lldb/Expression/IRMemoryMap.h +++ b/include/lldb/Expression/IRMemoryMap.h @@ -60,7 +60,7 @@ public: void ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error); void ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error); void ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error); - + bool GetAllocSize(lldb::addr_t address, size_t &size); void GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error); lldb::ByteOrder GetByteOrder(); diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h index caf33634057d..235367a7cc5c 100644 --- a/include/lldb/Host/Host.h +++ b/include/lldb/Host/Host.h @@ -244,8 +244,8 @@ public: #endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__) #endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) - static const lldb_private::UnixSignalsSP& - GetUnixSignals (); + static const lldb::UnixSignalsSP & + GetUnixSignals(); static Error LaunchProcess (ProcessLaunchInfo &launch_info); diff --git a/include/lldb/Host/MainLoop.h b/include/lldb/Host/MainLoop.h new file mode 100644 index 000000000000..276538a336b6 --- /dev/null +++ b/include/lldb/Host/MainLoop.h @@ -0,0 +1,27 @@ +//===-- MainLoop.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_MainLoop_h_ +#define lldb_Host_MainLoop_h_ + +#ifdef _WIN32 +#include "lldb/Host/MainLoopBase.h" +namespace lldb_private +{ +typedef MainLoopBase MainLoop; +} +#else +#include "lldb/Host/posix/MainLoopPosix.h" +namespace lldb_private +{ +typedef MainLoopPosix MainLoop; +} +#endif + +#endif // lldb_Host_MainLoop_h_ diff --git a/include/lldb/Host/MainLoopBase.h b/include/lldb/Host/MainLoopBase.h new file mode 100644 index 000000000000..bff2ce78110d --- /dev/null +++ b/include/lldb/Host/MainLoopBase.h @@ -0,0 +1,94 @@ +//===-- MainLoopBase.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_MainLoopBase_h_ +#define lldb_Host_posix_MainLoopBase_h_ + +#include <functional> + +#include "llvm/Support/ErrorHandling.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/IOObject.h" + +namespace lldb_private { + +// The purpose of this class is to enable multiplexed processing of data from different sources +// without resorting to multi-threading. Clients can register IOObjects, which will be monitored +// for readability, and when they become ready, the specified callback will be invoked. +// Monitoring for writability is not supported, but can be easily added if needed. +// +// The RegisterReadObject function return a handle, which controls the duration of the monitoring. When +// this handle is destroyed, the callback is deregistered. +// +// This class simply defines the interface common for all platforms, actual implementations are +// platform-specific. +class MainLoopBase +{ +private: + class ReadHandle; + +public: + MainLoopBase() { } + virtual ~MainLoopBase() { } + + typedef std::unique_ptr<ReadHandle> ReadHandleUP; + + typedef std::function<void(MainLoopBase &)> Callback; + + virtual ReadHandleUP + RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Error &error) + { llvm_unreachable("Not implemented"); } + + // Waits for registered events and invoke the proper callbacks. Returns when all callbacks + // deregister themselves or when someone requests termination. + virtual Error + Run() + { llvm_unreachable("Not implemented"); } + + // Requests the exit of the Run() function. + virtual void + RequestTermination() + { llvm_unreachable("Not implemented"); } + +protected: + ReadHandleUP + CreateReadHandle(const lldb::IOObjectSP &object_sp) + { return ReadHandleUP(new ReadHandle(*this, object_sp)); } + + virtual void + UnregisterReadObject(const lldb::IOObjectSP &object_sp) + { llvm_unreachable("Not implemented"); } + +private: + class ReadHandle + { + public: + ~ReadHandle() { m_mainloop.UnregisterReadObject(m_object_sp); } + + private: + ReadHandle(MainLoopBase &mainloop, const lldb::IOObjectSP &object_sp) + : m_mainloop(mainloop), m_object_sp(object_sp) + { } + + MainLoopBase &m_mainloop; + lldb::IOObjectSP m_object_sp; + + friend class MainLoopBase; + DISALLOW_COPY_AND_ASSIGN(ReadHandle); + }; + +private: + DISALLOW_COPY_AND_ASSIGN(MainLoopBase); +}; + +} // namespace lldb_private + + +#endif // lldb_Host_posix_MainLoopBase_h_ diff --git a/include/lldb/Host/StringConvert.h b/include/lldb/Host/StringConvert.h index 3cc260cf2be1..af5c2a08db87 100644 --- a/include/lldb/Host/StringConvert.h +++ b/include/lldb/Host/StringConvert.h @@ -39,6 +39,8 @@ ToSInt64 (const char *s, int64_t fail_value = 0, int base = 0, bool *success_ptr uint64_t ToUInt64 (const char *s, uint64_t fail_value = 0, int base = 0, bool *success_ptr = nullptr); +double +ToDouble (const char *s, double fail_value = 0.0, bool *success_ptr = nullptr); } // namespace StringConvert } // namespace lldb_private diff --git a/include/lldb/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h index f6a685aae147..4f0f3a962d32 100644 --- a/include/lldb/Host/common/NativeProcessProtocol.h +++ b/include/lldb/Host/common/NativeProcessProtocol.h @@ -35,8 +35,6 @@ namespace lldb_private friend class SoftwareBreakpoint; public: - static NativeProcessProtocol * - CreateInstance (lldb::pid_t pid); // lldb_private::Host calls should be used to launch a process for debugging, and // then the process should be attached to. When attaching to a process @@ -44,7 +42,6 @@ namespace lldb_private // and then this function should be called. NativeProcessProtocol (lldb::pid_t pid); - public: virtual ~NativeProcessProtocol () { } @@ -297,6 +294,62 @@ namespace lldb_private virtual Error GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) = 0; + //------------------------------------------------------------------ + /// Launch a process for debugging. This method will create an concrete + /// instance of NativeProcessProtocol, based on the host platform. + /// (e.g. NativeProcessLinux on linux, etc.) + /// + /// @param[in] launch_info + /// Information required to launch the process. + /// + /// @param[in] native_delegate + /// The delegate that will receive messages regarding the + /// inferior. Must outlive the NativeProcessProtocol + /// instance. + /// + /// @param[out] process_sp + /// On successful return from the method, this parameter + /// contains the shared pointer to the + /// NativeProcessProtocol that can be used to manipulate + /// the native process. + /// + /// @return + /// An error object indicating if the operation succeeded, + /// and if not, what error occurred. + //------------------------------------------------------------------ + static Error + Launch (ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp); + + //------------------------------------------------------------------ + /// Attach to an existing process. This method will create an concrete + /// instance of NativeProcessProtocol, based on the host platform. + /// (e.g. NativeProcessLinux on linux, etc.) + /// + /// @param[in] pid + /// pid of the process locatable + /// + /// @param[in] native_delegate + /// The delegate that will receive messages regarding the + /// inferior. Must outlive the NativeProcessProtocol + /// instance. + /// + /// @param[out] process_sp + /// On successful return from the method, this parameter + /// contains the shared pointer to the + /// NativeProcessProtocol that can be used to manipulate + /// the native process. + /// + /// @return + /// An error object indicating if the operation succeeded, + /// and if not, what error occurred. + //------------------------------------------------------------------ + static Error + Attach (lldb::pid_t pid, + NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp); + protected: lldb::pid_t m_pid; diff --git a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index bcbb6014b116..2e0fd705b2a8 100644 --- a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -59,12 +59,7 @@ class ConnectionFileDescriptor : public Connection bool InterruptRead() override; lldb::IOObjectSP - GetReadObject() - { - return m_read_sp; - } - const lldb::IOObjectSP - GetReadObject() const + GetReadObject() override { return m_read_sp; } diff --git a/include/lldb/Host/posix/MainLoopPosix.h b/include/lldb/Host/posix/MainLoopPosix.h new file mode 100644 index 000000000000..9a665ded295e --- /dev/null +++ b/include/lldb/Host/posix/MainLoopPosix.h @@ -0,0 +1,100 @@ +//===-- MainLoopPosix.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_MainLoopPosix_h_ +#define lldb_Host_posix_MainLoopPosix_h_ + +#include "lldb/Host/MainLoopBase.h" + +#include "llvm/ADT/DenseMap.h" + +namespace lldb_private { + +// Posix implementation of the MainLoopBase class. It can monitor file descriptors for +// readability using pselect. In addition to the common base, this class provides the ability to +// invoke a given handler when a signal is received. +// +// Since this class is primarily intended to be used for single-threaded processing, it does not +// attempt to perform any internal synchronisation and any concurrent accesses must be protected +// externally. However, it is perfectly legitimate to have more than one instance of this class +// running on separate threads, or even a single thread (with some limitations on signal +// monitoring). +// TODO: Add locking if this class is to be used in a multi-threaded context. +class MainLoopPosix: public MainLoopBase +{ +private: + class SignalHandle; + +public: + typedef std::unique_ptr<SignalHandle> SignalHandleUP; + + ~MainLoopPosix() override; + + ReadHandleUP + RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Error &error) override; + + // Listening for signals from multiple MainLoopPosix instances is perfectly safe as long as they + // don't try to listen for the same signal. The callback function is invoked when the control + // returns to the Run() function, not when the hander is executed. This means that you can + // treat the callback as a normal function and perform things which would not be safe in a + // signal handler. However, since the callback is not invoked synchronously, you cannot use + // this mechanism to handle SIGSEGV and the like. + SignalHandleUP + RegisterSignal(int signo, const Callback &callback, Error &error); + + Error + Run() override; + + // This should only be performed from a callback. Do not attempt to terminate the processing + // from another thread. + // TODO: Add synchronization if we want to be terminated from another thread. + void + RequestTermination() override + { m_terminate_request = true; } + +protected: + void + UnregisterReadObject(const lldb::IOObjectSP &object_sp) override; + + void + UnregisterSignal(int signo); + +private: + class SignalHandle + { + public: + ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); } + + private: + SignalHandle(MainLoopPosix &mainloop, int signo) : m_mainloop(mainloop), m_signo(signo) { } + + MainLoopPosix &m_mainloop; + int m_signo; + + friend class MainLoopPosix; + DISALLOW_COPY_AND_ASSIGN(SignalHandle); + }; + + struct SignalInfo + { + Callback callback; + struct sigaction old_action; + bool was_blocked : 1; + }; + + llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds; + llvm::DenseMap<int, SignalInfo> m_signals; + bool m_terminate_request : 1; +}; + +} // namespace lldb_private + + +#endif // lldb_Host_posix_MainLoopPosix_h_ + diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h index c0901d5e3032..023de29c7b6c 100644 --- a/include/lldb/Interpreter/CommandObject.h +++ b/include/lldb/Interpreter/CommandObject.h @@ -161,6 +161,9 @@ public: } void + FormatLongHelpText (Stream &output_strm, const char *long_help); + + void GenerateHelpText (CommandReturnObject &result); virtual void diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index 5954cf520d70..30c8f168e5f1 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -123,7 +123,7 @@ public: /// @return /// A const reference to the method name object. //------------------------------------------------------------------ - const ConstString& + ConstString GetName () const; //------------------------------------------------------------------ @@ -240,11 +240,14 @@ public: Dump(Stream *s, bool show_fullpaths) const; void - DumpStopContext (Stream *s) const; + DumpStopContext (Stream *s, lldb::LanguageType language) const; - const ConstString & - GetName () const; + ConstString + GetName (lldb::LanguageType language) const; + ConstString + GetDisplayName (lldb::LanguageType language) const; + //------------------------------------------------------------------ /// Get accessor for the call site declaration information. /// @@ -437,6 +440,8 @@ public: return m_range; } + lldb::LanguageType + GetLanguage() const; //------------------------------------------------------------------ /// Find the file and line number of the source location of the start /// of the function. This will use the declaration if present and fall @@ -524,11 +529,14 @@ public: return m_frame_base; } - const ConstString & - GetName() const - { - return m_mangled.GetName(); - } + ConstString + GetName() const; + + ConstString + GetNameNoArguments () const; + + ConstString + GetDisplayName () const; const Mangled & GetMangled() const diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index ad11563634ea..f9438b006c4e 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -152,18 +152,28 @@ public: lldb::addr_t ResolveCallableAddress(Target &target) const; - const ConstString & - GetName () const - { - return m_mangled.GetName(); - } + ConstString + GetName () const; + + ConstString + GetNameNoArguments () const; + ConstString + GetDisplayName () const; + uint32_t GetID() const { return m_uid; } + lldb::LanguageType + GetLanguage() const + { + // TODO: See if there is a way to determine the language for a symbol somehow, for now just return our best guess + return m_mangled.GuessLanguage(); + } + void SetID(uint32_t uid) { diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h index a345bcb8c23a..8d413cac3d7d 100644 --- a/include/lldb/Symbol/Variable.h +++ b/include/lldb/Symbol/Variable.h @@ -55,7 +55,7 @@ public: return m_declaration; } - const ConstString& + ConstString GetName() const; SymbolContextScope * @@ -70,12 +70,7 @@ public: // function that can be called by commands and expression parsers to make // sure we match anything we come across. bool - NameMatches (const ConstString &name) const - { - if (m_name == name) - return true; - return m_mangled.NameMatches (name); - } + NameMatches (const ConstString &name) const; bool NameMatches (const RegularExpression& regex) const; @@ -83,6 +78,9 @@ public: Type * GetType(); + lldb::LanguageType + GetLanguage () const; + lldb::ValueType GetScope() const { diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h index cfd214d28874..89d4f6bdba6c 100644 --- a/include/lldb/Target/ABI.h +++ b/include/lldb/Target/ABI.h @@ -39,10 +39,9 @@ public: }; eType type; /* value of eType */ size_t size; /* size in bytes of this argument */ - union { - lldb::addr_t value; /* literal value */ - uint8_t *data; /* host data pointer */ - }; + + lldb::addr_t value; /* literal value */ + std::unique_ptr<uint8_t[]> data_ap; /* host data pointer */ }; virtual @@ -58,7 +57,7 @@ public: lldb::addr_t returnAddress, llvm::ArrayRef<lldb::addr_t> args) const = 0; - // Prepare trivial call used from ThreadPlanFunctionCallGDB + // Prepare trivial call used from ThreadPlanFunctionCallUsingABI // AD: // . Because i don't want to change other ABI's this is not declared pure virtual. // The dummy implementation will simply fail. Only HexagonABI will currently diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h index 8f89e9b3cf5f..feaac57b128a 100644 --- a/include/lldb/Target/Platform.h +++ b/include/lldb/Target/Platform.h @@ -863,6 +863,12 @@ class ModuleCache; return 1; } + virtual const lldb::UnixSignalsSP & + GetRemoteUnixSignals(); + + const lldb::UnixSignalsSP & + GetUnixSignals(); + //------------------------------------------------------------------ /// Locate a queue name given a thread's qaddr /// @@ -939,65 +945,6 @@ class ModuleCache; virtual const std::vector<ConstString> & GetTrapHandlerSymbolNames (); - //------------------------------------------------------------------ - /// Launch a process for debugging. - /// - /// This differs from Launch in that it returns a NativeProcessProtocol. - /// Currently used by lldb-gdbserver. - /// - /// @param[in] launch_info - /// Information required to launch the process. - /// - /// @param[in] native_delegate - /// The delegate that will receive messages regarding the - /// inferior. Must outlive the NativeProcessProtocol - /// instance. - /// - /// @param[out] process_sp - /// On successful return from the method, this parameter - /// contains the shared pointer to the - /// NativeProcessProtocol that can be used to manipulate - /// the native process. - /// - /// @return - /// An error object indicating if the operation succeeded, - /// and if not, what error occurred. - //------------------------------------------------------------------ - virtual Error - LaunchNativeProcess ( - ProcessLaunchInfo &launch_info, - lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, - NativeProcessProtocolSP &process_sp); - - //------------------------------------------------------------------ - /// Attach to an existing process on the given platform. - /// - /// This method differs from Attach() in that it returns a - /// NativeProcessProtocol. Currently this is used by lldb-gdbserver. - /// - /// @param[in] pid - /// pid of the process locatable by the platform. - /// - /// @param[in] native_delegate - /// The delegate that will receive messages regarding the - /// inferior. Must outlive the NativeProcessProtocol - /// instance. - /// - /// @param[out] process_sp - /// On successful return from the method, this parameter - /// contains the shared pointer to the - /// NativeProcessProtocol that can be used to manipulate - /// the native process. - /// - /// @return - /// An error object indicating if the operation succeeded, - /// and if not, what error occurred. - //------------------------------------------------------------------ - virtual Error - AttachNativeProcess (lldb::pid_t pid, - lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, - NativeProcessProtocolSP &process_sp); - protected: bool m_is_host; // Set to true when we are able to actually set the OS version while diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index db0f0cfa028b..f75b3cd5683d 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -30,6 +30,7 @@ #include "lldb/Core/Event.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Breakpoint/BreakpointSiteList.h" #include "lldb/Host/HostThread.h" @@ -949,7 +950,7 @@ public: /// Construct with a shared pointer to a target, the Process listener, /// and the appropriate UnixSignalsSP for the process. //------------------------------------------------------------------ - Process(Target &target, Listener &listener, const UnixSignalsSP &unix_signals_sp); + Process(Target &target, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp); //------------------------------------------------------------------ /// Destructor. @@ -1401,10 +1402,10 @@ public: Signal (int signal); void - SetUnixSignals (const UnixSignalsSP &signals_sp); + SetUnixSignals(const lldb::UnixSignalsSP &signals_sp); - UnixSignals & - GetUnixSignals (); + const lldb::UnixSignalsSP & + GetUnixSignals(); //================================================================== // Plug-in Process Control Overrides @@ -1887,6 +1888,37 @@ public: virtual void ModulesDidLoad (ModuleList &module_list); + + //------------------------------------------------------------------ + /// Retrieve the list of shared libraries that are loaded for this process + /// + /// For certain platforms, the time it takes for the DynamicLoader plugin to + /// read all of the shared libraries out of memory over a slow communication + /// channel may be too long. In that instance, the gdb-remote stub may be + /// able to retrieve the necessary information about the solibs out of memory + /// and return a concise summary sufficient for the DynamicLoader plugin. + /// + /// @param [in] image_list_address + /// The address where the table of shared libraries is stored in memory, + /// if that is appropriate for this platform. Else this may be + /// passed as LLDB_INVALID_ADDRESS. + /// + /// @param [in] image_count + /// The number of shared libraries that are present in this process, if + /// that is appropriate for this platofrm Else this may be passed as + /// LLDB_INVALID_ADDRESS. + /// + /// @return + /// A StructureDataSP object which, if non-empty, will contain the + /// information the DynamicLoader needs to get the initial scan of + /// solibs resolved. + //------------------------------------------------------------------ + virtual lldb_private::StructuredData::ObjectSP + GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) + { + return StructuredData::ObjectSP(); + } + protected: void @@ -2439,8 +2471,41 @@ public: /// True if execution of JIT code is possible; false otherwise. //------------------------------------------------------------------ void SetCanJIT (bool can_jit); + + //------------------------------------------------------------------ + /// Determines whether executing function calls using the interpreter + /// is possible for this process. + /// + /// @return + /// True if possible; false otherwise. + //------------------------------------------------------------------ + bool CanInterpretFunctionCalls () + { + return m_can_interpret_function_calls; + } //------------------------------------------------------------------ + /// Sets whether executing function calls using the interpreter + /// is possible for this process. + /// + /// @param[in] can_interpret_function_calls + /// True if possible; false otherwise. + //------------------------------------------------------------------ + void SetCanInterpretFunctionCalls (bool can_interpret_function_calls) + { + m_can_interpret_function_calls = can_interpret_function_calls; + } + + //------------------------------------------------------------------ + /// Sets whether executing code in this process is possible. + /// This could be either through JIT or interpreting. + /// + /// @param[in] can_run_code + /// True if execution of code is possible; false otherwise. + //------------------------------------------------------------------ + void SetCanRunCode (bool can_run_code); + + //------------------------------------------------------------------ /// Actually deallocate memory in the process. /// /// This function will deallocate memory in the process's address @@ -3205,7 +3270,7 @@ protected: lldb::DynamicCheckerFunctionsUP m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use. lldb::OperatingSystemUP m_os_ap; lldb::SystemRuntimeUP m_system_runtime_ap; - UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process. + lldb::UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process. lldb::ABISP m_abi_sp; lldb::IOHandlerSP m_process_input_reader; Communication m_stdio_communication; @@ -3236,6 +3301,7 @@ protected: lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent. std::map<lldb::addr_t,lldb::addr_t> m_resolved_indirect_addresses; bool m_destroy_in_process; + bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, don't support the ability to modify the stack. enum { eCanJITDontKnow= 0, diff --git a/include/lldb/Target/ThreadPlanCallFunction.h b/include/lldb/Target/ThreadPlanCallFunction.h index 12200ab76553..36e4d6e71c79 100644 --- a/include/lldb/Target/ThreadPlanCallFunction.h +++ b/include/lldb/Target/ThreadPlanCallFunction.h @@ -34,6 +34,10 @@ public: llvm::ArrayRef<lldb::addr_t> args, const EvaluateExpressionOptions &options); + ThreadPlanCallFunction(Thread &thread, + const Address &function, + const EvaluateExpressionOptions &options); + virtual ~ThreadPlanCallFunction (); @@ -134,7 +138,8 @@ protected: virtual bool DoPlanExplainsStop (Event *event_ptr); -private: + virtual void + SetReturnValue(); bool ConstructorSetup (Thread &thread, @@ -153,7 +158,7 @@ private: bool BreakpointsExplainStop (); - + bool m_valid; bool m_stop_other_threads; bool m_unwind_on_error; @@ -172,13 +177,14 @@ private: // it's nice to know the real stop reason. // This gets set in DoTakedown. StreamString m_constructor_errors; - ClangASTType m_return_type; lldb::ValueObjectSP m_return_valobj_sp; // If this contains a valid pointer, use the ABI to extract values when complete bool m_takedown_done; // We want to ensure we only do the takedown once. This ensures that. bool m_should_clear_objc_exception_bp; bool m_should_clear_cxx_exception_bp; lldb::addr_t m_stop_address; // This is the address we stopped at. Also set in DoTakedown; +private: + ClangASTType m_return_type; DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction); }; diff --git a/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h b/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h new file mode 100644 index 000000000000..83d78a5dca08 --- /dev/null +++ b/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h @@ -0,0 +1,58 @@ +//===-- ThreadPlanCallFunctionUsingABI.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_ThreadPlanCallFunctionUsingABI_h_ +#define liblldb_ThreadPlanCallFunctionUsingABI_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/Type.h" + +namespace lldb_private { + +class ThreadPlanCallFunctionUsingABI : public ThreadPlanCallFunction +{ + // Create a thread plan to call a function at the address passed in the "function" + // argument, this function is executed using register manipulation instead of JIT. + // Class derives from ThreadPlanCallFunction and differs by calling a alternative + // ABI interface ABI::PrepareTrivialCall() which provides more detailed information. +public: + ThreadPlanCallFunctionUsingABI (Thread &thread, + const Address &function_address, + llvm::Type &function_prototype, + llvm::Type &return_type, + llvm::ArrayRef<ABI::CallArgument> args, + const EvaluateExpressionOptions &options); + + ~ThreadPlanCallFunctionUsingABI (); + + void + GetDescription (Stream *s, lldb::DescriptionLevel level) override; + +protected: + void + SetReturnValue () override; + + +private: + llvm::Type &m_return_type; + DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunctionUsingABI); +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanCallFunctionUsingABI_h_ diff --git a/include/lldb/Target/UnixSignals.h b/include/lldb/Target/UnixSignals.h index f47a90bbf545..76955deabc78 100644 --- a/include/lldb/Target/UnixSignals.h +++ b/include/lldb/Target/UnixSignals.h @@ -26,6 +26,9 @@ namespace lldb_private class UnixSignals { public: + static lldb::UnixSignalsSP + Create(const ArchSpec &arch); + //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ @@ -89,6 +92,12 @@ public: int32_t GetNextSignalNumber (int32_t current_signal) const; + int32_t + GetNumSignals() const; + + int32_t + GetSignalAtIndex(int32_t index) const; + // We assume that the elements of this object are constant once it is constructed, // since a process should never need to add or remove symbols as it runs. So don't // call these functions anywhere but the constructor of your subclass of UnixSignals or in @@ -130,14 +139,18 @@ protected: ~Signal () {} }; - void + virtual void Reset (); typedef std::map <int32_t, Signal> collection; collection m_signals; - DISALLOW_COPY_AND_ASSIGN (UnixSignals); + // GDBRemote signals need to be copyable. + UnixSignals(const UnixSignals &rhs); + + const UnixSignals & + operator=(const UnixSignals &rhs) = delete; }; } // Namespace lldb diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h index 45ddb71b5e03..da5e26dbda28 100644 --- a/include/lldb/Utility/JSON.h +++ b/include/lldb/Utility/JSON.h @@ -11,6 +11,7 @@ #define utility_JSON_h_ #include "lldb/Core/Stream.h" +#include "lldb/Utility/StringExtractor.h" #include <inttypes.h> #include <map> @@ -22,6 +23,7 @@ #include "llvm/Support/Casting.h" namespace lldb_private { + class JSONValue { public: @@ -97,8 +99,9 @@ namespace lldb_private { { public: JSONNumber (); - JSONNumber (int64_t i); - + explicit JSONNumber (uint64_t i); + explicit JSONNumber (double d); + JSONNumber (const JSONNumber& s) = delete; JSONNumber& operator = (const JSONNumber& s) = delete; @@ -107,10 +110,19 @@ namespace lldb_private { Write (Stream& s); typedef std::shared_ptr<JSONNumber> SP; - - int64_t + + uint64_t GetData () { return m_data; } - + + double + GetAsDouble() + { + if (m_is_integer) + return (double)m_data; + else + return m_double; + } + static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::Number; @@ -120,7 +132,9 @@ namespace lldb_private { ~JSONNumber () = default; private: - int64_t m_data; + bool m_is_integer; + uint64_t m_data; + double m_double; }; class JSONTrue : public JSONValue @@ -271,6 +285,48 @@ namespace lldb_private { Vector m_elements; }; + + + class JSONParser : public StringExtractor + { + public: + enum Token + { + Invalid, + Error, + ObjectStart, + ObjectEnd, + ArrayStart, + ArrayEnd, + Comma, + Colon, + String, + Integer, + Float, + True, + False, + Null, + EndOfFile + }; + + JSONParser (const char *cstr); + + int + GetEscapedChar (bool &was_escaped); + + Token + GetToken (std::string &value); + + JSONValue::SP + ParseJSONValue (); + + protected: + JSONValue::SP + ParseJSONObject (); + + JSONValue::SP + ParseJSONArray (); + }; } #endif // utility_ProcessStructReader_h_ diff --git a/source/Utility/StringExtractor.h b/include/lldb/Utility/StringExtractor.h index 49dfe99bd358..0f2dbb166be1 100644 --- a/source/Utility/StringExtractor.h +++ b/include/lldb/Utility/StringExtractor.h @@ -67,6 +67,9 @@ public: m_index = 0; } + void + SkipSpaces (); + std::string & GetStringRef () { @@ -96,6 +99,15 @@ public: char GetChar (char fail_value = '\0'); + char + PeekChar (char fail_value = '\0') + { + const char *cstr = Peek(); + if (cstr) + return cstr[0]; + return fail_value; + } + int DecodeHexU8(); diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index e0c2ae4b8b8d..da90ac4775ee 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -423,6 +423,8 @@ namespace lldb { #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildren> ScriptedSyntheticChildrenSP; #endif + typedef std::shared_ptr<lldb_private::UnixSignals> UnixSignalsSP; + typedef std::weak_ptr<lldb_private::UnixSignals> UnixSignalsWP; typedef std::shared_ptr<lldb_private::UnwindAssembly> UnwindAssemblySP; typedef std::shared_ptr<lldb_private::UnwindPlan> UnwindPlanSP; typedef lldb_private::SharingPtr<lldb_private::ValueObject> ValueObjectSP; diff --git a/include/lldb/lldb-private-forward.h b/include/lldb/lldb-private-forward.h index 424aa4cc53f4..bcfeb68b0b25 100644 --- a/include/lldb/lldb-private-forward.h +++ b/include/lldb/lldb-private-forward.h @@ -34,7 +34,6 @@ namespace lldb_private typedef std::weak_ptr<lldb_private::NativeProcessProtocol> NativeProcessProtocolWP; typedef std::shared_ptr<lldb_private::NativeRegisterContext> NativeRegisterContextSP; typedef std::shared_ptr<lldb_private::NativeThreadProtocol> NativeThreadProtocolSP; - typedef std::shared_ptr<lldb_private::UnixSignals> UnixSignalsSP; } #endif // #if defined(__cplusplus) diff --git a/source/API/SBBlock.cpp b/source/API/SBBlock.cpp index c8a665f7d6fb..fdbbbc045279 100644 --- a/source/API/SBBlock.cpp +++ b/source/API/SBBlock.cpp @@ -75,7 +75,15 @@ SBBlock::GetInlinedName () const { const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo (); if (inlined_info) - return inlined_info->GetName().AsCString (NULL); + { + Function *function = m_opaque_ptr->CalculateSymbolContextFunction(); + LanguageType language; + if (function) + language = function->GetLanguage(); + else + language = lldb::eLanguageTypeUnknown; + return inlined_info->GetName(language).AsCString (NULL); + } } return NULL; } diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp index e845aef41f45..08a5822cb781 100644 --- a/source/API/SBFrame.cpp +++ b/source/API/SBFrame.cpp @@ -1571,7 +1571,7 @@ SBFrame::GetFunctionName() const if (inlined_block) { const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo(); - name = inlined_info->GetName().AsCString(); + name = inlined_info->GetName(sc.function->GetLanguage()).AsCString(); } } @@ -1602,3 +1602,59 @@ SBFrame::GetFunctionName() const } return name; } + +const char * +SBFrame::GetDisplayFunctionName() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *name = NULL; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + SymbolContext sc (frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); + if (sc.block) + { + Block *inlined_block = sc.block->GetContainingInlinedBlock (); + if (inlined_block) + { + const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo(); + name = inlined_info->GetDisplayName(sc.function->GetLanguage()).AsCString(); + } + } + + if (name == NULL) + { + if (sc.function) + name = sc.function->GetDisplayName().GetCString(); + } + + if (name == NULL) + { + if (sc.symbol) + name = sc.symbol->GetDisplayName().GetCString(); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetDisplayFunctionName () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetDisplayFunctionName() => error: process is running"); + + } + } + return name; +} diff --git a/source/API/SBFunction.cpp b/source/API/SBFunction.cpp index bf5e9180a437..2ec6072b51eb 100644 --- a/source/API/SBFunction.cpp +++ b/source/API/SBFunction.cpp @@ -60,7 +60,7 @@ SBFunction::GetName() const { const char *cstr = NULL; if (m_opaque_ptr) - cstr = m_opaque_ptr->GetMangled().GetName().AsCString(); + cstr = m_opaque_ptr->GetName().AsCString(); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -76,6 +76,26 @@ SBFunction::GetName() const } const char * +SBFunction::GetDisplayName() const +{ + const char *cstr = NULL; + if (m_opaque_ptr) + cstr = m_opaque_ptr->GetMangled().GetDisplayDemangledName(m_opaque_ptr->GetLanguage()).AsCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (cstr) + log->Printf ("SBFunction(%p)::GetDisplayName () => \"%s\"", + static_cast<void*>(m_opaque_ptr), cstr); + else + log->Printf ("SBFunction(%p)::GetDisplayName () => NULL", + static_cast<void*>(m_opaque_ptr)); + } + return cstr; +} + +const char * SBFunction::GetMangledName () const { const char *cstr = NULL; diff --git a/source/API/SBPlatform.cpp b/source/API/SBPlatform.cpp index 5662f36b514d..97ffcf149750 100644 --- a/source/API/SBPlatform.cpp +++ b/source/API/SBPlatform.cpp @@ -11,6 +11,7 @@ #include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBLaunchInfo.h" +#include "lldb/API/SBUnixSignals.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Error.h" #include "lldb/Host/File.h" @@ -638,3 +639,11 @@ SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions) } +SBUnixSignals +SBPlatform::GetUnixSignals() const +{ + if (auto platform_sp = GetSP()) + return SBUnixSignals{platform_sp}; + + return {}; +} diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp index a1dbf686da03..01bfaf9aff01 100644 --- a/source/API/SBProcess.cpp +++ b/source/API/SBProcess.cpp @@ -912,14 +912,10 @@ SBProcess::Signal (int signo) SBUnixSignals SBProcess::GetUnixSignals() { - SBUnixSignals sb_unix_signals; - ProcessSP process_sp(GetSP()); - if (process_sp) - { - sb_unix_signals.SetSP(process_sp); - } + if (auto process_sp = GetSP()) + return SBUnixSignals{process_sp}; - return sb_unix_signals; + return {}; } void diff --git a/source/API/SBSymbol.cpp b/source/API/SBSymbol.cpp index 246a455d93a7..22d1e546b5ee 100644 --- a/source/API/SBSymbol.cpp +++ b/source/API/SBSymbol.cpp @@ -63,7 +63,7 @@ SBSymbol::GetName() const { const char *name = NULL; if (m_opaque_ptr) - name = m_opaque_ptr->GetMangled().GetName().AsCString(); + name = m_opaque_ptr->GetName().AsCString(); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -73,6 +73,20 @@ SBSymbol::GetName() const } const char * +SBSymbol::GetDisplayName() const +{ + const char *name = NULL; + if (m_opaque_ptr) + name = m_opaque_ptr->GetMangled().GetDisplayDemangledName(m_opaque_ptr->GetLanguage()).AsCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBSymbol(%p)::GetDisplayName () => \"%s\"", + static_cast<void*>(m_opaque_ptr), name ? name : ""); + return name; +} + +const char * SBSymbol::GetMangledName () const { const char *name = NULL; diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp index 923885223a5f..6597d4e77c73 100644 --- a/source/API/SBTarget.cpp +++ b/source/API/SBTarget.cpp @@ -2293,6 +2293,19 @@ SBTarget::FindSymbols (const char *name, lldb::SymbolType symbol_type) } +lldb::SBValue +SBTarget::EvaluateExpression (const char *expr) +{ + TargetSP target_sp(GetSP()); + if (!target_sp) + return SBValue(); + + SBExpressionOptions options; + lldb::DynamicValueType fetch_dynamic_value = target_sp->GetPreferDynamicValue(); + options.SetFetchDynamicValue (fetch_dynamic_value); + options.SetUnwindOnError (true); + return EvaluateExpression(expr, options); +} lldb::SBValue SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options) diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp index dfc7ce9629f3..42b5c9affe50 100644 --- a/source/API/SBThread.cpp +++ b/source/API/SBThread.cpp @@ -392,7 +392,7 @@ SBThread::GetStopDescription (char *dst, size_t dst_len) case eStopReasonSignal: { - stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); + stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue()); if (stop_desc == NULL || stop_desc[0] == '\0') { static char signal_desc[] = "signal"; diff --git a/source/API/SBUnixSignals.cpp b/source/API/SBUnixSignals.cpp index ca321d82fd60..531c9782973d 100644 --- a/source/API/SBUnixSignals.cpp +++ b/source/API/SBUnixSignals.cpp @@ -9,6 +9,7 @@ #include "lldb/lldb-defines.h" #include "lldb/Target/Process.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Core/Log.h" @@ -25,8 +26,13 @@ SBUnixSignals::SBUnixSignals (const SBUnixSignals &rhs) : { } -SBUnixSignals::SBUnixSignals (ProcessSP &process_sp) : - m_opaque_wp(process_sp) +SBUnixSignals::SBUnixSignals(ProcessSP &process_sp) : + m_opaque_wp(process_sp ? process_sp->GetUnixSignals() : nullptr) +{ +} + +SBUnixSignals::SBUnixSignals(PlatformSP &platform_sp) : + m_opaque_wp(platform_sp ? platform_sp->GetUnixSignals() : nullptr) { } @@ -42,16 +48,16 @@ SBUnixSignals::~SBUnixSignals() { } -ProcessSP +UnixSignalsSP SBUnixSignals::GetSP() const { return m_opaque_wp.lock(); } void -SBUnixSignals::SetSP (const ProcessSP &process_sp) +SBUnixSignals::SetSP(const UnixSignalsSP &signals_sp) { - m_opaque_wp = process_sp; + m_opaque_wp = signals_sp; } void @@ -63,30 +69,33 @@ SBUnixSignals::Clear () bool SBUnixSignals::IsValid() const { - return (bool) GetSP(); + return static_cast<bool>(GetSP()); } const char * SBUnixSignals::GetSignalAsCString (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetSignalAsCString(signo); - return NULL; + if (auto signals_sp = GetSP()) + return signals_sp->GetSignalAsCString(signo); + + return nullptr; } int32_t SBUnixSignals::GetSignalNumberFromName (const char *name) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetSignalNumberFromName(name); - return -1; + if (auto signals_sp = GetSP()) + return signals_sp->GetSignalNumberFromName(name); + + return LLDB_INVALID_SIGNAL_NUMBER; } bool SBUnixSignals::GetShouldSuppress (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetShouldSuppress(signo); + if (auto signals_sp = GetSP()) + return signals_sp->GetShouldSuppress(signo); + return false; } @@ -94,25 +103,28 @@ bool SBUnixSignals::SetShouldSuppress (int32_t signo, bool value) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ProcessSP process_sp(GetSP()); + auto signals_sp = GetSP(); if (log) { log->Printf ("SBUnixSignals(%p)::SetShouldSuppress (signo=%d, value=%d)", - static_cast<void*>(process_sp.get()), + static_cast<void*>(signals_sp.get()), signo, value); } - if (process_sp) return process_sp->GetUnixSignals().SetShouldSuppress(signo, value); + if (signals_sp) + return signals_sp->SetShouldSuppress(signo, value); + return false; } bool SBUnixSignals::GetShouldStop (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetShouldStop(signo); + if (auto signals_sp = GetSP()) + return signals_sp->GetShouldStop(signo); + return false; } @@ -120,25 +132,28 @@ bool SBUnixSignals::SetShouldStop (int32_t signo, bool value) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ProcessSP process_sp(GetSP()); + auto signals_sp = GetSP(); if (log) { log->Printf ("SBUnixSignals(%p)::SetShouldStop (signo=%d, value=%d)", - static_cast<void*>(process_sp.get()), + static_cast<void*>(signals_sp.get()), signo, value); } - if (process_sp) return process_sp->GetUnixSignals().SetShouldStop(signo, value); + if (signals_sp) + return signals_sp->SetShouldStop(signo, value); + return false; } bool SBUnixSignals::GetShouldNotify (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetShouldNotify(signo); + if (auto signals_sp = GetSP()) + return signals_sp->GetShouldNotify(signo); + return false; } @@ -146,54 +161,36 @@ bool SBUnixSignals::SetShouldNotify (int32_t signo, bool value) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ProcessSP process_sp(GetSP()); + auto signals_sp = GetSP(); if (log) { log->Printf ("SBUnixSignals(%p)::SetShouldNotify (signo=%d, value=%d)", - static_cast<void*>(process_sp.get()), + static_cast<void*>(signals_sp.get()), signo, value); } - if (process_sp) return process_sp->GetUnixSignals().SetShouldNotify(signo, value); + if (signals_sp) + return signals_sp->SetShouldNotify(signo, value); + return false; } int32_t SBUnixSignals::GetNumSignals () const { - if (auto process_sp = GetSP()) - { - // only valid while we hold process_sp - UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); - int32_t num_signals = 0; - for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); - signo != LLDB_INVALID_SIGNAL_NUMBER; - signo = unix_signals_ptr->GetNextSignalNumber(signo)) - { - num_signals++; - } - return num_signals; - } - return LLDB_INVALID_SIGNAL_NUMBER; + if (auto signals_sp = GetSP()) + return signals_sp->GetNumSignals(); + + return -1; } int32_t SBUnixSignals::GetSignalAtIndex (int32_t index) const { - if (auto process_sp = GetSP()) - { - // only valid while we hold process_sp - UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); - int32_t idx = 0; - for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); - signo != LLDB_INVALID_SIGNAL_NUMBER; - signo = unix_signals_ptr->GetNextSignalNumber(signo)) - { - if (index == idx) return signo; - idx++; - } - } + if (auto signals_sp = GetSP()) + return signals_sp->GetSignalAtIndex(index); + return LLDB_INVALID_SIGNAL_NUMBER; } diff --git a/source/API/SystemInitializerFull.cpp b/source/API/SystemInitializerFull.cpp index 731d38a37bee..01ad8157646e 100644 --- a/source/API/SystemInitializerFull.cpp +++ b/source/API/SystemInitializerFull.cpp @@ -58,7 +58,6 @@ #if defined(_MSC_VER) #include "lldb/Host/windows/windows.h" -#include "Plugins/Process/Windows/DynamicLoaderWindows.h" #include "Plugins/Process/Windows/ProcessWindows.h" #endif @@ -264,7 +263,6 @@ SystemInitializerFull::Initialize() RenderScriptRuntime::Initialize(); #if defined(_MSC_VER) - DynamicLoaderWindows::Initialize(); ProcessWindows::Initialize(); #endif #if defined(__FreeBSD__) @@ -369,9 +367,6 @@ SystemInitializerFull::Terminate() ProcessKDP::Terminate(); SymbolVendorMacOSX::Terminate(); #endif -#if defined(_MSC_VER) - DynamicLoaderWindows::Terminate(); -#endif #if defined(__FreeBSD__) ProcessFreeBSD::Terminate(); diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp index ef9144778df0..a199d390803b 100644 --- a/source/Breakpoint/BreakpointLocation.cpp +++ b/source/Breakpoint/BreakpointLocation.cpp @@ -611,7 +611,7 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) { s->EOL(); s->Indent("function = "); - s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>")); + s->PutCString (sc.function->GetName().AsCString("<unknown>")); } if (sc.line_entry.line > 0) @@ -632,7 +632,7 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) s->Indent ("re-exported target = "); else s->Indent("symbol = "); - s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>")); + s->PutCString(sc.symbol->GetName().AsCString("<unknown>")); } } } diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index 4cbcb70d5fd2..162bfb4b5a76 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -1249,27 +1249,27 @@ public: CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "breakpoint disable", - "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.", + "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.", NULL) { SetHelpLong( -"Disable the specified breakpoint(s) without removing it/them. \n\ -If no breakpoints are specified, disable them all.\n\ -\n\ -Note: disabling a breakpoint will cause none of its locations to be hit\n\ -regardless of whether they are enabled or disabled. So the sequence: \n\ -\n\ - (lldb) break disable 1\n\ - (lldb) break enable 1.1\n\ -\n\ -will NOT cause location 1.1 to get hit. To achieve that, do:\n\ -\n\ - (lldb) break disable 1.*\n\ - (lldb) break enable 1.1\n\ -\n\ -The first command disables all the locations of breakpoint 1, \n\ +"Disable the specified breakpoint(s) without removing them. \ +If none are specified, disable all breakpoints." R"( + +)" "Note: disabling a breakpoint will cause none of its locations to be hit \ +regardless of whether they are enabled or disabled. After the sequence:" R"( + + (lldb) break disable 1 + (lldb) break enable 1.1 + +execution will NOT stop at location 1.1. To achieve that, type: + + (lldb) break disable 1.* + (lldb) break enable 1.1 + +)" "The first command disables all the locations of breakpoint 1, \ the second re-enables the first location." - ); + ); CommandArgumentEntry arg; CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index 180ab600a50e..ac9c9a64188c 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -49,143 +49,120 @@ public: m_options (interpreter) { SetHelpLong ( -"\nGeneral information about entering breakpoint commands\n\ -------------------------------------------------------\n\ -\n\ -This command will cause you to be prompted to enter the command or set of\n\ -commands you wish to be executed when the specified breakpoint is hit. You\n\ -will be told to enter your command(s), and will see a '> 'prompt. Because\n\ -you can enter one or many commands to be executed when a breakpoint is hit,\n\ -you will continue to be prompted after each new-line that you enter, until you\n\ -enter the word 'DONE', which will cause the commands you have entered to be\n\ -stored with the breakpoint and executed when the breakpoint is hit.\n\ -\n\ -Syntax checking is not necessarily done when breakpoint commands are entered.\n\ -An improperly written breakpoint command will attempt to get executed when the\n\ -breakpoint gets hit, and usually silently fail. If your breakpoint command does\n\ -not appear to be getting executed, go back and check your syntax.\n\ -\n\ -Special information about PYTHON breakpoint commands\n\ -----------------------------------------------------\n\ -\n\ -You may enter either one line of Python, multiple lines of Python (including\n\ -function definitions), or specify a Python function in a module that has already,\n\ -or will be imported. If you enter a single line of Python, that will be passed\n\ -to the Python interpreter 'as is' when the breakpoint gets hit. If you enter\n\ -function definitions, they will be passed to the Python interpreter as soon as\n\ -you finish entering the breakpoint command, and they can be called later (don't\n\ -forget to add calls to them, if you want them called when the breakpoint is\n\ -hit). If you enter multiple lines of Python that are not function definitions,\n\ -they will be collected into a new, automatically generated Python function, and\n\ -a call to the newly generated function will be attached to the breakpoint.\n\ -\n\ -\n\ -This auto-generated function is passed in three arguments:\n\ -\n\ - frame: a lldb.SBFrame object for the frame which hit breakpoint.\n\ - bp_loc: a lldb.SBBreakpointLocation object that represents the breakpoint\n\ - location that was hit.\n\ - dict: the python session dictionary hit.\n\ -\n\ -When specifying a python function with the --python-function option, you need\n\ -to supply the function name prepended by the module name. So if you import a\n\ -module named 'myutils' that contains a 'breakpoint_callback' function, you would\n\ -specify the option as:\n\ -\n\ - --python-function myutils.breakpoint_callback\n\ -\n\ -The function itself must have the following prototype:\n\ -\n\ -def breakpoint_callback(frame, bp_loc, dict):\n\ - # Your code goes here\n\ -\n\ -The arguments are the same as the 3 auto generation function arguments listed\n\ -above. Note that the global variable 'lldb.frame' will NOT be setup when this\n\ -function is called, so be sure to use the 'frame' argument. The 'frame' argument\n\ -can get you to the thread (frame.GetThread()), the thread can get you to the\n\ -process (thread.GetProcess()), and the process can get you back to the target\n\ -(process.GetTarget()).\n\ -\n\ -Important Note: Because loose Python code gets collected into functions, if you\n\ -want to access global variables in the 'loose' code, you need to specify that\n\ -they are global, using the 'global' keyword. Be sure to use correct Python\n\ -syntax, including indentation, when entering Python breakpoint commands.\n\ -\n\ -As a third option, you can pass the name of an already existing Python function\n\ -and that function will be attached to the breakpoint. It will get passed the\n\ -frame and bp_loc arguments mentioned above.\n\ -\n\ -Example Python one-line breakpoint command:\n\ -\n\ -(lldb) breakpoint command add -s python 1\n\ -Enter your Python command(s). Type 'DONE' to end.\n\ -> print \"Hit this breakpoint!\"\n\ -> DONE\n\ -\n\ -As a convenience, this also works for a short Python one-liner:\n\ -(lldb) breakpoint command add -s python 1 -o \"import time; print time.asctime()\"\n\ -(lldb) run\n\ -Launching '.../a.out' (x86_64)\n\ -(lldb) Fri Sep 10 12:17:45 2010\n\ -Process 21778 Stopped\n\ -* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread\n\ - 36 \n\ - 37 int c(int val)\n\ - 38 {\n\ - 39 -> return val + 3;\n\ - 40 }\n\ - 41 \n\ - 42 int main (int argc, char const *argv[])\n\ -(lldb)\n\ -\n\ -Example multiple line Python breakpoint command, using function definition:\n\ -\n\ -(lldb) breakpoint command add -s python 1\n\ -Enter your Python command(s). Type 'DONE' to end.\n\ -> def breakpoint_output (bp_no):\n\ -> out_string = \"Hit breakpoint number \" + repr (bp_no)\n\ -> print out_string\n\ -> return True\n\ -> breakpoint_output (1)\n\ -> DONE\n\ -\n\ -\n\ -Example multiple line Python breakpoint command, using 'loose' Python:\n\ -\n\ -(lldb) breakpoint command add -s p 1\n\ -Enter your Python command(s). Type 'DONE' to end.\n\ -> global bp_count\n\ -> bp_count = bp_count + 1\n\ -> print \"Hit this breakpoint \" + repr(bp_count) + \" times!\"\n\ -> DONE\n\ -\n\ -In this case, since there is a reference to a global variable,\n\ -'bp_count', you will also need to make sure 'bp_count' exists and is\n\ -initialized:\n\ -\n\ -(lldb) script\n\ ->>> bp_count = 0\n\ ->>> quit()\n\ -\n\ -(lldb)\n\ -\n\ -\n\ -Your Python code, however organized, can optionally return a value.\n\ -If the returned value is False, that tells LLDB not to stop at the breakpoint\n\ -to which the code is associated. Returning anything other than False, or even\n\ -returning None, or even omitting a return statement entirely, will cause\n\ -LLDB to stop.\n\ -\n\ -Final Note: If you get a warning that no breakpoint command was generated, but\n\ -you did not get any syntax errors, you probably forgot to add a call to your\n\ -functions.\n\ -\n\ -Special information about debugger command breakpoint commands\n\ ---------------------------------------------------------------\n\ -\n\ -You may enter any debugger command, exactly as you would at the debugger prompt.\n\ -You may enter as many debugger commands as you like, but do NOT enter more than\n\ -one command per line.\n" ); +R"( +General information about entering breakpoint commands +------------------------------------------------------ + +)" "This command will prompt for commands to be executed when the specified \ +breakpoint is hit. Each command is typed on its own line following the '> ' \ +prompt until 'DONE' is entered." R"( + +)" "Syntactic errors may not be detected when initially entered, and many \ +malformed commands can silently fail when executed. If your breakpoint commands \ +do not appear to be executing, double-check the command syntax." R"( + +)" "Note: You may enter any debugger command exactly as you would at the debugger \ +prompt. There is no limit to the number of commands supplied, but do NOT enter \ +more than one command per line." R"( + +Special information about PYTHON breakpoint commands +---------------------------------------------------- + +)" "You may enter either one or more lines of Python, including function \ +definitions or calls to functions that will have been imported by the time \ +the code executes. Single line breakpoint commands will be interpreted 'as is' \ +when the breakpoint is hit. Multiple lines of Python will be wrapped in a \ +generated function, and a call to the function will be attached to the breakpoint." R"( + +This auto-generated function is passed in three arguments: + + frame: an lldb.SBFrame object for the frame which hit breakpoint. + + bp_loc: an lldb.SBBreakpointLocation object that represents the breakpoint location that was hit. + + dict: the python session dictionary hit. + +)" "When specifying a python function with the --python-function option, you need \ +to supply the function name prepended by the module name:" R"( + + --python-function myutils.breakpoint_callback + +The function itself must have the following prototype: + +def breakpoint_callback(frame, bp_loc, dict): + # Your code goes here + +)" "The arguments are the same as the arguments passed to generated functions as \ +described above. Note that the global variable 'lldb.frame' will NOT be updated when \ +this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ +can get you to the thread via frame.GetThread(), the thread can get you to the \ +process via thread.GetProcess(), and the process can get you back to the target \ +via process.GetTarget()." R"( + +)" "Important Note: As Python code gets collected into functions, access to global \ +variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ +Python syntax, including indentation, when entering Python breakpoint commands." R"( + +Example Python one-line breakpoint command: + +(lldb) breakpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> print "Hit this breakpoint!" +> DONE + +As a convenience, this also works for a short Python one-liner: + +(lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()' +(lldb) run +Launching '.../a.out' (x86_64) +(lldb) Fri Sep 10 12:17:45 2010 +Process 21778 Stopped +* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread + 36 + 37 int c(int val) + 38 { + 39 -> return val + 3; + 40 } + 41 + 42 int main (int argc, char const *argv[]) + +Example multiple line Python breakpoint command: + +(lldb) breakpoint command add -s p 1 +Enter your Python command(s). Type 'DONE' to end. +> global bp_count +> bp_count = bp_count + 1 +> print "Hit this breakpoint " + repr(bp_count) + " times!" +> DONE + +Example multiple line Python breakpoint command, using function definition: + +(lldb) breakpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> def breakpoint_output (bp_no): +> out_string = "Hit breakpoint number " + repr (bp_no) +> print out_string +> return True +> breakpoint_output (1) +> DONE + +)" "In this case, since there is a reference to a global variable, \ +'bp_count', you will also need to make sure 'bp_count' exists and is \ +initialized:" R"( + +(lldb) script +>>> bp_count = 0 +>>> quit() + +)" "Your Python code, however organized, can optionally return a value. \ +If the returned value is False, that tells LLDB not to stop at the breakpoint \ +to which the code is associated. Returning anything other than False, or even \ +returning None, or even omitting a return statement entirely, will cause \ +LLDB to stop." R"( + +)" "Final Note: A warning that no breakpoint command was generated when there \ +are no syntax errors may indicate that a function was declared but never called." + ); CommandArgumentEntry arg; CommandArgumentData bp_id_arg; diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index 5fd99cfdabf4..f56d089877de 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -450,60 +450,74 @@ public: NULL) { SetHelpLong( - "'alias' allows the user to create a short-cut or abbreviation for long \n\ - commands, multi-word commands, and commands that take particular options. \n\ - Below are some simple examples of how one might use the 'alias' command: \n\ - \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ - // command. \n\ - 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ - // command. Since breakpoint commands are two-word \n\ - // commands, the user will still need to enter the \n\ - // second word after 'bp', e.g. 'bp enable' or \n\ - // 'bp delete'. \n\ - 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\ - // two-word command 'breakpoint list'. \n\ - \nAn alias can include some options for the command, with the values either \n\ - filled in at the time the alias is created, or specified as positional \n\ - arguments, to be filled in when the alias is invoked. The following example \n\ - shows how to create aliases with options: \n\ - \n\ - 'command alias bfl breakpoint set -f %1 -l %2' \n\ - \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ - options already part of the alias. So if the user wants to set a breakpoint \n\ - by file and line without explicitly having to use the -f and -l options, the \n\ - user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\ - for the actual arguments that will be passed when the alias command is used. \n\ - The number in the placeholder refers to the position/order the actual value \n\ - occupies when the alias is used. All the occurrences of '%1' in the alias \n\ - will be replaced with the first argument, all the occurrences of '%2' in the \n\ - alias will be replaced with the second argument, and so on. This also allows \n\ - actual arguments to be used multiple times within an alias (see 'process \n\ - launch' example below). \n\ - Note: the positional arguments must substitute as whole words in the resultant\n\ - command, so you can't at present do something like:\n\ - \n\ - command alias bcppfl breakpoint set -f %1.cpp -l %2\n\ - \n\ - to get the file extension \".cpp\" automatically appended. For more complex\n\ - aliasing, use the \"command regex\" command instead.\n\ - \nSo in the 'bfl' case, the actual file value will be \n\ - filled in with the first argument following 'bfl' and the actual line number \n\ - value will be filled in with the second argument. The user would use this \n\ - alias as follows: \n\ - \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\ - <... some time later ...> \n\ - (lldb) bfl my-file.c 137 \n\ - \nThis would be the same as if the user had entered \n\ - 'breakpoint set -f my-file.c -l 137'. \n\ - \nAnother example: \n\ - \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\ - (lldb) pltty /dev/tty0 \n\ - // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ - \nIf the user always wanted to pass the same value to a particular option, the \n\ - alias could be defined with that value directly in the alias as a constant, \n\ - rather than using a positional placeholder: \n\ - \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ - // 3 of whatever file is indicated. \n"); +"'alias' allows the user to create a short-cut or abbreviation for long \ +commands, multi-word commands, and commands that take particular options. \ +Below are some simple examples of how one might use the 'alias' command:" R"( + +(lldb) command alias sc script + + Creates the abbreviation 'sc' for the 'script' command. + +(lldb) command alias bp breakpoint + +)" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \ +breakpoint commands are two-word commands, the user would still need to \ +enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"( + +(lldb) command alias bpl breakpoint list + + Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'. + +)" "An alias can include some options for the command, with the values either \ +filled in at the time the alias is created, or specified as positional \ +arguments, to be filled in when the alias is invoked. The following example \ +shows how to create aliases with options:" R"( + +(lldb) command alias bfl breakpoint set -f %1 -l %2 + +)" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \ +options already part of the alias. So if the user wants to set a breakpoint \ +by file and line without explicitly having to use the -f and -l options, the \ +user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \ +for the actual arguments that will be passed when the alias command is used. \ +The number in the placeholder refers to the position/order the actual value \ +occupies when the alias is used. All the occurrences of '%1' in the alias \ +will be replaced with the first argument, all the occurrences of '%2' in the \ +alias will be replaced with the second argument, and so on. This also allows \ +actual arguments to be used multiple times within an alias (see 'process \ +launch' example below)." R"( + +)" "Note: the positional arguments must substitute as whole words in the resultant \ +command, so you can't at present do something like this to append the file extension \ +\".cpp\":" R"( + +(lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2 + +)" "For more complex aliasing, use the \"command regex\" command instead. In the \ +'bfl' case above, the actual file value will be filled in with the first argument \ +following 'bfl' and the actual line number value will be filled in with the second \ +argument. The user would use this alias as follows:" R"( + +(lldb) command alias bfl breakpoint set -f %1 -l %2 +(lldb) bfl my-file.c 137 + +This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'. + +Another example: + +(lldb) command alias pltty process launch -s -o %1 -e %1 +(lldb) pltty /dev/tty0 + + Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0' + +)" "If the user always wanted to pass the same value to a particular option, the \ +alias could be defined with that value directly in the alias as a constant, \ +rather than using a positional placeholder:" R"( + +(lldb) command alias bl3 breakpoint set -f %1 -l 3 + + Always sets a breakpoint on line 3 of whatever file is indicated.)" + ); CommandArgumentEntry arg1; CommandArgumentEntry arg2; @@ -960,31 +974,30 @@ public: IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), m_options (interpreter) { - SetHelpLong( -"This command allows the user to create powerful regular expression commands\n" -"with substitutions. The regular expressions and substitutions are specified\n" -"using the regular expression substitution format of:\n" -"\n" -" s/<regex>/<subst>/\n" -"\n" -"<regex> is a regular expression that can use parenthesis to capture regular\n" -"expression input and substitute the captured matches in the output using %1\n" -"for the first match, %2 for the second, and so on.\n" -"\n" -"The regular expressions can all be specified on the command line if more than\n" -"one argument is provided. If just the command name is provided on the command\n" -"line, then the regular expressions and substitutions can be entered on separate\n" -" lines, followed by an empty line to terminate the command definition.\n" -"\n" -"EXAMPLES\n" -"\n" -"The following example will define a regular expression command named 'f' that\n" -"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" -"a number follows 'f':\n" -"\n" -" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" -"\n" - ); + SetHelpLong(R"( +)" "This command allows the user to create powerful regular expression commands \ +with substitutions. The regular expressions and substitutions are specified \ +using the regular expression substitution format of:" R"( + + s/<regex>/<subst>/ + +)" "<regex> is a regular expression that can use parenthesis to capture regular \ +expression input and substitute the captured matches in the output using %1 \ +for the first match, %2 for the second, and so on." R"( + +)" "The regular expressions can all be specified on the command line if more than \ +one argument is provided. If just the command name is provided on the command \ +line, then the regular expressions and substitutions can be entered on separate \ +lines, followed by an empty line to terminate the command definition." R"( + +EXAMPLES + +)" "The following example will define a regular expression command named 'f' that \ +will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \ +a number follows 'f':" R"( + + (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')" + ); } ~CommandObjectCommandsAddRegex() diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index f4bb8fbac11e..1be17a0cfddc 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -202,35 +202,39 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete m_expr_line_count (0), m_expr_lines () { - SetHelpLong( -"Timeouts:\n\ - If the expression can be evaluated statically (without running code) then it will be.\n\ - Otherwise, by default the expression will run on the current thread with a short timeout:\n\ - currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\ - and resumed with all threads running. You can use the -a option to disable retrying on all\n\ - threads. You can use the -t option to set a shorter timeout.\n\ -\n\ -User defined variables:\n\ - You can define your own variables for convenience or to be used in subsequent expressions.\n\ - You define them the same way you would define variables in C. If the first character of \n\ - your user defined variable is a $, then the variable's value will be available in future\n\ - expressions, otherwise it will just be available in the current expression.\n\ -\n\ -\n\ -Continuing evaluation after a breakpoint:\n\ - If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once\n\ - you are done with your investigation, you can either remove the expression execution frames\n\ - from the stack with \"thread return -x\" or if you are still interested in the expression result\n\ - you can issue the \"continue\" command and the expression evaluation will complete and the\n\ - expression result will be available using the \"thread.completed-expression\" key in the thread\n\ - format.\n\ -\n\ -Examples: \n\ -\n\ - expr my_struct->a = my_array[3] \n\ - expr -f bin -- (index * 8) + 5 \n\ - expr unsigned int $foo = 5\n\ - expr char c[] = \"foo\"; c[0]\n"); + SetHelpLong( +R"( +Timeouts: + +)" " If the expression can be evaluated statically (without running code) then it will be. \ +Otherwise, by default the expression will run on the current thread with a short timeout: \ +currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \ +and resumed with all threads running. You can use the -a option to disable retrying on all \ +threads. You can use the -t option to set a shorter timeout." R"( + +User defined variables: + +)" " You can define your own variables for convenience or to be used in subsequent expressions. \ +You define them the same way you would define variables in C. If the first character of \ +your user defined variable is a $, then the variable's value will be available in future \ +expressions, otherwise it will just be available in the current expression." R"( + +Continuing evaluation after a breakpoint: + +)" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \ +you are done with your investigation, you can either remove the expression execution frames \ +from the stack with \"thread return -x\" or if you are still interested in the expression result \ +you can issue the \"continue\" command and the expression evaluation will complete and the \ +expression result will be available using the \"thread.completed-expression\" key in the thread \ +format." R"( + +Examples: + + expr my_struct->a = my_array[3] + expr -f bin -- (index * 8) + 5 + expr unsigned int $foo = 5 + expr char c[] = \"foo\"; c[0])" + ); CommandArgumentEntry arg; CommandArgumentData expression_arg; diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 866587fb4ebc..a0979d059edb 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -1067,10 +1067,12 @@ public: 0) { SetHelpLong( -"Examples: \n\ -\n\ - platform get-file /the/remote/file/path /the/local/file/path\n\ - # Transfer a file from the remote end with file path /the/remote/file/path to the local host.\n"); +R"(Examples: + +(lldb) platform get-file /the/remote/file/path /the/local/file/path + + Transfer a file from the remote end with file path /the/remote/file/path to the local host.)" + ); CommandArgumentEntry arg1, arg2; CommandArgumentData file_arg_remote, file_arg_host; @@ -1150,10 +1152,12 @@ public: 0) { SetHelpLong( -"Examples: \n\ -\n\ - platform get-size /the/remote/file/path\n\ - # Get the file size from the remote end with path /the/remote/file/path.\n"); +R"(Examples: + +(lldb) platform get-size /the/remote/file/path + + Get the file size from the remote end with path /the/remote/file/path.)" + ); CommandArgumentEntry arg1; CommandArgumentData file_arg_remote; diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 4414bdf2a2c8..e587eadfa3d6 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -1337,7 +1337,7 @@ protected: if (::isxdigit (signal_name[0])) signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); else - signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); + signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); if (signo == LLDB_INVALID_SIGNAL_NUMBER) { @@ -1681,7 +1681,8 @@ public: NULL), m_options (interpreter) { - SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); + SetHelpLong ("\nIf no signals are specified, update them all. If no update " + "option is specified, list the current values."); CommandArgumentEntry arg; CommandArgumentData signal_arg; @@ -1734,14 +1735,14 @@ public: } void - PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) + PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp) { bool stop; bool suppress; bool notify; str.Printf ("%-11s ", sig_name); - if (signals.GetSignalInfo (signo, suppress, stop, notify)) + if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) { bool pass = !suppress; str.Printf ("%s %s %s", @@ -1753,7 +1754,7 @@ public: } void - PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) + PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp) { PrintSignalHeader (str); @@ -1762,18 +1763,18 @@ public: size_t num_args = signal_args.GetArgumentCount(); for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) - PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); + PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp); } } else // Print info for ALL signals { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { - PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); - signo = signals.GetNextSignalNumber (signo); + PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp); + signo = signals_sp->GetNextSignalNumber(signo); } } } @@ -1830,27 +1831,27 @@ protected: } size_t num_args = signal_args.GetArgumentCount(); - UnixSignals &signals = process_sp->GetUnixSignals(); + UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); int num_signals_set = 0; if (num_args > 0) { for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) { // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees // the value is either 0 or 1. if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); ++num_signals_set; } else @@ -1866,25 +1867,25 @@ protected: { if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } - signo = signals.GetNextSignalNumber (signo); + signo = signals_sp->GetNextSignalNumber(signo); } } } } - PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); + PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp); if (num_signals_set > 0) result.SetStatus (eReturnStatusSuccessFinishNoResult); diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index ccbf98c767f1..8ed783b211f6 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -60,24 +60,25 @@ public: m_arguments.push_back (arg2); SetHelpLong ( -"When setting a dictionary or array variable, you can set multiple entries \n\ -at once by giving the values to the set command. For example: \n\ -\n\ -(lldb) settings set target.run-args value1 value2 value3 \n\ -(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345 \n\ -\n\ -(lldb) settings show target.run-args \n\ - [0]: 'value1' \n\ - [1]: 'value2' \n\ - [3]: 'value3' \n\ -(lldb) settings show target.env-vars \n\ - 'MYPATH=~/.:/usr/bin'\n\ - 'SOME_ENV_VAR=12345' \n\ -\n\ -Warning: The 'set' command re-sets the entire array or dictionary. If you \n\ -just want to add, remove or update individual values (or add something to \n\ -the end), use one of the other settings sub-commands: append, replace, \n\ -insert-before or insert-after.\n"); +"\nWhen setting a dictionary or array variable, you can set multiple entries \ +at once by giving the values to the set command. For example:" R"( + +(lldb) settings set target.run-args value1 value2 value3 +(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345 + +(lldb) settings show target.run-args + [0]: 'value1' + [1]: 'value2' + [3]: 'value3' +(lldb) settings show target.env-vars + 'MYPATH=~/.:/usr/bin' + 'SOME_ENV_VAR=12345' + +)" "Warning: The 'set' command re-sets the entire array or dictionary. If you \ +just want to add, remove or update individual values (or add something to \ +the end), use one of the other settings sub-commands: append, replace, \ +insert-before or insert-after." + ); } diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp index 7c8061a6ca08..584e94d0452d 100644 --- a/source/Commands/CommandObjectType.cpp +++ b/source/Commands/CommandObjectType.cpp @@ -764,31 +764,39 @@ public: m_arguments.push_back (type_arg); SetHelpLong( - "Some examples of using this command.\n" - "We use as reference the following snippet of code:\n" - "\n" - "typedef int Aint;\n" - "typedef float Afloat;\n" - "typedef Aint Bint;\n" - "typedef Afloat Bfloat;\n" - "\n" - "Aint ix = 5;\n" - "Bint iy = 5;\n" - "\n" - "Afloat fx = 3.14;\n" - "BFloat fy = 3.14;\n" - "\n" - "Typing:\n" - "type format add -f hex AInt\n" - "frame variable iy\n" - "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n" - "To prevent this type\n" - "type format add -f hex -C no AInt\n" - "\n" - "A similar reasoning applies to\n" - "type format add -f hex -C no float -p\n" - "which now prints all floats and float&s as hexadecimal, but does not format float*s\n" - "and does not change the default display for Afloat and Bfloat objects.\n" +R"( +The following examples of 'type format add' refer to this code snippet for context: + + typedef int Aint; + typedef float Afloat; + typedef Aint Bint; + typedef Afloat Bfloat; + + Aint ix = 5; + Bint iy = 5; + + Afloat fx = 3.14; + BFloat fy = 3.14; + +Adding default formatting: + +(lldb) type format add -f hex AInt +(lldb) frame variable iy + +)" " Produces hexidecimal display of iy, because no formatter is available for Bint and \ +the one for Aint is used instead." R"( + +To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains: + + +(lldb) type format add -f hex -C no AInt + +Similar reasoning applies to this: + +(lldb) type format add -f hex -C no float -p + +)" " All float values and float references are now formatted as hexadecimal, but not \ +pointers to floats. Nor will it change the default display for Afloat and Bfloat objects." ); // Add the "--format" to all options groups @@ -1736,69 +1744,86 @@ CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &in m_arguments.push_back (type_arg); SetHelpLong( - "Some examples of using this command.\n" - "We use as reference the following snippet of code:\n" - "struct JustADemo\n" - "{\n" - "int* ptr;\n" - "float value;\n" - "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n" - "};\n" - "JustADemo object(42,3.14);\n" - "struct AnotherDemo : public JustADemo\n" - "{\n" - "uint8_t byte;\n" - "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n" - "};\n" - "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n" - "\n" - "type summary add --summary-string \"the answer is ${*var.ptr}\" JustADemo\n" - "when typing frame variable object you will get \"the answer is 42\"\n" - "type summary add --summary-string \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n" - "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n" - "\n" - "Alternatively, you could also say\n" - "type summary add --summary-string \"${var%V} -> ${*var}\" \"int *\"\n" - "and replace the above summary string with\n" - "type summary add --summary-string \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n" - "to obtain a similar result\n" - "\n" - "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n" - "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n" - "\n" - "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n" - "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n" - "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n" - "A similar option -r exists for references.\n" - "\n" - "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n" - "you can use the -c option, without giving any summary string:\n" - "type summary add -c JustADemo\n" - "frame variable object\n" - "the output being similar to (ptr=0xsomeaddress, value=3.14)\n" - "\n" - "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n" - "type summary add -e --summary-string \"*ptr = ${*var.ptr}\" JustADemo\n" - "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n" - "to get an output like:\n" - "\n" - "*ptr = 42 {\n" - " ptr = 0xsomeaddress\n" - " value = 3.14\n" - "}\n" - "\n" - "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables" - "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your" - "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n" - "type summary add JustADemo -o \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n" - "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with " - "the word DONE on a line by itself to mark you're finished editing your code:\n" - "(lldb)type summary add JustADemo -P\n" - " value = valobj.GetChildMemberWithName('value');\n" - " return 'My value is ' + value.GetValue();\n" - "DONE\n" - "(lldb) <-- type further LLDB commands here\n" - ); +R"( +The following examples of 'type summary add' refer to this code snippet for context: + + struct JustADemo + { + int* ptr; + float value; + JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {} + }; + JustADemo demo_instance(42, 3.14); + + typedef JustADemo NewDemo; + NewDemo new_demo_instance(42, 3.14); + +(lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo + + Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42" + +(lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo + + Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14" + +)" "Alternatively, you could define formatting for all pointers to integers and \ +rely on that when formatting JustADemo to obtain the same result:" R"( + +(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *" +(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo + +)" "Type summaries are automatically applied to derived typedefs, so the examples \ +above apply to both JustADemo and NewDemo. The cascade option can be used to \ +suppress this behavior:" R"( + +(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no + + The summary will now be used for values of JustADemo but not NewDemo. + +)" "By default summaries are shown for pointers and references to values of the \ +specified type. To suppress formatting for pointers use the -p option, or apply \ +the corresponding -r option to suppress formatting for references:" R"( + +(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo + +)" "One-line summaries including all fields in a type can be inferred without supplying an \ +explicit summary string by passing the -c option:" R"( + +(lldb) type summary add -c JustADemo +(lldb) frame variable demo_instance +(ptr=<address>, value=3.14) + +)" "Type summaries normally suppress the nested display of individual fields. To \ +supply a summary to supplement the default structure add the -e option:" R"( + +(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo + +)" "Now when displaying JustADemo values the int* is displayed, followed by the \ +standard LLDB sequence of children, one per line:" R"( + +*ptr = 42 { + ptr = <address> + value = 3.14 +} + +)" "You can also add summaries written in Python. These scripts use lldb public API to \ +gather information from your variables and produce a meaningful summary. To start a \ +multi-line script use the -P option. The function declaration will be displayed along with \ +a comment describing the two arguments. End your script with the word 'DONE' on a line by \ +itself:" R"( + +(lldb) type summary add JustADemo -P +def function (valobj,internal_dict): +"""valobj: an SBValue which you want to provide a summary for +internal_dict: an LLDB support object not to be used""" + value = valobj.GetChildMemberWithName('value'); + return 'My value is ' + value.GetValue(); + DONE + +Alternatively, the -o option can be used when providing a simple one-line Python script: + +(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")" + ); } bool @@ -4117,31 +4142,37 @@ public: m_arguments.push_back (type_arg); SetHelpLong( - "Some examples of using this command.\n" - "We use as reference the following snippet of code:\n" - "\n" - "class Foo {;\n" - " int a;\n" - " int b;\n" - " int c;\n" - " int d;\n" - " int e;\n" - " int f;\n" - " int g;\n" - " int h;\n" - " int i;\n" - "} \n" - "Typing:\n" - "type filter add --child a --child g Foo\n" - "frame variable a_foo\n" - "will produce an output where only a and g are displayed\n" - "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n" - "frame variable a_foo.b a_foo.c ... a_foo.i\n" - "\n" - "Use option --raw to frame variable prevails on the filter\n" - "frame variable a_foo --raw\n" - "shows all the children of a_foo (a thru i) as if no filter was defined\n" - ); +R"( +The following examples of 'type filter add' refer to this code snippet for context: + + class Foo { + int a; + int b; + int c; + int d; + int e; + int f; + int g; + int h; + int i; + } + Foo my_foo; + +Adding a simple filter: + +(lldb) type filter add --child a --child g Foo +(lldb) frame variable my_foo + +)" "Produces output where only a and g are displayed. Other children of my_foo \ +(b, c, d, e, f, h and i) are available by asking for them explicitly:" R"( + +(lldb) frame variable my_foo.b my_foo.c my_foo.i + +)" "The formatting option --raw on frame variable bypasses the filter, showing \ +all children of my_foo as if no filter was defined:" R"( + +(lldb) frame variable my_foo --raw)" + ); } ~CommandObjectTypeFilterAdd () diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp index 650fd253af02..414e78403cc8 100644 --- a/source/Commands/CommandObjectWatchpoint.cpp +++ b/source/Commands/CommandObjectWatchpoint.cpp @@ -931,10 +931,14 @@ public: m_option_watchpoint () { SetHelpLong( - "Examples: \n\ - \n\ - watchpoint set variable -w read_write my_global_var \n\ - # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n"); +R"( +Examples: + +(lldb) watchpoint set variable -w read_write my_global_var + +)" " Watches my_global_var for read/write access, with the region to watch \ +corresponding to the byte size of the data type." + ); CommandArgumentEntry arg; CommandArgumentData var_name_arg; @@ -1138,10 +1142,13 @@ public: m_option_watchpoint () { SetHelpLong( - "Examples: \n\ - \n\ - watchpoint set expression -w write -x 1 -- foo + 32\n\ - # Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n"); +R"( +Examples: + +(lldb) watchpoint set expression -w write -x 1 -- foo + 32 + + Watches write access for the 1-byte region pointed to by the address 'foo + 32')" + ); CommandArgumentEntry arg; CommandArgumentData expression_arg; diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp index d7d064e5fed9..84342cc8ffdf 100644 --- a/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/source/Commands/CommandObjectWatchpointCommand.cpp @@ -48,121 +48,112 @@ public: m_options (interpreter) { SetHelpLong ( -"\nGeneral information about entering watchpoint commands \n\ ------------------------------------------------------- \n\ - \n\ -This command will cause you to be prompted to enter the command or set \n\ -of commands you wish to be executed when the specified watchpoint is \n\ -hit. You will be told to enter your command(s), and will see a '> ' \n\ -prompt. Because you can enter one or many commands to be executed when \n\ -a watchpoint is hit, you will continue to be prompted after each \n\ -new-line that you enter, until you enter the word 'DONE', which will \n\ -cause the commands you have entered to be stored with the watchpoint \n\ -and executed when the watchpoint is hit. \n\ - \n\ -Syntax checking is not necessarily done when watchpoint commands are \n\ -entered. An improperly written watchpoint command will attempt to get \n\ -executed when the watchpoint gets hit, and usually silently fail. If \n\ -your watchpoint command does not appear to be getting executed, go \n\ -back and check your syntax. \n\ - \n\ - \n\ -Special information about PYTHON watchpoint commands \n\ ----------------------------------------------------- \n\ - \n\ -You may enter either one line of Python or multiple lines of Python \n\ -(including defining whole functions, if desired). If you enter a \n\ -single line of Python, that will be passed to the Python interpreter \n\ -'as is' when the watchpoint gets hit. If you enter function \n\ -definitions, they will be passed to the Python interpreter as soon as \n\ -you finish entering the watchpoint command, and they can be called \n\ -later (don't forget to add calls to them, if you want them called when \n\ -the watchpoint is hit). If you enter multiple lines of Python that \n\ -are not function definitions, they will be collected into a new, \n\ -automatically generated Python function, and a call to the newly \n\ -generated function will be attached to the watchpoint. \n\ - \n\ -This auto-generated function is passed in two arguments: \n\ - \n\ - frame: an SBFrame object representing the frame which hit the watchpoint. \n\ - From the frame you can get back to the thread and process. \n\ - wp: the watchpoint that was hit. \n\ - \n\ -Important Note: Because loose Python code gets collected into functions, \n\ -if you want to access global variables in the 'loose' code, you need to \n\ -specify that they are global, using the 'global' keyword. Be sure to \n\ -use correct Python syntax, including indentation, when entering Python \n\ -watchpoint commands. \n\ - \n\ -As a third option, you can pass the name of an already existing Python function \n\ -and that function will be attached to the watchpoint. It will get passed the \n\ -frame and wp_loc arguments mentioned above. \n\ - \n\ -Example Python one-line watchpoint command: \n\ - \n\ -(lldb) watchpoint command add -s python 1 \n\ -Enter your Python command(s). Type 'DONE' to end. \n\ -> print \"Hit this watchpoint!\" \n\ -> DONE \n\ - \n\ -As a convenience, this also works for a short Python one-liner: \n\ -(lldb) watchpoint command add -s python 1 -o \"import time; print time.asctime()\" \n\ -(lldb) run \n\ -Launching '.../a.out' (x86_64) \n\ -(lldb) Fri Sep 10 12:17:45 2010 \n\ -Process 21778 Stopped \n\ -* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = watchpoint 1.1, queue = com.apple.main-thread \n\ - 36 \n\ - 37 int c(int val)\n\ - 38 {\n\ - 39 -> return val + 3;\n\ - 40 }\n\ - 41 \n\ - 42 int main (int argc, char const *argv[])\n\ -(lldb) \n\ - \n\ -Example multiple line Python watchpoint command, using function definition: \n\ - \n\ -(lldb) watchpoint command add -s python 1 \n\ -Enter your Python command(s). Type 'DONE' to end. \n\ -> def watchpoint_output (wp_no): \n\ -> out_string = \"Hit watchpoint number \" + repr (wp_no) \n\ -> print out_string \n\ -> return True \n\ -> watchpoint_output (1) \n\ -> DONE \n\ - \n\ - \n\ -Example multiple line Python watchpoint command, using 'loose' Python: \n\ - \n\ -(lldb) watchpoint command add -s p 1 \n\ -Enter your Python command(s). Type 'DONE' to end. \n\ -> global wp_count \n\ -> wp_count = wp_count + 1 \n\ -> print \"Hit this watchpoint \" + repr(wp_count) + \" times!\" \n\ -> DONE \n\ - \n\ -In this case, since there is a reference to a global variable, \n\ -'wp_count', you will also need to make sure 'wp_count' exists and is \n\ -initialized: \n\ - \n\ -(lldb) script \n\ ->>> wp_count = 0 \n\ ->>> quit() \n\ - \n\ -(lldb) \n\ - \n\ - \n\ -Final Note: If you get a warning that no watchpoint command was generated, \n\ -but you did not get any syntax errors, you probably forgot to add a call \n\ -to your functions. \n\ - \n\ -Special information about debugger command watchpoint commands \n\ --------------------------------------------------------------- \n\ - \n\ -You may enter any debugger command, exactly as you would at the \n\ -debugger prompt. You may enter as many debugger commands as you like, \n\ -but do NOT enter more than one command per line. \n" ); +R"( +General information about entering watchpoint commands +------------------------------------------------------ + +)" "This command will prompt for commands to be executed when the specified \ +watchpoint is hit. Each command is typed on its own line following the '> ' \ +prompt until 'DONE' is entered." R"( + +)" "Syntactic errors may not be detected when initially entered, and many \ +malformed commands can silently fail when executed. If your watchpoint commands \ +do not appear to be executing, double-check the command syntax." R"( + +)" "Note: You may enter any debugger command exactly as you would at the debugger \ +prompt. There is no limit to the number of commands supplied, but do NOT enter \ +more than one command per line." R"( + +Special information about PYTHON watchpoint commands +---------------------------------------------------- + +)" "You may enter either one or more lines of Python, including function \ +definitions or calls to functions that will have been imported by the time \ +the code executes. Single line watchpoint commands will be interpreted 'as is' \ +when the watchpoint is hit. Multiple lines of Python will be wrapped in a \ +generated function, and a call to the function will be attached to the watchpoint." R"( + +This auto-generated function is passed in three arguments: + + frame: an lldb.SBFrame object for the frame which hit the watchpoint. + + wp: the watchpoint that was hit. + +)" "When specifying a python function with the --python-function option, you need \ +to supply the function name prepended by the module name:" R"( + + --python-function myutils.watchpoint_callback + +The function itself must have the following prototype: + +def watchpoint_callback(frame, wp): + # Your code goes here + +)" "The arguments are the same as the arguments passed to generated functions as \ +described above. Note that the global variable 'lldb.frame' will NOT be updated when \ +this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ +can get you to the thread via frame.GetThread(), the thread can get you to the \ +process via thread.GetProcess(), and the process can get you back to the target \ +via process.GetTarget()." R"( + +)" "Important Note: As Python code gets collected into functions, access to global \ +variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ +Python syntax, including indentation, when entering Python watchpoint commands." R"( + +Example Python one-line watchpoint command: + +(lldb) watchpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> print "Hit this watchpoint!" +> DONE + +As a convenience, this also works for a short Python one-liner: + +(lldb) watchpoint command add -s python 1 -o 'import time; print time.asctime()' +(lldb) run +Launching '.../a.out' (x86_64) +(lldb) Fri Sep 10 12:17:45 2010 +Process 21778 Stopped +* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = watchpoint 1.1, queue = com.apple.main-thread + 36 + 37 int c(int val) + 38 { + 39 -> return val + 3; + 40 } + 41 + 42 int main (int argc, char const *argv[]) + +Example multiple line Python watchpoint command, using function definition: + +(lldb) watchpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> def watchpoint_output (wp_no): +> out_string = "Hit watchpoint number " + repr (wp_no) +> print out_string +> return True +> watchpoint_output (1) +> DONE + +Example multiple line Python watchpoint command, using 'loose' Python: + +(lldb) watchpoint command add -s p 1 +Enter your Python command(s). Type 'DONE' to end. +> global wp_count +> wp_count = wp_count + 1 +> print "Hit this watchpoint " + repr(wp_count) + " times!" +> DONE + +)" "In this case, since there is a reference to a global variable, \ +'wp_count', you will also need to make sure 'wp_count' exists and is \ +initialized:" R"( + +(lldb) script +>>> wp_count = 0 +>>> quit() + +)" "Final Note: A warning that no watchpoint command was generated when there \ +are no syntax errors may indicate that a function was declared but never called." + ); CommandArgumentEntry arg; CommandArgumentData wp_id_arg; diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp index 33cbede9ce14..36344307743e 100644 --- a/source/Core/ArchSpec.cpp +++ b/source/Core/ArchSpec.cpp @@ -887,20 +887,15 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su } else if (arch_type == eArchTypeELF) { - llvm::Triple::OSType ostype; switch (os) { - case llvm::ELF::ELFOSABI_AIX: ostype = llvm::Triple::OSType::AIX; break; - case llvm::ELF::ELFOSABI_FREEBSD: ostype = llvm::Triple::OSType::FreeBSD; break; - case llvm::ELF::ELFOSABI_GNU: ostype = llvm::Triple::OSType::Linux; break; - case llvm::ELF::ELFOSABI_NETBSD: ostype = llvm::Triple::OSType::NetBSD; break; - case llvm::ELF::ELFOSABI_OPENBSD: ostype = llvm::Triple::OSType::OpenBSD; break; - case llvm::ELF::ELFOSABI_SOLARIS: ostype = llvm::Triple::OSType::Solaris; break; - default: - ostype = llvm::Triple::OSType::UnknownOS; + case llvm::ELF::ELFOSABI_AIX: m_triple.setOS (llvm::Triple::OSType::AIX); break; + case llvm::ELF::ELFOSABI_FREEBSD: m_triple.setOS (llvm::Triple::OSType::FreeBSD); break; + case llvm::ELF::ELFOSABI_GNU: m_triple.setOS (llvm::Triple::OSType::Linux); break; + case llvm::ELF::ELFOSABI_NETBSD: m_triple.setOS (llvm::Triple::OSType::NetBSD); break; + case llvm::ELF::ELFOSABI_OPENBSD: m_triple.setOS (llvm::Triple::OSType::OpenBSD); break; + case llvm::ELF::ELFOSABI_SOLARIS: m_triple.setOS (llvm::Triple::OSType::Solaris); break; } - m_triple.setOS (ostype); - m_triple.setVendor (llvm::Triple::UnknownVendor); } // Fall back onto setting the machine type if the arch by name failed... if (m_triple.getArch () == llvm::Triple::UnknownArch) @@ -1186,11 +1181,46 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in } break; + case ArchSpec::eCore_mips32: + if (!enforce_exact_match) + { + if (core2 >= ArchSpec::kCore_mips32_first && core2 <= ArchSpec::kCore_mips32_last) + return true; + try_inverse = false; + } + break; + + case ArchSpec::eCore_mips32el: + if (!enforce_exact_match) + { + if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= ArchSpec::kCore_mips32el_last) + return true; + try_inverse = false; + } + case ArchSpec::eCore_mips64: + if (!enforce_exact_match) + { + if (core2 >= ArchSpec::kCore_mips32_first && core2 <= ArchSpec::kCore_mips32_last) + return true; + if (core2 >= ArchSpec::kCore_mips64_first && core2 <= ArchSpec::kCore_mips64_last) + return true; + try_inverse = false; + } + + case ArchSpec::eCore_mips64el: + if (!enforce_exact_match) + { + if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= ArchSpec::kCore_mips32el_last) + return true; + if (core2 >= ArchSpec::kCore_mips64el_first && core2 <= ArchSpec::kCore_mips64el_last) + return true; + try_inverse = false; + } + case ArchSpec::eCore_mips64r2: case ArchSpec::eCore_mips64r3: case ArchSpec::eCore_mips64r5: - case ArchSpec::eCore_mips64r6: if (!enforce_exact_match) { if (core2 >= ArchSpec::kCore_mips32_first && core2 <= (core1 - 10)) @@ -1201,11 +1231,9 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in } break; - case ArchSpec::eCore_mips64el: case ArchSpec::eCore_mips64r2el: case ArchSpec::eCore_mips64r3el: case ArchSpec::eCore_mips64r5el: - case ArchSpec::eCore_mips64r6el: if (!enforce_exact_match) { if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= (core1 - 10)) @@ -1216,6 +1244,63 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in } break; + case ArchSpec::eCore_mips32r2: + case ArchSpec::eCore_mips32r3: + case ArchSpec::eCore_mips32r5: + if (!enforce_exact_match) + { + if (core2 >= ArchSpec::kCore_mips32_first && core2 <= core1) + return true; + } + break; + + case ArchSpec::eCore_mips32r2el: + case ArchSpec::eCore_mips32r3el: + case ArchSpec::eCore_mips32r5el: + if (!enforce_exact_match) + { + if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= core1) + return true; + } + break; + + case ArchSpec::eCore_mips32r6: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6) + return true; + } + break; + + case ArchSpec::eCore_mips32r6el: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el) + return true; + return true; + } + break; + + case ArchSpec::eCore_mips64r6: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6) + return true; + if (core2 == ArchSpec::eCore_mips64 || core2 == ArchSpec::eCore_mips64r6) + return true; + } + break; + + case ArchSpec::eCore_mips64r6el: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el) + return true; + if (core2 == ArchSpec::eCore_mips64el || core2 == ArchSpec::eCore_mips64r6el) + return true; + } + break; + default: break; } diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp index b4b43ed97780..861bece98da9 100644 --- a/source/Core/DataExtractor.cpp +++ b/source/Core/DataExtractor.cpp @@ -1830,26 +1830,14 @@ DataExtractor::Dump (Stream *s, } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) { + const auto &semantics = ast->getFloatTypeSemantics(ast->LongDoubleTy); + const auto byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; + llvm::APInt apint; - switch (target_sp->GetArchitecture().GetMachine()) + if (GetAPInt(*this, &offset, byte_size, apint)) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - // clang will assert when constructing the apfloat if we use a 16 byte integer value - if (GetAPInt (*this, &offset, 10, apint)) - { - llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint); - apfloat.toString(sv, format_precision, format_max_padding); - } - break; - - default: - if (GetAPInt (*this, &offset, item_byte_size, apint)) - { - llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint); - apfloat.toString(sv, format_precision, format_max_padding); - } - break; + llvm::APFloat apfloat(semantics, apint); + apfloat.toString(sv, format_precision, format_max_padding); } } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp index 2ebe95747bc0..e89d6c9cb4a9 100644 --- a/source/Core/FormatEntity.cpp +++ b/source/Core/FormatEntity.cpp @@ -1666,7 +1666,7 @@ FormatEntity::Format (const Entry &entry, if (inline_info) { s.PutCString(" [inlined] "); - inline_info->GetName().Dump(&s); + inline_info->GetName(sc->function->GetLanguage()).Dump(&s); } } } @@ -1679,9 +1679,9 @@ FormatEntity::Format (const Entry &entry, { ConstString name; if (sc->function) - name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments); + name = sc->function->GetNameNoArguments(); else if (sc->symbol) - name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments); + name = sc->symbol->GetNameNoArguments(); if (name) { s.PutCString(name.GetCString()); @@ -1724,7 +1724,7 @@ FormatEntity::Format (const Entry &entry, { s.PutCString (cstr); s.PutCString (" [inlined] "); - cstr = inline_info->GetName().GetCString(); + cstr = inline_info->GetName(sc->function->GetLanguage()).GetCString(); } VariableList args; diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index 3e1a8bb89139..a1916fe913c4 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -66,7 +66,7 @@ cstring_is_mangled(const char *s) } static const ConstString & -get_demangled_name_without_arguments (const Mangled *obj) +get_demangled_name_without_arguments (ConstString mangled, ConstString demangled) { // This pair is <mangled name, demangled name without function arguments> static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args; @@ -77,9 +77,6 @@ get_demangled_name_without_arguments (const Mangled *obj) static ConstString g_last_mangled; static ConstString g_last_demangled; - ConstString mangled = obj->GetMangledName (); - ConstString demangled = obj->GetDemangledName (); - if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) { return g_most_recent_mangled_to_name_sans_args.second; @@ -197,7 +194,7 @@ Mangled::Clear () int Mangled::Compare (const Mangled& a, const Mangled& b) { - return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled)); + return ConstString::Compare(a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); } @@ -261,7 +258,7 @@ Mangled::SetValue (const ConstString &name) // object's lifetime. //---------------------------------------------------------------------- const ConstString& -Mangled::GetDemangledName () const +Mangled::GetDemangledName (lldb::LanguageType language) const { // Check to make sure we have a valid mangled name and that we // haven't already decoded our mangled name. @@ -339,13 +336,20 @@ Mangled::GetDemangledName () const } +ConstString +Mangled::GetDisplayDemangledName (lldb::LanguageType language) const +{ + return GetDemangledName(language); +} + bool -Mangled::NameMatches (const RegularExpression& regex) const +Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType language) const { if (m_mangled && regex.Execute (m_mangled.AsCString())) return true; - - if (GetDemangledName() && regex.Execute (m_demangled.AsCString())) + + ConstString demangled = GetDemangledName(language); + if (demangled && regex.Execute (demangled.AsCString())) return true; return false; } @@ -353,30 +357,28 @@ Mangled::NameMatches (const RegularExpression& regex) const //---------------------------------------------------------------------- // Get the demangled name if there is one, else return the mangled name. //---------------------------------------------------------------------- -const ConstString& -Mangled::GetName (Mangled::NamePreference preference) const +ConstString +Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preference) const { + ConstString demangled = GetDemangledName(language); + if (preference == ePreferDemangledWithoutArguments) { - // Call the accessor to make sure we get a demangled name in case - // it hasn't been demangled yet... - GetDemangledName(); - - return get_demangled_name_without_arguments (this); + return get_demangled_name_without_arguments (m_mangled, demangled); } if (preference == ePreferDemangled) { // Call the accessor to make sure we get a demangled name in case // it hasn't been demangled yet... - if (GetDemangledName()) - return m_demangled; + if (demangled) + return demangled; return m_mangled; } else { if (m_mangled) return m_mangled; - return GetDemangledName(); + return demangled; } } @@ -429,7 +431,7 @@ Mangled::GuessLanguage () const ConstString mangled = GetMangledName(); if (mangled) { - if (GetDemangledName()) + if (GetDemangledName(lldb::eLanguageTypeUnknown)) { if (cstring_is_mangled(mangled.GetCString())) return lldb::eLanguageTypeC_plus_plus; @@ -447,7 +449,7 @@ operator << (Stream& s, const Mangled& obj) if (obj.GetMangledName()) s << "mangled = '" << obj.GetMangledName() << "'"; - const ConstString& demangled = obj.GetDemangledName(); + const ConstString& demangled = obj.GetDemangledName(lldb::eLanguageTypeUnknown); if (demangled) s << ", demangled = '" << demangled << '\''; else diff --git a/source/Core/StructuredData.cpp b/source/Core/StructuredData.cpp index a2c440948af1..efc104f1f3e8 100644 --- a/source/Core/StructuredData.cpp +++ b/source/Core/StructuredData.cpp @@ -14,301 +14,148 @@ #include <inttypes.h> #include "lldb/Core/StreamString.h" +#include "lldb/Host/StringConvert.h" +#include "lldb/Utility/JSON.h" using namespace lldb_private; -static StructuredData::ObjectSP read_json_object (const char **ch); -static StructuredData::ObjectSP read_json_array (const char **ch); +//---------------------------------------------------------------------- +// Functions that use a JSONParser to parse JSON into StructuredData +//---------------------------------------------------------------------- +static StructuredData::ObjectSP ParseJSONValue (JSONParser &json_parser); +static StructuredData::ObjectSP ParseJSONObject (JSONParser &json_parser); +static StructuredData::ObjectSP ParseJSONArray (JSONParser &json_parser); static StructuredData::ObjectSP -read_json_number (const char **ch) +ParseJSONObject (JSONParser &json_parser) { - StructuredData::ObjectSP object_sp; - while (isspace (**ch)) - (*ch)++; - const char *start_of_number = *ch; - bool is_integer = true; - bool is_float = false; - while (isdigit(**ch) || **ch == '-' || **ch == '.' || **ch == '+' || **ch == 'e' || **ch == 'E') - { - if (isdigit(**ch) == false && **ch != '-') - { - is_integer = false; - is_float = true; - } - (*ch)++; - } - while (isspace (**ch)) - (*ch)++; - if (**ch == ',' || **ch == ']' || **ch == '}') + // The "JSONParser::Token::ObjectStart" token should have already been consumed + // by the time this function is called + std::unique_ptr<StructuredData::Dictionary> dict_up(new StructuredData::Dictionary()); + + std::string value; + std::string key; + while (1) { - if (is_integer) + JSONParser::Token token = json_parser.GetToken(value); + + if (token == JSONParser::Token::String) { - errno = 0; - uint64_t val = strtoul (start_of_number, NULL, 10); - if (errno == 0) + key.swap(value); + token = json_parser.GetToken(value); + if (token == JSONParser::Token::Colon) { - object_sp.reset(new StructuredData::Integer()); - object_sp->GetAsInteger()->SetValue (val); + StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); + if (value_sp) + dict_up->AddItem(key, value_sp); + else + break; } } - if (is_float) + else if (token == JSONParser::Token::ObjectEnd) { - char *end_of_number = NULL; - errno = 0; - double val = strtod (start_of_number, &end_of_number); - if (errno == 0 && end_of_number != start_of_number && end_of_number != NULL) - { - object_sp.reset(new StructuredData::Float()); - object_sp->GetAsFloat()->SetValue (val); - } + return StructuredData::ObjectSP(dict_up.release()); } - } - return object_sp; -} - -static std::string -read_json_string (const char **ch) -{ - std::string string; - if (**ch == '"') - { - (*ch)++; - while (**ch != '\0') + else if (token == JSONParser::Token::Comma) { - if (**ch == '"') - { - (*ch)++; - while (isspace (**ch)) - (*ch)++; - break; - } - else if (**ch == '\\') - { - switch (**ch) - { - case '"': - string.push_back('"'); - *ch += 2; - break; - case '\\': - string.push_back('\\'); - *ch += 2; - break; - case '/': - string.push_back('/'); - *ch += 2; - break; - case 'b': - string.push_back('\b'); - *ch += 2; - break; - case 'f': - string.push_back('\f'); - *ch += 2; - break; - case 'n': - string.push_back('\n'); - *ch += 2; - break; - case 'r': - string.push_back('\r'); - *ch += 2; - break; - case 't': - string.push_back('\t'); - *ch += 2; - break; - case 'u': - // FIXME handle four-hex-digits - *ch += 10; - break; - default: - *ch += 1; - } - } - else - { - string.push_back (**ch); - } - (*ch)++; + continue; + } + else + { + break; } } - return string; + return StructuredData::ObjectSP(); } static StructuredData::ObjectSP -read_json_value (const char **ch) +ParseJSONArray (JSONParser &json_parser) { - StructuredData::ObjectSP object_sp; - while (isspace (**ch)) - (*ch)++; + // The "JSONParser::Token::ObjectStart" token should have already been consumed + // by the time this function is called + std::unique_ptr<StructuredData::Array> array_up(new StructuredData::Array()); - if (**ch == '{') - { - object_sp = read_json_object (ch); - } - else if (**ch == '[') + std::string value; + std::string key; + while (1) { - object_sp = read_json_array (ch); - } - else if (**ch == '"') - { - std::string string = read_json_string (ch); - object_sp.reset(new StructuredData::String()); - object_sp->GetAsString()->SetValue(string); - } - else - { - if (strncmp (*ch, "true", 4) == 0) - { - object_sp.reset(new StructuredData::Boolean()); - object_sp->GetAsBoolean()->SetValue(true); - *ch += 4; - } - else if (strncmp (*ch, "false", 5) == 0) + StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); + if (value_sp) + array_up->AddItem(value_sp); + else + break; + + JSONParser::Token token = json_parser.GetToken(value); + if (token == JSONParser::Token::Comma) { - object_sp.reset(new StructuredData::Boolean()); - object_sp->GetAsBoolean()->SetValue(false); - *ch += 5; + continue; } - else if (strncmp (*ch, "null", 4) == 0) + else if (token == JSONParser::Token::ArrayEnd) { - object_sp.reset(new StructuredData::Null()); - *ch += 4; + return StructuredData::ObjectSP(array_up.release()); } else { - object_sp = read_json_number (ch); + break; } } - return object_sp; + return StructuredData::ObjectSP(); } static StructuredData::ObjectSP -read_json_array (const char **ch) +ParseJSONValue (JSONParser &json_parser) { - StructuredData::ObjectSP object_sp; - if (**ch == '[') + std::string value; + const JSONParser::Token token = json_parser.GetToken(value); + switch (token) { - (*ch)++; - while (isspace (**ch)) - (*ch)++; + case JSONParser::Token::ObjectStart: + return ParseJSONObject(json_parser); - bool first_value = true; - while (**ch != '\0' && (first_value || **ch == ',')) - { - if (**ch == ',') - (*ch)++; - first_value = false; - while (isspace (**ch)) - (*ch)++; - lldb_private::StructuredData::ObjectSP value_sp = read_json_value (ch); - if (value_sp) + case JSONParser::Token::ArrayStart: + return ParseJSONArray(json_parser); + + case JSONParser::Token::Integer: { - if (object_sp.get() == NULL) - { - object_sp.reset(new StructuredData::Array()); - } - object_sp->GetAsArray()->Push (value_sp); + bool success = false; + uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); + if (success) + return StructuredData::ObjectSP(new StructuredData::Integer(uval)); } - while (isspace (**ch)) - (*ch)++; - } - if (**ch == ']') - { - // FIXME should throw an error if we don't see a } to close out the JSON object - (*ch)++; - while (isspace (**ch)) - (*ch)++; - } - } - return object_sp; -} + break; -static StructuredData::ObjectSP -read_json_object (const char **ch) -{ - StructuredData::ObjectSP object_sp; - if (**ch == '{') - { - (*ch)++; - while (isspace (**ch)) - (*ch)++; - bool first_pair = true; - while (**ch != '\0' && (first_pair || **ch == ',')) - { - first_pair = false; - if (**ch == ',') - (*ch)++; - while (isspace (**ch)) - (*ch)++; - if (**ch != '"') - break; - std::string key_string = read_json_string (ch); - while (isspace (**ch)) - (*ch)++; - if (key_string.size() > 0 && **ch == ':') + case JSONParser::Token::Float: { - (*ch)++; - while (isspace (**ch)) - (*ch)++; - lldb_private::StructuredData::ObjectSP value_sp = read_json_value (ch); - if (value_sp.get()) - { - if (object_sp.get() == NULL) - { - object_sp.reset(new StructuredData::Dictionary()); - } - object_sp->GetAsDictionary()->AddItem (key_string.c_str(), value_sp); - } + bool success = false; + double val = StringConvert::ToDouble(value.c_str(), 0.0, &success); + if (success) + return StructuredData::ObjectSP(new StructuredData::Float(val)); } - while (isspace (**ch)) - (*ch)++; - } - if (**ch == '}') - { - // FIXME should throw an error if we don't see a } to close out the JSON object - (*ch)++; - while (isspace (**ch)) - (*ch)++; - } + break; + + case JSONParser::Token::String: + return StructuredData::ObjectSP(new StructuredData::String(value)); + + case JSONParser::Token::True: + case JSONParser::Token::False: + return StructuredData::ObjectSP(new StructuredData::Boolean(token == JSONParser::Token::True)); + + case JSONParser::Token::Null: + return StructuredData::ObjectSP(new StructuredData::Null()); + + default: + break; } - return object_sp; -} + return StructuredData::ObjectSP(); +} StructuredData::ObjectSP StructuredData::ParseJSON (std::string json_text) { - StructuredData::ObjectSP object_sp; - const size_t json_text_size = json_text.size(); - if (json_text_size > 0) - { - const char *start_of_json_text = json_text.c_str(); - const char *c = json_text.c_str(); - while (*c != '\0' && - static_cast<size_t>(c - start_of_json_text) <= json_text_size) - { - while (isspace (*c) && - static_cast<size_t>(c - start_of_json_text) < json_text_size) - c++; - if (*c == '{') - { - object_sp = read_json_object (&c); - } - else if (*c == '[') - { - object_sp = read_json_array (&c); - } - else - { - // We have bad characters here, this is likely an illegal JSON string. - return object_sp; - } - } - } + JSONParser json_parser(json_text.c_str()); + StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser); return object_sp; } @@ -395,7 +242,7 @@ StructuredData::Integer::Dump (Stream &s) const void StructuredData::Float::Dump (Stream &s) const { - s.Printf ("%lf", m_value); + s.Printf ("%lg", m_value); } void diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp index 47456ba5c45b..4e0fffbe6a1a 100644 --- a/source/DataFormatters/FormatManager.cpp +++ b/source/DataFormatters/FormatManager.cpp @@ -1608,6 +1608,26 @@ FormatManager::LoadHardcodedFormatters() } return nullptr; }); + m_hardcoded_summaries.push_back( + [](lldb_private::ValueObject& valobj, + lldb::DynamicValueType, + FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer { + static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags() + .SetCascades(true) + .SetDontShowChildren(true) + .SetHideItemNames(true) + .SetShowMembersOneLiner(true) + .SetSkipPointers(true) + .SetSkipReferences(false), + lldb_private::formatters::VectorTypeSummaryProvider, + "vector_type pointer summary provider")); + if (valobj.GetClangType().IsVectorType(nullptr, nullptr)) + { + if (fmt_mgr.GetCategory(fmt_mgr.m_vectortypes_category_name)->IsEnabled()) + return formatter_sp; + } + return nullptr; + }); } { // insert code to load synthetics here diff --git a/source/DataFormatters/VectorType.cpp b/source/DataFormatters/VectorType.cpp index 57bf696ba4fa..316d7b540bcd 100644 --- a/source/DataFormatters/VectorType.cpp +++ b/source/DataFormatters/VectorType.cpp @@ -7,9 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "lldb/DataFormatters/CXXFormatterFunctions.h" +#include "lldb/DataFormatters/VectorType.h" #include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/CXXFormatterFunctions.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTType.h" @@ -267,6 +268,51 @@ namespace lldb_private { } } +bool +lldb_private::formatters::VectorTypeSummaryProvider (ValueObject& valobj, + Stream& s, + const TypeSummaryOptions&) +{ + auto synthetic_children = VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP()); + if (!synthetic_children) + return false; + + synthetic_children->Update(); + + s.PutChar('('); + bool first = true; + + size_t idx = 0, len = synthetic_children->CalculateNumChildren(); + + for (; + idx < len; + idx++) + { + auto child_sp = synthetic_children->GetChildAtIndex(idx); + if (!child_sp) + continue; + child_sp = child_sp->GetQualifiedRepresentationIfAvailable(lldb::eDynamicDontRunTarget, true); + + const char* child_value = child_sp->GetValueAsCString(); + if (child_value && *child_value) + { + if (first) + { + s.Printf("%s", child_value); + first = false; + } + else + { + s.Printf(", %s", child_value); + } + } + } + + s.PutChar(')'); + + return true; +} + lldb_private::SyntheticChildrenFrontEnd* lldb_private::formatters::VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) { diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp index 1013bb540601..2c66a0aa4278 100644 --- a/source/Expression/ClangExpressionDeclMap.cpp +++ b/source/Expression/ClangExpressionDeclMap.cpp @@ -1527,6 +1527,31 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, context.m_found.function_with_type_info = true; context.m_found.function = true; } + else if (llvm::isa<clang::VarDecl>(decl_from_modules)) + { + if (log) + { + log->Printf(" CAS::FEVD[%u] Matching variable found for \"%s\" in the modules", + current_id, + name.GetCString()); + } + + clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules); + clang::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr; + + if (!copied_var_decl) + { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a variable declaration from the modules", + current_id); + + break; + } + + context.AddNamedDecl(copied_var_decl); + + context.m_found.variable = true; + } } } while (0); } diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp index 3d5350d34028..2b344b0c3733 100644 --- a/source/Expression/ClangExpressionParser.cpp +++ b/source/Expression/ClangExpressionParser.cpp @@ -541,10 +541,11 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule()); Error interpret_error; + Process *process = exe_ctx.GetProcessPtr(); - can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error); + bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls(); + can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error, interpret_function_calls); - Process *process = exe_ctx.GetProcessPtr(); if (!ir_can_run) { diff --git a/source/Expression/ClangModulesDeclVendor.cpp b/source/Expression/ClangModulesDeclVendor.cpp index 97a4d088b982..e8253630724a 100644 --- a/source/Expression/ClangModulesDeclVendor.cpp +++ b/source/Expression/ClangModulesDeclVendor.cpp @@ -18,6 +18,7 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBAssert.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" @@ -444,18 +445,18 @@ ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVec } ssize_t found_priority = -1; - clang::MacroInfo *info = nullptr; + clang::MacroInfo *macro_info = nullptr; - for (clang::ModuleMacro *macro : m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) + for (clang::ModuleMacro *module_macro : m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) { - clang::Module *module = macro->getOwningModule(); + clang::Module *module = module_macro->getOwningModule(); { ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(module)); if (pi != module_priorities.end() && pi->second > found_priority) { - info = macro->getMacroInfo(); + macro_info = module_macro->getMacroInfo(); found_priority = pi->second; } } @@ -465,26 +466,20 @@ ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVec if (top_level_module != module) { ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(top_level_module)); - + if ((pi != module_priorities.end()) && pi->second > found_priority) { - info = macro->getMacroInfo(); + macro_info = module_macro->getMacroInfo(); found_priority = pi->second; } } } - if (!info) + if (macro_info) { - continue; - } - - if (mi->second.getLatest()->getKind() == clang::MacroDirective::MD_Define) - { std::string macro_expansion = "#define "; macro_expansion.append(mi->first->getName().str().c_str()); - - if (clang::MacroInfo *macro_info = mi->second.getLatest()->getMacroInfo()) + { if (macro_info->isFunctionLike()) { @@ -560,9 +555,7 @@ ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVec if (invalid) { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(!"Unhandled token kind"); -#endif + lldbassert(!"Unhandled token kind"); macro_expansion.append("<unknown literal value>"); } else @@ -594,17 +587,11 @@ ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVec } } } - } - else - { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(!"#define with no macro info"); -#endif - } - - if (handler(macro_expansion)) - { - return; + + if (handler(macro_expansion)) + { + return; + } } } } diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp index 661bab0e4b43..0da70e2b0a70 100644 --- a/source/Expression/ClangUserExpression.cpp +++ b/source/Expression/ClangUserExpression.cpp @@ -891,7 +891,8 @@ ClangUserExpression::Execute (Stream &error_stream, *m_execution_unit_sp.get(), interpreter_error, function_stack_bottom, - function_stack_top); + function_stack_top, + exe_ctx); if (!interpreter_error.Success()) { diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp index 7232685e4f41..59c7fb6f786f 100644 --- a/source/Expression/IRExecutionUnit.cpp +++ b/source/Expression/IRExecutionUnit.cpp @@ -373,7 +373,7 @@ IRExecutionUnit::GetRunnableInfo(Error &error, ss.PutCString("\n"); emitNewLine = true; ss.PutCString(" "); - ss.PutCString(Mangled(failed_lookup).GetDemangledName().AsCString()); + ss.PutCString(Mangled(failed_lookup).GetDemangledName(lldb::eLanguageTypeObjC_plus_plus).AsCString()); } m_failed_lookups.clear(); diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp index 11bc011d6d64..cf2a93b3ea7f 100644 --- a/source/Expression/IRForTarget.cpp +++ b/source/Expression/IRForTarget.cpp @@ -267,11 +267,11 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, { if (mangled_name.GetMangledName()) m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n", - mangled_name.GetName().GetCString(), + mangled_name.GetName(lldb::eLanguageTypeObjC_plus_plus).GetCString(), mangled_name.GetMangledName().GetCString()); else m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n", - mangled_name.GetName().GetCString()); + mangled_name.GetName(lldb::eLanguageTypeObjC_plus_plus).GetCString()); } return LookupResult::Fail; } diff --git a/source/Expression/IRInterpreter.cpp b/source/Expression/IRInterpreter.cpp index d11bdc1671b6..926d1f22b6aa 100644 --- a/source/Expression/IRInterpreter.cpp +++ b/source/Expression/IRInterpreter.cpp @@ -10,17 +10,28 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/Module.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Expression/IRInterpreter.h" #include "lldb/Host/Endian.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" + #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/raw_ostream.h" @@ -455,7 +466,8 @@ static const char *infinite_loop_error = "Interpreter ran for too m bool IRInterpreter::CanInterpret (llvm::Module &module, llvm::Function &function, - lldb_private::Error &error) + lldb_private::Error &error, + const bool support_function_calls) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -507,7 +519,7 @@ IRInterpreter::CanInterpret (llvm::Module &module, return false; } - if (!CanIgnoreCall(call_inst)) + if (!CanIgnoreCall(call_inst) && !support_function_calls) { if (log) log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str()); @@ -611,7 +623,8 @@ IRInterpreter::Interpret (llvm::Module &module, lldb_private::IRMemoryMap &memory_map, lldb_private::Error &error, lldb::addr_t stack_frame_bottom, - lldb::addr_t stack_frame_top) + lldb::addr_t stack_frame_top, + lldb_private::ExecutionContext &exe_ctx) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -668,29 +681,7 @@ IRInterpreter::Interpret (llvm::Module &module, { default: break; - case Instruction::Call: - { - const CallInst *call_inst = dyn_cast<CallInst>(inst); - - if (!call_inst) - { - if (log) - log->Printf("getOpcode() returns %s, but instruction is not a CallInst", inst->getOpcodeName()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } - if (!CanIgnoreCall(call_inst)) - { - if (log) - log->Printf("The interpreter shouldn't have accepted %s", PrintValue(call_inst).c_str()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } - } - break; case Instruction::Add: case Instruction::Sub: case Instruction::Mul: @@ -1476,6 +1467,242 @@ IRInterpreter::Interpret (llvm::Module &module, } } break; + case Instruction::Call: + { + const CallInst *call_inst = dyn_cast<CallInst>(inst); + + if (!call_inst) + { + if (log) + log->Printf("getOpcode() returns %s, but instruction is not a CallInst", inst->getOpcodeName()); + error.SetErrorToGenericError(); + error.SetErrorString(interpreter_internal_error); + return false; + } + + if (CanIgnoreCall(call_inst)) + break; + + // Get the return type + llvm::Type *returnType = call_inst->getType(); + if (returnType == nullptr) + { + error.SetErrorToGenericError(); + error.SetErrorString("unable to access return type"); + return false; + } + + // Work with void, integer and pointer return types + if (!returnType->isVoidTy() && + !returnType->isIntegerTy() && + !returnType->isPointerTy()) + { + error.SetErrorToGenericError(); + error.SetErrorString("return type is not supported"); + return false; + } + + // Check we can actually get a thread + if (exe_ctx.GetThreadPtr() == nullptr) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to acquire thread"); + return false; + } + + // Make sure we have a valid process + if (!exe_ctx.GetProcessPtr()) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to get the process"); + return false; + } + + // Find the address of the callee function + lldb_private::Scalar I; + const llvm::Value *val = call_inst->getCalledValue(); + + if (!frame.EvaluateValue(I, val, module)) + { + error.SetErrorToGenericError(); + error.SetErrorString("unable to get address of function"); + return false; + } + lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS)); + + lldb_private::StreamString error_stream; + lldb_private::EvaluateExpressionOptions options; + + // We generally receive a function pointer which we must dereference + llvm::Type* prototype = val->getType(); + if (!prototype->isPointerTy()) + { + error.SetErrorToGenericError(); + error.SetErrorString("call need function pointer"); + return false; + } + + // Dereference the function pointer + prototype = prototype->getPointerElementType(); + if (!(prototype->isFunctionTy() || prototype->isFunctionVarArg())) + { + error.SetErrorToGenericError(); + error.SetErrorString("call need function pointer"); + return false; + } + + // Find number of arguments + const int numArgs = call_inst->getNumArgOperands(); + + // We work with a fixed array of 16 arguments which is our upper limit + static lldb_private::ABI::CallArgument rawArgs[16]; + if (numArgs >= 16) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("function takes too many arguments"); + return false; + } + + // Push all function arguments to the argument list that will + // be passed to the call function thread plan + for (int i = 0; i < numArgs; i++) + { + // Get details of this argument + llvm::Value *arg_op = call_inst->getArgOperand(i); + llvm::Type *arg_ty = arg_op->getType(); + + // Ensure that this argument is an supported type + if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("argument %d must be integer type", i); + return false; + } + + // Extract the arguments value + lldb_private::Scalar tmp_op = 0; + if (!frame.EvaluateValue(tmp_op, arg_op, module)) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to evaluate argument %d", i); + return false; + } + + // Check if this is a string literal or constant string pointer + if (arg_ty->isPointerTy()) + { + // Pointer to just one type + assert(arg_ty->getNumContainedTypes() == 1); + + lldb::addr_t addr = tmp_op.ULongLong(); + size_t dataSize = 0; + + if (memory_map.GetAllocSize(addr, dataSize)) + { + // Create the required buffer + rawArgs[i].size = dataSize; + rawArgs[i].data_ap.reset(new uint8_t[dataSize + 1]); + + // Read string from host memory + memory_map.ReadMemory(rawArgs[i].data_ap.get(), addr, dataSize, error); + if (error.Fail()) + { + assert(!"we have failed to read the string from memory"); + return false; + } + // Add null terminator + rawArgs[i].data_ap[dataSize] = '\0'; + rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer; + } + else + { + assert(!"unable to locate host data for transfer to device"); + return false; + } + } + else /* if ( arg_ty->isPointerTy() ) */ + { + rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue; + // Get argument size in bytes + rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8; + // Push value into argument list for thread plan + rawArgs[i].value = tmp_op.ULongLong(); + } + + } + + // Pack the arguments into an llvm::array + llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs); + + // Setup a thread plan to call the target function + lldb::ThreadPlanSP call_plan_sp + ( + new lldb_private::ThreadPlanCallFunctionUsingABI + ( + exe_ctx.GetThreadRef(), + funcAddr, + *prototype, + *returnType, + args, + options + ) + ); + + // Check if the plan is valid + if (!call_plan_sp || !call_plan_sp->ValidatePlan(&error_stream)) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to make ThreadPlanCallFunctionUsingABI for 0x%llx", I.ULongLong()); + return false; + } + + exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); + + // Execute the actual function call thread plan + lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, error_stream); + + // Check that the thread plan completed successfully + if (res != lldb::ExpressionResults::eExpressionCompleted) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("ThreadPlanCallFunctionUsingABI failed"); + return false; + } + + exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); + + // Void return type + if (returnType->isVoidTy()) + { + // Cant assign to void types, so we leave the frame untouched + } + else + // Integer or pointer return type + if (returnType->isIntegerTy() || returnType->isPointerTy()) + { + // Get the encapsulated return value + lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject(); + + lldb_private::Scalar returnVal = -1; + lldb_private::ValueObject *vobj = retVal.get(); + + // Check if the return value is valid + if (vobj == nullptr || retVal.empty()) + { + error.SetErrorToGenericError(); + error.SetErrorStringWithFormat("unable to get the return value"); + return false; + } + + // Extract the return value as a integer + lldb_private::Value & value = vobj->GetValue(); + returnVal = value.GetScalar(); + + // Push the return value as the result + frame.AssignValue(inst, returnVal, module); + } + } + break; } ++frame.m_ii; diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp index a4fe7a968379..4733b16d5f1c 100644 --- a/source/Expression/IRMemoryMap.cpp +++ b/source/Expression/IRMemoryMap.cpp @@ -418,6 +418,32 @@ IRMemoryMap::Free (lldb::addr_t process_address, Error &error) m_allocations.erase(iter); } +bool +IRMemoryMap::GetAllocSize(lldb::addr_t address, size_t &size) +{ + AllocationMap::iterator iter = FindAllocation(address, size); + if (iter == m_allocations.end()) + return false; + + Allocation &al = iter->second; + + if (address > (al.m_process_start + al.m_size)) + { + size = 0; + return false; + } + + if (address > al.m_process_start) + { + int dif = address - al.m_process_start; + size = al.m_size - dif; + return true; + } + + size = al.m_size; + return true; +} + void IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error) { diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp index 20d6355e6195..94c78a015651 100644 --- a/source/Host/common/Host.cpp +++ b/source/Host/common/Host.cpp @@ -1070,13 +1070,9 @@ Host::SetCrashDescription (const char *description) #endif -#if !defined (__linux__) && !defined (__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined (__NetBSD__) - -const lldb_private::UnixSignalsSP& -Host::GetUnixSignals () +const UnixSignalsSP & +Host::GetUnixSignals() { - static UnixSignalsSP s_unix_signals_sp (new UnixSignals ()); + static const auto s_unix_signals_sp = UnixSignals::Create(HostInfo::GetArchitecture()); return s_unix_signals_sp; } - -#endif diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp index 35003f5d0207..818d69bdabdc 100644 --- a/source/Host/common/NativeProcessProtocol.cpp +++ b/source/Host/common/NativeProcessProtocol.cpp @@ -441,3 +441,25 @@ NativeProcessProtocol::Terminate () { // Default implementation does nothing. } + +#ifndef __linux__ +// These need to be implemented to support lldb-gdb-server on a given platform. Stubs are +// provided to make the rest of the code link on non-supported platforms. + +Error +NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp) +{ + llvm_unreachable("Platform has no NativeProcessProtocol support"); +} + +Error +NativeProcessProtocol::Attach (lldb::pid_t pid, + NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp) +{ + llvm_unreachable("Platform has no NativeProcessProtocol support"); +} + +#endif diff --git a/source/Host/common/StringConvert.cpp b/source/Host/common/StringConvert.cpp index 0a8e75f4b877..c4ff67515d4e 100644 --- a/source/Host/common/StringConvert.cpp +++ b/source/Host/common/StringConvert.cpp @@ -15,79 +15,103 @@ // Project includes #include "lldb/Host/StringConvert.h" -namespace lldb_private { - -namespace StringConvert { - -int32_t -ToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr) +namespace lldb_private { - if (s && s[0]) + namespace StringConvert { - char *end = nullptr; - const long sval = ::strtol (s, &end, base); - if (*end == '\0') + + int32_t + ToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr) { + if (s && s[0]) + { + char *end = nullptr; + const long sval = ::strtol (s, &end, base); + if (*end == '\0') + { + if (success_ptr) + *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN)); + return (int32_t)sval; // All characters were used, return the result + } + } if (success_ptr) - *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN)); - return (int32_t)sval; // All characters were used, return the result + *success_ptr = false; + return fail_value; } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} -uint32_t -ToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - const unsigned long uval = ::strtoul (s, &end, base); - if (*end == '\0') + uint32_t + ToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr) { + if (s && s[0]) + { + char *end = nullptr; + const unsigned long uval = ::strtoul (s, &end, base); + if (*end == '\0') + { + if (success_ptr) + *success_ptr = (uval <= UINT32_MAX); + return (uint32_t)uval; // All characters were used, return the result + } + } if (success_ptr) - *success_ptr = (uval <= UINT32_MAX); - return (uint32_t)uval; // All characters were used, return the result + *success_ptr = false; + return fail_value; } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} -int64_t -ToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - int64_t uval = ::strtoll (s, &end, base); - if (*end == '\0') + int64_t + ToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr) { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result + if (s && s[0]) + { + char *end = nullptr; + int64_t uval = ::strtoll (s, &end, base); + if (*end == '\0') + { + if (success_ptr) + *success_ptr = true; + return uval; // All characters were used, return the result + } + } + if (success_ptr) + *success_ptr = false; + return fail_value; } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} -uint64_t -ToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - uint64_t uval = ::strtoull (s, &end, base); - if (*end == '\0') + uint64_t + ToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr) { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result + if (s && s[0]) + { + char *end = nullptr; + uint64_t uval = ::strtoull (s, &end, base); + if (*end == '\0') + { + if (success_ptr) + *success_ptr = true; + return uval; // All characters were used, return the result + } + } + if (success_ptr) *success_ptr = false; + return fail_value; } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} -} + double + ToDouble (const char *s, double fail_value, bool *success_ptr) + { + if (s && s[0]) + { + char *end = nullptr; + double val = strtod (s, &end); + if (*end == '\0') + { + if (success_ptr) + *success_ptr = true; + return val; // All characters were used, return the result + } + } + if (success_ptr) + *success_ptr = false; + return fail_value; + } + } } diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp index 8b1c580af27d..7f8d7ae96e7a 100644 --- a/source/Host/freebsd/Host.cpp +++ b/source/Host/freebsd/Host.cpp @@ -40,8 +40,6 @@ #include "lldb/Utility/CleanUp.h" #include "lldb/Utility/NameMatches.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" - #include "llvm/Support/Host.h" extern "C" { @@ -277,13 +275,6 @@ Host::GetAuxvData(lldb_private::Process *process) return buf_sp; } -const UnixSignalsSP& -Host::GetUnixSignals () -{ - static const lldb_private::UnixSignalsSP s_unix_signals_sp (new FreeBSDSignals ()); - return s_unix_signals_sp; -} - Error Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) { diff --git a/source/Host/posix/MainLoopPosix.cpp b/source/Host/posix/MainLoopPosix.cpp new file mode 100644 index 000000000000..cb213b9b79f1 --- /dev/null +++ b/source/Host/posix/MainLoopPosix.cpp @@ -0,0 +1,193 @@ +//===-- MainLoopPosix.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/posix/MainLoopPosix.h" + +#include <vector> + +#include "lldb/Core/Error.h" + +using namespace lldb; +using namespace lldb_private; + +static sig_atomic_t g_signal_flags[NSIG]; + +static void +SignalHandler(int signo, siginfo_t *info, void *) +{ + assert(signo < NSIG); + g_signal_flags[signo] = 1; +} + + +MainLoopPosix::~MainLoopPosix() +{ + assert(m_read_fds.size() == 0); + assert(m_signals.size() == 0); +} + +MainLoopPosix::ReadHandleUP +MainLoopPosix::RegisterReadObject(const IOObjectSP &object_sp, const Callback &callback, Error &error) +{ + if (!object_sp || !object_sp->IsValid()) + { + error.SetErrorString("IO object is not valid."); + return nullptr; + } + + const bool inserted = m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second; + if (! inserted) + { + error.SetErrorStringWithFormat("File descriptor %d already monitored.", + object_sp->GetWaitableHandle()); + return nullptr; + } + + return CreateReadHandle(object_sp); +} + +// We shall block the signal, then install the signal handler. The signal will be unblocked in +// the Run() function to check for signal delivery. +MainLoopPosix::SignalHandleUP +MainLoopPosix::RegisterSignal(int signo, const Callback &callback, Error &error) +{ + if (m_signals.find(signo) != m_signals.end()) + { + error.SetErrorStringWithFormat("Signal %d already monitored.", signo); + return nullptr; + } + + SignalInfo info; + info.callback = callback; + struct sigaction new_action; + new_action.sa_sigaction = &SignalHandler; + new_action.sa_flags = SA_SIGINFO; + sigemptyset(&new_action.sa_mask); + sigaddset(&new_action.sa_mask, signo); + + sigset_t old_set; + if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) + { + error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n", ret); + return nullptr; + } + + info.was_blocked = sigismember(&old_set, signo); + if (sigaction(signo, &new_action, &info.old_action) == -1) + { + error.SetErrorToErrno(); + if (!info.was_blocked) + pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr); + return nullptr; + } + + m_signals.insert({signo, info}); + g_signal_flags[signo] = 0; + + return SignalHandleUP(new SignalHandle(*this, signo)); +} + +void +MainLoopPosix::UnregisterReadObject(const lldb::IOObjectSP &object_sp) +{ + bool erased = m_read_fds.erase(object_sp->GetWaitableHandle()); + (void) erased; + assert(erased); +} + +void +MainLoopPosix::UnregisterSignal(int signo) +{ + // We undo the actions of RegisterSignal on a best-effort basis. + auto it = m_signals.find(signo); + assert(it != m_signals.end()); + + sigaction(signo, &it->second.old_action, nullptr); + + sigset_t set; + sigemptyset(&set); + sigaddset(&set, signo); + pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set, nullptr); + + m_signals.erase(it); +} + +Error +MainLoopPosix::Run() +{ + std::vector<int> signals; + sigset_t sigmask; + std::vector<int> read_fds; + fd_set read_fd_set; + m_terminate_request = false; + + // run until termination or until we run out of things to listen to + while (! m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) + { + // To avoid problems with callbacks changing the things we're supposed to listen to, we + // will store the *real* list of events separately. + signals.clear(); + read_fds.clear(); + FD_ZERO(&read_fd_set); + int nfds = 0; + + if (int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask)) + return Error("pthread_sigmask failed with error %d\n", ret); + + for (const auto &fd: m_read_fds) + { + read_fds.push_back(fd.first); + FD_SET(fd.first, &read_fd_set); + nfds = std::max(nfds, fd.first+1); + } + + for (const auto &sig: m_signals) + { + signals.push_back(sig.first); + sigdelset(&sigmask, sig.first); + } + + if (pselect(nfds, &read_fd_set, nullptr, nullptr, nullptr, &sigmask) == -1 && errno != EINTR) + return Error(errno, eErrorTypePOSIX); + + for (int sig: signals) + { + if (g_signal_flags[sig] == 0) + continue; // No signal + g_signal_flags[sig] = 0; + + auto it = m_signals.find(sig); + if (it == m_signals.end()) + continue; // Signal must have gotten unregistered in the meantime + + it->second.callback(*this); // Do the work + + if (m_terminate_request) + return Error(); + } + + for (int fd: read_fds) + { + if (!FD_ISSET(fd, &read_fd_set)) + continue; // Not ready + + auto it = m_read_fds.find(fd); + if (it == m_read_fds.end()) + continue; // File descriptor must have gotten unregistered in the meantime + + it->second(*this); // Do the work + + if (m_terminate_request) + return Error(); + } + } + return Error(); +} + + diff --git a/source/Initialization/SystemInitializerCommon.cpp b/source/Initialization/SystemInitializerCommon.cpp index 35189c103f7c..51f32a2776a8 100644 --- a/source/Initialization/SystemInitializerCommon.cpp +++ b/source/Initialization/SystemInitializerCommon.cpp @@ -17,6 +17,7 @@ #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" +#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h" #include "Plugins/Instruction/ARM/EmulateInstructionARM.h" #include "Plugins/Instruction/MIPS/EmulateInstructionMIPS.h" #include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h" @@ -106,6 +107,7 @@ SystemInitializerCommon::Initialize() ObjectFileELF::Initialize(); ObjectFilePECOFF::Initialize(); DynamicLoaderPOSIXDYLD::Initialize(); + DynamicLoaderWindowsDYLD::Initialize(); platform_freebsd::PlatformFreeBSD::Initialize(); platform_linux::PlatformLinux::Initialize(); PlatformWindows::Initialize(); @@ -152,6 +154,7 @@ SystemInitializerCommon::Terminate() ObjectFileELF::Terminate(); ObjectFilePECOFF::Terminate(); DynamicLoaderPOSIXDYLD::Terminate(); + DynamicLoaderWindowsDYLD::Terminate(); platform_freebsd::PlatformFreeBSD::Terminate(); platform_linux::PlatformLinux::Terminate(); PlatformWindows::Terminate(); diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp index d67f76eba7b6..c0efd9e33c08 100644 --- a/source/Interpreter/CommandObject.cpp +++ b/source/Interpreter/CommandObject.cpp @@ -10,6 +10,7 @@ #include "lldb/Interpreter/CommandObject.h" #include <string> +#include <sstream> #include <map> #include <stdlib.h> @@ -921,6 +922,27 @@ ExprPathHelpTextCallback() } void +CommandObject::FormatLongHelpText (Stream &output_strm, const char *long_help) +{ + CommandInterpreter& interpreter = GetCommandInterpreter(); + std::stringstream lineStream (long_help); + std::string line; + while (std::getline (lineStream, line)) { + if (line.empty()) { + output_strm << "\n"; + continue; + } + size_t result = line.find_first_not_of (" \t"); + if (result == std::string::npos) { + result = 0; + } + std::string whitespace_prefix = line.substr (0, result); + std::string remainder = line.substr (result); + interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str()); + } +} + +void CommandObject::GenerateHelpText (CommandReturnObject &result) { GenerateHelpText(result.GetOutputStream()); @@ -947,7 +969,7 @@ CommandObject::GenerateHelpText (Stream &output_strm) const char *long_help = GetHelpLong(); if ((long_help != nullptr) && (strlen (long_help) > 0)) - output_strm.Printf ("\n%s", long_help); + FormatLongHelpText (output_strm, long_help); if (WantsRawCommandString() && !WantsCompletion()) { // Emit the message about using ' -- ' between the end of the command options and the raw input @@ -984,7 +1006,7 @@ CommandObject::GenerateHelpText (Stream &output_strm) const char *long_help = GetHelpLong(); if ((long_help != nullptr) && (strlen (long_help) > 0)) - output_strm.Printf ("%s", long_help); + FormatLongHelpText (output_strm, long_help); else if (WantsRawCommandString()) { std::string help_text (GetHelp()); diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 0853fe286963..4204d18769b8 100644 --- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -236,7 +236,8 @@ ABISP ABIMacOSX_i386::CreateInstance (const ArchSpec &arch) { static ABISP g_abi_sp; - if (arch.GetTriple().getArch() == llvm::Triple::x86) + if ((arch.GetTriple().getArch() == llvm::Triple::x86) && + (arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS())) { if (!g_abi_sp) g_abi_sp.reset (new ABIMacOSX_i386); diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp index e9e68bc0e949..69129df1f16b 100644 --- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp +++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp @@ -257,7 +257,7 @@ ABISysV_hexagon::PrepareTrivialCall ( Thread &thread, sp -= argSize; // write this argument onto the stack of the host process - proc.get( )->WriteMemory( sp, arg.data, arg.size, error ); + proc.get( )->WriteMemory( sp, arg.data_ap.get(), arg.size, error ); if ( error.Fail( ) ) return false; diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index bbafcf73fa16..2308129b8cab 100644 --- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -168,6 +168,9 @@ DynamicLoaderHexagonDYLD::DidAttach() // Disable JIT for hexagon targets because its not supported m_process->SetCanJIT(false); + // Enable Interpreting of function call expressions + m_process->SetCanInterpretFunctionCalls(true); + // Add the current executable to the module list ModuleList module_list; module_list.Append(executable); @@ -500,7 +503,7 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop if (sym == NULL || !sym->IsTrampoline()) return thread_plan_sp; - const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); + const ConstString sym_name = sym->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled); if (!sym_name) return thread_plan_sp; diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 6330b42ca14a..8724fc039cb9 100644 --- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -458,7 +458,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) if (sym == NULL || !sym->IsTrampoline()) return thread_plan_sp; - const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); + ConstString sym_name = sym->GetName(); if (!sym_name) return thread_plan_sp; @@ -667,7 +667,9 @@ DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp) if (module_sp && module_sp->MatchesModuleSpec (module_spec)) return; - auto error = platform_sp->ResolveExecutable (module_spec, module_sp, nullptr); + const auto executable_search_paths (Target::GetDefaultExecutableSearchPaths()); + auto error = platform_sp->ResolveExecutable ( + module_spec, module_sp, !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr); if (error.Fail ()) { StreamString stream; diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp new file mode 100644 index 000000000000..56b56ab3a194 --- /dev/null +++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -0,0 +1,102 @@ +//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DynamicLoaderWindowsDYLD.h" + +#include "lldb/Core/PluginManager.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +#include "llvm/ADT/Triple.h" + +using namespace lldb; +using namespace lldb_private; + +DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process) + : DynamicLoader(process) +{ + +} + +DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() +{ + +} + +void DynamicLoaderWindowsDYLD::Initialize() +{ + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), + CreateInstance); +} + +void DynamicLoaderWindowsDYLD::Terminate() +{ + +} + +ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() +{ + static ConstString g_plugin_name("windows-dyld"); + return g_plugin_name; +} + +const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() +{ + return "Dynamic loader plug-in that watches for shared library " + "loads/unloads in Windows processes."; +} + + +DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process, bool force) +{ + bool should_create = force; + if (!should_create) + { + const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); + if (triple_ref.getOS() == llvm::Triple::Win32) + should_create = true; + } + + if (should_create) + return new DynamicLoaderWindowsDYLD (process); + + return nullptr; +} + +void DynamicLoaderWindowsDYLD::DidAttach() +{ + +} + +void DynamicLoaderWindowsDYLD::DidLaunch() +{ + +} + +Error DynamicLoaderWindowsDYLD::CanLoadImage() +{ + return Error(); +} + +ConstString DynamicLoaderWindowsDYLD::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() +{ + return 1; +} + +ThreadPlanSP +DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) +{ + return ThreadPlanSP(); +} diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h new file mode 100644 index 000000000000..d12b999f4627 --- /dev/null +++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -0,0 +1,43 @@ +//===-- DynamicLoaderWindowsDYLDh ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_H_ +#define liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_H_ + +#include "lldb/lldb-forward.h" +#include "lldb/Target/DynamicLoader.h" + +namespace lldb_private +{ + +class DynamicLoaderWindowsDYLD : public DynamicLoader +{ + public: + DynamicLoaderWindowsDYLD(Process *process); + virtual ~DynamicLoaderWindowsDYLD(); + + static void Initialize(); + static void Terminate(); + static ConstString GetPluginNameStatic(); + static const char *GetPluginDescriptionStatic(); + + static DynamicLoader *CreateInstance(Process *process, bool force); + + void DidAttach () override; + void DidLaunch () override; + Error CanLoadImage () override; + lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override; + + ConstString GetPluginName() override; + uint32_t GetPluginVersion() override; +}; + +} + +#endif diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 7d21b779ebd2..3a3878ef09a1 100644 --- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -106,7 +106,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, Symbol *symbol = sc.symbol; if (symbol != NULL) { - const char *name = symbol->GetMangled().GetDemangledName().AsCString(); + const char *name = symbol->GetMangled().GetDemangledName(lldb::eLanguageTypeC_plus_plus).AsCString(); if (name && strstr(name, vtable_demangled_prefix) == name) { Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index f9cec2415382..5fc83f06157c 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1558,7 +1558,7 @@ ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) std::string ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { - size_t pos = symbol_name.find("@"); + size_t pos = symbol_name.find('@'); return symbol_name.substr(0, pos).str(); } @@ -1795,7 +1795,16 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, static ConstString bss_section_name(".bss"); static ConstString opd_section_name(".opd"); // For ppc64 - //StreamFile strm(stdout, false); + // On Android the oatdata and the oatexec symbols in system@framework@boot.oat covers the full + // .text section what causes issues with displaying unusable symbol name to the user and very + // slow unwinding speed because the instruction emulation based unwind plans try to emulate all + // instructions in these symbols. Don't add these symbols to the symbol list as they have no + // use for the debugger and they are causing a lot of trouble. + // Filtering can't be restricted to Android because this special object file don't contain the + // note section specifying the environment to Android but the custom extension and file name + // makes it highly unlikely that this will collide with anything else. + bool skip_oatdata_oatexec = m_file.GetFilename() == ConstString("system@framework@boot.oat"); + unsigned i; for (i = 0; i < num_symbols; ++i) { @@ -1809,7 +1818,10 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, (symbol_name == NULL || symbol_name[0] == '\0')) continue; - //symbol.Dump (&strm, i, &strtab_data, section_list); + // Skipping oatdata and oatexec sections if it is requested. See details above the + // definition of skip_oatdata_oatexec for the reasons. + if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || ::strcmp(symbol_name, "oatexec") == 0)) + continue; SectionSP symbol_section_sp; SymbolType symbol_type = eSymbolTypeInvalid; @@ -2031,8 +2043,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, if (! mangled_name.empty()) mangled.SetMangledName( ConstString((mangled_name + suffix).str()) ); - llvm::StringRef demangled_name = mangled.GetDemangledName().GetStringRef(); - if (! demangled_name.empty()) + ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeUnknown); + llvm::StringRef demangled_name = demangled.GetStringRef(); + if (!demangled_name.empty()) mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) ); } diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index fe425e02103b..b4f841a16dec 100644 --- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -535,6 +535,14 @@ PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec, return false; } +const lldb::UnixSignalsSP & +PlatformPOSIX::GetRemoteUnixSignals() { + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteUnixSignals(); + return Platform::GetRemoteUnixSignals(); +} + + FileSpec PlatformPOSIX::GetRemoteWorkingDirectory() { @@ -785,9 +793,6 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info, if (process_sp) { - // Set UnixSignals appropriately. - process_sp->SetUnixSignals (Host::GetUnixSignals ()); - auto listener_sp = attach_info.GetHijackListener(); if (listener_sp == nullptr) { diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h index 19a3f0c4eef1..82686dcef6b0 100644 --- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -109,6 +109,9 @@ public: lldb_private::ArchSpec GetRemoteSystemArchitecture () override; + const lldb::UnixSignalsSP & + GetRemoteUnixSignals() override; + size_t GetEnvironment (lldb_private::StringList &environment) override; diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index df0484c4e69b..b0e75d4f3457 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -32,6 +32,8 @@ #include "Utility/UriParser.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" + using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_gdb_server; @@ -139,13 +141,14 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec, // Resolve any executable within an apk on Android? //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); - if (resolved_module_spec.GetFileSpec().Exists()) + if (resolved_module_spec.GetFileSpec().Exists() || + module_spec.GetUUID().IsValid()) { if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, - NULL, + module_search_paths_ptr, NULL, NULL); @@ -161,7 +164,7 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec, { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, - NULL, + module_search_paths_ptr, NULL, NULL); // Did we find an executable using one of the @@ -413,6 +416,7 @@ PlatformRemoteGDBServer::DisconnectRemote () { Error error; m_gdb_client.Disconnect(&error); + m_remote_signals_sp.reset(); return error; } @@ -871,6 +875,97 @@ PlatformRemoteGDBServer::RunShellCommand(const char *command, // Shoul void PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames () -{ +{ m_trap_handlers.push_back (ConstString ("_sigtramp")); } + +const UnixSignalsSP & +PlatformRemoteGDBServer::GetRemoteUnixSignals() +{ + if (!IsConnected()) + return Platform::GetRemoteUnixSignals(); + + if (m_remote_signals_sp) + return m_remote_signals_sp; + + // If packet not implemented or JSON failed to parse, + // we'll guess the signal set based on the remote architecture. + m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture()); + + const char packet[] = "jSignalsInfo"; + StringExtractorGDBRemote response; + auto result = m_gdb_client.SendPacketAndWaitForResponse( + packet, strlen(packet), response, false); + + if (result != decltype(result)::Success || + response.GetResponseType() != response.eResponse) + return m_remote_signals_sp; + + auto object_sp = StructuredData::ParseJSON(response.GetStringRef()); + if (!object_sp || !object_sp->IsValid()) + return m_remote_signals_sp; + + auto array_sp = object_sp->GetAsArray(); + if (!array_sp || !array_sp->IsValid()) + return m_remote_signals_sp; + + auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>(); + + bool done = array_sp->ForEach( + [&remote_signals_sp](StructuredData::Object *object) -> bool + { + if (!object || !object->IsValid()) + return false; + + auto dict = object->GetAsDictionary(); + if (!dict || !dict->IsValid()) + return false; + + // Signal number and signal name are required. + int signo; + if (!dict->GetValueForKeyAsInteger("signo", signo)) + return false; + + std::string name; + if (!dict->GetValueForKeyAsString("name", name)) + return false; + + // We can live without short_name, description, etc. + std::string short_name{""}; + auto object_sp = dict->GetValueForKey("short_name"); + if (object_sp && object_sp->IsValid()) + short_name = object_sp->GetStringValue(); + + bool suppress{false}; + object_sp = dict->GetValueForKey("suppress"); + if (object_sp && object_sp->IsValid()) + suppress = object_sp->GetBooleanValue(); + + bool stop{false}; + object_sp = dict->GetValueForKey("stop"); + if (object_sp && object_sp->IsValid()) + stop = object_sp->GetBooleanValue(); + + bool notify{false}; + object_sp = dict->GetValueForKey("notify"); + if (object_sp && object_sp->IsValid()) + notify = object_sp->GetBooleanValue(); + + std::string description{""}; + object_sp = dict->GetValueForKey("description"); + if (object_sp && object_sp->IsValid()) + description = object_sp->GetStringValue(); + + remote_signals_sp->AddSignal(signo, + name.c_str(), + short_name.c_str(), + suppress, stop, notify, + description.c_str()); + return true; + }); + + if (done) + m_remote_signals_sp = std::move(remote_signals_sp); + + return m_remote_signals_sp; +} diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index 1d97b4dbc683..0bf013fdfb68 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -18,6 +18,7 @@ // Project includes #include "lldb/Target/Platform.h" #include "../../Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" namespace lldb_private { namespace platform_gdb_server { @@ -213,12 +214,17 @@ public: void CalculateTrapHandlerSymbolNames () override; + const lldb::UnixSignalsSP & + GetRemoteUnixSignals() override; + protected: process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client; std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to std::string m_platform_scheme; std::string m_platform_hostname; + lldb::UnixSignalsSP m_remote_signals_sp; + // Launch the lldb-gdbserver on the remote host and return the port it is listening on or 0 on // failure. Subclasses should override this method if they want to do extra actions before or // after launching the lldb-gdbserver. diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index cce7a1ef28c1..5e46c836beac 100644 --- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -46,7 +46,7 @@ FreeBSDThread::WillResume(lldb::StateType resume_state) ProcessSP process_sp(GetProcess()); ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get()); int signo = GetResumeSignal(); - bool signo_valid = process->GetUnixSignals().SignalIsValid(signo); + bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo); switch (resume_state) { diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 28bca0916148..427c66ce3e6b 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -1297,7 +1297,7 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, if (log) log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d", __FUNCTION__, - monitor->m_process->GetUnixSignals().GetSignalAsCString (signo), + monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo), "SI_USER", info->si_pid); if (info->si_pid == getpid()) @@ -1307,7 +1307,7 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, } if (log) - log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo)); + log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo)); switch (signo) { @@ -1483,7 +1483,7 @@ ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); if (log) { - const char *signame = m_process->GetUnixSignals().GetSignalAsCString (signo); + const char *signame = m_process->GetUnixSignals()->GetSignalAsCString (signo); if (signame == nullptr) signame = "<none>"; log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s", diff --git a/source/Plugins/Process/FreeBSD/ProcessPOSIX.h b/source/Plugins/Process/FreeBSD/ProcessPOSIX.h index 70694cb9b193..627017c547dc 100644 --- a/source/Plugins/Process/FreeBSD/ProcessPOSIX.h +++ b/source/Plugins/Process/FreeBSD/ProcessPOSIX.h @@ -33,7 +33,7 @@ public: //------------------------------------------------------------------ ProcessPOSIX(lldb_private::Target& target, lldb_private::Listener &listener, - lldb_private::UnixSignalsSP &unix_signals_sp); + lldb::UnixSignalsSP &unix_signals_sp); virtual ~ProcessPOSIX(); diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp index f082e143059c..c143d36e87c7 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -13,6 +13,8 @@ // Project includes #include "FreeBSDSignals.h" +using namespace lldb_private; + FreeBSDSignals::FreeBSDSignals() : UnixSignals() { diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h index 1e14ccb9fc4d..b715c62c81e9 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -13,16 +13,19 @@ // Project includes #include "lldb/Target/UnixSignals.h" +namespace lldb_private { + /// FreeBSD specific set of Unix signals. -class FreeBSDSignals - : public lldb_private::UnixSignals +class FreeBSDSignals : public UnixSignals { public: FreeBSDSignals(); private: void - Reset(); + Reset() override; }; +} // namespace lldb_private + #endif // liblldb_FreeBSDSignals_H_ diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp new file mode 100644 index 000000000000..4e355c63b3aa --- /dev/null +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -0,0 +1,32 @@ +//===-- GDBRemoteSignals.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "GDBRemoteSignals.h" + +using namespace lldb_private; + +GDBRemoteSignals::GDBRemoteSignals() + : UnixSignals() +{ + Reset(); +} + +GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs) + : UnixSignals(*rhs) +{ +} + +void +GDBRemoteSignals::Reset() +{ + m_signals.clear(); +} diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h new file mode 100644 index 000000000000..bbb631a14090 --- /dev/null +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -0,0 +1,36 @@ +//===-- GDBRemoteSignals.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_GDBRemoteSignals_H_ +#define liblldb_GDBRemoteSignals_H_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer +class GDBRemoteSignals : public UnixSignals +{ +public: + GDBRemoteSignals(); + + GDBRemoteSignals(const lldb::UnixSignalsSP &rhs); + +private: + void + Reset() override; +}; + +} // namespace lldb_private + +#endif // liblldb_GDBRemoteSignals_H_ diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp index 0680d268233c..cd1fc8165eb9 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -12,7 +12,7 @@ // Project includes #include "LinuxSignals.h" -using namespace lldb_private::process_linux; +using namespace lldb_private; LinuxSignals::LinuxSignals() : UnixSignals() diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h index 5102bcb95e74..dd9062f040a2 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.h +++ b/source/Plugins/Process/Utility/LinuxSignals.h @@ -17,21 +17,18 @@ #include "lldb/Target/UnixSignals.h" namespace lldb_private { -namespace process_linux { - /// Linux specific set of Unix signals. - class LinuxSignals - : public lldb_private::UnixSignals - { - public: - LinuxSignals(); +/// Linux specific set of Unix signals. +class LinuxSignals : public UnixSignals +{ +public: + LinuxSignals(); - private: - void - Reset(); - }; +private: + void + Reset() override; +}; } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_LinuxSignals_H_ diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index e4e654626eaa..1dc0be81c0ae 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -12,7 +12,7 @@ // Project includes #include "MipsLinuxSignals.h" -using namespace lldb_private::process_linux; +using namespace lldb_private; MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h index 2e603fbbdf3c..a5041b50eea3 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -17,21 +17,18 @@ #include "lldb/Target/UnixSignals.h" namespace lldb_private { -namespace process_linux { - /// Linux specific set of Unix signals. - class MipsLinuxSignals - : public lldb_private::UnixSignals - { - public: - MipsLinuxSignals(); +/// Linux specific set of Unix signals. +class MipsLinuxSignals : public UnixSignals +{ +public: + MipsLinuxSignals(); - private: - void - Reset(); - }; +private: + void + Reset() override; +}; } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_MipsLinuxSignals_H_ diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp index 02d3ecd7b3c5..1cdae9011673 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -120,29 +120,28 @@ unwind_done: return false; } -// For adding a non-zero stack frame to m_frames. -bool -UnwindLLDB::AddOneMoreFrame (ABI *abi) +UnwindLLDB::CursorSP +UnwindLLDB::GetOneMoreFrame (ABI* abi) { + assert (m_frames.size() != 0 && "Get one more frame called with empty frame list"); + // If we've already gotten to the end of the stack, don't bother to try again... if (m_unwind_complete) - return false; + return nullptr; Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - CursorSP cursor_sp(new Cursor ()); - // Frame zero is a little different - if (m_frames.size() == 0) - return false; + CursorSP prev_frame = m_frames.back(); + uint32_t cur_idx = m_frames.size(); - uint32_t cur_idx = m_frames.size (); + CursorSP cursor_sp(new Cursor ()); RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread, - m_frames[cur_idx - 1]->reg_ctx_lldb_sp, + prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); - // We want to detect an unwind that cycles erronously and stop backtracing. + // We want to detect an unwind that cycles erroneously and stop backtracing. // Don't want this maximum unwind limit to be too low -- if you have a backtrace // with an "infinitely recursing" bug, it will crash when the stack blows out // and the first 35,000 frames are uninteresting - it's the top most 5 frames that @@ -154,21 +153,20 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) if (log) log->Printf ("%*sFrame %d unwound too many frames, assuming unwind has gone astray, stopping.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - goto unwind_done; + return nullptr; } if (reg_ctx_sp.get() == NULL) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - goto unwind_done; + return nullptr; } if (!reg_ctx_sp->IsValid()) @@ -176,31 +174,25 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) // We failed to get a valid RegisterContext. // See if the regctx below this on the stack has a fallback unwind plan it can use. // Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } if (!reg_ctx_sp->GetCFA (cursor_sp->cfa)) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { @@ -219,24 +211,19 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } else { if (log) - { log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } } } } @@ -244,54 +231,103 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc)) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } - if (!m_frames.empty()) + // Infinite loop where the current cursor is the same as the previous one... + if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa) { - // Infinite loop where the current cursor is the same as the previous one... - if (m_frames.back()->start_pc == cursor_sp->start_pc && m_frames.back()->cfa == cursor_sp->cfa) - { - if (log) - log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); - goto unwind_done; - } + if (log) + log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); + return nullptr; } cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; - m_frames.push_back (cursor_sp); - return true; - -unwind_done: - if (log) + return cursor_sp; +} + +bool +UnwindLLDB::AddOneMoreFrame (ABI *abi) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); + + // Frame zero is a little different + if (m_frames.empty()) + return false; + + // If we've already gotten to the end of the stack, don't bother to try again... + if (m_unwind_complete) + return false; + + CursorSP new_frame = m_candidate_frame; + if (new_frame == nullptr) + new_frame = GetOneMoreFrame(abi); + + if (new_frame == nullptr) { - log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); + if (log) + log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); + m_unwind_complete = true; + return false; } - m_unwind_complete = true; - return false; + + m_frames.push_back(new_frame); + + // If we can get one more frame further then accept that we get back a correct frame. + m_candidate_frame = GetOneMoreFrame(abi); + if (m_candidate_frame) + return true; + + // We can't go further from the frame returned by GetOneMore frame. Lets try to get a + // different frame with using the fallback unwind plan. + if (!m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // We don't have a valid fallback unwind plan. Accept the frame as it is. This is a + // valid situation when we are at the bottom of the stack. + return true; + } + + // Remove the possibly incorrect frame from the frame list and try to add a different one with + // the newly selected fallback unwind plan. + m_frames.pop_back(); + CursorSP new_frame_v2 = GetOneMoreFrame(abi); + if (new_frame_v2 == nullptr) + { + // We haven't got a new frame from the fallback unwind plan. Accept the frame from the + // original unwind plan. This is a valid situation when we are at the bottom of the stack. + m_frames.push_back(new_frame); + return true; + } + + // Push the new frame to the list and try to continue from this frame. If we can get a new frame + // then accept it as the correct one. + m_frames.push_back(new_frame_v2); + m_candidate_frame = GetOneMoreFrame(abi); + if (m_candidate_frame) + return true; + + // The new frame isn't helped in unwinding. Fall back to the original one as the default unwind + // plan is usually more reliable then the fallback one. + m_frames.pop_back(); + m_frames.push_back(new_frame); + return true; } bool diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h index 35d85e2e3d26..ce897cd82423 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/source/Plugins/Process/Utility/UnwindLLDB.h @@ -65,6 +65,7 @@ protected: DoClear() { m_frames.clear(); + m_candidate_frame.reset(); m_unwind_complete = false; } @@ -126,14 +127,21 @@ private: typedef std::shared_ptr<Cursor> CursorSP; std::vector<CursorSP> m_frames; + CursorSP m_candidate_frame; bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the // number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size() // is how far we've currently gone. std::vector<ConstString> m_user_supplied_trap_handler_functions; - bool AddOneMoreFrame (ABI *abi); - bool AddFirstFrame (); + CursorSP + GetOneMoreFrame (ABI* abi); + + bool + AddOneMoreFrame (ABI *abi); + + bool + AddFirstFrame (); //------------------------------------------------------------------ // For UnwindLLDB only diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 2fff36dd4ee5..bf5cad8e39c5 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -29,8 +29,6 @@ #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" -#include "Plugins/Process/Utility/LinuxSignals.h" // Project includes #include "ProcessElfCore.h" @@ -237,23 +235,7 @@ ProcessElfCore::DoLoadCore () if (arch.IsValid()) m_target.SetArchitecture(arch); - switch (m_os) - { - case llvm::Triple::FreeBSD: - { - static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals ()); - SetUnixSignals(s_freebsd_signals_sp); - break; - } - case llvm::Triple::Linux: - { - static UnixSignalsSP s_linux_signals_sp(new process_linux::LinuxSignals ()); - SetUnixSignals(s_linux_signals_sp); - break; - } - default: - break; - } + SetUnixSignals(UnixSignals::Create(GetArchitecture())); return error; } @@ -370,7 +352,7 @@ ProcessElfCore::Clear() m_thread_list.Clear(); m_os = llvm::Triple::UnknownOS; - static UnixSignalsSP s_default_unix_signals_sp(new UnixSignals()); + static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>(); SetUnixSignals(s_default_unix_signals_sp); } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 1af3947a75f3..9c263c8c4087 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -564,8 +564,12 @@ GDBRemoteCommunication::DecompressPacket () return true; size_t pkt_size = m_bytes.size(); - if (pkt_size < 6) + + // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating + // an unsupported packet. Anything less than 5 characters, it's definitely not a compressed packet. + if (pkt_size < 5) return true; + if (m_bytes[0] != '$' && m_bytes[0] != '%') return true; if (m_bytes[1] != 'C' && m_bytes[1] != 'N') diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index ae0a2f5e66c5..2a253c5a99e8 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -87,6 +87,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : m_supports_qXfer_features_read (eLazyBoolCalculate), m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), m_supports_jThreadExtendedInfo (eLazyBoolCalculate), + m_supports_jLoadedDynamicLibrariesInfos (eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -654,6 +655,24 @@ GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported () } bool +GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported () +{ + if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) + { + StringExtractorGDBRemote response; + m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo; + if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", response, false) == PacketResult::Success) + { + if (response.IsOKResponse()) + { + m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes; + } + } + } + return m_supports_jLoadedDynamicLibrariesInfos; +} + +bool GDBRemoteCommunicationClient::GetxPacketSupported () { if (m_supports_x == eLazyBoolCalculate) @@ -1037,8 +1056,8 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse // may change if we are interrupted and we continue after an async packet... std::string continue_packet(payload, packet_length); - const auto sigstop_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGSTOP"); - const auto sigint_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGINT"); + const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP"); + const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT"); bool got_async_packet = false; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 65a2981018ea..deb41b066b45 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -550,6 +550,9 @@ public: GetThreadExtendedInfoSupported(); bool + GetLoadedDynamicLibrariesInfosSupported(); + + bool GetModuleInfo (const FileSpec& module_file_spec, const ArchSpec& arch_spec, ModuleSpec &module_spec); @@ -614,6 +617,7 @@ protected: LazyBool m_supports_qXfer_features_read; LazyBool m_supports_augmented_libraries_svr4_read; LazyBool m_supports_jThreadExtendedInfo; + LazyBool m_supports_jLoadedDynamicLibrariesInfos; bool m_supports_qProcessInfoPID:1, diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 13ce9b2dc5c3..4ee66b84d474 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -132,7 +132,7 @@ GDBRemoteCommunicationServer::SendOKResponse () } bool -GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) +GDBRemoteCommunicationServer::HandshakeWithClient() { return GetAck() == PacketResult::Success; } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 992c6dffaf54..44c0f6a32f5b 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -54,7 +54,7 @@ public: // After connecting, do a little handshake with the client to make sure // we are at least communicating bool - HandshakeWithClient (Error *error_ptr); + HandshakeWithClient (); protected: std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index e8955ddbd6e4..c4523252f190 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -75,10 +75,11 @@ namespace // GDBRemoteCommunicationServerLLGS constructor //---------------------------------------------------------------------- GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( - const lldb::PlatformSP& platform_sp) : + const lldb::PlatformSP& platform_sp, + MainLoop &mainloop) : GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"), m_platform_sp (platform_sp), - m_async_thread (LLDB_INVALID_HOST_THREAD), + m_mainloop (mainloop), m_current_tid (LLDB_INVALID_THREAD_ID), m_continue_tid (LLDB_INVALID_THREAD_ID), m_debugged_process_mutex (Mutex::eMutexTypeRecursive), @@ -88,7 +89,8 @@ GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( m_active_auxv_buffer_sp (), m_saved_registers_mutex (), m_saved_registers_map (), - m_next_saved_registers_id (1) + m_next_saved_registers_id (1), + m_handshake_completed (false) { assert(platform_sp); RegisterPacketHandlers(); @@ -218,7 +220,7 @@ GDBRemoteCommunicationServerLLGS::LaunchProcess () { Mutex::Locker locker (m_debugged_process_mutex); assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists"); - error = m_platform_sp->LaunchNativeProcess ( + error = NativeProcessProtocol::Launch( m_process_launch_info, *this, m_debugged_process_sp); @@ -306,7 +308,7 @@ GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid) } // Try to attach. - error = m_platform_sp->AttachNativeProcess (pid, *this, m_debugged_process_sp); + error = NativeProcessProtocol::Attach(pid, *this, m_debugged_process_sp); if (!error.Success ()) { fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ()); @@ -782,6 +784,58 @@ GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process) ClearProcessSpecificData (); } +void +GDBRemoteCommunicationServerLLGS::DataAvailableCallback () +{ + Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM)); + + if (! m_handshake_completed) + { + if (! HandshakeWithClient()) + { + if(log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting", + __FUNCTION__); + m_read_handle_up.reset(); + m_mainloop.RequestTermination(); + return; + } + m_handshake_completed = true; + } + + bool interrupt = false; + bool done = false; + Error error; + while (true) + { + const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done); + if (result == PacketResult::ErrorReplyTimeout) + break; // No more packets in the queue + + if ((result != PacketResult::Success)) + { + if(log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s", + __FUNCTION__, error.AsCString()); + m_read_handle_up.reset(); + m_mainloop.RequestTermination(); + break; + } + } +} + +Error +GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection) +{ + IOObjectSP read_object_sp = connection->GetReadObject(); + GDBRemoteCommunicationServer::SetConnection(connection.release()); + + Error error; + m_read_handle_up = m_mainloop.RegisterReadObject(read_object_sp, + [this] (MainLoopBase &) { DataAvailableCallback(); }, error); + return error; +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 1eda0b052bb7..29f3fdebcfb0 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -19,6 +19,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/common/NativeProcessProtocol.h" +#include "lldb/Host/MainLoop.h" // Project includes #include "GDBRemoteCommunicationServerCommon.h" @@ -26,6 +27,7 @@ class StringExtractorGDBRemote; namespace lldb_private { + namespace process_gdb_remote { class ProcessGDBRemote; @@ -38,7 +40,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp); + GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp, MainLoop &mainloop); virtual ~GDBRemoteCommunicationServerLLGS(); @@ -111,9 +113,13 @@ public: void DidExec (NativeProcessProtocol *process) override; + Error + InitializeConnection (std::unique_ptr<Connection> &&connection); + protected: lldb::PlatformSP m_platform_sp; - lldb::thread_t m_async_thread; + MainLoop &m_mainloop; + MainLoop::ReadHandleUP m_read_handle_up; lldb::tid_t m_current_tid; lldb::tid_t m_continue_tid; Mutex m_debugged_process_mutex; @@ -124,6 +130,7 @@ protected: Mutex m_saved_registers_mutex; std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map; uint32_t m_next_saved_registers_id; + bool m_handshake_completed : 1; PacketResult SendONotification (const char *buffer, uint32_t len); @@ -295,6 +302,9 @@ private: void RegisterPacketHandlers (); + void + DataAvailableCallback (); + //------------------------------------------------------------------ // For GDBRemoteCommunicationServerLLGS only //------------------------------------------------------------------ diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index f5e5d76f2e6f..1205049db3fb 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -19,6 +19,7 @@ // Other libraries and framework includes #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Host/Config.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" @@ -26,6 +27,7 @@ #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Target/UnixSignals.h" // Project includes #include "Utility/StringExtractorGDBRemote.h" @@ -54,6 +56,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() : &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir); + RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo, + &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, [this](StringExtractorGDBRemote packet, @@ -251,6 +255,35 @@ GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packe return SendPacketNoLock (response.GetData(), response.GetSize()); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet) +{ + StructuredData::Array signal_array; + + const auto &signals = Host::GetUnixSignals(); + for (auto signo = signals->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = signals->GetNextSignalNumber(signo)) + { + auto dictionary = std::make_shared<StructuredData::Dictionary>(); + + dictionary->AddIntegerItem("signo", signo); + dictionary->AddStringItem("name", signals->GetSignalAsCString(signo)); + + bool suppress, stop, notify; + signals->GetSignalInfo(signo, suppress, stop, notify); + dictionary->AddBooleanItem("suppress", suppress); + dictionary->AddBooleanItem("stop", stop); + dictionary->AddBooleanItem("notify", notify); + + signal_array.Push(dictionary); + } + + StreamString response; + signal_array.Dump(response); + return SendPacketNoLock(response.GetData(), response.GetSize()); +} + bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index 4124b0424f5d..5c011371a3eb 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -79,6 +79,9 @@ protected: PacketResult Handle_qC (StringExtractorGDBRemote &packet); + PacketResult + Handle_jSignalsInfo(StringExtractorGDBRemote &packet); + private: bool DebugserverProcessReaped (lldb::pid_t pid); diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 5cb4da514a7f..0bcc8ca4e5e3 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -65,10 +65,8 @@ // Project includes #include "lldb/Host/Host.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "Plugins/Process/Utility/LinuxSignals.h" -#include "Plugins/Process/Utility/MipsLinuxSignals.h" #include "Plugins/Process/Utility/StopInfoMachException.h" #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" #include "Utility/StringExtractorGDBRemote.h" @@ -823,41 +821,8 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url) if (log) log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ()); - // Set the Unix signals properly for the target. - // FIXME Add a gdb-remote packet to discover dynamically. - if (error.Success ()) - { - const ArchSpec arch_spec = m_gdb_comm.GetHostArchitecture(); - if (arch_spec.IsValid ()) - { - if (log) - log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": determining unix signals type based on architecture %s, triple %s", __FUNCTION__, GetID (), arch_spec.GetArchitectureName () ? arch_spec.GetArchitectureName () : "<null>", arch_spec.GetTriple ().getTriple ().c_str ()); - - switch (arch_spec.GetTriple ().getOS ()) - { - case llvm::Triple::Linux: - if (arch_spec.GetTriple ().getArch () == llvm::Triple::mips64 || arch_spec.GetTriple ().getArch () == llvm::Triple::mips64el) - SetUnixSignals (UnixSignalsSP (new process_linux::MipsLinuxSignals ())); - else - SetUnixSignals (UnixSignalsSP (new process_linux::LinuxSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using Linux unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - case llvm::Triple::OpenBSD: - case llvm::Triple::FreeBSD: - case llvm::Triple::NetBSD: - SetUnixSignals (UnixSignalsSP (new FreeBSDSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using *BSD unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - default: - SetUnixSignals (UnixSignalsSP (new UnixSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using generic unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - } - } - } + if (error.Success()) + SetUnixSignals(std::make_shared<GDBRemoteSignals>(GetTarget().GetPlatform()->GetUnixSignals())); return error; } @@ -3524,7 +3489,7 @@ ProcessGDBRemote::MonitorDebugserverProcess char error_str[1024]; if (signo) { - const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo); + const char *signal_cstr = process->GetUnixSignals()->GetSignalAsCString(signo); if (signal_cstr) ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr); else @@ -3985,6 +3950,44 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid) { if (!response.Empty()) { + object_sp = StructuredData::ParseJSON (response.GetStringRef()); + } + } + } + } + return object_sp; +} + +StructuredData::ObjectSP +ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) +{ + StructuredData::ObjectSP object_sp; + + if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) + { + StructuredData::ObjectSP args_dict(new StructuredData::Dictionary()); + args_dict->GetAsDictionary()->AddIntegerItem ("image_list_address", image_list_address); + args_dict->GetAsDictionary()->AddIntegerItem ("image_count", image_count); + + StreamString packet; + packet << "jGetLoadedDynamicLibrariesInfos:"; + args_dict->Dump (packet); + + // FIXME the final character of a JSON dictionary, '}', is the escape + // character in gdb-remote binary mode. lldb currently doesn't escape + // these characters in its packet output -- so we add the quoted version + // of the } character here manually in case we talk to a debugserver which + // un-escapes the characters at packet read time. + packet << (char) (0x7d ^ 0x20); + + StringExtractorGDBRemote response; + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success) + { + StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType(); + if (response_type == StringExtractorGDBRemote::eResponse) + { + if (!response.Empty()) + { // The packet has already had the 0x7d xor quoting stripped out at the // GDBRemoteCommunication packet receive level. object_sp = StructuredData::ParseJSON (response.GetStringRef()); @@ -3995,6 +3998,7 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid) return object_sp; } + // Establish the largest memory read/write payloads we should use. // If the remote stub has a max packet size, stay under that size. // @@ -4418,83 +4422,135 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list) GDBRemoteCommunicationClient & comm = m_gdb_comm; // check that we have extended feature read support - if (!comm.GetQXferLibrariesSVR4ReadSupported ()) - return Error (0, ErrorType::eErrorTypeGeneric); + if (comm.GetQXferLibrariesSVR4ReadSupported ()) { + list.clear (); - list.clear (); + // request the loaded library list + std::string raw; + lldb_private::Error lldberr; - // request the loaded library list - std::string raw; - lldb_private::Error lldberr; - if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr)) - return Error (0, ErrorType::eErrorTypeGeneric); + if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr)) + return Error (0, ErrorType::eErrorTypeGeneric); - // parse the xml file in memory - if (log) - log->Printf ("parsing: %s", raw.c_str()); - XMLDocument doc; - - if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Error (0, ErrorType::eErrorTypeGeneric); + // parse the xml file in memory + if (log) + log->Printf ("parsing: %s", raw.c_str()); + XMLDocument doc; + + if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + return Error (0, ErrorType::eErrorTypeGeneric); - XMLNode root_element = doc.GetRootElement("library-list-svr4"); - if (!root_element) - return Error(); + XMLNode root_element = doc.GetRootElement("library-list-svr4"); + if (!root_element) + return Error(); - // main link map structure - llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); - if (!main_lm.empty()) - { - list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); - } + // main link map structure + llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); + if (!main_lm.empty()) + { + list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); + } - root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { + root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { - GDBLoadedModuleInfoList::LoadedModuleInfo module; + GDBLoadedModuleInfoList::LoadedModuleInfo module; - library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - - if (name == "name") - module.set_name (value.str()); - else if (name == "lm") - { - // the address of the link_map struct. - module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); - } - else if (name == "l_addr") - { - // the displacement as read from the field 'l_addr' of the link_map struct. - module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - } - else if (name == "l_ld") + if (name == "name") + module.set_name (value.str()); + else if (name == "lm") + { + // the address of the link_map struct. + module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + } + else if (name == "l_addr") + { + // the displacement as read from the field 'l_addr' of the link_map struct. + module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + + } + else if (name == "l_ld") + { + // the memory address of the libraries PT_DYAMIC section. + module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + } + + return true; // Keep iterating over all properties of "library" + }); + + if (log) { - // the memory address of the libraries PT_DYAMIC section. - module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + std::string name; + lldb::addr_t lm=0, base=0, ld=0; + + module.get_name (name); + module.get_link_map (lm); + module.get_base (base); + module.get_dynamic (ld); + + log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str()); } - - return true; // Keep iterating over all properties of "library" + + list.add (module); + return true; // Keep iterating over all "library" elements in the root node }); if (log) - { - std::string name; - lldb::addr_t lm=0, base=0, ld=0; + log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + } else if (comm.GetQXferLibrariesReadSupported ()) { + list.clear (); - module.get_name (name); - module.get_link_map (lm); - module.get_base (base); - module.get_dynamic (ld); + // request the loaded library list + std::string raw; + lldb_private::Error lldberr; - log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str()); - } + if (!comm.ReadExtFeature (ConstString ("libraries"), ConstString (""), raw, lldberr)) + return Error (0, ErrorType::eErrorTypeGeneric); - list.add (module); - return true; // Keep iterating over all "library" elements in the root node - }); + if (log) + log->Printf ("parsing: %s", raw.c_str()); + XMLDocument doc; - if (log) - log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + return Error (0, ErrorType::eErrorTypeGeneric); + + XMLNode root_element = doc.GetRootElement("library-list"); + if (!root_element) + return Error(); + + root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { + GDBLoadedModuleInfoList::LoadedModuleInfo module; + + llvm::StringRef name = library.GetAttributeValue("name"); + module.set_name(name.str()); + + // The base address of a given library will be the address of its + // first section. Most remotes send only one section for Windows + // targets for example. + const XMLNode §ion = library.FindFirstChildElementWithName("section"); + llvm::StringRef address = section.GetAttributeValue("address"); + module.set_base(StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0)); + + if (log) + { + std::string name; + lldb::addr_t base = 0; + module.get_name (name); + module.get_base (base); + + log->Printf ("found (base:0x%" PRIx64 ", name:'%s')", base, name.c_str()); + } + + list.add (module); + return true; // Keep iterating over all "library" elements in the root node + }); + + if (log) + log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + } else { + return Error (0, ErrorType::eErrorTypeGeneric); + } return Error(); } diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 0a5e4a8a41b4..45c74ea64ee5 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -27,11 +27,11 @@ #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" #include "lldb/lldb-private-forward.h" +#include "lldb/Utility/StringExtractor.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "GDBRemoteCommunicationClient.h" -#include "Utility/StringExtractor.h" #include "GDBRemoteRegisterContext.h" namespace lldb_private { @@ -247,6 +247,9 @@ public: void ModulesDidLoad (ModuleList &module_list) override; + StructuredData::ObjectSP + GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override; + protected: friend class ThreadGDBRemote; friend class GDBRemoteCommunicationClient; diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 59c701d75a68..d2a6503caf8e 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -215,14 +215,14 @@ ThreadGDBRemote::WillResume (StateType resume_state) break; case eStateRunning: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) + if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo)); else gdb_process->m_continue_c_tids.push_back(tid); break; case eStateStepping: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) + if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo)); else gdb_process->m_continue_s_tids.push_back(tid); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 75934f966bcd..60933108c97a 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -669,6 +669,7 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, GetOffset()); } + const LanguageType cu_language = GetLanguageType(); DWARFDebugInfoEntry::const_iterator pos; DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); @@ -882,8 +883,9 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { Mangled mangled (ConstString(mangled_cstr), true); func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + func_fullnames.Insert (demangled, die.GetOffset()); } } } @@ -904,8 +906,9 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { Mangled mangled (ConstString(mangled_cstr), true); func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + func_fullnames.Insert (demangled, die.GetOffset()); } } else @@ -951,8 +954,9 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { Mangled mangled (ConstString(mangled_cstr), true); globals.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - globals.Insert (mangled.GetDemangledName(), die.GetOffset()); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + globals.Insert (demangled, die.GetOffset()); } } break; diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index dafd389449a2..ea8aedcc2be0 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -988,24 +988,38 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) std::string remapped_file; if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file)) cu_file_spec.SetFile(remapped_file, false); + } - LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); + LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); - cu_sp.reset(new CompileUnit (module_sp, - dwarf_cu, - cu_file_spec, - MakeUserID(dwarf_cu->GetOffset()), - cu_language)); - if (cu_sp) + cu_sp.reset(new CompileUnit (module_sp, + dwarf_cu, + cu_file_spec, + MakeUserID(dwarf_cu->GetOffset()), + cu_language)); + if (cu_sp) + { + // If we just created a compile unit with an invalid file spec, try and get the + // first entry in the supports files from the line table as that should be the + // compile unit. + if (!cu_file_spec) { - dwarf_cu->SetUserData(cu_sp.get()); - - // Figure out the compile unit index if we weren't given one - if (cu_idx == UINT32_MAX) - DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); - - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); + cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1); + if (cu_file_spec) + { + (FileSpec &)(*cu_sp) = cu_file_spec; + // Also fix the invalid file spec which was copied from the compile unit. + cu_sp->GetSupportFiles().Replace(0, cu_file_spec); + } } + + dwarf_cu->SetUserData(cu_sp.get()); + + // Figure out the compile unit index if we weren't given one + if (cu_idx == UINT32_MAX) + DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); + + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); } } } @@ -2196,7 +2210,7 @@ SymbolFileDWARF::ParseChildMembers } } - if (prop_name != NULL) + if (prop_name != NULL && member_type) { clang::ObjCIvarDecl *ivar_decl = NULL; @@ -3761,9 +3775,10 @@ SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die, } } - if (best_name.GetDemangledName()) + const LanguageType cu_language = const_cast<DWARFCompileUnit *>(dwarf_cu)->GetLanguageType(); + if (best_name.GetDemangledName(cu_language)) { - const char *demangled = best_name.GetDemangledName().GetCString(); + const char *demangled = best_name.GetDemangledName(cu_language).GetCString(); if (demangled) { std::string name_no_parens(partial_name, base_name_end - partial_name); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 5579a23ce716..de972acd7ed7 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -113,7 +113,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa // correctly to the new addresses in the main executable. // First we find the original symbol in the .o file's symbol table - Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), + Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); @@ -145,7 +145,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa // sizes from the DWARF info as we are parsing. // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file - Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), + Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 64c88ab716bf..09b919782608 100644 --- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -161,7 +161,7 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); if (cu_symbol) - cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown)); + cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown)); } return cu_sp; } diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 3c3e2e51d9af..68bcde8a47c1 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -1592,6 +1592,7 @@ ClangASTContext::CreateObjCClass SourceLocation(), &ast->Idents.get(name), nullptr, + nullptr, SourceLocation(), /*isForwardDecl,*/ isInternal); diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp index 64a7323d25cf..dd73b35d86a9 100644 --- a/source/Symbol/ClangASTImporter.cpp +++ b/source/Symbol/ClangASTImporter.cpp @@ -17,6 +17,7 @@ #include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/ClangNamespaceDecl.h" +#include "lldb/Utility/LLDBAssert.h" using namespace lldb_private; using namespace clang; @@ -109,6 +110,134 @@ ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast, return nullptr; } +class DeclContextOverride +{ +private: + struct Backup + { + clang::DeclContext *decl_context; + clang::DeclContext *lexical_decl_context; + }; + + std::map<clang::Decl *, Backup> m_backups; + + void OverrideOne(clang::Decl *decl) + { + if (m_backups.find(decl) != m_backups.end()) + { + return; + } + + m_backups[decl] = { decl->getDeclContext(), decl->getLexicalDeclContext() }; + + decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl()); + decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl()); + } + + bool ChainPassesThrough(clang::Decl *decl, + clang::DeclContext *base, + clang::DeclContext *(clang::Decl::*contextFromDecl)(), + clang::DeclContext *(clang::DeclContext::*contextFromContext)()) + { + for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); + decl_ctx; + decl_ctx = (decl_ctx->*contextFromContext)()) + { + if (decl_ctx == base) + { + return true; + } + } + + return false; + } + + clang::Decl *GetEscapedChild(clang::Decl *decl, clang::DeclContext *base = nullptr) + { + if (base) + { + // decl's DeclContext chains must pass through base. + + if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, &clang::DeclContext::getParent) || + !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, &clang::DeclContext::getLexicalParent)) + { + return decl; + } + } + else + { + base = clang::dyn_cast<clang::DeclContext>(decl); + + if (!base) + { + return nullptr; + } + } + + if (clang::DeclContext *context = clang::dyn_cast<clang::DeclContext>(decl)) + { + for (clang::Decl *decl : context->decls()) + { + if (clang::Decl *escaped_child = GetEscapedChild(decl)) + { + return escaped_child; + } + } + } + + return nullptr; + } + + void Override(clang::Decl *decl) + { + if (clang::Decl *escaped_child = GetEscapedChild(decl)) + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + log->Printf(" [ClangASTImporter] DeclContextOverride couldn't override (%sDecl*)%p - its child (%sDecl*)%p escapes", + decl->getDeclKindName(), static_cast<void*>(decl), + escaped_child->getDeclKindName(), static_cast<void*>(escaped_child)); + lldbassert(0 && "Couldn't override!"); + } + + OverrideOne(decl); + } + +public: + DeclContextOverride() + { + } + + void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) + { + for (DeclContext *decl_context = decl->getLexicalDeclContext(); + decl_context; + decl_context = decl_context->getLexicalParent()) + { + DeclContext *redecl_context = decl_context->getRedeclContext(); + + if (llvm::isa<FunctionDecl>(redecl_context) && + llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) + { + for (clang::Decl *child_decl : decl_context->decls()) + { + Override(child_decl); + } + } + } + } + + ~DeclContextOverride() + { + for (const std::pair<clang::Decl *, Backup> &backup : m_backups) + { + backup.first->setDeclContext(backup.second.decl_context); + backup.first->setLexicalDeclContext(backup.second.lexical_decl_context); + } + } +}; + lldb::clang_type_t ClangASTImporter::DeportType (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx, @@ -122,6 +251,13 @@ ClangASTImporter::DeportType (clang::ASTContext *dst_ctx, std::set<NamedDecl *> decls_to_deport; std::set<NamedDecl *> decls_already_deported; + DeclContextOverride decl_context_override; + + if (const clang::TagType *tag_type = clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) + { + decl_context_override.OverrideAllDeclsFromContainingFunction(tag_type->getDecl()); + } + minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); @@ -156,6 +292,10 @@ ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx, std::set<NamedDecl *> decls_to_deport; std::set<NamedDecl *> decls_already_deported; + + DeclContextOverride decl_context_override; + + decl_context_override.OverrideAllDeclsFromContainingFunction(decl); minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); @@ -568,7 +708,8 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from if (!to_objc_interface->hasDefinition()) to_objc_interface->startDefinition(); - to_objc_interface->setSuperClass(imported_from_superclass); + to_objc_interface->setSuperClass( + m_source_ctx->getTrivialTypeSourceInfo(m_source_ctx->getObjCInterfaceType(imported_from_superclass))); } while (0); } diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp index a62cc9f45a6b..6f1002fbd9fc 100644 --- a/source/Symbol/ClangASTType.cpp +++ b/source/Symbol/ClangASTType.cpp @@ -5354,7 +5354,9 @@ ClangASTType::SetObjCSuperClass (const ClangASTType &superclass_clang_type) clang::ObjCInterfaceDecl *super_interface_decl = superclass_clang_type.GetAsObjCInterfaceDecl (); if (class_interface_decl && super_interface_decl) { - class_interface_decl->setSuperClass(super_interface_decl); + + class_interface_decl->setSuperClass( + m_ast->getTrivialTypeSourceInfo(m_ast->getObjCInterfaceType(super_interface_decl))); return true; } } diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp index 0b7430ad75e3..77448d4f2a22 100644 --- a/source/Symbol/Function.cpp +++ b/source/Symbol/Function.cpp @@ -77,7 +77,7 @@ FunctionInfo::GetDeclaration() const return m_declaration; } -const ConstString& +ConstString FunctionInfo::GetName() const { return m_name; @@ -140,25 +140,32 @@ InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const } void -InlineFunctionInfo::DumpStopContext (Stream *s) const +InlineFunctionInfo::DumpStopContext (Stream *s, LanguageType language) const { // s->Indent("[inlined] "); s->Indent(); if (m_mangled) - s->PutCString (m_mangled.GetName().AsCString()); + s->PutCString (m_mangled.GetName(language).AsCString()); else s->PutCString (m_name.AsCString()); } -const ConstString & -InlineFunctionInfo::GetName () const +ConstString +InlineFunctionInfo::GetName (LanguageType language) const { if (m_mangled) - return m_mangled.GetName(); + return m_mangled.GetName(language); return m_name; } +ConstString +InlineFunctionInfo::GetDisplayName (LanguageType language) const +{ + if (m_mangled) + return m_mangled.GetDisplayDemangledName(language); + return m_name; +} Declaration & InlineFunctionInfo::GetCallSite () @@ -459,6 +466,14 @@ Function::MemorySize () const return mem_size; } +ConstString +Function::GetDisplayName () const +{ + if (!m_mangled) + return ConstString(); + return m_mangled.GetDisplayDemangledName(GetLanguage()); +} + clang::DeclContext * Function::GetClangDeclContext() { @@ -602,5 +617,32 @@ Function::GetPrologueByteSize () return m_prologue_byte_size; } +lldb::LanguageType +Function::GetLanguage() const +{ + if (m_comp_unit) + return m_comp_unit->GetLanguage(); + else + return lldb::eLanguageTypeUnknown; +} + +ConstString +Function::GetName() const +{ + LanguageType language = lldb::eLanguageTypeUnknown; + if (m_comp_unit) + language = m_comp_unit->GetLanguage(); + return m_mangled.GetName(language); +} + +ConstString +Function::GetNameNoArguments() const +{ + LanguageType language = lldb::eLanguageTypeUnknown; + if (m_comp_unit) + language = m_comp_unit->GetLanguage(); + return m_mangled.GetName(language, Mangled::ePreferDemangledWithoutArguments); +} + diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp index dff15dd92613..5884fcaa551d 100644 --- a/source/Symbol/Symbol.cpp +++ b/source/Symbol/Symbol.cpp @@ -185,6 +185,14 @@ Symbol::ValueIsAddress() const } ConstString +Symbol::GetDisplayName () const +{ + if (!m_mangled) + return ConstString(); + return m_mangled.GetDisplayDemangledName(GetLanguage()); +} + +ConstString Symbol::GetReExportedSymbolName() const { if (m_type == eSymbolTypeReExported) @@ -288,8 +296,9 @@ Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) else s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset()); } - if (m_mangled.GetDemangledName()) - s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString()); + ConstString demangled = m_mangled.GetDemangledName(GetLanguage()); + if (demangled) + s->Printf(", name=\"%s\"", demangled.AsCString()); if (m_mangled.GetMangledName()) s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString()); @@ -309,6 +318,7 @@ Symbol::Dump(Stream *s, Target *target, uint32_t index) const // Make sure the size of the symbol is up to date before dumping GetByteSize(); + ConstString name = m_mangled.GetName(GetLanguage()); if (ValueIsAddress()) { if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress)) @@ -325,13 +335,13 @@ Symbol::Dump(Stream *s, Target *target, uint32_t index) const s->Printf( format, GetByteSize(), m_flags, - m_mangled.GetName().AsCString("")); + name.AsCString("")); } else if (m_type == eSymbolTypeReExported) { s->Printf (" 0x%8.8x %s", m_flags, - m_mangled.GetName().AsCString("")); + name.AsCString("")); ConstString reexport_name = GetReExportedSymbolName(); intptr_t shlib = m_addr_range.GetByteSize(); @@ -349,7 +359,7 @@ Symbol::Dump(Stream *s, Target *target, uint32_t index) const m_addr_range.GetBaseAddress().GetOffset(), GetByteSize(), m_flags, - m_mangled.GetName().AsCString("")); + name.AsCString("")); } } @@ -439,7 +449,7 @@ bool Symbol::Compare(const ConstString& name, SymbolType type) const { if (type == eSymbolTypeAny || m_type == type) - return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name; + return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName(GetLanguage()) == name; return false; } @@ -635,6 +645,18 @@ Symbol::GetLoadAddress (Target *target) const return LLDB_INVALID_ADDRESS; } +ConstString +Symbol::GetName () const +{ + return m_mangled.GetName(GetLanguage()); +} + +ConstString +Symbol::GetNameNoArguments () const +{ + return m_mangled.GetName(GetLanguage(), Mangled::ePreferDemangledWithoutArguments); +} + lldb::addr_t Symbol::ResolveCallableAddress(Target &target) const diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp index 8e4240a4587d..4fb0dbc237c8 100644 --- a/source/Symbol/SymbolContext.cpp +++ b/source/Symbol/SymbolContext.cpp @@ -160,15 +160,15 @@ SymbolContext::DumpStopContext ( s->Printf("<"); dumped_something = true; } - else if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments)) - { - dumped_something = true; - function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments).Dump(s); - } - else if (function->GetMangled().GetName()) + else { - dumped_something = true; - function->GetMangled().GetName().Dump(s); + ConstString name; + if (show_function_arguments == false) + name = function->GetNameNoArguments(); + if (!name) + name = function->GetName(); + if (name) + name.Dump(s); } if (addr.IsValid()) @@ -192,7 +192,7 @@ SymbolContext::DumpStopContext ( dumped_something = true; Block *inlined_block = block->GetContainingInlinedBlock(); const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo(); - s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString()); + s->Printf (" [inlined] %s", inlined_block_info->GetName(function->GetLanguage()).GetCString()); lldb_private::AddressRange block_range; if (inlined_block->GetRangeContainingAddress(addr, block_range)) @@ -235,12 +235,12 @@ SymbolContext::DumpStopContext ( s->Printf("<"); dumped_something = true; } - else if (symbol->GetMangled().GetName()) + else if (symbol->GetName()) { dumped_something = true; if (symbol->GetType() == eSymbolTypeTrampoline) s->PutCString("symbol stub for: "); - symbol->GetMangled().GetName().Dump(s); + symbol->GetName().Dump(s); } if (addr.IsValid() && symbol->ValueIsAddress()) @@ -438,7 +438,7 @@ SymbolContext::Dump(Stream *s, Target *target) const s->Indent(); *s << "Symbol = " << (void *)symbol; if (symbol != nullptr && symbol->GetMangled()) - *s << ' ' << symbol->GetMangled().GetName().AsCString(); + *s << ' ' << symbol->GetName().AsCString(); s->EOL(); *s << "Variable = " << (void *)variable; if (variable != nullptr) @@ -681,14 +681,14 @@ SymbolContext::GetFunctionName (Mangled::NamePreference preference) const { const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo(); if (inline_info) - return inline_info->GetName(); + return inline_info->GetName(function->GetLanguage()); } } - return function->GetMangled().GetName(preference); + return function->GetMangled().GetName(function->GetLanguage(), preference); } else if (symbol && symbol->ValueIsAddress()) { - return symbol->GetMangled().GetName(preference); + return symbol->GetMangled().GetName(symbol->GetLanguage(), preference); } else { @@ -916,7 +916,7 @@ SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { was_inlined = true; const Mangled &name = inline_info->GetMangled(); - if (!name.NameMatches (func_name)) + if (!name.NameMatches (func_name, sc.function->GetLanguage())) return false; } } @@ -925,12 +925,12 @@ SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { if (sc.function != nullptr) { - if (!sc.function->GetMangled().NameMatches(func_name)) + if (!sc.function->GetMangled().NameMatches(func_name, sc.function->GetLanguage())) return false; } else if (sc.symbol != nullptr) { - if (!sc.symbol->GetMangled().NameMatches(func_name)) + if (!sc.symbol->GetMangled().NameMatches(func_name, sc.function->GetLanguage())) return false; } } diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp index 4cc03345d05b..c11efc0d9b24 100644 --- a/source/Symbol/Symtab.cpp +++ b/source/Symbol/Symtab.cpp @@ -136,7 +136,7 @@ Symtab::Dump (Stream *s, Target *target, SortOrder sort_order) CStringToSymbol name_map; for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); pos != end; ++pos) { - const char *name = pos->GetMangled().GetName(Mangled::ePreferDemangled).AsCString(); + const char *name = pos->GetName().AsCString(); if (name && name[0]) name_map.insert (std::make_pair(name, &(*pos))); } @@ -329,7 +329,7 @@ Symtab::InitNameIndexes() entry.cstring[2] != 'G' && // avoid guard variables entry.cstring[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back) { - CPPLanguageRuntime::MethodName cxx_method (mangled.GetDemangledName()); + CPPLanguageRuntime::MethodName cxx_method (mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus)); entry.cstring = ConstString(cxx_method.GetBasename()).GetCString(); if (entry.cstring && entry.cstring[0]) { @@ -378,7 +378,7 @@ Symtab::InitNameIndexes() } } - entry.cstring = mangled.GetDemangledName().GetCString(); + entry.cstring = mangled.GetDemangledName(symbol->GetLanguage()).GetCString(); if (entry.cstring && entry.cstring[0]) { m_name_to_index.Append (entry); @@ -486,7 +486,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes, const Mangled &mangled = symbol->GetMangled(); if (add_demangled) { - entry.cstring = mangled.GetDemangledName().GetCString(); + entry.cstring = mangled.GetDemangledName(symbol->GetLanguage()).GetCString(); if (entry.cstring && entry.cstring[0]) name_to_index_map.Append (entry); } @@ -746,7 +746,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp { if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) { - const char *name = m_symbols[i].GetMangled().GetName().AsCString(); + const char *name = m_symbols[i].GetName().AsCString(); if (name) { if (regexp.Execute (name)) @@ -773,7 +773,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility) == false) continue; - const char *name = m_symbols[i].GetMangled().GetName().AsCString(); + const char *name = m_symbols[i].GetName().AsCString(); if (name) { if (regexp.Execute (name)) diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp index 5665e4702ca6..2490e98ac1e8 100644 --- a/source/Symbol/Variable.cpp +++ b/source/Symbol/Variable.cpp @@ -15,6 +15,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Symbol/Block.h" +#include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" @@ -65,22 +66,48 @@ Variable::~Variable() { } +lldb::LanguageType +Variable::GetLanguage () const +{ + SymbolContext variable_sc; + m_owner_scope->CalculateSymbolContext(&variable_sc); + if (variable_sc.comp_unit) + return variable_sc.comp_unit->GetLanguage(); + return lldb::eLanguageTypeUnknown; +} + -const ConstString& + +ConstString Variable::GetName() const { - const ConstString &name = m_mangled.GetName(); + ConstString name = m_mangled.GetName(GetLanguage()); if (name) return name; return m_name; } bool +Variable::NameMatches (const ConstString &name) const +{ + if (m_name == name) + return true; + SymbolContext variable_sc; + m_owner_scope->CalculateSymbolContext(&variable_sc); + + LanguageType language = eLanguageTypeUnknown; + if (variable_sc.comp_unit) + language = variable_sc.comp_unit->GetLanguage(); + return m_mangled.NameMatches (name, language); +} +bool Variable::NameMatches (const RegularExpression& regex) const { if (regex.Execute (m_name.AsCString())) return true; - return m_mangled.NameMatches (regex); + if (m_mangled) + return m_mangled.NameMatches (regex, GetLanguage()); + return false; } Type * diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp index 6758ecf7e22e..2b586933ccd4 100644 --- a/source/Target/Platform.cpp +++ b/source/Target/Platform.cpp @@ -36,6 +36,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Utils.h" #include "llvm/Support/FileSystem.h" @@ -1536,27 +1537,6 @@ Platform::CalculateMD5 (const FileSpec& file_spec, return false; } -Error -Platform::LaunchNativeProcess ( - ProcessLaunchInfo &launch_info, - lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, - NativeProcessProtocolSP &process_sp) -{ - // Platforms should override this implementation if they want to - // support lldb-gdbserver. - return Error("unimplemented"); -} - -Error -Platform::AttachNativeProcess (lldb::pid_t pid, - lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, - NativeProcessProtocolSP &process_sp) -{ - // Platforms should override this implementation if they want to - // support lldb-gdbserver. - return Error("unimplemented"); -} - void Platform::SetLocalCacheDirectory (const char* local) { @@ -1951,3 +1931,18 @@ Platform::GetCacheHostname () { return GetHostname (); } + +const UnixSignalsSP & +Platform::GetRemoteUnixSignals() +{ + static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>(); + return s_default_unix_signals_sp; +} + +const UnixSignalsSP & +Platform::GetUnixSignals() +{ + if (IsHost()) + return Host::GetUnixSignals(); + return GetRemoteUnixSignals(); +} diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index 41942829ca55..3abae4fce5b1 100644 --- a/source/Target/Process.cpp +++ b/source/Target/Process.cpp @@ -693,7 +693,7 @@ Process::GetStaticBroadcasterClass () // Process constructor //---------------------------------------------------------------------- Process::Process(Target &target, Listener &listener) : - Process(target, listener, Host::GetUnixSignals ()) + Process(target, listener, UnixSignals::Create(HostInfo::GetArchitecture())) { // This constructor just delegates to the full Process constructor, // defaulting to using the Host's UnixSignals. @@ -754,6 +754,7 @@ Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_s m_force_next_event_delivery (false), m_last_broadcast_state (eStateInvalid), m_destroy_in_process (false), + m_can_interpret_function_calls(false), m_can_jit(eCanJITDontKnow) { CheckInWithManager (); @@ -763,14 +764,14 @@ Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_s log->Printf ("%p Process::Process()", static_cast<void*>(this)); if (!m_unix_signals_sp) - m_unix_signals_sp.reset (new UnixSignals ()); + m_unix_signals_sp = std::make_shared<UnixSignals>(); SetEventName (eBroadcastBitStateChanged, "state-changed"); SetEventName (eBroadcastBitInterrupt, "interrupt"); SetEventName (eBroadcastBitSTDOUT, "stdout-available"); SetEventName (eBroadcastBitSTDERR, "stderr-available"); SetEventName (eBroadcastBitProfileData, "profile-data-available"); - + m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" ); m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" ); m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume"); @@ -1145,6 +1146,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp, // Prefer a thread that has just completed its plan over another thread as current thread. ThreadSP plan_thread; ThreadSP other_thread; + const size_t num_threads = thread_list.GetSize(); size_t i; for (i = 0; i < num_threads; ++i) @@ -1157,10 +1159,22 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp, case eStopReasonNone: break; + case eStopReasonSignal: + { + // Don't select a signal thread if we weren't going to stop at that + // signal. We have to have had another reason for stopping here, and + // the user doesn't want to see this thread. + uint64_t signo = thread->GetStopInfo()->GetValue(); + if (process_sp->GetUnixSignals()->GetShouldStop(signo)) + { + if (!other_thread) + other_thread = thread; + } + break; + } case eStopReasonTrace: case eStopReasonBreakpoint: case eStopReasonWatchpoint: - case eStopReasonSignal: case eStopReasonException: case eStopReasonExec: case eStopReasonThreadExiting: @@ -1510,7 +1524,7 @@ Process::SetProcessExitStatus (void *callback_baton, { const char *signal_cstr = NULL; if (signo) - signal_cstr = process_sp->GetUnixSignals().GetSignalAsCString (signo); + signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo); process_sp->SetExitStatus (exit_status, signal_cstr); } @@ -2998,6 +3012,13 @@ Process::SetCanJIT (bool can_jit) m_can_jit = (can_jit ? eCanJITYes : eCanJITNo); } +void +Process::SetCanRunCode (bool can_run_code) +{ + SetCanJIT(can_run_code); + m_can_interpret_function_calls = can_run_code; +} + Error Process::DeallocateMemory (addr_t ptr) { @@ -4088,11 +4109,11 @@ Process::SetUnixSignals (const UnixSignalsSP &signals_sp) m_unix_signals_sp = signals_sp; } -UnixSignals & +const lldb::UnixSignalsSP & Process::GetUnixSignals () { assert (m_unix_signals_sp && "null m_unix_signals_sp"); - return *m_unix_signals_sp; + return m_unix_signals_sp; } lldb::ByteOrder diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp index 30c5aee63cad..bd2e1bc4c4a1 100644 --- a/source/Target/ProcessLaunchInfo.cpp +++ b/source/Target/ProcessLaunchInfo.cpp @@ -284,6 +284,13 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty) log->Printf ("ProcessLaunchInfo::%s at least one of stdin/stdout/stderr was not set, evaluating default handling", __FUNCTION__); + if (m_flags.Test(eLaunchFlagLaunchInTTY)) + { + // Do nothing, if we are launching in a remote terminal + // no file actions should be done at all. + return; + } + if (m_flags.Test(eLaunchFlagDisableSTDIO)) { if (log) diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp index 76e5f374f952..4f6ef7a92949 100644 --- a/source/Target/StopInfo.cpp +++ b/source/Target/StopInfo.cpp @@ -891,7 +891,7 @@ public: { ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) - return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value); + return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value); return false; } @@ -900,7 +900,7 @@ public: { ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) - return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value); + return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value); return false; } @@ -912,13 +912,13 @@ public: ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) { - bool should_notify = thread_sp->GetProcess()->GetUnixSignals().GetShouldNotify (m_value); + bool should_notify = thread_sp->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value); if (should_notify) { StreamString strm; strm.Printf ("thread %d received signal: %s", thread_sp->GetIndexID(), - thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value)); + thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(m_value)); Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData()); } return should_notify; @@ -933,7 +933,7 @@ public: ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) { - if (thread_sp->GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false) + if (thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(m_value) == false) thread_sp->SetResumeSignal(m_value); } } @@ -947,7 +947,7 @@ public: if (thread_sp) { StreamString strm; - const char *signal_name = thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value); + const char *signal_name = thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(m_value); if (signal_name) strm.Printf("signal %s", signal_name); else diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp index e742ece7ec50..e7b3abd3c941 100644 --- a/source/Target/ThreadPlanCallFunction.cpp +++ b/source/Target/ThreadPlanCallFunction.cpp @@ -147,15 +147,16 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, m_trap_exceptions (options.GetTrapExceptions()), m_function_addr (function), m_function_sp (0), - m_return_type (return_type), m_takedown_done (false), m_should_clear_objc_exception_bp(false), m_should_clear_cxx_exception_bp (false), - m_stop_address (LLDB_INVALID_ADDRESS) + m_stop_address (LLDB_INVALID_ADDRESS), + m_return_type (return_type) { - lldb::addr_t start_load_addr; - ABI *abi; - lldb::addr_t function_load_addr; + lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS; + ABI *abi = nullptr; + if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) return; @@ -171,6 +172,27 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, m_valid = true; } +ThreadPlanCallFunction::ThreadPlanCallFunction(Thread &thread, + const Address &function, + const EvaluateExpressionOptions &options) : + ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), + m_valid(false), + m_stop_other_threads(options.GetStopOthers()), + m_unwind_on_error(options.DoesUnwindOnError()), + m_ignore_breakpoints(options.DoesIgnoreBreakpoints()), + m_debug_execution(options.GetDebug()), + m_trap_exceptions(options.GetTrapExceptions()), + m_function_addr(function), + m_function_sp(0), + m_takedown_done(false), + m_should_clear_objc_exception_bp(false), + m_should_clear_cxx_exception_bp(false), + m_stop_address(LLDB_INVALID_ADDRESS), + m_return_type(ClangASTType()) +{ + +} + ThreadPlanCallFunction::~ThreadPlanCallFunction () { DoTakedown(PlanSucceeded()); @@ -222,13 +244,7 @@ ThreadPlanCallFunction::DoTakedown (bool success) { if (success) { - ProcessSP process_sp (m_thread.GetProcess()); - const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; - if (abi && m_return_type.IsValid()) - { - const bool persistent = false; - m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent); - } + SetReturnValue(); } if (log) log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", @@ -574,3 +590,15 @@ ThreadPlanCallFunction::RestoreThreadState() return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); } + +void +ThreadPlanCallFunction::SetReturnValue() +{ + ProcessSP process_sp(m_thread.GetProcess()); + const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; + if (abi && m_return_type.IsValid()) + { + const bool persistent = false; + m_return_valobj_sp = abi->GetReturnValueObject(m_thread, m_return_type, persistent); + } +} diff --git a/source/Target/ThreadPlanCallFunctionUsingABI.cpp b/source/Target/ThreadPlanCallFunctionUsingABI.cpp new file mode 100644 index 000000000000..53fabd2464e6 --- /dev/null +++ b/source/Target/ThreadPlanCallFunctionUsingABI.cpp @@ -0,0 +1,91 @@ +//===-- ThreadPlanCallFunctionUsingABI.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes + +// Project includes +#include "lldb/Core/Address.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +//-------------------------------------------------------------------------------------------- +// ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI instead of JIT +//------------------------------------------------------------------------------------------- +ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI (Thread &thread, + const Address &function, + llvm::Type &prototype, + llvm::Type &return_type, + llvm::ArrayRef<ABI::CallArgument> args, + const EvaluateExpressionOptions &options) : + ThreadPlanCallFunction(thread,function,options), + m_return_type(return_type) +{ + lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS; + ABI *abi = nullptr; + + if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr)) + return; + + if (!abi->PrepareTrivialCall(thread, + m_function_sp, + function_load_addr, + start_load_addr, + prototype, + args)) + return; + + ReportRegisterState("ABI Function call was set up. Register state was:"); + + m_valid = true; +} + +ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() +{ + +} + +void +ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s, DescriptionLevel level) +{ + if (level == eDescriptionLevelBrief) + { + s->Printf("Function call thread plan using ABI instead of JIT"); + } + else + { + TargetSP target_sp(m_thread.CalculateTarget()); + s->Printf("Thread plan to call 0x%" PRIx64" using ABI instead of JIT", m_function_addr.GetLoadAddress(target_sp.get())); + } +} + +void +ThreadPlanCallFunctionUsingABI::SetReturnValue() +{ + ProcessSP process_sp(m_thread.GetProcess()); + const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; + + // Ask the abi for the return value + if (abi) + { + const bool persistent = false; + m_return_valobj_sp = abi->GetReturnValueObject(m_thread, m_return_type, persistent); + } +} diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp index 701e93d3c4de..aba89224239c 100644 --- a/source/Target/ThreadPlanStepOverRange.cpp +++ b/source/Target/ThreadPlanStepOverRange.cpp @@ -430,7 +430,7 @@ ThreadPlanStepOverRange::DoWillResume (lldb::StateType resume_state, bool curren const InlineFunctionInfo *inline_info = frame_block->GetInlinedFunctionInfo(); const char *name; if (inline_info) - name = inline_info->GetName().AsCString(); + name = inline_info->GetName(frame_block->CalculateSymbolContextFunction()->GetLanguage()).AsCString(); else name = "<unknown-notinlined>"; diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp index 7f57579c1ee5..91579e8d7852 100644 --- a/source/Target/UnixSignals.cpp +++ b/source/Target/UnixSignals.cpp @@ -13,16 +13,21 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/ArchSpec.h" #include "lldb/Host/StringConvert.h" +#include "Plugins/Process/Utility/FreeBSDSignals.h" +#include "Plugins/Process/Utility/LinuxSignals.h" +#include "Plugins/Process/Utility/MipsLinuxSignals.h" + using namespace lldb_private; -UnixSignals::Signal::Signal +UnixSignals::Signal::Signal ( - const char *name, - const char *short_name, - bool default_suppress, - bool default_stop, + const char *name, + const char *short_name, + bool default_suppress, + bool default_stop, bool default_notify, const char *description ) : @@ -37,6 +42,34 @@ UnixSignals::Signal::Signal m_description.assign (description); } +lldb::UnixSignalsSP +UnixSignals::Create(const ArchSpec &arch) +{ + const auto &triple = arch.GetTriple(); + switch (triple.getOS()) + { + case llvm::Triple::Linux: + { + switch (triple.getArch()) + { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return std::make_shared<MipsLinuxSignals>(); + default: + return std::make_shared<LinuxSignals>(); + } + } + case llvm::Triple::FreeBSD: + case llvm::Triple::OpenBSD: + case llvm::Triple::NetBSD: + return std::make_shared<FreeBSDSignals>(); + default: + return std::make_shared<UnixSignals>(); + } +} + //---------------------------------------------------------------------- // UnixSignals constructor //---------------------------------------------------------------------- @@ -45,6 +78,11 @@ UnixSignals::UnixSignals () Reset (); } +UnixSignals::UnixSignals(const UnixSignals &rhs) + : m_signals(rhs.m_signals) +{ +} + //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- @@ -291,3 +329,19 @@ UnixSignals::SetShouldNotify (const char *signal_name, bool value) return SetShouldNotify (signo, value); return false; } + +int32_t +UnixSignals::GetNumSignals() const +{ + return m_signals.size(); +} + +int32_t +UnixSignals::GetSignalAtIndex(int32_t index) const +{ + if (index < 0 || m_signals.size() <= static_cast<size_t>(index)) + return LLDB_INVALID_SIGNAL_NUMBER; + auto it = m_signals.begin(); + std::advance(it, index); + return it->first; +} diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp index 0ba8cf4399ce..1e16a5ac9952 100644 --- a/source/Utility/JSON.cpp +++ b/source/Utility/JSON.cpp @@ -9,6 +9,10 @@ #include "lldb/Utility/JSON.h" +#include <limits.h> +#include "lldb/Core/StreamString.h" +#include "lldb/Host/StringConvert.h" + using namespace lldb_private; std::string @@ -33,20 +37,20 @@ JSONString::json_string_quote_metachars (const std::string &s) } JSONString::JSONString () : -JSONValue(JSONValue::Kind::String), -m_data() + JSONValue(JSONValue::Kind::String), + m_data() { } JSONString::JSONString (const char* s) : -JSONValue(JSONValue::Kind::String), -m_data(s ? s : "") + JSONValue(JSONValue::Kind::String), + m_data(s ? s : "") { } JSONString::JSONString (const std::string& s) : -JSONValue(JSONValue::Kind::String), -m_data(s) + JSONValue(JSONValue::Kind::String), + m_data(s) { } @@ -57,25 +61,41 @@ JSONString::Write (Stream& s) } JSONNumber::JSONNumber () : -JSONValue(JSONValue::Kind::Number), -m_data(0) + JSONValue(JSONValue::Kind::Number), + m_is_integer(true), + m_data(0), + m_double(0.0) +{ +} + +JSONNumber::JSONNumber (uint64_t i) : + JSONValue(JSONValue::Kind::Number), + m_is_integer(true), + m_data(i), + m_double(0.0) { } -JSONNumber::JSONNumber (int64_t i) : -JSONValue(JSONValue::Kind::Number), -m_data(i) + +JSONNumber::JSONNumber (double d) : + JSONValue(JSONValue::Kind::Number), + m_is_integer(false), + m_data(0), + m_double(d) { } void JSONNumber::Write (Stream& s) { - s.Printf("%" PRId64, m_data); + if (m_is_integer) + s.Printf("%" PRIu64, m_data); + else + s.Printf("%g", m_double); } JSONTrue::JSONTrue () : -JSONValue(JSONValue::Kind::True) + JSONValue(JSONValue::Kind::True) { } @@ -86,7 +106,7 @@ JSONTrue::Write(Stream& s) } JSONFalse::JSONFalse () : -JSONValue(JSONValue::Kind::False) + JSONValue(JSONValue::Kind::False) { } @@ -97,7 +117,7 @@ JSONFalse::Write(Stream& s) } JSONNull::JSONNull () : -JSONValue(JSONValue::Kind::Null) + JSONValue(JSONValue::Kind::Null) { } @@ -108,7 +128,7 @@ JSONNull::Write(Stream& s) } JSONObject::JSONObject () : -JSONValue(JSONValue::Kind::Object) + JSONValue(JSONValue::Kind::Object) { } @@ -153,7 +173,7 @@ JSONObject::GetObject (const std::string& key) } JSONArray::JSONArray () : -JSONValue(JSONValue::Kind::Array) + JSONValue(JSONValue::Kind::Array) { } @@ -215,3 +235,419 @@ JSONArray::GetNumElements () { return m_elements.size(); } + + +JSONParser::JSONParser (const char *cstr) : + StringExtractor(cstr) +{ +} + +JSONParser::Token +JSONParser::GetToken (std::string &value) +{ + StreamString error; + + value.clear(); + SkipSpaces (); + const uint64_t start_index = m_index; + const char ch = GetChar(); + switch (ch) + { + case '{': return Token::ObjectStart; + case '}': return Token::ObjectEnd; + case '[': return Token::ArrayStart; + case ']': return Token::ArrayEnd; + case ',': return Token::Comma; + case ':': return Token::Colon; + case '\0': return Token::EndOfFile; + case 't': + if (GetChar() == 'r') + if (GetChar() == 'u') + if (GetChar() == 'e') + return Token::True; + break; + + case 'f': + if (GetChar() == 'a') + if (GetChar() == 'l') + if (GetChar() == 's') + if (GetChar() == 'e') + return Token::False; + break; + + case 'n': + if (GetChar() == 'u') + if (GetChar() == 'l') + if (GetChar() == 'l') + return Token::Null; + break; + + case '"': + { + while (1) + { + bool was_escaped = false; + int escaped_ch = GetEscapedChar(was_escaped); + if (escaped_ch == -1) + { + error.Printf("error: an error occurred getting a character from offset %" PRIu64, start_index); + value = std::move(error.GetString()); + return Token::Error; + + } + else + { + const bool is_end_quote = escaped_ch == '"'; + const bool is_null = escaped_ch == 0; + if (was_escaped || (!is_end_quote && !is_null)) + { + if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) + { + value.append(1, (char)escaped_ch); + } + else + { + error.Printf("error: wide character support is needed for unicode character 0x%4.4x at offset %" PRIu64, escaped_ch, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + } + else if (is_end_quote) + { + return Token::String; + } + else if (is_null) + { + value = "error: missing end quote for string"; + return Token::Error; + } + } + } + } + break; + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + bool done = false; + bool got_decimal_point = false; + uint64_t exp_index = 0; + bool got_int_digits = (ch >= '0') && (ch <= '9'); + bool got_frac_digits = false; + bool got_exp_digits = false; + while (!done) + { + const char next_ch = PeekChar(); + switch (next_ch) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (exp_index != 0) + { + got_exp_digits = true; + } + else if (got_decimal_point) + { + got_frac_digits = true; + } + else + { + got_int_digits = true; + } + ++m_index; // Skip this character + break; + + case '.': + if (got_decimal_point) + { + error.Printf("error: extra decimal point found at offset %" PRIu64, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + else + { + got_decimal_point = true; + ++m_index; // Skip this character + } + break; + + case 'e': + case 'E': + if (exp_index != 0) + { + error.Printf("error: extra expenent character found at offset %" PRIu64, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + else + { + exp_index = m_index; + ++m_index; // Skip this character + } + break; + + case '+': + case '-': + // The '+' and '-' can only come after an exponent character... + if (exp_index == m_index - 1) + { + ++m_index; // Skip the exponent sign character + } + else + { + error.Printf("error: unexpected %c character at offset %" PRIu64, next_ch, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + + default: + done = true; + break; + } + } + + if (m_index > start_index) + { + value = m_packet.substr(start_index, m_index - start_index); + if (got_decimal_point) + { + if (exp_index != 0) + { + // We have an exponent, make sure we got exponent digits + if (got_exp_digits) + { + return Token::Float; + } + else + { + error.Printf("error: got exponent character but no exponent digits at offset in float value \"%s\"", value.c_str()); + value = std::move(error.GetString()); + return Token::Error; + } + } + else + { + // No exponent, but we need at least one decimal after the decimal point + if (got_frac_digits) + { + return Token::Float; + } + else + { + error.Printf("error: no digits after decimal point \"%s\"", value.c_str()); + value = std::move(error.GetString()); + return Token::Error; + } + } + } + else + { + // No decimal point + if (got_int_digits) + { + // We need at least some integer digits to make an integer + return Token::Integer; + } + else + { + error.Printf("error: no digits negate sign \"%s\"", value.c_str()); + value = std::move(error.GetString()); + return Token::Error; + } + } + } + else + { + error.Printf("error: invalid number found at offset %" PRIu64, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + } + break; + default: + break; + } + error.Printf("error: failed to parse token at offset %" PRIu64 " (around character '%c')", start_index, ch); + value = std::move(error.GetString()); + return Token::Error; +} + +int +JSONParser::GetEscapedChar(bool &was_escaped) +{ + was_escaped = false; + const char ch = GetChar(); + if (ch == '\\') + { + was_escaped = true; + const char ch2 = GetChar(); + switch (ch2) + { + case '"': + case '\\': + case '/': + default: + break; + + case 'b': return '\b'; + case 'f': return '\f'; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + case 'u': + { + const int hi_byte = DecodeHexU8(); + const int lo_byte = DecodeHexU8(); + if (hi_byte >=0 && lo_byte >= 0) + return hi_byte << 8 | lo_byte; + return -1; + } + break; + } + return ch2; + } + return ch; +} + +JSONValue::SP +JSONParser::ParseJSONObject () +{ + // The "JSONParser::Token::ObjectStart" token should have already been consumed + // by the time this function is called + std::unique_ptr<JSONObject> dict_up(new JSONObject()); + + std::string value; + std::string key; + while (1) + { + JSONParser::Token token = GetToken(value); + + if (token == JSONParser::Token::String) + { + key.swap(value); + token = GetToken(value); + if (token == JSONParser::Token::Colon) + { + JSONValue::SP value_sp = ParseJSONValue(); + if (value_sp) + dict_up->SetObject(key, value_sp); + else + break; + } + } + else if (token == JSONParser::Token::ObjectEnd) + { + return JSONValue::SP(dict_up.release()); + } + else if (token == JSONParser::Token::Comma) + { + continue; + } + else + { + break; + } + } + return JSONValue::SP(); +} + +JSONValue::SP +JSONParser::ParseJSONArray () +{ + // The "JSONParser::Token::ObjectStart" token should have already been consumed + // by the time this function is called + std::unique_ptr<JSONArray> array_up(new JSONArray()); + + std::string value; + std::string key; + while (1) + { + JSONValue::SP value_sp = ParseJSONValue(); + if (value_sp) + array_up->AppendObject(value_sp); + else + break; + + JSONParser::Token token = GetToken(value); + if (token == JSONParser::Token::Comma) + { + continue; + } + else if (token == JSONParser::Token::ArrayEnd) + { + return JSONValue::SP(array_up.release()); + } + else + { + break; + } + } + return JSONValue::SP(); +} + +JSONValue::SP +JSONParser::ParseJSONValue () +{ + std::string value; + const JSONParser::Token token = GetToken(value); + switch (token) + { + case JSONParser::Token::ObjectStart: + return ParseJSONObject(); + + case JSONParser::Token::ArrayStart: + return ParseJSONArray(); + + case JSONParser::Token::Integer: + { + bool success = false; + uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); + if (success) + return JSONValue::SP(new JSONNumber(uval)); + } + break; + + case JSONParser::Token::Float: + { + bool success = false; + double val = StringConvert::ToDouble(value.c_str(), 0.0, &success); + if (success) + return JSONValue::SP(new JSONNumber(val)); + } + break; + + case JSONParser::Token::String: + return JSONValue::SP(new JSONString(value)); + + case JSONParser::Token::True: + return JSONValue::SP(new JSONTrue()); + + case JSONParser::Token::False: + return JSONValue::SP(new JSONFalse()); + + case JSONParser::Token::Null: + return JSONValue::SP(new JSONNull()); + + default: + break; + } + return JSONValue::SP(); + +} diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp index e82c83dfd093..6302c033c0c1 100644 --- a/source/Utility/StringExtractor.cpp +++ b/source/Utility/StringExtractor.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "Utility/StringExtractor.h" +#include "lldb/Utility/StringExtractor.h" // C Includes #include <stdlib.h> @@ -476,3 +476,12 @@ StringExtractor::GetNameColonValue (std::string &name, std::string &value) m_index = UINT64_MAX; return false; } + +void +StringExtractor::SkipSpaces () +{ + const size_t n = m_packet.size(); + while (m_index < n && isspace(m_packet[m_index])) + ++m_index; +} + diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp index aeceaa00fa1c..17ee0b63f3e5 100644 --- a/source/Utility/StringExtractorGDBRemote.cpp +++ b/source/Utility/StringExtractorGDBRemote.cpp @@ -82,7 +82,7 @@ StringExtractorGDBRemote::GetServerPacketType () const case 'A': return eServerPacketType_A; - + case 'Q': switch (packet_cstr[1]) @@ -122,7 +122,7 @@ StringExtractorGDBRemote::GetServerPacketType () const break; } break; - + case 'q': switch (packet_cstr[1]) { @@ -219,6 +219,10 @@ StringExtractorGDBRemote::GetServerPacketType () const break; } break; + + case 'j': + if (PACKET_MATCHES("jSignalInfo")) return eServerPacketType_jSignalsInfo; + case 'v': if (PACKET_STARTS_WITH("vFile:")) { diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h index beb07e5b57ea..475b5a8e36c8 100644 --- a/source/Utility/StringExtractorGDBRemote.h +++ b/source/Utility/StringExtractorGDBRemote.h @@ -15,7 +15,7 @@ #include <string> // Other libraries and framework includes // Project includes -#include "Utility/StringExtractor.h" +#include "lldb/Utility/StringExtractor.h" class StringExtractorGDBRemote : public StringExtractor { @@ -118,6 +118,8 @@ public: eServerPacketType_qWatchpointSupportInfoSupported, eServerPacketType_qXfer_auxv_read, + eServerPacketType_jSignalsInfo, + eServerPacketType_vAttach, eServerPacketType_vAttachWait, eServerPacketType_vAttachOrWait, diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp index 91b92d25f434..3b2eadd836b3 100644 --- a/tools/driver/Driver.cpp +++ b/tools/driver/Driver.cpp @@ -452,7 +452,7 @@ Driver::OptionData::Clear () } void -Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, bool silent, SBError &error) +Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, SBError &error) { std::vector<InitialCmdEntry> *command_set; switch (placement) @@ -472,18 +472,18 @@ Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement pla { SBFileSpec file(command); if (file.Exists()) - command_set->push_back (InitialCmdEntry(command, is_file, silent)); + command_set->push_back (InitialCmdEntry(command, is_file)); else if (file.ResolveExecutableLocation()) { char final_path[PATH_MAX]; file.GetPath (final_path, sizeof(final_path)); - command_set->push_back (InitialCmdEntry(final_path, is_file, silent)); + command_set->push_back (InitialCmdEntry(final_path, is_file)); } else error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); } else - command_set->push_back (InitialCmdEntry(command, is_file, silent)); + command_set->push_back (InitialCmdEntry(command, is_file)); } void @@ -746,10 +746,10 @@ Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting) break; case 'K': - m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true, true, error); + m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true, error); break; case 'k': - m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, false, true, error); + m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, false, error); break; case 'n': @@ -770,16 +770,16 @@ Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting) } break; case 's': - m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true, true, error); + m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true, error); break; case 'o': - m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false, true, error); + m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false, error); break; case 'S': - m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true, true, error); + m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true, error); break; case 'O': - m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, false, true, error); + m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, false, error); break; default: m_option_data.m_print_help = true; diff --git a/tools/driver/Driver.h b/tools/driver/Driver.h index 38b125481d92..b1e536d43c05 100644 --- a/tools/driver/Driver.h +++ b/tools/driver/Driver.h @@ -75,7 +75,7 @@ public: Clear(); void - AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, bool quietly, lldb::SBError &error); + AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, lldb::SBError &error); //static OptionDefinition m_cmd_option_table[]; diff --git a/tools/lldb-mi/MICmdArgSet.h b/tools/lldb-mi/MICmdArgSet.h index 00da679d7733..0dd2933f3bb8 100644 --- a/tools/lldb-mi/MICmdArgSet.h +++ b/tools/lldb-mi/MICmdArgSet.h @@ -28,7 +28,7 @@ class CMICmdArgValBase; // Argument objects added to *this container are owned by this container // and are deleted when this container goes out of scope. Allocate argument // objects on the heap. -// It is assummed the arguments to be parsed are read from left to right in +// It is assumed the arguments to be parsed are read from left to right in // order. The order added to *this container is the order they will parsed. // Gotchas: None. // Authors: Illya Rudkin 14/04/2014. diff --git a/tools/lldb-mi/MICmdArgValBase.h b/tools/lldb-mi/MICmdArgValBase.h index 0d0eedd6e5b7..3aaae499e5fc 100644 --- a/tools/lldb-mi/MICmdArgValBase.h +++ b/tools/lldb-mi/MICmdArgValBase.h @@ -43,18 +43,18 @@ class CMICmdArgValBase : public CMICmdArgSet::IArg // Overrideable: public: - /* dtor */ virtual ~CMICmdArgValBase(void); + /* dtor */ ~CMICmdArgValBase(void) override; // Overridden: public: // From CMICmdArgSet::IArg - virtual bool GetFound(void) const; - virtual bool GetIsHandledByCmd(void) const; - virtual bool GetIsMandatory(void) const; - virtual bool GetIsMissingOptions(void) const; - virtual const CMIUtilString &GetName(void) const; - virtual bool GetValid(void) const; - virtual bool Validate(CMICmdArgContext &vwArgContext); + bool GetFound(void) const override; + bool GetIsHandledByCmd(void) const override; + bool GetIsMandatory(void) const override; + bool GetIsMissingOptions(void) const override; + const CMIUtilString &GetName(void) const override; + bool GetValid(void) const override; + bool Validate(CMICmdArgContext &vwArgContext) override; // Attributes: protected: diff --git a/tools/lldb-mi/MICmdArgValConsume.h b/tools/lldb-mi/MICmdArgValConsume.h index 1d37b79eba14..75768ff52e61 100644 --- a/tools/lldb-mi/MICmdArgValConsume.h +++ b/tools/lldb-mi/MICmdArgValConsume.h @@ -45,7 +45,7 @@ class CMICmdArgValConsume : public CMICmdArgValBaseTemplate<CMIUtilString> // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValConsume(void); + /* dtor */ ~CMICmdArgValConsume(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vwArgContext); + bool Validate(CMICmdArgContext &vwArgContext) override; }; diff --git a/tools/lldb-mi/MICmdArgValFile.h b/tools/lldb-mi/MICmdArgValFile.h index 196f21fb3b34..07abc4baa242 100644 --- a/tools/lldb-mi/MICmdArgValFile.h +++ b/tools/lldb-mi/MICmdArgValFile.h @@ -39,9 +39,9 @@ class CMICmdArgValFile : public CMICmdArgValBaseTemplate<CMIUtilString> // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValFile(void); + /* dtor */ ~CMICmdArgValFile(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vwArgContext); + bool Validate(CMICmdArgContext &vwArgContext) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdArgValListBase.h b/tools/lldb-mi/MICmdArgValListBase.h index 153af814dcfc..f0135620321f 100644 --- a/tools/lldb-mi/MICmdArgValListBase.h +++ b/tools/lldb-mi/MICmdArgValListBase.h @@ -75,7 +75,7 @@ class CMICmdArgValListBase : public CMICmdArgValBaseTemplate<std::vector<CMICmdA // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValListBase(void); + /* dtor */ ~CMICmdArgValListBase(void) override; // Methods: protected: diff --git a/tools/lldb-mi/MICmdArgValListOfN.h b/tools/lldb-mi/MICmdArgValListOfN.h index 356b494c0898..496bc6581117 100644 --- a/tools/lldb-mi/MICmdArgValListOfN.h +++ b/tools/lldb-mi/MICmdArgValListOfN.h @@ -49,9 +49,9 @@ class CMICmdArgValListOfN : public CMICmdArgValListBase // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValListOfN(void); + /* dtor */ ~CMICmdArgValListOfN(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vArgContext); + bool Validate(CMICmdArgContext &vArgContext) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdArgValNumber.h b/tools/lldb-mi/MICmdArgValNumber.h index fea94b698f74..58a28b379e3e 100644 --- a/tools/lldb-mi/MICmdArgValNumber.h +++ b/tools/lldb-mi/MICmdArgValNumber.h @@ -52,9 +52,9 @@ class CMICmdArgValNumber : public CMICmdArgValBaseTemplate<MIint64> // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValNumber(void); + /* dtor */ ~CMICmdArgValNumber(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vwArgContext); + bool Validate(CMICmdArgContext &vwArgContext) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdArgValOptionLong.h b/tools/lldb-mi/MICmdArgValOptionLong.h index ace939b64f83..ac55c47fb7af 100644 --- a/tools/lldb-mi/MICmdArgValOptionLong.h +++ b/tools/lldb-mi/MICmdArgValOptionLong.h @@ -46,9 +46,9 @@ class CMICmdArgValOptionLong : public CMICmdArgValListBase // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValOptionLong(void); + /* dtor */ ~CMICmdArgValOptionLong(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vArgContext); + bool Validate(CMICmdArgContext &vArgContext) override; // Methods: protected: diff --git a/tools/lldb-mi/MICmdArgValOptionShort.cpp b/tools/lldb-mi/MICmdArgValOptionShort.cpp index 25eac676f5f9..d18f72eaa8b1 100644 --- a/tools/lldb-mi/MICmdArgValOptionShort.cpp +++ b/tools/lldb-mi/MICmdArgValOptionShort.cpp @@ -80,7 +80,7 @@ CMICmdArgValOptionShort::IsArgShortOption(const CMIUtilString &vrTxt) const return false; // Look for -f short option - nPos = vrTxt.find("-"); + nPos = vrTxt.find('-'); if (nPos != 0) return false; diff --git a/tools/lldb-mi/MICmdArgValOptionShort.h b/tools/lldb-mi/MICmdArgValOptionShort.h index 971a0d3a148c..9157b37bb8dc 100644 --- a/tools/lldb-mi/MICmdArgValOptionShort.h +++ b/tools/lldb-mi/MICmdArgValOptionShort.h @@ -44,11 +44,11 @@ class CMICmdArgValOptionShort : public CMICmdArgValOptionLong // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValOptionShort(void); + /* dtor */ ~CMICmdArgValOptionShort(void) override; // Overridden: private: // From CMICmdArgValOptionLong - virtual bool IsArgOptionCorrect(const CMIUtilString &vrTxt) const; - virtual bool ArgNameMatch(const CMIUtilString &vrTxt) const; + bool IsArgOptionCorrect(const CMIUtilString &vrTxt) const override; + bool ArgNameMatch(const CMIUtilString &vrTxt) const override; }; diff --git a/tools/lldb-mi/MICmdArgValPrintValues.h b/tools/lldb-mi/MICmdArgValPrintValues.h index 37de923e9e52..9ac3238aeb75 100644 --- a/tools/lldb-mi/MICmdArgValPrintValues.h +++ b/tools/lldb-mi/MICmdArgValPrintValues.h @@ -38,9 +38,9 @@ class CMICmdArgValPrintValues : public CMICmdArgValBaseTemplate<MIuint> // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValPrintValues(void); + /* dtor */ ~CMICmdArgValPrintValues(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vArgContext); + bool Validate(CMICmdArgContext &vArgContext) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdArgValString.cpp b/tools/lldb-mi/MICmdArgValString.cpp index c8d32901a4e5..1c3e5f84d3dd 100644 --- a/tools/lldb-mi/MICmdArgValString.cpp +++ b/tools/lldb-mi/MICmdArgValString.cpp @@ -231,11 +231,11 @@ CMICmdArgValString::IsStringArgSingleText(const CMIUtilString &vrTxt) const return false; // Look for -f type short options, if found reject - if ((0 == vrTxt.find("-")) && (vrTxt.length() == 2)) + if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2)) return false; // Look for thread group i1 i2 i3...., if found reject - if ((vrTxt.find("i") == 0) && ::isdigit(vrTxt[1])) + if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1])) return false; // Look for numbers, if found reject diff --git a/tools/lldb-mi/MICmdArgValString.h b/tools/lldb-mi/MICmdArgValString.h index 54051d615919..8b58a0a88dd6 100644 --- a/tools/lldb-mi/MICmdArgValString.h +++ b/tools/lldb-mi/MICmdArgValString.h @@ -41,9 +41,9 @@ class CMICmdArgValString : public CMICmdArgValBaseTemplate<CMIUtilString> // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValString(void); + /* dtor */ ~CMICmdArgValString(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vrwArgContext); + bool Validate(CMICmdArgContext &vrwArgContext) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.h b/tools/lldb-mi/MICmdArgValThreadGrp.h index d361f3a87477..64c11405e8ab 100644 --- a/tools/lldb-mi/MICmdArgValThreadGrp.h +++ b/tools/lldb-mi/MICmdArgValThreadGrp.h @@ -39,9 +39,9 @@ class CMICmdArgValThreadGrp : public CMICmdArgValBaseTemplate<MIuint> // Overridden: public: // From CMICmdArgValBase - /* dtor */ virtual ~CMICmdArgValThreadGrp(void); + /* dtor */ ~CMICmdArgValThreadGrp(void) override; // From CMICmdArgSet::IArg - virtual bool Validate(CMICmdArgContext &vArgContext); + bool Validate(CMICmdArgContext &vArgContext) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdBase.cpp b/tools/lldb-mi/MICmdBase.cpp index de4fec2ff2ff..97bf5a074d6d 100644 --- a/tools/lldb-mi/MICmdBase.cpp +++ b/tools/lldb-mi/MICmdBase.cpp @@ -69,7 +69,7 @@ CMICmdBase::GetErrorDescription(void) const // options description string. // Type: Overridden. // Args: None. -// Return: CMIUtilString & - Command decription. +// Return: CMIUtilString & - Command description. // Throws: None. //-- const CMIUtilString & @@ -141,7 +141,7 @@ CMICmdBase::GetMIResultRecord(void) const //++ ------------------------------------------------------------------------------------ // Details: Retrieve from the command additional MI result to its 1 line response. -// Because of using LLDB addtional 'fake'/hack output is sometimes required to +// Because of using LLDB additional 'fake'/hack output is sometimes required to // help the driver client operate i.e. Eclipse. // Type: Overridden. // Args: None. @@ -156,7 +156,7 @@ CMICmdBase::GetMIResultRecordExtra(void) const //++ ------------------------------------------------------------------------------------ // Details: Hss *this command got additional MI result to its 1 line response. -// Because of using LLDB addtional 'fake'/hack output is sometimes required to +// Because of using LLDB additional 'fake'/hack output is sometimes required to // help the driver client operate i.e. Eclipse. // Type: Overridden. // Args: None. diff --git a/tools/lldb-mi/MICmdBase.h b/tools/lldb-mi/MICmdBase.h index 7209f4fe5d12..df1e429bdce6 100644 --- a/tools/lldb-mi/MICmdBase.h +++ b/tools/lldb-mi/MICmdBase.h @@ -25,7 +25,7 @@ class CMICmnLLDBDebugSessionInfo; //++ ============================================================================ // Details: MI command base class. MI commands derive from this base class. // The Command Factory creates command objects and passes them to the -// Command Invoker. The Invoker takes ownersip of any commands created +// Command Invoker. The Invoker takes ownership of any commands created // which means it is the only object to delete them when a command is // finished working. Commands do not delete themselves. // There are two types of command implicitly defined by the state of diff --git a/tools/lldb-mi/MICmdCmd.h b/tools/lldb-mi/MICmdCmd.h index a360ad6a56af..26697643c5e3 100644 --- a/tools/lldb-mi/MICmdCmd.h +++ b/tools/lldb-mi/MICmdCmd.h @@ -59,10 +59,10 @@ class CMICmdCmdEnablePrettyPrinting : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdEnablePrettyPrinting(void); + /* dtor */ ~CMICmdCmdEnablePrettyPrinting(void) override; }; //++ ============================================================================ @@ -86,8 +86,8 @@ class CMICmdCmdSource : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdSource(void); + /* dtor */ ~CMICmdCmdSource(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp index 1b3480984bb5..8a310c79d02b 100644 --- a/tools/lldb-mi/MICmdCmdBreak.cpp +++ b/tools/lldb-mi/MICmdCmdBreak.cpp @@ -1009,7 +1009,7 @@ CMICmdCmdBreakCondition::CreateSelf(void) // a single string i.e. '2' -> ok. // a quoted string i.e. "a > 100" -> ok // a non quoted string i.e. 'a > 100' -> not ok -// CMICmdArgValString only extracts the first space seperated string, the "a". +// CMICmdArgValString only extracts the first space separated string, the "a". // This function using the optional argument type CMICmdArgValListOfN collects // the rest of the expression so that is may be added to the 'a' part to form a // complete expression string i.e. "a > 100". diff --git a/tools/lldb-mi/MICmdCmdBreak.h b/tools/lldb-mi/MICmdCmdBreak.h index 06a3434ca5bb..476ab45762de 100644 --- a/tools/lldb-mi/MICmdCmdBreak.h +++ b/tools/lldb-mi/MICmdCmdBreak.h @@ -53,11 +53,11 @@ class CMICmdCmdBreakInsert : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdBreakInsert(void); + /* dtor */ ~CMICmdCmdBreakInsert(void) override; // Enumerations: private: @@ -122,11 +122,11 @@ class CMICmdCmdBreakDelete : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdBreakDelete(void); + /* dtor */ ~CMICmdCmdBreakDelete(void) override; // Attributes: private: @@ -155,11 +155,11 @@ class CMICmdCmdBreakDisable : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdBreakDisable(void); + /* dtor */ ~CMICmdCmdBreakDisable(void) override; // Attributes: private: @@ -190,11 +190,11 @@ class CMICmdCmdBreakEnable : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdBreakEnable(void); + /* dtor */ ~CMICmdCmdBreakEnable(void) override; // Attributes: private: @@ -225,11 +225,11 @@ class CMICmdCmdBreakAfter : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdBreakAfter(void); + /* dtor */ ~CMICmdCmdBreakAfter(void) override; // Attributes: private: @@ -261,11 +261,11 @@ class CMICmdCmdBreakCondition : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdBreakCondition(void); + /* dtor */ ~CMICmdCmdBreakCondition(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp index bd0209337cd4..0b950d5a4c4b 100644 --- a/tools/lldb-mi/MICmdCmdData.cpp +++ b/tools/lldb-mi/MICmdCmdData.cpp @@ -1750,8 +1750,8 @@ CMICmdCmdDataInfoLine::Acknowledge(void) // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1] // ^^^^^^^^^^^^^^^^^^ -- start address - const size_t nStartAddressStartPos = rLine.find("["); - const size_t nStartAddressEndPos = rLine.find("-"); + const size_t nStartAddressStartPos = rLine.find('['); + const size_t nStartAddressEndPos = rLine.find('-'); const size_t nStartAddressLen = nStartAddressEndPos - nStartAddressStartPos - 1; const CMIUtilString strStartAddress(rLine.substr(nStartAddressStartPos + 1, nStartAddressLen).c_str()); const CMICmnMIValueConst miValueConst(strStartAddress); @@ -1760,7 +1760,7 @@ CMICmdCmdDataInfoLine::Acknowledge(void) // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1] // ^^^^^^^^^^^^^^^^^^ -- end address - const size_t nEndAddressEndPos = rLine.find(")"); + const size_t nEndAddressEndPos = rLine.find(')'); const size_t nEndAddressLen = nEndAddressEndPos - nStartAddressEndPos - 1; const CMIUtilString strEndAddress(rLine.substr(nStartAddressEndPos + 1, nEndAddressLen).c_str()); const CMICmnMIValueConst miValueConst2(strEndAddress); diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h index 11873e9cbe4f..576441024a37 100644 --- a/tools/lldb-mi/MICmdCmdData.h +++ b/tools/lldb-mi/MICmdCmdData.h @@ -60,11 +60,11 @@ class CMICmdCmdDataEvaluateExpression : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataEvaluateExpression(void); + /* dtor */ ~CMICmdCmdDataEvaluateExpression(void) override; // Methods: private: @@ -105,11 +105,11 @@ class CMICmdCmdDataDisassemble : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataDisassemble(void); + /* dtor */ ~CMICmdCmdDataDisassemble(void) override; // Attributes: private: @@ -142,11 +142,11 @@ class CMICmdCmdDataReadMemoryBytes : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataReadMemoryBytes(void); + /* dtor */ ~CMICmdCmdDataReadMemoryBytes(void) override; // Attributes: private: @@ -181,10 +181,10 @@ class CMICmdCmdDataReadMemory : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataReadMemory(void); + /* dtor */ ~CMICmdCmdDataReadMemory(void) override; }; //++ ============================================================================ @@ -208,11 +208,11 @@ class CMICmdCmdDataListRegisterNames : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataListRegisterNames(void); + /* dtor */ ~CMICmdCmdDataListRegisterNames(void) override; // Methods: private: @@ -246,11 +246,11 @@ class CMICmdCmdDataListRegisterValues : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataListRegisterValues(void); + /* dtor */ ~CMICmdCmdDataListRegisterValues(void) override; // Methods: private: @@ -287,10 +287,10 @@ class CMICmdCmdDataListRegisterChanged : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataListRegisterChanged(void); + /* dtor */ ~CMICmdCmdDataListRegisterChanged(void) override; }; //++ ============================================================================ @@ -314,11 +314,11 @@ class CMICmdCmdDataWriteMemoryBytes : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataWriteMemoryBytes(void); + /* dtor */ ~CMICmdCmdDataWriteMemoryBytes(void) override; // Attributes: private: @@ -351,11 +351,11 @@ class CMICmdCmdDataWriteMemory : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataWriteMemory(void); + /* dtor */ ~CMICmdCmdDataWriteMemory(void) override; // Attributes: private: @@ -390,11 +390,11 @@ class CMICmdCmdDataInfoLine : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdDataInfoLine(void); + /* dtor */ ~CMICmdCmdDataInfoLine(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdCmdEnviro.h b/tools/lldb-mi/MICmdCmdEnviro.h index 1fb699e989b6..7d5cf98dd4bc 100644 --- a/tools/lldb-mi/MICmdCmdEnviro.h +++ b/tools/lldb-mi/MICmdCmdEnviro.h @@ -46,11 +46,11 @@ class CMICmdCmdEnvironmentCd : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdEnvironmentCd(void); + /* dtor */ ~CMICmdCmdEnvironmentCd(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdCmdExec.h b/tools/lldb-mi/MICmdCmdExec.h index 8889fb96402e..94d646fd8325 100644 --- a/tools/lldb-mi/MICmdCmdExec.h +++ b/tools/lldb-mi/MICmdCmdExec.h @@ -56,10 +56,10 @@ class CMICmdCmdExecRun : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecRun(void); + /* dtor */ ~CMICmdCmdExecRun(void) override; // Attributes: private: @@ -87,10 +87,10 @@ class CMICmdCmdExecContinue : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecContinue(void); + /* dtor */ ~CMICmdCmdExecContinue(void) override; // Attributes: private: @@ -118,11 +118,11 @@ class CMICmdCmdExecNext : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecNext(void); + /* dtor */ ~CMICmdCmdExecNext(void) override; // Attributes: private: @@ -152,11 +152,11 @@ class CMICmdCmdExecStep : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecStep(void); + /* dtor */ ~CMICmdCmdExecStep(void) override; // Attributes: private: @@ -186,11 +186,11 @@ class CMICmdCmdExecNextInstruction : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecNextInstruction(void); + /* dtor */ ~CMICmdCmdExecNextInstruction(void) override; // Attributes: private: @@ -220,11 +220,11 @@ class CMICmdCmdExecStepInstruction : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecStepInstruction(void); + /* dtor */ ~CMICmdCmdExecStepInstruction(void) override; // Attributes: private: @@ -254,11 +254,11 @@ class CMICmdCmdExecFinish : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecFinish(void); + /* dtor */ ~CMICmdCmdExecFinish(void) override; // Attributes: private: @@ -290,10 +290,10 @@ class CMICmdCmdExecInterrupt : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecInterrupt(void); + /* dtor */ ~CMICmdCmdExecInterrupt(void) override; // Attributes: private: @@ -321,11 +321,11 @@ class CMICmdCmdExecArguments : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecArguments(void); + /* dtor */ ~CMICmdCmdExecArguments(void) override; // Attributes: private: @@ -350,8 +350,8 @@ class CMICmdCmdExecAbort : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdExecAbort(void); + /* dtor */ ~CMICmdCmdExecAbort(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdFile.h b/tools/lldb-mi/MICmdCmdFile.h index 307f4f887aa5..2c1b59ca47ad 100644 --- a/tools/lldb-mi/MICmdCmdFile.h +++ b/tools/lldb-mi/MICmdCmdFile.h @@ -29,7 +29,7 @@ // Details: MI command class. MI commands derived from the command base class. // *this class implements MI command "file-exec-and-symbols". // This command does not follow the MI documentation exactly. -// Gotchas: This command has additonal flags that were not available in GDB MI. +// Gotchas: This command has additional flags that were not available in GDB MI. // See MIextensions.txt for details. // Authors: Illya Rudkin 25/02/2014. // Changes: None. @@ -48,12 +48,12 @@ class CMICmdCmdFileExecAndSymbols : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdFileExecAndSymbols(void); - virtual bool GetExitAppOnCommandFailure(void) const; + /* dtor */ ~CMICmdCmdFileExecAndSymbols(void) override; + bool GetExitAppOnCommandFailure(void) const override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.h b/tools/lldb-mi/MICmdCmdGdbInfo.h index eb60f8277c01..a1b5770e200b 100644 --- a/tools/lldb-mi/MICmdCmdGdbInfo.h +++ b/tools/lldb-mi/MICmdCmdGdbInfo.h @@ -55,11 +55,11 @@ class CMICmdCmdGdbInfo : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdGdbInfo(void); + /* dtor */ ~CMICmdCmdGdbInfo(void) override; // Typedefs: private: diff --git a/tools/lldb-mi/MICmdCmdGdbSet.h b/tools/lldb-mi/MICmdCmdGdbSet.h index 0095f81838d1..84d21f0557b7 100644 --- a/tools/lldb-mi/MICmdCmdGdbSet.h +++ b/tools/lldb-mi/MICmdCmdGdbSet.h @@ -55,11 +55,11 @@ class CMICmdCmdGdbSet : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdGdbSet(void); + /* dtor */ ~CMICmdCmdGdbSet(void) override; // Typedefs: private: diff --git a/tools/lldb-mi/MICmdCmdGdbShow.h b/tools/lldb-mi/MICmdCmdGdbShow.h index 5cb4cb58f809..6ca5ef8781a0 100644 --- a/tools/lldb-mi/MICmdCmdGdbShow.h +++ b/tools/lldb-mi/MICmdCmdGdbShow.h @@ -52,11 +52,11 @@ class CMICmdCmdGdbShow : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdGdbShow(void); + /* dtor */ ~CMICmdCmdGdbShow(void) override; // Typedefs: private: diff --git a/tools/lldb-mi/MICmdCmdGdbThread.h b/tools/lldb-mi/MICmdCmdGdbThread.h index a4b8596a47c1..6a3804a1c89b 100644 --- a/tools/lldb-mi/MICmdCmdGdbThread.h +++ b/tools/lldb-mi/MICmdCmdGdbThread.h @@ -44,8 +44,8 @@ class CMICmdCmdGdbThread : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdGdbThread(void); + /* dtor */ ~CMICmdCmdGdbThread(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.cpp b/tools/lldb-mi/MICmdCmdMiscellanous.cpp index 37cae404ad7d..3abc7c488d8b 100644 --- a/tools/lldb-mi/MICmdCmdMiscellanous.cpp +++ b/tools/lldb-mi/MICmdCmdMiscellanous.cpp @@ -184,7 +184,7 @@ CMICmdCmdListThreadGroups::ParseArgs(void) //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. -// Synopis: -list-thread-groups [ --available ] [ --recurse 1 ] [ group ... ] +// Synopsis: -list-thread-groups [ --available ] [ --recurse 1 ] [ group ... ] // This command does not follow the MI documentation exactly. Has an extra // argument "i1" to handle. // Ref: diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.h b/tools/lldb-mi/MICmdCmdMiscellanous.h index ffc691cdc927..876554981e34 100644 --- a/tools/lldb-mi/MICmdCmdMiscellanous.h +++ b/tools/lldb-mi/MICmdCmdMiscellanous.h @@ -52,10 +52,10 @@ class CMICmdCmdGdbExit : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdGdbExit(void); + /* dtor */ ~CMICmdCmdGdbExit(void) override; }; //++ ============================================================================ @@ -81,11 +81,11 @@ class CMICmdCmdListThreadGroups : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdListThreadGroups(void); + /* dtor */ ~CMICmdCmdListThreadGroups(void) override; // Typedefs: private: @@ -124,11 +124,11 @@ class CMICmdCmdInterpreterExec : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdInterpreterExec(void); + /* dtor */ ~CMICmdCmdInterpreterExec(void) override; // Attributes: private: @@ -158,8 +158,8 @@ class CMICmdCmdInferiorTtySet : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdInferiorTtySet(void); + /* dtor */ ~CMICmdCmdInferiorTtySet(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdStack.h b/tools/lldb-mi/MICmdCmdStack.h index ed141fcf942f..274415aaafc4 100644 --- a/tools/lldb-mi/MICmdCmdStack.h +++ b/tools/lldb-mi/MICmdCmdStack.h @@ -51,11 +51,11 @@ class CMICmdCmdStackInfoDepth : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackInfoDepth(void); + /* dtor */ ~CMICmdCmdStackInfoDepth(void) override; // Attributes: private: @@ -82,11 +82,11 @@ class CMICmdCmdStackInfoFrame : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackInfoFrame(void); + /* dtor */ ~CMICmdCmdStackInfoFrame(void) override; // Attributes: private: @@ -114,11 +114,11 @@ class CMICmdCmdStackListFrames : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackListFrames(void); + /* dtor */ ~CMICmdCmdStackListFrames(void) override; // Typedefs: private: @@ -154,11 +154,11 @@ class CMICmdCmdStackListArguments : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackListArguments(void); + /* dtor */ ~CMICmdCmdStackListArguments(void) override; // Attributes: private: @@ -191,11 +191,11 @@ class CMICmdCmdStackListLocals : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackListLocals(void); + /* dtor */ ~CMICmdCmdStackListLocals(void) override; // Attributes: private: @@ -224,11 +224,11 @@ public: // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackListVariables(void); + /* dtor */ ~CMICmdCmdStackListVariables(void) override; // Attributes private: @@ -257,11 +257,11 @@ class CMICmdCmdStackSelectFrame : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdStackSelectFrame(void); + /* dtor */ ~CMICmdCmdStackSelectFrame(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.h b/tools/lldb-mi/MICmdCmdSupportInfo.h index a8c22526484d..8dfcfba8ed7d 100644 --- a/tools/lldb-mi/MICmdCmdSupportInfo.h +++ b/tools/lldb-mi/MICmdCmdSupportInfo.h @@ -45,11 +45,11 @@ class CMICmdCmdSupportInfoMiCmdQuery : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdSupportInfoMiCmdQuery(void); + /* dtor */ ~CMICmdCmdSupportInfoMiCmdQuery(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdCmdSupportList.h b/tools/lldb-mi/MICmdCmdSupportList.h index 16c140bca349..a317b079247b 100644 --- a/tools/lldb-mi/MICmdCmdSupportList.h +++ b/tools/lldb-mi/MICmdCmdSupportList.h @@ -45,8 +45,8 @@ class CMICmdCmdSupportListFeatures : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdSupportListFeatures(void); + /* dtor */ ~CMICmdCmdSupportListFeatures(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdSymbol.h b/tools/lldb-mi/MICmdCmdSymbol.h index 449d8aed81b0..ef268bbdb598 100644 --- a/tools/lldb-mi/MICmdCmdSymbol.h +++ b/tools/lldb-mi/MICmdCmdSymbol.h @@ -44,11 +44,11 @@ class CMICmdCmdSymbolListLines : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdSymbolListLines(void); + /* dtor */ ~CMICmdCmdSymbolListLines(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdCmdTarget.h b/tools/lldb-mi/MICmdCmdTarget.h index b3810305d4d9..62f77eed47c5 100644 --- a/tools/lldb-mi/MICmdCmdTarget.h +++ b/tools/lldb-mi/MICmdCmdTarget.h @@ -47,11 +47,11 @@ class CMICmdCmdTargetSelect : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdTargetSelect(void); + /* dtor */ ~CMICmdCmdTargetSelect(void) override; // Attributes: private: @@ -78,11 +78,11 @@ public: // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdTargetAttach(void); + /* dtor */ ~CMICmdCmdTargetAttach(void) override; // Attributes: private: @@ -110,10 +110,10 @@ public: // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdTargetDetach(void); + /* dtor */ ~CMICmdCmdTargetDetach(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdThread.h b/tools/lldb-mi/MICmdCmdThread.h index 6b268f40e8eb..7bce823a0b24 100644 --- a/tools/lldb-mi/MICmdCmdThread.h +++ b/tools/lldb-mi/MICmdCmdThread.h @@ -46,11 +46,11 @@ class CMICmdCmdThreadInfo : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdThreadInfo(void); + /* dtor */ ~CMICmdCmdThreadInfo(void) override; // Typedefs: private: diff --git a/tools/lldb-mi/MICmdCmdTrace.h b/tools/lldb-mi/MICmdCmdTrace.h index c9a6f72a379a..cafe2d89420e 100644 --- a/tools/lldb-mi/MICmdCmdTrace.h +++ b/tools/lldb-mi/MICmdCmdTrace.h @@ -44,8 +44,8 @@ class CMICmdCmdTraceStatus : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); + bool Execute(void) override; + bool Acknowledge(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdTraceStatus(void); + /* dtor */ ~CMICmdCmdTraceStatus(void) override; }; diff --git a/tools/lldb-mi/MICmdCmdVar.h b/tools/lldb-mi/MICmdCmdVar.h index b6b65726eb8a..9f5ad1c3a11c 100644 --- a/tools/lldb-mi/MICmdCmdVar.h +++ b/tools/lldb-mi/MICmdCmdVar.h @@ -59,14 +59,14 @@ class CMICmdCmdVarCreate : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarCreate(void); + /* dtor */ ~CMICmdCmdVarCreate(void) override; // Methods: private: @@ -110,14 +110,14 @@ class CMICmdCmdVarUpdate : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarUpdate(void); + /* dtor */ ~CMICmdCmdVarUpdate(void) override; // Methods: private: @@ -153,11 +153,11 @@ class CMICmdCmdVarDelete : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarDelete(void); + /* dtor */ ~CMICmdCmdVarDelete(void) override; // Attribute: private: @@ -185,11 +185,11 @@ class CMICmdCmdVarAssign : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarAssign(void); + /* dtor */ ~CMICmdCmdVarAssign(void) override; // Attributes: private: @@ -220,11 +220,11 @@ class CMICmdCmdVarSetFormat : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarSetFormat(void); + /* dtor */ ~CMICmdCmdVarSetFormat(void) override; // Attributes: private: @@ -254,11 +254,11 @@ class CMICmdCmdVarListChildren : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarListChildren(void); + /* dtor */ ~CMICmdCmdVarListChildren(void) override; // Attributes: private: @@ -293,11 +293,11 @@ class CMICmdCmdVarEvaluateExpression : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarEvaluateExpression(void); + /* dtor */ ~CMICmdCmdVarEvaluateExpression(void) override; // Attributes: private: @@ -328,11 +328,11 @@ class CMICmdCmdVarInfoPathExpression : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarInfoPathExpression(void); + /* dtor */ ~CMICmdCmdVarInfoPathExpression(void) override; // Attributes: private: @@ -362,11 +362,11 @@ class CMICmdCmdVarShowAttributes : public CMICmdBase // Overridden: public: // From CMICmdInvoker::ICmd - virtual bool Execute(void); - virtual bool Acknowledge(void); - virtual bool ParseArgs(void); + bool Execute(void) override; + bool Acknowledge(void) override; + bool ParseArgs(void) override; // From CMICmnBase - /* dtor */ virtual ~CMICmdCmdVarShowAttributes(void); + /* dtor */ ~CMICmdCmdVarShowAttributes(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdFactory.cpp b/tools/lldb-mi/MICmdFactory.cpp index 3fe4062b7721..717a497a96be 100644 --- a/tools/lldb-mi/MICmdFactory.cpp +++ b/tools/lldb-mi/MICmdFactory.cpp @@ -85,7 +85,7 @@ CMICmdFactory::Shutdown(void) } //++ ------------------------------------------------------------------------------------ -// Details: Register a command's creator function with the command identitier the MI +// Details: Register a command's creator function with the command identifier the MI // command name i.e. 'file-exec-and-symbols'. // Type: Method. // Args: vMiCmd - (R) Command's name, the MI command. @@ -159,7 +159,7 @@ CMICmdFactory::IsValid(const CMIUtilString &vMiCmd) const return false; } - const size_t nPos = vMiCmd.find(" "); + const size_t nPos = vMiCmd.find(' '); if (nPos != std::string::npos) bValid = false; diff --git a/tools/lldb-mi/MICmdFactory.h b/tools/lldb-mi/MICmdFactory.h index 8ad64fb5eafe..9a5e07690a34 100644 --- a/tools/lldb-mi/MICmdFactory.h +++ b/tools/lldb-mi/MICmdFactory.h @@ -55,8 +55,8 @@ class CMICmdFactory : public CMICmnBase, public MI::ISingleton<CMICmdFactory> // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; bool CmdRegister(const CMIUtilString &vMiCmd, CmdCreatorFnPtr vCmdCreateFn); bool CmdCreate(const CMIUtilString &vMiCmd, const SMICmdData &vCmdData, CMICmdBase *&vpNewCmd); bool CmdExist(const CMIUtilString &vMiCmd) const; @@ -73,7 +73,7 @@ class CMICmdFactory : public CMICmnBase, public MI::ISingleton<CMICmdFactory> // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmdFactory(void); + /* dtor */ ~CMICmdFactory(void) override; // Typedefs: private: diff --git a/tools/lldb-mi/MICmdInterpreter.cpp b/tools/lldb-mi/MICmdInterpreter.cpp index ce5d30e92316..3c5285fc8cc8 100644 --- a/tools/lldb-mi/MICmdInterpreter.cpp +++ b/tools/lldb-mi/MICmdInterpreter.cpp @@ -153,7 +153,7 @@ bool CMICmdInterpreter::MiHasCmdTokenEndingHyphen(const CMIUtilString &vTextLine) { // The hyphen is mandatory - const size_t nPos = vTextLine.find("-", 0); + const size_t nPos = vTextLine.find('-', 0); if ((nPos == std::string::npos)) return false; @@ -215,7 +215,7 @@ CMICmdInterpreter::MiHasCmdTokenEndingAlpha(const CMIUtilString &vTextLine) bool CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine) { - const size_t nPos = vTextLine.find("-", 0); + const size_t nPos = vTextLine.find('-', 0); return (nPos > 0); } @@ -246,12 +246,12 @@ CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine) } else { - nPos = vTextLine.find("-", 0); + nPos = vTextLine.find('-', 0); } bool bFoundCmd = false; const size_t nLen = vTextLine.length(); - const size_t nPos2 = vTextLine.find(" ", nPos); + const size_t nPos2 = vTextLine.find(' ', nPos); if (nPos2 != std::string::npos) { if (nPos2 == nLen) diff --git a/tools/lldb-mi/MICmdInterpreter.h b/tools/lldb-mi/MICmdInterpreter.h index acb052289ba2..e24308484d23 100644 --- a/tools/lldb-mi/MICmdInterpreter.h +++ b/tools/lldb-mi/MICmdInterpreter.h @@ -35,8 +35,8 @@ class CMICmdInterpreter : public CMICmnBase, public MI::ISingleton<CMICmdInterpr public: // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; bool ValidateIsMi(const CMIUtilString &vTextLine, bool &vwbYesValid, bool &vwbCmdNotInCmdFactor, SMICmdData &rwCmdData); // Methods: @@ -55,7 +55,7 @@ class CMICmdInterpreter : public CMICmnBase, public MI::ISingleton<CMICmdInterpr // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmdInterpreter(void); + /* dtor */ ~CMICmdInterpreter(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdInvoker.cpp b/tools/lldb-mi/MICmdInvoker.cpp index ef957c53bd70..9f82e92dc4bb 100644 --- a/tools/lldb-mi/MICmdInvoker.cpp +++ b/tools/lldb-mi/MICmdInvoker.cpp @@ -176,7 +176,7 @@ CMICmdInvoker::CmdAdd(const CMICmdBase &vCmd) //++ ------------------------------------------------------------------------------------ // Details: Having previously had the potential command validated and found valid now // get the command executed. -// If the Functionalityity returns MIstatus::failure call GetErrorDescription(). +// If the Functionality returns MIstatus::failure call GetErrorDescription(). // This function is used by the application's main thread. // Type: Method. // Args: vCmd - (RW) Command object. @@ -220,7 +220,7 @@ CMICmdInvoker::CmdExecute(CMICmdBase &vCmd) //++ ------------------------------------------------------------------------------------ // Details: Called when a command has finished its Execution() work either synchronously -// because the command executed was the type a non event type or asynchronoulsy +// because the command executed was the type a non event type or asynchronously // via the command's callback (because of an SB Listener event). Needs to be called // so that *this invoker call do some house keeping and then proceed to call // the command's Acknowledge() function. diff --git a/tools/lldb-mi/MICmdInvoker.h b/tools/lldb-mi/MICmdInvoker.h index a03c2d36103a..b178d4322577 100644 --- a/tools/lldb-mi/MICmdInvoker.h +++ b/tools/lldb-mi/MICmdInvoker.h @@ -33,7 +33,7 @@ class CMICmnStreamStdout; // exceed a time limit which if it exceeds informs the command(s) to // stop work. // The work by the Invoker is carried out in the main thread. -// The Invoker takes ownersip of any commands created which means it +// The Invoker takes ownership of any commands created which means it // is the only object to delete them when a command is finished working. // A singleton class. // Gotchas: None. @@ -68,8 +68,8 @@ class CMICmdInvoker : public CMICmnBase, public CMICmdMgrSetCmdDeleteCallback::I // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; bool CmdExecute(CMICmdBase &vCmd); bool CmdExecuteFinished(CMICmdBase &vCmd); @@ -92,9 +92,9 @@ class CMICmdInvoker : public CMICmnBase, public CMICmdMgrSetCmdDeleteCallback::I // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmdInvoker(void); + /* dtor */ ~CMICmdInvoker(void) override; // From CMICmdMgrSetCmdDeleteCallback::ICallback - virtual void Delete(SMICmdData &vCmd); + void Delete(SMICmdData &vCmd) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdMgr.cpp b/tools/lldb-mi/MICmdMgr.cpp index 998a72f5d07e..76dbff69dbe7 100644 --- a/tools/lldb-mi/MICmdMgr.cpp +++ b/tools/lldb-mi/MICmdMgr.cpp @@ -170,7 +170,7 @@ CMICmdMgr::CmdInterpret(const CMIUtilString &vTextLine, bool &vwbYesValid, bool //++ ------------------------------------------------------------------------------------ // Details: Having previously had the potential command validated and found valid now // get the command executed. -// If the Functionalityity returns MIstatus::failure call GetErrorDescription(). +// If the Functionality returns MIstatus::failure call GetErrorDescription(). // This function is used by the application's main thread. // Type: Method. // Args: vCmdData - (RW) Command meta data. diff --git a/tools/lldb-mi/MICmdMgr.h b/tools/lldb-mi/MICmdMgr.h index a45ecb61a3ce..4956d5c3a376 100644 --- a/tools/lldb-mi/MICmdMgr.h +++ b/tools/lldb-mi/MICmdMgr.h @@ -27,7 +27,7 @@ class CMICmdBase; //++ ============================================================================ // Details: MI command manager. Oversees command operations, controls command // production and the running of commands. -// Command Invoker, Command Factory and Command Monitor while independant +// Command Invoker, Command Factory and Command Monitor while independent // units are overseen/managed by *this manager. // A singleton class. // Gotchas: None. @@ -40,8 +40,8 @@ class CMICmdMgr : public CMICmnBase, public MI::ISingleton<CMICmdMgr> // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; bool CmdInterpret(const CMIUtilString &vTextLine, bool &vwbYesValid, bool &vwbCmdNotInCmdFactor, SMICmdData &rwCmdData); bool CmdExecute(const SMICmdData &vCmdData); @@ -58,7 +58,7 @@ class CMICmdMgr : public CMICmnBase, public MI::ISingleton<CMICmdMgr> // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmdMgr(void); + /* dtor */ ~CMICmdMgr(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h index 16b11e5d0f4b..1c9be826c516 100644 --- a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h +++ b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h @@ -64,7 +64,7 @@ class CSetClients : public std::set<class ICallback *>, public CMICmnBase // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CSetClients(void); + /* dtor */ ~CSetClients(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnBase.cpp b/tools/lldb-mi/MICmnBase.cpp index 909393564da4..0d9eda70f0b0 100644 --- a/tools/lldb-mi/MICmnBase.cpp +++ b/tools/lldb-mi/MICmnBase.cpp @@ -46,7 +46,7 @@ CMICmnBase::~CMICmnBase(void) // Details: Retrieve whether *this object has an error description set. // Type: Method. // Args: None. -// Return: bool - True = Yes already defined, false = empty discription. +// Return: bool - True = Yes already defined, false = empty description. // Throws: None. //-- bool diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.cpp b/tools/lldb-mi/MICmnLLDBBroadcaster.cpp index 55927b691d77..8bad24313b78 100644 --- a/tools/lldb-mi/MICmnLLDBBroadcaster.cpp +++ b/tools/lldb-mi/MICmnLLDBBroadcaster.cpp @@ -35,7 +35,7 @@ CMICmnLLDBBroadcaster::~CMICmnLLDBBroadcaster(void) } //++ ------------------------------------------------------------------------------------ -// Details: Initialize resources for *this broardcaster object. +// Details: Initialize resources for *this broadcaster object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. @@ -56,7 +56,7 @@ CMICmnLLDBBroadcaster::Initialize(void) } //++ ------------------------------------------------------------------------------------ -// Details: Release resources for *this broardcaster object. +// Details: Release resources for *this broadcaster object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.h b/tools/lldb-mi/MICmnLLDBBroadcaster.h index 469aae969b96..dc0de47d3bb3 100644 --- a/tools/lldb-mi/MICmnLLDBBroadcaster.h +++ b/tools/lldb-mi/MICmnLLDBBroadcaster.h @@ -15,7 +15,7 @@ #include "MIUtilSingletonBase.h" //++ ============================================================================ -// Details: MI derived class from LLDB SBBroardcaster API. +// Details: MI derived class from LLDB SBBroadcaster API. // // *** This class (files) is a place holder until we know we need it or // *** not @@ -31,8 +31,8 @@ class CMICmnLLDBBroadcaster : public CMICmnBase, public lldb::SBBroadcaster, pub // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // Methods: private: /* ctor */ CMICmnLLDBBroadcaster(void); @@ -42,5 +42,5 @@ class CMICmnLLDBBroadcaster : public CMICmnBase, public lldb::SBBroadcaster, pub // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnLLDBBroadcaster(void); + /* dtor */ ~CMICmnLLDBBroadcaster(void) override; }; diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp index cff651dd4a57..cf74fe58fbd9 100644 --- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp +++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp @@ -231,7 +231,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MI // MI print // "frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}, // ..." - CMIUtilString strListCommaSeperated; + CMIUtilString strListCommaSeparated; for (MIuint nLevel = 0; nLevel < nFrames; nLevel++) { CMICmnMIValueTuple miValueTuple; @@ -240,11 +240,11 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MI const CMICmnMIValueResult miValueResult2("frame", miValueTuple); if (nLevel != 0) - strListCommaSeperated += ","; - strListCommaSeperated += miValueResult2.GetString(); + strListCommaSeparated += ","; + strListCommaSeparated += miValueResult2.GetString(); } - vwrThreadFrames = strListCommaSeperated; + vwrThreadFrames = strListCommaSeparated; return MIstatus::success; } @@ -383,7 +383,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, const char *pThreadName = rThread.GetName(); const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0; const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && - CMIUtilString::IsAllValidAlphaAndNumeric(pThreadName)); // 32 is arbitary number + CMIUtilString::IsAllValidAlphaAndNumeric(pThreadName)); // 32 is arbitrary number const char *pThrdFmt = bHaveName ? "%s" : "Thread %d"; CMIUtilString strThread; if (bHaveName) @@ -523,7 +523,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfo // Args: vrValue - (R) LLDB value object. // vbInSimpleForm - (R) True = Get variable info in simple form (i.e. don't expand aggregates). // - False = Get variable info (and expand aggregates if any). -// vwrStrValue t - (W) The string representatin of this value. +// vwrStrValue t - (W) The string representation of this value. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h index e3e16cd2ca54..7e0ce6ab8246 100644 --- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h +++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h @@ -35,8 +35,8 @@ class CMICmnMIValueList; // Details: MI debug session object that holds debugging information between // instances of MI commands executing their work and producing MI // result records. Information/data is set by one or many commands then -// retrieved by the same or other sebsequent commands. -// It primarily to hold LLDB type objects. +// retrieved by the same or other subsequent commands. +// It primarily holds LLDB type objects. // A singleton class. // Gotchas: None. // Authors: Illya Rudkin 04/03/2014. @@ -140,8 +140,8 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // Variant type data which can be assigned and retrieved across all command instances template <typename T> bool SharedDataAdd(const CMIUtilString &vKey, const T &vData); @@ -209,7 +209,7 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnLLDBDebugSessionInfo(void); + /* dtor */ ~CMICmnLLDBDebugSessionInfo(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp index a42964c136cb..62130844d22d 100644 --- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp +++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp @@ -289,7 +289,7 @@ CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(const lldb::SBValue &v } //++ ------------------------------------------------------------------------------------ -// Details: Return nuber formatted string according to the given value type. +// Details: Return number formatted string according to the given value type. // Type: Static method. // Args: vnValue - (R) The number value to get formatted. // vpStrValueNatural - (R) The natural representation of the number value. @@ -535,7 +535,7 @@ CMICmnLLDBDebugSessionInfoVarObj::GetValue(void) const } //++ ------------------------------------------------------------------------------------ -// Details: Set the var format type for *this object and upate the formatting. +// Details: Set the var format type for *this object and update the formatting. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h index ad5a6ab680f2..e768c5fdf0cc 100644 --- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h +++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h @@ -120,7 +120,7 @@ class CMICmnLLDBDebugSessionInfoVarObj static MIuint ms_nVarUniqueId; static varFormat_e ms_eDefaultFormat; // overrides "natural" format // - // *** Upate the copy move constructors and assignment operator *** + // *** Update the copy move constructors and assignment operator *** varFormat_e m_eVarFormat; varType_e m_eVarType; CMIUtilString m_strName; @@ -128,5 +128,5 @@ class CMICmnLLDBDebugSessionInfoVarObj CMIUtilString m_strNameReal; CMIUtilString m_strFormattedValue; CMIUtilString m_strVarObjParentName; - // *** Upate the copy move constructors and assignment operator *** + // *** Update the copy move constructors and assignment operator *** }; diff --git a/tools/lldb-mi/MICmnLLDBDebugger.cpp b/tools/lldb-mi/MICmnLLDBDebugger.cpp index 5d4a09a8a43b..b626ccc3f12d 100644 --- a/tools/lldb-mi/MICmnLLDBDebugger.cpp +++ b/tools/lldb-mi/MICmnLLDBDebugger.cpp @@ -423,13 +423,13 @@ CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const lld const char *pBroadcasterName = vBroadcaster.GetName(); if (pBroadcasterName == nullptr) { - SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME), MIRSRC(IDS_WORD_INVALIDNULLPTR))); + SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME), MIRSRC(IDS_WORD_INVALIDNULLPTR))); return MIstatus::failure; } CMIUtilString broadcasterName(pBroadcasterName); if (broadcasterName.length() == 0) { - SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME), MIRSRC(IDS_WORD_INVALIDEMPTY))); + SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME), MIRSRC(IDS_WORD_INVALIDEMPTY))); return MIstatus::failure; } diff --git a/tools/lldb-mi/MICmnLLDBDebugger.h b/tools/lldb-mi/MICmnLLDBDebugger.h index 6c7e90006d8e..de7611221522 100644 --- a/tools/lldb-mi/MICmnLLDBDebugger.h +++ b/tools/lldb-mi/MICmnLLDBDebugger.h @@ -42,8 +42,8 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase, // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; bool SetDriver(const CMIDriverBase &vClientDriver); CMIDriverBase &GetDriver(void) const; @@ -62,13 +62,13 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase, // Overridden: public: // From CMIUtilThreadActiveObjBase - virtual const CMIUtilString &ThreadGetName(void) const; + const CMIUtilString &ThreadGetName(void) const override; // Overridden: protected: // From CMIUtilThreadActiveObjBase - virtual bool ThreadRun(bool &vrIsAlive); - virtual bool ThreadFinish(void); + bool ThreadRun(bool &vrIsAlive) override; + bool ThreadFinish(void) override; // Typedefs: private: @@ -100,7 +100,7 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase, // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnLLDBDebugger(void); + /* dtor */ ~CMICmnLLDBDebugger(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp index 49fce12739f8..29ff15c92f44 100644 --- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -64,7 +64,7 @@ CMICmnLLDBDebuggerHandleEvents::~CMICmnLLDBDebuggerHandleEvents(void) } //++ ------------------------------------------------------------------------------------ -// Details: Initialize resources for *this broardcaster object. +// Details: Initialize resources for *this broadcaster object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. @@ -90,7 +90,7 @@ CMICmnLLDBDebuggerHandleEvents::Initialize(void) } //++ ------------------------------------------------------------------------------------ -// Details: Release resources for *this broardcaster object. +// Details: Release resources for *this broadcaster object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. @@ -112,7 +112,7 @@ CMICmnLLDBDebuggerHandleEvents::Shutdown(void) } //++ ------------------------------------------------------------------------------------ -// Details: Interpret the event object to asscertain the action to take or information to +// Details: Interpret the event object to ascertain the action to take or information to // to form and put in a MI Out-of-band record object which is given to stdout. // Type: Method. // Args: vEvent - (R) An LLDB broadcast event. diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h index 9b7b5d6f7b03..1abb52012979 100644 --- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h +++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h @@ -36,8 +36,8 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton< // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // bool HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent); @@ -84,7 +84,7 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton< // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnLLDBDebuggerHandleEvents(void); + /* dtor */ ~CMICmnLLDBDebuggerHandleEvents(void) override; void InitializeSignals(); bool m_bSignalsInitialized; MIuint64 m_SIGINT; diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp index b60ce1aa4c4f..eeafa9ddd2ab 100644 --- a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp +++ b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp @@ -36,7 +36,7 @@ CMICmnLLDBProxySBValue::GetValueAsUnsigned(const lldb::SBValue &vrValue, MIuint6 MIuint64 nValue = rValue.GetValueAsUnsigned(nFailValue); if (nValue == nFailValue) { - nFailValue = 5; // Some arbitary number + nFailValue = 5; // Some arbitrary number nValue = rValue.GetValueAsUnsigned(nFailValue); if (nValue != nFailValue) { @@ -72,7 +72,7 @@ CMICmnLLDBProxySBValue::GetValueAsSigned(const lldb::SBValue &vrValue, MIint64 & MIuint64 nValue = rValue.GetValueAsSigned(nFailValue); if (nValue == nFailValue) { - nFailValue = 5; // Some arbitary number + nFailValue = 5; // Some arbitrary number nValue = rValue.GetValueAsSigned(nFailValue); if (nValue != nFailValue) { diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.h b/tools/lldb-mi/MICmnLLDBProxySBValue.h index a4ff0b72b236..c9cd3a9f995f 100644 --- a/tools/lldb-mi/MICmnLLDBProxySBValue.h +++ b/tools/lldb-mi/MICmnLLDBProxySBValue.h @@ -15,12 +15,12 @@ // In-house headers: #include "MIDataTypes.h" -// Declerations: +// Declarations: class CMIUtilString; //++ ============================================================================ // Details: MI proxy wrapper class to lldb::SBValue. The class provides functionality -// to assist in the use of SBValue's parculiar function usage. +// to assist in the use of SBValue's particular function usage. // Gotchas: None. // Authors: Illya Rudkin 03/04/2014. // Changes: None. diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp index 7ccb35e45449..45f030bf535f 100644 --- a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp +++ b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp @@ -20,7 +20,7 @@ //++ ------------------------------------------------------------------------------------ // Details: CMICmnLLDBUtilSBValue constructor. // Type: Method. -// Args: vrValue - (R) The LLDb value object. +// Args: vrValue - (R) The LLDB value object. // vbHandleCharType - (R) True = Yes return text molding to char type, // False = just return data. // Return: None. @@ -579,7 +579,7 @@ CMICmnLLDBUtilSBValue::HasName(void) const } //++ ------------------------------------------------------------------------------------ -// Details: Determine if the value object' respresents a LLDB variable i.e. "$0". +// Details: Determine if the value object' represents a LLDB variable i.e. "$0". // Type: Method. // Args: None. // Return: bool - True = Yes LLDB variable, false = no. diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.h b/tools/lldb-mi/MICmnLLDBUtilSBValue.h index 468170b6a731..8bb6783a2a34 100644 --- a/tools/lldb-mi/MICmnLLDBUtilSBValue.h +++ b/tools/lldb-mi/MICmnLLDBUtilSBValue.h @@ -16,7 +16,7 @@ #include "MIDataTypes.h" #include "MICmnMIValueTuple.h" -// Declerations: +// Declarations: class CMIUtilString; //++ ============================================================================ diff --git a/tools/lldb-mi/MICmnLog.h b/tools/lldb-mi/MICmnLog.h index 30505359d749..f0ae534e840b 100644 --- a/tools/lldb-mi/MICmnLog.h +++ b/tools/lldb-mi/MICmnLog.h @@ -20,7 +20,7 @@ //++ ============================================================================ // Details: MI common code implementation class. Handle application trace // activity logging. Medium objects derived from the Medium abstract -/// class are registered with this loggor. The function Write is called +/// class are registered with this logger. The function Write is called // by a client callee to log information. That information is given to // registered relevant mediums. The medium file is registered during // *this logs initialization so it will always have a file log for the @@ -37,14 +37,14 @@ class CMICmnLog : public MI::ISingleton<CMICmnLog> // Enumeration: public: //++ - // Description: Data given to the Logger can be of serveral types. The Logger can be + // Description: Data given to the Logger can be of several types. The Logger can be // set at levels of verbosity. Can determine how data is sent to one or // mediums. //-- enum ELogVerbosity { // Descriptions of what 'may' occur, depends ultimately on the medium itself. See the medium. eLogVerbosity_FnTrace = 0x00000004, // Debug function stack call tracing - eLogVerbosity_DbgOp = 0x00000008, // Send a string to the debugguer for display (not implemented) + eLogVerbosity_DbgOp = 0x00000008, // Send a string to the debugger for display (not implemented) eLogVerbosity_ClientMsg = 0x00000010, // A client using MI can insert messages into the log (not implemented) eLogVerbosity_Log = 0x00000020 // Send to only the Log file. }; @@ -93,8 +93,8 @@ class CMICmnLog : public MI::ISingleton<CMICmnLog> // Overridden: public: // From MI::ISingleton - virtual bool Initialize(void); - virtual bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // Methods: private: @@ -105,7 +105,7 @@ class CMICmnLog : public MI::ISingleton<CMICmnLog> // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnLog(void); + /* dtor */ ~CMICmnLog(void) override; // Typedef: private: diff --git a/tools/lldb-mi/MICmnLogMediumFile.cpp b/tools/lldb-mi/MICmnLogMediumFile.cpp index 4080bc5cf29d..67b8086221cd 100644 --- a/tools/lldb-mi/MICmnLogMediumFile.cpp +++ b/tools/lldb-mi/MICmnLogMediumFile.cpp @@ -396,7 +396,7 @@ CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const } //++ ------------------------------------------------------------------------------------ -// Details: Set the header text that is written to the logger file at the begining. +// Details: Set the header text that is written to the logger file at the beginning. // Type: Method. // Args: vText - (R) Text. // Return: MIstatus::success - Functional succeeded. @@ -425,7 +425,7 @@ CMICmnLogMediumFile::GetLineReturn(void) const } //++ ------------------------------------------------------------------------------------ -// Details: Set the diretory to place the log file. +// Details: Set the directory to place the log file. // Type: Method. // Args: vPath - (R) Path to log. // Return: MIstatus::success - Functional succeeded. diff --git a/tools/lldb-mi/MICmnLogMediumFile.h b/tools/lldb-mi/MICmnLogMediumFile.h index 53961d8f4f73..b79baf184880 100644 --- a/tools/lldb-mi/MICmnLogMediumFile.h +++ b/tools/lldb-mi/MICmnLogMediumFile.h @@ -48,13 +48,13 @@ class CMICmnLogMediumFile : public CMICmnBase, public CMICmnLog::IMedium // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnLogMediumFile(void); + /* dtor */ ~CMICmnLogMediumFile(void) override; // From CMICmnLog::IMedium - virtual bool Initialize(void); - virtual const CMIUtilString &GetName(void) const; - virtual bool Write(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType); - virtual const CMIUtilString &GetError(void) const; - virtual bool Shutdown(void); + bool Initialize(void) override; + const CMIUtilString &GetName(void) const override; + bool Write(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType) override; + const CMIUtilString &GetError(void) const override; + bool Shutdown(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnMIOutOfBandRecord.h b/tools/lldb-mi/MICmnMIOutOfBandRecord.h index 60a67165a3ff..6277e860878f 100644 --- a/tools/lldb-mi/MICmnMIOutOfBandRecord.h +++ b/tools/lldb-mi/MICmnMIOutOfBandRecord.h @@ -86,7 +86,7 @@ class CMICmnMIOutOfBandRecord : public CMICmnBase // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIOutOfBandRecord(void); + /* dtor */ ~CMICmnMIOutOfBandRecord(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnMIResultRecord.h b/tools/lldb-mi/MICmnMIResultRecord.h index 92666ab87733..981cf3635d53 100644 --- a/tools/lldb-mi/MICmnMIResultRecord.h +++ b/tools/lldb-mi/MICmnMIResultRecord.h @@ -76,7 +76,7 @@ class CMICmnMIResultRecord : public CMICmnBase // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIResultRecord(void); + /* dtor */ ~CMICmnMIResultRecord(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnMIValue.h b/tools/lldb-mi/MICmnMIValue.h index d5de4275231b..6a372e600146 100644 --- a/tools/lldb-mi/MICmnMIValue.h +++ b/tools/lldb-mi/MICmnMIValue.h @@ -43,7 +43,7 @@ class CMICmnMIValue : public CMICmnBase // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIValue(void); + /* dtor */ ~CMICmnMIValue(void) override; // Attributes: protected: diff --git a/tools/lldb-mi/MICmnMIValueConst.h b/tools/lldb-mi/MICmnMIValueConst.h index 72b5f2455f42..403619438919 100644 --- a/tools/lldb-mi/MICmnMIValueConst.h +++ b/tools/lldb-mi/MICmnMIValueConst.h @@ -45,7 +45,7 @@ class CMICmnMIValueConst : public CMICmnMIValue // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIValueConst(void); + /* dtor */ ~CMICmnMIValueConst(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnMIValueList.cpp b/tools/lldb-mi/MICmnMIValueList.cpp index 68eceab09cd2..30888cfbb59c 100644 --- a/tools/lldb-mi/MICmnMIValueList.cpp +++ b/tools/lldb-mi/MICmnMIValueList.cpp @@ -84,7 +84,7 @@ CMICmnMIValueList::BuildList(void) //++ ------------------------------------------------------------------------------------ // Details: Add another MI result object to the value list's of list is results. -// Only result obejcts can be added to a list of result otherwise this function +// Only result objects can be added to a list of result otherwise this function // will return MIstatus::failure. // Type: Method. // Args: vResult - (R) The MI result object. @@ -116,7 +116,7 @@ CMICmnMIValueList::Add(const CMICmnMIValue &vValue) //++ ------------------------------------------------------------------------------------ // Details: Add another MI result object to the value list's of list is results. -// Only result obejcts can be added to a list of result otherwise this function +// Only result objects can be added to a list of result otherwise this function // will return MIstatus::failure. // Type: Method. // Args: vResult - (R) The MI result object. diff --git a/tools/lldb-mi/MICmnMIValueList.h b/tools/lldb-mi/MICmnMIValueList.h index 85bc5d4fbc99..26a217dfc77b 100644 --- a/tools/lldb-mi/MICmnMIValueList.h +++ b/tools/lldb-mi/MICmnMIValueList.h @@ -48,7 +48,7 @@ class CMICmnMIValueList : public CMICmnMIValue // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIValueList(void); + /* dtor */ ~CMICmnMIValueList(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnMIValueResult.h b/tools/lldb-mi/MICmnMIValueResult.h index 99051bfc3f26..7c8e9801e4a0 100644 --- a/tools/lldb-mi/MICmnMIValueResult.h +++ b/tools/lldb-mi/MICmnMIValueResult.h @@ -45,7 +45,7 @@ class CMICmnMIValueResult : public CMICmnMIValue // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIValueResult(void); + /* dtor */ ~CMICmnMIValueResult(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnMIValueTuple.h b/tools/lldb-mi/MICmnMIValueTuple.h index 3b6a8835d25f..ecf5402dc54c 100644 --- a/tools/lldb-mi/MICmnMIValueTuple.h +++ b/tools/lldb-mi/MICmnMIValueTuple.h @@ -50,7 +50,7 @@ class CMICmnMIValueTuple : public CMICmnMIValue // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMICmnMIValueTuple(void); + /* dtor */ ~CMICmnMIValueTuple(void) override; // Methods: private: diff --git a/tools/lldb-mi/MICmnResources.cpp b/tools/lldb-mi/MICmnResources.cpp index 3d8583f29d84..ee9c93d7eba2 100644 --- a/tools/lldb-mi/MICmnResources.cpp +++ b/tools/lldb-mi/MICmnResources.cpp @@ -129,7 +129,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[] {IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME, "LLDB Debugger. Invalid client name '%s' "}, {IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED, "LLDB Debugger. Client name '%s' not registered for listening events"}, {IDS_LLDBDEBUGGER_ERR_STOPLISTENER, "LLDB Debugger. Failure occurred stopping event for client '%s' SBBroadcaster '%s'"}, - {IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME, "LLDB Debugger. Broardcaster's name '%s' is not valid"}, + {IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME, "LLDB Debugger. Broadcaster's name '%s' is not valid"}, {IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT, "LLDB Debugger. Unhandled event '%s'"}, {IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT, "LLDB Out-of-band. Handling event for '%s', an event enumeration '%d' not recognised"}, {IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID, "LLDB Out-of-band. Invalid '%s' in '%s'"}, diff --git a/tools/lldb-mi/MICmnResources.h b/tools/lldb-mi/MICmnResources.h index 7e5b70fcbdd2..633eba8de9e4 100644 --- a/tools/lldb-mi/MICmnResources.h +++ b/tools/lldb-mi/MICmnResources.h @@ -140,7 +140,7 @@ enum IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME, IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED, IDS_LLDBDEBUGGER_ERR_STOPLISTENER, - IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME, + IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME, IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT, IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT, @@ -289,8 +289,8 @@ class CMICmnResources : public CMICmnBase, public MI::ISingleton<CMICmnResources // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; CMIUtilString GetString(const MIuint vResourceId) const; bool HasString(const MIuint vResourceId) const; @@ -327,7 +327,7 @@ class CMICmnResources : public CMICmnBase, public MI::ISingleton<CMICmnResources // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnResources(void); + /* dtor */ ~CMICmnResources(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnStreamStderr.cpp b/tools/lldb-mi/MICmnStreamStderr.cpp index 74f36121ee63..5a18951b271c 100644 --- a/tools/lldb-mi/MICmnStreamStderr.cpp +++ b/tools/lldb-mi/MICmnStreamStderr.cpp @@ -93,7 +93,7 @@ CMICmnStreamStderr::Shutdown(void) //++ ------------------------------------------------------------------------------------ // Details: Write text data to stderr. Prefix the message with "MI:". The text data does -// not need to include a carrage line return as this is added to the text. The +// not need to include a carriage line return as this is added to the text. The // function also then passes the text data into the CMICmnLog logger. // Type: Method. // Args: vText - (R) Text data. @@ -115,7 +115,7 @@ CMICmnStreamStderr::Write(const CMIUtilString &vText, const bool vbSendToLog /* //++ ------------------------------------------------------------------------------------ // Details: Write an LLDB text message to stderr. -// The text data does not need to include a carrage line return as this is added +// The text data does not need to include a carriage line return as this is added // to the text. The function also then passes the text data into the CMICmnLog // logger. // Type: Method. @@ -138,7 +138,7 @@ CMICmnStreamStderr::WriteLLDBMsg(const CMIUtilString &vText, const bool vbSendTo //++ ------------------------------------------------------------------------------------ // Details: Write text data to stderr. The text data does not need to -// include a carrage line return as this is added to the text. The function also +// include a carriage line return as this is added to the text. The function also // then passes the text data into the CMICmnLog logger. // Type: Method. // Args: vText - (R) Text data. May be prefixed with MI app's short name. diff --git a/tools/lldb-mi/MICmnStreamStderr.h b/tools/lldb-mi/MICmnStreamStderr.h index 4f4874ebc9bc..afceada9ff2e 100644 --- a/tools/lldb-mi/MICmnStreamStderr.h +++ b/tools/lldb-mi/MICmnStreamStderr.h @@ -35,8 +35,8 @@ class CMICmnStreamStderr : public CMICmnBase, public MI::ISingleton<CMICmnStream // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // bool Lock(void); bool Unlock(void); @@ -54,7 +54,7 @@ class CMICmnStreamStderr : public CMICmnBase, public MI::ISingleton<CMICmnStream // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnStreamStderr(void); + /* dtor */ ~CMICmnStreamStderr(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnStreamStdin.h b/tools/lldb-mi/MICmnStreamStdin.h index 309c7d8eed2f..71076d6dcd4e 100644 --- a/tools/lldb-mi/MICmnStreamStdin.h +++ b/tools/lldb-mi/MICmnStreamStdin.h @@ -32,8 +32,8 @@ class CMICmnStreamStdin : public CMICmnBase, public MI::ISingleton<CMICmnStreamS // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // const CMIUtilString &GetPrompt(void) const; bool SetPrompt(const CMIUtilString &vNewPrompt); @@ -50,7 +50,7 @@ class CMICmnStreamStdin : public CMICmnBase, public MI::ISingleton<CMICmnStreamS // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnStreamStdin(void); + /* dtor */ ~CMICmnStreamStdin(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnStreamStdout.cpp b/tools/lldb-mi/MICmnStreamStdout.cpp index 63dec65a7753..2c93c99e6c8a 100644 --- a/tools/lldb-mi/MICmnStreamStdout.cpp +++ b/tools/lldb-mi/MICmnStreamStdout.cpp @@ -93,7 +93,7 @@ CMICmnStreamStdout::Shutdown(void) //++ ------------------------------------------------------------------------------------ // Details: Write an MI format type response to stdout. The text data does not need to -// include a carrage line return as this is added to the text. The function also +// include a carriage line return as this is added to the text. The function also // then passes the text data into the CMICmnLog logger. // Type: Method. // Args: vText - (R) MI formatted text. @@ -110,7 +110,7 @@ CMICmnStreamStdout::WriteMIResponse(const CMIUtilString &vText, const bool vbSen //++ ------------------------------------------------------------------------------------ // Details: Write text data to stdout. The text data does not need to -// include a carrage line return as this is added to the text. The function also +// include a carriage line return as this is added to the text. The function also // then passes the text data into the CMICmnLog logger. // Type: Method. // Args: vText - (R) Text data. @@ -132,7 +132,7 @@ CMICmnStreamStdout::Write(const CMIUtilString &vText, const bool vbSendToLog /* //++ ------------------------------------------------------------------------------------ // Details: Write text data to stdout. The text data does not need to -// include a carrage line return as this is added to the text. The function also +// include a carriage line return as this is added to the text. The function also // then passes the text data into the CMICmnLog logger. // Type: Method. // Args: vText - (R) Text data prefixed with MI app's short name. diff --git a/tools/lldb-mi/MICmnStreamStdout.h b/tools/lldb-mi/MICmnStreamStdout.h index 526a322f6e35..664faae863da 100644 --- a/tools/lldb-mi/MICmnStreamStdout.h +++ b/tools/lldb-mi/MICmnStreamStdout.h @@ -35,8 +35,8 @@ class CMICmnStreamStdout : public CMICmnBase, public MI::ISingleton<CMICmnStream // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // bool Lock(void); bool Unlock(void); @@ -54,7 +54,7 @@ class CMICmnStreamStdout : public CMICmnBase, public MI::ISingleton<CMICmnStream // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnStreamStdout(void); + /* dtor */ ~CMICmnStreamStdout(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MICmnThreadMgrStd.h b/tools/lldb-mi/MICmnThreadMgrStd.h index 8f2d207995c6..fef999b2a7b1 100644 --- a/tools/lldb-mi/MICmnThreadMgrStd.h +++ b/tools/lldb-mi/MICmnThreadMgrStd.h @@ -35,8 +35,8 @@ class CMICmnThreadMgrStd : public CMICmnBase, public MI::ISingleton<CMICmnThread // Methods: public: - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; bool ThreadAllTerminate(void); // Ask all threads to stop (caution) template <typename T> // Ask the thread manager to start and stop threads on our behalf @@ -58,7 +58,7 @@ class CMICmnThreadMgrStd : public CMICmnBase, public MI::ISingleton<CMICmnThread // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMICmnThreadMgrStd(void); + /* dtor */ ~CMICmnThreadMgrStd(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MIDataTypes.h b/tools/lldb-mi/MIDataTypes.h index b0583343ab3c..33c5b20095d9 100644 --- a/tools/lldb-mi/MIDataTypes.h +++ b/tools/lldb-mi/MIDataTypes.h @@ -51,18 +51,14 @@ const bool failure = false; // Portability issues #ifdef _WIN64 typedef unsigned __int64 size_t; -typedef unsigned __int64 PointerToInteger_t; typedef __int64 MIint; typedef unsigned __int64 MIuint; #else #ifdef _WIN32 typedef unsigned int size_t; -typedef unsigned int PointerToInteger_t; typedef int MIint; typedef unsigned int MIuint; #else -// typedef long unsigned int size_t; // size_t already defined -typedef unsigned int PointerToInteger_t; typedef int MIint; typedef unsigned int MIuint; @@ -74,8 +70,6 @@ typedef unsigned int MIuint; // Common types: // Fundamentals: -typedef float MIflt; -typedef double MIdbl; typedef long long MIint64; // 64bit signed integer. typedef unsigned long long MIuint64; // 64bit unsigned integer. diff --git a/tools/lldb-mi/MIDriver.cpp b/tools/lldb-mi/MIDriver.cpp index 549f9e255790..d4a31958d9ec 100644 --- a/tools/lldb-mi/MIDriver.cpp +++ b/tools/lldb-mi/MIDriver.cpp @@ -343,7 +343,7 @@ CMIDriver::SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver) //++ ------------------------------------------------------------------------------------ // Details: Proxy function CMIDriverMgr IDriver interface implementation. *this driver's // implementation called from here to match the existing function name of the -// original LLDb driver class (the extra indirection is not necessarily required). +// original LLDB driver class (the extra indirection is not necessarily required). // Check the arguments that were passed to this program to make sure they are // valid and to get their argument values (if any). // Type: Overridden. @@ -925,7 +925,7 @@ bool CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid) { // Convert any CLI commands into MI commands - CMIUtilString vMITextLine(WrapCLICommandIntoMICommand(vTextLine)); + const CMIUtilString vMITextLine(WrapCLICommandIntoMICommand(vTextLine)); vwbCmdYesValid = false; bool bCmdNotInCmdFactor = false; diff --git a/tools/lldb-mi/MIDriver.h b/tools/lldb-mi/MIDriver.h index 795549e0f4a0..55c662494e21 100644 --- a/tools/lldb-mi/MIDriver.h +++ b/tools/lldb-mi/MIDriver.h @@ -46,7 +46,7 @@ class CMIDriver : public CMICmnBase, // Enumerations: public: //++ ---------------------------------------------------------------------- - // Details: The MI Driver has a running state which is used to help determin + // Details: The MI Driver has a running state which is used to help determine // which specific action(s) it should take or not allow. // The driver when operational and not shutting down alternates // between eDriverState_RunningNotDebugging and @@ -68,8 +68,8 @@ class CMIDriver : public CMICmnBase, // Methods: public: // MI system - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // MI state bool GetExitApplicationFlag(void) const; @@ -94,26 +94,26 @@ class CMIDriver : public CMICmnBase, // Overridden: public: // From CMIDriverMgr::IDriver - virtual bool DoInitialize(void); - virtual bool DoShutdown(void); - virtual bool DoMainLoop(void); - virtual lldb::SBError DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting); - virtual CMIUtilString GetError(void) const; - virtual const CMIUtilString &GetName(void) const; - virtual lldb::SBDebugger &GetTheDebugger(void); - virtual bool GetDriverIsGDBMICompatibleDriver(void) const; - virtual bool SetId(const CMIUtilString &vId); - virtual const CMIUtilString &GetId(void) const; + bool DoInitialize(void) override; + bool DoShutdown(void) override; + bool DoMainLoop(void) override; + lldb::SBError DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting) override; + CMIUtilString GetError(void) const override; + const CMIUtilString &GetName(void) const override; + lldb::SBDebugger &GetTheDebugger(void) override; + bool GetDriverIsGDBMICompatibleDriver(void) const override; + bool SetId(const CMIUtilString &vId) override; + const CMIUtilString &GetId(void) const override; // From CMIDriverBase - virtual void SetExitApplicationFlag(const bool vbForceExit); - virtual bool DoFallThruToAnotherDriver(const CMIUtilString &vCmd, CMIUtilString &vwErrMsg); - virtual bool SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver); - virtual FILE *GetStdin(void) const; - virtual FILE *GetStdout(void) const; - virtual FILE *GetStderr(void) const; - virtual const CMIUtilString &GetDriverName(void) const; - virtual const CMIUtilString &GetDriverId(void) const; - virtual void DeliverSignal(int signal); + void SetExitApplicationFlag(const bool vbForceExit) override; + bool DoFallThruToAnotherDriver(const CMIUtilString &vCmd, CMIUtilString &vwErrMsg) override; + bool SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver) override; + FILE *GetStdin(void) const override; + FILE *GetStdout(void) const override; + FILE *GetStderr(void) const override; + const CMIUtilString &GetDriverName(void) const override; + const CMIUtilString &GetDriverId(void) const override; + void DeliverSignal(int signal) override; // Typedefs: private: @@ -142,7 +142,7 @@ class CMIDriver : public CMICmnBase, // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMIDriver(void); + /* dtor */ ~CMIDriver(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MIDriverBase.cpp b/tools/lldb-mi/MIDriverBase.cpp index e03e7b0abee8..6bf5ab6e3bec 100644 --- a/tools/lldb-mi/MIDriverBase.cpp +++ b/tools/lldb-mi/MIDriverBase.cpp @@ -175,7 +175,7 @@ CMIDriverBase::GetStderr(void) const //++ ------------------------------------------------------------------------------------ // Details: Set the MI Driver's exit application flag. The application checks this flag -// after every stdin line is read so the exit may not be instantious. +// after every stdin line is read so the exit may not be instantaneous. // If vbForceExit is false the MI Driver queries its state and determines if is // should exit or continue operating depending on that running state. // Type: Overrideable. diff --git a/tools/lldb-mi/MIDriverMain.cpp b/tools/lldb-mi/MIDriverMain.cpp index 3b7588ba5df0..2f469bf6d976 100644 --- a/tools/lldb-mi/MIDriverMain.cpp +++ b/tools/lldb-mi/MIDriverMain.cpp @@ -124,7 +124,7 @@ DriverSystemShutdown(const bool vbAppExitOk) } //++ ------------------------------------------------------------------------------------ -// Details: MI's application start point of execution. The applicaton runs in two modes. +// Details: MI's application start point of execution. The application runs in two modes. // An LLDB native driver mode where it acts no different from the LLDB driver. // The other mode is the MI when it finds on the command line // the --interpreter option. Command line argument --help on its own will give @@ -140,7 +140,7 @@ DriverSystemShutdown(const bool vbAppExitOk) // >0 = Program success with status i.e. Control-C signal status // <0 = Program failed. // -1 = Program failed reason not specified here, see MI log file. -// -1000 = Program failed did not initailize successfully. +// -1000 = Program failed did not initialize successfully. // Throws: None. //-- int diff --git a/tools/lldb-mi/MIDriverMgr.h b/tools/lldb-mi/MIDriverMgr.h index 53fc984f3178..c84ef04c75c4 100644 --- a/tools/lldb-mi/MIDriverMgr.h +++ b/tools/lldb-mi/MIDriverMgr.h @@ -32,7 +32,7 @@ // those objects (modules/components) to support it's own functionality). // The Driver manager is the first object instantiated as part of the // MI code base. It is also the first thing to interpret the command -// line arguments passed to the executeable. Bases on options it +// line arguments passed to the executable. Bases on options it // understands the manage will set up the appropriate driver or give // help information. Other options are passed on to the driver chosen // to do work. @@ -75,8 +75,8 @@ class CMIDriverMgr : public CMICmnBase, public MI::ISingleton<CMIDriverMgr> // Methods: public: // MI system - bool Initialize(void); - bool Shutdown(void); + bool Initialize(void) override; + bool Shutdown(void) override; // CMIUtilString GetAppVersion(void) const; bool RegisterDriver(const IDriver &vrADriver, const CMIUtilString &vrDriverID); @@ -115,7 +115,7 @@ class CMIDriverMgr : public CMICmnBase, public MI::ISingleton<CMIDriverMgr> // Overridden: private: // From CMICmnBase - /* dtor */ virtual ~CMIDriverMgr(void); + /* dtor */ ~CMIDriverMgr(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MIUtilFileStd.h b/tools/lldb-mi/MIUtilFileStd.h index 4b27d2f2faeb..5a2234897768 100644 --- a/tools/lldb-mi/MIUtilFileStd.h +++ b/tools/lldb-mi/MIUtilFileStd.h @@ -41,7 +41,7 @@ class CMIUtilFileStd : public CMICmnBase // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMIUtilFileStd(void); + /* dtor */ ~CMIUtilFileStd(void) override; // Attributes: private: diff --git a/tools/lldb-mi/MIUtilMapIdToVariant.h b/tools/lldb-mi/MIUtilMapIdToVariant.h index 1b9c6a102ef0..c77f0b946683 100644 --- a/tools/lldb-mi/MIUtilMapIdToVariant.h +++ b/tools/lldb-mi/MIUtilMapIdToVariant.h @@ -20,7 +20,7 @@ //++ ============================================================================ // Details: MI common code utility class. Map type container that hold general -// object types (by being wrappin an variant wrapper) +// object types (by being a variant wrapper) // objects by ID. // Gotchas: None. // Authors: Illya Rudkin 19/06/2014. @@ -42,9 +42,9 @@ class CMIUtilMapIdToVariant : public CMICmnBase // Overridden: public: // From CMICmnBase - /* dtor */ virtual ~CMIUtilMapIdToVariant(void); + /* dtor */ ~CMIUtilMapIdToVariant(void) override; - // Typdefs: + // Typedefs: private: typedef std::map<CMIUtilString, CMIUtilVariant> MapKeyToVariantValue_t; typedef std::pair<CMIUtilString, CMIUtilVariant> MapPairKeyToVariantValue_t; @@ -65,8 +65,8 @@ class CMIUtilMapIdToVariant : public CMICmnBase // Args: T - The data object's variable type. // vId - (R) Unique ID i.e. GUID. // vData - (R) The general data object to be stored of some type. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. // Throws: None. //-- template <typename T> @@ -98,8 +98,8 @@ CMIUtilMapIdToVariant::Add(const CMIUtilString &vId, const T &vData) // vId - (R) Unique ID i.e. GUID. // vrwData - (W) Copy of the data object held. // vrwbFound - (W) True = data found, false = data not found. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. // Throws: None. //-- template <typename T> diff --git a/tools/lldb-mi/MIUtilSingletonBase.h b/tools/lldb-mi/MIUtilSingletonBase.h index c6d7f55b159c..3649a73b9fa5 100644 --- a/tools/lldb-mi/MIUtilSingletonBase.h +++ b/tools/lldb-mi/MIUtilSingletonBase.h @@ -22,8 +22,8 @@ namespace MI // // Overridden: // public: // // From MI::ISingleton -// virtual bool Initialize( void ); -// virtual bool Shutdown( void ); +// bool Initialize(void) override; +// bool Shutdown(void) override; // }; //++ ============================================================================ diff --git a/tools/lldb-mi/MIUtilSingletonHelper.h b/tools/lldb-mi/MIUtilSingletonHelper.h index 5bd879e1aa9f..19cc3a92e82f 100644 --- a/tools/lldb-mi/MIUtilSingletonHelper.h +++ b/tools/lldb-mi/MIUtilSingletonHelper.h @@ -24,7 +24,7 @@ namespace MI // MI components (singletons) required by a client module. // Type: Template method. // Args: vErrorResrcId - (R) The string resource ID error message identifier to place in errMsg. -// vwrbOk - (RW) On input True = Try to initalise MI driver module. +// vwrbOk - (RW) On input True = Try to initialize MI driver module. // On output True = MI driver module initialise successfully. // vwrErrMsg - (W) MI driver module initialise error description on failure. // Return: MIstatus::success - Functional succeeded. @@ -46,7 +46,7 @@ ModuleInit(const MIint vErrorResrcId, bool &vwrbOk, CMIUtilString &vwrErrMsg) } //++ ============================================================================ -// Details: Short cut helper function to simplify repeated shutodown of +// Details: Short cut helper function to simplify repeated shutdown of // MI components (singletons) required by a client module. // Type: Template method. // Args: vErrorResrcId - (R) The string resource ID error message identifier diff --git a/tools/lldb-mi/MIUtilString.h b/tools/lldb-mi/MIUtilString.h index eac0746e7d0d..7b188edefefa 100644 --- a/tools/lldb-mi/MIUtilString.h +++ b/tools/lldb-mi/MIUtilString.h @@ -26,7 +26,7 @@ //-- class CMIUtilString : public std::string { - // Typdefs: + // Typedefs: public: typedef std::vector<CMIUtilString> VecString_t; diff --git a/tools/lldb-mi/MIUtilSystemLinux.cpp b/tools/lldb-mi/MIUtilSystemLinux.cpp index a4ae327657f7..8fd2470c992b 100644 --- a/tools/lldb-mi/MIUtilSystemLinux.cpp +++ b/tools/lldb-mi/MIUtilSystemLinux.cpp @@ -78,7 +78,7 @@ CMIUtilSystemLinux::GetOSLastError(void) const // Details: Retrieves the fully qualified path for the this application. If the function // fails the string is filled with the error message. // Type: Method. -// Args: vrwFileNamePath - (W) The excutable's name and path or last error description. +// Args: vrwFileNamePath - (W) The executable's name and path or last error description. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. diff --git a/tools/lldb-mi/MIUtilSystemOsx.cpp b/tools/lldb-mi/MIUtilSystemOsx.cpp index 1834651d40b0..b926342973a6 100644 --- a/tools/lldb-mi/MIUtilSystemOsx.cpp +++ b/tools/lldb-mi/MIUtilSystemOsx.cpp @@ -78,7 +78,7 @@ CMIUtilSystemOsx::GetOSLastError(void) const // Details: Retrieves the fully qualified path for the this application. If the function // fails the string is filled with the error message. // Type: Method. -// Args: vrwFileNamePath - (W) The excutable's name and path or last error description. +// Args: vrwFileNamePath - (W) The executable's name and path or last error description. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. diff --git a/tools/lldb-mi/MIUtilSystemWindows.cpp b/tools/lldb-mi/MIUtilSystemWindows.cpp index 19c6e9eb979f..80f4aac7b63a 100644 --- a/tools/lldb-mi/MIUtilSystemWindows.cpp +++ b/tools/lldb-mi/MIUtilSystemWindows.cpp @@ -100,7 +100,7 @@ CMIUtilSystemWindows::GetOSLastError(void) const // Details: Retrieves the fully qualified path for the this application. If the function // fails the string is filled with the error message. // Type: Method. -// Args: vrwFileNamePath - (W) The excutable's name and path or last error description. +// Args: vrwFileNamePath - (W) The executable's name and path or last error description. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. diff --git a/tools/lldb-mi/MIUtilThreadBaseStd.cpp b/tools/lldb-mi/MIUtilThreadBaseStd.cpp index 2dc6d3d28dde..96f53ff65bf5 100644 --- a/tools/lldb-mi/MIUtilThreadBaseStd.cpp +++ b/tools/lldb-mi/MIUtilThreadBaseStd.cpp @@ -59,7 +59,7 @@ CMIUtilThreadActiveObjBase::ThreadIsActive(void) //++ ------------------------------------------------------------------------------------ // Details: Set up *this thread. -// Type: Mrthod. +// Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. @@ -73,7 +73,7 @@ CMIUtilThreadActiveObjBase::ThreadExecute(void) } //++ ------------------------------------------------------------------------------------ -// Details: Aquire a reference to CMIUtilThreadActiveObjBase. +// Details: Acquire a reference to CMIUtilThreadActiveObjBase. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. diff --git a/tools/lldb-mi/MIUtilVariant.h b/tools/lldb-mi/MIUtilVariant.h index 8e7ac7b8573a..a6c3ba439031 100644 --- a/tools/lldb-mi/MIUtilVariant.h +++ b/tools/lldb-mi/MIUtilVariant.h @@ -95,9 +95,9 @@ class CMIUtilVariant // Overridden: public: // From CDataObjectBase - virtual ~CDataObject(void); - virtual CDataObjectBase *CreateCopyOfSelf(void); - virtual bool GetIsDerivedClass(void) const; + ~CDataObject(void) override; + CDataObjectBase *CreateCopyOfSelf(void) override; + bool GetIsDerivedClass(void) const override; // Overrideable: private: @@ -106,7 +106,7 @@ class CMIUtilVariant // Overridden: private: // From CDataObjectBase - virtual void Destroy(void); + void Destroy(void) override; // Attributes: private: diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp index a286e3df0de4..30bb2d686770 100644 --- a/tools/lldb-server/lldb-gdbserver.cpp +++ b/tools/lldb-server/lldb-gdbserver.cpp @@ -109,16 +109,21 @@ signal_handler(int signo) case SIGPIPE: g_sigpipe_received = 1; break; - case SIGHUP: - ++g_sighup_received_count; - - // For now, swallow SIGHUP. - if (log) - log->Printf ("lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count); - signal (SIGHUP, signal_handler); - break; } } + +static void +sighup_handler(MainLoopBase &mainloop) +{ + ++g_sighup_received_count; + + Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + if (log) + log->Printf ("lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count); + + if (g_sighup_received_count >= 2) + mainloop.RequestTermination(); +} #endif // #ifndef _WIN32 static void @@ -338,7 +343,7 @@ writePortToPipe(int unnamed_pipe_fd, const uint16_t port) } void -ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, +ConnectToRemote(MainLoop &mainloop, GDBRemoteCommunicationServerLLGS &gdb_server, bool reverse_connect, const char *const host_and_port, const char *const progname, const char *const subcommand, const char *const named_pipe_path, int unnamed_pipe_fd) @@ -372,6 +377,8 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, exit (1); } + std::unique_ptr<ConnectionFileDescriptor> connection_up; + if (reverse_connect) { // llgs will connect to the gdb-remote client. @@ -388,8 +395,7 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, snprintf(connection_url, sizeof(connection_url), "connect://%s", final_host_and_port.c_str ()); // Create the connection. - std::unique_ptr<ConnectionFileDescriptor> connection_up (new ConnectionFileDescriptor ()); - connection_up.reset (new ConnectionFileDescriptor ()); + connection_up.reset(new ConnectionFileDescriptor); auto connection_result = connection_up->Connect (connection_url, &error); if (connection_result != eConnectionStatusSuccess) { @@ -401,10 +407,6 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, fprintf (stderr, "error: failed to connect to client at '%s': %s", connection_url, error.AsCString ()); exit (-1); } - - // We're connected. - printf ("Connection established.\n"); - gdb_server.SetConnection (connection_up.release()); } else { @@ -461,10 +463,7 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, // Ensure we connected. if (s_listen_connection_up) - { - printf ("Connection established '%s'\n", s_listen_connection_up->GetURI().c_str()); - gdb_server.SetConnection (s_listen_connection_up.release()); - } + connection_up = std::move(s_listen_connection_up); else { fprintf (stderr, "failed to connect to '%s': %s\n", final_host_and_port.c_str (), error.AsCString ()); @@ -472,46 +471,13 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, exit (1); } } - } - - if (gdb_server.IsConnected()) - { - // After we connected, we need to get an initial ack from... - if (gdb_server.HandshakeWithClient(&error)) + error = gdb_server.InitializeConnection (std::move(connection_up)); + if (error.Fail()) { - // We'll use a half a second timeout interval so that an exit conditions can - // be checked that often. - const uint32_t TIMEOUT_USEC = 500000; - - bool interrupt = false; - bool done = false; - while (!interrupt && !done && (g_sighup_received_count < 2)) - { - const GDBRemoteCommunication::PacketResult result = gdb_server.GetPacketAndSendResponse (TIMEOUT_USEC, error, interrupt, done); - if ((result != GDBRemoteCommunication::PacketResult::Success) && - (result != GDBRemoteCommunication::PacketResult::ErrorReplyTimeout)) - { - // We're bailing out - we only support successful handling and timeouts. - fprintf(stderr, "leaving packet loop due to PacketResult %d\n", result); - break; - } - } - - if (error.Fail()) - { - fprintf(stderr, "error: %s\n", error.AsCString()); - } - } - else - { - fprintf(stderr, "error: handshake with client failed\n"); + fprintf(stderr, "Failed to initialize connection: %s\n", error.AsCString()); + exit(-1); } - } - else - { - fprintf (stderr, "no connection information provided, unable to run\n"); - display_usage (progname, subcommand); - exit (1); + printf ("Connection established.\n"); } } @@ -521,10 +487,12 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server, int main_gdbserver (int argc, char *argv[]) { + Error error; + MainLoop mainloop; #ifndef _WIN32 // Setup signal handlers first thing. signal (SIGPIPE, signal_handler); - signal (SIGHUP, signal_handler); + MainLoop::SignalHandleUP sighup_handle = mainloop.RegisterSignal(SIGHUP, sighup_handler, error); #endif #ifdef __linux__ // Block delivery of SIGCHLD on linux. NativeProcessLinux will read it using signalfd. @@ -539,7 +507,6 @@ main_gdbserver (int argc, char *argv[]) argc--; argv++; int long_option_index = 0; - Error error; int ch; std::string platform_name; std::string attach_target; @@ -670,7 +637,7 @@ main_gdbserver (int argc, char *argv[]) // Setup the platform that GDBRemoteCommunicationServerLLGS will use. lldb::PlatformSP platform_sp = setup_platform (platform_name); - GDBRemoteCommunicationServerLLGS gdb_server (platform_sp); + GDBRemoteCommunicationServerLLGS gdb_server (platform_sp, mainloop); const char *const host_and_port = argv[0]; argc -= 1; @@ -688,10 +655,19 @@ main_gdbserver (int argc, char *argv[]) // Print version info. printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR); - ConnectToRemote(gdb_server, reverse_connect, + ConnectToRemote(mainloop, gdb_server, reverse_connect, host_and_port, progname, subcommand, named_pipe_path.c_str(), unnamed_pipe_fd); + + if (! gdb_server.IsConnected()) + { + fprintf (stderr, "no connection information provided, unable to run\n"); + display_usage (progname, subcommand); + return 1; + } + + mainloop.Run(); fprintf(stderr, "lldb-server exiting...\n"); return 0; diff --git a/tools/lldb-server/lldb-platform.cpp b/tools/lldb-server/lldb-platform.cpp index 33ba1ad1ef98..4dfa7d23a4a8 100644 --- a/tools/lldb-server/lldb-platform.cpp +++ b/tools/lldb-server/lldb-platform.cpp @@ -20,13 +20,18 @@ #include <sys/wait.h> // C++ Includes +#include <fstream> // Other libraries and framework includes #include "lldb/Core/Error.h" #include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostGetOpt.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/Socket.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" @@ -56,6 +61,7 @@ static struct option g_long_options[] = { "gdbserver-port", required_argument, NULL, 'P' }, { "min-gdbserver-port", required_argument, NULL, 'm' }, { "max-gdbserver-port", required_argument, NULL, 'M' }, + { "port-file", required_argument, NULL, 'f' }, { "server", no_argument, &g_server, 1 }, { NULL, 0, NULL, 0 } }; @@ -89,10 +95,42 @@ signal_handler(int signo) static void display_usage (const char *progname, const char *subcommand) { - fprintf(stderr, "Usage:\n %s %s [--log-file log-file-name] [--log-channels log-channel-list] --server --listen port\n", progname, subcommand); + fprintf(stderr, "Usage:\n %s %s [--log-file log-file-name] [--log-channels log-channel-list] [--port-file port-file-path] --server --listen port\n", progname, subcommand); exit(0); } +static Error +save_port_to_file(const uint16_t port, const FileSpec &port_file_spec) +{ + FileSpec temp_file_spec(port_file_spec.GetDirectory().AsCString(), false); + auto error = FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault); + if (error.Fail()) + return Error("Failed to create directory %s: %s", temp_file_spec.GetCString(), error.AsCString()); + + llvm::SmallString<PATH_MAX> temp_file_path; + temp_file_spec.AppendPathComponent("port-file.%%%%%%"); + auto err_code = llvm::sys::fs::createUniqueFile(temp_file_spec.GetCString(), temp_file_path); + if (err_code) + return Error("Failed to create temp file: %s", err_code.message().c_str()); + + llvm::FileRemover tmp_file_remover(temp_file_path.c_str()); + + { + std::ofstream temp_file(temp_file_path.c_str(), std::ios::out); + if (!temp_file.is_open()) + return Error("Failed to open temp file %s", temp_file_path.c_str()); + temp_file << port; + } + + err_code = llvm::sys::fs::rename(temp_file_path.c_str(), port_file_spec.GetPath().c_str()); + if (err_code) + return Error("Failed to rename file %s to %s: %s", + temp_file_path.c_str(), port_file_spec.GetPath().c_str(), err_code.message().c_str()); + + tmp_file_remover.releaseFile(); + return Error(); +} + //---------------------------------------------------------------------- // main //---------------------------------------------------------------------- @@ -112,12 +150,13 @@ main_platform (int argc, char *argv[]) std::string log_file; StringRef log_channels; // e.g. "lldb process threads:gdb-remote default:linux all" - + GDBRemoteCommunicationServerPlatform::PortMap gdbserver_portmap; int min_gdbserver_port = 0; int max_gdbserver_port = 0; uint16_t port_offset = 0; - + + FileSpec port_file; bool show_usage = false; int option_error = 0; int socket_error = -1; @@ -152,6 +191,11 @@ main_platform (int argc, char *argv[]) log_channels = StringRef(optarg); break; + case 'f': // Port file + if (optarg && optarg[0]) + port_file.SetFile(optarg, false); + break; + case 'p': { char *end = NULL; @@ -255,6 +299,15 @@ main_platform (int argc, char *argv[]) } listening_socket_up.reset(socket); printf ("Listening for a connection from %u...\n", listening_socket_up->GetLocalPortNumber()); + if (port_file) + { + error = save_port_to_file(listening_socket_up->GetLocalPortNumber(), port_file); + if (error.Fail()) + { + fprintf(stderr, "failed to write port to %s: %s", port_file.GetPath().c_str(), error.AsCString()); + return 1; + } + } do { GDBRemoteCommunicationServerPlatform platform; @@ -308,7 +361,7 @@ main_platform (int argc, char *argv[]) if (platform.IsConnected()) { // After we connected, we need to get an initial ack from... - if (platform.HandshakeWithClient(&error)) + if (platform.HandshakeWithClient()) { bool interrupt = false; bool done = false; |