From gclayton at apple.com Mon Aug 30 13:11:35 2010 From: gclayton at apple.com (Greg Clayton) Date: Mon, 30 Aug 2010 18:11:35 -0000 Subject: [Lldb-commits] [lldb] r112495 - in /lldb/trunk: include/lldb/Core/Address.h include/lldb/Symbol/Symbol.h include/lldb/Symbol/SymbolContextScope.h include/lldb/Symbol/Variable.h include/lldb/Target/StackFrame.h include/lldb/Target/StackID.h source/Core/Address.cpp source/Plugins/Process/Utility/UnwindLibUnwind.cpp source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp source/Symbol/Symbol.cpp source/Symbol/Variable.cpp source/Target/StackFrame.cpp source/Target/StackFrameList.cpp source/Target/StackID.cpp Message-ID: <20100830181135.77B7F2A6C12C@llvm.org> Author: gclayton Date: Mon Aug 30 13:11:35 2010 New Revision: 112495 URL: http://llvm.org/viewvc/llvm-project?rev=112495&view=rev Log: Clarified the intent of the SymbolContextScope class in the header documentation. Symbol now inherits from the symbol context scope so that the StackID can use a "SymbolContextScope *" instead of a blockID (which could have been the same as some other blockID from another symbol file). Modified the stacks that are created on subsequent stops to reuse the previous stack frame objects which will allow for some internal optimization using pointer comparisons during stepping. Modified: lldb/trunk/include/lldb/Core/Address.h lldb/trunk/include/lldb/Symbol/Symbol.h lldb/trunk/include/lldb/Symbol/SymbolContextScope.h lldb/trunk/include/lldb/Symbol/Variable.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackID.h lldb/trunk/source/Core/Address.cpp lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp lldb/trunk/source/Symbol/Symbol.cpp lldb/trunk/source/Symbol/Variable.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/StackID.cpp Modified: lldb/trunk/include/lldb/Core/Address.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Address.h (original) +++ lldb/trunk/include/lldb/Core/Address.h Mon Aug 30 13:11:35 2010 @@ -51,8 +51,7 @@ /// this happens, breakpoints that are in one of these sections can be /// set/cleared. //---------------------------------------------------------------------- -class Address : - public SymbolContextScope +class Address { public: //------------------------------------------------------------------ @@ -98,7 +97,6 @@ /// offset (LLDB_INVALID_ADDRESS). //------------------------------------------------------------------ Address () : - SymbolContextScope(), m_section (NULL), m_offset (LLDB_INVALID_ADDRESS) { @@ -114,7 +112,6 @@ /// A const Address object reference to copy. //------------------------------------------------------------------ Address (const Address& rhs) : - SymbolContextScope(rhs), m_section (rhs.m_section), m_offset (rhs.m_offset) { @@ -134,7 +131,6 @@ /// The offset in bytes into \a section. //------------------------------------------------------------------ Address (const Section* section, lldb::addr_t offset) : - SymbolContextScope(), m_section (section), m_offset (offset) { @@ -433,27 +429,24 @@ SetSection (const Section* section) { m_section = section; } //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// Reconstruct a symbol context from ad address. /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - CalculateSymbolContext (SymbolContext *sc); - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// This class doesn't inherit from SymbolContextScope because many + /// address objects have short lifespans. Address objects that are + /// section offset can reconstruct their symbol context by looking + /// up the address in the module found in the section. /// - /// @see SymbolContextScope + /// @see SymbolContextScope::CalculateSymbolContext(SymbolContext*) //------------------------------------------------------------------ void - DumpSymbolContext (Stream *s); + CalculateSymbolContext (SymbolContext *sc); protected: //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ - const Section* m_section; ///< The section for the address, can be NULL. - lldb::addr_t m_offset; ///< Offset into section if \a m_section != NULL, else the absolute address value. + const Section* m_section; ///< The section for the address, can be NULL. + lldb::addr_t m_offset; ///< Offset into section if \a m_section != NULL, else the absolute address value. }; //bool operator< (const Address& lhs, const Address& rhs); Modified: lldb/trunk/include/lldb/Symbol/Symbol.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Symbol.h?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Symbol.h (original) +++ lldb/trunk/include/lldb/Symbol/Symbol.h Mon Aug 30 13:11:35 2010 @@ -14,11 +14,13 @@ #include "lldb/Core/AddressRange.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/UserID.h" +#include "lldb/Symbol/SymbolContextScope.h" namespace lldb_private { class Symbol : - public UserID // Used to uniquely identify this symbol in its symbol table + public UserID, // Used to uniquely identify this symbol in its symbol table + public SymbolContextScope { public: // ObjectFile readers can classify their symbol table entries and searches can be made @@ -162,6 +164,22 @@ uint32_t GetPrologueByteSize (); + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext (SymbolContext *sc); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + DumpSymbolContext (Stream *s); + protected: Mangled m_mangled; // uniqued symbol name/mangled name pair Modified: lldb/trunk/include/lldb/Symbol/SymbolContextScope.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContextScope.h?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolContextScope.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolContextScope.h Mon Aug 30 13:11:35 2010 @@ -20,23 +20,47 @@ //---------------------------------------------------------------------- /// @class SymbolContextScope SymbolContextScope.h "lldb/Symbol/SymbolContextScope.h" -/// @brief Inherit from this if your object can reconstruct its symbol -/// context. +/// @brief Inherit from this if your object is part of a symbol context +/// and can reconstruct its symbol context. /// -/// Many objects that have pointers back to parent objects that own them -/// that all inherit from this pure virtual class can reconstruct their -/// symbol context without having to keep a complete SymbolContextScope -/// object in the object state. Examples of these objects include: -/// Module, CompileUnit, Function, and Block. +/// Many objects that are part of a symbol context that have pointers +/// back to parent objects that own them. Any members of a symbol +/// context that, once they are built, will not go away, can inherit +/// from this pure virtual class and can then reconstruct their symbol +/// context without having to keep a complete SymbolContext object in +/// the object. /// -/// Other objects can contain a valid pointer to an instance of this -/// class so they can reconstruct the symbol context in which they are -/// scoped. Example objects include: Variable and Type. Such objects -/// can be scoped at a variety of levels: -/// @li module level for a built built in types. -/// @li file level for compile unit types and variables. -/// @li function or block level for types and variables defined in -/// a function body. +/// Examples of these objects include: +/// @li Module +/// @li CompileUnit +/// @li Function +/// @li Block +/// @li Symbol +/// +/// Other objects can store a "SymbolContextScope *" using any pointers +/// to one of the above objects. This allows clients to hold onto a +/// pointer that uniquely will identify a symbol context. Those clients +/// can then always reconstruct the symbol context using the pointer, or +/// use it to uniquely identify a symbol context for an object. +/// +/// Example objects include that currently use "SymbolContextScope *" +/// objects include: +/// @li Variable objects that can reconstruct where they are scoped +/// by making sure the SymbolContextScope * comes from the scope +/// in which the variable was declared. If a variable is a global, +/// the appropriate CompileUnit * will be used when creating the +/// variable. A static function variables, can the Block scope +/// in which the variable is defined. Function arguments can use +/// the Function object as their scope. The SymbolFile parsers +/// will set these correctly as the variables are parsed. +/// @li Type objects that know exactly in which scope they +/// originated much like the variables above. +/// @li StackID objects that are able to know that if the CFA +/// (stack pointer at the beginning of a function) and the +/// start PC for the function/symbol and the SymbolContextScope +/// pointer (a unique pointer that identifies a symbol context +/// location) match within the same thread, that the stack +/// frame is the same as the previous stack frame. /// /// Objects that adhere to this protocol can reconstruct enough of a /// symbol context to allow functions that take a symbol context to be Modified: lldb/trunk/include/lldb/Symbol/Variable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Variable.h?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Variable.h (original) +++ lldb/trunk/include/lldb/Symbol/Variable.h Mon Aug 30 13:11:35 2010 @@ -29,7 +29,7 @@ Variable(lldb::user_id_t uid, const ConstString& name, Type *type, lldb::ValueType scope, - SymbolContextScope *context, + SymbolContextScope *owner_scope, Declaration* decl, const DWARFExpression& location, bool external, @@ -105,14 +105,14 @@ IsInScope (StackFrame *frame); protected: - ConstString m_name; // Name of the variable - Type * m_type; // The type pointer of the variable (int, struct, class, etc) - lldb::ValueType m_scope; // global, parameter, local - SymbolContextScope *m_context;// The symbol file scope that this variable was defined in - Declaration m_declaration; // Declaration location for this item. - DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() - uint8_t m_external:1, // Visible outside the containing compile unit? - m_artificial:1; // Non-zero if the variable is not explicitly declared in source + ConstString m_name; // Name of the variable + Type *m_type; // The type pointer of the variable (int, struct, class, etc) + lldb::ValueType m_scope; // global, parameter, local + SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in + Declaration m_declaration; // Declaration location for this item. + DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() + uint8_t m_external:1, // Visible outside the containing compile unit? + m_artificial:1; // Non-zero if the variable is not explicitly declared in source private: Variable(const Variable& rhs); Variable& operator=(const Variable& rhs); Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Mon Aug 30 13:11:35 2010 @@ -33,9 +33,29 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr); - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr); - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, const Address& pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, + lldb::user_id_t unwind_frame_idx, + Thread &thread, + lldb::addr_t cfa, + lldb::addr_t pc, + const SymbolContext *sc_ptr); + + StackFrame (lldb::user_id_t frame_idx, + lldb::user_id_t unwind_frame_idx, + Thread &thread, + const lldb::RegisterContextSP ®_context_sp, + lldb::addr_t cfa, + lldb::addr_t pc, + const SymbolContext *sc_ptr); + + StackFrame (lldb::user_id_t frame_idx, + lldb::user_id_t unwind_frame_idx, + Thread &thread, + const lldb::RegisterContextSP ®_context_sp, + lldb::addr_t cfa, + const Address& pc, + const SymbolContext *sc_ptr); + virtual ~StackFrame (); Thread & @@ -95,9 +115,9 @@ } uint32_t - GetConcreteFrameIndex () const + GetUnwindFrameIndex () const { - return m_concrete_frame_index; + return m_unwind_frame_index; } //------------------------------------------------------------------ @@ -121,29 +141,26 @@ protected: friend class StackFrameList; - //------------------------------------------------------------------ - // Classes that inherit from StackFrame can see and modify these - //------------------------------------------------------------------ void - SetInlineBlockID (lldb::user_id_t inline_block_id) - { - m_id.SetInlineBlockID(inline_block_id); - } - + SetSymbolContextScope (SymbolContextScope *symbol_scope); + void - UpdateCurrentFrameFromPreviousFrame (StackFrame &frame); + UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame); + void + UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame); + private: //------------------------------------------------------------------ // For StackFrame only //------------------------------------------------------------------ Thread &m_thread; uint32_t m_frame_index; - uint32_t m_concrete_frame_index; + uint32_t m_unwind_frame_index; lldb::RegisterContextSP m_reg_context_sp; StackID m_id; Address m_frame_code_addr; // The frame code address (might not be the same as the actual PC for inlined frames) as a section/offset address - SymbolContext m_sc; + SymbolContext m_sc; Flags m_flags; Scalar m_frame_base; Error m_frame_base_error; Modified: lldb/trunk/include/lldb/Target/StackID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackID.h (original) +++ lldb/trunk/include/lldb/Target/StackID.h Mon Aug 30 13:11:35 2010 @@ -28,22 +28,22 @@ StackID () : m_start_pc (LLDB_INVALID_ADDRESS), m_cfa (LLDB_INVALID_ADDRESS), - m_inline_block_id (LLDB_INVALID_UID) + m_symbol_scope (NULL) { } explicit - StackID (lldb::addr_t start_pc, lldb::addr_t cfa, lldb::user_id_t inline_block_id) : - m_start_pc (), + StackID (lldb::addr_t start_pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) : + m_start_pc (start_pc), m_cfa (cfa), - m_inline_block_id (inline_block_id) + m_symbol_scope (symbol_scope) { } StackID (const StackID& rhs) : m_start_pc (rhs.m_start_pc), m_cfa (rhs.m_cfa), - m_inline_block_id (rhs.m_inline_block_id) + m_symbol_scope (rhs.m_symbol_scope) { } @@ -69,18 +69,21 @@ return m_cfa; } - lldb::user_id_t - GetInlineBlockID () const + SymbolContextScope * + GetSymbolContextScope () const { - return m_inline_block_id; + return m_symbol_scope; } void - SetInlineBlockID (lldb::user_id_t inline_block_id) + SetSymbolContextScope (SymbolContextScope *symbol_scope) { - m_inline_block_id = inline_block_id; + m_symbol_scope = symbol_scope; } + void + Dump (Stream *s); + //------------------------------------------------------------------ // Operators //------------------------------------------------------------------ @@ -91,7 +94,7 @@ { m_start_pc = rhs.m_start_pc; m_cfa = rhs.m_cfa; - m_inline_block_id = rhs.m_inline_block_id; + m_symbol_scope = rhs.m_symbol_scope; } return *this; } @@ -103,10 +106,15 @@ lldb::addr_t m_start_pc; // The start address for the function/symbol for this frame lldb::addr_t m_cfa; // The call frame address (stack pointer) value // at the beginning of the function that uniquely - // identifies this frame (along with m_inline_block_id below) - lldb::user_id_t m_inline_block_id; // The inline height of a stack frame. Zero is the actual - // value for the place where a thread stops, 1 and above - // are for the inlined frames above the concrete base frame. + // identifies this frame (along with m_symbol_scope below) + SymbolContextScope *m_symbol_scope; // If NULL, there is no block or symbol for this frame. + // If not NULL, this will either be the scope for the + // lexical block for the frame, or the scope + // for the symbol. Symbol context scopes are + // always be unique pointers since the are part + // of the Block and Symbol objects and can easily + // be used to tell if a stack ID is the same as + // another. }; bool operator== (const StackID& lhs, const StackID& rhs); Modified: lldb/trunk/source/Core/Address.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Core/Address.cpp (original) +++ lldb/trunk/source/Core/Address.cpp Mon Aug 30 13:11:35 2010 @@ -241,7 +241,6 @@ } Address::Address (addr_t address, const SectionList * sections) : - SymbolContextScope(), m_section (NULL), m_offset (LLDB_INVALID_ADDRESS) { @@ -707,14 +706,6 @@ } void -Address::DumpSymbolContext (Stream *s) -{ - SymbolContext sc; - CalculateSymbolContext (&sc); - sc.Dump (s, NULL); -} - -void Address::DumpDebug(Stream *s) const { *s << (void *)this << ": " << "Address"; Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp Mon Aug 30 13:11:35 2010 @@ -65,7 +65,7 @@ RegisterContext * UnwindLibUnwind::CreateRegisterContextForFrame (StackFrame *frame) { - uint32_t idx = frame->GetConcreteFrameIndex (); + uint32_t idx = frame->GetUnwindFrameIndex (); const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]); Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp Mon Aug 30 13:11:35 2010 @@ -66,7 +66,7 @@ RegisterContext * UnwindMacOSXFrameBackchain::CreateRegisterContextForFrame (StackFrame *frame) { - uint32_t idx = frame->GetConcreteFrameIndex (); + uint32_t idx = frame->GetUnwindFrameIndex (); const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) return new RegisterContextMacOSXFrameBackchain (m_thread, frame, m_cursors[idx]); Modified: lldb/trunk/source/Symbol/Symbol.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symbol.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Symbol.cpp (original) +++ lldb/trunk/source/Symbol/Symbol.cpp Mon Aug 30 13:11:35 2010 @@ -19,6 +19,7 @@ Symbol::Symbol() : + SymbolContextScope (), UserID (), m_mangled (), m_type (eSymbolTypeInvalid), @@ -51,6 +52,7 @@ uint32_t size, uint32_t flags ) : + SymbolContextScope (), UserID (symID), m_mangled (name, name_is_mangled), m_type (type), @@ -81,6 +83,7 @@ const AddressRange &range, uint32_t flags ) : + SymbolContextScope (), UserID (symID), m_mangled (name, name_is_mangled), m_type (type), @@ -99,6 +102,7 @@ } Symbol::Symbol(const Symbol& rhs): + SymbolContextScope (rhs), UserID (rhs), m_mangled (rhs.m_mangled), m_type (rhs.m_type), @@ -121,6 +125,7 @@ { if (this != &rhs) { + SymbolContextScope::operator= (rhs); UserID::operator= (rhs); m_mangled = rhs.m_mangled; m_type = rhs.m_type; @@ -335,3 +340,43 @@ return ""; } + +void +Symbol::CalculateSymbolContext (SymbolContext *sc) +{ + // Symbols can reconstruct the symbol and the module in the symbol context + sc->symbol = this; + const AddressRange *range = GetAddressRangePtr(); + if (range) + { + Module *module = range->GetBaseAddress().GetModule (); + if (module) + { + sc->module_sp = module->GetSP(); + return; + } + } + sc->module_sp.reset(); +} + +void +Symbol::DumpSymbolContext (Stream *s) +{ + bool dumped_module = false; + const AddressRange *range = GetAddressRangePtr(); + if (range) + { + Module *module = range->GetBaseAddress().GetModule (); + if (module) + { + dumped_module = true; + module->DumpSymbolContext(s); + } + } + if (dumped_module) + s->PutCString(", "); + + s->Printf("Symbol{0x%8.8x}", GetID()); +} + + Modified: lldb/trunk/source/Symbol/Variable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Variable.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Variable.cpp (original) +++ lldb/trunk/source/Symbol/Variable.cpp Mon Aug 30 13:11:35 2010 @@ -37,7 +37,7 @@ m_name(name), m_type(type), m_scope(scope), - m_context(context), + m_owner_scope(context), m_declaration(decl_ptr), m_location(location), m_external(external), @@ -82,10 +82,10 @@ } } - if (show_context && m_context != NULL) + if (show_context && m_owner_scope != NULL) { s->PutCString(", context = ( "); - m_context->DumpSymbolContext(s); + m_owner_scope->DumpSymbolContext(s); s->PutCString(" )"); } @@ -117,8 +117,8 @@ void Variable::CalculateSymbolContext (SymbolContext *sc) { - if (m_context) - m_context->CalculateSymbolContext(sc); + if (m_owner_scope) + m_owner_scope->CalculateSymbolContext(sc); else sc->Clear(); } Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Mon Aug 30 13:11:35 2010 @@ -29,26 +29,26 @@ // The first bits in the flags are reserved for the SymbolContext::Scope bits // so we know if we have tried to look up information in our internal symbol // context (m_sc) already. -#define RESOLVED_FRAME_ADDR (uint32_t(eSymbolContextEverything + 1)) -#define RESOLVED_FRAME_ID (RESOLVED_FRAME_ADDR << 1) -#define GOT_FRAME_BASE (RESOLVED_FRAME_ID << 1) -#define FRAME_IS_OBSOLETE (GOT_FRAME_BASE << 1) -#define RESOLVED_VARIABLES (FRAME_IS_OBSOLETE << 1) +#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) +#define RESOLVED_FRAME_ID_START_ADDR (RESOLVED_FRAME_CODE_ADDR << 1) +#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_ID_START_ADDR << 1) +#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) +#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) StackFrame::StackFrame ( lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_index, + lldb::user_id_t unwind_frame_index, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_concrete_frame_index (concrete_frame_index), + m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (), - m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_id (LLDB_INVALID_ADDRESS, cfa, NULL), m_frame_code_addr (NULL, pc), m_sc (), m_flags (), @@ -67,7 +67,7 @@ StackFrame::StackFrame ( lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_index, + lldb::user_id_t unwind_frame_index, Thread &thread, const RegisterContextSP ®_context_sp, lldb::addr_t cfa, @@ -75,10 +75,10 @@ const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_concrete_frame_index (concrete_frame_index), + m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_id (LLDB_INVALID_ADDRESS, cfa, NULL), m_frame_code_addr (NULL, pc), m_sc (), m_flags (), @@ -103,7 +103,7 @@ StackFrame::StackFrame ( lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_index, + lldb::user_id_t unwind_frame_index, Thread &thread, const RegisterContextSP ®_context_sp, lldb::addr_t cfa, @@ -111,10 +111,10 @@ const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_concrete_frame_index (concrete_frame_index), + m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_id (LLDB_INVALID_ADDRESS, cfa, NULL), m_frame_code_addr (pc_addr), m_sc (), m_flags (), @@ -160,41 +160,92 @@ // Make sure we have resolved our stack ID's start PC before we give // it out to any external clients. This allows us to not have to lookup // this information if it is never asked for. - if (m_flags.IsClear(RESOLVED_FRAME_ID) && m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + if (m_flags.IsClear(RESOLVED_FRAME_ID_START_ADDR)) { - m_flags.Set (RESOLVED_FRAME_ID); + m_flags.Set (RESOLVED_FRAME_ID_START_ADDR); - // Resolve our PC to section offset if we haven't alreday done so - // and if we don't have a module. The resolved address section will - // contain the module to which it belongs. - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) - GetFrameCodeAddress(); + if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + { + // Resolve our PC to section offset if we haven't alreday done so + // and if we don't have a module. The resolved address section will + // contain the module to which it belongs. + if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) + GetFrameCodeAddress(); - if (GetSymbolContext (eSymbolContextFunction).function) + if (GetSymbolContext (eSymbolContextFunction).function) + { + m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + } + else if (GetSymbolContext (eSymbolContextSymbol).symbol) + { + AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); + if (symbol_range_ptr) + m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + } + + // We didn't find a function or symbol, just use the frame code address + // which will be the same as the PC in the frame. + if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); + } + } + + if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) + { + if (m_id.GetSymbolContextScope ()) { - m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); } - else if (GetSymbolContext (eSymbolContextSymbol).symbol) + else { - AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); - if (symbol_range_ptr) - m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock); + + if (m_sc.block) + { + Block *inline_block = m_sc.block->GetContainingInlinedBlock(); + if (inline_block) + { + // Use the block with the inlined function info + // as the symbol context since we want this frame + // to have only the variables for the inlined function + SetSymbolContextScope (inline_block); + } + else + { + // This block is not inlined with means it has no + // inlined parents either, so we want to use the top + // most function block. + SetSymbolContextScope (&m_sc.function->GetBlock(false)); + } + } + else + { + // The current stack frame doesn't have a block. Check to see + // if it has a symbol. If it does we will use this as the + // symbol scope. It is ok if "m_sc.symbol" is NULL below as + // it will set the symbol context to NULL and set the + // RESOLVED_FRAME_ID_SYMBOL_SCOPE flag bit. + GetSymbolContext (eSymbolContextSymbol); + SetSymbolContextScope (m_sc.symbol); + } } - - // We didn't find a function or symbol, just use the frame code address - // which will be the same as the PC in the frame. - if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) - m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); } return m_id; } +void +StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) +{ + m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); + m_id.SetSymbolContextScope (symbol_scope); +} + Address& StackFrame::GetFrameCodeAddress() { - if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_frame_code_addr.IsSectionOffset()) + if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) { - m_flags.Set (RESOLVED_FRAME_ADDR); + m_flags.Set (RESOLVED_FRAME_CODE_ADDR); // Resolve the PC into a temporary address because if ResolveLoadAddress // fails to resolve the address, it will clear the address object... @@ -263,7 +314,7 @@ // Resolve our PC to section offset if we haven't alreday done so // and if we don't have a module. The resolved address section will // contain the module to which it belongs - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) + if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) GetFrameCodeAddress(); // If this is not frame zero, then we need to subtract 1 from the PC @@ -479,7 +530,11 @@ bool StackFrame::IsInlined () { - return m_id.GetInlineBlockID() != LLDB_INVALID_UID; + if (m_sc.block == NULL) + GetSymbolContext (eSymbolContextBlock); + if (m_sc.block) + return m_sc.block->GetContainingInlinedBlock() != NULL; + return false; } Target * @@ -532,13 +587,35 @@ } void -StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &frame) +StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) { - assert (GetStackID() == frame.GetStackID()); // TODO: remove this after some testing - m_variable_list_sp = frame.m_variable_list_sp; - m_value_object_list.Swap (frame.m_value_object_list); + assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing + m_variable_list_sp = prev_frame.m_variable_list_sp; + m_value_object_list.Swap (prev_frame.m_value_object_list); if (!m_disassembly.GetString().empty()) m_disassembly.GetString().swap (m_disassembly.GetString()); } +void +StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) +{ + assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing + assert (&m_thread == &curr_frame.m_thread); + m_frame_index = curr_frame.m_frame_index; + m_unwind_frame_index = curr_frame.m_unwind_frame_index; + m_reg_context_sp = curr_frame.m_reg_context_sp; + m_frame_code_addr = curr_frame.m_frame_code_addr; + assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); + assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); + assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); + assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); + assert (m_sc.symbol == NULL || curr_frame.m_sc.symbol == NULL || m_sc.symbol == curr_frame.m_sc.symbol); + m_sc = curr_frame.m_sc; + m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); + m_flags.Set (m_sc.GetResolvedMask()); + m_frame_base.Clear(); + m_frame_base_error.Clear(); +} + + Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Mon Aug 30 13:11:35 2010 @@ -16,6 +16,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" @@ -60,7 +61,8 @@ StreamFile s(stdout); #endif Unwind *unwinder = m_thread.GetUnwinder (); - addr_t pc, cfa; + addr_t pc = LLDB_INVALID_ADDRESS; + addr_t cfa = LLDB_INVALID_ADDRESS; // If we are going to show inlined stack frames as actual frames, // we need to calculate all concrete frames first, then iterate @@ -77,12 +79,13 @@ // if we need to if (m_frames.empty()) { + cfa = m_thread.m_reg_context_sp->GetSP(); m_thread.GetRegisterContext(); unwind_frame_sp.reset (new StackFrame (m_frames.size(), idx, m_thread, m_thread.m_reg_context_sp, - m_thread.m_reg_context_sp->GetSP(), + cfa, m_thread.m_reg_context_sp->GetPC(), NULL)); m_frames.push_back (unwind_frame_sp); @@ -90,6 +93,7 @@ else { unwind_frame_sp = m_frames.front(); + cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); } } else @@ -100,48 +104,64 @@ m_frames.push_back (unwind_frame_sp); } - Block *block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block; + Block *unwind_block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block; - if (block) + if (unwind_block) { - for (block = block->GetContainingInlinedBlock(); block != NULL; block = block->GetInlinedParent ()) + Block *inlined_block = unwind_block->GetContainingInlinedBlock(); + if (inlined_block) { - SymbolContext inline_sc; - Block *parent_block = block->GetInlinedParent(); + for (; inlined_block != NULL; inlined_block = inlined_block->GetInlinedParent ()) + { + SymbolContext inline_sc; + Block *parent_block = inlined_block->GetInlinedParent(); - const bool is_inlined_frame = parent_block != NULL; - - if (parent_block == NULL) - parent_block = block->GetParent(); + const bool is_inlined_frame = parent_block != NULL; - parent_block->CalculateSymbolContext (&inline_sc); - - Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress()); - if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get()) - previous_frame_lookup_addr.Slide (-1); - - AddressRange range; - block->GetRangeContainingAddress (previous_frame_lookup_addr, range); - - const InlineFunctionInfo* inline_info = block->InlinedFunctionInfo(); - assert (inline_info); - inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress(); - inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); - inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); - inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); - - StackFrameSP frame_sp(new StackFrame (m_frames.size(), - idx, - m_thread, - unwind_frame_sp->GetRegisterContextSP (), - unwind_frame_sp->GetStackID().GetCallFrameAddress(), // CFA - range.GetBaseAddress(), - &inline_sc)); // The symbol context for this inline frame + if (parent_block == NULL) + parent_block = inlined_block->GetParent(); + + parent_block->CalculateSymbolContext (&inline_sc); + + Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress()); + if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get()) + previous_frame_lookup_addr.Slide (-1); - if (is_inlined_frame) - frame_sp->SetInlineBlockID (block->GetID()); + AddressRange range; + inlined_block->GetRangeContainingAddress (previous_frame_lookup_addr, range); - m_frames.push_back (frame_sp); + const InlineFunctionInfo* inline_info = inlined_block->InlinedFunctionInfo(); + assert (inline_info); + inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress(); + inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + + StackFrameSP frame_sp(new StackFrame (m_frames.size(), + idx, + m_thread, + unwind_frame_sp->GetRegisterContextSP (), + cfa, + range.GetBaseAddress(), + &inline_sc)); // The symbol context for this inline frame + + if (is_inlined_frame) + { + // Use the block with the inlined function info + // as the symbol context since we want this frame + // to have only the variables for the inlined function + frame_sp->SetSymbolContextScope (parent_block); + } + else + { + // This block is not inlined with means it has no + // inlined parents either, so we want to use the top + // most function block. + frame_sp->SetSymbolContextScope (&unwind_frame_sp->GetSymbolContext (eSymbolContextFunction).function->GetBlock(false)); + } + + m_frames.push_back (frame_sp); + } } } } @@ -188,34 +208,15 @@ if (curr_frame == NULL || prev_frame == NULL) break; - // Do a quick sanity check to see if the CFA values are the same. - if (curr_frame->m_id.GetCallFrameAddress() != prev_frame->m_id.GetCallFrameAddress()) + // Check the stack ID to make sure they are equal + if (curr_frame->GetStackID() != prev_frame->GetStackID()) break; - // Now check our function or symbol - SymbolContext curr_sc (curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); - SymbolContext prev_sc (prev_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); - if (curr_sc.function && curr_sc.function == prev_sc.function) - { - // Same function - if (curr_sc.block != prev_sc.block) - { - // Same function different block - if (m_show_inlined_frames) - break; - } - } - else if (curr_sc.symbol && curr_sc.symbol == prev_sc.symbol) - { - // Same symbol - } - else if (curr_frame->GetFrameCodeAddress() != prev_frame->GetFrameCodeAddress()) - { - // No symbols for this frame and the PC was different - break; - } - - curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); + prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame); + // Now copy the fixed up previous frame into the current frames + // so the pointer doesn't change + m_frames[curr_frame_idx] = prev_frame_sp; + //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); #if defined (DEBUG_STACK_FRAMES) s.Printf("\n Copying previous frame to current frame"); @@ -253,7 +254,10 @@ StackFrame *frame = (*pos).get(); s->Printf("%p: ", frame); if (frame) + { + frame->GetStackID().Dump (s); frame->Dump(s, true); + } else s->Printf("frame #%u", std::distance (begin, pos)); s->EOL(); @@ -289,17 +293,6 @@ m_thread.m_reg_context_sp->GetPC(), NULL)); - if (m_show_inlined_frames) - { - Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; - - if (block) - { - Block *inline_block = block->GetContainingInlinedBlock(); - if (inline_block) - frame_sp->SetInlineBlockID (inline_block->GetID()); - } - } SetFrameAtIndex(idx, frame_sp); } else if (idx < GetNumFrames()) @@ -318,11 +311,23 @@ if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) { frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL)); + + Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function; + if (function) + { + // When we aren't showing inline functions we always use + // the top most function block as the scope. + frame_sp->SetSymbolContextScope (&function->GetBlock(false)); + } + else + { + // Set the symbol scope from the symbol regardless if it is NULL or valid. + frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol); + } SetFrameAtIndex(idx, frame_sp); } } } - } return frame_sp; } Modified: lldb/trunk/source/Target/StackID.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackID.cpp?rev=112495&r1=112494&r2=112495&view=diff ============================================================================== --- lldb/trunk/source/Target/StackID.cpp (original) +++ lldb/trunk/source/Target/StackID.cpp Mon Aug 30 13:11:35 2010 @@ -13,15 +13,36 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" using namespace lldb_private; +void +StackID::Dump (Stream *s) +{ + s->Printf("StackID (start_pc = 0x%16.16llx, cfa = 0x%16.16llx, symbol_scope = %p", (uint64_t)m_start_pc, (uint64_t)m_cfa, m_symbol_scope); + if (m_symbol_scope) + { + SymbolContext sc; + + m_symbol_scope->CalculateSymbolContext (&sc); + if (sc.block) + s->Printf(" (Block {0x%8.8x})", sc.block->GetID()); + else if (sc.symbol) + s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID()); + } + s->PutCString(") "); +} + bool lldb_private::operator== (const StackID& lhs, const StackID& rhs) { return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && - lhs.GetInlineBlockID() == rhs.GetInlineBlockID() && + lhs.GetSymbolContextScope() == rhs.GetSymbolContextScope() && lhs.GetStartAddress() == rhs.GetStartAddress(); } @@ -29,14 +50,12 @@ lldb_private::operator!= (const StackID& lhs, const StackID& rhs) { return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || - lhs.GetInlineBlockID() != rhs.GetInlineBlockID() || + lhs.GetSymbolContextScope() != rhs.GetSymbolContextScope() || lhs.GetStartAddress() != rhs.GetStartAddress(); } bool lldb_private::operator< (const StackID& lhs, const StackID& rhs) { - if (lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress()) - return true; - return lhs.GetInlineBlockID() < rhs.GetInlineBlockID(); + return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress(); } From jingham at apple.com Mon Aug 30 14:44:40 2010 From: jingham at apple.com (Jim Ingham) Date: Mon, 30 Aug 2010 19:44:40 -0000 Subject: [Lldb-commits] [lldb] r112502 - in /lldb/trunk: include/lldb/API/SBDebugger.h include/lldb/Core/Debugger.h include/lldb/Host/Host.h lldb.xcodeproj/project.pbxproj source/API/SBDebugger.cpp source/Commands/CommandObjectFrame.cpp source/Commands/CommandObjectThread.cpp source/Core/Debugger.cpp source/Host/macosx/Host.mm source/Host/macosx/cfcpp/CFCReleaser.h tools/driver/Driver.cpp tools/driver/Driver.h Message-ID: <20100830194440.73E4F2A6C12C@llvm.org> Author: jingham Date: Mon Aug 30 14:44:40 2010 New Revision: 112502 URL: http://llvm.org/viewvc/llvm-project?rev=112502&view=rev Log: Added a way to open the current source file & line in an external editor, and you can turn this on with: lldb -e Modified: lldb/trunk/include/lldb/API/SBDebugger.h lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Host/Host.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/API/SBDebugger.cpp lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h lldb/trunk/tools/driver/Driver.cpp lldb/trunk/tools/driver/Driver.h Modified: lldb/trunk/include/lldb/API/SBDebugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDebugger.h (original) +++ lldb/trunk/include/lldb/API/SBDebugger.h Mon Aug 30 14:44:40 2010 @@ -106,6 +106,14 @@ lldb::SBSourceManager & GetSourceManager (); + + // FIXME: Once we get the set show stuff in place, the driver won't need + // an interface to the Set/Get UseExternalEditor. + bool + SetUseExternalEditor (bool input); + + bool + UseExternalEditor (); bool GetDefaultArchitecture (char *arch_name, size_t arch_name_len); Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Mon Aug 30 14:44:40 2010 @@ -143,6 +143,20 @@ static lldb::DebuggerSP FindDebuggerWithID (lldb::user_id_t id); + + bool + SetUseExternalEditor (bool value) + { + bool old_value = m_use_external_editor; + m_use_external_editor = value; + return old_value; + } + + bool + UseExternalEditor () + { + return m_use_external_editor; + } protected: @@ -170,6 +184,7 @@ std::stack m_input_readers; std::string m_input_reader_data; + bool m_use_external_editor; // FIXME: Convert this to a set/show variable on the debugger. private: Modified: lldb/trunk/include/lldb/Host/Host.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/Host.h (original) +++ lldb/trunk/include/lldb/Host/Host.h Mon Aug 30 14:44:40 2010 @@ -267,6 +267,9 @@ static ArchSpec GetArchSpecForExistingProcess (const char *process_name); + + static bool + OpenFileInExternalEditor (FileSpec &file_spec, uint32_t line_no); }; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Aug 30 14:44:40 2010 @@ -356,6 +356,7 @@ 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */; }; 4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */; }; 4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */; }; + 4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C74CB6212288704006A8171 /* Carbon.framework */; }; 4CA9637B11B6E99A00780E28 /* CommandObjectApropos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */; }; 9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; }; @@ -960,6 +961,7 @@ 4C51FF1611A4C486007C962F /* ObjCTrampolineHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjCTrampolineHandler.cpp; sourceTree = ""; }; 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectCommands.cpp; path = source/Commands/CommandObjectCommands.cpp; sourceTree = ""; }; 4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectCommands.h; path = source/Commands/CommandObjectCommands.h; sourceTree = ""; }; + 4C74CB6212288704006A8171 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunction.cpp; path = source/Expression/ClangFunction.cpp; sourceTree = ""; }; 4C98D3DB118FB96F00E575D0 /* RecordingMemoryManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecordingMemoryManager.cpp; path = source/Expression/RecordingMemoryManager.cpp; sourceTree = ""; }; 4C98D3E0118FB98F00E575D0 /* ClangFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangFunction.h; path = include/lldb/Expression/ClangFunction.h; sourceTree = ""; }; @@ -1075,6 +1077,7 @@ 26680231115FD1A0008E1FE4 /* Foundation.framework in Frameworks */, 26680232115FD1A4008E1FE4 /* libpython2.6.dylib in Frameworks */, 26680233115FD1A7008E1FE4 /* libobjc.dylib in Frameworks */, + 4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1105,6 +1108,7 @@ 08FB7795FE84155DC02AAC07 /* Source */, 26F5C22410F3D950009D5894 /* Tools */, 1AB674ADFE9D54B511CA2CBB /* Products */, + 4C74CB6212288704006A8171 /* Carbon.framework */, ); name = lldb; sourceTree = ""; Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Mon Aug 30 14:44:40 2010 @@ -563,3 +563,23 @@ sb_debugger.reset (debugger_sp); return sb_debugger; } + +bool +SBDebugger::SetUseExternalEditor (bool value) +{ + if (m_opaque_sp) + return m_opaque_sp->SetUseExternalEditor (value); + else + return false; +} + +bool +SBDebugger::UseExternalEditor () +{ + if (m_opaque_sp) + return m_opaque_sp->UseExternalEditor (); + else + return false; +} + + Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Mon Aug 30 14:44:40 2010 @@ -114,12 +114,19 @@ if (exe_ctx.frame) { + bool already_shown = false; + SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry)); + if (interpreter.GetDebugger().UseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) + { + already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); + } + if (DisplayFrameForExecutionContext (exe_ctx.thread, exe_ctx.frame, interpreter, result.GetOutputStream(), true, - true, + !already_shown, 3, 3)) { Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Mon Aug 30 14:44:40 2010 @@ -60,13 +60,21 @@ // Show one frame with only the first showing source if (show_source) { + bool already_shown = false; + StackFrameSP frame_sp = thread->GetStackFrameAtIndex(0); + SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry)); + if (interpreter.GetDebugger().UseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) + { + already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); + } + DisplayFramesForExecutionContext (thread, interpreter, strm, 0, // Start at first frame 1, // Number of frames to show false,// Don't show the frame info since we already displayed most of it above... - 1, // Show source for the first frame + !already_shown, // Show source for the first frame 3, // lines of source context before 3); // lines of source context after } Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Mon Aug 30 14:44:40 2010 @@ -128,7 +128,8 @@ m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), m_exe_ctx (), m_input_readers (), - m_input_reader_data () + m_input_reader_data (), + m_use_external_editor(false) { m_command_interpreter_ap->Initialize (); } Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug 30 14:44:40 2010 @@ -24,6 +24,8 @@ #include #include +#include +#include #include "cfcpp/CFCBundle.h" #include "cfcpp/CFCReleaser.h" @@ -779,3 +781,116 @@ } return returnSpec; } + +bool +Host::OpenFileInExternalEditor (FileSpec &file_spec, uint32_t line_no) +{ + // We attach this to an 'odoc' event to specify a particular selection + typedef struct { + int16_t reserved0; // must be zero + int16_t fLineNumber; + int32_t fSelStart; + int32_t fSelEnd; + uint32_t reserved1; // must be zero + uint32_t reserved2; // must be zero + } BabelAESelInfo; + + char file_path[PATH_MAX]; + file_spec.GetPath(file_path, PATH_MAX); + CFCString file_cfstr (file_path, kCFStringEncodingUTF8); + CFCReleaser file_URL(::CFURLCreateWithFileSystemPath(NULL, file_cfstr.get(), kCFURLPOSIXPathStyle, false)); + + OSStatus error; + BabelAESelInfo file_and_line_info; + + AEKeyDesc file_and_line_desc; + + bzero(&file_and_line_info, sizeof (file_and_line_info)); + file_and_line_info.fSelStart = 1; + file_and_line_info.fSelEnd = 1; + file_and_line_info.fLineNumber = line_no - 1; + + error = AECreateDesc(typeChar, &file_and_line_info, sizeof (file_and_line_info), &(file_and_line_desc.descContent)); + if (error != noErr) + { + return false; + } + + file_and_line_desc.descKey = keyAEPosition; + + LSApplicationParameters app_params; + bzero (&app_params, sizeof (app_params)); + app_params.flags = kLSLaunchDefaults | kLSLaunchDontSwitch; + + ProcessSerialNumber psn; + CFCReleaser file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL)); + error = LSOpenURLsWithRole(file_array.get(), kLSRolesAll, &file_and_line_desc, &app_params, &psn, 1); + + AEDisposeDesc (&(file_and_line_desc.descContent)); + + if (error != noErr) + { + return false; + } + + ProcessInfoRec which_process; + bzero(&which_process, sizeof(which_process)); + unsigned char ap_name[PATH_MAX]; + which_process.processName = ap_name; + error = GetProcessInformation (&psn, &which_process); + + bool using_xcode = strncmp((char *) ap_name+1, "Xcode", 5) == 0; + + // Xcode doesn't obey the line number in the Open Apple Event. So I have to send + // it an AppleScript to focus on the right line. + + if (using_xcode) + { + static ComponentInstance osa_component = NULL; + static const char *as_template = "tell application \"Xcode\"\n" + "set doc to the first document whose path is \"%s\"\n" + "set the selection to paragraph %d of doc\n" + "--- set the selected paragraph range to {%d, %d} of doc\n" + "end tell\n"; + const int chars_for_int = 32; + static int as_template_len = strlen (as_template); + + + char *as_str; + AEDesc as_desc; + + if (osa_component == NULL) + { + osa_component = OpenDefaultComponent (kOSAComponentType, + kAppleScriptSubtype); + } + + if (osa_component == NULL) + { + return false; + } + + uint32_t as_str_size = as_template_len + strlen (file_path) + 3 * chars_for_int + 1; + as_str = (char *) malloc (as_str_size); + snprintf (as_str, as_str_size - 1, as_template, file_path, line_no, line_no, line_no); + error = AECreateDesc (typeChar, as_str, strlen (as_str), &as_desc); + + free (as_str); + + if (error != noErr) + return false; + + OSAID ret_OSAID; + error = OSACompileExecute (osa_component, &as_desc, kOSANullScript, + kOSAModeNeverInteract, &ret_OSAID); + + OSADispose (osa_component, ret_OSAID); + + AEDisposeDesc (&as_desc); + + if (error != noErr) + return false; + } + + return true; +} Modified: lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h (original) +++ lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h Mon Aug 30 14:44:40 2010 @@ -96,11 +96,14 @@ // assertion fires, check the offending code, or call // reset() prior to using the "ptr_address()" member to make // sure any owned objects has CFRelease called on it. + // I had to add the "enforce_null" bool here because some + // API's require the pointer address even though they don't change it. //---------------------------------------------------------- T* - ptr_address() + ptr_address(bool enforce_null = true) { - assert (_ptr == NULL); + if (enforce_null) + assert (_ptr == NULL); return &_ptr; } Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Mon Aug 30 14:44:40 2010 @@ -70,6 +70,9 @@ { LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, NULL, "", "Tells the debugger to use the file as the program to be debugged." }, + { LLDB_OPT_SET_ALL, false, "editor", 'e', no_argument, NULL, NULL, "", + "Tells the debugger to open source files using the host's \"external editor\" mechanism." }, + // { LLDB_OPT_SET_4, true, "crash-log", 'c', required_argument, NULL, NULL, "", // "Load executable images from a crash log for symbolication." }, @@ -324,7 +327,8 @@ m_debug_mode (false), m_print_version (false), m_print_help (false), - m_seen_options() + m_seen_options(), + m_use_external_editor(false) { } @@ -341,6 +345,7 @@ m_debug_mode = false; m_print_help = false; m_print_version = false; + m_use_external_editor = false; } void @@ -508,7 +513,10 @@ case 'c': m_option_data.m_crash_log = optarg; break; - + case 'e': + m_option_data.m_use_external_editor = true; + break; + case 'f': { SBFileSpec file(optarg); @@ -1042,6 +1050,8 @@ m_debugger.SetErrorFileHandle (stderr, false); m_debugger.SetOutputFileHandle (stdout, false); m_debugger.SetInputFileHandle (stdin, true); + + m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); // You have to drain anything that comes to the master side of the PTY. master_out_comm is // for that purpose. The reason you need to do this is a curious reason... editline will echo Modified: lldb/trunk/tools/driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=112502&r1=112501&r2=112502&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.h (original) +++ lldb/trunk/tools/driver/Driver.h Mon Aug 30 14:44:40 2010 @@ -103,6 +103,7 @@ bool m_debug_mode; bool m_print_version; bool m_print_help; + bool m_use_external_editor; // FIXME: When we have set/show variables we can remove this from here. typedef std::set OptionSet; OptionSet m_seen_options; }; From scallanan at apple.com Mon Aug 30 16:15:33 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 30 Aug 2010 21:15:33 -0000 Subject: [Lldb-commits] [lldb] r112527 - in /lldb/trunk: include/lldb/Expression/ClangExpressionVariable.h source/Expression/ClangExpressionVariable.cpp Message-ID: <20100830211533.D73512A6C12C@llvm.org> Author: spyffe Date: Mon Aug 30 16:15:33 2010 New Revision: 112527 URL: http://llvm.org/viewvc/llvm-project?rev=112527&view=rev Log: Fixed a bug where ClangExpressionVariableList was storing pointers to objects inside a std::vector. These objects can move around as the std::vector changes, invalidating the pointers. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h lldb/trunk/source/Expression/ClangExpressionVariable.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=112527&r1=112526&r2=112527&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Mon Aug 30 16:15:33 2010 @@ -28,7 +28,8 @@ } namespace lldb_private { - + +class ClangExpressionVariableStore; class DataBufferHeap; class ExecutionContext; class Stream; @@ -83,6 +84,12 @@ TypeFromUser m_user_type; ///< The type of the variable according to some LLDB context; NULL if the type hasn't yet been migrated to one //---------------------------------------------------------------------- + /// The following values indicate where the variable originally came from + //---------------------------------------------------------------------- + ClangExpressionVariableStore *m_store; ///< The store containing the variable + uint64_t m_index; ///< The index of the variable in the store + + //---------------------------------------------------------------------- /// The following values should not live beyond parsing //---------------------------------------------------------------------- struct ParserVars { @@ -273,14 +280,14 @@ return NULL; } }; - + //---------------------------------------------------------------------- /// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" /// @brief A list of variable references. /// -/// This class stores references to variables stored elsewhere. +/// This class stores variables internally, acting as the permanent store. //---------------------------------------------------------------------- -class ClangExpressionVariableList : public ClangExpressionVariableListBase +class ClangExpressionVariableStore : public ClangExpressionVariableListBase { public: //---------------------------------------------------------------------- @@ -293,25 +300,39 @@ ClangExpressionVariable &VariableAtIndex(uint64_t index) { - return *m_variables[index]; + return m_variables[index]; } uint64_t AddVariable(ClangExpressionVariable &var) { - m_variables.push_back(&var); + m_variables.push_back(var); return m_variables.size() - 1; } + + //---------------------------------------------------------------------- + /// Create a new variable in the list and return its index + //---------------------------------------------------------------------- + uint64_t CreateVariable() + { + uint64_t index = m_variables.size(); + + m_variables.push_back(ClangExpressionVariable()); + m_variables[index].m_store = this; + m_variables[index].m_index = index; + + return index; + } private: - std::vector m_variables; + std::vector m_variables; }; //---------------------------------------------------------------------- /// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" /// @brief A list of variable references. /// -/// This class stores variables internally, acting as the permanent store. +/// This class stores references to variables stored elsewhere. //---------------------------------------------------------------------- -class ClangExpressionVariableStore : public ClangExpressionVariableListBase +class ClangExpressionVariableList : public ClangExpressionVariableListBase { public: //---------------------------------------------------------------------- @@ -319,30 +340,24 @@ //---------------------------------------------------------------------- uint64_t Size() { - return m_variables.size(); + return m_references.size(); } ClangExpressionVariable &VariableAtIndex(uint64_t index) { - return m_variables[index]; + return m_references[index].first->VariableAtIndex(m_references[index].second); } uint64_t AddVariable(ClangExpressionVariable &var) { - m_variables.push_back(var); - return m_variables.size() - 1; - } - - //---------------------------------------------------------------------- - /// Create a new variable in the list and return its index - //---------------------------------------------------------------------- - uint64_t CreateVariable() - { - m_variables.push_back(ClangExpressionVariable()); - return m_variables.size() - 1; + m_references.push_back(ClangExpressionVariableRef(var.m_store, var.m_index)); + return m_references.size() - 1; } private: - std::vector m_variables; + typedef std::pair + ClangExpressionVariableRef; + + std::vector m_references; }; } // namespace lldb_private Modified: lldb/trunk/source/Expression/ClangExpressionVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionVariable.cpp?rev=112527&r1=112526&r2=112527&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionVariable.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionVariable.cpp Mon Aug 30 16:15:33 2010 @@ -133,7 +133,9 @@ ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) : m_name(cev.m_name), - m_user_type(cev.m_user_type) + m_user_type(cev.m_user_type), + m_store(cev.m_store), + m_index(cev.m_index) { if (cev.m_parser_vars.get()) { From johnny.chen at apple.com Mon Aug 30 16:35:00 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 30 Aug 2010 21:35:00 -0000 Subject: [Lldb-commits] [lldb] r112530 - in /lldb/trunk/test: hello_world/TestHelloWorld.py lldbtest.py Message-ID: <20100830213500.EF9D32A6C12C@llvm.org> Author: johnny Date: Mon Aug 30 16:35:00 2010 New Revision: 112530 URL: http://llvm.org/viewvc/llvm-project?rev=112530&view=rev Log: Added a system() method to the TestBase class of lldbtest.py, which is actually taken from Python 2.7's subprocess.check_output() convenience function. The purpose of this method is to run the os command with arguments and return its output as a byte string. Modified hello_world/TestHelloWorld.py to have two test cases: o test_with_dsym_and_run_command o test_with_dwarf_and_process_launch_api with the dsym case conditioned on sys.platform.startswith("darwin") being true. The two cases utilize the system() method to invoke "make clean; make MAKE_DYSM=YES/NO" to prepare for the appropriate debugging format before running the test logic. Modified: lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112530&r1=112529&r2=112530&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Mon Aug 30 16:35:00 2010 @@ -1,6 +1,6 @@ """Test Python APIs for target, breakpoint, and process.""" -import os, time +import os, sys, time import unittest2 import lldb from lldbtest import * @@ -9,8 +9,25 @@ mydir = "hello_world" + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Create target, breakpoint, launch a process, and then kill it. + + Use dsym info and lldb "run" command. + """ + self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=YES"]) + self.hello_world_python(useLaunchAPI = False) + @unittest2.expectedFailure - def test_hello_world_python(self): + def test_with_dwarf_and_process_launch_api(self): + """Create target, breakpoint, launch a process, and then kill it. + + Use dwarf map (no dsym) and process launch API. + """ + self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=NO"]) + self.hello_world_python(useLaunchAPI = True) + + def hello_world_python(self, useLaunchAPI): """Create target, breakpoint, launch a process, and then kill it.""" exe = os.path.join(os.getcwd(), "a.out") @@ -34,31 +51,30 @@ # rdar://problem/8364687 # SBTarget.LaunchProcess() issue (or is there some race condition)? - # The following approach of launching a process looks untidy and only - # works sometimes. - process = target.LaunchProcess([''], [''], os.ctermid(), False) - - SR = process.GetThreadAtIndex(0).GetStopReason() - count = 0 - while SR == StopReasonEnum("Invalid") or SR == StopReasonEnum("Signal"): - print >> sys.stderr, "StopReason =", StopReasonString(SR) - - time.sleep(1.0) - print >> sys.stderr, "Continuing the process:", process - process.Continue() - - count = count + 1 - if count == 10: - print >> sys.stderr, "Reached 10 iterations, giving up..." - break + if useLaunchAPI: + # The following approach of launching a process looks untidy and only + # works sometimes. + process = target.LaunchProcess([''], [''], os.ctermid(), False) SR = process.GetThreadAtIndex(0).GetStopReason() - - # End of section of launching a process. - - # On the other hand, the following two lines of code are more reliable. - #self.runCmd("run") - #process = target.GetProcess() + count = 0 + while SR == StopReasonEnum("Invalid") or SR == StopReasonEnum("Signal"): + print >> sys.stderr, "StopReason =", StopReasonString(SR) + + time.sleep(1.0) + print >> sys.stderr, "Continuing the process:", process + process.Continue() + + count = count + 1 + if count == 10: + print >> sys.stderr, "Reached 10 iterations, giving up..." + break + + SR = process.GetThreadAtIndex(0).GetStopReason() + else: + # On the other hand, the following two lines of code are more reliable. + self.runCmd("run") + process = target.GetProcess() self.runCmd("thread backtrace") self.runCmd("breakpoint list") Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112530&r1=112529&r2=112530&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 30 16:35:00 2010 @@ -105,8 +105,8 @@ $ """ -import os -import sys +import os, sys +from subprocess import * import time import unittest2 import lldb @@ -364,6 +364,46 @@ print str(method) + ":", result return result + # From 2.7's subprocess.check_output() convenience function. + def system(self, *popenargs, **kwargs): + r"""Run command with arguments and return its output as a byte string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example: + + >>> check_output(["ls", "-l", "/dev/null"]) + 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + + The stdout argument is not allowed as it is used internally. + To capture standard error in the result, use stderr=STDOUT. + + >>> check_output(["/bin/sh", "-c", + ... "ls -l non_existent_file ; exit 0"], + ... stderr=STDOUT) + 'ls: non_existent_file: No such file or directory\n' + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + process = Popen(stdout=PIPE, *popenargs, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + + if self.traceAlways: + print >> sys.stderr + print >> sys.stderr, "output:", output + print >> sys.stderr, "error:", unused_err + print >> sys.stderr, "retcode:", retcode + + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(retcode, cmd, output=output) + return output + def DebugSBValue(self, frame, val): """Debug print a SBValue object, if self.traceAlways is True.""" if not self.traceAlways: @@ -379,4 +419,3 @@ err.write('\t' + "IsPtrType -> " + str(val.TypeIsPtrType()) + '\n') err.write('\t' + "Location -> " + val.GetLocation(frame) + '\n') - From gclayton at apple.com Mon Aug 30 17:00:34 2010 From: gclayton at apple.com (Greg Clayton) Date: Mon, 30 Aug 2010 22:00:34 -0000 Subject: [Lldb-commits] [lldb] r112536 - /lldb/trunk/source/Host/macosx/Host.mm Message-ID: <20100830220034.C6D862A6C12C@llvm.org> Author: gclayton Date: Mon Aug 30 17:00:34 2010 New Revision: 112536 URL: http://llvm.org/viewvc/llvm-project?rev=112536&view=rev Log: Stopped the external editor from adding stuff to the recent list when lldb is launched with the -e option on Mac OS X. Modified: lldb/trunk/source/Host/macosx/Host.mm Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112536&r1=112535&r2=112536&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug 30 17:00:34 2010 @@ -787,30 +787,40 @@ { // We attach this to an 'odoc' event to specify a particular selection typedef struct { - int16_t reserved0; // must be zero - int16_t fLineNumber; - int32_t fSelStart; - int32_t fSelEnd; - uint32_t reserved1; // must be zero - uint32_t reserved2; // must be zero + int16_t reserved0; // must be zero + int16_t fLineNumber; + int32_t fSelStart; + int32_t fSelEnd; + uint32_t reserved1; // must be zero + uint32_t reserved2; // must be zero } BabelAESelInfo; char file_path[PATH_MAX]; file_spec.GetPath(file_path, PATH_MAX); CFCString file_cfstr (file_path, kCFStringEncodingUTF8); - CFCReleaser file_URL(::CFURLCreateWithFileSystemPath(NULL, file_cfstr.get(), kCFURLPOSIXPathStyle, false)); - + CFCReleaser file_URL (::CFURLCreateWithFileSystemPath (NULL, + file_cfstr.get(), + kCFURLPOSIXPathStyle, + false)); + OSStatus error; - BabelAESelInfo file_and_line_info; + BabelAESelInfo file_and_line_info = + { + 0, // reserved0 + line_no - 1, // fLineNumber (zero based line number) + 1, // fSelStart + 1024, // fSelEnd + 0, // reserved1 + 0 // reserved2 + }; AEKeyDesc file_and_line_desc; - bzero(&file_and_line_info, sizeof (file_and_line_info)); - file_and_line_info.fSelStart = 1; - file_and_line_info.fSelEnd = 1; - file_and_line_info.fLineNumber = line_no - 1; + error = ::AECreateDesc (typeUTF8Text, + &file_and_line_info, + sizeof (file_and_line_info), + &(file_and_line_desc.descContent)); - error = AECreateDesc(typeChar, &file_and_line_info, sizeof (file_and_line_info), &(file_and_line_desc.descContent)); if (error != noErr) { return false; @@ -820,12 +830,19 @@ LSApplicationParameters app_params; bzero (&app_params, sizeof (app_params)); - app_params.flags = kLSLaunchDefaults | kLSLaunchDontSwitch; + app_params.flags = kLSLaunchDefaults | + kLSLaunchDontAddToRecents | + kLSLaunchDontSwitch; ProcessSerialNumber psn; CFCReleaser file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL)); - error = LSOpenURLsWithRole(file_array.get(), kLSRolesAll, &file_and_line_desc, &app_params, &psn, 1); - + error = ::LSOpenURLsWithRole (file_array.get(), + kLSRolesViewer, + &file_and_line_desc, + &app_params, + &psn, + 1); + AEDisposeDesc (&(file_and_line_desc.descContent)); if (error != noErr) @@ -837,7 +854,7 @@ bzero(&which_process, sizeof(which_process)); unsigned char ap_name[PATH_MAX]; which_process.processName = ap_name; - error = GetProcessInformation (&psn, &which_process); + error = ::GetProcessInformation (&psn, &which_process); bool using_xcode = strncmp((char *) ap_name+1, "Xcode", 5) == 0; @@ -861,8 +878,8 @@ if (osa_component == NULL) { - osa_component = OpenDefaultComponent (kOSAComponentType, - kAppleScriptSubtype); + osa_component = ::OpenDefaultComponent (kOSAComponentType, + kAppleScriptSubtype); } if (osa_component == NULL) @@ -872,21 +889,34 @@ uint32_t as_str_size = as_template_len + strlen (file_path) + 3 * chars_for_int + 1; as_str = (char *) malloc (as_str_size); - snprintf (as_str, as_str_size - 1, as_template, file_path, line_no, line_no, line_no); - error = AECreateDesc (typeChar, as_str, strlen (as_str), &as_desc); - - free (as_str); + ::snprintf (as_str, + as_str_size - 1, + as_template, + file_path, + line_no, + line_no, + line_no); + + error = ::AECreateDesc (typeChar, + as_str, + strlen (as_str), + &as_desc); + + ::free (as_str); if (error != noErr) return false; OSAID ret_OSAID; - error = OSACompileExecute (osa_component, &as_desc, kOSANullScript, - kOSAModeNeverInteract, &ret_OSAID); - - OSADispose (osa_component, ret_OSAID); + error = ::OSACompileExecute (osa_component, + &as_desc, + kOSANullScript, + kOSAModeNeverInteract, + &ret_OSAID); + + ::OSADispose (osa_component, ret_OSAID); - AEDisposeDesc (&as_desc); + ::AEDisposeDesc (&as_desc); if (error != noErr) return false; From scallanan at apple.com Mon Aug 30 17:17:17 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 30 Aug 2010 22:17:17 -0000 Subject: [Lldb-commits] [lldb] r112540 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp Message-ID: <20100830221717.198082A6C12C@llvm.org> Author: spyffe Date: Mon Aug 30 17:17:16 2010 New Revision: 112540 URL: http://llvm.org/viewvc/llvm-project?rev=112540&view=rev Log: Fixed a bug where the parser-specific members of persistent variables were staying around too long. This caused the following problem: - A persistent result variable is created for the result of an expression. The pointer to the corresponding Decl is stored in the variable. - The persistent variable is looked up during struct generation (correctly) using its Decl. - Another expression defines a new result variable which happens to have a Decl in the same place as the original result variable. - The persistent variable is looked up during struct generation using its Decl, but the old result variable appears first in the list and has the same Decl pointer. The fix is to destroy parser-specific data when it is no longer valid. Also improved some logging as I diagnosed the bug. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=112540&r1=112539&r2=112540&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Mon Aug 30 17:17:16 2010 @@ -117,6 +117,9 @@ /// @param[in] decl /// The Clang declaration for the variable. /// + /// @param[in] name + /// The name of the variable. + /// /// @param[in] value /// The LLVM IR value for this variable. /// @@ -130,6 +133,7 @@ /// True on success; false otherwise. //------------------------------------------------------------------ bool AddValueToStruct (const clang::NamedDecl *decl, + const char *name, llvm::Value *value, size_t size, off_t alignment); @@ -185,6 +189,9 @@ /// As long as the struct is aligned according to its required /// alignment, this offset will align the field correctly. /// + /// @param[out] name + /// The name of the field as used in materialization. + /// /// @param[in] index /// The index of the field about which information is requested. /// @@ -194,6 +201,7 @@ bool GetStructElement (const clang::NamedDecl *&decl, llvm::Value *&value, off_t &offset, + const char *&name, uint32_t index); //------------------------------------------------------------------ Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=112540&r1=112539&r2=112540&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Aug 30 17:17:16 2010 @@ -60,6 +60,16 @@ if (entity.m_parser_vars.get() && entity.m_parser_vars->m_lldb_value) delete entity.m_parser_vars->m_lldb_value; + + entity.DisableParserVars(); + } + + for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size(); + pvar_index < num_pvars; + ++pvar_index) + { + ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index)); + pvar.DisableParserVars(); } if (m_sym_ctx) @@ -106,10 +116,13 @@ bool ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl, + const char *name, llvm::Value *value, size_t size, off_t alignment) { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + m_struct_laid_out = false; if (m_struct_members.GetVariable(decl)) @@ -123,6 +136,12 @@ if (!var) return false; + if (log) + log->Printf("Adding value for decl %p [%s - %s] to the structure", + decl, + name, + var->m_name.c_str()); + // We know entity->m_parser_vars is valid because we used a parser variable // to find it var->m_parser_vars->m_llvm_value = value; @@ -190,6 +209,7 @@ ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl, llvm::Value *&value, off_t &offset, + const char *&name, uint32_t index) { if (!m_struct_laid_out) @@ -207,6 +227,7 @@ decl = member.m_parser_vars->m_named_decl; value = member.m_parser_vars->m_llvm_value; offset = member.m_jit_vars->m_offset; + name = member.m_name.c_str(); return true; } @@ -427,17 +448,20 @@ } else if (persistent_variable) { - if (!member.m_name.compare(m_result_name) && !dematerialize) - continue; + if (!member.m_name.compare(m_result_name)) + { + if (!dematerialize) + continue; - if (dematerialize) - { if (log) log->PutCString("Found result member in the struct"); - + *result = &member; } + if (log) + log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str()); + if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err)) return false; } @@ -457,12 +481,7 @@ const char *name, lldb::addr_t addr, Error &err) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - if (log) - log->Printf("Found persistent variable %s", name); - +{ ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); if (!pvar) @@ -883,6 +902,8 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, ClangExpressionVariable *pvar) { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + TypeFromUser user_type = pvar->m_user_type; TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), @@ -897,6 +918,9 @@ pvar->m_parser_vars->m_named_decl = var_decl; pvar->m_parser_vars->m_llvm_value = NULL; pvar->m_parser_vars->m_lldb_value = NULL; + + if (log) + log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl); } void Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=112540&r1=112539&r2=112540&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Aug 30 17:17:16 2010 @@ -529,6 +529,7 @@ off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type); if (named_decl && !m_decl_map->AddValueToStruct(named_decl, + name.c_str(), V, value_size, value_alignment)) @@ -881,13 +882,15 @@ const clang::NamedDecl *decl; Value *value; off_t offset; + const char *name; - if (!m_decl_map->GetStructElement (decl, value, offset, element_index)) + if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index)) return false; if (log) - log->Printf(" %s (%s) placed at %d", + log->Printf(" %s [%s] (%s) placed at %d", value->getName().str().c_str(), + name, PrintValue(value, true).c_str(), offset); From johnny.chen at apple.com Mon Aug 30 17:26:48 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 30 Aug 2010 22:26:48 -0000 Subject: [Lldb-commits] [lldb] r112542 - in /lldb/trunk/test: hello_world/TestHelloWorld.py lldbtest.py Message-ID: <20100830222648.D49D42A6C12C@llvm.org> Author: johnny Date: Mon Aug 30 17:26:48 2010 New Revision: 112542 URL: http://llvm.org/viewvc/llvm-project?rev=112542&view=rev Log: Added buildDsym() and buildDwarf() methods to lldbtest.TestBase class, and call them from test cases instead of issuing "make clean; make ..." os command. Modified: lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112542&r1=112541&r2=112542&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Mon Aug 30 17:26:48 2010 @@ -15,7 +15,7 @@ Use dsym info and lldb "run" command. """ - self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=YES"]) + self.buildDsym() self.hello_world_python(useLaunchAPI = False) @unittest2.expectedFailure @@ -24,7 +24,7 @@ Use dwarf map (no dsym) and process launch API. """ - self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=NO"]) + self.buildDwarf() self.hello_world_python(useLaunchAPI = True) def hello_world_python(self, useLaunchAPI): Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112542&r1=112541&r2=112542&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 30 17:26:48 2010 @@ -404,6 +404,20 @@ raise CalledProcessError(retcode, cmd, output=output) return output + def buildDsym(self): + """Platform specific way to build binaries with dsym info.""" + if sys.platform.startswith("darwin"): + self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=YES"]) + else: + raise Exception("Don't know how to build binary with dsym") + + def buildDwarf(self): + """Platform specific way to build binaries with dwarf maps.""" + if sys.platform.startswith("darwin"): + self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=NO"]) + else: + raise Exception("Don't know how to build binary with dwarf") + def DebugSBValue(self, frame, val): """Debug print a SBValue object, if self.traceAlways is True.""" if not self.traceAlways: From johnny.chen at apple.com Mon Aug 30 18:08:53 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 30 Aug 2010 23:08:53 -0000 Subject: [Lldb-commits] [lldb] r112547 - in /lldb/trunk/test: array_types/TestArrayTypes.py lldbtest.py Message-ID: <20100830230853.154F02A6C133@llvm.org> Author: johnny Date: Mon Aug 30 18:08:52 2010 New Revision: 112547 URL: http://llvm.org/viewvc/llvm-project?rev=112547&view=rev Log: Converted TestArrayTypes.py to Dsym/Dwarf combination, and added verbose output of os command to lldbtest.TestBase.system() method. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112547&r1=112546&r2=112547&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Mon Aug 30 18:08:52 2010 @@ -9,7 +9,25 @@ mydir = "array_types" - def test_array_types(self): + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + self.buildDsym() + self.array_types() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_python_api(self): + self.buildDsym() + self.array_types_python() + + def test_with_dwarf_and_run_command(self): + self.buildDwarf() + self.array_types() + + def test_with_dwarf_and_python_api(self): + self.buildDwarf() + self.array_types_python() + + def array_types(self): """Test 'variable list var_name' on some variables with array types.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -52,7 +70,7 @@ self.expect("variable list long_6", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(long [6])') - def test_array_types_python(self): + def array_types_python(self): """Use Python APIs to inspect variables with array types.""" exe = os.path.join(os.getcwd(), "a.out") Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112547&r1=112546&r2=112547&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 30 18:08:52 2010 @@ -108,6 +108,7 @@ import os, sys from subprocess import * import time +import types import unittest2 import lldb @@ -392,7 +393,12 @@ retcode = process.poll() if self.traceAlways: + if isinstance(popenargs, types.StringTypes): + args = [popenargs] + else: + args = list(popenargs) print >> sys.stderr + print >> sys.stderr, "os command:", args print >> sys.stderr, "output:", output print >> sys.stderr, "error:", unused_err print >> sys.stderr, "retcode:", retcode From scallanan at apple.com Mon Aug 30 18:10:43 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 30 Aug 2010 23:10:43 -0000 Subject: [Lldb-commits] [lldb] r112548 - /lldb/trunk/include/lldb/Expression/IRForTarget.h Message-ID: <20100830231043.78E522A6C133@llvm.org> Author: spyffe Date: Mon Aug 30 18:10:43 2010 New Revision: 112548 URL: http://llvm.org/viewvc/llvm-project?rev=112548&view=rev Log: Removed documentation for a non-existent function parameter. Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=112548&r1=112547&r2=112548&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Mon Aug 30 18:10:43 2010 @@ -47,10 +47,6 @@ //------------------------------------------------------------------ /// Constructor /// - /// @param[in] pid - /// A unique identifier for this pass. I'm not sure what this does; - /// it just gets passed down to ModulePass's constructor. - /// /// @param[in] decl_map /// The list of externally-referenced variables for the expression, /// for use in looking up globals and allocating the argument From johnny.chen at apple.com Mon Aug 30 18:44:39 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 30 Aug 2010 23:44:39 -0000 Subject: [Lldb-commits] [lldb] r112556 - in /lldb/trunk/test: array_types/TestArrayTypes.py lldbtest.py Message-ID: <20100830234439.6F94B2A6C133@llvm.org> Author: johnny Date: Mon Aug 30 18:44:39 2010 New Revision: 112556 URL: http://llvm.org/viewvc/llvm-project?rev=112556&view=rev Log: Added doc strings to the array_types test cases. And terminate the current process being debugged in the TestBase.tearDown() instead of letting it continue and finish. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112556&r1=112555&r2=112556&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Mon Aug 30 18:44:39 2010 @@ -11,19 +11,23 @@ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_run_command(self): + """Test 'variable list var_name' on some variables with array types.""" self.buildDsym() self.array_types() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_python_api(self): + """Use Python APIs to inspect variables with array types.""" self.buildDsym() self.array_types_python() def test_with_dwarf_and_run_command(self): + """Test 'variable list var_name' on some variables with array types.""" self.buildDwarf() self.array_types() def test_with_dwarf_and_python_api(self): + """Use Python APIs to inspect variables with array types.""" self.buildDwarf() self.array_types_python() @@ -134,6 +138,10 @@ self.assertTrue(long(child5.GetValue(frame)) == 6, "long_6[5] == 6") + # Now kill the process, and we are done. + rc = target.GetProcess().Kill() + self.assertTrue(rc.Success()) + if __name__ == '__main__': import atexit Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112556&r1=112555&r2=112556&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 30 18:44:39 2010 @@ -270,9 +270,9 @@ self.res = lldb.SBCommandReturnObject() def tearDown(self): - # Finish the inferior process, if it was "run" previously. + # Terminate the current process being debugged. if self.runStarted: - self.ci.HandleCommand("continue", self.res) + self.ci.HandleCommand("process kill", self.res) del self.dbg From jingham at apple.com Mon Aug 30 18:48:26 2010 From: jingham at apple.com (Jim Ingham) Date: Mon, 30 Aug 2010 23:48:26 -0000 Subject: [Lldb-commits] [lldb] r112558 - /lldb/trunk/source/Host/macosx/Host.mm Message-ID: <20100830234826.0C77F2A6C133@llvm.org> Author: jingham Date: Mon Aug 30 18:48:25 2010 New Revision: 112558 URL: http://llvm.org/viewvc/llvm-project?rev=112558&view=rev Log: Add LLDB_EXTERNAL_EDITOR Modified: lldb/trunk/source/Host/macosx/Host.mm Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112558&r1=112557&r2=112558&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug 30 18:48:25 2010 @@ -829,15 +829,47 @@ file_and_line_desc.descKey = keyAEPosition; LSApplicationParameters app_params; + static FSRef app_to_use; + static std::string app_name; bzero (&app_params, sizeof (app_params)); app_params.flags = kLSLaunchDefaults | kLSLaunchDontAddToRecents | kLSLaunchDontSwitch; + + char *external_editor = ::getenv ("LLDB_EXTERNAL_EDITOR"); + + if (external_editor != NULL) + { + bool calculate_fsref = true; + if (app_name.empty() || strcmp (app_name.c_str(), external_editor) != 0) + { + calculate_fsref = true; + } + else + calculate_fsref = false; + + if (calculate_fsref) + { + CFCString editor_name (external_editor, kCFStringEncodingUTF8); + error = ::LSFindApplicationForInfo(kLSUnknownCreator, NULL, editor_name.get(), &app_to_use, NULL); + + // If we found the app, then store away the name so we don't have to re-look it up. + if (error == noErr) + app_name.assign (external_editor); + else + return false; + + } + + app_params.application = &app_to_use; + } + + ProcessSerialNumber psn; CFCReleaser file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL)); error = ::LSOpenURLsWithRole (file_array.get(), - kLSRolesViewer, + kLSRolesAll, &file_and_line_desc, &app_params, &psn, From johnny.chen at apple.com Tue Aug 31 12:42:54 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 31 Aug 2010 17:42:54 -0000 Subject: [Lldb-commits] [lldb] r112606 - in /lldb/trunk/test: dotest.py lldbtest.py plugins/ plugins/darwin.py Message-ID: <20100831174254.631DF2A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 12:42:54 2010 New Revision: 112606 URL: http://llvm.org/viewvc/llvm-project?rev=112606&view=rev Log: Changed the buildDsym()/buildDwarf() TestBase methods to use a plugin framework to delegate the building of binaries to a sys.platform-sepcific plugin. Modified the dotest.py test driver to add the "plugins" directory to the PYTHONPATH as well. darwin.py is the Mac OS X plugin module. Added: lldb/trunk/test/plugins/ lldb/trunk/test/plugins/darwin.py Modified: lldb/trunk/test/dotest.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=112606&r1=112605&r2=112606&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Tue Aug 31 12:42:54 2010 @@ -81,6 +81,7 @@ sys.exit(-1) os.environ["LLDB_TEST"] = scriptPath + pluginPath = os.path.join(scriptPath, 'plugins') base = os.path.abspath(os.path.join(scriptPath, os.pardir)) dbgPath = os.path.join(base, 'build', 'Debug', 'LLDB.framework', @@ -101,6 +102,7 @@ sys.path.append(lldbPath) sys.path.append(scriptPath) + sys.path.append(pluginPath) def initTestdirs(): Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112606&r1=112605&r2=112606&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue Aug 31 12:42:54 2010 @@ -13,11 +13,11 @@ LLDB_TEST and PYTHONPATH environment variables, for example: $ export LLDB_TEST=$PWD -$ export PYTHONPATH=/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:$LLDB_TEST +$ export PYTHONPATH=/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:$LLDB_TEST:$LLDB_TEST/plugins $ echo $LLDB_TEST /Volumes/data/lldb/svn/trunk/test $ echo $PYTHONPATH -/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:/Volumes/data/lldb/svn/trunk/test +/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:/Volumes/data/lldb/svn/trunk/test:/Volumes/data/lldb/svn/trunk/test/plugins $ python function_types/TestFunctionTypes.py . ---------------------------------------------------------------------- @@ -112,6 +112,12 @@ import unittest2 import lldb +if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES": + traceAlways = True +else: + traceAlways = False + + # # Some commonly used assert messages. # @@ -203,6 +209,51 @@ def EnvArray(): return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values()) +# From 2.7's subprocess.check_output() convenience function. +def system(*popenargs, **kwargs): + r"""Run command with arguments and return its output as a byte string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example: + + >>> check_output(["ls", "-l", "/dev/null"]) + 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + + The stdout argument is not allowed as it is used internally. + To capture standard error in the result, use stderr=STDOUT. + + >>> check_output(["/bin/sh", "-c", + ... "ls -l non_existent_file ; exit 0"], + ... stderr=STDOUT) + 'ls: non_existent_file: No such file or directory\n' + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + process = Popen(stdout=PIPE, *popenargs, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + + if traceAlways: + if isinstance(popenargs, types.StringTypes): + args = [popenargs] + else: + args = list(popenargs) + print >> sys.stderr + print >> sys.stderr, "os command:", args + print >> sys.stderr, "output:", output + print >> sys.stderr, "error:", unused_err + print >> sys.stderr, "retcode:", retcode + + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(retcode, cmd, output=output) + return output + class TestBase(unittest2.TestCase): """This LLDB abstract base class is meant to be subclassed.""" @@ -221,9 +272,6 @@ # Can be overridden by the LLDB_TIME_WAIT environment variable. timeWait = 1.0; - # os.environ["LLDB_COMMAND_TRACE"], if set to "YES", will turn on this flag. - traceAlways = False; - def setUp(self): #import traceback #traceback.print_stack() @@ -245,10 +293,6 @@ if "LLDB_TIME_WAIT" in os.environ: self.timeWait = float(os.environ["LLDB_TIME_WAIT"]) - if ("LLDB_COMMAND_TRACE" in os.environ and - os.environ["LLDB_COMMAND_TRACE"] == "YES"): - self.traceAlways = True - # Create the debugger instance if necessary. try: self.dbg = lldb.DBG @@ -288,7 +332,7 @@ if not cmd or len(cmd) == 0: raise Exception("Bad 'cmd' parameter encountered") - trace = (True if self.traceAlways else trace) + trace = (True if traceAlways else trace) self.runStarted = (cmd.startswith("run") or cmd.startswith("process launch")) @@ -324,7 +368,7 @@ 'startstr' and matches the substrings contained in 'substrs'. """ - trace = (True if self.traceAlways else trace) + trace = (True if traceAlways else trace) # First run the command. self.runCmd(cmd, trace = (True if trace else False)) @@ -354,79 +398,32 @@ def invoke(self, obj, name, trace=False): """Use reflection to call a method dynamically with no argument.""" - trace = (True if self.traceAlways else trace) + trace = (True if traceAlways else trace) method = getattr(obj, name) import inspect self.assertTrue(inspect.ismethod(method), name + "is a method name of object: " + str(obj)) result = method() - if self.traceAlways: + if trace: print str(method) + ":", result return result - # From 2.7's subprocess.check_output() convenience function. - def system(self, *popenargs, **kwargs): - r"""Run command with arguments and return its output as a byte string. - - If the exit code was non-zero it raises a CalledProcessError. The - CalledProcessError object will have the return code in the returncode - attribute and output in the output attribute. - - The arguments are the same as for the Popen constructor. Example: - - >>> check_output(["ls", "-l", "/dev/null"]) - 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' - - The stdout argument is not allowed as it is used internally. - To capture standard error in the result, use stderr=STDOUT. - - >>> check_output(["/bin/sh", "-c", - ... "ls -l non_existent_file ; exit 0"], - ... stderr=STDOUT) - 'ls: non_existent_file: No such file or directory\n' - """ - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - process = Popen(stdout=PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - - if self.traceAlways: - if isinstance(popenargs, types.StringTypes): - args = [popenargs] - else: - args = list(popenargs) - print >> sys.stderr - print >> sys.stderr, "os command:", args - print >> sys.stderr, "output:", output - print >> sys.stderr, "error:", unused_err - print >> sys.stderr, "retcode:", retcode - - if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise CalledProcessError(retcode, cmd, output=output) - return output - def buildDsym(self): """Platform specific way to build binaries with dsym info.""" - if sys.platform.startswith("darwin"): - self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=YES"]) - else: + module = __import__(sys.platform) + if not module.buildDsym(): raise Exception("Don't know how to build binary with dsym") def buildDwarf(self): """Platform specific way to build binaries with dwarf maps.""" - if sys.platform.startswith("darwin"): - self.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=NO"]) - else: + module = __import__(sys.platform) + if not module.buildDwarf(): raise Exception("Don't know how to build binary with dwarf") def DebugSBValue(self, frame, val): - """Debug print a SBValue object, if self.traceAlways is True.""" - if not self.traceAlways: + """Debug print a SBValue object, if traceAlways is True.""" + if not traceAlways: return err = sys.stderr Added: lldb/trunk/test/plugins/darwin.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/plugins/darwin.py?rev=112606&view=auto ============================================================================== --- lldb/trunk/test/plugins/darwin.py (added) +++ lldb/trunk/test/plugins/darwin.py Tue Aug 31 12:42:54 2010 @@ -0,0 +1,15 @@ +import lldbtest + +#print "Hello, darwin plugin!" + +def buildDsym(): + lldbtest.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=YES"]) + + # True signifies that we can handle building dsym. + return True + +def buildDwarf(): + lldbtest.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=NO"]) + + # True signifies that we can handle building dsym. + return True From johnny.chen at apple.com Tue Aug 31 12:51:08 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 31 Aug 2010 17:51:08 -0000 Subject: [Lldb-commits] [lldb] r112607 - /lldb/trunk/test/README-TestSuite Message-ID: <20100831175108.991182A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 12:51:08 2010 New Revision: 112607 URL: http://llvm.org/viewvc/llvm-project?rev=112607&view=rev Log: Updated to reflect the "plugins" directory. Modified: lldb/trunk/test/README-TestSuite Modified: lldb/trunk/test/README-TestSuite URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/README-TestSuite?rev=112607&r1=112606&r2=112607&view=diff ============================================================================== --- lldb/trunk/test/README-TestSuite (original) +++ lldb/trunk/test/README-TestSuite Tue Aug 31 12:51:08 2010 @@ -59,6 +59,11 @@ Contains Makefile.rules, which can be utilized by test cases to write Makefile based rules to build native binaries. +o plugins directory + + Contains platform specific plugin to build binaries with dsym/dwarf debugging + info. Other platform specific functionalities may be added in the future. + o unittest2 directory Many new features were added to unittest in Python 2.7, including test From jingham at apple.com Tue Aug 31 13:05:13 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 31 Aug 2010 18:05:13 -0000 Subject: [Lldb-commits] [lldb] r112614 - in /lldb/trunk: include/lldb/lldb-private-log.h source/Host/macosx/Host.mm source/lldb-log.cpp Message-ID: <20100831180513.5A52E2A6C12D@llvm.org> Author: jingham Date: Tue Aug 31 13:05:13 2010 New Revision: 112614 URL: http://llvm.org/viewvc/llvm-project?rev=112614&view=rev Log: Add a "lldb host" logging channel, and put logging in the Host::OpenInExternalEditor code. Modified: lldb/trunk/include/lldb/lldb-private-log.h lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/lldb-log.cpp Modified: lldb/trunk/include/lldb/lldb-private-log.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-log.h?rev=112614&r1=112613&r2=112614&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-private-log.h (original) +++ lldb/trunk/include/lldb/lldb-private-log.h Tue Aug 31 13:05:13 2010 @@ -33,6 +33,7 @@ #define LIBLLDB_LOG_OBJECT (1u << 11) #define LIBLLDB_LOG_COMMUNICATION (1u << 12) #define LIBLLDB_LOG_CONNECTION (1u << 13) +#define LIBLLDB_LOG_HOST (1u << 14) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112614&r1=112613&r2=112614&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Tue Aug 31 13:05:13 2010 @@ -795,6 +795,7 @@ uint32_t reserved2; // must be zero } BabelAESelInfo; + Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST); char file_path[PATH_MAX]; file_spec.GetPath(file_path, PATH_MAX); CFCString file_cfstr (file_path, kCFStringEncodingUTF8); @@ -802,6 +803,9 @@ file_cfstr.get(), kCFURLPOSIXPathStyle, false)); + + if (log) + log->Printf("Sending source file: \"%s\" and line: %d to external editor.\n", file_path, line_no); OSStatus error; BabelAESelInfo file_and_line_info = @@ -823,6 +827,8 @@ if (error != noErr) { + if (log) + log->Printf("Error creating AEDesc: %d.\n", error); return false; } @@ -841,6 +847,9 @@ if (external_editor != NULL) { bool calculate_fsref = true; + if (log) + log->Printf("Looking for external editor \"%s\".\n", external_editor); + if (app_name.empty() || strcmp (app_name.c_str(), external_editor) != 0) { calculate_fsref = true; @@ -857,7 +866,11 @@ if (error == noErr) app_name.assign (external_editor); else + { + if (log) + log->Printf("Could not find External Editor application, error: %d.\n", error); return false; + } } @@ -879,6 +892,9 @@ if (error != noErr) { + if (log) + log->Printf("LSOpenURLsWithRole failed, error: %d.\n", error); + return false; } @@ -888,7 +904,15 @@ which_process.processName = ap_name; error = ::GetProcessInformation (&psn, &which_process); - bool using_xcode = strncmp((char *) ap_name+1, "Xcode", 5) == 0; + bool using_xcode; + if (error != noErr) + { + if (log) + log->Printf("GetProcessInformation failed, error: %d.\n", error); + using_xcode = false; + } + else + using_xcode = strncmp((char *) ap_name+1, "Xcode", (int) ap_name[0]) == 0; // Xcode doesn't obey the line number in the Open Apple Event. So I have to send // it an AppleScript to focus on the right line. @@ -916,6 +940,8 @@ if (osa_component == NULL) { + if (log) + log->Printf("Could not get default AppleScript component.\n"); return false; } @@ -937,7 +963,11 @@ ::free (as_str); if (error != noErr) + { + if (log) + log->Printf("Failed to create AEDesc for Xcode AppleEvent: %d.\n", error); return false; + } OSAID ret_OSAID; error = ::OSACompileExecute (osa_component, @@ -951,7 +981,11 @@ ::AEDisposeDesc (&as_desc); if (error != noErr) + { + if (log) + log->Printf("Sending AppleEvent to Xcode failed, error: %d.\n", error); return false; + } } return true; Modified: lldb/trunk/source/lldb-log.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=112614&r1=112613&r2=112614&view=diff ============================================================================== --- lldb/trunk/source/lldb-log.cpp (original) +++ lldb/trunk/source/lldb-log.cpp Tue Aug 31 13:05:13 2010 @@ -151,6 +151,7 @@ else if (strcasestr(arg, "temp") == arg) flag_bits |= LIBLLDB_LOG_TEMPORARY; else if (strcasestr(arg, "comm") == arg) flag_bits |= LIBLLDB_LOG_COMMUNICATION; else if (strcasestr(arg, "conn") == arg) flag_bits |= LIBLLDB_LOG_CONNECTION; + else if (strcasestr(arg, "host") == arg) flag_bits |= LIBLLDB_LOG_HOST; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); From gclayton at apple.com Tue Aug 31 13:35:14 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 31 Aug 2010 18:35:14 -0000 Subject: [Lldb-commits] [lldb] r112616 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Interpreter/ include/lldb/Target/ lldb.xcodeproj/ source/API/ source/Commands/ source/Host/macosx/ source/Interpreter/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/gdb-remote/ source/Target/ tools/debugserver/debugserver.xcodeproj/ tools/debugserver/source/ tools/debugserver/source/MacOSX/ Message-ID: <20100831183514.EDBED2A6C12C@llvm.org> Author: gclayton Date: Tue Aug 31 13:35:14 2010 New Revision: 112616 URL: http://llvm.org/viewvc/llvm-project?rev=112616&view=rev Log: Added the ability to disable ASLR (Address Space Layout Randomization). ASLR is disabled by default, and can be enabled using: (lldb) set disable-aslr 0 Modified: lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/include/lldb/Target/Process.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/API/SBTarget.cpp lldb/trunk/source/Commands/CommandObjectProcess.cpp lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h lldb/trunk/source/Target/Process.cpp lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj lldb/trunk/tools/debugserver/source/DNB.cpp lldb/trunk/tools/debugserver/source/DNB.h lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h lldb/trunk/tools/debugserver/source/debugserver.cpp Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Tue Aug 31 13:35:14 2010 @@ -59,6 +59,7 @@ LaunchProcess (char const **argv, char const **envp, const char *tty, + uint32_t launch_flags, // See lldb::LaunchFlags bool stop_at_entry); lldb::SBFileSpec Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Tue Aug 31 13:35:14 2010 @@ -166,6 +166,9 @@ const Args * GetEnvironmentVariables (); + int + GetDisableASLR (); + const char * ProcessEmbeddedScriptCommands (const char *arg); Modified: lldb/trunk/include/lldb/Target/Process.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Process.h (original) +++ lldb/trunk/include/lldb/Target/Process.h Tue Aug 31 13:35:14 2010 @@ -251,6 +251,9 @@ /// @param[in] envp /// The environment array. /// + /// @param[in] launch_flags + /// Flags to modify the launch (@see lldb::LaunchFlags) + /// /// @param[in] stdin_path /// The path to use when re-directing the STDIN of the new /// process. If all stdXX_path arguments are NULL, a pseudo @@ -273,6 +276,7 @@ virtual Error Launch (char const *argv[], char const *envp[], + uint32_t launch_flags, const char *stdin_path, const char *stdout_path, const char *stderr_path); @@ -620,6 +624,9 @@ /// @param[in] envp /// The environment array. /// + /// @param[in] launch_flags + /// Flags to modify the launch (@see lldb::LaunchFlags) + /// /// @param[in] stdin_path /// The path to use when re-directing the STDIN of the new /// process. If all stdXX_path arguments are NULL, a pseudo @@ -643,6 +650,7 @@ DoLaunch (Module* module, char const *argv[], char const *envp[], + uint32_t launch_flags, const char *stdin_path, const char *stdout_path, const char *stderr_path) = 0; Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Aug 31 13:35:14 2010 @@ -50,6 +50,15 @@ } StepType; //---------------------------------------------------------------------- +// Launch Flags +//---------------------------------------------------------------------- +typedef enum LaunchFlags +{ + eLaunchFlagNone = 0u, + eLaunchFlagDisableASLR = (1u << 0) ///< Disable Address Space Layout Randomization +} LaunchFlags; + +//---------------------------------------------------------------------- // Thread Run Modes //---------------------------------------------------------------------- typedef enum RunMode { Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Aug 31 13:35:14 2010 @@ -2308,6 +2308,7 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, @@ -2811,7 +2812,10 @@ GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = 4.2; - HEADER_SEARCH_PATHS = /usr/include/python2.6; + HEADER_SEARCH_PATHS = ( + /System/Library/Frameworks/System.framework/PrivateHeaders, + /usr/include/python2.6, + ); INFOPLIST_FILE = "resources/LLDB-Info.plist"; INSTALL_PATH = /Developer/Library/PrivateFrameworks; LD_DYLIB_INSTALL_NAME = "@rpath/LLDB.framework/Versions/A/LLDB"; @@ -2864,7 +2868,10 @@ GCC_ENABLE_OBJC_GC = supported; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_VERSION = 4.2; - HEADER_SEARCH_PATHS = /usr/include/python2.6; + HEADER_SEARCH_PATHS = ( + /System/Library/Frameworks/System.framework/PrivateHeaders, + /usr/include/python2.6, + ); INFOPLIST_FILE = "resources/LLDB-Info.plist"; INSTALL_PATH = /Developer/Library/PrivateFrameworks; LD_DYLIB_INSTALL_NAME = "@rpath/LLDB.framework/Versions/A/LLDB"; @@ -2974,7 +2981,10 @@ GCC_ENABLE_OBJC_GC = supported; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_VERSION = 4.2; - HEADER_SEARCH_PATHS = /usr/include/python2.6; + HEADER_SEARCH_PATHS = ( + /System/Library/Frameworks/System.framework/PrivateHeaders, + /usr/include/python2.6, + ); INFOPLIST_FILE = "resources/LLDB-Info.plist"; INSTALL_PATH = /Developer/Library/PrivateFrameworks; LD_DYLIB_INSTALL_NAME = "@rpath/LLDB.framework/Versions/A/LLDB"; Modified: lldb/trunk/source/API/SBTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/API/SBTarget.cpp (original) +++ lldb/trunk/source/API/SBTarget.cpp Tue Aug 31 13:35:14 2010 @@ -121,6 +121,7 @@ char const **argv, char const **envp, const char *tty, + uint32_t launch_flags, bool stop_at_entry ) { @@ -129,7 +130,7 @@ process = CreateProcess(); if (process.IsValid()) { - Error error (process->Launch (argv, envp, tty, tty, tty)); + Error error (process->Launch (argv, envp, launch_flags, tty, tty, tty)); if (error.Success()) { if (!stop_at_entry) Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Tue Aug 31 13:35:14 2010 @@ -163,6 +163,9 @@ const Args *environment = interpreter.GetEnvironmentVariables(); const Args *run_args = interpreter.GetProgramArguments(); + uint32_t launch_flags = eLaunchFlagNone; + if (interpreter.GetDisableASLR()) + launch_flags |= eLaunchFlagDisableASLR; // There are two possible sources of args to be passed to the process upon launching: Those the user // typed at the run command (launch_args); or those the user pre-set in the run-args variable (run_args). @@ -204,6 +207,7 @@ Error error (process->Launch (launch_args.GetConstArgumentVector(), environment ? environment->GetConstArgumentVector() : NULL, + launch_flags, stdin_path, stdout_path, stderr_path)); Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Tue Aug 31 13:35:14 2010 @@ -834,17 +834,17 @@ file_and_line_desc.descKey = keyAEPosition; + static FSRef g_app_fsref; + LSApplicationParameters app_params; - static FSRef app_to_use; - static std::string app_name; - bzero (&app_params, sizeof (app_params)); + ::bzero (&app_params, sizeof (app_params)); app_params.flags = kLSLaunchDefaults | kLSLaunchDontAddToRecents | kLSLaunchDontSwitch; - + char *external_editor = ::getenv ("LLDB_EXTERNAL_EDITOR"); - if (external_editor != NULL) + if (external_editor) { bool calculate_fsref = true; if (log) @@ -852,20 +852,15 @@ if (app_name.empty() || strcmp (app_name.c_str(), external_editor) != 0) { - calculate_fsref = true; - } - else - calculate_fsref = false; - - if (calculate_fsref) - { CFCString editor_name (external_editor, kCFStringEncodingUTF8); - error = ::LSFindApplicationForInfo(kLSUnknownCreator, NULL, editor_name.get(), &app_to_use, NULL); + error = ::LSFindApplicationForInfo (kLSUnknownCreator, + NULL, + editor_name.get(), + &g_app_fsref, + NULL); // If we found the app, then store away the name so we don't have to re-look it up. - if (error == noErr) - app_name.assign (external_editor); - else + if (error != noErr) { if (log) log->Printf("Could not find External Editor application, error: %d.\n", error); @@ -873,12 +868,9 @@ } } - - app_params.application = &app_to_use; + app_params.application = &g_app_fsref; } - - ProcessSerialNumber psn; CFCReleaser file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL)); error = ::LSOpenURLsWithRole (file_array.get(), Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Tue Aug 31 13:35:14 2010 @@ -161,6 +161,11 @@ 80, "The maximum number of columns to use for displaying text.")); + m_variables["disable-aslr"] = + StateVariableSP (new StateVariable ("disable-aslr", + 1, + "Disable Address Space Layout Randomization (ASLR).")); + } const char * @@ -898,6 +903,14 @@ return NULL; } +int +CommandInterpreter::GetDisableASLR () +{ + StateVariable *var = GetStateVariable ("disable-aslr"); + int disable_aslr = var->GetIntValue(); + + return disable_aslr; +} CommandInterpreter::~CommandInterpreter () { Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Tue Aug 31 13:35:14 2010 @@ -64,6 +64,9 @@ #define MACH_PROCESS_USE_POSIX_SPAWN 1 #endif +#ifndef _POSIX_SPAWN_DISABLE_ASLR +#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 +#endif #if defined (__arm__) @@ -312,6 +315,7 @@ Module* module, char const *argv[], char const *envp[], + uint32_t flags, const char *stdin_path, const char *stdout_path, const char *stderr_path @@ -328,7 +332,7 @@ ArchSpec arch_spec(module->GetArchitecture()); // Set our user ID to our process ID. - SetID (LaunchForDebug(argv[0], argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, eLaunchDefault, error)); + SetID (LaunchForDebug(argv[0], argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, eLaunchDefault, flags, error)); } else { @@ -1557,6 +1561,7 @@ const char *stdout_path, const char *stderr_path, PDLaunchType launch_type, + uint32_t flags, Error &launch_err) { // Clear out and clean up from any current state @@ -1569,7 +1574,7 @@ Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); if (log) - log->Printf ("%s( path = '%s', argv = %p, envp = %p, launch_type = %u )", __FUNCTION__, path, argv, envp, launch_type); + log->Printf ("%s( path = '%s', argv = %p, envp = %p, launch_type = %u, flags = %x )", __FUNCTION__, path, argv, envp, launch_type, flags); // Fork a child process for debugging SetPrivateState (eStateLaunching); @@ -1580,7 +1585,7 @@ break; case eLaunchPosixSpawn: - SetID(ProcessMacOSX::PosixSpawnChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, launch_err)); + SetID(ProcessMacOSX::PosixSpawnChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, flags & eLaunchFlagDisableASLR ? 1 : 0, launch_err)); break; #if defined (__arm__) @@ -1683,11 +1688,12 @@ const char *stdout_path, const char *stderr_path, ProcessMacOSX* process, + int disable_aslr, Error &err ) { posix_spawnattr_t attr; - + short flags; Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); Error local_err; // Errors that don't affect the spawning. @@ -1699,9 +1705,13 @@ if (err.Fail()) return LLDB_INVALID_PROCESS_ID; - err.SetError( ::posix_spawnattr_setflags (&attr, POSIX_SPAWN_START_SUSPENDED), eErrorTypePOSIX); + flags = POSIX_SPAWN_START_SUSPENDED; + if (disable_aslr) + flags |= _POSIX_SPAWN_DISABLE_ASLR; + + err.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); if (err.Fail() || log) - err.PutToLog(log, "::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED )"); + err.PutToLog(log, "::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", disable_aslr ? " | _POSIX_SPAWN_DISABLE_ASLR" : ""); if (err.Fail()) return LLDB_INVALID_PROCESS_ID; Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Tue Aug 31 13:35:14 2010 @@ -93,6 +93,7 @@ DoLaunch (lldb_private::Module* module, char const *argv[], // Can be NULL char const *envp[], // Can be NULL + uint32_t launch_flags, const char *stdin_path, // Can be NULL const char *stdout_path, // Can be NULL const char *stderr_path); // Can be NULL @@ -261,6 +262,7 @@ const char *stdout_path, const char *stderr_path, PDLaunchType launch_type, + uint32_t flags, lldb_private::Error &launch_err); static lldb::pid_t @@ -283,6 +285,7 @@ const char *stdout_path, const char *stderr_path, ProcessMacOSX* process, + int disable_aslr, lldb_private::Error &launch_err); #if defined (__arm__) Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Aug 31 13:35:14 2010 @@ -375,6 +375,7 @@ Module* module, char const *argv[], char const *envp[], + uint32_t launch_flags, const char *stdin_path, const char *stdout_path, const char *stderr_path @@ -404,6 +405,7 @@ NULL, //stdin_path, LLDB_INVALID_PROCESS_ID, NULL, false, + launch_flags & eLaunchFlagDisableASLR != 0, inferior_arch); if (error.Fail()) return error; @@ -422,6 +424,7 @@ NULL, //stdin_path, LLDB_INVALID_PROCESS_ID, NULL, false, + launch_flags & eLaunchFlagDisableASLR != 0, inferior_arch); if (error.Fail()) return error; @@ -639,12 +642,14 @@ SetPrivateState (eStateAttaching); char host_port[128]; snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); - error = StartDebugserverProcess (host_port, - NULL, - NULL, - NULL, - LLDB_INVALID_PROCESS_ID, - NULL, false, + error = StartDebugserverProcess (host_port, // debugserver_url + NULL, // inferior_argv + NULL, // inferior_envp + NULL, // stdin_path + LLDB_INVALID_PROCESS_ID, // attach_pid + NULL, // attach_pid_name + false, // wait_for_launch + false, // disable_aslr arch_spec); if (error.Fail()) @@ -740,12 +745,14 @@ char host_port[128]; ArchSpec arch_spec = GetTarget().GetArchitecture(); snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); - error = StartDebugserverProcess (host_port, - NULL, - NULL, - NULL, - LLDB_INVALID_PROCESS_ID, - NULL, false, + error = StartDebugserverProcess (host_port, // debugserver_url + NULL, // inferior_argv + NULL, // inferior_envp + NULL, // stdin_path + LLDB_INVALID_PROCESS_ID, // attach_pid + NULL, // attach_pid_name + false, // wait_for_launch + false, // disable_aslr arch_spec); if (error.Fail()) { @@ -1644,6 +1651,7 @@ lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID then attach to this attach_pid const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name" bool wait_for_launch, // Wait for the process named "attach_name" to launch + bool disable_aslr, // Disable ASLR ArchSpec& inferior_arch // The arch of the inferior that we will launch ) { @@ -1771,6 +1779,9 @@ // signals generated by special terminal key // sequences (^C) don't affect debugserver + if (disable_aslr) + debugserver_args.AppendArguments("--disable-aslr"); + // Only set the inferior if (launch_process) { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Tue Aug 31 13:35:14 2010 @@ -81,6 +81,7 @@ DoLaunch (lldb_private::Module* module, char const *argv[], // Can be NULL char const *envp[], // Can be NULL + uint32_t flags, const char *stdin_path, // Can be NULL const char *stdout_path, // Can be NULL const char *stderr_path); // Can be NULL @@ -292,6 +293,7 @@ lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, then attach to this pid const char *attach_pid_name, // Wait for the next process to launch whose basename matches "attach_wait_name" bool wait_for_launch, // Wait for the process named "attach_wait_name" to launch + bool disable_aslr, // Disable ASLR lldb_private::ArchSpec& arch_spec); void Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Tue Aug 31 13:35:14 2010 @@ -946,6 +946,7 @@ ( char const *argv[], char const *envp[], + uint32_t launch_flags, const char *stdin_path, const char *stdout_path, const char *stderr_path @@ -994,6 +995,7 @@ error = DoLaunch (exe_module, exec_path_plus_argv.empty() ? NULL : &exec_path_plus_argv.front(), envp, + launch_flags, stdin_path, stdout_path, stderr_path); Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original) +++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Tue Aug 31 13:35:14 2010 @@ -499,6 +499,7 @@ CURRENT_PROJECT_VERSION = 112; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER; + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_PATH = /Developer/usr/bin; LLDB_DEBUGSERVER = 1; OTHER_CFLAGS = "-Wparentheses"; @@ -531,6 +532,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER; + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_PATH = /Developer/usr/bin; LLDB_DEBUGSERVER = 1; OTHER_CFLAGS = "-Wparentheses"; @@ -561,6 +563,7 @@ CURRENT_PROJECT_VERSION = 112; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER; + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_PATH = /Developer/usr/bin; LLDB_DEBUGSERVER = 1; OTHER_CFLAGS = "-Wparentheses"; Modified: lldb/trunk/tools/debugserver/source/DNB.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/DNB.cpp (original) +++ lldb/trunk/tools/debugserver/source/DNB.cpp Tue Aug 31 13:35:14 2010 @@ -177,10 +177,11 @@ const char *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, + int disable_aslr, char *err_str, size_t err_len) { - DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, launch_flavor = %u, err = %p, err_len = %zu) called...", __FUNCTION__, path, argv, envp, launch_flavor, err_str, err_len); + DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = %zu) called...", __FUNCTION__, path, argv, envp, launch_flavor, disable_aslr, err_str, err_len); if (err_str && err_len > 0) err_str[0] = '\0'; @@ -197,7 +198,7 @@ if (processSP.get()) { DNBError launch_err; - pid_t pid = processSP->LaunchForDebug(path, argv, envp, stdio_path, launch_flavor, launch_err); + pid_t pid = processSP->LaunchForDebug(path, argv, envp, stdio_path, launch_flavor, disable_aslr, launch_err); if (err_str) { *err_str = '\0'; Modified: lldb/trunk/tools/debugserver/source/DNB.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/DNB.h (original) +++ lldb/trunk/tools/debugserver/source/DNB.h Tue Aug 31 13:35:14 2010 @@ -28,7 +28,7 @@ //---------------------------------------------------------------------- // Process control //---------------------------------------------------------------------- -nub_process_t DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, char *err_str, size_t err_len) DNB_EXPORT; +nub_process_t DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, char *err_str, size_t err_len) DNB_EXPORT; nub_process_t DNBProcessAttach (nub_process_t pid, struct timespec *timeout, char *err_str, size_t err_len) DNB_EXPORT; nub_process_t DNBProcessAttachByName (const char *name, struct timespec *timeout, char *err_str, size_t err_len) DNB_EXPORT; nub_process_t DNBProcessAttachWait (const char *wait_name, nub_launch_flavor_t launch_flavor, struct timespec *timeout, useconds_t interval, char *err_str, size_t err_len, DNBShouldCancelCallback should_cancel = NULL, void *callback_data = NULL) DNB_EXPORT; Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp Tue Aug 31 13:35:14 2010 @@ -85,6 +85,9 @@ #define MACH_PROCESS_USE_POSIX_SPAWN 1 #endif +#ifndef _POSIX_SPAWN_DISABLE_ASLR +#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 +#endif MachProcess::MachProcess() : m_pid (0), @@ -1457,13 +1460,14 @@ char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, + int disable_aslr, DNBError &launch_err ) { // Clear out and clean up from any current state Clear(); - DNBLogThreadedIf(LOG_PROCESS, "%s( path = '%s', argv = %p, envp = %p, launch_flavor = %u )", __FUNCTION__, path, argv, envp, launch_flavor); + DNBLogThreadedIf(LOG_PROCESS, "%s( path = '%s', argv = %p, envp = %p, launch_flavor = %u, disable_aslr = %d )", __FUNCTION__, path, argv, envp, launch_flavor, disable_aslr); // Fork a child process for debugging SetState(eStateLaunching); @@ -1475,7 +1479,7 @@ break; case eLaunchFlavorPosixSpawn: - m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, argv, envp, stdio_path, this, launch_err); + m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, argv, envp, stdio_path, this, disable_aslr, launch_err); break; #if defined (__arm__) @@ -1562,10 +1566,12 @@ char const *envp[], const char *stdio_path, MachProcess* process, + int disable_aslr, DNBError& err ) { posix_spawnattr_t attr; + short flags; DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv=%p, envp=%p, process )", __FUNCTION__, path, argv, envp); err.SetError( ::posix_spawnattr_init (&attr), DNBError::POSIX); @@ -1574,9 +1580,13 @@ if (err.Fail()) return INVALID_NUB_PROCESS; - err.SetError( ::posix_spawnattr_setflags (&attr, POSIX_SPAWN_START_SUSPENDED), DNBError::POSIX); + flags = POSIX_SPAWN_START_SUSPENDED; + if (disable_aslr) + flags |= _POSIX_SPAWN_DISABLE_ASLR; + + err.SetError( ::posix_spawnattr_setflags (&attr, flags), DNBError::POSIX); if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) - err.LogThreaded("::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED )"); + err.LogThreaded("::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", flags & _POSIX_SPAWN_DISABLE_ASLR ? " | _POSIX_SPAWN_DISABLE_ASLR" : ""); if (err.Fail()) return INVALID_NUB_PROCESS; @@ -1585,13 +1595,6 @@ // On SnowLeopard we should set "DYLD_NO_PIE" in the inferior environment.... -//#ifndef _POSIX_SPAWN_DISABLE_ASLR -//#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 -//#endif -// err.SetError( ::posix_spawnattr_setflags (&attr, _POSIX_SPAWN_DISABLE_ASLR), DNBError::POSIX); -// if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) -// err.LogThreaded("::posix_spawnattr_setflags ( &attr, _POSIX_SPAWN_DISABLE_ASLR )"); - #if !defined(__arm__) // We don't need to do this for ARM, and we really shouldn't now that we Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Tue Aug 31 13:35:14 2010 @@ -46,9 +46,9 @@ // Child process control //---------------------------------------------------------------------- pid_t AttachForDebug (pid_t pid, char *err_str, size_t err_len); - pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, DNBError &err); + pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &err); static pid_t ForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &err); - static pid_t PosixSpawnChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, DNBError& err); + static pid_t PosixSpawnChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, int disable_aslr, DNBError& err); nub_addr_t GetDYLDAllImageInfosAddress (); static const void * PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str); static void CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str); Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=112616&r1=112615&r2=112616&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/debugserver.cpp (original) +++ lldb/trunk/tools/debugserver/source/debugserver.cpp Tue Aug 31 13:35:14 2010 @@ -53,6 +53,7 @@ static int g_lockdown_opt = 0; static int g_applist_opt = 0; static nub_launch_flavor_t g_launch_flavor = eLaunchFlavorDefault; +static int g_disable_aslr = 0; int g_isatty = 0; @@ -209,6 +210,7 @@ &inferior_envp[0], stdio_path, launch_flavor, + g_disable_aslr, launch_err_str, sizeof(launch_err_str)); @@ -655,6 +657,7 @@ { "native-regs", no_argument, NULL, 'r' }, // Specify to use the native registers instead of the gdb defaults for the architecture. { "stdio-path", required_argument, NULL, 's' }, // Set the STDIO path to be used when launching applications { "setsid", no_argument, NULL, 'S' }, // call setsid() to make debugserver run in its own sessions + { "disable-aslr", no_argument, NULL, 'D' }, // Use _POSIX_SPAWN_DISABLE_ASLR to avoid shared library randomization { NULL, 0, NULL, 0 } }; @@ -861,6 +864,9 @@ // signals sent to the session (i.e. dying when anyone hits ^C). setsid(); break; + case 'D': + g_disable_aslr = 1; + break; } } From gclayton at apple.com Tue Aug 31 13:56:24 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 31 Aug 2010 18:56:24 -0000 Subject: [Lldb-commits] [lldb] r112626 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj source/Host/macosx/Host.mm Message-ID: <20100831185624.BF29B2A6C12C@llvm.org> Author: gclayton Date: Tue Aug 31 13:56:24 2010 New Revision: 112626 URL: http://llvm.org/viewvc/llvm-project?rev=112626&view=rev Log: Cleaned up my previous submission which had some header search paths that were not needed and fixed a merge issue. Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Host/macosx/Host.mm Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112626&r1=112625&r2=112626&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Aug 31 13:56:24 2010 @@ -2812,10 +2812,7 @@ GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = 4.2; - HEADER_SEARCH_PATHS = ( - /System/Library/Frameworks/System.framework/PrivateHeaders, - /usr/include/python2.6, - ); + HEADER_SEARCH_PATHS = /usr/include/python2.6; INFOPLIST_FILE = "resources/LLDB-Info.plist"; INSTALL_PATH = /Developer/Library/PrivateFrameworks; LD_DYLIB_INSTALL_NAME = "@rpath/LLDB.framework/Versions/A/LLDB"; @@ -2868,10 +2865,7 @@ GCC_ENABLE_OBJC_GC = supported; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_VERSION = 4.2; - HEADER_SEARCH_PATHS = ( - /System/Library/Frameworks/System.framework/PrivateHeaders, - /usr/include/python2.6, - ); + HEADER_SEARCH_PATHS = /usr/include/python2.6; INFOPLIST_FILE = "resources/LLDB-Info.plist"; INSTALL_PATH = /Developer/Library/PrivateFrameworks; LD_DYLIB_INSTALL_NAME = "@rpath/LLDB.framework/Versions/A/LLDB"; @@ -2981,10 +2975,7 @@ GCC_ENABLE_OBJC_GC = supported; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_VERSION = 4.2; - HEADER_SEARCH_PATHS = ( - /System/Library/Frameworks/System.framework/PrivateHeaders, - /usr/include/python2.6, - ); + HEADER_SEARCH_PATHS = /usr/include/python2.6; INFOPLIST_FILE = "resources/LLDB-Info.plist"; INSTALL_PATH = /Developer/Library/PrivateFrameworks; LD_DYLIB_INSTALL_NAME = "@rpath/LLDB.framework/Versions/A/LLDB"; Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112626&r1=112625&r2=112626&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Tue Aug 31 13:56:24 2010 @@ -834,6 +834,7 @@ file_and_line_desc.descKey = keyAEPosition; + static std::string g_app_name; static FSRef g_app_fsref; LSApplicationParameters app_params; @@ -846,11 +847,10 @@ if (external_editor) { - bool calculate_fsref = true; if (log) log->Printf("Looking for external editor \"%s\".\n", external_editor); - if (app_name.empty() || strcmp (app_name.c_str(), external_editor) != 0) + if (g_app_name.empty() || strcmp (g_app_name.c_str(), external_editor) != 0) { CFCString editor_name (external_editor, kCFStringEncodingUTF8); error = ::LSFindApplicationForInfo (kLSUnknownCreator, From johnny.chen at apple.com Tue Aug 31 16:49:24 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 31 Aug 2010 21:49:24 -0000 Subject: [Lldb-commits] [lldb] r112646 - /lldb/trunk/test/bitfields/TestBitfields.py Message-ID: <20100831214924.46F582A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 16:49:24 2010 New Revision: 112646 URL: http://llvm.org/viewvc/llvm-project?rev=112646&view=rev Log: Converted TestBitfields.py to Dsym/Dwarf combination. Modified: lldb/trunk/test/bitfields/TestBitfields.py Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112646&r1=112645&r2=112646&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue Aug 31 16:49:24 2010 @@ -9,8 +9,31 @@ mydir = "bitfields" + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @unittest2.expectedFailure - def test_variable_list_for_bitfields(self): + def test_with_dsym_and_run_command(self): + """Test 'variable list ...' on a variable with bitfields.""" + self.buildDsym() + self.bitfields_variable() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_python_api(self): + """Use Python APIs to inspect a bitfields variable.""" + self.buildDsym() + self.bitfields_variable_python() + + @unittest2.expectedFailure + def test_with_dwarf_and_run_command(self): + """Test 'variable list ...' on a variable with bitfields.""" + self.buildDwarf() + self.bitfields_variable() + + def test_with_dwarf_and_python_api(self): + """Use Python APIs to inspect a bitfields variable.""" + self.buildDwarf() + self.bitfields_variable_python() + + def bitfields_variable(self): """Test 'variable list ...' on a variable with bitfields.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -53,7 +76,7 @@ '(uint32_t:7) b7 = 0x0000007f,', '(uint32_t:4) four = 0x0000000f']) - def test_bitfields_variable_python(self): + def bitfields_variable_python(self): """Use Python APIs to inspect a bitfields variable.""" exe = os.path.join(os.getcwd(), "a.out") From johnny.chen at apple.com Tue Aug 31 17:26:16 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 31 Aug 2010 22:26:16 -0000 Subject: [Lldb-commits] [lldb] r112660 - /lldb/trunk/test/class_types/TestClassTypes.py Message-ID: <20100831222616.30CBE2A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 17:26:16 2010 New Revision: 112660 URL: http://llvm.org/viewvc/llvm-project?rev=112660&view=rev Log: Converted TestClassTypes.py to Dsym/Dwarf combination. Marked one test case as expectedFailure because in dwarf format, "variable list this" returns an error. Modified: lldb/trunk/test/class_types/TestClassTypes.py Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=112660&r1=112659&r2=112660&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Tue Aug 31 17:26:16 2010 @@ -9,7 +9,33 @@ mydir = "class_types" - def test_class_types(self): + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test 'variable list this' when stopped on a class constructor.""" + self.buildDsym() + self.class_types() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_python_api(self): + """Use Python APIs to create a breakpoint by (filespec, line).""" + self.buildDsym() + self.breakpoint_creation_by_filespec_python() + + # rdar://problem/8378863 + # "variable list this" returns + # error: unable to find any variables named 'this' + @unittest2.expectedFailure + def test_with_dwarf_and_run_command(self): + """Test 'variable list this' when stopped on a class constructor.""" + self.buildDwarf() + self.class_types() + + def test_with_dwarf_and_python_api(self): + """Use Python APIs to create a breakpoint by (filespec, line).""" + self.buildDwarf() + self.breakpoint_creation_by_filespec_python() + + def class_types(self): """Test 'variable list this' when stopped on a class constructor.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -33,7 +59,7 @@ self.expect("variable list this", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(class C *const) this = ') - def test_breakpoint_creation_by_filespec_python(self): + def breakpoint_creation_by_filespec_python(self): """Use Python APIs to create a breakpoint by (filespec, line).""" exe = os.path.join(os.getcwd(), "a.out") From johnny.chen at apple.com Tue Aug 31 18:12:15 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 31 Aug 2010 23:12:15 -0000 Subject: [Lldb-commits] [lldb] r112670 - /lldb/trunk/test/dead-strip/TestDeadStrip.py Message-ID: <20100831231215.4EB882A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 18:12:15 2010 New Revision: 112670 URL: http://llvm.org/viewvc/llvm-project?rev=112670&view=rev Log: Converted TestDeadStrip.py to Dsym/Dwarf combination. Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=112670&r1=112669&r2=112670&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Tue Aug 31 18:12:15 2010 @@ -11,7 +11,18 @@ mydir = "dead-strip" - def test_dead_strip(self): + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test breakpoint works correctly with dead-code stripping.""" + self.buildDsym() + self.dead_strip() + + def test_with_dwarf(self): + """Test breakpoint works correctly with dead-code stripping.""" + self.buildDwarf() + self.dead_strip() + + def dead_strip(self): """Test breakpoint works correctly with dead-code stripping.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From jingham at apple.com Tue Aug 31 18:51:36 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 31 Aug 2010 23:51:36 -0000 Subject: [Lldb-commits] [lldb] r112679 - /lldb/trunk/source/Core/Module.cpp Message-ID: <20100831235136.335522A6C12C@llvm.org> Author: jingham Date: Tue Aug 31 18:51:36 2010 New Revision: 112679 URL: http://llvm.org/viewvc/llvm-project?rev=112679&view=rev Log: Don't re-look up the symbol in ResolveSymbolContextForAddress. Modified: lldb/trunk/source/Core/Module.cpp Modified: lldb/trunk/source/Core/Module.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=112679&r1=112678&r2=112679&view=diff ============================================================================== --- lldb/trunk/source/Core/Module.cpp (original) +++ lldb/trunk/source/Core/Module.cpp Tue Aug 31 18:51:36 2010 @@ -215,8 +215,8 @@ resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); } - // Resolve the symbol if requested - if (resolve_scope & eSymbolContextSymbol) + // Resolve the symbol if requested, but don't re-look it up if we've already found it. + if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) { ObjectFile* ofile = GetObjectFile(); if (ofile) From johnny.chen at apple.com Tue Aug 31 19:15:19 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 01 Sep 2010 00:15:19 -0000 Subject: [Lldb-commits] [lldb] r112682 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py lldbtest.py Message-ID: <20100901001519.7788C2A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 19:15:19 2010 New Revision: 112682 URL: http://llvm.org/viewvc/llvm-project?rev=112682&view=rev Log: Avoid killing the inferior process twice by passing a setCookie=False keyword argument when issuing a "run" lldb command within the test case meant to exercise the Python APIs, but is using the command interface due to certain reason (such as target.LaunchProcess() does not reliably bring up the inferior). Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112682&r1=112681&r2=112682&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Tue Aug 31 19:15:19 2010 @@ -84,7 +84,7 @@ breakpoint = target.BreakpointCreateByLocation("main.c", 42) self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) - self.runCmd("run", RUN_SUCCEEDED) + self.runCmd("run", RUN_SUCCEEDED, setCookie=False) # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112682&r1=112681&r2=112682&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue Aug 31 19:15:19 2010 @@ -86,7 +86,7 @@ breakpoint = target.BreakpointCreateByLocation("main.c", 42) self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) - self.runCmd("run", RUN_SUCCEEDED) + self.runCmd("run", RUN_SUCCEEDED, setCookie=False) # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) @@ -131,6 +131,10 @@ int(four.GetValue(frame), 16) == 0x0f, 'bits.four has type uint32_t:4, is in scope, and == 0x0f') + # Now kill the process, and we are done. + rc = target.GetProcess().Kill() + self.assertTrue(rc.Success()) + if __name__ == '__main__': import atexit Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112682&r1=112681&r2=112682&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue Aug 31 19:15:19 2010 @@ -323,7 +323,7 @@ # Restore old working directory. os.chdir(self.oldcwd) - def runCmd(self, cmd, msg=None, check=True, trace=False): + def runCmd(self, cmd, msg=None, check=True, trace=False, setCookie=True): """ Ask the command interpreter to handle the command and then check its return status. @@ -334,10 +334,9 @@ trace = (True if traceAlways else trace) - self.runStarted = (cmd.startswith("run") or - cmd.startswith("process launch")) + running = (cmd.startswith("run") or cmd.startswith("process launch")) - for i in range(self.maxLaunchCount if self.runStarted else 1): + for i in range(self.maxLaunchCount if running else 1): self.ci.HandleCommand(cmd, self.res) if trace: @@ -350,10 +349,12 @@ if self.res.Succeeded(): break else: - if self.runStarted: + if running: # Process launch failed, wait some time before the next try. time.sleep(self.timeWait) + self.runStarted = running and setCookie + if check: self.assertTrue(self.res.Succeeded(), msg if msg else CMD_MSG(cmd)) From johnny.chen at apple.com Tue Aug 31 19:55:37 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 01 Sep 2010 00:55:37 -0000 Subject: [Lldb-commits] [lldb] r112688 - /lldb/trunk/test/dotest.pl Message-ID: <20100901005537.12D432A6C12C@llvm.org> Author: johnny Date: Tue Aug 31 19:55:36 2010 New Revision: 112688 URL: http://llvm.org/viewvc/llvm-project?rev=112688&view=rev Log: Updated to add plugins directory to PYTHONPATH. Modified: lldb/trunk/test/dotest.pl Modified: lldb/trunk/test/dotest.pl URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.pl?rev=112688&r1=112687&r2=112688&view=diff ============================================================================== --- lldb/trunk/test/dotest.pl (original) +++ lldb/trunk/test/dotest.pl Tue Aug 31 19:55:36 2010 @@ -16,14 +16,15 @@ my $scriptDir = $FindBin::Bin; my $baseDir = abs_path("$scriptDir/.."); +my $pluginDir = "$baseDir/test/plugins"; my $testDir = $ARGV[0]; my $dbgPath = "$baseDir/build/Debug/LLDB.framework/Resources/Python"; my $relPath = "$baseDir/build/Release/LLDB.framework/Resources/Python"; if (-d $dbgPath) { - $ENV{'PYTHONPATH'} = "$dbgPath:$scriptDir"; + $ENV{'PYTHONPATH'} = "$dbgPath:$scriptDir:$pluginDir"; } elsif (-d $relPath) { - $ENV{'PYTHONPATH'} = "$relPath:$scriptDir"; + $ENV{'PYTHONPATH'} = "$relPath:$scriptDir:$pluginDir"; } #print("ENV{PYTHONPATH}=$ENV{'PYTHONPATH'}\n"); From scallanan at apple.com Tue Aug 31 19:58:00 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 01 Sep 2010 00:58:00 -0000 Subject: [Lldb-commits] [lldb] r112690 - in /lldb/trunk: include/lldb/Expression/IRDynamicChecks.h include/lldb/Target/Process.h lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpressionParser.cpp source/Expression/ClangUtilityFunction.cpp source/Expression/IRDynamicChecks.cpp Message-ID: <20100901005800.8B36D2A6C12C@llvm.org> Author: spyffe Date: Tue Aug 31 19:58:00 2010 New Revision: 112690 URL: http://llvm.org/viewvc/llvm-project?rev=112690&view=rev Log: Added support for dynamic sanity checking in expressions. Values used by the expression are checked by validation functions which cause the program to crash if the values are unsafe. Major changes: - Added IRDynamicChecks.[ch], which contains the core code related to this feature - Modified CommandObjectExpression to install the validator functions into the target process. - Added an accessor to Process that gets/sets the helper functions Added: lldb/trunk/include/lldb/Expression/IRDynamicChecks.h lldb/trunk/source/Expression/IRDynamicChecks.cpp Modified: lldb/trunk/include/lldb/Target/Process.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Expression/ClangExpressionParser.cpp lldb/trunk/source/Expression/ClangUtilityFunction.cpp Added: lldb/trunk/include/lldb/Expression/IRDynamicChecks.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRDynamicChecks.h?rev=112690&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/IRDynamicChecks.h (added) +++ lldb/trunk/include/lldb/Expression/IRDynamicChecks.h Tue Aug 31 19:58:00 2010 @@ -0,0 +1,141 @@ +//===-- IRDynamicChecks.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_IRDynamicChecks_h_ +#define liblldb_IRDynamicChecks_h_ + +#include "llvm/Pass.h" + +namespace llvm { + class BasicBlock; + class CallInst; + class Constant; + class Function; + class Instruction; + class Module; + class TargetData; + class Value; +} + +namespace lldb_private +{ + +class ClangExpressionDeclMap; +class ClangUtilityFunction; +class ExecutionContext; +class Stream; + +//---------------------------------------------------------------------- +/// @class DynamicCheckerFunctions IRDynamicChecks.h "lldb/Expression/IRDynamicChecks.h" +/// @brief Encapsulates dynamic check functions used by expressions. +/// +/// Each of the utility functions encapsulated in this class is responsible +/// for validating some data that an expression is about to use. Examples are: +/// +/// a = *b; // check that b is a valid pointer +/// [b init]; // check that b is a valid object to send "init" to +/// +/// The class installs each checker function into the target process and +/// makes it available to IRDynamicChecks to use. +//---------------------------------------------------------------------- +class DynamicCheckerFunctions +{ +public: + //------------------------------------------------------------------ + /// Constructor + //------------------------------------------------------------------ + DynamicCheckerFunctions (); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~DynamicCheckerFunctions (); + + //------------------------------------------------------------------ + /// Install the utility functions into a process. This binds the + /// instance of DynamicCheckerFunctions to that process. + /// + /// @param[in] error_stream + /// A stream to print errors on. + /// + /// @param[in] exe_ctx + /// The execution context to install the functions into. + /// + /// @return + /// True on success; false on failure, or if the functions have + /// already been installed. + //------------------------------------------------------------------ + bool Install (Stream &error_stream, + ExecutionContext &exe_ctx); + + std::auto_ptr m_valid_pointer_check; +}; + +//---------------------------------------------------------------------- +/// @class IRDynamicChecks IRDynamicChecks.h "lldb/Expression/IRDynamicChecks.h" +/// @brief Adds dynamic checks to a user-entered expression to reduce its likelihood of crashing +/// +/// When an IR function is executed in the target process, it may cause +/// crashes or hangs by dereferencing NULL pointers, trying to call Objective-C +/// methods on objects that do not respond to them, and so forth. +/// +/// IRDynamicChecks adds calls to the functions in DynamicCheckerFunctions +/// to appropriate locations in an expression's IR. +//---------------------------------------------------------------------- +class IRDynamicChecks : public llvm::ModulePass +{ +public: + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] checker_functions + /// The checker functions for the target process. + /// + /// @param[in] func_name + /// The name of the function to prepare for execution in the target. + //------------------------------------------------------------------ + IRDynamicChecks(DynamicCheckerFunctions &checker_functions, + const char* func_name = "___clang_expr"); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~IRDynamicChecks(); + + //------------------------------------------------------------------ + /// Run this IR transformer on a single module + /// + /// @param[in] M + /// The module to run on. This module is searched for the function + /// ___clang_expr, and that function is passed to the passes one by + /// one. + /// + /// @return + /// True on success; false otherwise + //------------------------------------------------------------------ + bool runOnModule(llvm::Module &M); + + //------------------------------------------------------------------ + /// Interface stub + //------------------------------------------------------------------ + void assignPassManager(llvm::PMStack &PMS, + llvm::PassManagerType T = llvm::PMT_ModulePassManager); + + //------------------------------------------------------------------ + /// Returns PMT_ModulePassManager + //------------------------------------------------------------------ + llvm::PassManagerType getPotentialPassManagerType() const; +private: + std::string m_func_name; ///< The name of the function to add checks to + DynamicCheckerFunctions &m_checker_functions; ///< The checker functions for the process +}; + +} + +#endif Modified: lldb/trunk/include/lldb/Target/Process.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=112690&r1=112689&r2=112690&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Process.h (original) +++ lldb/trunk/include/lldb/Target/Process.h Tue Aug 31 19:58:00 2010 @@ -26,6 +26,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Breakpoint/BreakpointSiteList.h" #include "lldb/Expression/ClangPersistentVariables.h" +#include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/ObjCObjectPrinter.h" #include "lldb/Target/ThreadList.h" @@ -1353,6 +1354,16 @@ bool IsRunning () const; + + DynamicCheckerFunctions *GetDynamicCheckers() + { + return m_dynamic_checkers.get(); + } + + void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers) + { + m_dynamic_checkers.reset(dynamic_checkers); + } //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions @@ -1405,6 +1416,7 @@ BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend ///< to insert in the target. ClangPersistentVariables m_persistent_vars; ///< These are the persistent variables associated with this process for the expression parser. + std::auto_ptr m_dynamic_checkers; ///< The functions used by the expression parser to validate data that expressions use. UnixSignals m_unix_signals; /// This is the current signal set for this process. ConstString m_target_triple; lldb::ABISP m_abi_sp; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112690&r1=112689&r2=112690&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Aug 31 19:58:00 2010 @@ -341,6 +341,8 @@ 49A8A3A011D568A300AD3B68 /* ASTResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */; }; 49A8A3A411D568BF00AD3B68 /* ASTResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */; }; 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; }; + 49CF982A122C70BD007A0B96 /* IRDynamicChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */; }; + 49CF9834122C718B007A0B96 /* IRDynamicChecks.h in Headers */ = {isa = PBXBuildFile; fileRef = 49CF9833122C718B007A0B96 /* IRDynamicChecks.h */; }; 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */; }; 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; }; 49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; }; @@ -933,6 +935,8 @@ 49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = ""; }; 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = ""; }; 49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = ""; }; + 49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRDynamicChecks.cpp; path = source/Expression/IRDynamicChecks.cpp; sourceTree = ""; }; + 49CF9833122C718B007A0B96 /* IRDynamicChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRDynamicChecks.h; path = include/lldb/Expression/IRDynamicChecks.h; sourceTree = ""; }; 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangPersistentVariables.h; path = include/lldb/Expression/ClangPersistentVariables.h; sourceTree = ""; }; 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangPersistentVariables.cpp; path = source/Expression/ClangPersistentVariables.cpp; sourceTree = ""; }; 49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = ""; }; @@ -1882,6 +1886,8 @@ 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */, 4911934B1226383D00578B7F /* ASTStructExtractor.h */, 491193501226386000578B7F /* ASTStructExtractor.cpp */, + 49CF9833122C718B007A0B96 /* IRDynamicChecks.h */, + 49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */, 49307AB111DEA4F20081F992 /* IRForTarget.h */, 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */, 49DA743411DE6BB2006AEF7E /* IRToDWARF.h */, @@ -2254,6 +2260,7 @@ 49445E351225AB6A00C11A81 /* ClangUserExpression.h in Headers */, 4911934C1226383D00578B7F /* ASTStructExtractor.h in Headers */, 497C86C2122823F300B54702 /* ClangUtilityFunction.h in Headers */, + 49CF9834122C718B007A0B96 /* IRDynamicChecks.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2308,7 +2315,6 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, @@ -2713,6 +2719,7 @@ 49445C2612245E3600C11A81 /* ClangExpressionParser.cpp in Sources */, 491193521226386000578B7F /* ASTStructExtractor.cpp in Sources */, 497C86BE122823D800B54702 /* ClangUtilityFunction.cpp in Sources */, + 49CF982A122C70BD007A0B96 /* IRDynamicChecks.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=112690&r1=112689&r2=112690&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Aug 31 19:58:00 2010 @@ -190,6 +190,27 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream, CommandReturnObject *result) { + if (!m_exe_ctx.process) + { + error_stream.Printf ("Execution context doesn't contain a process"); + return false; + } + + if (!m_exe_ctx.process->GetDynamicCheckers()) + { + DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); + + StreamString install_errors; + + if (!dynamic_checkers->Install(install_errors, m_exe_ctx)) + { + error_stream.Printf("Couldn't install dynamic checkers into the execution context: %s", install_errors.GetData()); + return false; + } + + m_exe_ctx.process->SetDynamicCheckers(dynamic_checkers); + } + ClangUserExpression user_expression (expr); if (!user_expression.Parse (error_stream, m_exe_ctx)) Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=112690&r1=112689&r2=112690&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Tue Aug 31 19:58:00 2010 @@ -13,8 +13,10 @@ #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Stream.h" +#include "lldb/Core/StreamString.h" #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangExpression.h" +#include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/IRForTarget.h" #include "lldb/Expression/IRToDWARF.h" #include "lldb/Expression/RecordingMemoryManager.h" @@ -409,6 +411,15 @@ err.SetErrorString("Couldn't convert the expression to DWARF"); return err; } + + IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), m_expr.FunctionName()); + + if (!ir_dynamic_checks.runOnModule(*module)) + { + err.SetErrorToGenericError(); + err.SetErrorString("Couldn't add dynamic checks to the expression"); + return err; + } } m_jit_mm = new RecordingMemoryManager(); Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=112690&r1=112689&r2=112690&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Tue Aug 31 19:58:00 2010 @@ -37,7 +37,9 @@ ClangUtilityFunction::ClangUtilityFunction (const char *text, const char *name) : m_function_text(text), - m_function_name(name) + m_function_name(name), + m_jit_begin(LLDB_INVALID_ADDRESS), + m_jit_end(LLDB_INVALID_ADDRESS) { } @@ -56,7 +58,13 @@ bool ClangUtilityFunction::Install (Stream &error_stream, ExecutionContext &exe_ctx) -{ +{ + if (m_jit_begin != LLDB_INVALID_ADDRESS) + { + error_stream.PutCString("error: already installed\n"); + return false; + } + //////////////////////////////////// // Set up the target and compiler // Added: lldb/trunk/source/Expression/IRDynamicChecks.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRDynamicChecks.cpp?rev=112690&view=auto ============================================================================== --- lldb/trunk/source/Expression/IRDynamicChecks.cpp (added) +++ lldb/trunk/source/Expression/IRDynamicChecks.cpp Tue Aug 31 19:58:00 2010 @@ -0,0 +1,117 @@ +//===-- IRDynamicChecks.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/Expression/IRDynamicChecks.h" +#include "lldb/Expression/ClangUtilityFunction.h" + +#include "lldb/Core/Log.h" + +#include "llvm/Support/raw_ostream.h" +#include "llvm/Function.h" +#include "llvm/Module.h" +#include "llvm/Value.h" + +using namespace llvm; +using namespace lldb_private; + +static char ID; + +static const char valid_pointer_check_text[] = + "extern \"C\" void " + "___clang_valid_pointer_check (unsigned char *ptr)" + "{" + "unsigned char val = *ptr;" + "}"; + +static const char valid_pointer_check_name[] = + "___clang_valid_pointer_check"; + +DynamicCheckerFunctions::DynamicCheckerFunctions () +{ + m_valid_pointer_check.reset(new ClangUtilityFunction(valid_pointer_check_text, + valid_pointer_check_name)); +} + +DynamicCheckerFunctions::~DynamicCheckerFunctions () +{ +} + +bool +DynamicCheckerFunctions::Install(Stream &error_stream, + ExecutionContext &exe_ctx) +{ + if (!m_valid_pointer_check->Install(error_stream, exe_ctx)) + return false; + + return true; +} + +IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions, + const char *func_name) : + ModulePass(&ID), + m_checker_functions(checker_functions), + m_func_name(func_name) +{ +} + +/* A handy utility function used at several places in the code */ + +static std::string +PrintValue(llvm::Value *V, bool truncate = false) +{ + std::string s; + raw_string_ostream rso(s); + V->print(rso); + rso.flush(); + if (truncate) + s.resize(s.length() - 1); + return s; +} + +IRDynamicChecks::~IRDynamicChecks() +{ +} + +bool +IRDynamicChecks::runOnModule(llvm::Module &M) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str())); + + if (!function) + { + if (log) + log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); + + return false; + } + + llvm::Function::iterator bbi; + + for (bbi = function->begin(); + bbi != function->end(); + ++bbi) + { + } + + return true; +} + +void +IRDynamicChecks::assignPassManager(PMStack &PMS, + PassManagerType T) +{ +} + +PassManagerType +IRDynamicChecks::getPotentialPassManagerType() const +{ + return PMT_ModulePassManager; +} From scallanan at apple.com Wed Sep 1 14:04:01 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 01 Sep 2010 19:04:01 -0000 Subject: [Lldb-commits] [lldb] r112725 - /lldb/trunk/include/lldb/Expression/IRForTarget.h Message-ID: <20100901190401.502C12A6C12C@llvm.org> Author: spyffe Date: Wed Sep 1 14:04:01 2010 New Revision: 112725 URL: http://llvm.org/viewvc/llvm-project?rev=112725&view=rev Log: Fixed a comment. Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=112725&r1=112724&r2=112725&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Wed Sep 1 14:04:01 2010 @@ -131,8 +131,8 @@ /// @param[in] selector_load /// The load of the statically-allocated selector. /// - /// @param[in] BB - /// The basic block currently being processed. + /// @param[in] M + /// The module containing the load. /// /// @return /// True on success; false otherwise From jingham at apple.com Wed Sep 1 14:53:33 2010 From: jingham at apple.com (Jim Ingham) Date: Wed, 01 Sep 2010 19:53:33 -0000 Subject: [Lldb-commits] [lldb] r112731 - /lldb/trunk/source/Commands/CommandObjectExpression.cpp Message-ID: <20100901195333.2E2102A6C12C@llvm.org> Author: jingham Date: Wed Sep 1 14:53:33 2010 New Revision: 112731 URL: http://llvm.org/viewvc/llvm-project?rev=112731&view=rev Log: Stream::Printf doesn't add a newline, so it needs to be added to all the error messages in CommandObjectExpression::EvaluateExpression. Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=112731&r1=112730&r2=112731&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Wed Sep 1 14:53:33 2010 @@ -192,7 +192,7 @@ { if (!m_exe_ctx.process) { - error_stream.Printf ("Execution context doesn't contain a process"); + error_stream.Printf ("Execution context doesn't contain a process\n"); return false; } @@ -204,7 +204,7 @@ if (!dynamic_checkers->Install(install_errors, m_exe_ctx)) { - error_stream.Printf("Couldn't install dynamic checkers into the execution context: %s", install_errors.GetData()); + error_stream.Printf("Couldn't install dynamic checkers into the execution context: %s\n", install_errors.GetData()); return false; } @@ -215,7 +215,7 @@ if (!user_expression.Parse (error_stream, m_exe_ctx)) { - error_stream.Printf ("Couldn't parse the expresssion"); + error_stream.Printf ("Couldn't parse the expresssion\n"); return false; } @@ -223,7 +223,7 @@ if (!user_expression.Execute (error_stream, m_exe_ctx, expr_result)) { - error_stream.Printf ("Couldn't execute the expresssion"); + error_stream.Printf ("Couldn't execute the expresssion\n"); return false; } From johnny.chen at apple.com Wed Sep 1 14:59:58 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 01 Sep 2010 19:59:58 -0000 Subject: [Lldb-commits] [lldb] r112732 - in /lldb/trunk/test: array_types/ bitfields/ class_types/ command_source/ dead-strip/ enum_types/ example/ function_types/ global_variables/ hello_world/ help/ load_unload/ macosx/universal/ order/ persistent_variables/ set_values/ stl/ struct_types/ unsigned_types/ Message-ID: <20100901195958.E8C292A6C12C@llvm.org> Author: johnny Date: Wed Sep 1 14:59:58 2010 New Revision: 112732 URL: http://llvm.org/viewvc/llvm-project?rev=112732&view=rev Log: Changed the test case class names to be noun-like instead of verb-like. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/command_source/TestCommandSource.py lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/enum_types/TestEnumTypes.py lldb/trunk/test/example/TestSequenceFunctions.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/help/TestHelp.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/macosx/universal/TestUniversal.py lldb/trunk/test/order/TestOrderFile.py lldb/trunk/test/persistent_variables/TestPersistentVariables.py lldb/trunk/test/set_values/TestSetValues.py lldb/trunk/test/stl/TestSTL.py lldb/trunk/test/struct_types/TestStructTypes.py lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestArrayTypes(TestBase): +class ArrayTypesTestCase(TestBase): mydir = "array_types" Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestBitfields(TestBase): +class BitfieldsTestCase(TestBase): mydir = "bitfields" Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestClassTypes(TestBase): +class ClassTypesTestCase(TestBase): mydir = "class_types" Modified: lldb/trunk/test/command_source/TestCommandSource.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/TestCommandSource.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/command_source/TestCommandSource.py (original) +++ lldb/trunk/test/command_source/TestCommandSource.py Wed Sep 1 14:59:58 2010 @@ -9,7 +9,7 @@ import lldb from lldbtest import * -class TestCommandSource(TestBase): +class CommandSourceTestCase(TestBase): mydir = "command_source" Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Wed Sep 1 14:59:58 2010 @@ -7,7 +7,7 @@ import lldb from lldbtest import * -class TestDeadStrip(TestBase): +class DeadStripTestCase(TestBase): mydir = "dead-strip" Modified: lldb/trunk/test/enum_types/TestEnumTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/enum_types/TestEnumTypes.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/enum_types/TestEnumTypes.py (original) +++ lldb/trunk/test/enum_types/TestEnumTypes.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestEnumTypes(TestBase): +class EnumTypesTestCase(TestBase): mydir = "enum_types" Modified: lldb/trunk/test/example/TestSequenceFunctions.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/example/TestSequenceFunctions.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/example/TestSequenceFunctions.py (original) +++ lldb/trunk/test/example/TestSequenceFunctions.py Wed Sep 1 14:59:58 2010 @@ -4,7 +4,7 @@ import unittest import traceback -class TestSequenceFunctions(unittest.TestCase): +class SequenceFunctionsTestCase(unittest.TestCase): def setUp(self): #traceback.print_stack() Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestFunctionTypes(TestBase): +class FunctionTypesTestCase(TestBase): mydir = "function_types" Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestGlobalVariables(TestBase): +class GlobalVariablesTestCase(TestBase): mydir = "global_variables" Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestHelloWorld(TestBase): +class HelloWorldTestCase(TestBase): mydir = "hello_world" Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Wed Sep 1 14:59:58 2010 @@ -9,7 +9,7 @@ import lldb from lldbtest import * -class TestHelpCommand(TestBase): +class HelpCommandTestCase(TestBase): mydir = "help" Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Wed Sep 1 14:59:58 2010 @@ -7,7 +7,7 @@ import lldb from lldbtest import * -class TestLoadUnload(TestBase): +class LoadUnloadTestCase(TestBase): mydir = "load_unload" Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestUniversal(TestBase): +class UniversalTestCase(TestBase): mydir = "macosx/universal" Modified: lldb/trunk/test/order/TestOrderFile.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrderFile.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrderFile.py (original) +++ lldb/trunk/test/order/TestOrderFile.py Wed Sep 1 14:59:58 2010 @@ -8,7 +8,7 @@ import lldb from lldbtest import * -class TestOrderFile(TestBase): +class OrderFileTestCase(TestBase): mydir = "order" Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (original) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Wed Sep 1 14:59:58 2010 @@ -7,7 +7,7 @@ import lldb from lldbtest import * -class TestPersistentVariables(TestBase): +class PersistentVariablesTestCase(TestBase): mydir = "persistent_variables" Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Wed Sep 1 14:59:58 2010 @@ -5,7 +5,7 @@ import lldb from lldbtest import * -class TestSetValues(TestBase): +class SetValuesTestCase(TestBase): mydir = "set_values" Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Wed Sep 1 14:59:58 2010 @@ -7,7 +7,7 @@ import lldb from lldbtest import * -class TestSTL(TestBase): +class STLTestCase(TestBase): mydir = "stl" Modified: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (original) +++ lldb/trunk/test/struct_types/TestStructTypes.py Wed Sep 1 14:59:58 2010 @@ -9,7 +9,7 @@ import lldb from lldbtest import * -class TestStructTypes(TestBase): +class StructTypesTestCase(TestBase): mydir = "struct_types" Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=112732&r1=112731&r2=112732&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Wed Sep 1 14:59:58 2010 @@ -8,7 +8,7 @@ import lldb from lldbtest import * -class TestUnsignedTypes(TestBase): +class UnsignedTypesTestCase(TestBase): mydir = "unsigned_types" From johnny.chen at apple.com Wed Sep 1 17:08:51 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 01 Sep 2010 22:08:51 -0000 Subject: [Lldb-commits] [lldb] r112749 - in /lldb/trunk/test: hello_world/TestHelloWorld.py lldbtest.py Message-ID: <20100901220851.C472B2A6C12C@llvm.org> Author: johnny Date: Wed Sep 1 17:08:51 2010 New Revision: 112749 URL: http://llvm.org/viewvc/llvm-project?rev=112749&view=rev Log: Put the little dances done after SBTarget.LaunchProcess() into the base class. Modified: lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112749&r1=112748&r2=112749&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Wed Sep 1 17:08:51 2010 @@ -18,7 +18,7 @@ self.buildDsym() self.hello_world_python(useLaunchAPI = False) - @unittest2.expectedFailure + #@unittest2.expectedFailure def test_with_dwarf_and_process_launch_api(self): """Create target, breakpoint, launch a process, and then kill it. @@ -52,38 +52,21 @@ # SBTarget.LaunchProcess() issue (or is there some race condition)? if useLaunchAPI: - # The following approach of launching a process looks untidy and only - # works sometimes. - process = target.LaunchProcess([''], [''], os.ctermid(), False) - - SR = process.GetThreadAtIndex(0).GetStopReason() - count = 0 - while SR == StopReasonEnum("Invalid") or SR == StopReasonEnum("Signal"): - print >> sys.stderr, "StopReason =", StopReasonString(SR) - - time.sleep(1.0) - print >> sys.stderr, "Continuing the process:", process - process.Continue() - - count = count + 1 - if count == 10: - print >> sys.stderr, "Reached 10 iterations, giving up..." - break - - SR = process.GetThreadAtIndex(0).GetStopReason() + process = target.LaunchProcess([''], [''], os.ctermid(), 0, False) + # Apply some dances after LaunchProcess() in order to break at "main". + # It only works sometimes. + self.breakAfterLaunch(process, "main") else: # On the other hand, the following two lines of code are more reliable. - self.runCmd("run") - process = target.GetProcess() + self.runCmd("run", setCookie=False) - self.runCmd("thread backtrace") - self.runCmd("breakpoint list") - self.runCmd("thread list") + #self.runCmd("thread backtrace") + #self.runCmd("breakpoint list") + #self.runCmd("thread list") - # The stop reason of the thread should be breakpoint. + process = target.GetProcess() thread = process.GetThreadAtIndex(0) - - print >> sys.stderr, "StopReason =", StopReasonString(thread.GetStopReason()) + self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), STOPPED_DUE_TO_BREAKPOINT) Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112749&r1=112748&r2=112749&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Wed Sep 1 17:08:51 2010 @@ -368,7 +368,6 @@ message. We expect the output from running the command to start with 'startstr' and matches the substrings contained in 'substrs'. """ - trace = (True if traceAlways else trace) # First run the command. @@ -398,7 +397,6 @@ def invoke(self, obj, name, trace=False): """Use reflection to call a method dynamically with no argument.""" - trace = (True if traceAlways else trace) method = getattr(obj, name) @@ -410,6 +408,45 @@ print str(method) + ":", result return result + def breakAfterLaunch(self, process, func, trace=False): + """ + Perform some dancees after LaunchProcess() to break at func name. + + Return True if we can successfully break at the func name in due time. + """ + trace = (True if traceAlways else trace) + + count = 0 + while True: + # The stop reason of the thread should be breakpoint. + thread = process.GetThreadAtIndex(0) + SR = thread.GetStopReason() + if trace: + print >> sys.stderr, "StopReason =", StopReasonString(SR) + + if SR == StopReasonEnum("Breakpoint"): + frame = thread.GetFrameAtIndex(0) + name = frame.GetFunction().GetName() + if (name == func): + # We got what we want; now break out of the loop. + return True + + # The inferior is in a transient state; continue the process. + time.sleep(1.0) + if trace: + print >> sys.stderr, "Continuing the process:", process + process.Continue() + + count = count + 1 + if count == 10: + if trace: + print >> sys.stderr, "Reached 10 iterations, giving up..." + # Enough iterations already, break out of the loop. + return False + + # End of while loop. + + def buildDsym(self): """Platform specific way to build binaries with dsym info.""" module = __import__(sys.platform) From johnny.chen at apple.com Wed Sep 1 17:10:09 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 01 Sep 2010 22:10:09 -0000 Subject: [Lldb-commits] [lldb] r112750 - /lldb/trunk/test/hello_world/TestHelloWorld.py Message-ID: <20100901221009.C70C12A6C12C@llvm.org> Author: johnny Date: Wed Sep 1 17:10:09 2010 New Revision: 112750 URL: http://llvm.org/viewvc/llvm-project?rev=112750&view=rev Log: Fixed comment. Modified: lldb/trunk/test/hello_world/TestHelloWorld.py Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112750&r1=112749&r2=112750&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Wed Sep 1 17:10:09 2010 @@ -57,7 +57,7 @@ # It only works sometimes. self.breakAfterLaunch(process, "main") else: - # On the other hand, the following two lines of code are more reliable. + # On the other hand, the following line of code are more reliable. self.runCmd("run", setCookie=False) #self.runCmd("thread backtrace") From jingham at apple.com Wed Sep 1 19:18:39 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 02 Sep 2010 00:18:39 -0000 Subject: [Lldb-commits] [lldb] r112782 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectFrame.cpp source/Commands/CommandObjectVariable.cpp source/Commands/CommandObjectVariable.h source/Interpreter/CommandInterpreter.cpp tools/driver/Driver.cpp Message-ID: <20100902001839.66EE62A6C12C@llvm.org> Author: jingham Date: Wed Sep 1 19:18:39 2010 New Revision: 112782 URL: http://llvm.org/viewvc/llvm-project?rev=112782&view=rev Log: Move "variable list" to "frame variable" Removed: lldb/trunk/source/Commands/CommandObjectVariable.cpp lldb/trunk/source/Commands/CommandObjectVariable.h Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/tools/driver/Driver.cpp Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112782&r1=112781&r2=112782&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Sep 1 19:18:39 2010 @@ -104,7 +104,6 @@ 26D5B08811B07550009A862E /* CommandObjectSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */; }; 26D5B08B11B07550009A862E /* CommandObjectSyntax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4510F1B84700F91463 /* CommandObjectSyntax.cpp */; }; 26D5B08C11B07550009A862E /* CommandObjectThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */; }; - 26D5B08D11B07550009A862E /* CommandObjectVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4810F1B84700F91463 /* CommandObjectVariable.cpp */; }; 26D5B08E11B07550009A862E /* Address.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E6910F1B85900F91463 /* Address.cpp */; }; 26D5B08F11B07550009A862E /* AddressRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E6A10F1B85900F91463 /* AddressRange.cpp */; }; 26D5B09011B07550009A862E /* ArchSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E6B10F1B85900F91463 /* ArchSpec.cpp */; }; @@ -638,7 +637,6 @@ 26BC7D2910F1B76300F91463 /* CommandObjectSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSource.h; path = source/Commands/CommandObjectSource.h; sourceTree = ""; }; 26BC7D2C10F1B76300F91463 /* CommandObjectSyntax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSyntax.h; path = source/Commands/CommandObjectSyntax.h; sourceTree = ""; }; 26BC7D2D10F1B76300F91463 /* CommandObjectThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectThread.h; path = source/Commands/CommandObjectThread.h; sourceTree = ""; }; - 26BC7D2F10F1B76300F91463 /* CommandObjectVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectVariable.h; path = source/Commands/CommandObjectVariable.h; sourceTree = ""; }; 26BC7D5010F1B77400F91463 /* Address.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Address.h; path = include/lldb/Core/Address.h; sourceTree = ""; }; 26BC7D5110F1B77400F91463 /* AddressRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AddressRange.h; path = include/lldb/Core/AddressRange.h; sourceTree = ""; }; 26BC7D5210F1B77400F91463 /* ArchSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ArchSpec.h; path = include/lldb/Core/ArchSpec.h; sourceTree = ""; }; @@ -753,7 +751,6 @@ 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSource.cpp; path = source/Commands/CommandObjectSource.cpp; sourceTree = ""; }; 26BC7E4510F1B84700F91463 /* CommandObjectSyntax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSyntax.cpp; path = source/Commands/CommandObjectSyntax.cpp; sourceTree = ""; }; 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectThread.cpp; path = source/Commands/CommandObjectThread.cpp; sourceTree = ""; }; - 26BC7E4810F1B84700F91463 /* CommandObjectVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectVariable.cpp; path = source/Commands/CommandObjectVariable.cpp; sourceTree = ""; }; 26BC7E6910F1B85900F91463 /* Address.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Address.cpp; path = source/Core/Address.cpp; sourceTree = ""; }; 26BC7E6A10F1B85900F91463 /* AddressRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AddressRange.cpp; path = source/Core/AddressRange.cpp; sourceTree = ""; }; 26BC7E6B10F1B85900F91463 /* ArchSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ArchSpec.cpp; path = source/Core/ArchSpec.cpp; sourceTree = ""; }; @@ -1854,8 +1851,6 @@ 269416AD119A024800FF2715 /* CommandObjectTarget.cpp */, 26BC7D2D10F1B76300F91463 /* CommandObjectThread.h */, 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */, - 26BC7D2F10F1B76300F91463 /* CommandObjectVariable.h */, - 26BC7E4810F1B84700F91463 /* CommandObjectVariable.cpp */, ); name = Commands; sourceTree = ""; @@ -2467,7 +2462,6 @@ 26D5B08811B07550009A862E /* CommandObjectSource.cpp in Sources */, 26D5B08B11B07550009A862E /* CommandObjectSyntax.cpp in Sources */, 26D5B08C11B07550009A862E /* CommandObjectThread.cpp in Sources */, - 26D5B08D11B07550009A862E /* CommandObjectVariable.cpp in Sources */, 26D5B08E11B07550009A862E /* Address.cpp in Sources */, 26D5B08F11B07550009A862E /* AddressRange.cpp in Sources */, 26D5B09011B07550009A862E /* ArchSpec.cpp in Sources */, Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=112782&r1=112781&r2=112782&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Wed Sep 1 19:18:39 2010 @@ -13,15 +13,28 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Interpreter/Args.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/StreamFile.h" #include "lldb/Core/Timer.h" -#include "lldb/Core/Debugger.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/Options.h" +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" +#include "lldb/Target/Target.h" #include "CommandObjectThread.h" @@ -155,6 +168,686 @@ } }; +#pragma mark CommandObjectFrameVariable +//---------------------------------------------------------------------- +// List images with associated information +//---------------------------------------------------------------------- +class CommandObjectFrameVariable : public CommandObject +{ +public: + + class CommandOptions : public Options + { + public: + + CommandOptions () : + Options() + { + ResetOptionValues (); + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (int option_idx, const char *option_arg) + { + Error error; + bool success; + char short_option = (char) m_getopt_table[option_idx].val; + switch (short_option) + { + case 'o': use_objc = true; break; + case 'n': name = option_arg; break; + case 'r': use_regex = true; break; + case 'a': show_args = false; break; + case 'l': show_locals = false; break; + case 'g': show_globals = false; break; + case 't': show_types = false; break; + case 'y': show_summary = false; break; + case 'L': show_location= true; break; + case 'D': debug = true; break; + case 'd': + max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid max depth '%s'.\n", option_arg); + break; + + case 'p': + ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg); + break; + + case 'G': + { + ConstString const_string (option_arg); + globals.push_back(const_string); + } + break; + + case 's': + show_scope = true; + break; + + default: + error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); + break; + } + + return error; + } + + void + ResetOptionValues () + { + Options::ResetOptionValues(); + + name.clear(); + use_objc = false; + use_regex = false; + show_args = true; + show_locals = true; + show_globals = true; + show_types = true; + show_scope = false; + show_summary = true; + show_location = false; + debug = false; + max_depth = UINT32_MAX; + ptr_depth = 0; + globals.clear(); + } + + const lldb::OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static lldb::OptionDefinition g_option_table[]; + std::string name; + bool use_objc; + bool use_regex; + bool show_args; + bool show_locals; + bool show_globals; + bool show_types; + bool show_scope; // local/arg/global/static + bool show_summary; + bool show_location; + bool debug; + uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values + uint32_t ptr_depth; // The default depth that is dumped when we find pointers + std::vector globals; + // Instance variables to hold the values for command options. + }; + + CommandObjectFrameVariable () : + CommandObject ( + "frame variable", + "Show specified argument, local variable, static variable or global variable for the current frame. If none specified, list them all.", + "frame variable [] [ [...]]") + { + } + + virtual + ~CommandObjectFrameVariable () + { + } + + virtual + Options * + GetOptions () + { + return &m_options; + } + + void + DumpVariable (CommandReturnObject &result, ExecutionContext *exe_ctx, Variable *variable) + { + if (variable) + { + Stream &s = result.GetOutputStream(); + DWARFExpression &expr = variable->LocationExpression(); + Value expr_result; + Error expr_error; + Type *variable_type = variable->GetType(); + bool expr_success = expr.Evaluate(exe_ctx, NULL, NULL, expr_result, &expr_error); + + if (m_options.debug) + s.Printf ("Variable{0x%8.8x}: ", variable->GetID()); + + if (!expr_success) + s.Printf ("%s = ERROR: %s\n", variable->GetName().AsCString(NULL), expr_error.AsCString()); + else + { + Value::ValueType expr_value_type = expr_result.GetValueType(); + switch (expr_value_type) + { + case Value::eValueTypeScalar: + s.Printf ("%s = ", variable->GetName().AsCString(NULL)); + if (variable_type) + { + DataExtractor data; + if (expr_result.ResolveValue (exe_ctx, NULL).GetData (data)) + variable_type->DumpValue (exe_ctx, &s, data, 0, m_options.show_types, m_options.show_summary, m_options.debug); + } + break; + + case Value::eValueTypeFileAddress: + case Value::eValueTypeLoadAddress: + case Value::eValueTypeHostAddress: + { + s.Printf ("%s = ", variable->GetName().AsCString(NULL)); + lldb::addr_t addr = LLDB_INVALID_ADDRESS; + lldb::AddressType addr_type = eAddressTypeLoad; + + if (expr_value_type == Value::eValueTypeFileAddress) + { + lldb::addr_t file_addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); + SymbolContext var_sc; + variable->CalculateSymbolContext(&var_sc); + if (var_sc.module_sp) + { + ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); + if (objfile) + { + Address so_addr(file_addr, objfile->GetSectionList()); + addr = so_addr.GetLoadAddress(exe_ctx->process); + } + if (addr == LLDB_INVALID_ADDRESS) + { + result.GetErrorStream().Printf ("error: %s is not loaded", var_sc.module_sp->GetFileSpec().GetFilename().AsCString()); + } + } + else + { + result.GetErrorStream().Printf ("error: unable to resolve the variable address 0x%llx", file_addr); + } + } + else + { + if (expr_value_type == Value::eValueTypeHostAddress) + addr_type = eAddressTypeHost; + addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); + } + + if (addr != LLDB_INVALID_ADDRESS) + { + if (m_options.debug) + s.Printf("@ 0x%8.8llx, value = ", addr); + variable_type->DumpValueInMemory (exe_ctx, &s, addr, addr_type, m_options.show_types, m_options.show_summary, m_options.debug); + } + } + break; + } + s.EOL(); + } + } + } + + void + DumpValueObject (CommandReturnObject &result, + ExecutionContextScope *exe_scope, + ValueObject *valobj, + const char *root_valobj_name, + uint32_t ptr_depth, + uint32_t curr_depth, + uint32_t max_depth, + bool use_objc) + { + if (valobj) + { + Stream &s = result.GetOutputStream(); + + //const char *loc_cstr = valobj->GetLocationAsCString(); + if (m_options.show_location) + { + s.Printf("@ %s: ", valobj->GetLocationAsCString(exe_scope)); + } + if (m_options.debug) + s.Printf ("%p ValueObject{%u} ", valobj, valobj->GetID()); + + s.Indent(); + + if (m_options.show_types) + s.Printf("(%s) ", valobj->GetTypeName().AsCString()); + + const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); + s.Printf ("%s = ", name_cstr); + + const char *val_cstr = valobj->GetValueAsCString(exe_scope); + const char *err_cstr = valobj->GetError().AsCString(); + + if (err_cstr) + { + s.Printf ("error: %s\n", err_cstr); + } + else + { + const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); + + const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetOpaqueClangQualType()); + + if (val_cstr) + s.PutCString(val_cstr); + + if (sum_cstr) + s.Printf(" %s", sum_cstr); + + if (use_objc) + { + if (!ClangASTContext::IsPointerType (valobj->GetOpaqueClangQualType())) + return; + + if (!valobj->GetValueIsValid()) + return; + + Process *process = exe_scope->CalculateProcess(); + + if (!process) + return; + + Scalar scalar; + + if (!ClangASTType::GetValueAsScalar (valobj->GetClangAST(), + valobj->GetOpaqueClangQualType(), + valobj->GetDataExtractor(), + 0, + valobj->GetByteSize(), + scalar)) + return; + + ConstString po_output; + + ExecutionContext exe_ctx; + exe_scope->Calculate(exe_ctx); + + Value val(scalar); + val.SetContext(Value::eContextTypeOpaqueClangQualType, + ClangASTContext::GetVoidPtrType(valobj->GetClangAST(), false)); + + if (!process->GetObjCObjectPrinter().PrintObject(po_output, val, exe_ctx)) + return; + + s.Printf("\n%s\n", po_output.GetCString()); + + return; + } + + + if (curr_depth < max_depth) + { + if (is_aggregate) + s.PutChar('{'); + + bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetOpaqueClangQualType()); + + if (is_ptr_or_ref && ptr_depth == 0) + return; + + const uint32_t num_children = valobj->GetNumChildren(); + if (num_children) + { + s.IndentMore(); + for (uint32_t idx=0; idxGetChildAtIndex(idx, true)); + if (child_sp.get()) + { + s.EOL(); + DumpValueObject (result, + exe_scope, + child_sp.get(), + NULL, + is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, + curr_depth + 1, + max_depth, + false); + if (idx + 1 < num_children) + s.PutChar(','); + } + } + s.IndentLess(); + } + if (is_aggregate) + { + s.EOL(); + s.Indent("}"); + } + } + else + { + if (is_aggregate) + { + s.PutCString("{...}"); + } + } + + } + } + } + + virtual bool + Execute + ( + CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result + ) + { + ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); + if (exe_ctx.frame == NULL) + { + result.AppendError ("invalid frame"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + VariableList variable_list; + + bool show_inlined = true; // TODO: Get this from the process + SymbolContext frame_sc = exe_ctx.frame->GetSymbolContext (eSymbolContextEverything); + if (exe_ctx.frame && frame_sc.block) + frame_sc.block->AppendVariables(true, true, show_inlined, &variable_list); + VariableSP var_sp; + ValueObjectSP valobj_sp; + //ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList(); + const char *name_cstr = NULL; + size_t idx; + if (!m_options.globals.empty()) + { + uint32_t fail_count = 0; + if (exe_ctx.target) + { + const size_t num_globals = m_options.globals.size(); + for (idx = 0; idx < num_globals; ++idx) + { + VariableList global_var_list; + const uint32_t num_matching_globals = exe_ctx.target->GetImages().FindGlobalVariables (m_options.globals[idx], true, UINT32_MAX, global_var_list); + + if (num_matching_globals == 0) + { + ++fail_count; + result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", m_options.globals[idx].AsCString()); + } + else + { + for (uint32_t global_idx=0; global_idxGetValueObjectList().FindValueObjectByValueName (m_options.globals[idx].AsCString()); + if (!valobj_sp) + valobj_sp.reset (new ValueObjectVariable (var_sp)); + + if (valobj_sp) + { + exe_ctx.frame->GetValueObjectList().Append (valobj_sp); + DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, m_options.ptr_depth, 0, m_options.max_depth, false); + result.GetOutputStream().EOL(); + } + } + } + } + } + } + if (fail_count) + { + result.SetStatus (eReturnStatusFailed); + } + } + + if (command.GetArgumentCount() > 0) + { + // If we have any args to the variable command, we will make + // variable objects from them... + for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx) + { + uint32_t ptr_depth = m_options.ptr_depth; + // If first character is a '*', then show pointer contents + if (name_cstr[0] == '*') + { + ++ptr_depth; + name_cstr++; // Skip the '*' + } + + std::string var_path (name_cstr); + size_t separator_idx = var_path.find_first_of(".-["); + + ConstString name_const_string; + if (separator_idx == std::string::npos) + name_const_string.SetCString (var_path.c_str()); + else + name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); + + var_sp = variable_list.FindVariable(name_const_string); + if (var_sp) + { + //DumpVariable (result, &exe_ctx, var_sp.get()); + // TODO: redo history variables using a different map +// if (var_path[0] == '$') +// valobj_sp = valobj_list.FindValueObjectByValueObjectName (name_const_string.GetCString()); +// else + valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (name_const_string.GetCString()); + + if (!valobj_sp) + { + valobj_sp.reset (new ValueObjectVariable (var_sp)); + exe_ctx.frame->GetValueObjectList().Append (valobj_sp); + } + + var_path.erase (0, name_const_string.GetLength ()); + // We are dumping at least one child + while (separator_idx != std::string::npos) + { + // Calculate the next separator index ahead of time + ValueObjectSP child_valobj_sp; + const char separator_type = var_path[0]; + switch (separator_type) + { + + case '-': + if (var_path.size() >= 2 && var_path[1] != '>') + { + result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n", + var_path.c_str()); + var_path.clear(); + valobj_sp.reset(); + break; + } + var_path.erase (0, 1); // Remove the '-' + // Fall through + case '.': + { + var_path.erase (0, 1); // Remove the '.' or '>' + separator_idx = var_path.find_first_of(".-["); + ConstString child_name; + if (separator_idx == std::string::npos) + child_name.SetCString (var_path.c_str()); + else + child_name.SetCStringWithLength(var_path.c_str(), separator_idx); + + child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); + if (!child_valobj_sp) + { + result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n", + valobj_sp->GetName().AsCString(), + child_name.GetCString()); + var_path.clear(); + valobj_sp.reset(); + break; + } + // Remove the child name from the path + var_path.erase(0, child_name.GetLength()); + } + break; + + case '[': + // Array member access, or treating pointer as an array + if (var_path.size() > 2) // Need at least two brackets and a number + { + char *end = NULL; + int32_t child_index = ::strtol (&var_path[1], &end, 0); + if (end && *end == ']') + { + + if (valobj_sp->IsPointerType ()) + { + child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); + } + else + { + child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); + } + + if (!child_valobj_sp) + { + result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n", + child_index, + valobj_sp->GetName().AsCString()); + var_path.clear(); + valobj_sp.reset(); + break; + } + + // Erase the array member specification '[%i]' where %i is the array index + var_path.erase(0, (end - var_path.c_str()) + 1); + separator_idx = var_path.find_first_of(".-["); + + // Break out early from the switch since we were able to find the child member + break; + } + } + result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n", + valobj_sp->GetName().AsCString(), + var_path.c_str()); + var_path.clear(); + valobj_sp.reset(); + break; + + break; + + default: + result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n", + var_path.c_str()); + var_path.clear(); + valobj_sp.reset(); + separator_idx = std::string::npos; + break; + } + + if (child_valobj_sp) + valobj_sp = child_valobj_sp; + + if (var_path.empty()) + break; + + } + + if (valobj_sp) + { + DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, ptr_depth, 0, m_options.max_depth, m_options.use_objc); + result.GetOutputStream().EOL(); + } + } + else + { + result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr); + var_path.clear(); + } + } + } + else + { + + if (m_options.show_globals) + { + if (frame_sc.comp_unit) + { + variable_list.AddVariables (frame_sc.comp_unit->GetVariableList(true).get()); + } + } + + const uint32_t num_variables = variable_list.GetSize(); + + if (num_variables > 0) + { + for (uint32_t i=0; iGetScope()) + { + case eValueTypeVariableGlobal: + dump_variable = m_options.show_globals; + if (dump_variable && m_options.show_scope) + result.GetOutputStream().PutCString("GLOBAL: "); + break; + + case eValueTypeVariableStatic: + dump_variable = m_options.show_globals; + if (dump_variable && m_options.show_scope) + result.GetOutputStream().PutCString("STATIC: "); + break; + + case eValueTypeVariableArgument: + dump_variable = m_options.show_args; + if (dump_variable && m_options.show_scope) + result.GetOutputStream().PutCString(" ARG: "); + break; + + case eValueTypeVariableLocal: + dump_variable = m_options.show_locals; + if (dump_variable && m_options.show_scope) + result.GetOutputStream().PutCString(" LOCAL: "); + break; + + default: + break; + } + + if (dump_variable) + DumpVariable (result, &exe_ctx, variable); + } + } + } + result.SetStatus (eReturnStatusSuccessFinishResult); + } + return result.Succeeded(); + } +protected: + + CommandOptions m_options; +}; + +lldb::OptionDefinition +CommandObjectFrameVariable::CommandOptions::g_option_table[] = +{ +{ LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, NULL, "Show verbose debug information."}, +{ LLDB_OPT_SET_1, false, "depth", 'd', required_argument, NULL, 0, "", "Set the max recurse depth when dumping aggregate types (default is infinity)."}, +{ LLDB_OPT_SET_1, false, "globals", 'g', no_argument, NULL, 0, NULL, "List global and static variables for the current stack frame source file."}, +{ LLDB_OPT_SET_1, false, "global", 'G', required_argument, NULL, 0, NULL, "Find a global variable by name (which might not be in the current stack frame source file)."}, +{ LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, NULL, "Show variable location information."}, +{ LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, "", "Lookup a variable by name or regex (--regex) for the current execution context."}, +{ LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, NULL, "Omit function arguments."}, +{ LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, NULL, "Omit local variables."}, +{ LLDB_OPT_SET_1, false, "no-types", 't', no_argument, NULL, 0, NULL, "Omit variable type names."}, +{ LLDB_OPT_SET_1, false, "no-summary", 'y', no_argument, NULL, 0, NULL, "Omit summary information."}, +{ LLDB_OPT_SET_1, false, "scope", 's', no_argument, NULL, 0, NULL, "Show variable scope (argument, local, global, static)."}, +{ LLDB_OPT_SET_1, false, "objc", 'o', no_argument, NULL, 0, NULL, "When looking up a variable by name (--name), print as an Objective-C object."}, +{ LLDB_OPT_SET_1, false, "ptr-depth", 'p', required_argument, NULL, 0, "", "The number of pointers to be traversed when dumping values (default is zero)."}, +{ LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, NULL, "The argument for name lookups are regular expressions."}, +{ 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL } +}; #pragma mark CommandObjectMultiwordFrame //------------------------------------------------------------------------- @@ -168,6 +861,7 @@ { LoadSubCommand (interpreter, "info", CommandObjectSP (new CommandObjectFrameInfo ())); LoadSubCommand (interpreter, "select", CommandObjectSP (new CommandObjectFrameSelect ())); + LoadSubCommand (interpreter, "variable", CommandObjectSP (new CommandObjectFrameVariable ())); } CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame () Removed: lldb/trunk/source/Commands/CommandObjectVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectVariable.cpp?rev=112781&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectVariable.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectVariable.cpp (removed) @@ -1,804 +0,0 @@ -//===-- CommandObjectVariable.cpp -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectVariable.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/Options.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/Value.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Core/ValueObjectVariable.h" - -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -#include "lldb/Symbol/ClangASTType.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/Variable.h" -#include "lldb/Symbol/VariableList.h" - -#include "lldb/Target/Process.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; - -//void -//DumpValueObjectValues (Stream *sout, const char *root_valobj_name, ValueObjectSP& valobj_sp, bool follow_ptrs_and_refs, uint32_t curr_depth, uint32_t max_depth) -//{ -// ValueObject *valobj = valobj_sp.get(); -// if (valobj) -// { -// const char *name_cstr = valobj->GetName().AsCString(NULL); -// const char *val_cstr = valobj->GetValueAsCString(); -// const char *loc_cstr = valobj->GetLocationAsCString(); -// const char *type_cstr = valobj->GetTypeName().AsCString(); -// const char *sum_cstr = valobj->GetSummaryAsCString(); -// const char *err_cstr = valobj->GetError().AsCString(); -// // Indent -// sout->Indent(); -// if (root_valobj_name) -// { -// sout->Printf ("%s = ", root_valobj_name); -// } -// -// if (name_cstr) -// sout->Printf ("%s => ", name_cstr); -// -// sout->Printf ("ValueObject{%u}", valobj->GetID()); -// const uint32_t num_children = valobj->GetNumChildren(); -// -// if (type_cstr) -// sout->Printf (", type = '%s'", type_cstr); -// -// if (loc_cstr) -// sout->Printf (", location = %s", loc_cstr); -// -// sout->Printf (", num_children = %u", num_children); -// -// if (val_cstr) -// sout->Printf (", value = %s", val_cstr); -// -// if (err_cstr) -// sout->Printf (", error = %s", err_cstr); -// -// if (sum_cstr) -// sout->Printf (", summary = %s", sum_cstr); -// -// sout->EOL(); -// bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetOpaqueClangQualType()); -// if (!follow_ptrs_and_refs && is_ptr_or_ref) -// return; -// -// if (curr_depth < max_depth) -// { -// for (uint32_t idx=0; idxGetChildAtIndex(idx, true)); -// if (child_sp.get()) -// { -// sout->IndentMore(); -// DumpValueObjectValues (sout, NULL, child_sp, follow_ptrs_and_refs, curr_depth + 1, max_depth); -// sout->IndentLess(); -// } -// } -// } -// } -//} - -//---------------------------------------------------------------------- -// List images with associated information -//---------------------------------------------------------------------- -class CommandObjectVariableList : public CommandObject -{ -public: - - class CommandOptions : public Options - { - public: - - CommandOptions () : - Options() - { - ResetOptionValues (); - } - - virtual - ~CommandOptions () - { - } - - virtual Error - SetOptionValue (int option_idx, const char *option_arg) - { - Error error; - bool success; - char short_option = (char) m_getopt_table[option_idx].val; - switch (short_option) - { - case 'o': use_objc = true; break; - case 'n': name = option_arg; break; - case 'r': use_regex = true; break; - case 'a': show_args = false; break; - case 'l': show_locals = false; break; - case 'g': show_globals = false; break; - case 't': show_types = false; break; - case 'y': show_summary = false; break; - case 'L': show_location= true; break; - case 'D': debug = true; break; - case 'd': - max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid max depth '%s'.\n", option_arg); - break; - - case 'p': - ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg); - break; - - case 'G': - { - ConstString const_string (option_arg); - globals.push_back(const_string); - } - break; - - case 's': - show_scope = true; - break; - - default: - error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); - break; - } - - return error; - } - - void - ResetOptionValues () - { - Options::ResetOptionValues(); - - name.clear(); - use_objc = false; - use_regex = false; - show_args = true; - show_locals = true; - show_globals = true; - show_types = true; - show_scope = false; - show_summary = true; - show_location = false; - debug = false; - max_depth = UINT32_MAX; - ptr_depth = 0; - globals.clear(); - } - - const lldb::OptionDefinition* - GetDefinitions () - { - return g_option_table; - } - - // Options table: Required for subclasses of Options. - - static lldb::OptionDefinition g_option_table[]; - std::string name; - bool use_objc; - bool use_regex; - bool show_args; - bool show_locals; - bool show_globals; - bool show_types; - bool show_scope; // local/arg/global/static - bool show_summary; - bool show_location; - bool debug; - uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values - uint32_t ptr_depth; // The default depth that is dumped when we find pointers - std::vector globals; - // Instance variables to hold the values for command options. - }; - - CommandObjectVariableList () : - CommandObject ( - "variable list", - "Show specified argument, local variable, static variable or global variable. If none specified, list them all.", - "variable list [] [ [...]]") - { - } - - virtual - ~CommandObjectVariableList () - { - } - - virtual - Options * - GetOptions () - { - return &m_options; - } - - void - DumpVariable (CommandReturnObject &result, ExecutionContext *exe_ctx, Variable *variable) - { - if (variable) - { - Stream &s = result.GetOutputStream(); - DWARFExpression &expr = variable->LocationExpression(); - Value expr_result; - Error expr_error; - Type *variable_type = variable->GetType(); - bool expr_success = expr.Evaluate(exe_ctx, NULL, NULL, expr_result, &expr_error); - - if (m_options.debug) - s.Printf ("Variable{0x%8.8x}: ", variable->GetID()); - - if (!expr_success) - s.Printf ("%s = ERROR: %s\n", variable->GetName().AsCString(NULL), expr_error.AsCString()); - else - { - Value::ValueType expr_value_type = expr_result.GetValueType(); - switch (expr_value_type) - { - case Value::eValueTypeScalar: - s.Printf ("%s = ", variable->GetName().AsCString(NULL)); - if (variable_type) - { - DataExtractor data; - if (expr_result.ResolveValue (exe_ctx, NULL).GetData (data)) - variable_type->DumpValue (exe_ctx, &s, data, 0, m_options.show_types, m_options.show_summary, m_options.debug); - } - break; - - case Value::eValueTypeFileAddress: - case Value::eValueTypeLoadAddress: - case Value::eValueTypeHostAddress: - { - s.Printf ("%s = ", variable->GetName().AsCString(NULL)); - lldb::addr_t addr = LLDB_INVALID_ADDRESS; - lldb::AddressType addr_type = eAddressTypeLoad; - - if (expr_value_type == Value::eValueTypeFileAddress) - { - lldb::addr_t file_addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); - SymbolContext var_sc; - variable->CalculateSymbolContext(&var_sc); - if (var_sc.module_sp) - { - ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); - if (objfile) - { - Address so_addr(file_addr, objfile->GetSectionList()); - addr = so_addr.GetLoadAddress(exe_ctx->process); - } - if (addr == LLDB_INVALID_ADDRESS) - { - result.GetErrorStream().Printf ("error: %s is not loaded", var_sc.module_sp->GetFileSpec().GetFilename().AsCString()); - } - } - else - { - result.GetErrorStream().Printf ("error: unable to resolve the variable address 0x%llx", file_addr); - } - } - else - { - if (expr_value_type == Value::eValueTypeHostAddress) - addr_type = eAddressTypeHost; - addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); - } - - if (addr != LLDB_INVALID_ADDRESS) - { - if (m_options.debug) - s.Printf("@ 0x%8.8llx, value = ", addr); - variable_type->DumpValueInMemory (exe_ctx, &s, addr, addr_type, m_options.show_types, m_options.show_summary, m_options.debug); - } - } - break; - } - s.EOL(); - } - } - } - - void - DumpValueObject (CommandReturnObject &result, - ExecutionContextScope *exe_scope, - ValueObject *valobj, - const char *root_valobj_name, - uint32_t ptr_depth, - uint32_t curr_depth, - uint32_t max_depth, - bool use_objc) - { - if (valobj) - { - Stream &s = result.GetOutputStream(); - - //const char *loc_cstr = valobj->GetLocationAsCString(); - if (m_options.show_location) - { - s.Printf("@ %s: ", valobj->GetLocationAsCString(exe_scope)); - } - if (m_options.debug) - s.Printf ("%p ValueObject{%u} ", valobj, valobj->GetID()); - - s.Indent(); - - if (m_options.show_types) - s.Printf("(%s) ", valobj->GetTypeName().AsCString()); - - const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); - s.Printf ("%s = ", name_cstr); - - const char *val_cstr = valobj->GetValueAsCString(exe_scope); - const char *err_cstr = valobj->GetError().AsCString(); - - if (err_cstr) - { - s.Printf ("error: %s\n", err_cstr); - } - else - { - const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); - - const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetOpaqueClangQualType()); - - if (val_cstr) - s.PutCString(val_cstr); - - if (sum_cstr) - s.Printf(" %s", sum_cstr); - - if (use_objc) - { - if (!ClangASTContext::IsPointerType (valobj->GetOpaqueClangQualType())) - return; - - if (!valobj->GetValueIsValid()) - return; - - Process *process = exe_scope->CalculateProcess(); - - if (!process) - return; - - Scalar scalar; - - if (!ClangASTType::GetValueAsScalar (valobj->GetClangAST(), - valobj->GetOpaqueClangQualType(), - valobj->GetDataExtractor(), - 0, - valobj->GetByteSize(), - scalar)) - return; - - ConstString po_output; - - ExecutionContext exe_ctx; - exe_scope->Calculate(exe_ctx); - - Value val(scalar); - val.SetContext(Value::eContextTypeOpaqueClangQualType, - ClangASTContext::GetVoidPtrType(valobj->GetClangAST(), false)); - - if (!process->GetObjCObjectPrinter().PrintObject(po_output, val, exe_ctx)) - return; - - s.Printf("\n%s\n", po_output.GetCString()); - - return; - } - - - if (curr_depth < max_depth) - { - if (is_aggregate) - s.PutChar('{'); - - bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetOpaqueClangQualType()); - - if (is_ptr_or_ref && ptr_depth == 0) - return; - - const uint32_t num_children = valobj->GetNumChildren(); - if (num_children) - { - s.IndentMore(); - for (uint32_t idx=0; idxGetChildAtIndex(idx, true)); - if (child_sp.get()) - { - s.EOL(); - DumpValueObject (result, - exe_scope, - child_sp.get(), - NULL, - is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, - curr_depth + 1, - max_depth, - false); - if (idx + 1 < num_children) - s.PutChar(','); - } - } - s.IndentLess(); - } - if (is_aggregate) - { - s.EOL(); - s.Indent("}"); - } - } - else - { - if (is_aggregate) - { - s.PutCString("{...}"); - } - } - - } - } - } - - virtual bool - Execute - ( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result - ) - { - ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); - if (exe_ctx.frame == NULL) - { - result.AppendError ("invalid frame"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - VariableList variable_list; - - bool show_inlined = true; // TODO: Get this from the process - SymbolContext frame_sc = exe_ctx.frame->GetSymbolContext (eSymbolContextEverything); - if (exe_ctx.frame && frame_sc.block) - frame_sc.block->AppendVariables(true, true, show_inlined, &variable_list); - VariableSP var_sp; - ValueObjectSP valobj_sp; - //ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList(); - const char *name_cstr = NULL; - size_t idx; - if (!m_options.globals.empty()) - { - uint32_t fail_count = 0; - if (exe_ctx.target) - { - const size_t num_globals = m_options.globals.size(); - for (idx = 0; idx < num_globals; ++idx) - { - VariableList global_var_list; - const uint32_t num_matching_globals = exe_ctx.target->GetImages().FindGlobalVariables (m_options.globals[idx], true, UINT32_MAX, global_var_list); - - if (num_matching_globals == 0) - { - ++fail_count; - result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", m_options.globals[idx].AsCString()); - } - else - { - for (uint32_t global_idx=0; global_idxGetValueObjectList().FindValueObjectByValueName (m_options.globals[idx].AsCString()); - if (!valobj_sp) - valobj_sp.reset (new ValueObjectVariable (var_sp)); - - if (valobj_sp) - { - exe_ctx.frame->GetValueObjectList().Append (valobj_sp); - DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, m_options.ptr_depth, 0, m_options.max_depth, false); - result.GetOutputStream().EOL(); - } - } - } - } - } - } - if (fail_count) - { - result.SetStatus (eReturnStatusFailed); - } - } - - if (command.GetArgumentCount() > 0) - { - // If we have any args to the variable command, we will make - // variable objects from them... - for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx) - { - uint32_t ptr_depth = m_options.ptr_depth; - // If first character is a '*', then show pointer contents - if (name_cstr[0] == '*') - { - ++ptr_depth; - name_cstr++; // Skip the '*' - } - - std::string var_path (name_cstr); - size_t separator_idx = var_path.find_first_of(".-["); - - ConstString name_const_string; - if (separator_idx == std::string::npos) - name_const_string.SetCString (var_path.c_str()); - else - name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); - - var_sp = variable_list.FindVariable(name_const_string); - if (var_sp) - { - //DumpVariable (result, &exe_ctx, var_sp.get()); - // TODO: redo history variables using a different map -// if (var_path[0] == '$') -// valobj_sp = valobj_list.FindValueObjectByValueObjectName (name_const_string.GetCString()); -// else - valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (name_const_string.GetCString()); - - if (!valobj_sp) - { - valobj_sp.reset (new ValueObjectVariable (var_sp)); - exe_ctx.frame->GetValueObjectList().Append (valobj_sp); - } - - var_path.erase (0, name_const_string.GetLength ()); - // We are dumping at least one child - while (separator_idx != std::string::npos) - { - // Calculate the next separator index ahead of time - ValueObjectSP child_valobj_sp; - const char separator_type = var_path[0]; - switch (separator_type) - { - - case '-': - if (var_path.size() >= 2 && var_path[1] != '>') - { - result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n", - var_path.c_str()); - var_path.clear(); - valobj_sp.reset(); - break; - } - var_path.erase (0, 1); // Remove the '-' - // Fall through - case '.': - { - var_path.erase (0, 1); // Remove the '.' or '>' - separator_idx = var_path.find_first_of(".-["); - ConstString child_name; - if (separator_idx == std::string::npos) - child_name.SetCString (var_path.c_str()); - else - child_name.SetCStringWithLength(var_path.c_str(), separator_idx); - - child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); - if (!child_valobj_sp) - { - result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n", - valobj_sp->GetName().AsCString(), - child_name.GetCString()); - var_path.clear(); - valobj_sp.reset(); - break; - } - // Remove the child name from the path - var_path.erase(0, child_name.GetLength()); - } - break; - - case '[': - // Array member access, or treating pointer as an array - if (var_path.size() > 2) // Need at least two brackets and a number - { - char *end = NULL; - int32_t child_index = ::strtol (&var_path[1], &end, 0); - if (end && *end == ']') - { - - if (valobj_sp->IsPointerType ()) - { - child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); - } - else - { - child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); - } - - if (!child_valobj_sp) - { - result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n", - child_index, - valobj_sp->GetName().AsCString()); - var_path.clear(); - valobj_sp.reset(); - break; - } - - // Erase the array member specification '[%i]' where %i is the array index - var_path.erase(0, (end - var_path.c_str()) + 1); - separator_idx = var_path.find_first_of(".-["); - - // Break out early from the switch since we were able to find the child member - break; - } - } - result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n", - valobj_sp->GetName().AsCString(), - var_path.c_str()); - var_path.clear(); - valobj_sp.reset(); - break; - - break; - - default: - result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n", - var_path.c_str()); - var_path.clear(); - valobj_sp.reset(); - separator_idx = std::string::npos; - break; - } - - if (child_valobj_sp) - valobj_sp = child_valobj_sp; - - if (var_path.empty()) - break; - - } - - if (valobj_sp) - { - DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, ptr_depth, 0, m_options.max_depth, m_options.use_objc); - result.GetOutputStream().EOL(); - } - } - else - { - result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr); - var_path.clear(); - } - } - } - else - { - - if (m_options.show_globals) - { - if (frame_sc.comp_unit) - { - variable_list.AddVariables (frame_sc.comp_unit->GetVariableList(true).get()); - } - } - - const uint32_t num_variables = variable_list.GetSize(); - - if (num_variables > 0) - { - for (uint32_t i=0; iGetScope()) - { - case eValueTypeVariableGlobal: - dump_variable = m_options.show_globals; - if (dump_variable && m_options.show_scope) - result.GetOutputStream().PutCString("GLOBAL: "); - break; - - case eValueTypeVariableStatic: - dump_variable = m_options.show_globals; - if (dump_variable && m_options.show_scope) - result.GetOutputStream().PutCString("STATIC: "); - break; - - case eValueTypeVariableArgument: - dump_variable = m_options.show_args; - if (dump_variable && m_options.show_scope) - result.GetOutputStream().PutCString(" ARG: "); - break; - - case eValueTypeVariableLocal: - dump_variable = m_options.show_locals; - if (dump_variable && m_options.show_scope) - result.GetOutputStream().PutCString(" LOCAL: "); - break; - - default: - break; - } - - if (dump_variable) - DumpVariable (result, &exe_ctx, variable); - } - } - } - result.SetStatus (eReturnStatusSuccessFinishResult); - } - return result.Succeeded(); - } -protected: - - CommandOptions m_options; -}; - -lldb::OptionDefinition -CommandObjectVariableList::CommandOptions::g_option_table[] = -{ -{ LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, NULL, "Show verbose debug information."}, -{ LLDB_OPT_SET_1, false, "depth", 'd', required_argument, NULL, 0, "", "Set the max recurse depth when dumping aggregate types (default is infinity)."}, -{ LLDB_OPT_SET_1, false, "globals", 'g', no_argument, NULL, 0, NULL, "List global and static variables for the current stack frame source file."}, -{ LLDB_OPT_SET_1, false, "global", 'G', required_argument, NULL, 0, NULL, "Find a global variable by name (which might not be in the current stack frame source file)."}, -{ LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, NULL, "Show variable location information."}, -{ LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, "", "Lookup a variable by name or regex (--regex) for the current execution context."}, -{ LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, NULL, "Omit function arguments."}, -{ LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, NULL, "Omit local variables."}, -{ LLDB_OPT_SET_1, false, "no-types", 't', no_argument, NULL, 0, NULL, "Omit variable type names."}, -{ LLDB_OPT_SET_1, false, "no-summary", 'y', no_argument, NULL, 0, NULL, "Omit summary information."}, -{ LLDB_OPT_SET_1, false, "scope", 's', no_argument, NULL, 0, NULL, "Show variable scope (argument, local, global, static)."}, -{ LLDB_OPT_SET_1, false, "objc", 'o', no_argument, NULL, 0, NULL, "When looking up a variable by name (--name), print as an Objective-C object."}, -{ LLDB_OPT_SET_1, false, "ptr-depth", 'p', required_argument, NULL, 0, "", "The number of pointers to be traversed when dumping values (default is zero)."}, -{ LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, NULL, "The argument for name lookups are regular expressions."}, -{ 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL } -}; - -//---------------------------------------------------------------------- -// CommandObjectVariable constructor -//---------------------------------------------------------------------- -CommandObjectVariable::CommandObjectVariable(CommandInterpreter &interpreter) : - CommandObjectMultiword ("variable", - "Access program arguments, locals, static and global variables.", - "variable [list] ...") -{ - LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectVariableList ())); -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CommandObjectVariable::~CommandObjectVariable() -{ -} - - - - Removed: lldb/trunk/source/Commands/CommandObjectVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectVariable.h?rev=112781&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectVariable.h (original) +++ lldb/trunk/source/Commands/CommandObjectVariable.h (removed) @@ -1,43 +0,0 @@ -//===-- CommandObjectVariable.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_CommandObjectVariable_h_ -#define liblldb_CommandObjectVariable_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObjectMultiword.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectImage -//------------------------------------------------------------------------- - -class CommandObjectVariable : public CommandObjectMultiword -{ -public: - - CommandObjectVariable (CommandInterpreter &interpreter); - - virtual - ~CommandObjectVariable (); - -private: - //------------------------------------------------------------------ - // For CommandObjectVariable only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (CommandObjectVariable); -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectVariable_h_ Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=112782&r1=112781&r2=112782&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Wed Sep 1 19:18:39 2010 @@ -41,7 +41,6 @@ #include "../Commands/CommandObjectSyntax.h" #include "../Commands/CommandObjectTarget.h" #include "../Commands/CommandObjectThread.h" -#include "../Commands/CommandObjectVariable.h" #include "lldb/Interpreter/Args.h" #include "lldb/Core/Debugger.h" @@ -232,7 +231,6 @@ m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); - m_command_dict["variable"] = CommandObjectSP (new CommandObjectVariable (*this)); std::auto_ptr break_regex_cmd_ap(new CommandObjectRegexCommand ("regexp-break", Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=112782&r1=112781&r2=112782&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Wed Sep 1 19:18:39 2010 @@ -70,7 +70,7 @@ { LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, NULL, "", "Tells the debugger to use the file as the program to be debugged." }, - { LLDB_OPT_SET_ALL, false, "editor", 'e', no_argument, NULL, NULL, "", + { LLDB_OPT_SET_ALL, false, "editor", 'e', no_argument, NULL, NULL, NULL, "Tells the debugger to open source files using the host's \"external editor\" mechanism." }, // { LLDB_OPT_SET_4, true, "crash-log", 'c', required_argument, NULL, NULL, "", From scallanan at apple.com Wed Sep 1 19:37:32 2010 From: scallanan at apple.com (Sean Callanan) Date: Thu, 02 Sep 2010 00:37:32 -0000 Subject: [Lldb-commits] [lldb] r112785 - in /lldb/trunk: include/lldb/Expression/IRDynamicChecks.h source/Expression/IRDynamicChecks.cpp Message-ID: <20100902003732.47C162A6C12C@llvm.org> Author: spyffe Date: Wed Sep 1 19:37:32 2010 New Revision: 112785 URL: http://llvm.org/viewvc/llvm-project?rev=112785&view=rev Log: Added code to run pointer validation checks in expressions. If an expression dereferences an invalid pointer, there will still be a crash - just now the crash will be in the function ___clang_valid_pointer_check(). Modified: lldb/trunk/include/lldb/Expression/IRDynamicChecks.h lldb/trunk/source/Expression/IRDynamicChecks.cpp Modified: lldb/trunk/include/lldb/Expression/IRDynamicChecks.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRDynamicChecks.h?rev=112785&r1=112784&r2=112785&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRDynamicChecks.h (original) +++ lldb/trunk/include/lldb/Expression/IRDynamicChecks.h Wed Sep 1 19:37:32 2010 @@ -132,6 +132,26 @@ //------------------------------------------------------------------ llvm::PassManagerType getPotentialPassManagerType() const; private: + //------------------------------------------------------------------ + /// A basic block-level pass to find all pointer dereferences and + /// validate them before use. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + /// + /// @return + /// True on success; false otherwise + //------------------------------------------------------------------ + bool FindDataLoads(llvm::Module &M, + llvm::BasicBlock &BB); + std::string m_func_name; ///< The name of the function to add checks to DynamicCheckerFunctions &m_checker_functions; ///< The checker functions for the process }; Modified: lldb/trunk/source/Expression/IRDynamicChecks.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRDynamicChecks.cpp?rev=112785&r1=112784&r2=112785&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRDynamicChecks.cpp (original) +++ lldb/trunk/source/Expression/IRDynamicChecks.cpp Wed Sep 1 19:37:32 2010 @@ -14,6 +14,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Function.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Value.h" @@ -52,16 +53,6 @@ return true; } -IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions, - const char *func_name) : - ModulePass(&ID), - m_checker_functions(checker_functions), - m_func_name(func_name) -{ -} - -/* A handy utility function used at several places in the code */ - static std::string PrintValue(llvm::Value *V, bool truncate = false) { @@ -74,6 +65,257 @@ return s; } +//---------------------------------------------------------------------- +/// @class Instrumenter IRDynamicChecks.cpp +/// @brief Finds and instruments individual LLVM IR instructions +/// +/// When instrumenting LLVM IR, it is frequently desirable to first search +/// for instructions, and then later modify them. This way iterators +/// remain intact, and multiple passes can look at the same code base without +/// treading on each other's toes. +/// +/// The Instrumenter class implements this functionality. A client first +/// calls Inspect on a function, which populates a list of instructions to +/// be instrumented. Then, later, when all passes' Inspect functions have +/// been called, the client calls Instrument, which adds the desired +/// instrumentation. +/// +/// A subclass of Instrumenter must override InstrumentInstruction, which +/// is responsible for adding whatever instrumentation is necessary. +/// +/// A subclass of Instrumenter may override: +/// +/// - InspectInstruction [default: does nothing] +/// +/// - InspectBasicBlock [default: iterates through the instructions in a +/// basic block calling InspectInstruction] +/// +/// - InspectFunction [default: iterates through the basic blocks in a +/// function calling InspectBasicBlock] +//---------------------------------------------------------------------- +class Instrumenter { +public: + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] module + /// The module being instrumented. + //------------------------------------------------------------------ + Instrumenter (llvm::Module &module, + DynamicCheckerFunctions &checker_functions) : + m_module(module), + m_checker_functions(checker_functions) + { + } + + //------------------------------------------------------------------ + /// Inspect a function to find instructions to instrument + /// + /// @param[in] function + /// The function to inspect. + /// + /// @return + /// True on success; false on error. + //------------------------------------------------------------------ + bool Inspect (llvm::Function &function) + { + return InspectFunction(function); + } + + //------------------------------------------------------------------ + /// Instrument all the instructions found by Inspect() + /// + /// @return + /// True on success; false on error. + //------------------------------------------------------------------ + bool Instrument () + { + for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end(); + ii != last_ii; + ++ii) + { + if (!InstrumentInstruction(*ii)) + return false; + } + + return true; + } +protected: + //------------------------------------------------------------------ + /// Add instrumentation to a single instruction + /// + /// @param[in] inst + /// The instruction to be instrumented. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0; + + //------------------------------------------------------------------ + /// Register a single instruction to be instrumented + /// + /// @param[in] inst + /// The instruction to be instrumented. + //------------------------------------------------------------------ + void RegisterInstruction(llvm::Instruction &i) + { + m_to_instrument.push_back(&i); + } + + //------------------------------------------------------------------ + /// Determine whether a single instruction is interesting to + /// instrument, and, if so, call RegisterInstruction + /// + /// @param[in] i + /// The instruction to be inspected. + /// + /// @return + /// False if there was an error scanning; true otherwise. + //------------------------------------------------------------------ + virtual bool InspectInstruction(llvm::Instruction &i) + { + return true; + } + + //------------------------------------------------------------------ + /// Scan a basic block to see if any instructions are interesting + /// + /// @param[in] bb + /// The basic block to be inspected. + /// + /// @return + /// False if there was an error scanning; true otherwise. + //------------------------------------------------------------------ + virtual bool InspectBasicBlock(llvm::BasicBlock &bb) + { + for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end(); + ii != last_ii; + ++ii) + { + if (!InspectInstruction(*ii)) + return false; + } + + return true; + } + + //------------------------------------------------------------------ + /// Scan a function to see if any instructions are interesting + /// + /// @param[in] f + /// The function to be inspected. + /// + /// @return + /// False if there was an error scanning; true otherwise. + //------------------------------------------------------------------ + virtual bool InspectFunction(llvm::Function &f) + { + for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end(); + bbi != last_bbi; + ++bbi) + { + if (!InspectBasicBlock(*bbi)) + return false; + } + + return true; + } + + typedef std::vector InstVector; + typedef InstVector::iterator InstIterator; + + InstVector m_to_instrument; ///< List of instructions the inspector found + llvm::Module &m_module; ///< The module which is being instrumented + DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process +}; + +class ValidPointerChecker : public Instrumenter +{ +public: + ValidPointerChecker(llvm::Module &module, + DynamicCheckerFunctions &checker_functions) : + Instrumenter(module, checker_functions), + m_valid_pointer_check_func(NULL) + { + } +private: + bool InstrumentInstruction(llvm::Instruction *inst) + { + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + if(log) + log->Printf("Instrumenting load/store instruction: %s\n", + PrintValue(inst).c_str()); + + if (!m_valid_pointer_check_func) + { + std::vector params; + + const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), + (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32); + + m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext()); + + params.push_back(m_i8ptr_ty); + + FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true); + PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); + Constant *fun_addr_int = ConstantInt::get(intptr_ty, m_checker_functions.m_valid_pointer_check->StartAddress(), false); + m_valid_pointer_check_func = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); + } + + llvm::Value *dereferenced_ptr; + + if (llvm::LoadInst *li = dyn_cast (inst)) + dereferenced_ptr = li->getPointerOperand(); + else if (llvm::StoreInst *si = dyn_cast (inst)) + dereferenced_ptr = si->getPointerOperand(); + else + return false; + + // Insert an instruction to cast the loaded value to int8_t* + + BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr, + m_i8ptr_ty, + "", + inst); + + // Insert an instruction to call the helper with the result + + SmallVector args; + args.push_back(bit_cast); + + CallInst::Create(m_valid_pointer_check_func, + args.begin(), + args.end(), + "", + inst); + + return true; + } + + bool InspectInstruction(llvm::Instruction &i) + { + if (dyn_cast (&i) || + dyn_cast (&i)) + RegisterInstruction(i); + + return true; + } + + llvm::Value *m_valid_pointer_check_func; + const PointerType *m_i8ptr_ty; +}; + +IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions, + const char *func_name) : + ModulePass(&ID), + m_checker_functions(checker_functions), + m_func_name(func_name) +{ +} + IRDynamicChecks::~IRDynamicChecks() { } @@ -92,14 +334,14 @@ return false; } + + ValidPointerChecker vpc(M, m_checker_functions); - llvm::Function::iterator bbi; + if (!vpc.Inspect(*function)) + return false; - for (bbi = function->begin(); - bbi != function->end(); - ++bbi) - { - } + if (!vpc.Instrument()) + return false; return true; } From gclayton at apple.com Wed Sep 1 21:59:19 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 02 Sep 2010 02:59:19 -0000 Subject: [Lldb-commits] [lldb] r112800 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Symbol/ include/lldb/Target/ lldb.xcodeproj/ source/API/ source/Commands/ source/Core/ source/Symbol/ source/Target/ Message-ID: <20100902025919.3BB722A6C12C@llvm.org> Author: gclayton Date: Wed Sep 1 21:59:18 2010 New Revision: 112800 URL: http://llvm.org/viewvc/llvm-project?rev=112800&view=rev Log: StackFrame objects now own ValueObjects for any frame variables (locals, args, function statics, file globals and static variables) that a frame contains. The StackFrame objects can give out ValueObjects instances for each variable which allows us to track when a variable changes and doesn't depend on variable names when getting value objects. StackFrame::GetVariableList now takes a boolean to indicate if we want to get the frame compile unit globals and static variables. The value objects in the stack frames can now correctly track when they have been modified. There are a few more tweaks needed to complete this work. The biggest issue is when stepping creates partial stacks (just frame zero usually) and causes previous stack frames not to match up with the current stack frames because the previous frames only has frame zero. We don't really want to require that all previous frames be complete since stepping often must check stack frames to complete their jobs. I will fix this issue tomorrow. Modified: lldb/trunk/include/lldb/API/SBValue.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/Core/ValueObjectList.h lldb/trunk/include/lldb/Core/ValueObjectVariable.h lldb/trunk/include/lldb/Symbol/VariableList.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/API/SBValue.cpp lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Core/ValueObjectList.cpp lldb/trunk/source/Core/ValueObjectVariable.cpp lldb/trunk/source/Symbol/VariableList.cpp lldb/trunk/source/Target/StackFrame.cpp Modified: lldb/trunk/include/lldb/API/SBValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValue.h (original) +++ lldb/trunk/include/lldb/API/SBValue.h Wed Sep 1 21:59:18 2010 @@ -45,7 +45,7 @@ GetValue (const lldb::SBFrame &frame); bool - GetValueDidChange (); + GetValueDidChange (const lldb::SBFrame &frame); const char * GetSummary (const lldb::SBFrame &frame); Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Sep 1 21:59:18 2010 @@ -145,10 +145,10 @@ GetUpdateID() const; bool - GetValueIsValid (); + GetValueIsValid () const; bool - GetValueDidChange () const; + GetValueDidChange (ExecutionContextScope *exe_scope); bool UpdateValueIfNeeded (ExecutionContextScope *exe_scope); @@ -173,11 +173,6 @@ GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create); protected: - enum { - eValueChanged = (1 << 0), - eNumChildrenHasBeenSet = (1 << 1), - eValueIsValid = (1 << 2) - }; //------------------------------------------------------------------ // Classes that inherit from ValueObject can see and modify these //------------------------------------------------------------------ @@ -191,12 +186,17 @@ DataExtractor m_data; // A data extractor that can be used to extract the value. Value m_value; Error m_error; // An error object that can describe any errors that occur when updating values. - Flags m_flags; // A boolean that indicates this value has changed std::string m_value_str; // Cached value string that will get cleared if/when the value is updated. + std::string m_old_value_str;// Cached old value string from the last time the value was gotten std::string m_location_str; // Cached location string that will get cleared if/when the value is updated. std::string m_summary_str; // Cached summary string that will get cleared if/when the value is updated. std::vector m_children; std::map m_synthetic_children; + bool m_value_is_valid:1, + m_value_did_change:1, + m_children_count_valid:1, + m_old_value_valid:1; + //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Core/ValueObjectList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectList.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectList.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectList.h Wed Sep 1 21:59:18 2010 @@ -48,11 +48,18 @@ FindValueObjectByPointer (ValueObject *valobj); uint32_t - GetSize() const; + GetSize () const; + + void + Resize (uint32_t size); lldb::ValueObjectSP - GetValueObjectAtIndex (uint32_t); + GetValueObjectAtIndex (uint32_t idx); + void + SetValueObjectAtIndex (uint32_t idx, + const lldb::ValueObjectSP &valobj_sp); + lldb::ValueObjectSP FindValueObjectByValueName (const char *name); Modified: lldb/trunk/include/lldb/Core/ValueObjectVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectVariable.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectVariable.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectVariable.h Wed Sep 1 21:59:18 2010 @@ -25,7 +25,7 @@ class ValueObjectVariable : public ValueObject { public: - ValueObjectVariable (lldb::VariableSP &var_sp); + ValueObjectVariable (const lldb::VariableSP &var_sp); virtual ~ValueObjectVariable(); Modified: lldb/trunk/include/lldb/Symbol/VariableList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/VariableList.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/VariableList.h (original) +++ lldb/trunk/include/lldb/Symbol/VariableList.h Wed Sep 1 21:59:18 2010 @@ -27,7 +27,7 @@ virtual ~VariableList(); void - AddVariable (lldb::VariableSP &var_sp); + AddVariable (const lldb::VariableSP &var_sp); void AddVariables(VariableList *variable_list); @@ -42,14 +42,11 @@ GetVariableAtIndex(uint32_t idx); lldb::VariableSP - FindVariable(const ConstString& name); + FindVariable (const ConstString& name); + + uint32_t + FindIndexForVariable (Variable* variable); -// const SymbolContext& -// GetSymbolContext() const -// { -// return m_symbol_context; -// } -// size_t MemorySize() const; Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Wed Sep 1 21:59:18 2010 @@ -91,14 +91,11 @@ } VariableList * - GetVariableList (); + GetVariableList (bool get_file_globals); bool HasDebugInformation (); - ValueObjectList & - GetValueObjectList(); - const char * Disassemble (); @@ -120,6 +117,12 @@ return m_unwind_frame_index; } + lldb::ValueObjectSP + GetValueObjectForFrameVariable (const lldb::VariableSP &variable_sp); + + lldb::ValueObjectSP + TrackGlobalVariable (const lldb::VariableSP &variable_sp); + //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ @@ -165,7 +168,7 @@ Scalar m_frame_base; Error m_frame_base_error; lldb::VariableListSP m_variable_list_sp; - ValueObjectList m_value_object_list; + ValueObjectList m_variable_list_value_objects; // Value objects for each variable in m_variable_list_sp StreamString m_disassembly; DISALLOW_COPY_AND_ASSIGN (StackFrame); }; Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Wed Sep 1 21:59:18 2010 @@ -62,6 +62,7 @@ typedef SharedPtr::Type ValueObjectSP; typedef SharedPtr::Type VariableSP; typedef SharedPtr::Type VariableListSP; + typedef SharedPtr::Type ValueObjectListSP; } // namespace lldb Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Sep 1 21:59:18 2010 @@ -2310,6 +2310,7 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Wed Sep 1 21:59:18 2010 @@ -304,7 +304,7 @@ if (m_opaque_sp) { size_t i; - VariableList *variable_list = m_opaque_sp->GetVariableList(); + VariableList *variable_list = m_opaque_sp->GetVariableList(true); if (variable_list) { const size_t num_variables = variable_list->GetSize(); @@ -339,38 +339,12 @@ if (in_scope_only && !variable_sp->IsInScope(m_opaque_sp.get())) continue; - value_list.Append(ValueObjectSP (new ValueObjectVariable (variable_sp))); + value_list.Append(m_opaque_sp->GetValueObjectForFrameVariable (variable_sp)); } } } } - } - - if (statics) - { - CompileUnit *frame_comp_unit = m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit; - - if (frame_comp_unit) - { - variable_list = frame_comp_unit->GetVariableList(true).get(); - - if (variable_list) - { - const size_t num_variables = variable_list->GetSize(); - if (num_variables) - { - for (i = 0; i < num_variables; ++i) - { - VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); - if (variable_sp) - { - value_list.Append(ValueObjectSP (new ValueObjectVariable (variable_sp))); - } - } - } - } - } - } + } } return value_list; } Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Wed Sep 1 21:59:18 2010 @@ -172,15 +172,15 @@ { const char *value_string = NULL; if ( m_opaque_sp) - value_string = m_opaque_sp->GetValueAsCString(frame.get()); + value_string = m_opaque_sp->GetValueAsCString (frame.get()); return value_string; } bool -SBValue::GetValueDidChange () +SBValue::GetValueDidChange (const SBFrame &frame) { if (IsValid()) - return m_opaque_sp->GetValueDidChange(); + return m_opaque_sp->GetValueDidChange (frame.get()); return false; } Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Wed Sep 1 21:59:18 2010 @@ -584,13 +584,12 @@ var_sp = global_var_list.GetVariableAtIndex(global_idx); if (var_sp) { - valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (m_options.globals[idx].AsCString()); + valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp); if (!valobj_sp) - valobj_sp.reset (new ValueObjectVariable (var_sp)); + valobj_sp = exe_ctx.frame->TrackGlobalVariable (var_sp); if (valobj_sp) { - exe_ctx.frame->GetValueObjectList().Append (valobj_sp); DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, m_options.ptr_depth, 0, m_options.max_depth, false); result.GetOutputStream().EOL(); } @@ -631,18 +630,7 @@ var_sp = variable_list.FindVariable(name_const_string); if (var_sp) { - //DumpVariable (result, &exe_ctx, var_sp.get()); - // TODO: redo history variables using a different map -// if (var_path[0] == '$') -// valobj_sp = valobj_list.FindValueObjectByValueObjectName (name_const_string.GetCString()); -// else - valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (name_const_string.GetCString()); - - if (!valobj_sp) - { - valobj_sp.reset (new ValueObjectVariable (var_sp)); - exe_ctx.frame->GetValueObjectList().Append (valobj_sp); - } + valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp); var_path.erase (0, name_const_string.GetLength ()); // We are dumping at least one child Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Wed Sep 1 21:59:18 2010 @@ -44,12 +44,16 @@ m_data (), m_value (), m_error (), - m_flags (), - m_value_str(), - m_location_str(), - m_summary_str(), - m_children(), - m_synthetic_children() + m_value_str (), + m_old_value_str (), + m_location_str (), + m_summary_str (), + m_children (), + m_synthetic_children (), + m_value_is_valid (false), + m_value_did_change (false), + m_children_count_valid (false), + m_old_value_valid (false) { } @@ -77,10 +81,19 @@ const user_id_t stop_id = process->GetStopID(); if (m_update_id != stop_id) { + bool first_update = m_update_id == 0; // Save the old value using swap to avoid a string copy which // also will clear our m_value_str - std::string old_value_str; - old_value_str.swap (m_value_str); + if (m_value_str.empty()) + { + m_old_value_valid = false; + } + else + { + m_old_value_valid = true; + m_old_value_str.swap (m_value_str); + m_value_str.clear(); + } m_location_str.clear(); m_summary_str.clear(); @@ -97,22 +110,14 @@ m_update_id = stop_id; bool success = m_error.Success(); SetValueIsValid (success); - // If the variable hasn't already been marked as changed do it - // by comparing the old any new value - if (!GetValueDidChange()) + + if (first_update) + SetValueDidChange (false); + else if (!m_value_did_change && success == false) { - if (success) - { - // The value was gotten successfully, so we consider the - // value as changed if the value string differs - SetValueDidChange (old_value_str != m_value_str); - } - else - { - // The value wasn't gotten successfully, so we mark this - // as changed if the value used to be valid and now isn't - SetValueDidChange (value_was_valid); - } + // The value wasn't gotten successfully, so we mark this + // as changed if the value used to be valid and now isn't + SetValueDidChange (value_was_valid); } } } @@ -202,31 +207,29 @@ } bool -ValueObject::GetValueIsValid () +ValueObject::GetValueIsValid () const { - return m_flags.IsSet(eValueIsValid); + return m_value_is_valid; } void ValueObject::SetValueIsValid (bool b) { - if (b) - m_flags.Set(eValueIsValid); - else - m_flags.Clear(eValueIsValid); + m_value_is_valid = b; } bool -ValueObject::GetValueDidChange () const +ValueObject::GetValueDidChange (ExecutionContextScope *exe_scope) { - return m_flags.IsSet(eValueChanged); + GetValueAsCString (exe_scope); + return m_value_did_change; } void ValueObject::SetValueDidChange (bool value_changed) { - m_flags.Set(eValueChanged); + m_value_did_change = value_changed; } ValueObjectSP @@ -301,7 +304,7 @@ uint32_t ValueObject::GetNumChildren () { - if (m_flags.IsClear(eNumChildrenHasBeenSet)) + if (!m_children_count_valid) { SetNumChildren (CalculateNumChildren()); } @@ -310,7 +313,7 @@ void ValueObject::SetNumChildren (uint32_t num_children) { - m_flags.Set(eNumChildrenHasBeenSet); + m_children_count_valid = true; m_children.resize(num_children); } @@ -552,6 +555,13 @@ break; } } + + if (!m_value_did_change && m_old_value_valid) + { + // The value was gotten successfully, so we consider the + // value as changed if the value string differs + SetValueDidChange (m_old_value_str != m_value_str); + } } } if (m_value_str.empty()) Modified: lldb/trunk/source/Core/ValueObjectList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectList.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectList.cpp (original) +++ lldb/trunk/source/Core/ValueObjectList.cpp Wed Sep 1 21:59:18 2010 @@ -57,6 +57,12 @@ return m_value_objects.size(); } +void +ValueObjectList::Resize (uint32_t size) +{ + m_value_objects.resize (size); +} + lldb::ValueObjectSP ValueObjectList::GetValueObjectAtIndex (uint32_t idx) { @@ -66,6 +72,14 @@ return valobj_sp; } +void +ValueObjectList::SetValueObjectAtIndex (uint32_t idx, const ValueObjectSP &valobj_sp) +{ + if (idx >= m_value_objects.size()) + m_value_objects.resize (idx + 1); + m_value_objects[idx] = valobj_sp; +} + ValueObjectSP ValueObjectList::FindValueObjectByValueName (const char *name) { @@ -74,7 +88,8 @@ collection::iterator pos, end = m_value_objects.end(); for (pos = m_value_objects.begin(); pos != end; ++pos) { - if ((*pos)->GetName() == name_const_str) + ValueObject *valobj = (*pos).get(); + if (valobj && valobj->GetName() == name_const_str) { val_obj_sp = *pos; break; @@ -91,7 +106,10 @@ for (pos = m_value_objects.begin(); pos != end; ++pos) { - if ((*pos)->GetID() == uid) + // Watch out for NULL objects in our list as the list + // might get resized to a specific size and lazily filled in + ValueObject *valobj = (*pos).get(); + if (valobj && valobj->GetID() == uid) { valobj_sp = *pos; break; @@ -102,14 +120,15 @@ ValueObjectSP -ValueObjectList::FindValueObjectByPointer (ValueObject *valobj) +ValueObjectList::FindValueObjectByPointer (ValueObject *find_valobj) { ValueObjectSP valobj_sp; collection::iterator pos, end = m_value_objects.end(); for (pos = m_value_objects.begin(); pos != end; ++pos) { - if ((*pos).get() == valobj) + ValueObject *valobj = (*pos).get(); + if (valobj && valobj == find_valobj) { valobj_sp = *pos; break; Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectVariable.cpp (original) +++ lldb/trunk/source/Core/ValueObjectVariable.cpp Wed Sep 1 21:59:18 2010 @@ -32,7 +32,7 @@ using namespace lldb_private; -ValueObjectVariable::ValueObjectVariable (lldb::VariableSP &var_sp) : +ValueObjectVariable::ValueObjectVariable (const lldb::VariableSP &var_sp) : ValueObject(), m_variable_sp(var_sp) { Modified: lldb/trunk/source/Symbol/VariableList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/VariableList.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/Symbol/VariableList.cpp (original) +++ lldb/trunk/source/Symbol/VariableList.cpp Wed Sep 1 21:59:18 2010 @@ -32,7 +32,7 @@ void -VariableList::AddVariable(VariableSP &variable_sp) +VariableList::AddVariable(const VariableSP &variable_sp) { m_variables.push_back(variable_sp); } @@ -82,6 +82,20 @@ return var_sp; } +uint32_t +VariableList::FindIndexForVariable (Variable* variable) +{ + VariableSP var_sp; + iterator pos; + const iterator begin = m_variables.begin(); + const iterator end = m_variables.end(); + for (pos = m_variables.begin(); pos != end; ++pos) + { + if ((*pos).get() == variable) + return std::distance (begin, pos); + } + return UINT32_MAX; +} size_t VariableList::MemorySize() const Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112800&r1=112799&r2=112800&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Wed Sep 1 21:59:18 2010 @@ -16,7 +16,9 @@ #include "lldb/Core/Module.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectVariable.h" #include "lldb/Symbol/Function.h" +#include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -55,7 +57,7 @@ m_frame_base (), m_frame_base_error (), m_variable_list_sp (), - m_value_object_list () + m_variable_list_value_objects () { if (sc_ptr != NULL) { @@ -85,7 +87,7 @@ m_frame_base (), m_frame_base_error (), m_variable_list_sp (), - m_value_object_list () + m_variable_list_value_objects () { if (sc_ptr != NULL) { @@ -121,7 +123,7 @@ m_frame_base (), m_frame_base_error (), m_variable_list_sp (), - m_value_object_list () + m_variable_list_value_objects () { if (sc_ptr != NULL) { @@ -450,18 +452,31 @@ VariableList * -StackFrame::GetVariableList () +StackFrame::GetVariableList (bool get_file_globals) { if (m_flags.IsClear(RESOLVED_VARIABLES)) { m_flags.Set(RESOLVED_VARIABLES); - if (GetSymbolContext (eSymbolContextFunction).function) + GetSymbolContext (eSymbolContextCompUnit | + eSymbolContextFunction | + eSymbolContextBlock); + + if (m_sc.block) { bool get_child_variables = true; bool can_create = true; m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create); } + + if (get_file_globals && m_sc.comp_unit) + { + VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); + if (m_variable_list_sp) + m_variable_list_sp->AddVariables (global_variable_list_sp.get()); + else + m_variable_list_sp = global_variable_list_sp; + } } return m_variable_list_sp.get(); } @@ -521,10 +536,52 @@ return m_sc.line_entry.IsValid(); } -ValueObjectList & -StackFrame::GetValueObjectList() + +ValueObjectSP +StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) { - return m_value_object_list; + ValueObjectSP valobj_sp; + VariableList *var_list = GetVariableList (true); + if (var_list) + { + // Make sure the variable is a frame variable + const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); + const uint32_t num_variables = var_list->GetSize(); + if (var_idx < num_variables) + { + valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); + if (valobj_sp.get() == NULL) + { + if (m_variable_list_value_objects.GetSize() < num_variables) + m_variable_list_value_objects.Resize(num_variables); + valobj_sp.reset (new ValueObjectVariable (variable_sp)); + m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); + } + } + } + return valobj_sp; +} + +ValueObjectSP +StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) +{ + // Check to make sure we aren't already tracking this variable? + ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp)); + if (!valobj_sp) + { + // We aren't already tracking this global + VariableList *var_list = GetVariableList (true); + // If this frame has no variables, create a new list + if (var_list == NULL) + m_variable_list_sp.reset (new VariableList()); + + // Add the global/static variable to this frame + m_variable_list_sp->AddVariable (variable_sp); + + // Now make a value object for it so we can track its changes + valobj_sp = GetValueObjectForFrameVariable (variable_sp); + } + return valobj_sp; } bool @@ -591,7 +648,7 @@ { assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing m_variable_list_sp = prev_frame.m_variable_list_sp; - m_value_object_list.Swap (prev_frame.m_value_object_list); + m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); if (!m_disassembly.GetString().empty()) m_disassembly.GetString().swap (m_disassembly.GetString()); } @@ -610,7 +667,6 @@ assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); - assert (m_sc.symbol == NULL || curr_frame.m_sc.symbol == NULL || m_sc.symbol == curr_frame.m_sc.symbol); m_sc = curr_frame.m_sc; m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); m_flags.Set (m_sc.GetResolvedMask()); From johnny.chen at apple.com Thu Sep 2 10:59:20 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 02 Sep 2010 15:59:20 -0000 Subject: [Lldb-commits] [lldb] r112824 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py class_types/TestClassTypes.py function_types/TestFunctionTypes.py global_variables/TestGlobalVariables.py hello_world/TestHelloWorld.py set_values/TestSetValues.py unsigned_types/TestUnsignedTypes.py Message-ID: <20100902155920.D46F72A6C12C@llvm.org> Author: johnny Date: Thu Sep 2 10:59:20 2010 New Revision: 112824 URL: http://llvm.org/viewvc/llvm-project?rev=112824&view=rev Log: (query-replace "variable list" "frame variable") Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/set_values/TestSetValues.py lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Sep 2 10:59:20 2010 @@ -11,7 +11,7 @@ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_run_command(self): - """Test 'variable list var_name' on some variables with array types.""" + """Test 'frame variable var_name' on some variables with array types.""" self.buildDsym() self.array_types() @@ -22,7 +22,7 @@ self.array_types_python() def test_with_dwarf_and_run_command(self): - """Test 'variable list var_name' on some variables with array types.""" + """Test 'frame variable var_name' on some variables with array types.""" self.buildDwarf() self.array_types() @@ -32,7 +32,7 @@ self.array_types_python() def array_types(self): - """Test 'variable list var_name' on some variables with array types.""" + """Test 'frame variable var_name' on some variables with array types.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -53,7 +53,7 @@ # Issue 'variable list' command on several array-type variables. - self.expect("variable list strings", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable strings", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(char *[4])', substrs = ['(char *) strings[0]', '(char *) strings[1]', @@ -64,14 +64,14 @@ 'Bonjour', 'Guten Tag']) - self.expect("variable list char_16", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable char_16", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(char) char_16[0]', '(char) char_16[15]']) - self.expect("variable list ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(unsigned short [2][3])') - self.expect("variable list long_6", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable long_6", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(long [6])') def array_types_python(self): Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Thu Sep 2 10:59:20 2010 @@ -12,7 +12,7 @@ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @unittest2.expectedFailure def test_with_dsym_and_run_command(self): - """Test 'variable list ...' on a variable with bitfields.""" + """Test 'frame variable ...' on a variable with bitfields.""" self.buildDsym() self.bitfields_variable() @@ -24,7 +24,7 @@ @unittest2.expectedFailure def test_with_dwarf_and_run_command(self): - """Test 'variable list ...' on a variable with bitfields.""" + """Test 'frame variable ...' on a variable with bitfields.""" self.buildDwarf() self.bitfields_variable() @@ -34,7 +34,7 @@ self.bitfields_variable_python() def bitfields_variable(self): - """Test 'variable list ...' on a variable with bitfields.""" + """Test 'frame variable ...' on a variable with bitfields.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -54,7 +54,7 @@ substrs = [' resolved, hit count = 1']) # This should display correctly. - self.expect("variable list bits", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable bits", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(uint32_t:1) b1 = 0x00000001,', '(uint32_t:2) b2 = 0x00000003,', '(uint32_t:3) b3 = 0x00000007,', @@ -66,7 +66,7 @@ # And so should this. # rdar://problem/8348251 - self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(uint32_t:1) b1 = 0x00000001,', '(uint32_t:2) b2 = 0x00000003,', '(uint32_t:3) b3 = 0x00000007,', Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Thu Sep 2 10:59:20 2010 @@ -11,7 +11,7 @@ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_run_command(self): - """Test 'variable list this' when stopped on a class constructor.""" + """Test 'frame variable this' when stopped on a class constructor.""" self.buildDsym() self.class_types() @@ -22,11 +22,11 @@ self.breakpoint_creation_by_filespec_python() # rdar://problem/8378863 - # "variable list this" returns + # "frame variable this" returns # error: unable to find any variables named 'this' @unittest2.expectedFailure def test_with_dwarf_and_run_command(self): - """Test 'variable list this' when stopped on a class constructor.""" + """Test 'frame variable this' when stopped on a class constructor.""" self.buildDwarf() self.class_types() @@ -36,7 +36,7 @@ self.breakpoint_creation_by_filespec_python() def class_types(self): - """Test 'variable list this' when stopped on a class constructor.""" + """Test 'frame variable this' when stopped on a class constructor.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -56,7 +56,7 @@ substrs = [' resolved, hit count = 1']) # We should be stopped on the ctor function of class C. - self.expect("variable list this", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable this", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(class C *const) this = ') def breakpoint_creation_by_filespec_python(self): Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Thu Sep 2 10:59:20 2010 @@ -30,7 +30,7 @@ substrs = [' resolved, hit count = 1']) # Check that the 'callback' variable display properly. - self.expect("variable list callback", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable callback", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(int (*)(char const *)) callback =') # And that we can break on the callback function. Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Thu Sep 2 10:59:20 2010 @@ -10,7 +10,7 @@ mydir = "global_variables" def test_global_variables(self): - """Test 'variable list -s -a' which omits args and shows scopes.""" + """Test 'frame variable -s -a' which omits args and shows scopes.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -30,7 +30,7 @@ substrs = [' resolved, hit count = 1']) # Check that GLOBAL scopes are indicated for the variables. - self.expect("variable list -s -a", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -s -a", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['GLOBAL: g_file_static_cstr', '"g_file_static_cstr"', 'GLOBAL: g_file_global_int', Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Thu Sep 2 10:59:20 2010 @@ -18,7 +18,7 @@ self.buildDsym() self.hello_world_python(useLaunchAPI = False) - #@unittest2.expectedFailure + @unittest2.expectedFailure def test_with_dwarf_and_process_launch_api(self): """Create target, breakpoint, launch a process, and then kill it. Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Thu Sep 2 10:59:20 2010 @@ -42,8 +42,8 @@ substrs = [' resolved, hit count = 1']) # main.c:15 - # Check that 'variable list' displays the correct data type and value. - self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable' displays the correct data type and value. + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, startstr = "i = (char) 'a'") # TODO: @@ -52,8 +52,8 @@ self.runCmd("continue") # main.c:36 - # Check that 'variable list' displays the correct data type and value. - self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable' displays the correct data type and value. + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, startstr = "i = (short unsigned int) 0x0021") # TODO: @@ -62,8 +62,8 @@ self.runCmd("continue") # main.c:57 - # Check that 'variable list' displays the correct data type and value. - self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable' displays the correct data type and value. + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, startstr = "i = (long int) 33") # TODO: @@ -72,8 +72,8 @@ self.runCmd("continue") # main.c:78 - # Check that 'variable list' displays the correct data type and value. - self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable' displays the correct data type and value. + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, startstr = "i = (double) 3.14159") # TODO: @@ -82,8 +82,8 @@ self.runCmd("continue") # main.c:85 - # Check that 'variable list' displays the correct data type and value. - self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable' displays the correct data type and value. + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, startstr = "i = (long double) ") # TODO: Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=112824&r1=112823&r2=112824&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Thu Sep 2 10:59:20 2010 @@ -32,7 +32,7 @@ substrs = [' resolved, hit count = 1']) # Test that unsigned types display correctly. - self.expect("variable list -a", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -a", VARIABLES_DISPLAYED_CORRECTLY, startstr = "the_unsigned_char = (unsigned char) 'c'", substrs = ["the_unsigned_short = (short unsigned int) 0x0063", "the_unsigned_int = (unsigned int) 0x00000063", From johnny.chen at apple.com Thu Sep 2 16:23:13 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 02 Sep 2010 21:23:13 -0000 Subject: [Lldb-commits] [lldb] r112863 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py hello_world/TestHelloWorld.py lldbtest.py Message-ID: <20100902212313.2334B2A6C12C@llvm.org> Author: johnny Date: Thu Sep 2 16:23:12 2010 New Revision: 112863 URL: http://llvm.org/viewvc/llvm-project?rev=112863&view=rev Log: Moved the process cleanup of Script-Bridge-based APIs into TestBase.tearDown() method where they belong. Also fixed a logic error in maintaining the command interface flag (runStarted) indicating whether the lldb "run"/"process launch" command has been issued. It was erroneously cleared. Modified the test cases to take advantage of the refactoring. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112863&r1=112862&r2=112863&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Sep 2 16:23:12 2010 @@ -88,8 +88,11 @@ # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) + self.process = target.GetProcess() + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + # The stop reason of the thread should be breakpoint. - thread = target.GetProcess().GetThreadAtIndex(0) + thread = self.process.GetThreadAtIndex(0) self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), STOPPED_DUE_TO_BREAKPOINT) @@ -138,10 +141,6 @@ self.assertTrue(long(child5.GetValue(frame)) == 6, "long_6[5] == 6") - # Now kill the process, and we are done. - rc = target.GetProcess().Kill() - self.assertTrue(rc.Success()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112863&r1=112862&r2=112863&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Thu Sep 2 16:23:12 2010 @@ -90,6 +90,9 @@ # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) + self.process = target.GetProcess() + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + # The stop reason of the thread should be breakpoint. thread = target.GetProcess().GetThreadAtIndex(0) self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112863&r1=112862&r2=112863&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Thu Sep 2 16:23:12 2010 @@ -64,19 +64,16 @@ #self.runCmd("breakpoint list") #self.runCmd("thread list") - process = target.GetProcess() - thread = process.GetThreadAtIndex(0) + self.process = target.GetProcess() + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + thread = self.process.GetThreadAtIndex(0) self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) - # Now kill the process, and we are done. - rc = process.Kill() - self.assertTrue(rc.Success()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112863&r1=112862&r2=112863&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Sep 2 16:23:12 2010 @@ -124,6 +124,10 @@ CURRENT_EXECUTABLE_SET = "Current executable set successfully" +PROCESS_IS_VALID = "Process is valid" + +PROCESS_KILLED = "Process is killed successfully" + RUN_SUCCEEDED = "Process is launched successfully" RUN_COMPLETED = "Process exited successfully" @@ -305,6 +309,9 @@ # We want our debugger to be synchronous. self.dbg.SetAsync(False) + # There is no process associated with the debugger as yet. + self.process = None + # Retrieve the associated command interpreter instance. self.ci = self.dbg.GetCommandInterpreter() if not self.ci: @@ -314,9 +321,15 @@ self.res = lldb.SBCommandReturnObject() def tearDown(self): - # Terminate the current process being debugged. + #import traceback + #traceback.print_stack() + + # Terminate the current process being debugged, if any. if self.runStarted: - self.ci.HandleCommand("process kill", self.res) + self.runCmd("process kill", PROCESS_KILLED, check=False) + elif self.process and self.process.IsValid(): + rc = self.process.Kill() + self.assertTrue(rc.Success(), PROCESS_KILLED) del self.dbg @@ -353,7 +366,9 @@ # Process launch failed, wait some time before the next try. time.sleep(self.timeWait) - self.runStarted = running and setCookie + # Modify runStarted only if "run" or "process launch" was encountered. + if running: + self.runStarted = running and setCookie if check: self.assertTrue(self.res.Succeeded(), From gclayton at apple.com Thu Sep 2 16:44:10 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 02 Sep 2010 21:44:10 -0000 Subject: [Lldb-commits] [lldb] r112867 - in /lldb/trunk: include/lldb/Symbol/ include/lldb/Target/ source/API/ source/Breakpoint/ source/Commands/ source/Core/ source/Symbol/ source/Target/ Message-ID: <20100902214411.1E8A62A6C12C@llvm.org> Author: gclayton Date: Thu Sep 2 16:44:10 2010 New Revision: 112867 URL: http://llvm.org/viewvc/llvm-project?rev=112867&view=rev Log: Added a new bool parameter to many of the DumpStopContext() methods that might dump file paths that allows the dumping of full paths or just the basenames. Switched the stack frame dumping code to use just the basenames for the files instead of the full path. Modified the StackID class to no rely on needing the start PC for the current function/symbol since we can use the SymbolContextScope to uniquely identify that, unless there is no symbol context scope. In that case we can rely upon the current PC value. This saves the StackID from having to calculate the start PC when the StackFrame::GetStackID() accessor is called. Also improved the StackID less than operator to correctly handle inlined stack frames in the same stack. Modified: lldb/trunk/include/lldb/Symbol/Block.h lldb/trunk/include/lldb/Symbol/Declaration.h lldb/trunk/include/lldb/Symbol/LineEntry.h lldb/trunk/include/lldb/Symbol/SymbolContext.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackID.h lldb/trunk/source/API/SBThread.cpp lldb/trunk/source/Breakpoint/BreakpointLocation.cpp lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Commands/CommandObjectImage.cpp lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Core/Address.cpp lldb/trunk/source/Core/Disassembler.cpp lldb/trunk/source/Symbol/Block.cpp lldb/trunk/source/Symbol/Declaration.cpp lldb/trunk/source/Symbol/LineEntry.cpp lldb/trunk/source/Symbol/SymbolContext.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/StackID.cpp lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Symbol/Block.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Block.h?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Block.h (original) +++ lldb/trunk/include/lldb/Symbol/Block.h Thu Sep 2 16:44:10 2010 @@ -133,6 +133,9 @@ bool Contains (const VMRange& range) const; + bool + Contains (const Block *block) const; + //------------------------------------------------------------------ /// Dump the block contents. /// @@ -156,7 +159,7 @@ Dump (Stream *s, lldb::addr_t base_addr, int32_t depth, bool show_context) const; void - DumpStopContext (Stream *s, const SymbolContext *sc); + DumpStopContext (Stream *s, const SymbolContext *sc, bool show_fullpaths); //------------------------------------------------------------------ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) Modified: lldb/trunk/include/lldb/Symbol/Declaration.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Declaration.h?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Declaration.h (original) +++ lldb/trunk/include/lldb/Symbol/Declaration.h Thu Sep 2 16:44:10 2010 @@ -103,7 +103,7 @@ Dump (Stream *s) const; void - DumpStopContext (Stream *s) const; + DumpStopContext (Stream *s, bool show_fullpaths) const; //------------------------------------------------------------------ /// Get accessor for the declaration column number. /// Modified: lldb/trunk/include/lldb/Symbol/LineEntry.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/LineEntry.h?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/LineEntry.h (original) +++ lldb/trunk/include/lldb/Symbol/LineEntry.h Thu Sep 2 16:44:10 2010 @@ -110,7 +110,7 @@ /// \b false otherwise. //------------------------------------------------------------------ bool - DumpStopContext (Stream *s) const; + DumpStopContext (Stream *s, bool show_fullpaths) const; //------------------------------------------------------------------ /// Check if a line entry object is valid. Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Thu Sep 2 16:44:10 2010 @@ -163,6 +163,7 @@ DumpStopContext (Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, + bool show_fullpaths, bool show_module, bool show_inlined_frames) const; Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Thu Sep 2 16:44:10 2010 @@ -100,7 +100,7 @@ Disassemble (); void - Dump (Stream *strm, bool show_frame_index); + Dump (Stream *strm, bool show_frame_index, bool show_fullpaths); bool IsInlined (); Modified: lldb/trunk/include/lldb/Target/StackID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackID.h (original) +++ lldb/trunk/include/lldb/Target/StackID.h Thu Sep 2 16:44:10 2010 @@ -26,22 +26,22 @@ // Constructors and Destructors //------------------------------------------------------------------ StackID () : - m_start_pc (LLDB_INVALID_ADDRESS), + m_pc (LLDB_INVALID_ADDRESS), m_cfa (LLDB_INVALID_ADDRESS), m_symbol_scope (NULL) { } explicit - StackID (lldb::addr_t start_pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) : - m_start_pc (start_pc), + StackID (lldb::addr_t pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) : + m_pc (pc), m_cfa (cfa), m_symbol_scope (symbol_scope) { } StackID (const StackID& rhs) : - m_start_pc (rhs.m_start_pc), + m_pc (rhs.m_pc), m_cfa (rhs.m_cfa), m_symbol_scope (rhs.m_symbol_scope) { @@ -52,15 +52,9 @@ } const lldb::addr_t - GetStartAddress() const + GetPC() const { - return m_start_pc; - } - - void - SetStartAddress(lldb::addr_t start_pc) - { - m_start_pc = start_pc; + return m_pc; } lldb::addr_t @@ -92,7 +86,7 @@ { if (this != &rhs) { - m_start_pc = rhs.m_start_pc; + m_pc = rhs.m_pc; m_cfa = rhs.m_cfa; m_symbol_scope = rhs.m_symbol_scope; } @@ -103,7 +97,10 @@ //------------------------------------------------------------------ // Classes that inherit from StackID can see and modify these //------------------------------------------------------------------ - lldb::addr_t m_start_pc; // The start address for the function/symbol for this frame + lldb::addr_t m_pc; // The pc value for the function/symbol for this frame. This will + // only get used if the symbol scope is NULL (the code where we are + // stopped is not represented by any function or symbol in any + // shared library). lldb::addr_t m_cfa; // The call frame address (stack pointer) value // at the beginning of the function that uniquely // identifies this frame (along with m_symbol_scope below) Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Thu Sep 2 16:44:10 2010 @@ -288,7 +288,7 @@ frame_idx, GetThreadID(), (long long)pc); - sc->DumpStopContext (&str, &m_opaque_sp->GetProcess(), *frame.GetPCAddress(), true, false); + sc->DumpStopContext (&str, &m_opaque_sp->GetProcess(), *frame.GetPCAddress(), false, true, false); fprintf (out, "\n"); success = true; } Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original) +++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Thu Sep 2 16:44:10 2010 @@ -285,7 +285,7 @@ if (level == lldb::eDescriptionLevelFull) { s->PutCString("where = "); - sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, true, false); + sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, true, true, false); } else { @@ -313,7 +313,7 @@ { s->EOL(); s->Indent("location = "); - sc.line_entry.DumpStopContext (s); + sc.line_entry.DumpStopContext (s, true); } } Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Thu Sep 2 16:44:10 2010 @@ -71,7 +71,7 @@ ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); if (exe_ctx.frame) { - exe_ctx.frame->Dump (&result.GetOutputStream(), true); + exe_ctx.frame->Dump (&result.GetOutputStream(), true, false); result.GetOutputStream().EOL(); result.SetStatus (eReturnStatusSuccessFinishResult); } Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectImage.cpp Thu Sep 2 16:44:10 2010 @@ -341,7 +341,7 @@ strm.PutCString(" in "); } } - sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, false); + sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false); } } strm.IndentLess (); Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Sep 2 16:44:10 2010 @@ -224,7 +224,7 @@ if (show_frame_info) { strm.Indent(); - frame->Dump (&strm, true); + frame->Dump (&strm, true, false); strm.EOL(); } Modified: lldb/trunk/source/Core/Address.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Core/Address.cpp (original) +++ lldb/trunk/source/Core/Address.cpp Thu Sep 2 16:44:10 2010 @@ -503,7 +503,7 @@ #endif Address cstr_addr(*this); cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size); - func_sc.DumpStopContext(s, exe_scope, so_addr, true, false); + func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false); if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr)) { #if VERBOSE_OUTPUT @@ -586,7 +586,7 @@ if (pointer_sc.function || pointer_sc.symbol) { s->PutCString(": "); - pointer_sc.DumpStopContext(s, exe_scope, so_addr, false, false); + pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false); } } } @@ -625,7 +625,7 @@ { // We have a function or a symbol from the same // sections as this address. - sc.DumpStopContext(s, exe_scope, *this, show_module, false); + sc.DumpStopContext(s, exe_scope, *this, true, show_module, false); } else { Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Thu Sep 2 16:44:10 2010 @@ -238,7 +238,7 @@ if (offset != 0) strm.EOL(); - sc.DumpStopContext(&strm, process, addr, true, false); + sc.DumpStopContext(&strm, process, addr, true, true, false); if (sc.comp_unit && sc.line_entry.IsValid()) { Modified: lldb/trunk/source/Symbol/Block.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Block.cpp (original) +++ lldb/trunk/source/Symbol/Block.cpp Thu Sep 2 16:44:10 2010 @@ -145,7 +145,7 @@ } void -Block::DumpStopContext (Stream *s, const SymbolContext *sc) +Block::DumpStopContext (Stream *s, const SymbolContext *sc, bool show_fullpaths) { Block* parent_block = GetParent(); @@ -170,7 +170,7 @@ if (call_site.IsValid()) { s->PutCString(" at "); - call_site.DumpStopContext (s); + call_site.DumpStopContext (s, show_fullpaths); } } } @@ -182,11 +182,11 @@ if (sc->line_entry.IsValid()) { s->PutCString(" at "); - sc->line_entry.DumpStopContext (s); + sc->line_entry.DumpStopContext (s, show_fullpaths); } } if (parent_block) - parent_block->Block::DumpStopContext (s, NULL); + parent_block->Block::DumpStopContext (s, NULL, show_fullpaths); } @@ -207,6 +207,24 @@ } bool +Block::Contains (const Block *block) const +{ + // Block objects can't contain themselves... + if (this == block) + return false; + + const Block *block_parent; + for (block_parent = block->GetParent(); + block_parent != NULL; + block_parent = block_parent->GetParent()) + { + if (block_parent == block) + return true; + } + return false; +} + +bool Block::Contains (const VMRange& range) const { return VMRange::ContainsRange(m_ranges, range); Modified: lldb/trunk/source/Symbol/Declaration.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Declaration.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Declaration.cpp (original) +++ lldb/trunk/source/Symbol/Declaration.cpp Thu Sep 2 16:44:10 2010 @@ -81,11 +81,11 @@ } void -Declaration::DumpStopContext (Stream *s) const +Declaration::DumpStopContext (Stream *s, bool show_fullpaths) const { if (m_file) { - if (s->GetVerbose()) + if (show_fullpaths || s->GetVerbose()) *s << m_file; else m_file.GetFilename().Dump(s); Modified: lldb/trunk/source/Symbol/LineEntry.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/LineEntry.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Symbol/LineEntry.cpp (original) +++ lldb/trunk/source/Symbol/LineEntry.cpp Thu Sep 2 16:44:10 2010 @@ -74,12 +74,16 @@ } bool -LineEntry::DumpStopContext(Stream *s) const +LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const { bool result = false; if (file) { - file.Dump (s); + if (show_fullpaths) + file.Dump (s); + else + file.GetFilename().Dump (s); + if (line) s->PutChar(':'); result = true; Modified: lldb/trunk/source/Symbol/SymbolContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolContext.cpp (original) +++ lldb/trunk/source/Symbol/SymbolContext.cpp Thu Sep 2 16:44:10 2010 @@ -114,13 +114,18 @@ Stream *s, ExecutionContextScope *exe_scope, const Address &addr, + bool show_fullpaths, bool show_module, bool show_inlined_frames ) const { if (show_module && module_sp) { - *s << module_sp->GetFileSpec().GetFilename() << '`'; + if (show_fullpaths) + *s << module_sp->GetFileSpec(); + else + *s << module_sp->GetFileSpec().GetFilename(); + s->PutChar('`'); } if (function != NULL) @@ -128,7 +133,6 @@ if (function->GetMangled().GetName()) function->GetMangled().GetName().Dump(s); - if (show_inlined_frames && block) { const InlineFunctionInfo *inline_info = block->InlinedFunctionInfo(); @@ -147,7 +151,7 @@ if (line_entry.IsValid()) { s->PutCString(" at "); - line_entry.DumpStopContext(s); + line_entry.DumpStopContext(s, show_fullpaths); } return; } @@ -159,7 +163,7 @@ if (block != NULL) { s->IndentMore(); - block->DumpStopContext(s, this); + block->DumpStopContext(s, this, show_fullpaths); s->IndentLess(); } else @@ -167,7 +171,7 @@ if (line_entry.IsValid()) { s->PutCString(" at "); - if (line_entry.DumpStopContext(s)) + if (line_entry.DumpStopContext(s, show_fullpaths)) return; } } Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Thu Sep 2 16:44:10 2010 @@ -32,8 +32,7 @@ // so we know if we have tried to look up information in our internal symbol // context (m_sc) already. #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) -#define RESOLVED_FRAME_ID_START_ADDR (RESOLVED_FRAME_CODE_ADDR << 1) -#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_ID_START_ADDR << 1) +#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) @@ -50,7 +49,7 @@ m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (), - m_id (LLDB_INVALID_ADDRESS, cfa, NULL), + m_id (pc, cfa, NULL), m_frame_code_addr (NULL, pc), m_sc (), m_flags (), @@ -80,7 +79,7 @@ m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (LLDB_INVALID_ADDRESS, cfa, NULL), + m_id (pc, cfa, NULL), m_frame_code_addr (NULL, pc), m_sc (), m_flags (), @@ -116,7 +115,7 @@ m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (LLDB_INVALID_ADDRESS, cfa, NULL), + m_id (pc_addr.GetLoadAddress (&thread.GetProcess()), cfa, NULL), m_frame_code_addr (pc_addr), m_sc (), m_flags (), @@ -159,42 +158,12 @@ StackID& StackFrame::GetStackID() { - // Make sure we have resolved our stack ID's start PC before we give - // it out to any external clients. This allows us to not have to lookup - // this information if it is never asked for. - if (m_flags.IsClear(RESOLVED_FRAME_ID_START_ADDR)) - { - m_flags.Set (RESOLVED_FRAME_ID_START_ADDR); - - if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) - { - // Resolve our PC to section offset if we haven't alreday done so - // and if we don't have a module. The resolved address section will - // contain the module to which it belongs. - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) - GetFrameCodeAddress(); + // Make sure we have resolved the StackID object's symbol context scope if + // we already haven't looked it up. - if (GetSymbolContext (eSymbolContextFunction).function) - { - m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); - } - else if (GetSymbolContext (eSymbolContextSymbol).symbol) - { - AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); - if (symbol_range_ptr) - m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); - } - - // We didn't find a function or symbol, just use the frame code address - // which will be the same as the PC in the frame. - if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) - m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); - } - } - if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) { - if (m_id.GetSymbolContextScope ()) + if (m_id.GetSymbolContextScope () == NULL) { m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); } @@ -627,20 +596,18 @@ } void -StackFrame::Dump (Stream *strm, bool show_frame_index) +StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) { if (strm == NULL) return; if (show_frame_index) strm->Printf("frame #%u: ", m_frame_index); - strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); + strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); GetSymbolContext(eSymbolContextEverything); - strm->PutCString(", where = "); - // TODO: need to get the const bool show_module = true; const bool show_inline = true; - m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline); + m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline); } void Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Thu Sep 2 16:44:10 2010 @@ -256,7 +256,7 @@ if (frame) { frame->GetStackID().Dump (s); - frame->Dump(s, true); + frame->Dump(s, true, false); } else s->Printf("frame #%u", std::distance (begin, pos)); Modified: lldb/trunk/source/Target/StackID.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackID.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Target/StackID.cpp (original) +++ lldb/trunk/source/Target/StackID.cpp Thu Sep 2 16:44:10 2010 @@ -24,7 +24,7 @@ void StackID::Dump (Stream *s) { - s->Printf("StackID (start_pc = 0x%16.16llx, cfa = 0x%16.16llx, symbol_scope = %p", (uint64_t)m_start_pc, (uint64_t)m_cfa, m_symbol_scope); + s->Printf("StackID (pc = 0x%16.16llx, cfa = 0x%16.16llx, symbol_scope = %p", (uint64_t)m_pc, (uint64_t)m_cfa, m_symbol_scope); if (m_symbol_scope) { SymbolContext sc; @@ -41,21 +41,64 @@ bool lldb_private::operator== (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && - lhs.GetSymbolContextScope() == rhs.GetSymbolContextScope() && - lhs.GetStartAddress() == rhs.GetStartAddress(); + if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress()) + return false; + + SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); + SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); + + // Only compare the PC values if both symbol context scopes are NULL + if (lhs_scope == NULL && rhs_scope == NULL) + return lhs.GetPC() == rhs.GetPC(); + + return lhs_scope == rhs_scope; } bool lldb_private::operator!= (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || - lhs.GetSymbolContextScope() != rhs.GetSymbolContextScope() || - lhs.GetStartAddress() != rhs.GetStartAddress(); + if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress()) + return true; + + SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); + SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); + + if (lhs_scope == NULL && rhs_scope == NULL) + return lhs.GetPC() != rhs.GetPC(); + + return lhs_scope != rhs_scope; } bool lldb_private::operator< (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress(); + const lldb::addr_t lhs_cfa = lhs.GetCallFrameAddress(); + const lldb::addr_t rhs_cfa = rhs.GetCallFrameAddress(); + + if (lhs_cfa != rhs_cfa) + return lhs_cfa < rhs_cfa; + + SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); + SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); + + if (lhs_scope != NULL && rhs_scope != NULL) + { + // Same exact scope, lhs is not less than (younger than rhs) + if (lhs_scope == rhs_scope) + return false; + + SymbolContext lhs_sc; + SymbolContext rhs_sc; + lhs_scope->CalculateSymbolContext (&lhs_sc); + rhs_scope->CalculateSymbolContext (&rhs_sc); + + // Items with the same function can only be compared + if (lhs_sc.function == rhs_sc.function && + lhs_sc.function != NULL && lhs_sc.block != NULL && + rhs_sc.function != NULL && rhs_sc.block != NULL) + { + return rhs_sc.block->Contains (lhs_sc.block); + } + } + return false; } Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=112867&r1=112866&r2=112867&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Thu Sep 2 16:44:10 2010 @@ -820,7 +820,7 @@ lldb::StackFrameSP Thread::GetStackFrameAtIndex (uint32_t idx) { - return StackFrameSP (GetStackFrameList().GetFrameAtIndex(idx)); + return GetStackFrameList().GetFrameAtIndex(idx); } lldb::StackFrameSP @@ -859,7 +859,7 @@ if (frame_sp) { strm.PutCString(", "); - frame_sp->Dump (&strm, false); + frame_sp->Dump (&strm, false, false); } } From johnny.chen at apple.com Thu Sep 2 17:25:47 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 02 Sep 2010 22:25:47 -0000 Subject: [Lldb-commits] [lldb] r112880 - in /lldb/trunk/test: dead-strip/TestDeadStrip.py function_types/TestFunctionTypes.py lldbtest.py Message-ID: <20100902222547.6ECFF2A6C12C@llvm.org> Author: johnny Date: Thu Sep 2 17:25:47 2010 New Revision: 112880 URL: http://llvm.org/viewvc/llvm-project?rev=112880&view=rev Log: Added comments regarding the two mechanisms of process cleanup to lldbtest.py. Also changed the expected strings to be matched since "thread list" changed its output format. Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=112880&r1=112879&r2=112880&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Thu Sep 2 17:25:47 2010 @@ -45,7 +45,7 @@ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['state is Stopped', 'main.c:20', - 'where = a.out`f1', + 'a.out`f1', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. @@ -58,7 +58,7 @@ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['state is Stopped', 'main.c:40', - 'where = a.out`f3', + 'a.out`f3', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=112880&r1=112879&r2=112880&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Thu Sep 2 17:25:47 2010 @@ -39,7 +39,7 @@ # Check that we do indeed stop on the string_not_empty function. self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, - substrs = ['where = a.out`string_not_empty', + substrs = ['a.out`string_not_empty', 'main.c:12', 'stop reason = breakpoint']) Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112880&r1=112879&r2=112880&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Sep 2 17:25:47 2010 @@ -25,9 +25,8 @@ OK $ LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py -LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py -runCmd: file /Volumes/data/lldb/svn/trunk/test/array_types/a.out -output: Current executable set to '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64). + +... runCmd: breakpoint set -f main.c -l 42 output: Breakpoint created: 1: file ='main.c', line = 42, locations = 1 @@ -35,17 +34,9 @@ runCmd: run output: Launching '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64) -runCmd: thread list -output: Process 24987 state is Stopped - thread #1: tid = 0x2e03, pc = 0x0000000100000df4, where = a.out`main + 612 at /Volumes/data/lldb/svn/trunk/test/array_types/main.c:45, stop reason = breakpoint 1.1, queue = com.apple.main-thread - -runCmd: breakpoint list -output: Current breakpoints: -1: file ='main.c', line = 42, locations = 1, resolved = 1 - 1.1: where = a.out`main + 612 at /Volumes/data/lldb/svn/trunk/test/array_types/main.c:45, address = 0x0000000100000df4, resolved, hit count = 1 - +... -runCmd: variable list strings +runCmd: frame variable strings output: (char *[4]) strings = { (char *) strings[0] = 0x0000000100000f0c "Hello", (char *) strings[1] = 0x0000000100000f12 "Hola", @@ -53,7 +44,7 @@ (char *) strings[3] = 0x0000000100000f1f "Guten Tag" } -runCmd: variable list char_16 +runCmd: frame variable char_16 output: (char [16]) char_16 = { (char) char_16[0] = 'H', (char) char_16[1] = 'e', @@ -73,7 +64,7 @@ (char) char_16[15] = '\0' } -runCmd: variable list ushort_matrix +runCmd: frame variable ushort_matrix output: (unsigned short [2][3]) ushort_matrix = { (unsigned short [3]) ushort_matrix[0] = { (unsigned short) ushort_matrix[0][0] = 0x0001, @@ -87,7 +78,7 @@ } } -runCmd: variable list long_6 +runCmd: frame variable long_6 output: (long [6]) long_6 = { (long) long_6[0] = 1, (long) long_6[1] = 2, @@ -266,6 +257,9 @@ mydir = None # State pertaining to the inferior process, if any. + # This reflects inferior process started through the command interface with + # either the lldb "run" or "process launch" command. + # See also self.runCmd(). runStarted = False # Maximum allowed attempts when launching the inferior process. @@ -310,6 +304,8 @@ self.dbg.SetAsync(False) # There is no process associated with the debugger as yet. + # See also self.tearDown() where it checks whether self.process has a + # valid reference and calls self.process.Kill() to kill the process. self.process = None # Retrieve the associated command interpreter instance. From gclayton at apple.com Fri Sep 3 12:10:42 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 03 Sep 2010 17:10:42 -0000 Subject: [Lldb-commits] [lldb] r112973 - in /lldb/trunk: include/lldb/ include/lldb/Target/ source/ source/Breakpoint/ source/Plugins/Process/gdb-remote/ source/Target/ Message-ID: <20100903171042.D8BE02A6C12C@llvm.org> Author: gclayton Date: Fri Sep 3 12:10:42 2010 New Revision: 112973 URL: http://llvm.org/viewvc/llvm-project?rev=112973&view=rev Log: Fixed the StackFrame to correctly resolve the StackID's SymbolContextScope. Added extra logging for stepping. Fixed an issue where cached stack frame data could be lost between runs when the thread plans read a stack frame. Modified: lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackFrameList.h lldb/trunk/include/lldb/Target/StackID.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/include/lldb/Target/ThreadList.h lldb/trunk/include/lldb/lldb-private.h lldb/trunk/source/Breakpoint/BreakpointLocation.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/Thread.cpp lldb/trunk/source/Target/ThreadList.cpp lldb/trunk/source/Target/ThreadPlan.cpp lldb/trunk/source/Target/ThreadPlanStepRange.cpp lldb/trunk/source/lldb.cpp Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Sep 3 12:10:42 2010 @@ -153,6 +153,8 @@ void UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame); + bool + HasCachedData () const; private: //------------------------------------------------------------------ // For StackFrame only Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Fri Sep 3 12:10:42 2010 @@ -28,13 +28,13 @@ // Constructors and Destructors //------------------------------------------------------------------ StackFrameList (Thread &thread, - StackFrameList *prev_frames, + const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames); ~StackFrameList(); uint32_t - GetNumFrames(); + GetNumFrames (bool can_create = true); lldb::StackFrameSP GetFrameAtIndex (uint32_t idx); @@ -61,9 +61,15 @@ protected: + friend class Thread; + bool SetFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); + static void + Merge (std::auto_ptr& curr_ap, + lldb::StackFrameListSP& prev_sp); + //------------------------------------------------------------------ // Classes that inherit from StackFrameList can see and modify these //------------------------------------------------------------------ @@ -72,7 +78,7 @@ typedef collection::const_iterator const_iterator; Thread &m_thread; - std::auto_ptr m_prev_frames_ap; + lldb::StackFrameListSP m_prev_frames_sp; mutable Mutex m_mutex; collection m_frames; uint32_t m_selected_frame_idx; Modified: lldb/trunk/include/lldb/Target/StackID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackID.h (original) +++ lldb/trunk/include/lldb/Target/StackID.h Fri Sep 3 12:10:42 2010 @@ -51,12 +51,12 @@ { } - const lldb::addr_t + lldb::addr_t GetPC() const { return m_pc; } - + lldb::addr_t GetCallFrameAddress() const { @@ -94,6 +94,16 @@ } protected: + + friend class StackFrame; + + void + SetPC (lldb::addr_t pc) + { + m_pc = pc; + } + + //------------------------------------------------------------------ // Classes that inherit from StackID can see and modify these //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Fri Sep 3 12:10:42 2010 @@ -556,7 +556,7 @@ plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes. plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes. std::auto_ptr m_curr_frames_ap; ///< The stack frames that get lazily populated after a thread stops. - std::auto_ptr m_prev_frames_ap; ///< The previous stack frames from the last time this thread stopped. + lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped. int m_resume_signal; ///< The signal that should be used when continuing this thread. lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed. std::auto_ptr m_unwinder_ap; Modified: lldb/trunk/include/lldb/Target/ThreadList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadList.h?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ThreadList.h (original) +++ lldb/trunk/include/lldb/Target/ThreadList.h Fri Sep 3 12:10:42 2010 @@ -99,6 +99,12 @@ void SetStopID (uint32_t stop_id); + Mutex & + GetMutex () + { + return m_threads_mutex; + } + protected: typedef std::vector collection; Modified: lldb/trunk/include/lldb/lldb-private.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private.h?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-private.h (original) +++ lldb/trunk/include/lldb/lldb-private.h Fri Sep 3 12:10:42 2010 @@ -64,6 +64,10 @@ const char * GetVersion (); +const char * +GetVoteAsCString (lldb::Vote vote); + + // The function below can be moved into lldb::Debugger when/if we get one ArchSpec & GetDefaultArchitecture (); Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original) +++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Fri Sep 3 12:10:42 2010 @@ -285,7 +285,7 @@ if (level == lldb::eDescriptionLevelFull) { s->PutCString("where = "); - sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, true, true, false); + sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); } else { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Sep 3 12:10:42 2010 @@ -951,6 +951,7 @@ if (log && log->GetMask().IsSet(GDBR_LOG_VERBOSE)) log->Printf ("ProcessGDBRemote::%s (pid = %i)", __FUNCTION__, GetID()); + Mutex::Locker locker (m_thread_list.GetMutex ()); const uint32_t stop_id = GetStopID(); if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID()) { Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Fri Sep 3 12:10:42 2010 @@ -163,7 +163,7 @@ if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) { - if (m_id.GetSymbolContextScope () == NULL) + if (m_id.GetSymbolContextScope ()) { m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); } @@ -624,7 +624,8 @@ void StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) { - assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing + assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing + m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value assert (&m_thread == &curr_frame.m_thread); m_frame_index = curr_frame.m_frame_index; m_unwind_frame_index = curr_frame.m_unwind_frame_index; @@ -642,3 +643,14 @@ } +bool +StackFrame::HasCachedData () const +{ + if (m_variable_list_sp.get()) + return true; + if (m_variable_list_value_objects.GetSize() > 0) + return true; + if (!m_disassembly.GetString().empty()) + return true; + return false; +} \ No newline at end of file Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Fri Sep 3 12:10:42 2010 @@ -30,9 +30,14 @@ //---------------------------------------------------------------------- // StackFrameList constructor //---------------------------------------------------------------------- -StackFrameList::StackFrameList(Thread &thread, StackFrameList *prev_frames, bool show_inline_frames) : +StackFrameList::StackFrameList +( + Thread &thread, + const lldb::StackFrameListSP &prev_frames_sp, + bool show_inline_frames +) : m_thread (thread), - m_prev_frames_ap (prev_frames), + m_prev_frames_sp (prev_frames_sp), m_show_inlined_frames (show_inline_frames), m_mutex (Mutex::eMutexTypeRecursive), m_frames (), @@ -49,11 +54,11 @@ uint32_t -StackFrameList::GetNumFrames() +StackFrameList::GetNumFrames (bool can_create) { Mutex::Locker locker (m_mutex); - if (m_frames.size() <= 1) + if (can_create && m_frames.size() <= 1) { if (m_show_inlined_frames) { @@ -165,9 +170,10 @@ } } } - StackFrameList *prev_frames = m_prev_frames_ap.get(); - if (prev_frames) + + if (m_prev_frames_sp) { + StackFrameList *prev_frames = m_prev_frames_sp.get(); StackFrameList *curr_frames = this; #if defined (DEBUG_STACK_FRAMES) @@ -189,17 +195,16 @@ StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]); #if defined (DEBUG_STACK_FRAMES) - s.Printf("\nCurrent frame #%u ", curr_frame_idx); + s.Printf("\n\nCurr frame #%u ", curr_frame_idx); if (curr_frame_sp) - curr_frame_sp->Dump (&s, true); + curr_frame_sp->Dump (&s, true, false); else s.PutCString("NULL"); - s.Printf("\nPrevious frame #%u ", prev_frame_idx); + s.Printf("\nPrev frame #%u ", prev_frame_idx); if (prev_frame_sp) - prev_frame_sp->Dump (&s, true); + prev_frame_sp->Dump (&s, true, false); else s.PutCString("NULL"); - s.EOL(); #endif StackFrame *curr_frame = curr_frame_sp.get(); @@ -223,8 +228,7 @@ #endif } // We are done with the old stack frame list, we can release it now - m_prev_frames_ap.release(); - prev_frames = NULL; + m_prev_frames_sp.reset(); } #if defined (DEBUG_STACK_FRAMES) @@ -332,7 +336,6 @@ return frame_sp; } - bool StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) { @@ -409,3 +412,104 @@ } } } + +void +StackFrameList::Merge (std::auto_ptr& curr_ap, lldb::StackFrameListSP& prev_sp) +{ + Mutex::Locker curr_locker (curr_ap.get() ? curr_ap->m_mutex.GetMutex() : NULL); + Mutex::Locker prev_locker (prev_sp.get() ? prev_sp->m_mutex.GetMutex() : NULL); + +#if defined (DEBUG_STACK_FRAMES) + StreamFile s(stdout); + s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n"); + if (prev_sp.get()) + prev_sp->Dump (&s); + else + s.PutCString ("NULL"); + s.PutCString("\nCurr:\n"); + if (curr_ap.get()) + curr_ap->Dump (&s); + else + s.PutCString ("NULL"); + s.EOL(); +#endif + + if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0) + { +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("No current frames, leave previous frames alone...\n"); +#endif + curr_ap.release(); + return; + } + + if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0) + { +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("No previous frames, so use current frames...\n"); +#endif + // We either don't have any previous frames, or since we have more than + // one current frames it means we have all the frames and can safely + // replace our previous frames. + prev_sp.reset (curr_ap.release()); + return; + } + + const uint32_t num_curr_frames = curr_ap->GetNumFrames (false); + + if (num_curr_frames > 1) + { +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("We have more than one current frame, so use current frames...\n"); +#endif + // We have more than one current frames it means we have all the frames + // and can safely replace our previous frames. + prev_sp.reset (curr_ap.release()); + +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("\nMerged:\n"); + prev_sp->Dump (&s); +#endif + return; + } + + StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0)); + StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0)); + StackID curr_stack_id (curr_frame_zero_sp->GetStackID()); + StackID prev_stack_id (prev_frame_zero_sp->GetStackID()); + + //const uint32_t num_prev_frames = prev_sp->GetNumFrames (false); + +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\n%u previous frames with one current frame\n", num_prev_frames); +#endif + + // We have only a single current frame + // Our previous stack frames only had a single frame as well... + if (curr_stack_id == prev_stack_id) + { +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n"); +#endif + + curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp); +// prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp); +// prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp); + } + else if (curr_stack_id < prev_stack_id) + { +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n"); +#endif + prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp); + } + + curr_ap.release(); + +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("\nMerged:\n"); + prev_sp->Dump (&s); +#endif + + +} Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Fri Sep 3 12:10:42 2010 @@ -293,17 +293,28 @@ Thread::ShouldReportStop (Event* event_ptr) { StateType thread_state = GetResumeState (); - if (thread_state == eStateSuspended - || thread_state == eStateInvalid) + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + + if (thread_state == eStateSuspended || thread_state == eStateInvalid) + { + if (log) + log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion); return eVoteNoOpinion; + } if (m_completed_plan_stack.size() > 0) { // Don't use GetCompletedPlan here, since that suppresses private plans. + if (log) + log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote for complete stack's back plan\n", GetID()); return m_completed_plan_stack.back()->ShouldReportStop (event_ptr); } else + { + if (log) + log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote for current plan\n", GetID()); return GetCurrentPlan()->ShouldReportStop (event_ptr); + } } Vote @@ -797,7 +808,7 @@ Thread::GetStackFrameList () { if (m_curr_frames_ap.get() == NULL) - m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_ap.release(), true)); + m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_sp, true)); return *m_curr_frames_ap; } @@ -813,8 +824,13 @@ void Thread::ClearStackFrames () { - if (m_curr_frames_ap.get()) - m_prev_frames_ap = m_curr_frames_ap; + if (m_curr_frames_ap.get() && m_curr_frames_ap->GetNumFrames (false) > 1) + m_prev_frames_sp.reset (m_curr_frames_ap.release()); + else + m_curr_frames_ap.release(); + +// StackFrameList::Merge (m_curr_frames_ap, m_prev_frames_sp); +// assert (m_curr_frames_ap.get() == NULL); } lldb::StackFrameSP Modified: lldb/trunk/source/Target/ThreadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadList.cpp (original) +++ lldb/trunk/source/Target/ThreadList.cpp Fri Sep 3 12:10:42 2010 @@ -10,6 +10,8 @@ #include +#include "lldb/Core/Log.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -177,24 +179,51 @@ // Running events should never stop, obviously... + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); bool should_stop = false; m_process->UpdateThreadListIfNeeded(); collection::iterator pos, end = m_threads.end(); + if (log) + log->Printf ("%s %zu threads\n", __FUNCTION__, m_threads.size()); + // Run through the threads and ask whether we should stop. Don't ask // suspended threads, however, it makes more sense for them to preserve their // state across the times the process runs but they don't get a chance to. for (pos = m_threads.begin(); pos != end; ++pos) { ThreadSP thread_sp(*pos); - if ((thread_sp->GetResumeState () != eStateSuspended) && (thread_sp->ThreadStoppedForAReason())) + + if (log) + log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx ", __FUNCTION__, thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC()); + + if (thread_sp->GetResumeState () == eStateSuspended) + { + if (log) + log->Printf("ignore: thread was suspended\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC()); + continue; + } + + if (thread_sp->ThreadStoppedForAReason() == false) { - should_stop |= thread_sp->ShouldStop(event_ptr); + if (log) + log->Printf("ignore: no stop reason\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC()); + continue; + } + + const bool thread_should_stop = thread_sp->ShouldStop(event_ptr); + if (log) + log->Printf("should_stop = %i\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC(), thread_should_stop); + if (thread_should_stop) + should_stop |= true; } + if (log) + log->Printf ("%s overall should_stop = %i\n", __FUNCTION__, should_stop); + if (should_stop) { for (pos = m_threads.begin(); pos != end; ++pos) @@ -210,10 +239,17 @@ Vote ThreadList::ShouldReportStop (Event *event_ptr) { + Mutex::Locker locker(m_threads_mutex); + Vote result = eVoteNoOpinion; m_process->UpdateThreadListIfNeeded(); collection::iterator pos, end = m_threads.end(); + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + + if (log) + log->Printf ("%s %zu threads\n", __FUNCTION__, m_threads.size()); + // Run through the threads and ask whether we should report this event. // For stopping, a YES vote wins over everything. A NO vote wins over NO opinion. for (pos = m_threads.begin(); pos != end; ++pos) @@ -221,26 +257,52 @@ ThreadSP thread_sp(*pos); if (thread_sp->ThreadStoppedForAReason() && (thread_sp->GetResumeState () != eStateSuspended)) { - switch (thread_sp->ShouldReportStop (event_ptr)) + const lldb::Vote vote = thread_sp->ShouldReportStop (event_ptr); + if (log) + log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx vote: %s\n", + __FUNCTION__, + thread_sp->GetID (), + thread_sp->GetRegisterContext()->GetPC(), + GetVoteAsCString (vote)); + switch (vote) { - case eVoteNoOpinion: - continue; - case eVoteYes: - result = eVoteYes; - break; - case eVoteNo: - if (result == eVoteNoOpinion) - result = eVoteNo; - break; + case eVoteNoOpinion: + continue; + + case eVoteYes: + result = eVoteYes; + break; + + case eVoteNo: + if (result == eVoteNoOpinion) + { + result = eVoteNo; + } + else + { + if (log) + log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx voted %s, but lost out because result was %s\n", + __FUNCTION__, + thread_sp->GetID (), + thread_sp->GetRegisterContext()->GetPC(), + GetVoteAsCString (vote), + GetVoteAsCString (result)); + } + break; } } } + if (log) + log->Printf ("%s returning %s\n", __FUNCTION__, GetVoteAsCString (result)); return result; } Vote ThreadList::ShouldReportRun (Event *event_ptr) { + + Mutex::Locker locker(m_threads_mutex); + Vote result = eVoteNoOpinion; m_process->UpdateThreadListIfNeeded(); collection::iterator pos, end = m_threads.end(); Modified: lldb/trunk/source/Target/ThreadPlan.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlan.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlan.cpp (original) +++ lldb/trunk/source/Target/ThreadPlan.cpp Fri Sep 3 12:10:42 2010 @@ -13,9 +13,10 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Target/Thread.h" #include "lldb/Core/Log.h" #include "lldb/Core/State.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; @@ -88,12 +89,21 @@ Vote ThreadPlan::ShouldReportStop (Event *event_ptr) { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + if (m_stop_vote == eVoteNoOpinion) { ThreadPlan *prev_plan = GetPreviousPlan (); if (prev_plan) - return prev_plan->ShouldReportStop (event_ptr); + { + Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); + if (log) + log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote %s\n", GetVoteAsCString (prev_vote)); + return prev_vote; + } } + if (log) + log->Printf ("ThreadPlan::ShouldReportStop() returning vote %s\n", GetVoteAsCString (m_stop_vote)); return m_stop_vote; } @@ -128,8 +138,21 @@ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); if (log) - log->Printf("Thread #%u: tid = 0x%4.4x about to resume the \"%s\" plan - state: %s - stop others: %d.", - m_thread.GetIndexID(), m_thread.GetID(), m_name.c_str(), StateAsCString(resume_state), StopOthers()); + { + RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + addr_t pc = reg_ctx->GetPC(); + addr_t sp = reg_ctx->GetSP(); + addr_t fp = reg_ctx->GetFP(); + log->Printf("Thread #%u: tid = 0x%4.4x (pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx) about to resume the \"%s\" plan - state: %s - stop others: %d.", + m_thread.GetIndexID(), + m_thread.GetID(), + (uint64_t)pc, + (uint64_t)sp, + (uint64_t)fp, + m_name.c_str(), + StateAsCString(resume_state), + StopOthers()); + } } return true; } Modified: lldb/trunk/source/Target/ThreadPlanStepRange.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepRange.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepRange.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepRange.cpp Fri Sep 3 12:10:42 2010 @@ -84,10 +84,12 @@ Vote ThreadPlanStepRange::ShouldReportStop (Event *event_ptr) { - if (IsPlanComplete()) - return eVoteYes; - else - return eVoteNo; + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + + const Vote vote = IsPlanComplete() ? eVoteYes : eVoteNo; + if (log) + log->Printf ("ThreadPlanStepRange::ShouldReportStop() returning vote %i\n", eVoteYes); + return vote; } bool Modified: lldb/trunk/source/lldb.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=112973&r1=112972&r2=112973&view=diff ============================================================================== --- lldb/trunk/source/lldb.cpp (original) +++ lldb/trunk/source/lldb.cpp Fri Sep 3 12:10:42 2010 @@ -129,3 +129,14 @@ static ArchSpec g_default_arch; return g_default_arch; } + + +const char * +lldb_private::GetVoteAsCString (lldb::Vote vote) +{ + static const char * g_vote_cstrings[] = { "no", "no opinion", "yes" }; + if (vote >= eVoteNo && vote <= eVoteYes) + return g_vote_cstrings[vote-1]; + return "invalid"; +} + From benny.kra at googlemail.com Fri Sep 3 13:20:07 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 03 Sep 2010 18:20:07 -0000 Subject: [Lldb-commits] [lldb] r112985 - /lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Message-ID: <20100903182007.37F6F2A6C12C@llvm.org> Author: d0k Date: Fri Sep 3 13:20:07 2010 New Revision: 112985 URL: http://llvm.org/viewvc/llvm-project?rev=112985&view=rev Log: Pacify operator precedence warnings. No functionality change because eLaunchFlagDisableASLR happens to be 1. Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=112985&r1=112984&r2=112985&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Sep 3 13:20:07 2010 @@ -405,7 +405,7 @@ NULL, //stdin_path, LLDB_INVALID_PROCESS_ID, NULL, false, - launch_flags & eLaunchFlagDisableASLR != 0, + (launch_flags & eLaunchFlagDisableASLR) != 0, inferior_arch); if (error.Fail()) return error; @@ -424,7 +424,7 @@ NULL, //stdin_path, LLDB_INVALID_PROCESS_ID, NULL, false, - launch_flags & eLaunchFlagDisableASLR != 0, + (launch_flags & eLaunchFlagDisableASLR) != 0, inferior_arch); if (error.Fail()) return error; From jingham at apple.com Fri Sep 3 14:08:19 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 03 Sep 2010 19:08:19 -0000 Subject: [Lldb-commits] [lldb] r112993 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectDelete.cpp source/Commands/CommandObjectDelete.h source/Commands/CommandObjectInfo.cpp source/Commands/CommandObjectInfo.h source/Commands/CommandObjectSelect.cpp source/Commands/CommandObjectSelect.h source/Interpreter/CommandInterpreter.cpp Message-ID: <20100903190819.A28772A6C12C@llvm.org> Author: jingham Date: Fri Sep 3 14:08:19 2010 New Revision: 112993 URL: http://llvm.org/viewvc/llvm-project?rev=112993&view=rev Log: Delete the vestigal "select", "info" and "delete" commands. Also move "Carbon.framework" to the right place. Removed: lldb/trunk/source/Commands/CommandObjectDelete.cpp lldb/trunk/source/Commands/CommandObjectDelete.h lldb/trunk/source/Commands/CommandObjectInfo.cpp lldb/trunk/source/Commands/CommandObjectInfo.h lldb/trunk/source/Commands/CommandObjectSelect.cpp lldb/trunk/source/Commands/CommandObjectSelect.h Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112993&r1=112992&r2=112993&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 3 14:08:19 2010 @@ -85,19 +85,16 @@ 26D5B07411B07550009A862E /* WatchpointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */; }; 26D5B07611B07550009A862E /* CommandObjectAppend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */; }; 26D5B07711B07550009A862E /* CommandObjectBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */; }; - 26D5B07811B07550009A862E /* CommandObjectDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2F10F1B84700F91463 /* CommandObjectDelete.cpp */; }; 26D5B07911B07550009A862E /* CommandObjectDisassemble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */; }; 26D5B07A11B07550009A862E /* CommandObjectExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */; }; 26D5B07B11B07550009A862E /* CommandObjectFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3210F1B84700F91463 /* CommandObjectFile.cpp */; }; 26D5B07C11B07550009A862E /* CommandObjectHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3310F1B84700F91463 /* CommandObjectHelp.cpp */; }; 26D5B07D11B07550009A862E /* CommandObjectImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3410F1B84700F91463 /* CommandObjectImage.cpp */; }; - 26D5B07E11B07550009A862E /* CommandObjectInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3510F1B84700F91463 /* CommandObjectInfo.cpp */; }; 26D5B07F11B07550009A862E /* CommandObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3610F1B84700F91463 /* CommandObjectMemory.cpp */; }; 26D5B08011B07550009A862E /* CommandObjectProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3810F1B84700F91463 /* CommandObjectProcess.cpp */; }; 26D5B08111B07550009A862E /* CommandObjectQuit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */; }; 26D5B08211B07550009A862E /* CommandObjectRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */; }; 26D5B08311B07550009A862E /* CommandObjectScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */; }; - 26D5B08411B07550009A862E /* CommandObjectSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3E10F1B84700F91463 /* CommandObjectSelect.cpp */; }; 26D5B08511B07550009A862E /* CommandObjectSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */; }; 26D5B08611B07550009A862E /* CommandObjectSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */; }; 26D5B08711B07550009A862E /* CommandObjectShow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */; }; @@ -618,19 +615,16 @@ 26BC7CFC10F1B71400F91463 /* WatchpointLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WatchpointLocation.h; path = include/lldb/Breakpoint/WatchpointLocation.h; sourceTree = ""; }; 26BC7D1210F1B76300F91463 /* CommandObjectAppend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectAppend.h; path = source/Commands/CommandObjectAppend.h; sourceTree = ""; }; 26BC7D1410F1B76300F91463 /* CommandObjectBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectBreakpoint.h; path = source/Commands/CommandObjectBreakpoint.h; sourceTree = ""; }; - 26BC7D1610F1B76300F91463 /* CommandObjectDelete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectDelete.h; path = source/Commands/CommandObjectDelete.h; sourceTree = ""; }; 26BC7D1710F1B76300F91463 /* CommandObjectDisassemble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectDisassemble.h; path = source/Commands/CommandObjectDisassemble.h; sourceTree = ""; }; 26BC7D1810F1B76300F91463 /* CommandObjectExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectExpression.h; path = source/Commands/CommandObjectExpression.h; sourceTree = ""; }; 26BC7D1910F1B76300F91463 /* CommandObjectFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectFile.h; path = source/Commands/CommandObjectFile.h; sourceTree = ""; }; 26BC7D1A10F1B76300F91463 /* CommandObjectHelp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectHelp.h; path = source/Commands/CommandObjectHelp.h; sourceTree = ""; }; 26BC7D1B10F1B76300F91463 /* CommandObjectImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectImage.h; path = source/Commands/CommandObjectImage.h; sourceTree = ""; }; - 26BC7D1C10F1B76300F91463 /* CommandObjectInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectInfo.h; path = source/Commands/CommandObjectInfo.h; sourceTree = ""; }; 26BC7D1D10F1B76300F91463 /* CommandObjectMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectMemory.h; path = source/Commands/CommandObjectMemory.h; sourceTree = ""; }; 26BC7D1F10F1B76300F91463 /* CommandObjectProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectProcess.h; path = source/Commands/CommandObjectProcess.h; sourceTree = ""; }; 26BC7D2010F1B76300F91463 /* CommandObjectQuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectQuit.h; path = source/Commands/CommandObjectQuit.h; sourceTree = ""; }; 26BC7D2210F1B76300F91463 /* CommandObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectRegister.h; path = source/Commands/CommandObjectRegister.h; sourceTree = ""; }; 26BC7D2410F1B76300F91463 /* CommandObjectScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectScript.h; path = source/Interpreter/CommandObjectScript.h; sourceTree = ""; }; - 26BC7D2510F1B76300F91463 /* CommandObjectSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSelect.h; path = source/Commands/CommandObjectSelect.h; sourceTree = ""; }; 26BC7D2610F1B76300F91463 /* CommandObjectSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSet.h; path = source/Commands/CommandObjectSet.h; sourceTree = ""; }; 26BC7D2710F1B76300F91463 /* CommandObjectSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSettings.h; path = source/Commands/CommandObjectSettings.h; sourceTree = ""; }; 26BC7D2810F1B76300F91463 /* CommandObjectShow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectShow.h; path = source/Commands/CommandObjectShow.h; sourceTree = ""; }; @@ -732,19 +726,16 @@ 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointLocation.cpp; path = source/Breakpoint/WatchpointLocation.cpp; sourceTree = ""; }; 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectAppend.cpp; path = source/Commands/CommandObjectAppend.cpp; sourceTree = ""; }; 26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectBreakpoint.cpp; path = source/Commands/CommandObjectBreakpoint.cpp; sourceTree = ""; }; - 26BC7E2F10F1B84700F91463 /* CommandObjectDelete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectDelete.cpp; path = source/Commands/CommandObjectDelete.cpp; sourceTree = ""; }; 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectDisassemble.cpp; path = source/Commands/CommandObjectDisassemble.cpp; sourceTree = ""; }; 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectExpression.cpp; path = source/Commands/CommandObjectExpression.cpp; sourceTree = ""; }; 26BC7E3210F1B84700F91463 /* CommandObjectFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectFile.cpp; path = source/Commands/CommandObjectFile.cpp; sourceTree = ""; }; 26BC7E3310F1B84700F91463 /* CommandObjectHelp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectHelp.cpp; path = source/Commands/CommandObjectHelp.cpp; sourceTree = ""; }; 26BC7E3410F1B84700F91463 /* CommandObjectImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectImage.cpp; path = source/Commands/CommandObjectImage.cpp; sourceTree = ""; }; - 26BC7E3510F1B84700F91463 /* CommandObjectInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectInfo.cpp; path = source/Commands/CommandObjectInfo.cpp; sourceTree = ""; }; 26BC7E3610F1B84700F91463 /* CommandObjectMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectMemory.cpp; path = source/Commands/CommandObjectMemory.cpp; sourceTree = ""; }; 26BC7E3810F1B84700F91463 /* CommandObjectProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectProcess.cpp; path = source/Commands/CommandObjectProcess.cpp; sourceTree = ""; }; 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectQuit.cpp; path = source/Commands/CommandObjectQuit.cpp; sourceTree = ""; }; 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectRegister.cpp; path = source/Commands/CommandObjectRegister.cpp; sourceTree = ""; }; 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectScript.cpp; path = source/Interpreter/CommandObjectScript.cpp; sourceTree = ""; }; - 26BC7E3E10F1B84700F91463 /* CommandObjectSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSelect.cpp; path = source/Commands/CommandObjectSelect.cpp; sourceTree = ""; }; 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSet.cpp; path = source/Commands/CommandObjectSet.cpp; sourceTree = ""; }; 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSettings.cpp; path = source/Commands/CommandObjectSettings.cpp; sourceTree = ""; }; 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectShow.cpp; path = source/Commands/CommandObjectShow.cpp; sourceTree = ""; }; @@ -1109,7 +1100,6 @@ 08FB7795FE84155DC02AAC07 /* Source */, 26F5C22410F3D950009D5894 /* Tools */, 1AB674ADFE9D54B511CA2CBB /* Products */, - 4C74CB6212288704006A8171 /* Carbon.framework */, ); name = lldb; sourceTree = ""; @@ -1807,8 +1797,6 @@ 4C98D3E4118FB9B100E575D0 /* CommandObjectCall.cpp */, 4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */, 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */, - 26BC7D1610F1B76300F91463 /* CommandObjectDelete.h */, - 26BC7E2F10F1B84700F91463 /* CommandObjectDelete.cpp */, 26BC7D1710F1B76300F91463 /* CommandObjectDisassemble.h */, 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */, 26BC7D1810F1B76300F91463 /* CommandObjectExpression.h */, @@ -1821,8 +1809,6 @@ 26BC7E3310F1B84700F91463 /* CommandObjectHelp.cpp */, 26BC7D1B10F1B76300F91463 /* CommandObjectImage.h */, 26BC7E3410F1B84700F91463 /* CommandObjectImage.cpp */, - 26BC7D1C10F1B76300F91463 /* CommandObjectInfo.h */, - 26BC7E3510F1B84700F91463 /* CommandObjectInfo.cpp */, 264AD83911095BBD00E0B039 /* CommandObjectLog.h */, 264AD83711095BA600E0B039 /* CommandObjectLog.cpp */, 26BC7D1D10F1B76300F91463 /* CommandObjectMemory.h */, @@ -1835,8 +1821,6 @@ 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */, 26BC7D2410F1B76300F91463 /* CommandObjectScript.h */, 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */, - 26BC7D2510F1B76300F91463 /* CommandObjectSelect.h */, - 26BC7E3E10F1B84700F91463 /* CommandObjectSelect.cpp */, 26BC7D2610F1B76300F91463 /* CommandObjectSet.h */, 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */, 26BC7D2710F1B76300F91463 /* CommandObjectSettings.h */, @@ -2074,6 +2058,7 @@ 26F5C37410F3F61B009D5894 /* libobjc.dylib */, 26F5C32410F3DF23009D5894 /* libpython2.6.dylib */, 26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */, + 4C74CB6212288704006A8171 /* Carbon.framework */, ); name = Libraries; sourceTree = ""; @@ -2310,7 +2295,6 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, @@ -2444,19 +2428,16 @@ 26D5B07411B07550009A862E /* WatchpointLocation.cpp in Sources */, 26D5B07611B07550009A862E /* CommandObjectAppend.cpp in Sources */, 26D5B07711B07550009A862E /* CommandObjectBreakpoint.cpp in Sources */, - 26D5B07811B07550009A862E /* CommandObjectDelete.cpp in Sources */, 26D5B07911B07550009A862E /* CommandObjectDisassemble.cpp in Sources */, 26D5B07A11B07550009A862E /* CommandObjectExpression.cpp in Sources */, 26D5B07B11B07550009A862E /* CommandObjectFile.cpp in Sources */, 26D5B07C11B07550009A862E /* CommandObjectHelp.cpp in Sources */, 26D5B07D11B07550009A862E /* CommandObjectImage.cpp in Sources */, - 26D5B07E11B07550009A862E /* CommandObjectInfo.cpp in Sources */, 26D5B07F11B07550009A862E /* CommandObjectMemory.cpp in Sources */, 26D5B08011B07550009A862E /* CommandObjectProcess.cpp in Sources */, 26D5B08111B07550009A862E /* CommandObjectQuit.cpp in Sources */, 26D5B08211B07550009A862E /* CommandObjectRegister.cpp in Sources */, 26D5B08311B07550009A862E /* CommandObjectScript.cpp in Sources */, - 26D5B08411B07550009A862E /* CommandObjectSelect.cpp in Sources */, 26D5B08511B07550009A862E /* CommandObjectSet.cpp in Sources */, 26D5B08611B07550009A862E /* CommandObjectSettings.cpp in Sources */, 26D5B08711B07550009A862E /* CommandObjectShow.cpp in Sources */, Removed: lldb/trunk/source/Commands/CommandObjectDelete.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDelete.cpp?rev=112992&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectDelete.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectDelete.cpp (removed) @@ -1,32 +0,0 @@ -//===-- CommandObjectDelete.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectDelete.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes - -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectDelete -//------------------------------------------------------------------------- - -CommandObjectDelete::CommandObjectDelete () : -CommandObjectCrossref ("delete", "Lists the kinds of objects you can delete, and shows syntax for deleting them.", "delete") -{ -} - -CommandObjectDelete::~CommandObjectDelete () -{ -} - - Removed: lldb/trunk/source/Commands/CommandObjectDelete.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDelete.h?rev=112992&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectDelete.h (original) +++ lldb/trunk/source/Commands/CommandObjectDelete.h (removed) @@ -1,37 +0,0 @@ -//===-- CommandObjectDelete.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_CommandObjectDelete_h_ -#define liblldb_CommandObjectDelete_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObjectCrossref.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectDelete -//------------------------------------------------------------------------- - -class CommandObjectDelete : public CommandObjectCrossref -{ -public: - CommandObjectDelete (); - - virtual - ~CommandObjectDelete (); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectDelete_h_ Removed: lldb/trunk/source/Commands/CommandObjectInfo.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectInfo.cpp?rev=112992&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectInfo.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectInfo.cpp (removed) @@ -1,32 +0,0 @@ -//===-- CommandObjectInfo.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectInfo.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes - -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectInfo -//------------------------------------------------------------------------- - -CommandObjectInfo::CommandObjectInfo () : -CommandObjectCrossref ("info", "Lists the kinds of objects for which you can get information, and shows the syntax for doing so.", "info") -{ -} - -CommandObjectInfo::~CommandObjectInfo () -{ -} - - Removed: lldb/trunk/source/Commands/CommandObjectInfo.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectInfo.h?rev=112992&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectInfo.h (original) +++ lldb/trunk/source/Commands/CommandObjectInfo.h (removed) @@ -1,37 +0,0 @@ -//===-- CommandObjectInfo.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_CommandObjectInfo_h_ -#define liblldb_CommandObjectInfo_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObjectCrossref.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectInfo -//------------------------------------------------------------------------- - -class CommandObjectInfo : public CommandObjectCrossref -{ -public: - CommandObjectInfo (); - - virtual - ~CommandObjectInfo (); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectInfo_h_ Removed: lldb/trunk/source/Commands/CommandObjectSelect.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSelect.cpp?rev=112992&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSelect.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSelect.cpp (removed) @@ -1,32 +0,0 @@ -//===-- CommandObjectSelect.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectSelect.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes - -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectSelect -//------------------------------------------------------------------------- - -CommandObjectSelect::CommandObjectSelect () : - CommandObjectCrossref ("select", "Lists the kinds of objects you can select, and shows syntax for selecting them.", "select") -{ -} - -CommandObjectSelect::~CommandObjectSelect () -{ -} - - Removed: lldb/trunk/source/Commands/CommandObjectSelect.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSelect.h?rev=112992&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSelect.h (original) +++ lldb/trunk/source/Commands/CommandObjectSelect.h (removed) @@ -1,37 +0,0 @@ -//===-- CommandObjectSelect.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_CommandObjectSelect_h_ -#define liblldb_CommandObjectSelect_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObjectCrossref.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectSelect -//------------------------------------------------------------------------- - -class CommandObjectSelect : public CommandObjectCrossref -{ -public: - CommandObjectSelect (); - - virtual - ~CommandObjectSelect (); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectSelect_h_ Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=112993&r1=112992&r2=112993&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri Sep 3 14:08:19 2010 @@ -17,14 +17,12 @@ #include "../Commands/CommandObjectArgs.h" #include "../Commands/CommandObjectBreakpoint.h" //#include "../Commands/CommandObjectCall.h" -#include "../Commands/CommandObjectDelete.h" #include "../Commands/CommandObjectDisassemble.h" #include "../Commands/CommandObjectExpression.h" #include "../Commands/CommandObjectFile.h" #include "../Commands/CommandObjectFrame.h" #include "../Commands/CommandObjectHelp.h" #include "../Commands/CommandObjectImage.h" -#include "../Commands/CommandObjectInfo.h" #include "../Commands/CommandObjectLog.h" #include "../Commands/CommandObjectMemory.h" #include "../Commands/CommandObjectProcess.h" @@ -32,7 +30,6 @@ #include "lldb/Interpreter/CommandObjectRegexCommand.h" #include "../Commands/CommandObjectRegister.h" #include "CommandObjectScript.h" -#include "../Commands/CommandObjectSelect.h" #include "../Commands/CommandObjectSet.h" #include "../Commands/CommandObjectSettings.h" #include "../Commands/CommandObjectShow.h" @@ -202,10 +199,6 @@ // the crossref object exists and is ready to take the cross reference. Put the cross referencing command // objects into the CommandDictionary now, so they are ready for use when the other commands get created. - m_command_dict["select"] = CommandObjectSP (new CommandObjectSelect ()); - m_command_dict["info"] = CommandObjectSP (new CommandObjectInfo ()); - m_command_dict["delete"] = CommandObjectSP (new CommandObjectDelete ()); - // Non-CommandObjectCrossref commands can now be created. m_command_dict["append"] = CommandObjectSP (new CommandObjectAppend ()); From gclayton at apple.com Fri Sep 3 14:15:44 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 03 Sep 2010 19:15:44 -0000 Subject: [Lldb-commits] [lldb] r112996 - in /lldb/trunk: source/Host/posix/Mutex.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp tools/debugserver/debugserver.xcodeproj/project.pbxproj Message-ID: <20100903191544.2D71E2A6C12C@llvm.org> Author: gclayton Date: Fri Sep 3 14:15:43 2010 New Revision: 112996 URL: http://llvm.org/viewvc/llvm-project?rev=112996&view=rev Log: Fixed a case where we might be able to acquire a mutex with a try lock and not release it by making sure a mutex locker object is appropriately used. Modified: lldb/trunk/source/Host/posix/Mutex.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Modified: lldb/trunk/source/Host/posix/Mutex.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/Mutex.cpp?rev=112996&r1=112995&r2=112996&view=diff ============================================================================== --- lldb/trunk/source/Host/posix/Mutex.cpp (original) +++ lldb/trunk/source/Host/posix/Mutex.cpp Fri Sep 3 14:15:43 2010 @@ -78,8 +78,7 @@ //---------------------------------------------------------------------- Mutex::Locker::~Locker () { - if (m_mutex_ptr) - Mutex::Unlock (m_mutex_ptr); + Reset(); } //---------------------------------------------------------------------- @@ -89,6 +88,10 @@ void Mutex::Locker::Reset (pthread_mutex_t *mutex_ptr) { + // We already have this mutex locked or both are NULL... + if (m_mutex_ptr == mutex_ptr) + return; + if (m_mutex_ptr) Mutex::Unlock (m_mutex_ptr); @@ -100,9 +103,12 @@ bool Mutex::Locker::TryLock (pthread_mutex_t *mutex_ptr) { - if (m_mutex_ptr) - Mutex::Unlock (m_mutex_ptr); - m_mutex_ptr = NULL; + // We already have this mutex locked! + if (m_mutex_ptr == mutex_ptr) + return true; + + Reset (); + if (mutex_ptr) { if (Mutex::TryLock (mutex_ptr) == 0) Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=112996&r1=112995&r2=112996&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Sep 3 14:15:43 2010 @@ -124,7 +124,7 @@ timeout_time = TimeValue::Now(); timeout_time.OffsetWithSeconds (timeout_seconds); - if (locker.TryLock (m_sequence_mutex.GetMutex())) + if (GetSequenceMutex (locker)) { if (SendPacketNoLock (payload, strlen(payload))) return WaitForPacketNoLock (response, &timeout_time); @@ -139,7 +139,7 @@ m_async_packet_predicate.SetValue (true, eBroadcastNever); bool timed_out = false; - if (SendInterrupt(1, &timed_out)) + if (SendInterrupt(locker, 1, &timed_out)) { if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) { @@ -396,14 +396,25 @@ { m_async_signal = signo; bool timed_out = false; - if (SendInterrupt(1, &timed_out)) + Mutex::Locker locker; + if (SendInterrupt (locker, 1, &timed_out)) return true; m_async_signal = -1; return false; } +// This function takes a mutex locker as a parameter in case the GetSequenceMutex +// actually succeeds. If it doesn't succeed in acquiring the sequence mutex +// (the expected result), then it will send the halt packet. If it does succeed +// then the caller that requested the interrupt will want to keep the sequence +// locked down so that no one else can send packets while the caller has control. +// This function usually gets called when we are running and need to stop the +// target. It can also be used when we are running and and we need to do something +// else (like read/write memory), so we need to interrupt the running process +// (gdb remote protocol requires this), and do what we need to do, then resume. + bool -GDBRemoteCommunication::SendInterrupt (uint32_t seconds_to_wait_for_stop, bool *timed_out) +GDBRemoteCommunication::SendInterrupt (Mutex::Locker& locker, uint32_t seconds_to_wait_for_stop, bool *timed_out) { if (timed_out) *timed_out = false; @@ -411,7 +422,7 @@ if (IsConnected() && IsRunning()) { // Only send an interrupt if our debugserver is running... - if (m_sequence_mutex.TryLock() != 0) + if (GetSequenceMutex (locker) == false) { // Someone has the mutex locked waiting for a response or for the // inferior to stop, so send the interrupt on the down low... Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=112996&r1=112995&r2=112996&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Fri Sep 3 14:15:43 2010 @@ -99,7 +99,9 @@ SendAsyncSignal (int signo); bool - SendInterrupt (uint32_t seconds_to_wait_for_stop, bool *timed_out = NULL); + SendInterrupt (lldb_private::Mutex::Locker &locker, + uint32_t seconds_to_wait_for_stop, + bool *timed_out = NULL); bool GetSequenceMutex(lldb_private::Mutex::Locker& locker); Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=112996&r1=112995&r2=112996&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Sep 3 14:15:43 2010 @@ -1117,7 +1117,8 @@ if (m_gdb_comm.IsRunning()) { bool timed_out = false; - if (!m_gdb_comm.SendInterrupt (2, &timed_out)) + Mutex::Locker locker; + if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out)) { if (timed_out) error.SetErrorString("timed out sending interrupt packet"); @@ -1150,7 +1151,8 @@ log->Printf ("ProcessGDBRemote::DoDestroy()"); // Interrupt if our inferior is running... - m_gdb_comm.SendInterrupt (1); + Mutex::Locker locker; + m_gdb_comm.SendInterrupt (locker, 1); DisableAllBreakpointSites (); SetExitStatus(-1, "process killed"); Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=112996&r1=112995&r2=112996&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original) +++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Fri Sep 3 14:15:43 2010 @@ -369,7 +369,14 @@ isa = PBXProject; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* dbgnub */; projectDirPath = ""; projectRoot = ""; From gclayton at apple.com Fri Sep 3 16:14:27 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 03 Sep 2010 21:14:27 -0000 Subject: [Lldb-commits] [lldb] r113012 - in /lldb/trunk/source/Plugins/Process/gdb-remote: GDBRemoteCommunication.cpp ProcessGDBRemoteLog.cpp ProcessGDBRemoteLog.h Message-ID: <20100903211427.4DE192A6C12C@llvm.org> Author: gclayton Date: Fri Sep 3 16:14:27 2010 New Revision: 113012 URL: http://llvm.org/viewvc/llvm-project?rev=113012&view=rev Log: Added some extra logging to track asynchronous packet activity. Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=113012&r1=113011&r2=113012&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Sep 3 16:14:27 2010 @@ -194,6 +194,7 @@ ) { Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); + Log *async_log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC); if (log) log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__); @@ -226,6 +227,9 @@ case 'S': if (m_async_signal != -1) { + if (async_log) + async_log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal)); + // Save off the async signal we are supposed to send const int async_signal = m_async_signal; // Clear the async signal member so we don't end up @@ -235,6 +239,9 @@ uint8_t signo = response.GetHexU8(255); if (signo == async_signal) { + if (async_log) + async_log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo)); + // We already stopped with a signal that we wanted // to stop with, so we are done response.SetFilePos (0); @@ -251,8 +258,16 @@ "C%2.2x", async_signal); + if (async_log) + async_log->Printf ("async: stopped with signal %s, resume with %s", + Host::GetSignalAsCString (signo), + Host::GetSignalAsCString (async_signal)); + if (SendPacket(signal_packet, signal_packet_len) == 0) { + if (async_log) + async_log->Printf ("async: error: failed to resume with %s", + Host::GetSignalAsCString (async_signal)); state = eStateInvalid; break; } @@ -262,6 +277,10 @@ } else if (m_async_packet_predicate.GetValue()) { + if (async_log) + async_log->Printf ("async: send async packet: %s", + m_async_packet.c_str()); + // We are supposed to send an asynchronous packet while // we are running. m_async_response.Clear(); @@ -277,6 +296,10 @@ // packet know that the packet has been sent. m_async_packet_predicate.SetValue(false, eBroadcastAlways); + if (async_log) + async_log->Printf ("async: resume after async response received: %s", + m_async_response.GetStringRef().c_str()); + // Continue again if (SendPacket("c", 1) == 0) { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp?rev=113012&r1=113011&r2=113012&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp Fri Sep 3 16:14:27 2010 @@ -59,7 +59,9 @@ const char *arg = args.GetArgumentAtIndex(i); if (::strcasecmp (arg, "all") == 0 ) flag_bits |= GDBR_LOG_ALL; + else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= GDBR_LOG_ASYNC; else if (::strcasestr (arg, "break") == arg ) flag_bits |= GDBR_LOG_BREAKPOINTS; + else if (::strcasestr (arg, "comm") == arg ) flag_bits |= GDBR_LOG_COMM; else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= GDBR_LOG_DEFAULT; else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= GDBR_LOG_PACKETS; else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= GDBR_LOG_MEMORY; @@ -93,7 +95,9 @@ { strm->Printf("Logging categories for '%s':\n" "\tall - turn on all available logging categories\n" + "\tasync - log asynchronous activity\n" "\tbreak - log breakpoints\n" + "\tcommunication - log communication activity\n" "\tdefault - enable the default set of logging categories for liblldb\n" "\tpackets - log gdb remote packets\n" "\tmemory - log memory reads and writes\n" Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h?rev=113012&r1=113011&r2=113012&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h Fri Sep 3 16:14:27 2010 @@ -28,6 +28,7 @@ #define GDBR_LOG_WATCHPOINTS (1u << 8) #define GDBR_LOG_STEP (1u << 9) #define GDBR_LOG_COMM (1u << 10) +#define GDBR_LOG_ASYNC (1u << 11) #define GDBR_LOG_ALL (UINT32_MAX) #define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS From johnny.chen at apple.com Fri Sep 3 17:35:47 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 03 Sep 2010 22:35:47 -0000 Subject: [Lldb-commits] [lldb] r113022 - in /lldb/trunk: source/Core/Debugger.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp test/lldbtest.py Message-ID: <20100903223547.C226D2A6C12C@llvm.org> Author: johnny Date: Fri Sep 3 17:35:47 2010 New Revision: 113022 URL: http://llvm.org/viewvc/llvm-project?rev=113022&view=rev Log: Fixed an lldb infrastructure bug, where the debugger should reaaly update its execution context only when the process is still alive. When running the test suite, the debugger is launching and killing processes constantly. This might be the cause of the test hang as reported in rdar://problem/8377854, where the debugger was looping infinitely trying to update a supposedly stale thread list. Modified: lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/test/lldbtest.py Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=113022&r1=113021&r2=113022&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Fri Sep 3 17:35:47 2010 @@ -479,7 +479,7 @@ { m_exe_ctx.target = target_sp.get(); m_exe_ctx.process = target_sp->GetProcessSP().get(); - if (m_exe_ctx.process && m_exe_ctx.process->IsRunning() == false) + if (m_exe_ctx.process && m_exe_ctx.process->IsAlive() && !m_exe_ctx.process->IsRunning()) { m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get(); if (m_exe_ctx.thread == NULL) Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=113022&r1=113021&r2=113022&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Sep 3 17:35:47 2010 @@ -1171,6 +1171,7 @@ StopAsyncThread (); m_gdb_comm.StopReadThread(); KillDebugserverProcess (); + m_gdb_comm.Disconnect(); // Disconnect from the debug server. return error; } Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=113022&r1=113021&r2=113022&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Sep 3 17:35:47 2010 @@ -355,12 +355,12 @@ else: print >> sys.stderr, self.res.GetError() + if running: + # For process launch, wait some time before possible next try. + time.sleep(self.timeWait) + if self.res.Succeeded(): break - else: - if running: - # Process launch failed, wait some time before the next try. - time.sleep(self.timeWait) # Modify runStarted only if "run" or "process launch" was encountered. if running: From gclayton at apple.com Fri Sep 3 17:45:01 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 03 Sep 2010 22:45:01 -0000 Subject: [Lldb-commits] [lldb] r113023 - in /lldb/trunk/source: Commands/CommandObjectThread.cpp Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Target/Thread.cpp Target/ThreadList.cpp Target/ThreadPlan.cpp lldb.cpp Message-ID: <20100903224501.AE3E42A6C12C@llvm.org> Author: gclayton Date: Fri Sep 3 17:45:01 2010 New Revision: 113023 URL: http://llvm.org/viewvc/llvm-project?rev=113023&view=rev Log: Cleaned up step logging a bit. Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp lldb/trunk/source/Target/Thread.cpp lldb/trunk/source/Target/ThreadList.cpp lldb/trunk/source/Target/ThreadPlan.cpp lldb/trunk/source/lldb.cpp Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=113023&r1=113022&r2=113023&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Fri Sep 3 17:45:01 2010 @@ -404,7 +404,7 @@ 3, 3)) { - result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%d\"\n", i); + result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i); result.SetStatus (eReturnStatusFailed); return false; } Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=113023&r1=113022&r2=113023&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Fri Sep 3 17:45:01 2010 @@ -1436,7 +1436,7 @@ if (thread_sp.get()) resume_signal = thread_sp->GetResumeSignal(); if (log) - log->Printf ("Replying to exception %d for thread 0x%4.4x (resume_signal = %i).", std::distance(begin, pos), thread_sp->GetID(), resume_signal); + log->Printf ("Replying to exception %d, tid = 0x%4.4x, resume_signal = %i", std::distance(begin, pos), thread_sp->GetID(), resume_signal); Error curr_error (pos->Reply (Task().GetTaskPort(), GetID(), resume_signal)); // Only report the first error Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=113023&r1=113022&r2=113023&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Fri Sep 3 17:45:01 2010 @@ -360,7 +360,7 @@ { StreamString s; thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull); - log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.", + log->Printf("Pushing plan: \"%s\", tid = 0x%4.4x, immediate = %s.", s.GetData(), thread_plan_sp->GetThread().GetID(), thread_plan_sp->IsImmediate() ? "true" : "false"); @@ -378,7 +378,7 @@ ThreadPlanSP &plan = m_immediate_plan_stack.back(); if (log) { - log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID()); + log->Printf("Popping plan: \"%s\", tid = 0x%4.4x, immediate = true.", plan->GetName(), plan->GetThread().GetID()); } plan->WillPop(); m_immediate_plan_stack.pop_back(); @@ -390,7 +390,7 @@ ThreadPlanSP &plan = m_plan_stack.back(); if (log) { - log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID()); + log->Printf("Popping plan: \"%s\", tid = 0x%4.4x, immediate = false.", plan->GetName(), plan->GetThread().GetID()); } m_completed_plan_stack.push_back (plan); plan->WillPop(); @@ -535,7 +535,7 @@ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); if (log) { - log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force); + log->Printf("Discarding thread plans for thread (tid = 0x%4.4x, force %d)", GetID(), force); } if (force) @@ -726,8 +726,9 @@ Thread::DumpThreadPlans (lldb_private::Stream *s) const { uint32_t stack_size = m_plan_stack.size(); - s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x - %d elements.\n", GetIndexID(), GetID(), stack_size); - for (int i = stack_size - 1; i > 0; i--) + int i; + s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x, stack_size = %d\n", GetIndexID(), GetID(), stack_size); + for (i = stack_size - 1; i >= 0; i--) { s->Printf ("Element %d: ", i); s->IndentMore(); @@ -738,7 +739,7 @@ stack_size = m_immediate_plan_stack.size(); s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size); - for (int i = stack_size - 1; i > 0; i--) + for (i = stack_size - 1; i >= 0; i--) { s->Printf ("Element %d: ", i); s->IndentMore(); @@ -749,7 +750,7 @@ stack_size = m_completed_plan_stack.size(); s->Printf ("Completed Plan Stack: %d elements.\n", stack_size); - for (int i = stack_size - 1; i > 0; i--) + for (i = stack_size - 1; i >= 0; i--) { s->Printf ("Element %d: ", i); s->IndentMore(); @@ -760,7 +761,7 @@ stack_size = m_discarded_plan_stack.size(); s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size); - for (int i = stack_size - 1; i > 0; i--) + for (int i = stack_size - 1; i >= 0; i--) { s->Printf ("Element %d: ", i); s->IndentMore(); Modified: lldb/trunk/source/Target/ThreadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=113023&r1=113022&r2=113023&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadList.cpp (original) +++ lldb/trunk/source/Target/ThreadList.cpp Fri Sep 3 17:45:01 2010 @@ -187,7 +187,7 @@ collection::iterator pos, end = m_threads.end(); if (log) - log->Printf ("%s %zu threads\n", __FUNCTION__, m_threads.size()); + log->Printf ("%s %zu threads", __FUNCTION__, m_threads.size()); // Run through the threads and ask whether we should stop. Don't ask // suspended threads, however, it makes more sense for them to preserve their @@ -196,33 +196,39 @@ { ThreadSP thread_sp(*pos); - if (log) - log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx ", __FUNCTION__, thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC()); - if (thread_sp->GetResumeState () == eStateSuspended) { if (log) - log->Printf("ignore: thread was suspended\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC()); + log->Printf ("%s tid = 0x%4.4x, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)", + __FUNCTION__, + thread_sp->GetID (), + thread_sp->GetRegisterContext()->GetPC()); continue; } if (thread_sp->ThreadStoppedForAReason() == false) { if (log) - log->Printf("ignore: no stop reason\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC()); + log->Printf ("%s tid = 0x%4.4x, pc = 0x%16.16llx, should_stop = 0 (ignore since no stop reason)", + __FUNCTION__, + thread_sp->GetID (), + thread_sp->GetRegisterContext()->GetPC()); continue; - } const bool thread_should_stop = thread_sp->ShouldStop(event_ptr); if (log) - log->Printf("should_stop = %i\n", thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC(), thread_should_stop); + log->Printf ("%s tid = 0x%4.4x, pc = 0x%16.16llx, should_stop = %i", + __FUNCTION__, + thread_sp->GetID (), + thread_sp->GetRegisterContext()->GetPC(), + thread_should_stop); if (thread_should_stop) should_stop |= true; } if (log) - log->Printf ("%s overall should_stop = %i\n", __FUNCTION__, should_stop); + log->Printf ("%s overall should_stop = %i", __FUNCTION__, should_stop); if (should_stop) { @@ -248,7 +254,7 @@ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); if (log) - log->Printf ("%s %zu threads\n", __FUNCTION__, m_threads.size()); + log->Printf ("%s %zu threads", __FUNCTION__, m_threads.size()); // Run through the threads and ask whether we should report this event. // For stopping, a YES vote wins over everything. A NO vote wins over NO opinion. @@ -259,7 +265,7 @@ { const lldb::Vote vote = thread_sp->ShouldReportStop (event_ptr); if (log) - log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx vote: %s\n", + log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx, vote = %s", __FUNCTION__, thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC(), @@ -281,7 +287,7 @@ else { if (log) - log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx voted %s, but lost out because result was %s\n", + log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx voted %s, but lost out because result was %s", __FUNCTION__, thread_sp->GetID (), thread_sp->GetRegisterContext()->GetPC(), @@ -293,7 +299,7 @@ } } if (log) - log->Printf ("%s returning %s\n", __FUNCTION__, GetVoteAsCString (result)); + log->Printf ("%s returning %s", __FUNCTION__, GetVoteAsCString (result)); return result; } Modified: lldb/trunk/source/Target/ThreadPlan.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlan.cpp?rev=113023&r1=113022&r2=113023&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlan.cpp (original) +++ lldb/trunk/source/Target/ThreadPlan.cpp Fri Sep 3 17:45:01 2010 @@ -98,12 +98,12 @@ { Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); if (log) - log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote %s\n", GetVoteAsCString (prev_vote)); + log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", GetVoteAsCString (prev_vote)); return prev_vote; } } if (log) - log->Printf ("ThreadPlan::ShouldReportStop() returning vote %s\n", GetVoteAsCString (m_stop_vote)); + log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote)); return m_stop_vote; } @@ -143,7 +143,8 @@ addr_t pc = reg_ctx->GetPC(); addr_t sp = reg_ctx->GetSP(); addr_t fp = reg_ctx->GetFP(); - log->Printf("Thread #%u: tid = 0x%4.4x (pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx) about to resume the \"%s\" plan - state: %s - stop others: %d.", + log->Printf("%s Thread #%u: tid = 0x%4.4x, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, plan = '%s', state = %s, stop others = %d", + __FUNCTION__, m_thread.GetIndexID(), m_thread.GetID(), (uint64_t)pc, Modified: lldb/trunk/source/lldb.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=113023&r1=113022&r2=113023&view=diff ============================================================================== --- lldb/trunk/source/lldb.cpp (original) +++ lldb/trunk/source/lldb.cpp Fri Sep 3 17:45:01 2010 @@ -134,9 +134,14 @@ const char * lldb_private::GetVoteAsCString (lldb::Vote vote) { - static const char * g_vote_cstrings[] = { "no", "no opinion", "yes" }; - if (vote >= eVoteNo && vote <= eVoteYes) - return g_vote_cstrings[vote-1]; + switch (vote) + { + case eVoteNo: return "no"; + case eVoteNoOpinion: return "no opinion"; + case eVoteYes: return "yes"; + default: + break; + } return "invalid"; } From johnny.chen at apple.com Fri Sep 3 18:10:24 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 03 Sep 2010 23:10:24 -0000 Subject: [Lldb-commits] [lldb] r113028 - /lldb/trunk/test/enum_types/TestEnumTypes.py Message-ID: <20100903231024.AD98C2A6C12C@llvm.org> Author: johnny Date: Fri Sep 3 18:10:24 2010 New Revision: 113028 URL: http://llvm.org/viewvc/llvm-project?rev=113028&view=rev Log: Converted TestEnumTypes.py to Dsym/Dwarf combination. Marked test_with_dwarf() as expectedFailure where 'image lookup -t days' returns nothing. Modified: lldb/trunk/test/enum_types/TestEnumTypes.py Modified: lldb/trunk/test/enum_types/TestEnumTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/enum_types/TestEnumTypes.py?rev=113028&r1=113027&r2=113028&view=diff ============================================================================== --- lldb/trunk/test/enum_types/TestEnumTypes.py (original) +++ lldb/trunk/test/enum_types/TestEnumTypes.py Fri Sep 3 18:10:24 2010 @@ -9,7 +9,21 @@ mydir = "enum_types" - def test_image_lookup_for_enum_type(self): + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test 'image lookup -t days' and check for correct display.""" + self.buildDsym() + self.image_lookup_for_enum_type() + + # rdar://problem/8394746 + # 'image lookup -t days' returns nothing with dwarf debug format. + @unittest2.expectedFailure + def test_with_dwarf(self): + """Test 'image lookup -t days' and check for correct display.""" + self.buildDwarf() + self.image_lookup_for_enum_type() + + def image_lookup_for_enum_type(self): """Test 'image lookup -t days' and check for correct display.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From johnny.chen at apple.com Fri Sep 3 18:14:26 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 03 Sep 2010 23:14:26 -0000 Subject: [Lldb-commits] [lldb] r113029 - /lldb/trunk/test/function_types/TestFunctionTypes.py Message-ID: <20100903231426.D7D9D2A6C12C@llvm.org> Author: johnny Date: Fri Sep 3 18:14:26 2010 New Revision: 113029 URL: http://llvm.org/viewvc/llvm-project?rev=113029&view=rev Log: Converted TestFunctionTypes.py to Dsym/Dwarf combination. Modified: lldb/trunk/test/function_types/TestFunctionTypes.py Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=113029&r1=113028&r2=113029&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Fri Sep 3 18:14:26 2010 @@ -9,7 +9,18 @@ mydir = "function_types" - def test_function_types(self): + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test 'callback' has function ptr type, then break on the function.""" + self.buildDsym() + self.function_types() + + def test_with_dwarf(self): + """Test 'callback' has function ptr type, then break on the function.""" + self.buildDwarf() + self.function_types() + + def function_types(self): """Test 'callback' has function ptr type, then break on the function.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From johnny.chen at apple.com Fri Sep 3 18:16:49 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 03 Sep 2010 23:16:49 -0000 Subject: [Lldb-commits] [lldb] r113030 - /lldb/trunk/test/global_variables/TestGlobalVariables.py Message-ID: <20100903231649.764D42A6C12C@llvm.org> Author: johnny Date: Fri Sep 3 18:16:49 2010 New Revision: 113030 URL: http://llvm.org/viewvc/llvm-project?rev=113030&view=rev Log: Converted TestGlobalVariables.py to Dsym/Dwarf combination. Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=113030&r1=113029&r2=113030&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Fri Sep 3 18:16:49 2010 @@ -9,7 +9,18 @@ mydir = "global_variables" - def test_global_variables(self): + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test 'frame variable -s -a' which omits args and shows scopes.""" + self.buildDsym() + self.global_variables() + + def test_with_dwarf(self): + """Test 'frame variable -s -a' which omits args and shows scopes.""" + self.buildDwarf() + self.global_variables() + + def global_variables(self): """Test 'frame variable -s -a' which omits args and shows scopes.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From gclayton at apple.com Fri Sep 3 18:26:12 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 03 Sep 2010 23:26:12 -0000 Subject: [Lldb-commits] [lldb] r113032 - in /lldb/trunk: include/lldb/Core/ConstString.h lldb.xcodeproj/project.pbxproj source/Core/ConstString.cpp source/Core/Mangled.cpp source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Message-ID: <20100903232612.62B682A6C12C@llvm.org> Author: gclayton Date: Fri Sep 3 18:26:12 2010 New Revision: 113032 URL: http://llvm.org/viewvc/llvm-project?rev=113032&view=rev Log: Improved name demangling performance by 20% on darwin. Modified: lldb/trunk/include/lldb/Core/ConstString.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Core/ConstString.cpp lldb/trunk/source/Core/Mangled.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Modified: lldb/trunk/include/lldb/Core/ConstString.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConstString.h?rev=113032&r1=113031&r2=113032&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ConstString.h (original) +++ lldb/trunk/include/lldb/Core/ConstString.h Fri Sep 3 18:26:12 2010 @@ -290,7 +290,11 @@ /// @li \b false if the contained string is not empty. //------------------------------------------------------------------ bool - IsEmpty () const; + IsEmpty () const + { + return m_string == NULL || m_string[0] == '\0'; + } + //------------------------------------------------------------------ /// Set the C string value. Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=113032&r1=113031&r2=113032&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 3 18:26:12 2010 @@ -2295,6 +2295,7 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, Modified: lldb/trunk/source/Core/ConstString.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConstString.cpp?rev=113032&r1=113031&r2=113032&view=diff ============================================================================== --- lldb/trunk/source/Core/ConstString.cpp (original) +++ lldb/trunk/source/Core/ConstString.cpp Fri Sep 3 18:26:12 2010 @@ -391,15 +391,6 @@ } //---------------------------------------------------------------------- -// Returns true if the contained string is empty. -//---------------------------------------------------------------------- -bool -ConstString::IsEmpty() const -{ - return m_string == NULL || m_string[0] == '\0'; -} - -//---------------------------------------------------------------------- // Set the string value in the object by uniquing the "cstr" string // value in our global string pool. // Modified: lldb/trunk/source/Core/Mangled.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Mangled.cpp?rev=113032&r1=113031&r2=113032&view=diff ============================================================================== --- lldb/trunk/source/Core/Mangled.cpp (original) +++ lldb/trunk/source/Core/Mangled.cpp Fri Sep 3 18:26:12 2010 @@ -9,6 +9,8 @@ #include +#include "llvm/ADT/DenseMap.h" + #include "lldb/Core/ConstString.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Stream.h" @@ -142,18 +144,47 @@ const char * mangled = m_mangled.AsCString(); if (mangled[0]) { - char *demangled_name = abi::__cxa_demangle (mangled, NULL, NULL, NULL); - - if (demangled_name) + // Since demangling can be a costly, and since all names that go + // into a ConstString (like our m_mangled and m_demangled members) + // end up being unique "const char *" values, we can use a DenseMap + // to speed up our lookup. We do this because often our symbol table + // and our debug information both have the mangled names which they + // would each need to demangle. Also, with GCC we end up with the one + // definition rule where a lot of STL code produces symbols that are + // in multiple compile units and the mangled names end up being in + // the same binary multiple times. The performance win isn't huge, + // but we showed a 20% improvement on darwin. + typedef llvm::DenseMap MangledToDemangledMap; + static MangledToDemangledMap g_mangled_to_demangled; + + // Check our mangled string pointer to demangled string pointer map first + MangledToDemangledMap::const_iterator pos = g_mangled_to_demangled.find (mangled); + if (pos != g_mangled_to_demangled.end()) { - m_demangled.SetCString (demangled_name); - free (demangled_name); + // We have already demangled this string, we can just use our saved result! + m_demangled.SetCString(pos->second); } else { - // Set the demangled string to the empty string to indicate we - // tried to parse it once and failed. - m_demangled.SetCString(""); + // We didn't already mangle this name, demangle it and if all goes well + // add it to our map. + char *demangled_name = abi::__cxa_demangle (mangled, NULL, NULL, NULL); + + if (demangled_name) + { + m_demangled.SetCString (demangled_name); + // Now that the name has been uniqued, add the uniqued C string + // pointer from m_mangled as the key to the uniqued C string + // pointer in m_demangled. + g_mangled_to_demangled.insert (std::make_pair (mangled, m_demangled.GetCString())); + free (demangled_name); + } + else + { + // Set the demangled string to the empty string to indicate we + // tried to parse it once and failed. + m_demangled.SetCString(""); + } } } } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=113032&r1=113031&r2=113032&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Fri Sep 3 18:26:12 2010 @@ -9,6 +9,7 @@ #include "DWARFCompileUnit.h" +#include "lldb/Core/Mangled.h" #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" @@ -591,7 +592,7 @@ DWARFDebugInfoEntry::Attributes attributes; const char *name = NULL; - const char *mangled = NULL; + Mangled mangled; bool is_variable = false; bool is_declaration = false; bool is_artificial = false; @@ -629,7 +630,7 @@ case DW_AT_MIPS_linkage_name: if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) - mangled = form_value.AsCString(debug_str); + mangled.GetMangledName().SetCString(form_value.AsCString(debug_str)); break; case DW_AT_low_pc: @@ -761,8 +762,10 @@ else base_name_to_function_die.Append(ConstString(name).AsCString(), die.GetOffset()); } - if (mangled) - full_name_to_function_die.Append(ConstString(mangled).AsCString(), die.GetOffset()); + if (mangled.GetMangledName()) + full_name_to_function_die.Append(mangled.GetMangledName().AsCString(), die.GetOffset()); + if (mangled.GetDemangledName()) + full_name_to_function_die.Append(mangled.GetDemangledName().AsCString(), die.GetOffset()); } break; @@ -771,8 +774,10 @@ { if (name) base_name_to_function_die.Append(ConstString(name).AsCString(), die.GetOffset()); - if (mangled) - full_name_to_function_die.Append(ConstString(mangled).AsCString(), die.GetOffset()); + if (mangled.GetMangledName()) + full_name_to_function_die.Append(mangled.GetMangledName().AsCString(), die.GetOffset()); + if (mangled.GetDemangledName()) + full_name_to_function_die.Append(mangled.GetDemangledName().AsCString(), die.GetOffset()); } break; From johnny.chen at apple.com Fri Sep 3 18:49:17 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 03 Sep 2010 23:49:17 -0000 Subject: [Lldb-commits] [lldb] r113037 - in /lldb/trunk/test: lldbtest.py macosx/universal/TestUniversal.py plugins/darwin.py Message-ID: <20100903234917.281372A6C12C@llvm.org> Author: johnny Date: Fri Sep 3 18:49:16 2010 New Revision: 113037 URL: http://llvm.org/viewvc/llvm-project?rev=113037&view=rev Log: Marked test_process_launch_for_universal() test case as requiring 'darwin' and 'i386' in order to be run. And added a default build phase at the beginning of the method. Modified: lldb/trunk/test/lldbtest.py lldb/trunk/test/macosx/universal/TestUniversal.py lldb/trunk/test/plugins/darwin.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=113037&r1=113036&r2=113037&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Sep 3 18:49:16 2010 @@ -458,6 +458,12 @@ # End of while loop. + def buildDefault(self): + """Platform specific way to build the default binaries.""" + module = __import__(sys.platform) + if not module.buildDefault(): + raise Exception("Don't know how to build default binary") + def buildDsym(self): """Platform specific way to build binaries with dsym info.""" module = __import__(sys.platform) Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=113037&r1=113036&r2=113037&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Fri Sep 3 18:49:16 2010 @@ -9,9 +9,14 @@ mydir = "macosx/universal" + @unittest2.skipUnless(sys.platform.startswith("darwin") and os.uname()[4]=='i386', + "requires Darwin & i386") def test_process_launch_for_universal(self): """Test process launch of a universal binary.""" + # Invoke the default build rule. + self.buildDefault() + # Note that "testit" is a universal binary. exe = os.path.join(os.getcwd(), "testit") Modified: lldb/trunk/test/plugins/darwin.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/plugins/darwin.py?rev=113037&r1=113036&r2=113037&view=diff ============================================================================== --- lldb/trunk/test/plugins/darwin.py (original) +++ lldb/trunk/test/plugins/darwin.py Fri Sep 3 18:49:16 2010 @@ -2,6 +2,12 @@ #print "Hello, darwin plugin!" +def buildDefault(): + lldbtest.system(["/bin/sh", "-c", "make clean; make"]) + + # True signifies that we can handle building default. + return True + def buildDsym(): lldbtest.system(["/bin/sh", "-c", "make clean; make MAKE_DSYM=YES"]) From johnny.chen at apple.com Fri Sep 3 18:52:15 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 03 Sep 2010 23:52:15 -0000 Subject: [Lldb-commits] [lldb] r113039 - /lldb/trunk/test/load_unload/TestLoadUnload.py Message-ID: <20100903235215.4E74A2A6C12C@llvm.org> Author: johnny Date: Fri Sep 3 18:52:15 2010 New Revision: 113039 URL: http://llvm.org/viewvc/llvm-project?rev=113039&view=rev Log: Added a default build phase at the beginning of test_load_unload() test case. Modified: lldb/trunk/test/load_unload/TestLoadUnload.py Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=113039&r1=113038&r2=113039&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Fri Sep 3 18:52:15 2010 @@ -13,6 +13,10 @@ def test_load_unload(self): """Test breakpoint by name works correctly with dlopen'ing.""" + + # Invoke the default build rule. + self.buildDefault() + exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From ctice at apple.com Fri Sep 3 19:03:46 2010 From: ctice at apple.com (Caroline Tice) Date: Sat, 04 Sep 2010 00:03:46 -0000 Subject: [Lldb-commits] [lldb] r113041 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Target/ lldb.xcodeproj/ source/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Target/ tools/driver/ Message-ID: <20100904000346.ACF472A6C12C@llvm.org> Author: ctice Date: Fri Sep 3 19:03:46 2010 New Revision: 113041 URL: http://llvm.org/viewvc/llvm-project?rev=113041&view=rev Log: This is a very large commit that completely re-does the way lldb handles user settable internal variables (the equivalent of set/show variables in gdb). In addition to the basic infrastructure (most of which is defined in UserSettingsController.{h,cpp}, there are examples of two classes that have been set up to contain user settable variables (the Debugger and Process classes). The 'settings' command has been modified to be a command-subcommand structure, and the 'set', 'show' and 'append' commands have been moved into this sub-commabnd structure. The old StateVariable class has been completely replaced by this, and the state variable dictionary has been removed from the Command Interpreter. Places that formerly accessed the state variable mechanism have been modified to access the variables in this new structure instead (checking the term-width; getting/checking the prompt; etc.) Variables are attached to classes; there are two basic "flavors" of variables that can be set: "global" variables (static/class-wide), and "instance" variables (one per instance of the class). The whole thing has been set up so that any global or instance variable can be set at any time (e.g. on start up, in your .lldbinit file), whether or not any instances actually exist (there's a whole pending and default values mechanism to help deal with that). Added: lldb/trunk/include/lldb/Core/UserSettingsController.h lldb/trunk/source/Core/UserSettingsController.cpp Removed: lldb/trunk/include/lldb/Interpreter/StateVariable.h lldb/trunk/source/Commands/CommandObjectAppend.cpp lldb/trunk/source/Commands/CommandObjectAppend.h lldb/trunk/source/Commands/CommandObjectSet.cpp lldb/trunk/source/Commands/CommandObjectSet.h lldb/trunk/source/Commands/CommandObjectShow.cpp lldb/trunk/source/Commands/CommandObjectShow.h lldb/trunk/source/Interpreter/StateVariable.cpp Modified: lldb/trunk/include/lldb/API/SBCommandInterpreter.h lldb/trunk/include/lldb/API/SBDebugger.h lldb/trunk/include/lldb/API/SBDefines.h lldb/trunk/include/lldb/API/SBError.h lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Interpreter/CommandCompletions.h lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h lldb/trunk/include/lldb/Target/Process.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/API/SBCommandInterpreter.cpp lldb/trunk/source/API/SBDebugger.cpp lldb/trunk/source/Commands/CommandCompletions.cpp lldb/trunk/source/Commands/CommandObjectHelp.cpp lldb/trunk/source/Commands/CommandObjectProcess.cpp lldb/trunk/source/Commands/CommandObjectSettings.cpp lldb/trunk/source/Commands/CommandObjectSettings.h lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Interpreter/Options.cpp lldb/trunk/source/Interpreter/ScriptInterpreter.cpp lldb/trunk/source/Target/Process.cpp lldb/trunk/source/lldb.cpp lldb/trunk/tools/driver/Driver.cpp Modified: lldb/trunk/include/lldb/API/SBCommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCommandInterpreter.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBCommandInterpreter.h (original) +++ lldb/trunk/include/lldb/API/SBCommandInterpreter.h Fri Sep 3 19:03:46 2010 @@ -42,8 +42,8 @@ lldb::SBBroadcaster GetBroadcaster (); - const char ** - GetEnvironmentVariables (); + //const char ** + //GetEnvironmentVariables (); bool HasCommands (); @@ -57,8 +57,8 @@ bool HasAliasOptions (); - bool - HasInterpreterVariables (); + //bool + //HasInterpreterVariables (); lldb::SBProcess GetProcess (); Modified: lldb/trunk/include/lldb/API/SBDebugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDebugger.h (original) +++ lldb/trunk/include/lldb/API/SBDebugger.h Fri Sep 3 19:03:46 2010 @@ -145,6 +145,12 @@ static SBDebugger FindDebuggerWithID (int id); + lldb::SBError + SetInternalVariable (const char *var_name, const char *value); + + lldb::SBStringList + GetInternalVariableValue (const char *var_name); + private: #ifndef SWIG Modified: lldb/trunk/include/lldb/API/SBDefines.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDefines.h (original) +++ lldb/trunk/include/lldb/API/SBDefines.h Fri Sep 3 19:03:46 2010 @@ -50,6 +50,7 @@ class SBModule; class SBProcess; class SBSourceManager; +class SBStringList; class SBSymbol; class SBSymbolContext; class SBStringList; Modified: lldb/trunk/include/lldb/API/SBError.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBError.h (original) +++ lldb/trunk/include/lldb/API/SBError.h Fri Sep 3 19:03:46 2010 @@ -67,6 +67,7 @@ protected: friend class SBArguments; + friend class SBDebugger; friend class SBCommunication; friend class SBHostOS; friend class SBInputReader; Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Fri Sep 3 19:03:46 2010 @@ -22,6 +22,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/UserID.h" +#include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/TargetList.h" @@ -33,11 +34,112 @@ /// /// Provides a global root objects for the debugger core. //---------------------------------------------------------------------- + + +class DebuggerInstanceSettings : public InstanceSettings +{ +public: + + DebuggerInstanceSettings (UserSettingsController &owner, const char *name = NULL); + + DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs); + + virtual + ~DebuggerInstanceSettings (); + + DebuggerInstanceSettings& + operator= (const DebuggerInstanceSettings &rhs); + + void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending); + + void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value); + +protected: + + void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending); + + bool + BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt); + + const ConstString + CreateInstanceName (); + + const ConstString & + PromptVarName (); + + const ConstString & + ScriptLangVarName (); + +private: + + std::string m_prompt; + lldb::ScriptLanguage m_script_lang; +}; + + + class Debugger : - public UserID + public UserID, + public DebuggerInstanceSettings { public: + class DebuggerSettingsController : public UserSettingsController + { + public: + + DebuggerSettingsController (); + + virtual + ~DebuggerSettingsController (); + + void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err); + + void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value); + + static SettingEntry global_settings_table[]; + static SettingEntry instance_settings_table[]; + + protected: + + lldb::InstanceSettingsSP + CreateNewInstanceSettings (); + + bool + ValidTermWidthValue (const char *value, Error err); + + private: + + // Class-wide settings. + int m_term_width; + + DISALLOW_COPY_AND_ASSIGN (DebuggerSettingsController); + }; + + static lldb::UserSettingsControllerSP & + GetSettingsController (bool finish = false); + static lldb::DebuggerSP CreateInstance (); @@ -137,7 +239,6 @@ return m_exe_ctx; } - void UpdateExecutionContext (ExecutionContext *override_context); @@ -158,6 +259,9 @@ return m_use_external_editor; } + static lldb::DebuggerSP + FindDebuggerWithInstanceName (const ConstString &instance_name); + protected: static void @@ -192,8 +296,6 @@ // debugger object Debugger (); - - DISALLOW_COPY_AND_ASSIGN (Debugger); }; Added: lldb/trunk/include/lldb/Core/UserSettingsController.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/UserSettingsController.h?rev=113041&view=auto ============================================================================== --- lldb/trunk/include/lldb/Core/UserSettingsController.h (added) +++ lldb/trunk/include/lldb/Core/UserSettingsController.h Fri Sep 3 19:03:46 2010 @@ -0,0 +1,380 @@ +//====-- UserSettingsController.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_UserSettingsController_h_ +#define liblldb_UserSettingsController_h_ + +// C Includes +// C++ Includes + +#include +#include + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/StringList.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +typedef struct +{ + const char *var_name; + lldb::SettableVariableType var_type; + const char *default_value; + lldb::OptionEnumValueElement *enum_values; + bool initialized; + bool hidden; + const char *description; //help text +} SettingEntry; + + +typedef struct +{ + lldb::UserSettingsControllerSP parent; + ConstString level_name; + std::vector global_settings; + std::vector instance_settings; +} UserSettingDefinition; + +class UserSettingsController +{ +public: + + UserSettingsController (const char *level_name, + const lldb::UserSettingsControllerSP &parent); + + virtual + ~UserSettingsController (); + + // Pure virtual functions, which all sub-classes must implement. + + virtual lldb::InstanceSettingsSP + CreateNewInstanceSettings () = 0; + + virtual void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + const lldb::VarSetOperationType op, + Error &err) = 0; + + virtual void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) = 0; + + // End of pure virtual functions. + + Error + SetVariable (const char *full_dot_name, + const char *value, + const lldb::VarSetOperationType op, + const bool override, + const char *index_value = NULL); + + StringList + GetVariable (const char *full_dot_name, + lldb::SettableVariableType &var_type); + + const lldb::UserSettingsControllerSP & + GetParent (); + + const ConstString & + GetLevelName (); + + void + RegisterChild (const lldb::UserSettingsControllerSP &child); + + void + RemoveChild (const lldb::UserSettingsControllerSP &child); + + void + CreateSettingsVector (const SettingEntry *table, + const bool global); + + void + CreateDefaultInstanceSettings (); + + void + InitializeGlobalVariables (); + + const lldb::InstanceSettingsSP & + FindPendingSettings (const ConstString &instance_name); + + void + RemovePendingSettings (const ConstString &instance_name); + + void + RegisterInstanceSettings (InstanceSettings *instance_settings); + + void + UnregisterInstanceSettings (InstanceSettings *instance_settings); + + // ------------------------------------------------------------------------- + // Public static methods + // ------------------------------------------------------------------------- + + static void + FindAllSettingsDescriptions (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err); + + static void + GetAllVariableValues (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err); + + static int + CompleteSettingsNames (lldb::UserSettingsControllerSP root_settings, + Args &partial_setting_name_pieces, + bool &word_complete, + StringList &matches); + + static int + CompleteSettingsValue (lldb::UserSettingsControllerSP root_settings, + const char *full_dot_name, + const char *partial_value, + bool &word_complete, + StringList &matches); + + static Args + BreakNameIntoPieces (const char *full_dot_name); + + static const char * + GetTypeString (lldb::SettableVariableType var_type); + + + static const char * + EnumToString (const lldb::OptionEnumValueElement *enum_values, int value); + + static void + UpdateStringVariable (lldb::VarSetOperationType op, + std::string &string_var, + const char *new_value, + Error &err); + + + static void + UpdateBooleanVariable (lldb::VarSetOperationType op, + bool &bool_var, + const char *new_value, + Error &err); + + static void + UpdateStringArrayVariable (lldb::VarSetOperationType op, + const char *index_value, + Args &array_var, + const char *new_value, + Error &err); + + static void + UpdateDictionaryVariable (lldb::VarSetOperationType op, + const char *index_value, + std::map &dictionary, + const char *new_value, + Error &err); + + static void + UpdateEnumVariable (lldb::OptionEnumValueElement *enum_values, + int *enum_var, + const char *new_value, + Error &err); + +protected: + + // ------------------------------------------------------------------------- + // Protected methods are declared below here. + // ------------------------------------------------------------------------- + + bool + IsLiveInstance (const std::string &instance_name); + + int + GlobalVariableMatches (const char *partial_name, + const std::string &complete_prefix, + StringList &matches); + + int + InstanceVariableMatches (const char *partial_name, + const std::string &complete_prefix, + const char *instance_name, + StringList &matches); + + int + LiveInstanceMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches); + + int + ChildMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches); + + + size_t + GetNumChildren (); + + const lldb::UserSettingsControllerSP + GetChildAtIndex (size_t index); + + + const SettingEntry * + GetGlobalEntry (const ConstString &var_name); + + const SettingEntry * + GetInstanceEntry (const ConstString &var_name); + + void + BuildParentPrefix (std::string &parent_prefix); + + + void + CopyDefaultSettings (const lldb::InstanceSettingsSP &new_settings, + const ConstString &instance_name, + bool pending); + + lldb::InstanceSettingsSP + PendingSettingsForInstance (const ConstString &instance_name); + + InstanceSettings * + FindSettingsForInstance (const ConstString &instance_name); + + void + GetAllPendingSettingValues (StreamString &result_stream); + + void + GetAllDefaultSettingValues (StreamString &result_stream); + + void + GetAllInstanceVariableValues (CommandInterpreter &interpreter, + StreamString &result_stream); + + void + OverrideAllInstances (const ConstString &var_name, + const char *value, + lldb::VarSetOperationType op, + const char *index_value, + Error &err); + + UserSettingDefinition & + GetControllerSettings () { return m_settings; } + + // ------------------------------------------------------------------------- + // Static protected methods are declared below here. + // ------------------------------------------------------------------------- + + static void + PrintEnumValues (const lldb::OptionEnumValueElement *enum_values, Stream &str); + + + static int + BooleanMatches (const char *partial_value, + bool &word_complete, + StringList &matches); + + static int + EnumMatches (const char *partial_value, + lldb::OptionEnumValueElement *enum_values, + bool &word_complete, + StringList &matches); + + static void + VerifyOperationForType (lldb::SettableVariableType var_type, + lldb::VarSetOperationType op, + const ConstString &var_name, + Error &err); + + // This is protected rather than private so that classes that inherit from UserSettingsController can access it. + + lldb::InstanceSettingsSP m_default_settings; + +private: + + UserSettingDefinition m_settings; + + std::vector m_children; + std::map m_pending_settings; + std::map m_live_settings; // live settings should never be NULL (hence 'live') + + mutable Mutex m_children_mutex; + mutable Mutex m_pending_settings_mutex; + mutable Mutex m_live_settings_mutex; + + DISALLOW_COPY_AND_ASSIGN (UserSettingsController); +}; + +class InstanceSettings +{ +public: + + InstanceSettings (UserSettingsController &owner, const char *instance_name); + + InstanceSettings (const InstanceSettings &rhs); + + virtual + ~InstanceSettings (); + + InstanceSettings& + operator= (const InstanceSettings &rhs); + + // Begin Pure Virtual Functions + + virtual void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) = 0; + + virtual void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) = 0; + + virtual void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) = 0; + + virtual const ConstString + CreateInstanceName () = 0; + + // End Pure Virtual Functions + + const ConstString & + GetInstanceName () { return m_instance_name; } + + static const ConstString & + GetDefaultName (); + +protected: + + UserSettingsController &m_owner; + const ConstString m_instance_name; +}; + + + +} // namespace lldb_private + +#endif // liblldb_UserSettingsController_h_ Modified: lldb/trunk/include/lldb/Interpreter/CommandCompletions.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandCompletions.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandCompletions.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandCompletions.h Fri Sep 3 19:03:46 2010 @@ -44,7 +44,8 @@ eDiskDirectoryCompletion = (1 << 2), eSymbolCompletion = (1 << 3), eModuleCompletion = (1 << 4), - eCustomCompletion = (1 << 5) // This item serves two purposes. It is the last element in the enum, + eSettingsNameCompletion = (1 << 5), + eCustomCompletion = (1 << 6) // This item serves two purposes. It is the last element in the enum, // so you can add custom enums starting from here in your Option class. // Also if you & in this bit the base code will not process the option. @@ -112,6 +113,15 @@ bool &word_complete, lldb_private::StringList &matches); + static int + SettingsNames (CommandInterpreter &interpreter, + const char *partial_file_name, + int match_start_point, + int max_return_elements, + SearchFilter *searcher, + bool &word_complete, + lldb_private::StringList &matches); + //---------------------------------------------------------------------- // The Completer class is a convenient base class for building searchers // that go along with the SearchFilter passed to the standard Completer Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Fri Sep 3 19:03:46 2010 @@ -20,7 +20,6 @@ #include "lldb/Core/Log.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/StateVariable.h" #include "lldb/Core/Event.h" #include "lldb/Interpreter/Args.h" #include "lldb/Core/StringList.h" @@ -30,7 +29,6 @@ class CommandInterpreter : public Broadcaster { public: - typedef std::map VariableMap; typedef std::map OptionArgMap; enum @@ -59,9 +57,6 @@ CommandObject * GetCommandObject (const char *cmd, StringList *matches = NULL); - StateVariable * - GetStateVariable(const char *name); - bool CommandExists (const char *cmd); @@ -148,27 +143,12 @@ const char *help_text, uint32_t max_word_len); - void - ShowVariableValues (CommandReturnObject &result); - - void - ShowVariableHelp (CommandReturnObject &result); - Debugger & GetDebugger () { return m_debugger; } - const Args * - GetProgramArguments (); - - const Args * - GetEnvironmentVariables (); - - int - GetDisableASLR (); - const char * ProcessEmbeddedScriptCommands (const char *arg); @@ -185,9 +165,6 @@ Initialize (); void - InitializeVariables (); - - void CrossRegisterCommand (const char * dest_cmd, const char * object_type); void @@ -206,9 +183,6 @@ bool HasAliasOptions (); - bool - HasInterpreterVariables (); - void BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, CommandReturnObject &result); @@ -255,12 +229,10 @@ private: Debugger &m_debugger; // The debugger session that this interpreter is associated with - lldb::ScriptLanguage m_script_language; bool m_synchronous_execution; CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten). CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands CommandObject::CommandMap m_user_dict; // Stores user-defined commands - VariableMap m_variables; OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias. std::vector m_command_history; std::string m_repeat_command; // Stores the command that will be executed for an empty command string. Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Fri Sep 3 19:03:46 2010 @@ -86,6 +86,9 @@ CommandInterpreter * GetCommandInterpreter (); + static std::string + LanguageToString (lldb::ScriptLanguage); + private: lldb::ScriptLanguage m_script_lang; Removed: lldb/trunk/include/lldb/Interpreter/StateVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/StateVariable.h?rev=113040&view=auto ============================================================================== --- lldb/trunk/include/lldb/Interpreter/StateVariable.h (original) +++ lldb/trunk/include/lldb/Interpreter/StateVariable.h (removed) @@ -1,145 +0,0 @@ -//===-- StateVariable.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_InterpreterStateVariable_h_ -#define liblldb_InterpreterStateVariable_h_ - -// C Includes -// C++ Includes -#include -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Interpreter/Args.h" - -namespace lldb_private { - -class StateVariable -{ -public: - - // NOTE: If you add more types to this enumeration list, you need to check for them and "do the right thing" - // in CommandObjectSet::Execute. - typedef enum - { - eTypeBoolean, - eTypeInteger, - eTypeString, - eTypeStringArray - } Type; - - - typedef bool (*Callback) (CommandInterpreter *, - void *, - CommandReturnObject &); - - StateVariable (const char *name, - const char *value, - bool can_append = false, - const char *help_text = "", - Callback func_ptr = NULL); - - StateVariable (const char *name, - bool value, - const char *help_text = "", - Callback func_ptr = NULL); - - StateVariable (const char *name, - int value, - const char *help_text = "", - Callback func_ptr = NULL); - - StateVariable (const char *name, - const Args *value, - const char *help_text = "", - Callback func_ptr = NULL); - - virtual - ~StateVariable (); - - - const char * - GetName () const; - - Type - GetType () const; - - int - GetIntValue () const; - - bool - GetBoolValue () const; - - const char * - GetStringValue () const; - - Args & - GetArgs (); - - const Args & - GetArgs () const; - - const char * - GetHelp () const; - - void - SetHelp (const char *); - - void - AppendVariableInformation (CommandReturnObject &result); - - void - SetStringValue (const char *); - - void - SetIntValue (int); - - void - SetBoolValue (bool); - - void - ArrayAppendValue (const char *); - - void - ArrayClearValues (); - - void - AppendStringValue (const char *new_string); - - bool - VerifyValue (CommandInterpreter *interpreter, - void *data, - CommandReturnObject &result); - - bool - HasVerifyFunction (); - - static bool - VerifyScriptLanguage (CommandInterpreter *interpreter, - void *data, - CommandReturnObject &result); - - static bool - BroadcastPromptChange (CommandInterpreter *interpreter, - void *data, - CommandReturnObject &result); - -private: - std::string m_name; - Type m_type; - int m_int_value; - Args m_string_values; - std::string m_help_text; - Callback m_verification_func_ptr; -}; - - -} // namespace lldb_private - -#endif // liblldb_InterpreterStateVariable_h_ Modified: lldb/trunk/include/lldb/Target/Process.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Process.h (original) +++ lldb/trunk/include/lldb/Target/Process.h Fri Sep 3 19:03:46 2010 @@ -17,6 +17,8 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" #include "lldb/Core/Event.h" @@ -24,6 +26,7 @@ #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/UserSettingsController.h" #include "lldb/Breakpoint/BreakpointSiteList.h" #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/IRDynamicChecks.h" @@ -34,6 +37,80 @@ namespace lldb_private { +class ProcessInstanceSettings : public InstanceSettings +{ +public: + + ProcessInstanceSettings (UserSettingsController &owner, const char *name = NULL); + + ProcessInstanceSettings (const ProcessInstanceSettings &rhs); + + virtual + ~ProcessInstanceSettings (); + + ProcessInstanceSettings& + operator= (const ProcessInstanceSettings &rhs); + + + void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending); + + void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value); + + +protected: + + void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending); + + const ConstString + CreateInstanceName (); + + const ConstString & + RunArgsVarName (); + + const ConstString & + EnvVarsVarName (); + + const ConstString & + InputPathVarName (); + + const ConstString & + OutputPathVarName (); + + const ConstString & + ErrorPathVarName (); + + const ConstString & + PluginVarName (); + + const ConstString & + DisableASLRVarName(); + + +private: + + Args m_run_args; + std::map m_env_vars; + std::string m_input_path; + std::string m_output_path; + std::string m_error_path; + lldb::ProcessPlugins m_plugin; + bool m_disable_aslr; +}; + + //---------------------------------------------------------------------- /// @class Process Process.h "lldb/Target/Process.h" /// @brief A plug-in interface definition class for debugging a process. @@ -42,7 +119,8 @@ public UserID, public Broadcaster, public ExecutionContextScope, - public PluginInterface + public PluginInterface, + public ProcessInstanceSettings { friend class ThreadList; @@ -145,8 +223,50 @@ DISALLOW_COPY_AND_ASSIGN (ProcessEventData); }; + + class ProcessSettingsController : public UserSettingsController + { + public: + + ProcessSettingsController (); + + virtual + ~ProcessSettingsController (); + + void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err); + + void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value); + + static SettingEntry global_settings_table[]; + static SettingEntry instance_settings_table[]; + + protected: + + lldb::InstanceSettingsSP + CreateNewInstanceSettings (); + + static lldb::OptionEnumValueElement g_plugins[]; + + private: + + // Class-wide settings. + + DISALLOW_COPY_AND_ASSIGN (ProcessSettingsController); + }; + #endif + static lldb::UserSettingsControllerSP + GetSettingsController (bool finish = false); + //------------------------------------------------------------------ /// Construct with a shared pointer to a target, and the Process listener. //------------------------------------------------------------------ @@ -1478,12 +1598,13 @@ size_t WriteMemoryPrivate (lldb::addr_t addr, const void *buf, size_t size, Error &error); - + private: //------------------------------------------------------------------ // For Process only //------------------------------------------------------------------ void ControlPrivateStateThread (uint32_t signal); + DISALLOW_COPY_AND_ASSIGN (Process); }; Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Sep 3 19:03:46 2010 @@ -478,6 +478,40 @@ eAccessPackage } AccessType; +//---------------------------------------------------------------------- +/// Settable state variable types. +/// +//---------------------------------------------------------------------- + +typedef enum SettableVariableType +{ + eSetVarTypeInt, + eSetVarTypeBool, + eSetVarTypeString, + eSetVarTypeArray, + eSetVarTypeDictionary, + eSetVarTypeEnum, + eSetVarTypeNone +} SettableVariableType; + +typedef enum VarSetOperationType +{ + eVarSetOperationReplace, + eVarSetOperationInsertBefore, + eVarSetOperationInsertAfter, + eVarSetOperationRemove, + eVarSetOperationAppend, + eVarSetOperationClear, + eVarSetOperationAssign, + eVarSetOperationInvalid +} VarSetOperationType; + +typedef enum ProcessPlugins +{ + eMacosx, + eRemoteDebugger +} ProcessPlugins; + } // namespace lldb Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Fri Sep 3 19:03:46 2010 @@ -39,6 +39,7 @@ typedef SharedPtr::Type FunctionSP; typedef SharedPtr::Type InlineFunctionInfoSP; typedef SharedPtr::Type InputReaderSP; + typedef SharedPtr::Type InstanceSettingsSP; typedef SharedPtr::Type LineTableSP; typedef SharedPtr::Type ListenerSP; typedef SharedPtr::Type LogSP; @@ -50,7 +51,6 @@ typedef SharedPtr::Type SearchFilterSP; typedef SharedPtr::Type StackFrameSP; typedef SharedPtr::Type StackFrameListSP; - typedef SharedPtr::Type StateVariableSP; typedef SharedPtr::Type StopInfoSP; typedef SharedPtr::Type StoppointLocationSP; typedef SharedPtr::Type StreamSP; @@ -59,6 +59,7 @@ typedef SharedPtr::Type ThreadSP; typedef SharedPtr::Type ThreadPlanSP; typedef SharedPtr::Type TypeSP; + typedef SharedPtr::Type UserSettingsControllerSP; typedef SharedPtr::Type ValueObjectSP; typedef SharedPtr::Type VariableSP; typedef SharedPtr::Type VariableListSP; Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Fri Sep 3 19:03:46 2010 @@ -72,6 +72,7 @@ class FunctionInfo; class InlineFunctionInfo; class InputReader; +class InstanceSettings; struct LineEntry; class LineTable; class Listener; @@ -101,7 +102,6 @@ class StackFrame; class StackFrameList; class StackID; -class StateVariable; class StopInfo; class Stoppoint; class StoppointCallbackContext; @@ -134,6 +134,7 @@ class Type; class TypeList; class Unwind; +class UserSettingsController; class UUID; class VMRange; class Value; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 3 19:03:46 2010 @@ -83,7 +83,6 @@ 26D5B07211B07550009A862E /* Stoppoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1610F1B83100F91463 /* Stoppoint.cpp */; }; 26D5B07311B07550009A862E /* StoppointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1710F1B83100F91463 /* StoppointLocation.cpp */; }; 26D5B07411B07550009A862E /* WatchpointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */; }; - 26D5B07611B07550009A862E /* CommandObjectAppend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */; }; 26D5B07711B07550009A862E /* CommandObjectBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */; }; 26D5B07911B07550009A862E /* CommandObjectDisassemble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */; }; 26D5B07A11B07550009A862E /* CommandObjectExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */; }; @@ -95,9 +94,7 @@ 26D5B08111B07550009A862E /* CommandObjectQuit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */; }; 26D5B08211B07550009A862E /* CommandObjectRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */; }; 26D5B08311B07550009A862E /* CommandObjectScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */; }; - 26D5B08511B07550009A862E /* CommandObjectSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */; }; 26D5B08611B07550009A862E /* CommandObjectSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */; }; - 26D5B08711B07550009A862E /* CommandObjectShow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */; }; 26D5B08811B07550009A862E /* CommandObjectSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */; }; 26D5B08B11B07550009A862E /* CommandObjectSyntax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4510F1B84700F91463 /* CommandObjectSyntax.cpp */; }; 26D5B08C11B07550009A862E /* CommandObjectThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */; }; @@ -162,7 +159,6 @@ 26D5B0CB11B07550009A862E /* CommandInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0810F1B8DD00F91463 /* CommandInterpreter.cpp */; }; 26D5B0CC11B07550009A862E /* CommandObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0910F1B8DD00F91463 /* CommandObject.cpp */; }; 26D5B0CD11B07550009A862E /* CommandReturnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0A10F1B8DD00F91463 /* CommandReturnObject.cpp */; }; - 26D5B0CE11B07550009A862E /* StateVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0B10F1B8DD00F91463 /* StateVariable.cpp */; }; 26D5B0CF11B07550009A862E /* ScriptInterpreterPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */; }; 26D5B0D011B07550009A862E /* Block.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F1310F1B8EC00F91463 /* Block.cpp */; }; 26D5B0D111B07550009A862E /* ClangASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F1410F1B8EC00F91463 /* ClangASTContext.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; }; @@ -364,6 +360,8 @@ 9A357673116E7B6400E8ED2F /* SBStringList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A357672116E7B6400E8ED2F /* SBStringList.cpp */; }; 9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3576A7116E9AB700E8ED2F /* SBHostOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */; }; + 9A4633DB11F65D8600955CE1 /* UserSettingsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A4633DA11F65D8600955CE1 /* UserSettingsController.h */; }; + 9A4633DD11F65D9A00955CE1 /* UserSettingsController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4633DC11F65D9A00955CE1 /* UserSettingsController.cpp */; }; 9AA69DA61188F52100D753A0 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */; }; 9AA69DAF118A023300D753A0 /* SBInputReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AA69DAE118A023300D753A0 /* SBInputReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9AA69DB1118A024600D753A0 /* SBInputReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA69DB0118A024600D753A0 /* SBInputReader.cpp */; }; @@ -613,7 +611,6 @@ 26BC7CFA10F1B71400F91463 /* Stoppoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Stoppoint.h; path = include/lldb/Breakpoint/Stoppoint.h; sourceTree = ""; }; 26BC7CFB10F1B71400F91463 /* StoppointLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StoppointLocation.h; path = include/lldb/Breakpoint/StoppointLocation.h; sourceTree = ""; }; 26BC7CFC10F1B71400F91463 /* WatchpointLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WatchpointLocation.h; path = include/lldb/Breakpoint/WatchpointLocation.h; sourceTree = ""; }; - 26BC7D1210F1B76300F91463 /* CommandObjectAppend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectAppend.h; path = source/Commands/CommandObjectAppend.h; sourceTree = ""; }; 26BC7D1410F1B76300F91463 /* CommandObjectBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectBreakpoint.h; path = source/Commands/CommandObjectBreakpoint.h; sourceTree = ""; }; 26BC7D1710F1B76300F91463 /* CommandObjectDisassemble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectDisassemble.h; path = source/Commands/CommandObjectDisassemble.h; sourceTree = ""; }; 26BC7D1810F1B76300F91463 /* CommandObjectExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectExpression.h; path = source/Commands/CommandObjectExpression.h; sourceTree = ""; }; @@ -625,9 +622,7 @@ 26BC7D2010F1B76300F91463 /* CommandObjectQuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectQuit.h; path = source/Commands/CommandObjectQuit.h; sourceTree = ""; }; 26BC7D2210F1B76300F91463 /* CommandObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectRegister.h; path = source/Commands/CommandObjectRegister.h; sourceTree = ""; }; 26BC7D2410F1B76300F91463 /* CommandObjectScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectScript.h; path = source/Interpreter/CommandObjectScript.h; sourceTree = ""; }; - 26BC7D2610F1B76300F91463 /* CommandObjectSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSet.h; path = source/Commands/CommandObjectSet.h; sourceTree = ""; }; 26BC7D2710F1B76300F91463 /* CommandObjectSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSettings.h; path = source/Commands/CommandObjectSettings.h; sourceTree = ""; }; - 26BC7D2810F1B76300F91463 /* CommandObjectShow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectShow.h; path = source/Commands/CommandObjectShow.h; sourceTree = ""; }; 26BC7D2910F1B76300F91463 /* CommandObjectSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSource.h; path = source/Commands/CommandObjectSource.h; sourceTree = ""; }; 26BC7D2C10F1B76300F91463 /* CommandObjectSyntax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSyntax.h; path = source/Commands/CommandObjectSyntax.h; sourceTree = ""; }; 26BC7D2D10F1B76300F91463 /* CommandObjectThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectThread.h; path = source/Commands/CommandObjectThread.h; sourceTree = ""; }; @@ -695,7 +690,6 @@ 26BC7DE410F1B7F900F91463 /* CommandReturnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandReturnObject.h; path = include/lldb/Interpreter/CommandReturnObject.h; sourceTree = ""; }; 26BC7DE510F1B7F900F91463 /* ScriptInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptInterpreter.h; path = include/lldb/Interpreter/ScriptInterpreter.h; sourceTree = ""; }; 26BC7DE610F1B7F900F91463 /* ScriptInterpreterPython.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptInterpreterPython.h; path = include/lldb/Interpreter/ScriptInterpreterPython.h; sourceTree = ""; }; - 26BC7DE710F1B7F900F91463 /* StateVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StateVariable.h; path = include/lldb/Interpreter/StateVariable.h; sourceTree = ""; }; 26BC7DF110F1B81A00F91463 /* DynamicLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DynamicLoader.h; path = include/lldb/Target/DynamicLoader.h; sourceTree = ""; }; 26BC7DF210F1B81A00F91463 /* ExecutionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionContext.h; path = include/lldb/Target/ExecutionContext.h; sourceTree = ""; }; 26BC7DF310F1B81A00F91463 /* Process.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Process.h; path = include/lldb/Target/Process.h; sourceTree = ""; }; @@ -724,7 +718,6 @@ 26BC7E1610F1B83100F91463 /* Stoppoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Stoppoint.cpp; path = source/Breakpoint/Stoppoint.cpp; sourceTree = ""; }; 26BC7E1710F1B83100F91463 /* StoppointLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StoppointLocation.cpp; path = source/Breakpoint/StoppointLocation.cpp; sourceTree = ""; }; 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointLocation.cpp; path = source/Breakpoint/WatchpointLocation.cpp; sourceTree = ""; }; - 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectAppend.cpp; path = source/Commands/CommandObjectAppend.cpp; sourceTree = ""; }; 26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectBreakpoint.cpp; path = source/Commands/CommandObjectBreakpoint.cpp; sourceTree = ""; }; 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectDisassemble.cpp; path = source/Commands/CommandObjectDisassemble.cpp; sourceTree = ""; }; 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectExpression.cpp; path = source/Commands/CommandObjectExpression.cpp; sourceTree = ""; }; @@ -736,9 +729,7 @@ 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectQuit.cpp; path = source/Commands/CommandObjectQuit.cpp; sourceTree = ""; }; 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectRegister.cpp; path = source/Commands/CommandObjectRegister.cpp; sourceTree = ""; }; 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectScript.cpp; path = source/Interpreter/CommandObjectScript.cpp; sourceTree = ""; }; - 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSet.cpp; path = source/Commands/CommandObjectSet.cpp; sourceTree = ""; }; 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSettings.cpp; path = source/Commands/CommandObjectSettings.cpp; sourceTree = ""; }; - 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectShow.cpp; path = source/Commands/CommandObjectShow.cpp; sourceTree = ""; }; 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSource.cpp; path = source/Commands/CommandObjectSource.cpp; sourceTree = ""; }; 26BC7E4510F1B84700F91463 /* CommandObjectSyntax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSyntax.cpp; path = source/Commands/CommandObjectSyntax.cpp; sourceTree = ""; }; 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectThread.cpp; path = source/Commands/CommandObjectThread.cpp; sourceTree = ""; }; @@ -811,7 +802,6 @@ 26BC7F0810F1B8DD00F91463 /* CommandInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandInterpreter.cpp; path = source/Interpreter/CommandInterpreter.cpp; sourceTree = ""; }; 26BC7F0910F1B8DD00F91463 /* CommandObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObject.cpp; path = source/Interpreter/CommandObject.cpp; sourceTree = ""; }; 26BC7F0A10F1B8DD00F91463 /* CommandReturnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandReturnObject.cpp; path = source/Interpreter/CommandReturnObject.cpp; sourceTree = ""; }; - 26BC7F0B10F1B8DD00F91463 /* StateVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StateVariable.cpp; path = source/Interpreter/StateVariable.cpp; sourceTree = ""; }; 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptInterpreterPython.cpp; path = source/Interpreter/ScriptInterpreterPython.cpp; sourceTree = ""; }; 26BC7F1310F1B8EC00F91463 /* Block.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Block.cpp; path = source/Symbol/Block.cpp; sourceTree = ""; }; 26BC7F1410F1B8EC00F91463 /* ClangASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTContext.cpp; path = source/Symbol/ClangASTContext.cpp; sourceTree = ""; }; @@ -1012,6 +1002,8 @@ 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBHostOS.cpp; path = source/API/SBHostOS.cpp; sourceTree = ""; }; 9A42976111861A9F00FE05CD /* CommandObjectBreakpointCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectBreakpointCommand.h; path = source/Commands/CommandObjectBreakpointCommand.h; sourceTree = ""; }; 9A42976211861AA600FE05CD /* CommandObjectBreakpointCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectBreakpointCommand.cpp; path = source/Commands/CommandObjectBreakpointCommand.cpp; sourceTree = ""; }; + 9A4633DA11F65D8600955CE1 /* UserSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserSettingsController.h; path = include/lldb/Core/UserSettingsController.h; sourceTree = ""; }; + 9A4633DC11F65D9A00955CE1 /* UserSettingsController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserSettingsController.cpp; path = source/Core/UserSettingsController.cpp; sourceTree = ""; }; 9A633FE7112DCE3C001A7E43 /* SBFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFrame.cpp; path = source/API/SBFrame.cpp; sourceTree = ""; }; 9A633FE8112DCE3C001A7E43 /* SBFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFrame.h; path = include/lldb/API/SBFrame.h; sourceTree = ""; }; 9A82010B10FFB49800182560 /* ScriptInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptInterpreter.cpp; path = source/Interpreter/ScriptInterpreter.cpp; sourceTree = ""; }; @@ -1669,6 +1661,8 @@ 268A813F115B19D000F645B0 /* UniqueCStringMap.h */, 26BC7D8010F1B77400F91463 /* UserID.h */, 26BC7E9810F1B85900F91463 /* UserID.cpp */, + 9A4633DA11F65D8600955CE1 /* UserSettingsController.h */, + 9A4633DC11F65D9A00955CE1 /* UserSettingsController.cpp */, 26C81CA411335651004BDC5A /* UUID.h */, 26C81CA511335651004BDC5A /* UUID.cpp */, 26BC7D8110F1B77400F91463 /* Value.h */, @@ -1783,8 +1777,6 @@ 26BC7D0D10F1B71D00F91463 /* Commands */ = { isa = PBXGroup; children = ( - 26BC7D1210F1B76300F91463 /* CommandObjectAppend.h */, - 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */, 4CA9637A11B6E99A00780E28 /* CommandObjectApropos.h */, 4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */, 499F381E11A5B3F300F5CE02 /* CommandObjectArgs.h */, @@ -1821,12 +1813,8 @@ 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */, 26BC7D2410F1B76300F91463 /* CommandObjectScript.h */, 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */, - 26BC7D2610F1B76300F91463 /* CommandObjectSet.h */, - 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */, 26BC7D2710F1B76300F91463 /* CommandObjectSettings.h */, 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */, - 26BC7D2810F1B76300F91463 /* CommandObjectShow.h */, - 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */, 26BC7D2910F1B76300F91463 /* CommandObjectSource.h */, 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */, 26BC7D2C10F1B76300F91463 /* CommandObjectSyntax.h */, @@ -1921,8 +1909,6 @@ 9A2771FC1135A37500E6ADB6 /* ScriptInterpreterNone.cpp */, 26BC7DE610F1B7F900F91463 /* ScriptInterpreterPython.h */, 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */, - 26BC7DE710F1B7F900F91463 /* StateVariable.h */, - 26BC7F0B10F1B8DD00F91463 /* StateVariable.cpp */, ); name = Interpreter; sourceTree = ""; @@ -2230,6 +2216,7 @@ 49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */, 4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */, 26D27CA011ED3A4E0024D721 /* ELFHeader.h in Headers */, + 9A4633DB11F65D8600955CE1 /* UserSettingsController.h in Headers */, 49E45FAA11F660DC008F7B28 /* ClangASTType.h in Headers */, 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */, 264723A611FA076E00DE380C /* CleanUp.h in Headers */, @@ -2427,7 +2414,6 @@ 26D5B07211B07550009A862E /* Stoppoint.cpp in Sources */, 26D5B07311B07550009A862E /* StoppointLocation.cpp in Sources */, 26D5B07411B07550009A862E /* WatchpointLocation.cpp in Sources */, - 26D5B07611B07550009A862E /* CommandObjectAppend.cpp in Sources */, 26D5B07711B07550009A862E /* CommandObjectBreakpoint.cpp in Sources */, 26D5B07911B07550009A862E /* CommandObjectDisassemble.cpp in Sources */, 26D5B07A11B07550009A862E /* CommandObjectExpression.cpp in Sources */, @@ -2439,9 +2425,7 @@ 26D5B08111B07550009A862E /* CommandObjectQuit.cpp in Sources */, 26D5B08211B07550009A862E /* CommandObjectRegister.cpp in Sources */, 26D5B08311B07550009A862E /* CommandObjectScript.cpp in Sources */, - 26D5B08511B07550009A862E /* CommandObjectSet.cpp in Sources */, 26D5B08611B07550009A862E /* CommandObjectSettings.cpp in Sources */, - 26D5B08711B07550009A862E /* CommandObjectShow.cpp in Sources */, 26D5B08811B07550009A862E /* CommandObjectSource.cpp in Sources */, 26D5B08B11B07550009A862E /* CommandObjectSyntax.cpp in Sources */, 26D5B08C11B07550009A862E /* CommandObjectThread.cpp in Sources */, @@ -2506,7 +2490,6 @@ 26D5B0CB11B07550009A862E /* CommandInterpreter.cpp in Sources */, 26D5B0CC11B07550009A862E /* CommandObject.cpp in Sources */, 26D5B0CD11B07550009A862E /* CommandReturnObject.cpp in Sources */, - 26D5B0CE11B07550009A862E /* StateVariable.cpp in Sources */, 26D5B0CF11B07550009A862E /* ScriptInterpreterPython.cpp in Sources */, 26D5B0D011B07550009A862E /* Block.cpp in Sources */, 26D5B0D111B07550009A862E /* ClangASTContext.cpp in Sources */, @@ -2688,6 +2671,7 @@ 49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */, 4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */, 26D27C9F11ED3A4E0024D721 /* ELFHeader.cpp in Sources */, + 9A4633DD11F65D9A00955CE1 /* UserSettingsController.cpp in Sources */, 49E45FAF11F660FE008F7B28 /* ClangASTType.cpp in Sources */, 2615DB871208A9E40021781D /* StopInfo.cpp in Sources */, 2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */, Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/API/SBCommandInterpreter.cpp (original) +++ lldb/trunk/source/API/SBCommandInterpreter.cpp Fri Sep 3 19:03:46 2010 @@ -107,17 +107,17 @@ return num_completions; } -const char ** -SBCommandInterpreter::GetEnvironmentVariables () -{ - if (m_opaque_ptr) - { - const Args *env_vars = m_opaque_ptr->GetEnvironmentVariables(); - if (env_vars) - return env_vars->GetConstArgumentVector (); - } - return NULL; -} +//const char ** +//SBCommandInterpreter::GetEnvironmentVariables () +//{ +// if (m_opaque_ptr) +// { +// //const Args *env_vars = m_opaque_ptr->GetEnvironmentVariables(); +// //if (env_vars) +// // return env_vars->GetConstArgumentVector (); +// } +// return NULL; +//} bool SBCommandInterpreter::HasCommands () @@ -151,13 +151,13 @@ return false; } -bool -SBCommandInterpreter::HasInterpreterVariables () -{ - if (m_opaque_ptr) - return m_opaque_ptr->HasInterpreterVariables (); - return false; -} +//bool +//SBCommandInterpreter::HasInterpreterVariables () +//{ +// if (m_opaque_ptr) +// return m_opaque_ptr->HasInterpreterVariables (); +// return false; +//} SBProcess SBCommandInterpreter::GetProcess () Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Fri Sep 3 19:03:46 2010 @@ -22,11 +22,12 @@ #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBFrame.h" -#include "lldb/API/SBTarget.h" +#include "lldb/API/SBInputReader.h" #include "lldb/API/SBProcess.h" -#include "lldb/API/SBThread.h" #include "lldb/API/SBSourceManager.h" -#include "lldb/API/SBInputReader.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" using namespace lldb; using namespace lldb_private; @@ -564,6 +565,32 @@ return sb_debugger; } +SBError +SBDebugger::SetInternalVariable (const char *var_name, const char *value) +{ + lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController(); + + Error err = root_settings_controller->SetVariable (var_name, value, lldb::eVarSetOperationAssign, false); + SBError sb_error; + sb_error.SetError (err); + + return sb_error; +} + +lldb::SBStringList +SBDebugger::GetInternalVariableValue (const char *var_name) +{ + SBStringList ret_value; + lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController(); + + lldb::SettableVariableType var_type; + StringList value = root_settings_controller->GetVariable (var_name, var_type); + for (int i = 0; i < value.GetSize(); ++i) + ret_value.AppendString (value.GetStringAtIndex(i)); + + return ret_value; +} + bool SBDebugger::SetUseExternalEditor (bool value) { @@ -582,4 +609,3 @@ return false; } - Modified: lldb/trunk/source/Commands/CommandCompletions.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandCompletions.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandCompletions.cpp (original) +++ lldb/trunk/source/Commands/CommandCompletions.cpp Fri Sep 3 19:03:46 2010 @@ -38,6 +38,7 @@ {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, {eSymbolCompletion, CommandCompletions::Symbols}, {eModuleCompletion, CommandCompletions::Modules}, + {eSettingsNameCompletion, CommandCompletions::SettingsNames}, {eNoCompletion, NULL} // This one has to be last in the list. }; @@ -410,6 +411,26 @@ return matches.GetSize(); } +int +CommandCompletions::SettingsNames (CommandInterpreter &interpreter, + const char *partial_setting_name, + int match_start_point, + int max_return_elements, + SearchFilter *searcher, + bool &word_complete, + StringList &matches) +{ + lldb::UserSettingsControllerSP root_settings = Debugger::GetSettingsController(); + Args partial_setting_name_pieces = UserSettingsController::BreakNameIntoPieces (partial_setting_name); + + return UserSettingsController::CompleteSettingsNames (root_settings, + partial_setting_name_pieces, + word_complete, + matches); + + //return matches.GetSize(); +} + CommandCompletions::Completer::Completer ( CommandInterpreter &interpreter, @@ -687,6 +708,3 @@ filter->Search (*this); return m_matches.GetSize(); } - - - Removed: lldb/trunk/source/Commands/CommandObjectAppend.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectAppend.cpp?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectAppend.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectAppend.cpp (removed) @@ -1,94 +0,0 @@ -//===-- CommandObjectAppend.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectAppend.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -//----------------------------------------------------------------------------- -// CommandObjectAppend -//----------------------------------------------------------------------------- - -CommandObjectAppend::CommandObjectAppend () : - CommandObject ("append", - "Allows the user to append a value to a single debugger setting variable, for settings that are of list types. Type 'settings' to see a list of debugger setting variables", - "append ") -{ -} - -CommandObjectAppend::~CommandObjectAppend () -{ -} - -bool -CommandObjectAppend::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) -{ - CommandInterpreter::VariableMap::iterator pos; - - const int argc = command.GetArgumentCount(); - if (argc < 2) - { - result.AppendError ("'append' requires at least two arguments"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - const char *var_name = command.GetArgumentAtIndex(0); - command.Shift(); - - - if (var_name == NULL || var_name[0] == '\0') - { - result.AppendError ("'set' command requires a valid variable name. No value supplied"); - result.SetStatus (eReturnStatusFailed); - } - else - { - StateVariable *var = interpreter.GetStateVariable(var_name); - if (var == NULL) - { - result.AppendErrorWithFormat ("'%s' is not a settable internal variable.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - else - { - if (var->GetType() == StateVariable::eTypeString) - { - for (size_t i = 0; i < command.GetArgumentCount(); ++i) - var->AppendStringValue (command.GetArgumentAtIndex(i)); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else if (var->GetType() == StateVariable::eTypeStringArray) - { - var->GetArgs().AppendArguments (command); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendErrorWithFormat ("Values cannot be appended to variable '%s'. Try 'set' instead.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - } - } - return result.Succeeded(); -} - Removed: lldb/trunk/source/Commands/CommandObjectAppend.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectAppend.h?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectAppend.h (original) +++ lldb/trunk/source/Commands/CommandObjectAppend.h (removed) @@ -1,42 +0,0 @@ -//===-- CommandObjectAppend.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_CommandObjectAppend_h_ -#define liblldb_CommandObjectAppend_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { -//----------------------------------------------------------------------------- -// CommandObjectAppend -//----------------------------------------------------------------------------- - -class CommandObjectAppend : public CommandObject -{ -public: - CommandObjectAppend (); - - virtual - ~CommandObjectAppend (); - - virtual bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result); - - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectAppend_h_ Modified: lldb/trunk/source/Commands/CommandObjectHelp.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectHelp.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectHelp.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectHelp.cpp Fri Sep 3 19:03:46 2010 @@ -94,7 +94,7 @@ Stream &output_strm = result.GetOutputStream(); if (sub_cmd_obj->GetOptions() != NULL) { - output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj); const char *long_help = sub_cmd_obj->GetHelpLong(); @@ -104,7 +104,7 @@ } else if (sub_cmd_obj->IsMultiwordObject()) { - output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); ((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (interpreter, result); } else @@ -112,9 +112,9 @@ const char *long_help = sub_cmd_obj->GetHelpLong(); if ((long_help != NULL) && (strlen (long_help) > 0)) - output_strm.Printf ("%s", long_help); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelpLong(), 1); else - output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); } } Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Fri Sep 3 19:03:46 2010 @@ -161,11 +161,44 @@ process = target->CreateProcess (interpreter.GetDebugger().GetListener(), plugin_name).get(); - const Args *environment = interpreter.GetEnvironmentVariables(); - const Args *run_args = interpreter.GetProgramArguments(); - uint32_t launch_flags = eLaunchFlagNone; - if (interpreter.GetDisableASLR()) - launch_flags |= eLaunchFlagDisableASLR; + const char *process_name = process->GetInstanceName().AsCString(); + StreamString run_args_var_name; + StreamString env_vars_var_name; + StreamString disable_aslr_var_name; + lldb::SettableVariableType var_type; + + Args *run_args = NULL; + run_args_var_name.Printf ("process.[%s].run-args", process_name); + StringList run_args_value = Debugger::GetSettingsController()->GetVariable (run_args_var_name.GetData(), + var_type); + if (run_args_value.GetSize() > 0) + { + run_args = new Args; + for (int i = 0; i < run_args_value.GetSize(); ++i) + run_args->AppendArgument (run_args_value.GetStringAtIndex (i)); + } + + Args *environment = NULL; + env_vars_var_name.Printf ("process.[%s].env-vars", process_name); + StringList env_vars_value = Debugger::GetSettingsController()->GetVariable (env_vars_var_name.GetData(), + var_type); + if (env_vars_value.GetSize() > 0) + { + environment = new Args; + for (int i = 0; i < env_vars_value.GetSize(); ++i) + environment->AppendArgument (env_vars_value.GetStringAtIndex (i)); + } + + uint32_t launch_flags = eLaunchFlagNone; + disable_aslr_var_name.Printf ("process.[%s].disable-aslr", process_name); + StringList disable_aslr_value = Debugger::GetSettingsController()->GetVariable(disable_aslr_var_name.GetData(), + var_type); + if (disable_aslr_value.GetSize() > 0) + { + if (strcmp (disable_aslr_value.GetStringAtIndex(0), "true") == 0) + launch_flags |= eLaunchFlagDisableASLR; + + } // There are two possible sources of args to be passed to the process upon launching: Those the user // typed at the run command (launch_args); or those the user pre-set in the run-args variable (run_args). @@ -179,12 +212,9 @@ else { // launch-args was not empty; use that, AND re-set run-args to contains launch-args values. - StateVariable *run_args_var = interpreter.GetStateVariable ("run-args"); - if (run_args_var != NULL) - { - run_args_var->ArrayClearValues(); - run_args_var->GetArgs().AppendArguments (launch_args); - } + std::string new_run_args; + launch_args.GetCommandString (new_run_args); + Debugger::GetSettingsController()->SetVariable (run_args_var_name.GetData(), new_run_args.c_str(), lldb::eVarSetOperationAssign, false); } Removed: lldb/trunk/source/Commands/CommandObjectSet.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSet.cpp?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSet.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSet.cpp (removed) @@ -1,152 +0,0 @@ -//===-- CommandObjectSet.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectSet.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectSet -//------------------------------------------------------------------------- - -CommandObjectSet::CommandObjectSet () : - CommandObject ("set", - "Allows the user to set or change the value of a single debugger setting variable.", - "set ") -{ -} - -CommandObjectSet::~CommandObjectSet() -{ -} - - -bool -CommandObjectSet::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) -{ - CommandInterpreter::VariableMap::iterator pos; - - const int argc = command.GetArgumentCount(); - - if (argc < 1) - { - result.AppendError ("'set' takes at least two arguments"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - const char *var_name = command.GetArgumentAtIndex(0); - const char *var_value = command.GetArgumentAtIndex(1); - - if (var_name == NULL || var_name[0] == '\0') - { - result.AppendError ("'set' command requires a valid variable name; No value supplied"); - result.SetStatus (eReturnStatusFailed); - } - else if (var_value == NULL || var_value[0] == '\0') - { - // No value given: Check to see if we're trying to clear an array. - StateVariable *var = interpreter.GetStateVariable (var_name); - if (var != NULL - && var->GetType() == StateVariable::eTypeStringArray) - { - var->ArrayClearValues(); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendError ("'set' command requires a valid variable value; No value supplied"); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - StateVariable *var = interpreter.GetStateVariable(var_name); - if (var == NULL) - { - result.AppendErrorWithFormat ("'%s' is not a settable internal variable.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - else - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - if (var->GetType() == StateVariable::eTypeBoolean) - { - bool success = false; - bool new_value = Args::StringToBoolean (var_value, false, &success); - - if (success) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - if (!var->HasVerifyFunction() || var->VerifyValue (&interpreter, (void *) &new_value, result)) - var->SetBoolValue (new_value); - } - else - { - result.AppendErrorWithFormat ("Invalid boolean string '%s'.\n", var_value); - result.SetStatus (eReturnStatusFailed); - } - } - else if (var->GetType() == StateVariable::eTypeInteger) - { - bool success = false; - int new_value = Args::StringToSInt32(var_value, -1, 0, &success); - - if (success) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - if (!var->HasVerifyFunction() || var->VerifyValue (&interpreter, (void *) &new_value, result)) - var->SetIntValue (new_value); - } - else - { - result.AppendErrorWithFormat ("Invalid boolean string '%s'.\n", var_value); - result.SetStatus (eReturnStatusFailed); - } - } - else if (var->GetType() == StateVariable::eTypeString) - { - if (!var->HasVerifyFunction() || var->VerifyValue (&interpreter, (void *) var_value, result)) - var->SetStringValue (var_value); - } - else if (var->GetType() == StateVariable::eTypeStringArray) - { - if (var_value == NULL || var_value[0] == '\0') - var->ArrayClearValues (); - else - { - command.Shift(); // shift off variable name - var->ArrayClearValues(); // clear the old values - var->GetArgs().AppendArguments (command); // set the new values. - } - } - else - { - result.AppendErrorWithFormat ("Variable '%s' has unrecognized type.\n", - var->GetName()); - result.SetStatus (eReturnStatusFailed); - } - } - } - return result.Succeeded(); -} - Removed: lldb/trunk/source/Commands/CommandObjectSet.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSet.h?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSet.h (original) +++ lldb/trunk/source/Commands/CommandObjectSet.h (removed) @@ -1,43 +0,0 @@ -//===-- CommandObjectSet.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_CommandObjectSet_h_ -#define liblldb_CommandObjectSet_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectSet -//------------------------------------------------------------------------- - -class CommandObjectSet : public CommandObject -{ -public: - - CommandObjectSet (); - - virtual - ~CommandObjectSet (); - - virtual bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectSet_h_ Modified: lldb/trunk/source/Commands/CommandObjectSettings.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSettings.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSettings.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSettings.cpp Fri Sep 3 19:03:46 2010 @@ -15,47 +15,998 @@ // Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/CommandCompletions.h" using namespace lldb; using namespace lldb_private; //------------------------------------------------------------------------- -// CommandObjectSettings +// CommandObjectMultiwordSettings //------------------------------------------------------------------------- -CommandObjectSettings::CommandObjectSettings () : - CommandObject ("settings", - "Lists the debugger settings variables available to the user to 'set' or 'show'.", - "settings") +CommandObjectMultiwordSettings::CommandObjectMultiwordSettings (CommandInterpreter &interpreter) : + CommandObjectMultiword ("settings", + "A set of commands for manipulating internal settable debugger variables.", + "settings []") { + bool status; + + CommandObjectSP set_command_object (new CommandObjectSettingsSet ()); + CommandObjectSP show_command_object (new CommandObjectSettingsShow ()); + CommandObjectSP list_command_object (new CommandObjectSettingsList ()); + CommandObjectSP remove_command_object (new CommandObjectSettingsRemove ()); + CommandObjectSP replace_command_object (new CommandObjectSettingsReplace ()); + CommandObjectSP insert_before_command_object (new CommandObjectSettingsInsertBefore ()); + CommandObjectSP insert_after_command_object (new CommandObjectSettingsInsertAfter()); + CommandObjectSP append_command_object (new CommandObjectSettingsAppend()); + CommandObjectSP clear_command_object (new CommandObjectSettingsClear()); + + status = LoadSubCommand (interpreter, "set", set_command_object); + status = LoadSubCommand (interpreter, "show", show_command_object); + status = LoadSubCommand (interpreter, "list", list_command_object); + status = LoadSubCommand (interpreter, "remove", remove_command_object); + status = LoadSubCommand (interpreter, "replace", replace_command_object); + status = LoadSubCommand (interpreter, "insert-before", insert_before_command_object); + status = LoadSubCommand (interpreter, "insert-after", insert_after_command_object); + status = LoadSubCommand (interpreter, "append", append_command_object); + status = LoadSubCommand (interpreter, "clear", clear_command_object); +} + +CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings () +{ +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsSet +//------------------------------------------------------------------------- + +CommandObjectSettingsSet::CommandObjectSettingsSet () : + CommandObject ("settings set", + "Allows the user to set or change the value of a single debugger setting variable.", + "settings set [] "), + m_options () +{ +} + +CommandObjectSettingsSet::~CommandObjectSettingsSet() +{ +} + + +bool +CommandObjectSettingsSet::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 2) + { + result.AppendError ("'settings set' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings set' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if (!m_options.m_reset + && var_value == NULL) + { + result.AppendError ("'settings set' command requires a valid variable value unless using '--reset' option;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationAssign, + m_options.m_override); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + +int +CommandObjectSettingsSet::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index == 1) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + // Attempting to complete value + if ((cursor_index == 2) // Partly into the variable's value + || (cursor_index == 1 // Or at the end of a completed valid variable name + && matches.GetSize() == 1 + && completion_str.compare (matches.GetStringAtIndex(0)) == 0)) + { + matches.Clear(); + lldb::UserSettingsControllerSP root_settings = Debugger::GetSettingsController(); + if (cursor_index == 1) + { + // The user is at the end of the variable name, which is complete and valid. + UserSettingsController::CompleteSettingsValue (root_settings, + input.GetArgumentAtIndex (1), // variable name + NULL, // empty value string + word_complete, + matches); + } + else + { + // The user is partly into the variable value. + UserSettingsController::CompleteSettingsValue (root_settings, + input.GetArgumentAtIndex (1), // variable name + completion_str.c_str(), // partial value string + word_complete, + matches); + } + } + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsSet::CommandOptions +//------------------------------------------------------------------------- + +CommandObjectSettingsSet::CommandOptions::CommandOptions () : + Options (), + m_override (false), + m_reset (false) +{ +} + +CommandObjectSettingsSet::CommandOptions::~CommandOptions () +{ +} + +lldb::OptionDefinition +CommandObjectSettingsSet::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "override", 'o', no_argument, NULL, NULL, NULL, "Causes already existing instances and pending settings to use this new value. This option only makes sense when setting default values." }, + + { LLDB_OPT_SET_2, false, "reset", 'r', no_argument, NULL, NULL, NULL, "Causes value to be reset to the original default for this variable. No value needs to be specified when this option is used." }, +}; + +const lldb::OptionDefinition* +CommandObjectSettingsSet::CommandOptions::GetDefinitions () +{ + return g_option_table; +} + +Error +CommandObjectSettingsSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg) +{ + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'o': + m_override = true; + break; + case 'r': + m_reset = true; + break; + default: + error.SetErrorStringWithFormat ("Unrecognized options '%c'.\n", short_option); + break; + } + + return error; +} + +void +CommandObjectSettingsSet::CommandOptions::ResetOptionValues () +{ + Options::ResetOptionValues (); + + m_override = false; + m_reset = false; +} + +Options * +CommandObjectSettingsSet::GetOptions () +{ + return &m_options; +} + + +//------------------------------------------------------------------------- +// CommandObjectSettingsShow -- Show current values +//------------------------------------------------------------------------- + +CommandObjectSettingsShow::CommandObjectSettingsShow () : + CommandObject ("settings show", + "Allows the user to see a single internal debugger setting variable and its value, or lists them all.", + "settings show []") +{ +} + +CommandObjectSettingsShow::~CommandObjectSettingsShow() +{ +} + + +bool +CommandObjectSettingsShow::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + std::string current_prefix = root_settings->GetLevelName().AsCString(); + + Error err; + + if (command.GetArgumentCount()) + { + // The user requested to see the value of a particular variable. + lldb::SettableVariableType var_type; + const char *variable_name = command.GetArgumentAtIndex (0); + StringList value = root_settings->GetVariable (variable_name, var_type); + + if (value.GetSize() == 0) + { + result.AppendErrorWithFormat ("Unable to find variable named '%s'. " + "Try 'show' to see all variable values.\n", variable_name); + result.SetStatus (eReturnStatusFailed); + + } + else + { + char *type_name = (char *) ""; + if (var_type != eSetVarTypeNone) + { + StreamString tmp_str; + tmp_str.Printf (" (%s)", UserSettingsController::GetTypeString (var_type)); + type_name = (char *) tmp_str.GetData(); + } + + if (value.GetSize() == 1) + result.AppendMessageWithFormat ("%s%s = '%s'\n", variable_name, type_name, value.GetStringAtIndex (0)); + else + { + result.AppendMessageWithFormat ("%s%s:\n", variable_name, type_name); + for (int i = 0; i < value.GetSize(); ++i) + { + result.AppendMessageWithFormat (" [%d]: '%s'\n", i, value.GetStringAtIndex (i)); + } + } + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + } + else + { + UserSettingsController::GetAllVariableValues (interpreter, root_settings, current_prefix, + result.GetOutputStream(), err); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + { + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + } + + return result.Succeeded(); } -CommandObjectSettings::~CommandObjectSettings() +int +CommandObjectSettingsShow::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsList +//------------------------------------------------------------------------- + +CommandObjectSettingsList::CommandObjectSettingsList () : + CommandObject ("settings list", + "Lists the internal debugger settings variables available to the user to 'set' or 'show'.", + "settings list") +{ +} + +CommandObjectSettingsList::~CommandObjectSettingsList() { } bool -CommandObjectSettings::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) +CommandObjectSettingsList::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) { - CommandInterpreter::VariableMap::iterator pos; + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + std::string current_prefix = root_settings->GetLevelName().AsCString(); + + Error err; + + UserSettingsController::FindAllSettingsDescriptions (interpreter, root_settings, current_prefix, + result.GetOutputStream(), err); - if (command.GetArgumentCount() != 0) + if (err.Fail ()) { - result.AppendError ("'settings' does not take any arguments"); + result.AppendError (err.AsCString()); result.SetStatus (eReturnStatusFailed); } else { - interpreter.ShowVariableHelp (result); result.SetStatus (eReturnStatusSuccessFinishNoResult); } return result.Succeeded(); } +//------------------------------------------------------------------------- +// CommandObjectSettingsRemove +//------------------------------------------------------------------------- + +CommandObjectSettingsRemove::CommandObjectSettingsRemove () : + CommandObject ("settings remove", + "Removes the specified element from an internal debugger settings array or dictionary variable.", + "settings remove [|\"key\"]") +{ +} + +CommandObjectSettingsRemove::~CommandObjectSettingsRemove () +{ +} + +bool +CommandObjectSettingsRemove::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc != 2) + { + result.AppendError ("'settings remove' takes two arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings remove' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings remove' command requires an index or key value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + + Error err = root_settings->SetVariable (var_name_string.c_str(), NULL, lldb::eVarSetOperationRemove, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + + return result.Succeeded(); +} + +int +CommandObjectSettingsRemove::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsReplace +//------------------------------------------------------------------------- + +CommandObjectSettingsReplace::CommandObjectSettingsReplace () : + CommandObject ("settings replace", + "Replaces the specified element from an internal debugger settings array or dictionary variable.", + "settings replace [|\"\"] ") +{ +} + +CommandObjectSettingsReplace::~CommandObjectSettingsReplace () +{ +} + +bool +CommandObjectSettingsReplace::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 3) + { + result.AppendError ("'settings replace' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings replace' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires an index value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings replace' command requires a valid variable value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationReplace, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + +int +CommandObjectSettingsReplace::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsInsertBefore +//------------------------------------------------------------------------- + +CommandObjectSettingsInsertBefore::CommandObjectSettingsInsertBefore () : + CommandObject ("settings insert-before", + "Inserts value(s) into an internal debugger settings array variable, immediately before the specified element.", + "settings insert-before [] ") +{ +} + +CommandObjectSettingsInsertBefore::~CommandObjectSettingsInsertBefore () +{ +} + +bool +CommandObjectSettingsInsertBefore::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 3) + { + result.AppendError ("'settings insert-before' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires an index value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires a valid variable value;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationInsertBefore, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + + +int +CommandObjectSettingsInsertBefore::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingInsertAfter +//------------------------------------------------------------------------- + +CommandObjectSettingsInsertAfter::CommandObjectSettingsInsertAfter () : + CommandObject ("settings insert-after", + "Inserts value(s) into an internal debugger settings array variable, immediately after the specified element.", + "settings insert-after [] ") +{ +} + +CommandObjectSettingsInsertAfter::~CommandObjectSettingsInsertAfter () +{ +} + +bool +CommandObjectSettingsInsertAfter::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 3) + { + result.AppendError ("'settings insert-after' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings insert-after' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings insert-after' command requires an index value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings insert-after' command requires a valid variable value;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationInsertAfter, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + + +int +CommandObjectSettingsInsertAfter::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsAppend +//------------------------------------------------------------------------- + +CommandObjectSettingsAppend::CommandObjectSettingsAppend () : + CommandObject ("settings append", + "Appends new value to the end of an internal debugger settings array, dictionary or string variable.", + "settings append ") +{ +} + +CommandObjectSettingsAppend::~CommandObjectSettingsAppend () +{ +} + +bool +CommandObjectSettingsAppend::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 2) + { + result.AppendError ("'settings append' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings append' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings append' command requires a valid variable value;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationAppend, + false); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + + +int +CommandObjectSettingsAppend::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsClear +//------------------------------------------------------------------------- + +CommandObjectSettingsClear::CommandObjectSettingsClear () : + CommandObject ("settings clear", + "Erases all the contents of an internal debugger settings variables; only valid for variables with clearable types, i.e. strings, arrays or dictionaries.", + "settings clear") +{ +} + +CommandObjectSettingsClear::~CommandObjectSettingsClear () +{ +} + +bool +CommandObjectSettingsClear::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc != 1) + { + result.AppendError ("'setttings clear' takes exactly one argument"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings clear' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + Error err = root_settings->SetVariable (var_name, NULL, lldb::eVarSetOperationClear, false); + + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + + return result.Succeeded(); +} + + +int +CommandObjectSettingsClear::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} Modified: lldb/trunk/source/Commands/CommandObjectSettings.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSettings.h?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSettings.h (original) +++ lldb/trunk/source/Commands/CommandObjectSettings.h Fri Sep 3 19:03:46 2010 @@ -15,27 +15,327 @@ // Other libraries and framework includes // Project includes #include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/Options.h" + namespace lldb_private { //------------------------------------------------------------------------- -// CommandObjectSettings +// CommandObjectMultiwordSettings +//------------------------------------------------------------------------- + +class CommandObjectMultiwordSettings : public CommandObjectMultiword +{ +public: + + CommandObjectMultiwordSettings (CommandInterpreter &interpreter); + + virtual + ~CommandObjectMultiwordSettings (); + +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsSet +//------------------------------------------------------------------------- + +class CommandObjectSettingsSet : public CommandObject +{ +public: + CommandObjectSettingsSet (); + + virtual + ~CommandObjectSettingsSet (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual Options * + GetOptions (); + + class CommandOptions : public Options + { + public: + + CommandOptions (); + + virtual + ~CommandOptions (); + + virtual Error + SetOptionValue (int option_idx, const char *option_arg); + + void + ResetOptionValues (); + + const lldb::OptionDefinition* + GetDefinitions (); + + // Options table: Required for subclasses of Options. + + static lldb::OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + bool m_override; + bool m_reset; + + }; + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: + CommandOptions m_options; +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsShow -- Show current values //------------------------------------------------------------------------- -class CommandObjectSettings : public CommandObject +class CommandObjectSettingsShow : public CommandObject { public: + CommandObjectSettingsShow (); + + virtual + ~CommandObjectSettingsShow (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsList -- List settable variables +//------------------------------------------------------------------------- + +class CommandObjectSettingsList : public CommandObject +{ +public: + CommandObjectSettingsList (); + + virtual + ~CommandObjectSettingsList (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + +private: +}; - CommandObjectSettings (); +//------------------------------------------------------------------------- +// CommandObjectSettingsRemove +//------------------------------------------------------------------------- + +class CommandObjectSettingsRemove : public CommandObject +{ +public: + CommandObjectSettingsRemove (); virtual - ~CommandObjectSettings (); + ~CommandObjectSettingsRemove (); virtual bool Execute (CommandInterpreter &interpreter, Args& command, CommandReturnObject &result); + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsReplace +//------------------------------------------------------------------------- + +class CommandObjectSettingsReplace : public CommandObject +{ +public: + CommandObjectSettingsReplace (); + + virtual + ~CommandObjectSettingsReplace (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsInsertBefore +//------------------------------------------------------------------------- + +class CommandObjectSettingsInsertBefore : public CommandObject +{ +public: + CommandObjectSettingsInsertBefore (); + + virtual + ~CommandObjectSettingsInsertBefore (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingInsertAfter +//------------------------------------------------------------------------- + +class CommandObjectSettingsInsertAfter : public CommandObject +{ +public: + CommandObjectSettingsInsertAfter (); + + virtual + ~CommandObjectSettingsInsertAfter (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsAppend +//------------------------------------------------------------------------- + +class CommandObjectSettingsAppend : public CommandObject +{ +public: + CommandObjectSettingsAppend (); + + virtual + ~CommandObjectSettingsAppend (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsClear +//------------------------------------------------------------------------- + +class CommandObjectSettingsClear : public CommandObject +{ +public: + CommandObjectSettingsClear (); + + virtual + ~CommandObjectSettingsClear (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: }; } // namespace lldb_private Removed: lldb/trunk/source/Commands/CommandObjectShow.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectShow.cpp?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectShow.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectShow.cpp (removed) @@ -1,73 +0,0 @@ -//===-- CommandObjectShow.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectShow.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectShow -//------------------------------------------------------------------------- - -CommandObjectShow::CommandObjectShow () : - CommandObject ("show", - "Allows the user to see a single debugger setting variable and its value, or lists them all.", - "show []") -{ -} - -CommandObjectShow::~CommandObjectShow() -{ -} - - -bool -CommandObjectShow::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) -{ - CommandInterpreter::VariableMap::iterator pos; - - if (command.GetArgumentCount()) - { - // The user requested to see the value of a particular variable. - - const char *var_name = command.GetArgumentAtIndex(0); - StateVariable *var = interpreter.GetStateVariable(var_name); - if (var) - { - var->AppendVariableInformation (result); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendErrorWithFormat ("Unrecognized variable '%s'; cannot do 'show' command.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - // The user didn't specify a particular variable, so show the values of all of them. - interpreter.ShowVariableValues(result); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - - return result.Succeeded(); -} Removed: lldb/trunk/source/Commands/CommandObjectShow.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectShow.h?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectShow.h (original) +++ lldb/trunk/source/Commands/CommandObjectShow.h (removed) @@ -1,43 +0,0 @@ -//===-- CommandObjectShow.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_CommandObjectShow_h_ -#define liblldb_CommandObjectShow_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectShow -//------------------------------------------------------------------------- - -class CommandObjectShow : public CommandObject -{ -public: - - CommandObjectShow (); - - virtual - ~CommandObjectShow (); - - virtual bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectShow_h_ Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Fri Sep 3 19:03:46 2010 @@ -98,6 +98,25 @@ return debugger_sp; } +lldb::DebuggerSP +Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) +{ + lldb::DebuggerSP debugger_sp; + + Mutex::Locker locker (GetDebuggerListMutex ()); + DebuggerList &debugger_list = GetDebuggerList(); + DebuggerList::iterator pos, end = debugger_list.end(); + + for (pos = debugger_list.begin(); pos != end; ++pos) + { + if ((*pos).get()->m_instance_name == instance_name) + { + debugger_sp = *pos; + break; + } + } + return debugger_sp; +} TargetSP Debugger::FindTargetWithProcessID (lldb::pid_t pid) @@ -118,6 +137,7 @@ Debugger::Debugger () : UserID (g_unique_id++), + DebuggerInstanceSettings (*(Debugger::GetSettingsController().get())), m_input_comm("debugger.input"), m_input_file (), m_output_file (), @@ -513,3 +533,324 @@ } return debugger_sp; } + +lldb::UserSettingsControllerSP & +Debugger::GetSettingsController (bool finish) +{ + static lldb::UserSettingsControllerSP g_settings_controller (new DebuggerSettingsController); + static bool initialized = false; + + if (!initialized) + { + UserSettingsControllerSP parent = g_settings_controller->GetParent(); + if (parent) + parent->RegisterChild (g_settings_controller); + + g_settings_controller->CreateSettingsVector (Debugger::DebuggerSettingsController::global_settings_table, + true); + g_settings_controller->CreateSettingsVector (Debugger::DebuggerSettingsController::instance_settings_table, + false); + + g_settings_controller->InitializeGlobalVariables (); + g_settings_controller->CreateDefaultInstanceSettings (); + initialized = true; + } + + if (finish) + { + UserSettingsControllerSP parent = g_settings_controller->GetParent(); + if (parent) + parent->RemoveChild (g_settings_controller); + g_settings_controller.reset(); + } + return g_settings_controller; +} + +//-------------------------------------------------- +// class Debugger::DebuggerSettingsController +//-------------------------------------------------- + +Debugger::DebuggerSettingsController::DebuggerSettingsController () : + UserSettingsController ("", lldb::UserSettingsControllerSP()), + m_term_width (80) +{ + m_default_settings.reset (new DebuggerInstanceSettings (*this, InstanceSettings::GetDefaultName().AsCString())); +} + +Debugger::DebuggerSettingsController::~DebuggerSettingsController () +{ +} + + +lldb::InstanceSettingsSP +Debugger::DebuggerSettingsController::CreateNewInstanceSettings () +{ + DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*(Debugger::GetSettingsController().get())); + lldb::InstanceSettingsSP new_settings_sp (new_settings); + return new_settings_sp; +} + +bool +Debugger::DebuggerSettingsController::ValidTermWidthValue (const char *value, Error err) +{ + bool valid = true; + + // Verify we have a value string. + if (value == NULL + || strlen (value) == 0) + { + valid = false; + err.SetErrorString ("Missing value. Can't set terminal width without a value.\n"); + } + + // Verify the string consists entirely of digits. + if (valid) + { + int len = strlen (value); + for (int i = 0; i < len; ++i) + if (! isdigit (value[i])) + { + valid = false; + err.SetErrorStringWithFormat ("'%s' is not a valid representation of an integer.\n", value); + } + } + + // Verify the term-width is 'reasonable' (e.g. 10 <= width <= 250). + if (valid) + { + int width = atoi (value); + if (width < 10 + || width > 250) + { + valid = false; + err.SetErrorString ("Invalid term-width value; value must be between 10 and 250.\n"); + } + } + + return valid; +} + + +//-------------------------------------------------- +// class DebuggerInstanceSettings +//-------------------------------------------------- + +DebuggerInstanceSettings::DebuggerInstanceSettings (UserSettingsController &owner, const char *name) : + InstanceSettings (owner, (name == NULL ? CreateInstanceName ().AsCString() : name)), + m_prompt (), + m_script_lang () +{ + if (name == NULL) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings, false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) : + InstanceSettings (*(Debugger::GetSettingsController().get()), CreateInstanceName ().AsCString()), + m_prompt (rhs.m_prompt), + m_script_lang (rhs.m_script_lang) +{ + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings, false); + m_owner.RemovePendingSettings (m_instance_name); +} + +DebuggerInstanceSettings::~DebuggerInstanceSettings () +{ +} + +DebuggerInstanceSettings& +DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs) +{ + if (this != &rhs) + { + m_prompt = rhs.m_prompt; + m_script_lang = rhs.m_script_lang; + } + + return *this; +} + +void +DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) +{ + if (var_name == PromptVarName()) + { + UserSettingsController::UpdateStringVariable (op, m_prompt, value, err); + if (!pending) + { + BroadcastPromptChange (instance_name, m_prompt.c_str()); + } + } + else if (var_name == ScriptLangVarName()) + { + bool success; + m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault, + &success); + } +} + +void +Debugger::DebuggerSettingsController::UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err) +{ + static ConstString term_width_name ("term-width"); + + if (var_name == term_width_name) + { + if (ValidTermWidthValue (value, err)) + { + m_term_width = atoi (value); + } + } +} + +void +DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) +{ + if (var_name == PromptVarName()) + { + value.AppendString (m_prompt.c_str()); + + } + else if (var_name == ScriptLangVarName()) + { + value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str()); + } +} + +void +DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) +{ + if (new_settings.get() == NULL) + return; + + DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get(); + + m_prompt = new_debugger_settings->m_prompt; + if (!pending) + BroadcastPromptChange (m_instance_name, m_prompt.c_str()); + + m_script_lang = new_debugger_settings->m_script_lang; +} + +void +Debugger::DebuggerSettingsController::GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) +{ + static ConstString term_width_name ("term-width"); + + if (var_name == term_width_name) + { + StreamString width_str; + width_str.Printf ("%d", m_term_width); + value.AppendString (width_str.GetData()); + } +} + +bool +DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt) +{ + std::string tmp_prompt; + + if (new_prompt != NULL) + { + tmp_prompt = new_prompt ; + int len = tmp_prompt.size(); + if (len > 1 + && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"') + && (tmp_prompt[len-1] == tmp_prompt[0])) + { + tmp_prompt = tmp_prompt.substr(1,len-2); + } + len = tmp_prompt.size(); + if (tmp_prompt[len-1] != ' ') + tmp_prompt.append(" "); + } + EventSP new_event_sp; + new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, + new EventDataBytes (tmp_prompt.c_str()))); + + if (instance_name.GetLength() != 0) + { + // Set prompt for a particular instance. + Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get(); + if (dbg != NULL) + { + dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp); + } + } + + return true; +} + +const ConstString +DebuggerInstanceSettings::CreateInstanceName () +{ + static int instance_count = 1; + StreamString sstr; + + sstr.Printf ("debugger_%d", instance_count); + ++instance_count; + + const ConstString ret_val (sstr.GetData()); + + return ret_val; +} + +const ConstString & +DebuggerInstanceSettings::PromptVarName () +{ + static ConstString prompt_var_name ("prompt"); + + return prompt_var_name; +} + +const ConstString & +DebuggerInstanceSettings::ScriptLangVarName () +{ + static ConstString script_lang_var_name ("script-lang"); + + return script_lang_var_name; +} + +//-------------------------------------------------- +// DebuggerSettingsController Variable Tables +//-------------------------------------------------- + + +SettingEntry +Debugger::DebuggerSettingsController::global_settings_table[] = +{ + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { "term-width" , eSetVarTypeInt, "80" , NULL, false , false , "The maximum number of columns to use for displaying text." }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + + +SettingEntry +Debugger::DebuggerSettingsController::instance_settings_table[] = +{ + //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, + { "script-lang" , eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." }, + { "prompt" , eSetVarTypeString, "(lldb)", NULL, false, false, "The debugger command line prompt displayed for the user." }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; Added: lldb/trunk/source/Core/UserSettingsController.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/UserSettingsController.cpp?rev=113041&view=auto ============================================================================== --- lldb/trunk/source/Core/UserSettingsController.cpp (added) +++ lldb/trunk/source/Core/UserSettingsController.cpp Fri Sep 3 19:03:46 2010 @@ -0,0 +1,1857 @@ +//====-- UserSettingsController.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "lldb/Core/UserSettingsController.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Interpreter/CommandInterpreter.h" + +using namespace lldb_private; + +UserSettingsController::UserSettingsController (const char *level_name, + const lldb::UserSettingsControllerSP &parent) : + m_default_settings (), + m_settings (), + m_children (), + m_pending_settings (), + m_live_settings (), + m_children_mutex (Mutex::eMutexTypeNormal), + m_pending_settings_mutex (Mutex::eMutexTypeNormal), + m_live_settings_mutex (Mutex::eMutexTypeNormal) +{ + m_settings.parent = parent; + m_settings.level_name.SetCString (level_name); +} + +UserSettingsController::~UserSettingsController () +{ + m_live_settings.clear(); +} + +void +UserSettingsController::InitializeGlobalVariables () +{ + static bool global_initialized = false; + int num_entries; + const char *prefix = GetLevelName().AsCString(); + + if (! global_initialized) + { + num_entries = m_settings.global_settings.size(); + for (int i = 0; i < num_entries; ++i) + { + SettingEntry &entry = m_settings.global_settings[i]; + if (entry.default_value != NULL) + { + StreamString full_name; + if (prefix[0] != '\0') + full_name.Printf ("%s.%s", prefix, entry.var_name); + else + full_name.Printf ("%s", entry.var_name); + SetVariable (full_name.GetData(), entry.default_value, lldb::eVarSetOperationAssign, false); + } + else if ((entry.var_type == lldb::eSetVarTypeEnum) + && (entry.enum_values != NULL)) + { + StreamString full_name; + if (prefix[0] != '\0') + full_name.Printf ("%s.%s", prefix, entry.var_name); + else + full_name.Printf ("%s", entry.var_name); + SetVariable (full_name.GetData(), entry.enum_values[0].string_value, lldb::eVarSetOperationAssign, + false); + } + } + global_initialized = true; + } +} + +const lldb::UserSettingsControllerSP & +UserSettingsController::GetParent () +{ + return m_settings.parent; +} + +void +UserSettingsController::RegisterChild (const lldb::UserSettingsControllerSP &child) +{ + Mutex::Locker locker (m_children_mutex); + + // Verify child is not already in m_children. + size_t num_children = m_children.size(); + bool found = false; + for (size_t i = 0; i < num_children; ++i) + { + if (m_children[i].get() == child.get()) + found = true; + } + + // Add child to m_children. + if (! found) + m_children.push_back (child); +} + +const ConstString & +UserSettingsController::GetLevelName () +{ + return m_settings.level_name; +} + +size_t +UserSettingsController::GetNumChildren () +{ + return m_children.size(); +} + +const lldb::UserSettingsControllerSP +UserSettingsController::GetChildAtIndex (size_t index) +{ + if (index < m_children.size()) + return m_children[index]; + + lldb::UserSettingsControllerSP dummy_value; + + return dummy_value; +} + +const SettingEntry * +UserSettingsController::GetGlobalEntry (const ConstString &var_name) +{ + + for (int i = 0; i < m_settings.global_settings.size(); ++i) + { + SettingEntry &entry = m_settings.global_settings[i]; + ConstString entry_name (entry.var_name); + if (entry_name == var_name) + return &entry; + } + + return NULL; +} + +const SettingEntry * +UserSettingsController::GetInstanceEntry (const ConstString &const_var_name) +{ + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString entry_name (entry.var_name); + if (entry_name == const_var_name) + return &entry; + } + + return NULL; +} + +void +UserSettingsController::BuildParentPrefix (std::string &parent_prefix) +{ + lldb::UserSettingsControllerSP parent = GetParent(); + if (parent.get() != NULL) + { + parent->BuildParentPrefix (parent_prefix); + if (parent_prefix.length() > 0) + parent_prefix.append ("."); + } + parent_prefix.append (GetLevelName().AsCString()); +} + +void +UserSettingsController::RemoveChild (const lldb::UserSettingsControllerSP &child) +{ + Mutex::Locker locker (m_children_mutex); + std::vector::iterator pos, end = m_children.end(); + + for (pos = m_children.begin(); pos != end; ++pos) + { + lldb::UserSettingsControllerSP entry = *pos; + if (entry == child) + { + m_children.erase (pos); + break; + } + } +} + +Error +UserSettingsController::SetVariable (const char *full_dot_name, + const char *value, + const lldb::VarSetOperationType op, + const bool override, + const char *index_value) +{ + Error err; + ConstString const_var_name; + const ConstString &default_name = InstanceSettings::GetDefaultName(); + + Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); + int num_pieces = names.GetArgumentCount(); + + if (num_pieces < 1) + { + err.SetErrorStringWithFormat ("'%s' is not a valid variable name; cannot assign value.\n", full_dot_name); + return err; + } + + ConstString prefix (names.GetArgumentAtIndex (0)); + + if ((prefix == m_settings.level_name) + || (m_settings.level_name.GetLength() == 0)) + { + + if (prefix == m_settings.level_name) + { + names.Shift (); + num_pieces = names.GetArgumentCount(); + } + + if (num_pieces == 0) + { + err.SetErrorString ("No variable name specified; cannot assign value.\n"); + return err; + } + else if (num_pieces == 1) + { + + // Must be one of the class-wide settings. + + const_var_name.SetCString (names.GetArgumentAtIndex (0)); + const SettingEntry *entry = GetGlobalEntry (const_var_name); + if (entry) + { + UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); + + if (err.Fail()) + return err; + + if ((value == NULL || value[0] == '\0') + && (op == lldb::eVarSetOperationAssign)) + { + if (entry->var_type != lldb::eSetVarTypeEnum) + value = entry->default_value; + else + value = entry->enum_values[0].string_value; + } + UpdateGlobalVariable (const_var_name, index_value, value, *entry, op, err); + } + else + { + // MIGHT be instance variable, to be for ALL instances. + + entry = GetInstanceEntry (const_var_name); + if (entry == NULL) + { + err.SetErrorStringWithFormat ("Unable to find variable '%s.%s'; cannot assign value.\n", + prefix.AsCString(), const_var_name.AsCString()); + return err; + } + else + { + UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); + + if (err.Fail()) + return err; + + if ((value == NULL || value[0] == '\0') + && (op == lldb::eVarSetOperationAssign)) + { + if (entry->var_type != lldb::eSetVarTypeEnum) + value = entry->default_value; + else + value = entry->enum_values[0].string_value; + } + + m_default_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + default_name, *entry, op, err, true); + if (override) + { + OverrideAllInstances (const_var_name, value, op, index_value, err); + + // Update all pending records as well. + std::map::iterator pos, end = m_pending_settings.end(); + for (pos = m_pending_settings.begin(); pos != end; end++) + { + const ConstString instance_name (pos->first.c_str()); + lldb::InstanceSettingsSP setting_sp = pos->second; + setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + instance_name, *entry, op, err, true); + } + } + } + } + } + else + { + // Either a child's setting or an instance setting. + + if (names.GetArgumentAtIndex(0)[0] == '[') + { + // An instance setting. Supposedly. + + ConstString instance_name (names.GetArgumentAtIndex (0)); + + // First verify that there is only one more name. + + names.Shift(); + + if (names.GetArgumentCount() != 1) + { + err.SetErrorStringWithFormat ("Invalid variable name format '%s'; cannot assign value.\n", + full_dot_name); + return err; + } + + // Next verify that it is a valid instance setting name. + + const_var_name.SetCString (names.GetArgumentAtIndex (0)); + const SettingEntry *entry = GetInstanceEntry (const_var_name); + + if (entry == NULL) + { + err.SetErrorStringWithFormat ("Unknown instance variable '%s'; cannot assign value.\n", + const_var_name.AsCString()); + return err; + } + + UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); + + if (err.Fail()) + return err; + + if ((value == NULL || value[0] == '\0') + && (op == lldb::eVarSetOperationAssign)) + { + if (entry->var_type != lldb::eSetVarTypeEnum) + value = entry->default_value; + else + value = entry->enum_values[0].string_value; + } + + // Now look for existing instance with given instance name; if not found, find or create pending + // setting for instance with given name. + + InstanceSettings *current_settings = FindSettingsForInstance (instance_name); + + if (current_settings != NULL) + { + current_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + instance_name, *entry, op, err, false); + + } + else + { + // Instance does not currently exist; make or update a pending setting for it. + lldb::InstanceSettingsSP current_settings_sp = PendingSettingsForInstance (instance_name); + + // Now we have a settings record, update it appropriately. + + current_settings_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + instance_name, *entry, op, err, true); + + { // Scope for mutex. + Mutex::Locker locker (m_pending_settings_mutex); + m_pending_settings[instance_name.AsCString()] = current_settings_sp; + } + + if (override) + { + OverrideAllInstances (const_var_name, value, op, index_value, err); + + // Update all pending records as well. + std::map::iterator pos; + std::map::iterator end = m_pending_settings.end(); + for (pos = m_pending_settings.begin(); pos != end; end++) + { + const ConstString tmp_inst_name (pos->first.c_str()); + lldb::InstanceSettingsSP setting_sp = pos->second; + setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + tmp_inst_name, *entry, op, err, true); + } + } + } + } + else + { + // A child setting. + lldb::UserSettingsControllerSP child; + ConstString child_prefix (names.GetArgumentAtIndex (0)); + int num_children = GetNumChildren(); + bool found = false; + for (int i = 0; i < num_children && !found; ++i) + { + child = GetChildAtIndex (i); + ConstString current_prefix = child->GetLevelName(); + if (current_prefix == child_prefix) + { + found = true; + std::string new_name; + for (int j = 0; j < names.GetArgumentCount(); ++j) + { + if (j > 0) + new_name += '.'; + new_name += names.GetArgumentAtIndex (j); + } + return child->SetVariable (new_name.c_str(), value, op, override, index_value); + } + } + if (!found) + { + err.SetErrorStringWithFormat ("Unable to find variable '%s'; cannot assign value.\n", + full_dot_name); + return err; + } + } + } + } + else + { + err.SetErrorStringWithFormat ("'%s' is not a valid level name; was expecting '%s'. Cannot assign value.\n", + prefix.AsCString(), m_settings.level_name.AsCString()); + } + + return err; +} + +StringList +UserSettingsController::GetVariable (const char *full_dot_name, lldb::SettableVariableType &var_type) +{ + Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); + ConstString const_var_name; + StringList value; + + int num_pieces = names.GetArgumentCount(); + + ConstString prefix (names.GetArgumentAtIndex (0)); + const_var_name.SetCString (names.GetArgumentAtIndex (num_pieces - 1)); + + const SettingEntry *global_entry = GetGlobalEntry (const_var_name); + const SettingEntry *instance_entry = GetInstanceEntry (const_var_name); + + if ((prefix != m_settings.level_name) + && (m_settings.level_name.GetLength () > 0)) + { + value.AppendString ("Invalid variable name"); + return value; + } + + // prefix name matched; remove it from names. + if (m_settings.level_name.GetLength() > 0) + names.Shift(); + + // Should we pass this off to a child? If there is more than one name piece left, and the next name piece + // matches a child prefix, then yes. + + lldb::UserSettingsControllerSP child; + if (names.GetArgumentCount() > 1) + { + ConstString child_prefix (names.GetArgumentAtIndex (0)); + bool found = false; + for (int i = 0; i < m_children.size() && !found; ++i) + { + if (child_prefix == m_children[i]->GetLevelName()) + { + found = true; + child = m_children[i]; + std::string new_name; + for (int j = 0; j < names.GetArgumentCount(); ++j) + { + if (j > 0) + new_name += '.'; + new_name += names.GetArgumentAtIndex (j); + } + return child->GetVariable (new_name.c_str(), var_type); + } + } + + if (!found) + { + // Cannot be handled by a child, because name did not match any child prefixes. + // Cannot be a class-wide variable because there are too many name pieces. + + if (instance_entry != NULL) + { + var_type = instance_entry->var_type; + ConstString instance_name (names.GetArgumentAtIndex (0)); + InstanceSettings *current_settings = FindSettingsForInstance (instance_name); + + if (current_settings != NULL) + { + current_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + else + { + // Look for instance name setting in pending settings. + + std::string inst_name_str = instance_name.AsCString(); + std::map::iterator pos; + + pos = m_pending_settings.find (inst_name_str); + if (pos != m_pending_settings.end()) + { + lldb::InstanceSettingsSP settings_sp = pos->second; + settings_sp->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + else + { + // No valid instance name; assume they want the default settings. + m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + } + } + else + value.AppendString ("Invalid variable name"); + } + } + else + { + // Only one name left. It must belong to the current level, or be an error. + if ((global_entry == NULL) + && (instance_entry == NULL)) + { + value.AppendString ("Invalid variable name"); + } + else if (global_entry) + { + var_type = global_entry->var_type; + GetGlobalSettingsValue (const_var_name, value); + } + else if (instance_entry) + { + var_type = instance_entry->var_type; + m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + } + + return value; +} + +void +UserSettingsController::RemovePendingSettings (const ConstString &instance_name) +{ + std::map::iterator pos; + std::string instance_name_str (instance_name.AsCString()); + Mutex::Locker locker (m_pending_settings_mutex); + + m_pending_settings.erase (instance_name_str); +} + +const lldb::InstanceSettingsSP & +UserSettingsController::FindPendingSettings (const ConstString &instance_name) +{ + std::map::iterator pos; + std::string instance_name_str (instance_name.AsCString()); + + { // Scope for mutex. + Mutex::Locker locker (m_pending_settings_mutex); + + pos = m_pending_settings.find (instance_name_str); + if (pos != m_pending_settings.end()) + return pos->second; + } + + return m_default_settings; +} + +void +UserSettingsController::CreateDefaultInstanceSettings () +{ + Error err; + const ConstString &default_name = InstanceSettings::GetDefaultName(); + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + const char *value = entry.default_value; + + if (entry.var_type == lldb::eSetVarTypeEnum) + value = entry.enum_values[0].string_value; + + m_default_settings->UpdateInstanceSettingsVariable (var_name, NULL, value, default_name, entry, + lldb::eVarSetOperationAssign, err, true); + } +} + +void +UserSettingsController::CopyDefaultSettings (const lldb::InstanceSettingsSP &actual_settings, + const ConstString &instance_name, + bool pending) +{ + Error err; + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + StringList value; + m_default_settings->GetInstanceSettingsValue (entry, var_name, value); + + std::string value_str; + if (value.GetSize() == 1) + value_str.append (value.GetStringAtIndex (0)); + else if (value.GetSize() > 1) + { + for (int j = 0; j < value.GetSize(); ++j) + { + if (j > 0) + value_str.append (" "); + value_str.append (value.GetStringAtIndex (j)); + } + } + + actual_settings->UpdateInstanceSettingsVariable (var_name, NULL, value_str.c_str(), instance_name, entry, + lldb::eVarSetOperationAssign, err, pending); + + } +} + +lldb::InstanceSettingsSP +UserSettingsController::PendingSettingsForInstance (const ConstString &instance_name) +{ + std::string name_str (instance_name.AsCString()); + std::map::iterator pos; + Mutex::Locker locker (m_pending_settings_mutex); + + pos = m_pending_settings.find (name_str); + if (pos != m_pending_settings.end()) + { + lldb::InstanceSettingsSP settings_sp = pos->second; + return settings_sp; + } + else + { + lldb::InstanceSettingsSP default_settings_sp = + m_pending_settings[InstanceSettings::GetDefaultName().AsCString()]; + lldb::InstanceSettingsSP new_settings_sp = CreateNewInstanceSettings (); + CopyDefaultSettings (new_settings_sp, instance_name, true); + m_pending_settings[name_str] = new_settings_sp; + return new_settings_sp; + } + + // Should never reach this line. + + lldb::InstanceSettingsSP dummy; + + return dummy; +} + +void +UserSettingsController::GetAllDefaultSettingValues (StreamString &result_stream) +{ + std::string parent_prefix; + BuildParentPrefix (parent_prefix); + const char *prefix = parent_prefix.c_str(); + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + StringList tmp_value; + m_default_settings->GetInstanceSettingsValue (entry, var_name, tmp_value); + + StreamString value_string; + + if (tmp_value.GetSize() == 1) + value_string.Printf ("%s", tmp_value.GetStringAtIndex (0)); + else + { + for (int j = 0; j < tmp_value.GetSize(); ++j) + value_string.Printf ("%s ", tmp_value.GetStringAtIndex (j)); + } + + if (! parent_prefix.empty()) // May need to test size() > 0 + result_stream.Printf ("%s.[DEFAULT].%s (%s) = '%s'\n", prefix, var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + else + result_stream.Printf ("[DEFAULT].%s (%s) = '%s'\n", var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + } +} + +void +UserSettingsController::GetAllPendingSettingValues (StreamString &result_stream) +{ + //StreamString description; + std::map::iterator pos; + + std::string parent_prefix; + BuildParentPrefix (parent_prefix); + const char *prefix = parent_prefix.c_str(); + + for (pos = m_pending_settings.begin(); pos != m_pending_settings.end(); ++pos) + { + std::string tmp_name = pos->first; + lldb::InstanceSettingsSP settings_sp = pos->second; + + const ConstString instance_name (tmp_name.c_str()); + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + StringList tmp_value; + settings_sp->GetInstanceSettingsValue (entry, var_name, tmp_value); + + StreamString value_str; + + if (tmp_value.GetSize() == 0) + break; + if (tmp_value.GetSize() == 1) + value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); + else + { + for (int j = 0; j < tmp_value.GetSize(); ++j) + value_str.Printf ("%s ", tmp_value.GetStringAtIndex (j)); + } + + if (parent_prefix.length() > 0) + { + result_stream.Printf ("%s.%s.%s (%s) = '%s' [pending]\n", prefix, instance_name.AsCString(), + var_name.AsCString(), UserSettingsController::GetTypeString (entry.var_type), + value_str.GetData()); + } + else + { + result_stream.Printf ("%s (%s) = '%s' [pending]\n", var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), + value_str.GetData()); + } + } + } +} + +InstanceSettings * +UserSettingsController::FindSettingsForInstance (const ConstString &instance_name) +{ + std::string instance_name_str (instance_name.AsCString()); + std::map::iterator pos; + + pos = m_live_settings.find (instance_name_str); + if (pos != m_live_settings.end ()) + { + InstanceSettings *settings = pos->second; + return settings; + } + + return NULL; +} + +void +UserSettingsController::GetAllInstanceVariableValues (CommandInterpreter &interpreter, + StreamString &result_stream) +{ + std::map::iterator pos; + std::string parent_prefix; + BuildParentPrefix (parent_prefix); + const char *prefix = parent_prefix.c_str(); + StreamString description; + + for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) + { + std::string instance_name = pos->first; + InstanceSettings *settings = pos->second; + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + const ConstString var_name (entry.var_name); + StringList tmp_value; + settings->GetInstanceSettingsValue (entry, var_name, tmp_value); + StreamString tmp_value_str; + + if (tmp_value.GetSize() == 0) + break; + + if (tmp_value.GetSize() == 1) + tmp_value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); + else + { + for (int j = 0; j < tmp_value.GetSize(); ++j) + tmp_value_str.Printf ("%s ",tmp_value.GetStringAtIndex (j)); + } + + description.Clear(); + if (parent_prefix.length() > 0) + { + description.Printf ("%s.%s.%s (%s) = '%s'", prefix, instance_name.c_str(), var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), + tmp_value_str.GetData()); + } + else + { + description.Printf ("%s (%s) = '%s'", var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), tmp_value_str.GetData()); + } + result_stream.Printf ("%s\n", description.GetData()); + } + } +} + +void +UserSettingsController::OverrideAllInstances (const ConstString &var_name, + const char *value, + lldb::VarSetOperationType op, + const char *index_value, + Error &err) +{ + std::map::iterator pos; + StreamString description; + + for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) + { + InstanceSettings *settings = pos->second; + StreamString tmp_name; + tmp_name.Printf ("[%s]", settings->GetInstanceName().AsCString()); + const ConstString instance_name (tmp_name.GetData()); + const SettingEntry *entry = GetInstanceEntry (var_name); + settings->UpdateInstanceSettingsVariable (var_name, index_value, value, instance_name, *entry, op, err, false); + + } +} + +void +UserSettingsController::RegisterInstanceSettings (InstanceSettings *instance_settings) +{ + Mutex::Locker locker (m_live_settings_mutex); + StreamString tmp_name; + tmp_name.Printf ("[%s]", instance_settings->GetInstanceName().AsCString()); + const ConstString instance_name (tmp_name.GetData()); + std::string instance_name_str (instance_name.AsCString()); + if (instance_name_str.compare (InstanceSettings::GetDefaultName().AsCString()) != 0) + m_live_settings[instance_name_str] = instance_settings; +} + +void +UserSettingsController::UnregisterInstanceSettings (InstanceSettings *instance) +{ + Mutex::Locker locker (m_live_settings_mutex); + StreamString tmp_name; + tmp_name.Printf ("[%s]", instance->GetInstanceName().AsCString()); + std::string instance_name (tmp_name.GetData()); + + std::map ::iterator pos; + + pos = m_live_settings.find (instance_name); + if (pos != m_live_settings.end()) + m_live_settings.erase (pos); +} + +void +UserSettingsController::CreateSettingsVector (const SettingEntry *table, + bool global) +{ + int i = 0; + while (table[i].var_name != NULL) + { + const SettingEntry &table_entry = table[i]; + ConstString const_var_name (table_entry.var_name); + SettingEntry new_entry; + + new_entry = table_entry; + new_entry.var_name = const_var_name.AsCString(); + + if (global) + m_settings.global_settings.push_back (new_entry); + else + m_settings.instance_settings.push_back (new_entry); + + ++i; + } +} + +//---------------------------------------------------------------------- +// UserSettingsController static methods +//---------------------------------------------------------------------- + +int +FindMaxNameLength (std::vector table) +{ + int max_length = 1; + + for (int i = 0; i < table.size(); ++i) + { + int len = strlen (table[i].var_name); + if (len > max_length) + max_length = len; + } + + return max_length; +} + +const char * +UserSettingsController::GetTypeString (lldb::SettableVariableType var_type) +{ + switch (var_type) + { + case lldb::eSetVarTypeInt: + return "int"; + case lldb::eSetVarTypeBool: + return "boolean"; + case lldb::eSetVarTypeString: + return "string"; + case lldb::eSetVarTypeArray: + return "array"; + case lldb::eSetVarTypeDictionary: + return "dictionary"; + case lldb::eSetVarTypeEnum: + return "enum"; + case lldb::eSetVarTypeNone: + return "no type"; + } + + return ""; +} + +void +UserSettingsController::PrintEnumValues (const lldb::OptionEnumValueElement *enum_values, Stream &str) +{ + int i = 0; + while (enum_values[i].string_value != NULL) + { + str.Printf ("%s ", enum_values[i].string_value); + ++i; + } + +} + +void +UserSettingsController::FindAllSettingsDescriptions (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err) +{ + // Write out current prefix line. + StreamString prefix_line; + StreamString description; + uint32_t max_len; + int num_entries = root->m_settings.global_settings.size(); + + max_len = FindMaxNameLength (root->m_settings.global_settings); + + if (! current_prefix.empty()) + result_stream.Printf ("\n'%s' variables:\n\n", current_prefix.c_str()); + else + result_stream.Printf ("\nTop level variables:\n\n"); + + if (num_entries > 0) + { + // Write out all "global" variables. + for (int i = 0; i < num_entries; ++i) + { + SettingEntry entry = root->m_settings.global_settings[i]; + description.Clear(); + if (entry.var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); + description.Printf ("[static, enum] %s. Valid values: {%s} (default: '%s')", entry.description, + enum_values_str.GetData(), entry.enum_values[0].string_value); + } + else if (entry.default_value != NULL) + description.Printf ("[static, %s] %s (default: '%s')", GetTypeString (entry.var_type), + entry.description, entry.default_value); + + else + description.Printf ("[static, %s] %s (default: '')", GetTypeString (entry.var_type), + entry.description); + interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), + max_len); + } + } + + num_entries = root->m_settings.instance_settings.size(); + max_len = FindMaxNameLength (root->m_settings.instance_settings); + + if (num_entries > 0) + { + // Write out all instance variables. + for (int i = 0; i < num_entries; ++i) + { + SettingEntry entry = root->m_settings.instance_settings[i]; + description.Clear(); + if (entry.var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); + description.Printf ("[instance, enum] %s. Valid values: {%s} (default: '%s')", entry.description, + enum_values_str.GetData(), entry.enum_values[0].string_value); + } + else if (entry.default_value != NULL) + description.Printf ("[instance, %s] %s (default: '%s')", GetTypeString (entry.var_type), + entry.description, entry.default_value); + else + description.Printf ("[instance, %s] %s (default: '')", GetTypeString (entry.var_type), + entry.description); + interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), + max_len); + } + + } + + // Now, recurse across all children. + int num_children = root->GetNumChildren(); + for (int i = 0; i < num_children; ++i) + { + lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); + + if (child) + { + ConstString child_prefix = child->GetLevelName(); + StreamString new_prefix; + if (! current_prefix.empty() ) // May need to see if size() > 0 + new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); + else + new_prefix.Printf ("%s", child_prefix.AsCString()); + std::string new_prefix_str = new_prefix.GetData(); + UserSettingsController::FindAllSettingsDescriptions (interpreter, child, new_prefix_str, result_stream, + err); + } + } +} + +void +UserSettingsController::GetAllVariableValues (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err) +{ + StreamString description; + int num_entries = root->m_settings.global_settings.size(); + lldb::SettableVariableType var_type; + + + for (int i = 0; i < num_entries; ++i) + { + StreamString full_var_name; + SettingEntry entry = root->m_settings.global_settings[i]; + if (! current_prefix.empty()) // May need to see if size() > 0 + full_var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name); + else + full_var_name.Printf ("%s", entry.var_name); + StringList value = root->GetVariable (full_var_name.GetData(), var_type); + description.Clear(); + if (value.GetSize() == 1) + description.Printf ("%s (%s) = %s", full_var_name.GetData(), GetTypeString (entry.var_type), + value.GetStringAtIndex (0)); + else + { + description.Printf ("%s (%s) = ", full_var_name.GetData(), GetTypeString (entry.var_type)); + for (int j = 0; j < value.GetSize(); ++j) + description.Printf ("%s ", value.GetStringAtIndex (j)); + } + + result_stream.Printf ("%s\n", description.GetData()); + } + + root->GetAllInstanceVariableValues (interpreter, result_stream); + root->GetAllPendingSettingValues (result_stream); + root->GetAllDefaultSettingValues (result_stream); + + + // Now, recurse across all children. + int num_children = root->GetNumChildren(); + for (int i = 0; i < num_children; ++i) + { + lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); + + if (child) + { + ConstString child_prefix = child->GetLevelName(); + StreamString new_prefix; + if (! current_prefix.empty()) // May need to see if size() > 0 + new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); + else + new_prefix.Printf ("%s", child_prefix.AsCString()); + std::string new_prefix_str = new_prefix.GetData(); + UserSettingsController::GetAllVariableValues (interpreter, child, new_prefix_str, result_stream, + err); + } + } + +} + +Args +UserSettingsController::BreakNameIntoPieces (const char *full_dot_name) +{ + Args return_value; + std::string name_string (full_dot_name); + bool done = false; + + std::string piece; + std::string remainder (full_dot_name); + + while (!done) + { + size_t idx = remainder.find_first_of ('.'); + piece = remainder.substr (0, idx); + return_value.AppendArgument (piece.c_str()); + if (idx != std::string::npos) + remainder = remainder.substr (idx+1); + else + done = true; + } + + return return_value; +} + +bool +UserSettingsController::IsLiveInstance (const std::string &instance_name) +{ + std::map::iterator pos; + + pos = m_live_settings.find (instance_name); + if (pos != m_live_settings.end()) + return true; + + return false; +} + +int +UserSettingsController::CompleteSettingsValue (lldb::UserSettingsControllerSP root_settings, + const char *full_dot_name, + const char *partial_value, + bool &word_complete, + StringList &matches) +{ + Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); + int num_pieces = names.GetArgumentCount(); + word_complete = true; + + ConstString root_level = root_settings->GetLevelName(); + int num_extra_levels = num_pieces - 2; + if ((num_extra_levels > 0) + && root_level.GetLength() > 0) + { + ConstString current_level (names.GetArgumentAtIndex (0)); + if (current_level == root_level) + { + names.Shift(); + --num_extra_levels; + } + else + return 0; + } + + for (int i = 0; i < num_extra_levels; ++i) + { + ConstString child_level (names.GetArgumentAtIndex (0)); + bool found = false; + int num_children = root_settings->GetNumChildren(); + for (int j = 0; j < num_children && !found; ++j) + { + if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) + { + found = true; + root_settings = root_settings->GetChildAtIndex (j); + names.Shift(); + } + } + if (!found) + return 0; + } + + if (names.GetArgumentCount() != 2) + return 0; + + std::string next_name (names.GetArgumentAtIndex (0)); + int len = next_name.length(); + names.Shift(); + + if ((next_name[0] == '[') && (next_name[len-1] == ']')) + { + // 'next_name' is instance name. Instance names are irrelevent here. + } + else + { + // 'next_name' is child name. + bool found = false; + int num_children = root_settings->GetNumChildren(); + ConstString child_level (next_name.c_str()); + for (int j = 0; j < num_children && !found; ++j) + { + if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) + { + found = true; + root_settings = root_settings->GetChildAtIndex (j); + } + } + if (!found) + return 0; + } + + ConstString var_name (names.GetArgumentAtIndex(0)); + const SettingEntry *entry = root_settings->GetGlobalEntry (var_name); + if (entry == NULL) + entry = root_settings->GetInstanceEntry (var_name); + + if (entry == NULL) + return 0; + + if (entry->var_type == lldb::eSetVarTypeBool) + return UserSettingsController::BooleanMatches (partial_value, word_complete, matches); + else if (entry->var_type == lldb::eSetVarTypeEnum) + return UserSettingsController::EnumMatches (partial_value, entry->enum_values, word_complete, matches); + else + return 0; +} + +int +UserSettingsController::BooleanMatches (const char *partial_value, + bool &word_complete, + StringList &matches) +{ + static const std::string true_string ("true"); + static const std::string false_string ("false"); + + if (partial_value == NULL) + { + matches.AppendString ("true"); + matches.AppendString ("false"); + } + else + { + int partial_len = strlen (partial_value); + + if ((partial_len <= true_string.length()) + && (true_string.find (partial_value) == 0)) + matches.AppendString ("true"); + else if ((partial_len <= false_string.length()) + && (false_string.find (partial_value) == 0)) + matches.AppendString ("false"); + } + + word_complete = false; + if (matches.GetSize() == 1) + word_complete = true; + + return matches.GetSize(); +} + +int +UserSettingsController::EnumMatches (const char *partial_value, + lldb::OptionEnumValueElement *enum_values, + bool &word_complete, + StringList &matches) +{ + int len = (partial_value != NULL) ? strlen (partial_value) : 0; + + int i = 0; + while (enum_values[i].string_value != NULL) + { + if (len == 0) + matches.AppendString (enum_values[i].string_value); + else + { + std::string tmp_value (enum_values[i].string_value); + if ((len <= tmp_value.length()) + && tmp_value.find (partial_value) == 0) + matches.AppendString (enum_values[i].string_value); + } + ++i; + } + + word_complete = false; + if (matches.GetSize() == 1) + word_complete = true; + + return matches.GetSize(); +} + +int +UserSettingsController::CompleteSettingsNames (lldb::UserSettingsControllerSP root_settings, + Args &partial_setting_name_pieces, + bool &word_complete, + StringList &matches) +{ + int num_matches = 0; + int num_name_pieces = partial_setting_name_pieces.GetArgumentCount(); + + if (num_name_pieces > 1) + { + // There are at least two pieces, perhaps with multiple level names preceding them. + // First traverse all the extra levels, until we have exactly two pieces left. + + int num_extra_levels = num_name_pieces - 2; + + // Deal with current level first. + + ConstString root_level = root_settings->GetLevelName(); + if ((num_extra_levels > 0) + && (root_level.GetLength() > 0)) + { + ConstString current_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); + if (current_level == root_level) + { + partial_setting_name_pieces.Shift(); + --num_extra_levels; + } + else + return 0; // The current level did not match the name pieces; something is wrong, so return immediately + + } + + for (int i = 0; i < num_extra_levels; ++i) + { + ConstString child_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); + bool found = false; + int num_children = root_settings->GetNumChildren(); + for (int j = 0; j < num_children && !found; ++j) + { + if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) + { + found = true; + root_settings = root_settings->GetChildAtIndex (j); + partial_setting_name_pieces.Shift(); + } + } + if (! found) + { + return 0; // Unable to find a matching child level name; something is wrong, so return immediately. + } + } + + // Now there should be exactly two name pieces left. If not there is an error, so return immediately + + if (partial_setting_name_pieces.GetArgumentCount() != 2) + return 0; + + std::string next_name (partial_setting_name_pieces.GetArgumentAtIndex (0)); + int len = next_name.length(); + partial_setting_name_pieces.Shift(); + + if ((next_name[0] == '[') && (next_name[len-1] == ']')) + { + // 'next_name' is an instance name. The last name piece must be a non-empty partial match against an + // instance_name, assuming 'next_name' is valid. + + if (root_settings->IsLiveInstance (next_name)) + { + std::string complete_prefix; + root_settings->BuildParentPrefix (complete_prefix); + + num_matches = root_settings->InstanceVariableMatches(partial_setting_name_pieces.GetArgumentAtIndex(0), + complete_prefix, + next_name.c_str(), + matches); + word_complete = true; + if (num_matches > 1) + word_complete = false; + + return num_matches; + } + else + return 0; // Invalid instance_name + } + else + { + // 'next_name' must be a child name. Find the correct child and pass the remaining piece to be resolved. + bool found = false; + int num_children = root_settings->GetNumChildren(); + ConstString child_level (next_name.c_str()); + for (int i = 0; i < num_children; ++i) + { + if (root_settings->GetChildAtIndex (i)->GetLevelName() == child_level) + { + found = true; + return UserSettingsController::CompleteSettingsNames (root_settings->GetChildAtIndex (i), + partial_setting_name_pieces, + word_complete, matches); + } + } + if (!found) + return 0; + } + } + else if (num_name_pieces == 1) + { + std::string complete_prefix; + root_settings->BuildParentPrefix (complete_prefix); + + word_complete = true; + std::string name (partial_setting_name_pieces.GetArgumentAtIndex (0)); + + if (name[0] == '[') + { + // It's a partial instance name. + + num_matches = root_settings->LiveInstanceMatches (name.c_str(), complete_prefix, word_complete, matches); + } + else + { + // It could be anything *except* an instance name... + + num_matches = root_settings->GlobalVariableMatches (name.c_str(), complete_prefix, matches); + num_matches += root_settings->InstanceVariableMatches (name.c_str(), complete_prefix, NULL, matches); + num_matches += root_settings->ChildMatches (name.c_str(), complete_prefix, word_complete, matches); + } + + if (num_matches > 1) + word_complete = false; + + return num_matches; + } + else + { + // We have a user settings controller with a blank partial string. Return everything possible at this level. + + std::string complete_prefix; + root_settings->BuildParentPrefix (complete_prefix); + num_matches = root_settings->GlobalVariableMatches (NULL, complete_prefix, matches); + num_matches += root_settings->InstanceVariableMatches (NULL, complete_prefix, NULL, matches); + num_matches += root_settings->LiveInstanceMatches (NULL, complete_prefix, word_complete, matches); + num_matches += root_settings->ChildMatches (NULL, complete_prefix, word_complete, matches); + word_complete = false; + return num_matches; + } + + return num_matches; +} + +int +UserSettingsController::GlobalVariableMatches (const char *partial_name, + const std::string &complete_prefix, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_matches = 0; + + for (size_t i = 0; i < m_settings.global_settings.size(); ++i) + { + SettingEntry &entry = m_settings.global_settings[i]; + std::string var_name (entry.var_name); + if ((partial_len == 0) + || ((partial_len <= var_name.length()) + && (var_name.find (partial_name) == 0))) + { + StreamString match_name; + if (complete_prefix.length() > 0) + { + match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); + matches.AppendString (match_name.GetData()); + } + else + matches.AppendString (var_name.c_str()); + ++num_matches; + } + } + return num_matches; +} + +int +UserSettingsController::InstanceVariableMatches (const char *partial_name, + const std::string &complete_prefix, + const char *instance_name, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_matches = 0; + + for (size_t i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + std::string var_name (entry.var_name); + if ((partial_len == 0) + || ((partial_len <= var_name.length()) + && (var_name.find (partial_name) == 0))) + { + StreamString match_name; + if (complete_prefix.length() > 0) + { + if (instance_name != NULL) + match_name.Printf ("%s.%s.%s", complete_prefix.c_str(), instance_name, var_name.c_str()); + else + match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); + + matches.AppendString (match_name.GetData()); + } + else + { + if (instance_name != NULL) + { + match_name.Printf ("%s.%s", instance_name, var_name.c_str()); + matches.AppendString (match_name.GetData()); + } + else + matches.AppendString (var_name.c_str()); + } + ++num_matches; + } + } + return num_matches; +} + +int +UserSettingsController::LiveInstanceMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_matches = 0; + + std::map::iterator pos; + for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) + { + std::string instance_name = pos->first; + if ((partial_len == 0) + || ((partial_len <= instance_name.length()) + && (instance_name.find (partial_name) == 0))) + { + StreamString match_name; + if (complete_prefix.length() > 0) + match_name.Printf ("%s.%s.", complete_prefix.c_str(), instance_name.c_str()); + else + match_name.Printf ("%s.", instance_name.c_str()); + matches.AppendString (match_name.GetData()); + ++num_matches; + } + } + + if (num_matches > 0) + word_complete = false; + + return num_matches; +} + +int +UserSettingsController::ChildMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_children = GetNumChildren(); + int num_matches = 0; + for (int i = 0; i < num_children; ++i) + { + std::string child_name (GetChildAtIndex(i)->GetLevelName().AsCString()); + StreamString match_name; + if ((partial_len == 0) + || ((partial_len <= child_name.length()) + && (child_name.find (partial_name) == 0))) + { + if (complete_prefix.length() > 0) + match_name.Printf ("%s.%s.", complete_prefix.c_str(), child_name.c_str()); + else + match_name.Printf ("%s.", child_name.c_str()); + matches.AppendString (match_name.GetData()); + ++num_matches; + } + } + + if (num_matches > 0) + word_complete = false; + + return num_matches; +} + +void +UserSettingsController::VerifyOperationForType (lldb::SettableVariableType var_type, + lldb::VarSetOperationType op, + const ConstString &var_name, + Error &err) +{ + if (op == lldb::eVarSetOperationAssign) + return; + + + if (op == lldb::eVarSetOperationInvalid) + { + err.SetErrorString ("Invalid 'settings ' subcommand operation.\n"); + return; + } + + switch (op) + { + case lldb::eVarSetOperationInsertBefore: + case lldb::eVarSetOperationInsertAfter: + if (var_type != lldb::eSetVarTypeArray) + err.SetErrorString ("Invalid operation: This operation can only be performed on array variables.\n"); + break; + case lldb::eVarSetOperationReplace: + case lldb::eVarSetOperationRemove: + if ((var_type != lldb::eSetVarTypeArray) + && (var_type != lldb::eSetVarTypeDictionary)) + err.SetErrorString ("Invalid operation: This operation can only be performed on array or dictionary" + " variables.\n"); + break; + case lldb::eVarSetOperationAppend: + case lldb::eVarSetOperationClear: + if ((var_type != lldb::eSetVarTypeArray) + && (var_type != lldb::eSetVarTypeDictionary) + && (var_type != lldb::eSetVarTypeString)) + err.SetErrorString ("Invalid operation: This operation can only be performed on array, dictionary " + "or string variables.\n"); + break; + default: + break; + } + + return; +} + +void +UserSettingsController::UpdateStringVariable (lldb::VarSetOperationType op, + std::string &string_var, + const char *new_value, + Error &err) +{ + if (op == lldb::eVarSetOperationAssign) + string_var = new_value; + else if (op == lldb::eVarSetOperationAppend) + string_var.append (new_value); + else if (op == lldb::eVarSetOperationClear) + string_var.clear(); + else + err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); +} + +void +UserSettingsController::UpdateBooleanVariable (lldb::VarSetOperationType op, + bool &bool_var, + const char *new_value, + Error &err) +{ + if (op != lldb::eVarSetOperationAssign) + err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); + + + if ((new_value == NULL) + || (new_value[0] == '\0')) + err.SetErrorString ("Invalid value. Cannot perform update.\n"); + + std::string bool_val_str (new_value); + + std::transform (bool_val_str.begin(), bool_val_str.end(), bool_val_str.begin(), ::tolower); + + if (bool_val_str == "true") + bool_var = true; + else if (bool_val_str == "false") + bool_var = false; +} + +void +UserSettingsController::UpdateStringArrayVariable (lldb::VarSetOperationType op, + const char *index_value, + Args &array_var, + const char *new_value, + Error &err) +{ + int index = -1; + bool valid_index = true; + + if (index_value != NULL) + { + for (int i = 0; i < strlen(index_value); ++i) + if (!isdigit (index_value[i])) + { + valid_index = false; + err.SetErrorStringWithFormat ("'%s' is not a valid integer index. Cannot update array value.\n", + index_value); + } + + if (valid_index) + index = atoi (index_value); + + if (index < 0 + || index >= array_var.GetArgumentCount()) + { + valid_index = false; + err.SetErrorStringWithFormat ("%d is outside the bounds of the specified array variable. " + "Cannot update array value.\n", index); + } + } + + switch (op) + { + case lldb::eVarSetOperationAssign: + array_var.SetCommandString (new_value); + break; + case lldb::eVarSetOperationReplace: + { + if (valid_index) + array_var.ReplaceArgumentAtIndex (index, new_value); + break; + } + case lldb::eVarSetOperationInsertBefore: + case lldb::eVarSetOperationInsertAfter: + { + if (valid_index) + { + Args new_array (new_value); + if (op == lldb::eVarSetOperationInsertAfter) + ++index; + for (int i = 0; i < new_array.GetArgumentCount(); ++i) + array_var.InsertArgumentAtIndex (index, new_array.GetArgumentAtIndex (i)); + } + break; + } + case lldb::eVarSetOperationRemove: + { + if (valid_index) + array_var.DeleteArgumentAtIndex (index); + break; + } + case lldb::eVarSetOperationAppend: + { + Args new_array (new_value); + array_var.AppendArguments (new_array); + break; + } + case lldb::eVarSetOperationClear: + array_var.Clear(); + break; + default: + err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); + break; + } +} + +void +UserSettingsController::UpdateDictionaryVariable (lldb::VarSetOperationType op, + const char *index_value, + std::map &dictionary, + const char *new_value, + Error &err) +{ + switch (op) + { + case lldb::eVarSetOperationReplace: + if (index_value != NULL) + { + std::string key (index_value); + std::map::iterator pos; + + pos = dictionary.find (key); + if (pos != dictionary.end()) + dictionary[key] = new_value; + else + err.SetErrorStringWithFormat ("'%s' is not an existing key; cannot replace value.\n", index_value); + } + else + err.SetErrorString ("'settings replace' requires a key for dictionary variables. No key supplied.\n"); + break; + case lldb::eVarSetOperationRemove: + if (index_value != NULL) + { + std::string key (index_value); + dictionary.erase (key); + } + else + err.SetErrorString ("'settings remove' requires a key for dictionary variables. No key supplied.\n"); + break; + case lldb::eVarSetOperationClear: + dictionary.clear (); + break; + case lldb::eVarSetOperationAppend: + case lldb::eVarSetOperationAssign: + { + Args args (new_value); + size_t num_args = args.GetArgumentCount(); + for (size_t i = 0; i < num_args; ++i) + { + std::string tmp_arg = args.GetArgumentAtIndex (i); + size_t eq_sign = tmp_arg.find ('='); + if (eq_sign != std::string::npos) + { + if (eq_sign > 4) + { + std::string tmp_key = tmp_arg.substr (0, eq_sign); + std::string real_value = tmp_arg.substr (eq_sign+1); + if ((tmp_key[0] == '[') + && (tmp_key[1] == '"') + && (tmp_key[eq_sign-2] == '"') + && (tmp_key[eq_sign-1] == ']')) + { + std::string real_key = tmp_key.substr (2, eq_sign-4); + dictionary[real_key] = real_value; + } + else + err.SetErrorString ("Invalid key format for dictionary assignment. " + "Expected '[\"\"]'\n"); + } + else + err.SetErrorString ("Invalid key format for dictionary assignment. " + "Expected '[\"\"]'\n"); + } + else + err.SetErrorString ("Invalid format for dictionary value. Expected '[\"\"]='\n"); + } + } + break; + case lldb::eVarSetOperationInsertBefore: + case lldb::eVarSetOperationInsertAfter: + err.SetErrorString ("Specified operation cannot be performed on dictionary variables.\n"); + break; + default: + err.SetErrorString ("Unrecognized operation.\n"); + break; + } +} + +const char * +UserSettingsController::EnumToString (const lldb::OptionEnumValueElement *enum_values, + int value) +{ + int i = 0; + while (enum_values[i].string_value != NULL) + { + if (enum_values[i].value == value) + return enum_values[i].string_value; + ++i; + } + + return "Invalid enumeration value"; +} + + +void +UserSettingsController::UpdateEnumVariable (lldb::OptionEnumValueElement *enum_values, + int *enum_var, + const char *new_value, + Error &err) +{ + bool found_one; + + *enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, &found_one); + + if (!found_one) + err.SetErrorString ("Invalid enumeration value; cannot update variable.\n"); +} + +//---------------------------------------------------------------------- +// class InstanceSettings +//---------------------------------------------------------------------- + +InstanceSettings::InstanceSettings (UserSettingsController &owner, const char *instance_name) : + m_owner (owner), + m_instance_name (instance_name) +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + m_owner.RegisterInstanceSettings (this); +} + +InstanceSettings::~InstanceSettings () +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + m_owner.UnregisterInstanceSettings (this); +} + +const ConstString & +InstanceSettings::GetDefaultName () +{ + static const ConstString g_default_settings_name ("[DEFAULT]"); + + return g_default_settings_name; +} Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri Sep 3 19:03:46 2010 @@ -12,7 +12,6 @@ #include #include -#include "../Commands/CommandObjectAppend.h" #include "../Commands/CommandObjectApropos.h" #include "../Commands/CommandObjectArgs.h" #include "../Commands/CommandObjectBreakpoint.h" @@ -30,9 +29,7 @@ #include "lldb/Interpreter/CommandObjectRegexCommand.h" #include "../Commands/CommandObjectRegister.h" #include "CommandObjectScript.h" -#include "../Commands/CommandObjectSet.h" #include "../Commands/CommandObjectSettings.h" -#include "../Commands/CommandObjectShow.h" #include "../Commands/CommandObjectSource.h" #include "../Commands/CommandObjectCommands.h" #include "../Commands/CommandObjectSyntax.h" @@ -61,9 +58,13 @@ ) : Broadcaster ("CommandInterpreter"), m_debugger (debugger), - m_script_language (script_language), m_synchronous_execution (synchronous_execution) { + const char *dbg_name = debugger.GetInstanceName().AsCString(); + std::string lang_name = ScriptInterpreter::LanguageToString (script_language); + StreamString var_name; + var_name.Printf ("[%s].script-lang", dbg_name); + debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(), lldb::eVarSetOperationAssign, false); } void @@ -75,8 +76,6 @@ LoadCommandDictionary (); - InitializeVariables (); - // Set up some initial aliases. result.Clear(); HandleCommand ("command alias q quit", false, result); result.Clear(); HandleCommand ("command alias run process launch", false, result); @@ -98,72 +97,6 @@ result.Clear(); HandleCommand ("command alias list source list", false, result); } -void -CommandInterpreter::InitializeVariables () -{ - Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); - - m_variables["prompt"] = - StateVariableSP (new StateVariable ("prompt", - "(lldb) ", - false, - "The debugger prompt displayed for the user.", - StateVariable::BroadcastPromptChange)); - - m_variables["run-args"] = - StateVariableSP (new StateVariable ("run-args", - (Args*)NULL, - "An argument list containing the arguments to be passed to the executable when it is launched.")); - - - m_variables["env-vars"] = - StateVariableSP (new StateVariable ("env-vars", - (Args*)NULL, - "A list of strings containing the environment variables to be passed to the executable's environment.")); - - m_variables["input-path"] = - StateVariableSP (new StateVariable ("input-path", - "/dev/stdin", - false, - "The file/path to be used by the executable program for reading its input.")); - - m_variables["output-path"] = - StateVariableSP (new StateVariable ( "output-path", - "/dev/stdout", - false, - "The file/path to be used by the executable program for writing its output.")); - - m_variables["error-path"] = - StateVariableSP (new StateVariable ("error-path", - "/dev/stderr", - false, - "The file/path to be used by the executable program for writing its error messages.")); - - m_variables["arch"] = - StateVariableSP (new StateVariable ("arch", - "", - false, - "The architecture to be used for running the executable (e.g. i386, x86_64, etc).")); - - m_variables["script-lang"] = - StateVariableSP (new StateVariable ("script-lang", - "Python", - false, - "The script language to be used for evaluating user-written scripts.", - StateVariable::VerifyScriptLanguage)); - - m_variables["term-width"] = - StateVariableSP (new StateVariable ("term-width", - 80, - "The maximum number of columns to use for displaying text.")); - - m_variables["disable-aslr"] = - StateVariableSP (new StateVariable ("disable-aslr", - 1, - "Disable Address Space Layout Randomization (ASLR).")); - -} - const char * CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg) { @@ -201,7 +134,16 @@ // Non-CommandObjectCrossref commands can now be created. - m_command_dict["append"] = CommandObjectSP (new CommandObjectAppend ()); + lldb::ScriptLanguage script_language; + lldb::SettableVariableType var_type = lldb::eSetVarTypeString; + StringList value; + const char *dbg_name = GetDebugger().GetInstanceName().AsCString(); + StreamString var_name; + var_name.Printf ("[%s].script-lang", dbg_name); + value = Debugger::GetSettingsController()->GetVariable (var_name.GetData(), var_type); + bool success; + script_language = Args::StringToScriptLanguage (value.GetStringAtIndex(0), lldb::eScriptLanguageDefault, &success); + m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos ()); m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall ()); @@ -217,10 +159,8 @@ m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this)); m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit ()); m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this)); - m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (m_script_language)); - m_command_dict["set"] = CommandObjectSP (new CommandObjectSet ()); - m_command_dict["settings"] = CommandObjectSP (new CommandObjectSettings ()); - m_command_dict["show"] = CommandObjectSP (new CommandObjectShow ()); + m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (script_language)); + m_command_dict["settings"] = CommandObjectSP (new CommandObjectMultiwordSettings (*this)); m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); @@ -448,15 +388,6 @@ return false; } -StateVariable * -CommandInterpreter::GetStateVariable(const char *name) -{ - VariableMap::const_iterator pos = m_variables.find(name); - if (pos != m_variables.end()) - return pos->second.get(); - return NULL; -} - void CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string) { @@ -556,33 +487,6 @@ result.AppendMessage("For more information on any particular command, try 'help '."); } -void -CommandInterpreter::ShowVariableValues (CommandReturnObject &result) -{ - result.AppendMessage ("Below is a list of all the debugger setting variables and their values:"); - - for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos) - { - StateVariable *var = pos->second.get(); - var->AppendVariableInformation (result); - } -} - -void -CommandInterpreter::ShowVariableHelp (CommandReturnObject &result) -{ - result.AppendMessage ("Below is a list of all the internal debugger variables that are settable:"); - for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos) - { - StateVariable *var = pos->second.get(); - result.AppendMessageWithFormat (" %s -- %s \n", var->GetName(), var->GetHelp()); - } -} - -// Main entry point into the command_interpreter; this function takes a text -// line containing a debugger command, with all its flags, options, etc, -// parses the line and takes the appropriate actions. - bool CommandInterpreter::HandleCommand ( @@ -861,47 +765,6 @@ return num_command_matches; } -const Args * -CommandInterpreter::GetProgramArguments () -{ - if (! HasInterpreterVariables()) - return NULL; - - VariableMap::const_iterator pos = m_variables.find("run-args"); - if (pos == m_variables.end()) - return NULL; - - StateVariable *var = pos->second.get(); - - if (var) - return &var->GetArgs(); - return NULL; -} - -const Args * -CommandInterpreter::GetEnvironmentVariables () -{ - if (! HasInterpreterVariables()) - return NULL; - - VariableMap::const_iterator pos = m_variables.find("env-vars"); - if (pos == m_variables.end()) - return NULL; - - StateVariable *var = pos->second.get(); - if (var) - return &var->GetArgs(); - return NULL; -} - -int -CommandInterpreter::GetDisableASLR () -{ - StateVariable *var = GetStateVariable ("disable-aslr"); - int disable_aslr = var->GetIntValue(); - - return disable_aslr; -} CommandInterpreter::~CommandInterpreter () { @@ -910,37 +773,20 @@ const char * CommandInterpreter::GetPrompt () { - VariableMap::iterator pos; - - if (! HasInterpreterVariables()) - return NULL; - - pos = m_variables.find("prompt"); - if (pos == m_variables.end()) - return NULL; - - StateVariable *var = pos->second.get(); - - return ((char *) var->GetStringValue()); + lldb::SettableVariableType var_type; + const char *instance_name = GetDebugger().GetInstanceName().AsCString(); + StreamString var_name; + var_name.Printf ("[%s].prompt", instance_name); + return Debugger::GetSettingsController()->GetVariable (var_name.GetData(), var_type).GetStringAtIndex(0); } void CommandInterpreter::SetPrompt (const char *new_prompt) { - VariableMap::iterator pos; - CommandReturnObject result; - - if (! HasInterpreterVariables()) - return; - - pos = m_variables.find ("prompt"); - if (pos == m_variables.end()) - return; - - StateVariable *var = pos->second.get(); - - if (var->VerifyValue (this, (void *) new_prompt, result)) - var->SetStringValue (new_prompt); + const char *instance_name = GetDebugger().GetInstanceName().AsCString(); + StreamString name_str; + name_str.Printf ("[%s].prompt", instance_name); + Debugger::GetSettingsController()->SetVariable (name_str.GetData(), new_prompt, lldb::eVarSetOperationAssign, false); } void @@ -956,12 +802,6 @@ } } -void -CommandInterpreter::SetScriptLanguage (ScriptLanguage lang) -{ - m_script_language = lang; -} - OptionArgVectorSP CommandInterpreter::GetAliasOptions (const char *alias_name) { @@ -1020,12 +860,6 @@ return (!m_alias_options.empty()); } -bool -CommandInterpreter::HasInterpreterVariables () -{ - return (!m_variables.empty()); -} - void CommandInterpreter::BuildAliasCommandArgs ( @@ -1201,8 +1035,10 @@ const char *help_text, uint32_t max_word_len) { - StateVariable *var = GetStateVariable ("term-width"); - int max_columns = var->GetIntValue(); + lldb::SettableVariableType var_type; + const char *width_value = + Debugger::GetSettingsController()->GetVariable ("term-width", var_type).GetStringAtIndex(0); + int max_columns = atoi (width_value); // Sanity check max_columns, to cope with emacs shell mode with TERM=dumb // (0 rows; 0 columns;). if (max_columns <= 0) max_columns = 80; Modified: lldb/trunk/source/Interpreter/Options.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Options.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/Options.cpp (original) +++ lldb/trunk/source/Interpreter/Options.cpp Fri Sep 3 19:03:46 2010 @@ -364,7 +364,13 @@ CommandObject *cmd, const char *program_name) { - uint32_t screen_width = 80; + lldb::SettableVariableType var_type; + const char *screen_width_str = + Debugger::GetSettingsController()->GetVariable ("term-width", var_type).GetStringAtIndex(0); + uint32_t screen_width = atoi (screen_width_str); + if (screen_width == 0) + screen_width = 80; + const lldb::OptionDefinition *full_options_table = GetDefinitions(); const uint32_t save_indent_level = strm.GetIndentLevel(); const char *name; Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Fri Sep 3 19:03:46 2010 @@ -63,4 +63,21 @@ result.AppendError ("ScriptInterpreter::GetScriptCommands(StringList &) is not implemented."); } +std::string +ScriptInterpreter::LanguageToString (lldb::ScriptLanguage language) +{ + std::string return_value; + switch (language) + { + case eScriptLanguageNone: + return_value = "None"; + break; + case eScriptLanguagePython: + return_value = "Python"; + break; + + } + + return return_value; +} Removed: lldb/trunk/source/Interpreter/StateVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/StateVariable.cpp?rev=113040&view=auto ============================================================================== --- lldb/trunk/source/Interpreter/StateVariable.cpp (original) +++ lldb/trunk/source/Interpreter/StateVariable.cpp (removed) @@ -1,320 +0,0 @@ -//===-- StateVariable.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/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/CommandInterpreter.h" - - -#include "lldb/Interpreter/StateVariable.h" - -using namespace lldb; -using namespace lldb_private; - -// Variables with integer values. - -StateVariable::StateVariable -( - const char *name, - int value, - const char *help, - Callback func_ptr -) : - m_name (name), - m_type (eTypeInteger), - m_help_text (help), - m_verification_func_ptr (func_ptr) -{ - m_int_value = value; -} - -// Variables with boolean values. - -StateVariable::StateVariable -( - const char *name, - bool value, - const char *help, - Callback func_ptr - ) : - m_name (name), - m_type (eTypeBoolean), - m_help_text (help), - m_verification_func_ptr (func_ptr) -{ - m_int_value = value; -} - -// Variables with string values. - -StateVariable::StateVariable -( - const char *name, - const char *value, - bool can_append, - const char *help, - Callback func_ptr - ) : - m_name (name), - m_type (eTypeString), - m_int_value (0), - m_string_values (), - m_help_text (help), - m_verification_func_ptr (func_ptr) -{ - m_string_values.AppendArgument(value); -} - -// Variables with array of strings values. - -StateVariable::StateVariable -( - const char *name, - const Args *args, - const char *help, - Callback func_ptr - ) : - m_name (name), - m_type (eTypeStringArray), - m_string_values(), - m_help_text (help), - m_verification_func_ptr (func_ptr) -{ - if (args) - m_string_values = *args; -} - -StateVariable::~StateVariable () -{ -} - -const char * -StateVariable::GetName () const -{ - return m_name.c_str(); -} - -StateVariable::Type -StateVariable::GetType () const -{ - return m_type; -} - -int -StateVariable::GetIntValue () const -{ - return m_int_value; -} - -bool -StateVariable::GetBoolValue () const -{ - return m_int_value; -} - -const char * -StateVariable::GetStringValue () const -{ - return m_string_values.GetArgumentAtIndex(0); -} - -const Args & -StateVariable::GetArgs () const -{ - return m_string_values; -} - -Args & -StateVariable::GetArgs () -{ - return m_string_values; -} - -const char * -StateVariable::GetHelp () const -{ - return m_help_text.c_str(); -} - -void -StateVariable::SetHelp (const char *help) -{ - m_help_text = help; -} - -void -StateVariable::AppendVariableInformation (CommandReturnObject &result) -{ - switch (m_type) - { - case eTypeBoolean: - if (m_int_value) - result.AppendMessageWithFormat (" %s (bool) = True\n", m_name.c_str()); - else - result.AppendMessageWithFormat (" %s (bool) = False\n", m_name.c_str()); - break; - - case eTypeInteger: - result.AppendMessageWithFormat (" %s (int) = %d\n", m_name.c_str(), m_int_value); - break; - - case eTypeString: - { - const char *cstr = m_string_values.GetArgumentAtIndex(0); - if (cstr && cstr[0]) - result.AppendMessageWithFormat (" %s (str) = '%s'\n", m_name.c_str(), cstr); - else - result.AppendMessageWithFormat (" %s (str) = \n", m_name.c_str()); - } - break; - - case eTypeStringArray: - { - const size_t argc = m_string_values.GetArgumentCount(); - result.AppendMessageWithFormat (" %s (string vector):\n", m_name.c_str()); - for (size_t i = 0; i < argc; ++i) - result.AppendMessageWithFormat (" [%d] %s\n", i, m_string_values.GetArgumentAtIndex(i)); - } - break; - - default: - break; - } -} - -void -StateVariable::SetStringValue (const char *new_value) -{ - if (m_string_values.GetArgumentCount() > 0) - m_string_values.ReplaceArgumentAtIndex(0, new_value); - else - m_string_values.AppendArgument(new_value); -} - -void -StateVariable::SetIntValue (int new_value) -{ - m_int_value = new_value; -} - -void -StateVariable::SetBoolValue (bool new_value) -{ - m_int_value = new_value; -} - -void -StateVariable::AppendStringValue (const char *cstr) -{ - if (cstr && cstr[0]) - { - if (m_string_values.GetArgumentCount() == 0) - { - m_string_values.AppendArgument(cstr); - } - else - { - const char *curr_arg = m_string_values.GetArgumentAtIndex(0); - if (curr_arg != NULL) - { - std::string new_arg_str(curr_arg); - new_arg_str += " "; - new_arg_str += cstr; - m_string_values.ReplaceArgumentAtIndex(0, new_arg_str.c_str()); - } - else - { - m_string_values.ReplaceArgumentAtIndex(0, cstr); - } - } - } -} - -bool -StateVariable::VerifyValue (CommandInterpreter *interpreter, void *data, CommandReturnObject &result) -{ - return (*m_verification_func_ptr) (interpreter, data, result); -} - -//void -//StateVariable::SetArrayValue (STLStringArray &new_value) -//{ -// m_string_values.AppendArgument.append(cstr); -// -// if (m_array_value != NULL) -// { -// if (m_array_value->size() > 0) -// { -// m_array_value->clear(); -// } -// } -// else -// m_array_value = new STLStringArray; -// -// for (int i = 0; i < new_value.size(); ++i) -// m_array_value->push_back (new_value[i]); -//} -// - -void -StateVariable::ArrayClearValues () -{ - m_string_values.Clear(); -} - - -void -StateVariable::ArrayAppendValue (const char *cstr) -{ - m_string_values.AppendArgument(cstr); -} - - -bool -StateVariable::HasVerifyFunction () -{ - return (m_verification_func_ptr != NULL); -} - -// Verification functions for various command interpreter variables. - -bool -StateVariable::VerifyScriptLanguage (CommandInterpreter *interpreter, void *data, CommandReturnObject &result) -{ - bool valid_lang = true; - interpreter->SetScriptLanguage (Args::StringToScriptLanguage((char *) data, eScriptLanguageDefault, &valid_lang)); - return valid_lang; -} - -bool -StateVariable::BroadcastPromptChange (CommandInterpreter *interpreter, void *data, CommandReturnObject &result) -{ - char *prompt = (char *) data; - if (prompt != NULL) - { - std::string tmp_prompt = prompt ; - int len = tmp_prompt.size(); - if (len > 1 - && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"') - && (tmp_prompt[len-1] == tmp_prompt[0])) - { - tmp_prompt = tmp_prompt.substr(1,len-2); - } - len = tmp_prompt.size(); - if (tmp_prompt[len-1] != ' ') - tmp_prompt.append(" "); - strcpy (prompt, tmp_prompt.c_str()); - data = (void *) prompt; - } - EventSP new_event_sp; - new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (prompt))); - interpreter->BroadcastEvent (new_event_sp); - - return true; -} - Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Fri Sep 3 19:03:46 2010 @@ -18,6 +18,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" +#include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Host/Host.h" #include "lldb/Target/ABI.h" #include "lldb/Target/RegisterContext.h" @@ -63,6 +64,7 @@ Process::Process(Target &target, Listener &listener) : UserID (LLDB_INVALID_PROCESS_ID), Broadcaster ("Process"), + ProcessInstanceSettings (*(Process::GetSettingsController().get())), m_target (target), m_section_load_info (), m_public_state (eStateUnloaded), @@ -1919,4 +1921,345 @@ return Host::GetArchSpecForExistingProcess (process_name); } +lldb::UserSettingsControllerSP +Process::GetSettingsController (bool finish) +{ + static UserSettingsControllerSP g_settings_controller (new ProcessSettingsController); + static bool initialized = false; + + if (!initialized) + { + const lldb::UserSettingsControllerSP &parent = g_settings_controller->GetParent (); + if (parent) + parent->RegisterChild (g_settings_controller); + + g_settings_controller->CreateSettingsVector (Process::ProcessSettingsController::global_settings_table, + true); + g_settings_controller->CreateSettingsVector (Process::ProcessSettingsController::instance_settings_table, + false); + + g_settings_controller->InitializeGlobalVariables (); + g_settings_controller->CreateDefaultInstanceSettings (); + initialized = true; + } + + if (finish) + { + const lldb::UserSettingsControllerSP &parent = g_settings_controller->GetParent (); + if (parent) + parent->RemoveChild (g_settings_controller); + g_settings_controller.reset(); + } + + return g_settings_controller; +} + +//-------------------------------------------------------------- +// class Process::ProcessSettingsController +//-------------------------------------------------------------- + +Process::ProcessSettingsController::ProcessSettingsController () : + UserSettingsController ("process", Debugger::GetSettingsController()) +{ + m_default_settings.reset (new ProcessInstanceSettings (*this, InstanceSettings::GetDefaultName().AsCString())); +} + +Process::ProcessSettingsController::~ProcessSettingsController () +{ +} + +lldb::InstanceSettingsSP +Process::ProcessSettingsController::CreateNewInstanceSettings () +{ + ProcessInstanceSettings *new_settings = new ProcessInstanceSettings (*(Process::GetSettingsController().get())); + lldb::InstanceSettingsSP new_settings_sp (new_settings); + return new_settings_sp; +} + +//-------------------------------------------------------------- +// class ProcessInstanceSettings +//-------------------------------------------------------------- + +ProcessInstanceSettings::ProcessInstanceSettings (UserSettingsController &owner, const char *name) : + InstanceSettings (owner, (name == NULL ? CreateInstanceName().AsCString() : name)), + m_run_args (), + m_env_vars (), + m_input_path (), + m_output_path (), + m_error_path (), + m_plugin (), + m_disable_aslr (true) +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings,false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +ProcessInstanceSettings::ProcessInstanceSettings (const ProcessInstanceSettings &rhs) : + InstanceSettings (*(Process::GetSettingsController().get()), CreateInstanceName().AsCString()), + m_run_args (rhs.m_run_args), + m_env_vars (rhs.m_env_vars), + m_input_path (rhs.m_input_path), + m_output_path (rhs.m_output_path), + m_error_path (rhs.m_error_path), + m_plugin (rhs.m_plugin), + m_disable_aslr (rhs.m_disable_aslr) +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings,false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +ProcessInstanceSettings::~ProcessInstanceSettings () +{ +} + +ProcessInstanceSettings& +ProcessInstanceSettings::operator= (const ProcessInstanceSettings &rhs) +{ + if (this != &rhs) + { + m_run_args = rhs.m_run_args; + m_env_vars = rhs.m_env_vars; + m_input_path = rhs.m_input_path; + m_output_path = rhs.m_output_path; + m_error_path = rhs.m_error_path; + m_plugin = rhs.m_plugin; + m_disable_aslr = rhs.m_disable_aslr; + } + + return *this; +} + + +void +ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) +{ + if (var_name == RunArgsVarName()) + UserSettingsController::UpdateStringArrayVariable (op, index_value, m_run_args, value, err); + else if (var_name == EnvVarsVarName()) + UserSettingsController::UpdateDictionaryVariable (op, index_value, m_env_vars, value, err); + else if (var_name == InputPathVarName()) + UserSettingsController::UpdateStringVariable (op, m_input_path, value, err); + else if (var_name == OutputPathVarName()) + UserSettingsController::UpdateStringVariable (op, m_output_path, value, err); + else if (var_name == ErrorPathVarName()) + UserSettingsController::UpdateStringVariable (op, m_error_path, value, err); + else if (var_name == PluginVarName()) + UserSettingsController::UpdateEnumVariable (entry.enum_values, (int *) &m_plugin, value, err); + else if (var_name == DisableASLRVarName()) + UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, err); +} + +void +ProcessInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) +{ + if (new_settings.get() == NULL) + return; + + ProcessInstanceSettings *new_process_settings = (ProcessInstanceSettings *) new_settings.get(); + + m_run_args = new_process_settings->m_run_args; + m_env_vars = new_process_settings->m_env_vars; + m_input_path = new_process_settings->m_input_path; + m_output_path = new_process_settings->m_output_path; + m_error_path = new_process_settings->m_error_path; + m_plugin = new_process_settings->m_plugin; + m_disable_aslr = new_process_settings->m_disable_aslr; +} + +void +Process::ProcessSettingsController::UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err) +{ + // Currently 'process' does not have any global settings. +} + + +void +ProcessInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) +{ + if (var_name == RunArgsVarName()) + { + if (m_run_args.GetArgumentCount() > 0) + for (int i = 0; i < m_run_args.GetArgumentCount(); ++i) + value.AppendString (m_run_args.GetArgumentAtIndex (i)); + else + value.AppendString (""); + } + else if (var_name == EnvVarsVarName()) + { + if (m_env_vars.size() > 0) + { + std::map::iterator pos; + for (pos = m_env_vars.begin(); pos != m_env_vars.end(); ++pos) + { + StreamString value_str; + value_str.Printf ("%s=%s", pos->first.c_str(), pos->second.c_str()); + value.AppendString (value_str.GetData()); + } + } + else + value.AppendString (""); + } + else if (var_name == InputPathVarName()) + { + value.AppendString (m_input_path.c_str()); + } + else if (var_name == OutputPathVarName()) + { + value.AppendString (m_output_path.c_str()); + } + else if (var_name == ErrorPathVarName()) + { + value.AppendString (m_error_path.c_str()); + } + else if (var_name == PluginVarName()) + { + value.AppendString (UserSettingsController::EnumToString (entry.enum_values, (int) m_plugin)); + } + else if (var_name == DisableASLRVarName()) + { + if (m_disable_aslr) + value.AppendString ("true"); + else + value.AppendString ("false"); + } + else + value.AppendString ("unrecognized variable name"); +} + +void +Process::ProcessSettingsController::GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) +{ + // Currently 'process' does not have any global settings. +} + +const ConstString +ProcessInstanceSettings::CreateInstanceName () +{ + static int instance_count = 1; + StreamString sstr; + + sstr.Printf ("process_%d", instance_count); + ++instance_count; + + const ConstString ret_val (sstr.GetData()); + return ret_val; +} + +const ConstString & +ProcessInstanceSettings::RunArgsVarName () +{ + static ConstString run_args_var_name ("run-args"); + + return run_args_var_name; +} + +const ConstString & +ProcessInstanceSettings::EnvVarsVarName () +{ + static ConstString env_vars_var_name ("env-vars"); + + return env_vars_var_name; +} + +const ConstString & +ProcessInstanceSettings::InputPathVarName () +{ + static ConstString input_path_var_name ("input-path"); + + return input_path_var_name; +} + +const ConstString & +ProcessInstanceSettings::OutputPathVarName () +{ + static ConstString output_path_var_name ("output_path"); + + return output_path_var_name; +} + +const ConstString & +ProcessInstanceSettings::ErrorPathVarName () +{ + static ConstString error_path_var_name ("error_path"); + + return error_path_var_name; +} + +const ConstString & +ProcessInstanceSettings::PluginVarName () +{ + static ConstString plugin_var_name ("plugin"); + + return plugin_var_name; +} + + +const ConstString & +ProcessInstanceSettings::DisableASLRVarName () +{ + static ConstString disable_aslr_var_name ("disable-aslr"); + + return disable_aslr_var_name; +} + + +//-------------------------------------------------- +// ProcessSettingsController Variable Tables +//-------------------------------------------------- + +SettingEntry +Process::ProcessSettingsController::global_settings_table[] = +{ + //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + +lldb::OptionEnumValueElement +Process::ProcessSettingsController::g_plugins[] = +{ + { eMacosx, "macosx", "Use the Mac OS X plugin" }, + { eRemoteDebugger, "remote_debugger" , "Use the remote debugger plugin" }, + { 0, NULL, NULL } +}; + +SettingEntry +Process::ProcessSettingsController::instance_settings_table[] = +{ + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { "run-args", eSetVarTypeArray, NULL, NULL, false, false, "A list containing all the arguments to be passed to the executable when it is run." }, + { "env-vars", eSetVarTypeDictionary, NULL, NULL, false, false, "A list of all the environment variables to be passed to the executable's environment, and their values." }, + { "input-path", eSetVarTypeString, "/dev/stdin", NULL, false, false, "The file/path to be used by the executable program for reading its input." }, + { "output-path", eSetVarTypeString, "/dev/stdout", NULL, false, false, "The file/path to be used by the executable program for writing its output." }, + { "error-path", eSetVarTypeString, "/dev/stderr", NULL, false, false, "The file/path to be used by the executable program for writings its error messages." }, + { "plugin", eSetVarTypeEnum, NULL , g_plugins, false, false, "The plugin to be used to run the process." }, + { "disable-aslr", eSetVarTypeBool, "true", NULL, false, false, "Disable Address Space Layout Randomization (ASLR)" }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + Modified: lldb/trunk/source/lldb.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/source/lldb.cpp (original) +++ lldb/trunk/source/lldb.cpp Fri Sep 3 19:03:46 2010 @@ -74,6 +74,8 @@ ProcessMacOSX::Initialize(); SymbolVendorMacOSX::Initialize(); #endif + Debugger::GetSettingsController (false); + Process::GetSettingsController (false); #ifdef __linux__ ProcessLinux::Initialize(); @@ -107,6 +109,9 @@ SymbolVendorMacOSX::Terminate(); #endif + Process::GetSettingsController (true); + Debugger::GetSettingsController (true); + #ifdef __linux__ ProcessLinux::Terminate(); #endif Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=113041&r1=113040&r2=113041&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Fri Sep 3 19:03:46 2010 @@ -1087,7 +1087,8 @@ { char buffer[25]; - sprintf (buffer, "set term-width %d", window_size.ws_col); + if (window_size.ws_col > 0) + sprintf (buffer, "settings set term-width %d", window_size.ws_col); m_debugger.HandleCommand ((const char *) buffer); } From jingham at apple.com Fri Sep 3 19:49:36 2010 From: jingham at apple.com (Jim Ingham) Date: Sat, 04 Sep 2010 00:49:36 -0000 Subject: [Lldb-commits] [lldb] r113046 - /lldb/trunk/docs/lldb-for-gdb-users.txt Message-ID: <20100904004936.B5C7E2A6C12C@llvm.org> Author: jingham Date: Fri Sep 3 19:49:36 2010 New Revision: 113046 URL: http://llvm.org/viewvc/llvm-project?rev=113046&view=rev Log: Adding some docs on how to use lldb. First cut... Added: lldb/trunk/docs/lldb-for-gdb-users.txt Added: lldb/trunk/docs/lldb-for-gdb-users.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/docs/lldb-for-gdb-users.txt?rev=113046&view=auto ============================================================================== --- lldb/trunk/docs/lldb-for-gdb-users.txt (added) +++ lldb/trunk/docs/lldb-for-gdb-users.txt Fri Sep 3 19:49:36 2010 @@ -0,0 +1,405 @@ +Here's a short precis of how to run lldb if you are familiar with the +gdb command set: + + +1) LLDB Command Structure: + +First some details on lldb command structure to help orient you... + +Unlike gdb's command set, which is rather free-form, we tried to make +the lldb command set fairly structured. The commands are all of the +form + + [-options [option-value]] [argument [argument...]] + +We also tried to reduce the number of special purpose argument +parsers, which sometimes forces the user to be a little more explicit +about stating their intentions. The first instance you'll note of +this is the breakpoint command. In gdb, to set a breakpoint, you +would just say: + +(gdb) break set foo.c:12 + +or + +(gdb) break set foo + +if foo is a function. As time went on, the parser that tells foo.c:12 +from foo from foo.c::foo (which means the function foo in the file +foo.c) got more and more complex and bizarre, and especially in C++ +there are times where there's really no way to specify the function +you want to break on. The lldb commands are more verbose but also precise. +So you say: + +(lldb) breakpoint set -f foo.c -l 12 + +to set a file & line breakpoint. To set a breakpoint on a function by name, you do: + +(lldb) breakpoint set -n foo + +This can allow us to be more expressive, so you can say: + +(lldb) breakpoint set -M foo + +to break on all methods named foo, or: + +(lldb) breakpoint set -S alignLeftEdges: + +to set a breakpoint on all ObjC selectors called alignLeftEdges:. It +also makes it easy to compose specifications, like: + +(lldb) breakpoint set -s foo.dylib -n foo + +for all functions called foo in the shared library foo.dylib. Suggestions +on more interesting primitives of this sort are also very welcome. + +The next structural difference between lldb & gdb is that the command +line is actually parsed by the command interpreter not the commands. +That means the command syntax is more regular, but it also means you +may have to quote some arguments in lldb that you wouldn't in gdb. +But the command syntax is very simple, basically arguments, options +and option values are all white-space separated. If you need to put a +backslash or double-quote character in an argument you back-slash it +in the argument. So for instance: + +(lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]" + +Just like gdb, the lldb command interpreter does a shortest unique +string match on command names, so the previous command can also be +typed: + +(lldb) b s -n "-[SKTGraphicView alignLeftEdges:]" + +lldb also supports command completion for source file names, symbol +names, file names, etc. Completion is initiated by a hitting a . +Individual options a command can have different completers, so for +instance the -f option in "breakpoint" completes to source files, the +-s option to currently loaded dylibs, etc... We can even do things +like if you specify -s, and are completing on -f, we will only +list source files in the dylib specified by -s... + +The individual commands are pretty extensively documented, using +with the "help" command. And there is an "apropos" command that will +search the help for a particular word and dump a summary help string +for each matching command. + +Finally, there is a mechanism to construct aliases for commonly used +commands. So for instance if you get annoyed typing + +(lldb) b s -f foo.c -l 12 + +you can do: + +(lldb) command alias bfl breakpoint set -f %1 -l %2 +(lldb) bfl foo.c 12 + +We have added a few aliases for commonly used commands (e.g. "step", +"next" and "continue") but we haven't tried to be exhaustive because +in our experience it is more convenient to make the basic commands +unique down to a letter or two, and then learn these sequences than +fill the namespace with lots of aliases, and then have to type them +all the way out. + +However, users are free to customize lldb's command set however they +like, and since lldb reads the file ~/.lldbinit at startup, you can +store all your aliases there and they will be generally available to +you. Your aliases are also documented in the help command so you can +remind yourself of what you've set up. + +lldb also has a built-in Python interpreter, which is accessible by +the "script" command. All the functionality of the debugger is +available as classes in the Python interpreter, so the more complex +commands that in gdb you would introduce with the "define" command can +be done by writing Python functions using the lldb-Python library, +then loading the scripts into your running session and accessing them +with the "script" command. + + + +2) A typical session: + + +a) Setting the program to debug: + + +As with gdb, you can start lldb and specify the file you wish to debug +on the command line: + +$ lldb /Projects/Sketch/build/Debug/Sketch.app +Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64). + +or you can specify it after the fact with the "file" command: + +(lldb) file /Projects/Sketch/build/Debug/Sketch.app +Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64). + + +b) Setting breakpoints: + + +We've discussed how to set breakpoints above. You can use "help break set" +to see all the options for breakpoint setting. For instance, we might do: + +(lldb) b s -S alignLeftEdges: +Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1, resolved = 1 + +You can find out about the breakpoints you've set with: + +(lldb) break list +Current breakpoints: +1: name = 'alignLeftEdges:', locations = 1, resolved = 1 + 1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Volumes/ThePlayground/Users/jingham/Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0 + +Note that each "logical" breakpoint can have multiple resolved +"locations". The logical breakpoint has an integer id, and it's +locations have a an id within their parent breakpoint (the two are +joined by a ".", e.g. 1.1 in the example above.) Also the breakpoints +remain "live" so that if another shared library were to be loaded that +had another implementation of the "alignLeftEdges:" selector, and new +location would be added to the breakpoint 1 for it. + +You can delete, disable, set conditions and ignore counts either on +all the locations generated by your logical breakpoint. So for +instance if we wanted to add a command to print a backtrace when we +hit this breakpoint we could do: + +(lldb) b command add -c 1.1 +Enter your debugger command(s). Type 'DONE' to end. +> bt +> DONE + +The "-c" specifies that the breakpoint command is a set of lldb +commmand interpreter commands. Use "-s" if you want to implement your +breakpoint command using the lldb Python interface instead. + + +c) Running the program: + +Then you can either launch the process with the command: + +(lldb) process launch + +or its alias: + +(lldb) r + +Or you can attach to a process by name with: + +(lldb) process attach -n Sketch + +the "attach by name" also supports the "-w" option which waits for the +next process of that name to show up, and attaches to that. You can also +attach by PID: + +(lldb) process attach -p 12345 +Process 46915 Attaching +(lldb) Process 46915 Stopped +1 of 3 threads stopped with reasons: +* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread + +Note that we tell you that "1 of 3 threads stopped with reasons" and +then list those threads. In a multi-threaded environment it is very +common for more than one thread to hit your breakpoint(s) before the +kernel actually returns control to the debugger. In that case, you +will see all the threads that stopped for some interesting reason +listed in the stop message. + + +d) Controlling execution: + + +Then we can continue till we hit our breakpoint. The primitive +commands for process control all exist under the "thread" command: + +(lldb) thread continue +Resuming thread 0x2c03 in process 46915 +Resuming process 46915 +(lldb) + +At present you can only operate on one thread at a time, but the +design will ultimately support saying "step over the function in +Thread-1, and step into the function in Thread 2, and continue Thread +3" etc. When we eventually support keeping some threads running while +others are stopped this will be particularly important. For +convenience, however, all the stepping type commands have easy +aliases. So "thread continue" is just "c", etc. + +The other program stepping commands are pretty much the same as in gdb. You've got: + +(lldb) thread step-in + +which is the same as gdb's "step" or the alias: + +(lldb) s + +(lldb) thread step-over + +which is the same as gdb's "next" and is aliased to + +(lldb) n + +(lldb) thread step-out + +which is the same as gdb's "finish" and is aliased to + +(lldb) f + +And the "by instruction" versions: + +(lldb) thread step-inst +(lldb) thread step-over-inst + +Finally, there's: + +(lldb) thread until 100 + +which runs the thread in the current frame till it reaches line 100 in +this frame or stops if it leaves the current frame. This is a pretty +close equivalent to gdb's until command. + + +One thing here that might be a little disconcerting to gdb users here +is that when you resume you immediately get a prompt back. That's +because the lldb interpreter remains live when you are running the +target. This allows you to set a breakpoint, etc without having to +explicitly interrupt the program you are debugging. We're still +working out all the operations that it is safe to do while running. +But this way of operation will set us up for "no stop" debugging when +we get to implementing that. + +If you want to interrupt a running program do: + +(lldb) process interrupt + +To find out the state of the program, use: + +(lldb) process status +Process 47958 is running. + +This is very convenient, but it does have the down-side that debugging +programs that use stdin is no longer as straightforward. For now, you +have to specify another tty to use as the program stdout & stdin using +the appropriate options to "process launch", or start your program in +another terminal and catch it with "process attach -w". We will come +up with some more convenient way to juggle the terminal back & forth +over time. + + +e) Examining program state: + +Once you've stopped, lldb will choose a current thread, usually the +one that stopped "for a reason", and a current frame in that thread. +Many the commands for inspecting state work on this current +thread/frame. + +To inspect the current state of your process, you can start with the +threads: + +(lldb) thread list +Process 46915 state is Stopped +* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread + thread #2: tid = 0x2e03, 0x00007fff85cbb08a, where = libSystem.B.dylib`kevent + 10, queue = com.apple.libdispatch-manager + thread #3: tid = 0x2f03, 0x00007fff85cbbeaa, where = libSystem.B.dylib`__workq_kernreturn + 10 + +The * indicates that Thread 1 is the current thread. To get a +backtrace for that thread, do: + +(lldb) thread backtrace +thread #1: tid = 0x2c03, stop reason = breakpoint 1.1, queue = com.apple.main-thread + frame #0: 0x0000000100010d5b, where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405 + frame #1: 0x00007fff8602d152, where = AppKit`-[NSApplication sendAction:to:from:] + 95 + frame #2: 0x00007fff860516be, where = AppKit`-[NSMenuItem _corePerformAction] + 365 + frame #3: 0x00007fff86051428, where = AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 121 + frame #4: 0x00007fff860370c1, where = AppKit`-[NSMenu performKeyEquivalent:] + 272 + frame #5: 0x00007fff86035e69, where = AppKit`-[NSApplication _handleKeyEquivalent:] + 559 + frame #6: 0x00007fff85f06aa1, where = AppKit`-[NSApplication sendEvent:] + 3630 + frame #7: 0x00007fff85e9d922, where = AppKit`-[NSApplication run] + 474 + frame #8: 0x00007fff85e965f8, where = AppKit`NSApplicationMain + 364 + frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11 + frame #10: 0x0000000100000f20, where = Sketch`start + 52 + +You can also provide a list of threads to backtrace, or the keyword +"all" to see all threads: + +(lldb) thread backtrace all... + +Next task is inspecting data: + +The most convenient way to inspect a frame's arguments and local variables is: + +(lldb) frame variable +self = (SKTGraphicView *) 0x0000000100208b40 +_cmd = (struct objc_selector *) 0x000000010001bae1 +sender = (id) 0x00000001001264e0 +selection = (NSArray *) 0x00000001001264e0 +i = (NSUInteger) 0x00000001001264e0 +c = (NSUInteger) 0x00000001001253b0 + +You can also choose particular variables to view: + +(lldb) frame variable self +(SKTGraphicView *) self = 0x0000000100208b40 + +The frame variable command is not a full expression parser but it does support some common operations like defererencing: + +(lldb) fr v *self +(SKTGraphicView *) self = 0x0000000100208b40 + (NSView) NSView = { + (NSResponder) NSResponder = { +... + +and structure element references: + +(lldb) frame variable self.NS(lldb) frame variable self.isa +(struct objc_class *) self.isa = 0x0000000100023730 + +The frame variable command will also perform "object printing" operations on variables (currently we +only support NSPrintForDebugger) with: + +(lldb) fr v -o self +(SKTGraphicView *) self = 0x0000000100208b40 + + +You can select another frame to view with: + +(lldb) frame select 9 +frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11 + 8 + 9 + 10 int main(int argc, const char *argv[]) { + 11 -> return NSApplicationMain(argc, argv); + 12 } + 13 + 14 + +Another neat trick that the variable list does is array references, so: + +(lldb) fr v argv[0] +(char const *) argv[0] = 0x00007fff5fbffaf8 "/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS/Sketch" + +If you need to view more complex data or change program data, you can +use the general "expression" command. It takes an expression and +evaluates it in the scope of the currently selected frame. For instance: + +(lldb) expr self +$0 = (SKTGraphicView *) 0x0000000100135430 +(lldb) expr self = 0x00 +$1 = (SKTGraphicView *) 0x0000000000000000 +(lldb) frame var self +(SKTGraphicView *) self = 0x0000000000000000 + +You can also call functions: + +(lldb) expr (int) printf ("I have a pointer 0x%llx.\n", self) +$2 = (int) 22 +I have a pointer 0x0. + +One thing to note from this example is that lldb commands can be +defined to take "raw" input. "expression" is one of these. So in the expression command, +you don't have to quote your whole expression, nor backslash protect quotes, etc... + +Finally, the results of the expressions are stored in persistent +variables (of the form \$([0-9])+) that you can use in further expressions, like: + +(lldb) expr self = $0 +$4 = (SKTGraphicView *) 0x0000000100135430