From johnny.chen at apple.com Mon May 2 12:53:04 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 02 May 2011 17:53:04 -0000 Subject: [Lldb-commits] [lldb] r130698 - /lldb/trunk/scripts/Python/modify-python-lldb.py Message-ID: <20110502175304.6B73A2A6C12D@llvm.org> Author: johnny Date: Mon May 2 12:53:04 2011 New Revision: 130698 URL: http://llvm.org/viewvc/llvm-project?rev=130698&view=rev Log: Fix a typo in comment. Modified: lldb/trunk/scripts/Python/modify-python-lldb.py Modified: lldb/trunk/scripts/Python/modify-python-lldb.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=130698&r1=130697&r2=130698&view=diff ============================================================================== --- lldb/trunk/scripts/Python/modify-python-lldb.py (original) +++ lldb/trunk/scripts/Python/modify-python-lldb.py Mon May 2 12:53:04 2011 @@ -128,7 +128,7 @@ # Next state will be NORMAL. state = NORMAL - # Pass the original line of content to the ew_content. + # Pass the original line of content to new_content. print >> new_content, line with open(output_name, 'w') as f_out: From jingham at apple.com Mon May 2 13:13:59 2011 From: jingham at apple.com (Jim Ingham) Date: Mon, 02 May 2011 18:13:59 -0000 Subject: [Lldb-commits] [lldb] r130701 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Symbol/ include/lldb/Target/ source/API/ source/Core/ source/Expression/ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Symbol/ source/Target/ test/objc-dynamic-value/ Message-ID: <20110502181359.D808A2A6C12C@llvm.org> Author: jingham Date: Mon May 2 13:13:59 2011 New Revision: 130701 URL: http://llvm.org/viewvc/llvm-project?rev=130701&view=rev Log: Adding support for fetching the Dynamic Value for ObjC Objects. Added: lldb/trunk/test/objc-dynamic-value/ lldb/trunk/test/objc-dynamic-value/Makefile lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py lldb/trunk/test/objc-dynamic-value/dynamic-value.m Modified: lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/Symbol/Type.h lldb/trunk/include/lldb/Target/LanguageRuntime.h lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/source/API/SBValue.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Core/ValueObjectDynamicValue.cpp lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h lldb/trunk/source/Symbol/Type.cpp lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Mon May 2 13:13:59 2011 @@ -138,11 +138,7 @@ } void - SetUpdated () - { - m_first_update = false; - m_needs_update = false; - } + SetUpdated (); bool NeedsUpdating() Modified: lldb/trunk/include/lldb/Symbol/Type.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Type.h (original) +++ lldb/trunk/include/lldb/Symbol/Type.h Mon May 2 13:13:59 2011 @@ -12,6 +12,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" +#include "lldb/Core/ConstString.h" #include "lldb/Core/UserID.h" #include "lldb/Symbol/Declaration.h" #include @@ -250,6 +251,48 @@ ResolveClangType (ResolveState clang_type_resolve_state); }; + +/// +/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug +/// information for it. If that is the case, you can return one of these objects, and then if it +/// has a full type, you can use that, but if not at least you can print the name for informational +/// purposes. +/// + +class TypeAndOrName +{ +public: + TypeAndOrName (); + TypeAndOrName (lldb::TypeSP &type_sp); + TypeAndOrName (const char *type_str); + TypeAndOrName (const TypeAndOrName &rhs); + TypeAndOrName (ConstString &type_const_string); + + TypeAndOrName & + operator= (const TypeAndOrName &rhs); + + ConstString GetName () const; + lldb::TypeSP GetTypeSP () const { + return m_type_sp; + }; + + void + SetName (ConstString &type_name_const_str); + + void + SetName (const char *type_name_str); + + void + SetTypeSP (lldb::TypeSP type_sp); + + bool + IsEmpty (); + +private: + lldb::TypeSP m_type_sp; + ConstString m_type_name; +}; + } // namespace lldb_private #endif // liblldb_Type_h_ Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original) +++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Mon May 2 13:13:59 2011 @@ -43,7 +43,7 @@ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0; virtual bool - GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) = 0; + GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) = 0; // This should be a fast test to determine whether it is likely that this value would // have a dynamic type. Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original) +++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Mon May 2 13:13:59 2011 @@ -55,6 +55,15 @@ void AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); + TypeAndOrName + LookupInClassNameCache (lldb::addr_t class_addr); + + void + AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp); + + void + AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name); + virtual ClangUtilityFunction * CreateObjectChecker (const char *) = 0; @@ -117,7 +126,10 @@ }; typedef std::map MsgImplMap; - MsgImplMap m_impl_cache; + MsgImplMap m_impl_cache; + + typedef std::map ClassNameMap; + ClassNameMap m_class_name_cache; DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime); }; Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Mon May 2 13:13:59 2011 @@ -155,6 +155,7 @@ class ThreadSpec; class TimeValue; class Type; +class TypeAndOrName; class TypeList; class UUID; class Unwind; Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Mon May 2 13:13:59 2011 @@ -357,7 +357,7 @@ { if (child_sp) { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue(true); + lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (true); if (dynamic_sp) child_sp = dynamic_sp; } @@ -410,7 +410,7 @@ { if (child_sp) { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue(true); + lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (true); if (dynamic_sp) child_sp = dynamic_sp; } Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Mon May 2 13:13:59 2011 @@ -1644,6 +1644,16 @@ return true; } +void +ValueObject::EvaluationPoint::SetUpdated () +{ + m_first_update = false; + m_needs_update = false; + if (m_process_sp) + m_stop_id = m_process_sp->GetStopID(); +} + + bool ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope) { Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original) +++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Mon May 2 13:13:59 2011 @@ -135,7 +135,7 @@ if (!process) return false; - lldb::TypeSP dynamic_type_sp; + TypeAndOrName class_type_or_name; Address dynamic_address; bool found_dynamic_type = false; @@ -144,22 +144,29 @@ { LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); if (runtime) - found_dynamic_type = runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address); + found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, class_type_or_name, dynamic_address); } else { LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); if (cpp_runtime) - found_dynamic_type = cpp_runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address); + found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, class_type_or_name, dynamic_address); if (!found_dynamic_type) { LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); if (objc_runtime) - found_dynamic_type = cpp_runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address); + found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, class_type_or_name, dynamic_address); } } + lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP(); + + // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really + // don't... + + m_update_point.SetUpdated(); + // If we don't have a dynamic type, then make ourselves just a echo of our parent. // Or we could return false, and make ourselves an echo of our parent? if (!found_dynamic_type) Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon May 2 13:13:59 2011 @@ -73,7 +73,8 @@ m_parser_vars->m_sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything); else if (exe_ctx.thread) m_parser_vars->m_sym_ctx = exe_ctx.thread->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); - + else if (exe_ctx.process) + m_parser_vars->m_sym_ctx = SymbolContext(exe_ctx.target->GetSP(), ModuleSP()); if (exe_ctx.target) m_parser_vars->m_persistent_vars = &exe_ctx.target->GetPersistentVariables(); } Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Mon May 2 13:13:59 2011 @@ -41,7 +41,7 @@ } bool -ItaniumABILanguageRuntime::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &dynamic_type_sp, Address &dynamic_address) +ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &dynamic_address) { // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0 // in the object. That will point to the "address point" within the vtable (not the beginning of the @@ -104,6 +104,7 @@ { // We are a C++ class, that's good. Get the class name and look it up: const char *class_name = name + strlen(vtable_demangled_prefix); + class_type_or_name.SetName (class_name); TypeList class_types; uint32_t num_matches = target->GetImages().FindTypes (sc, ConstString(class_name), @@ -112,14 +113,40 @@ class_types); if (num_matches == 1) { - dynamic_type_sp = class_types.GetTypeAtIndex(0); + class_type_or_name.SetTypeSP(class_types.GetTypeAtIndex(0)); } else if (num_matches > 1) { - // How to sort out which of the type matches to pick? + for (size_t i = 0; i < num_matches; i++) + { + lldb::TypeSP this_type(class_types.GetTypeAtIndex(i)); + if (this_type) + { + if (ClangASTContext::IsCXXClassType(this_type->GetClangFullType())) + { + // There can only be one type with a given name, + // so we've just found duplicate definitions, and this + // one will do as well as any other. + // We don't consider something to have a dynamic type if + // it is the same as the static type. So compare against + // the value we were handed: + + clang::ASTContext *in_ast_ctx = in_value.GetClangAST (); + clang::ASTContext *this_ast_ctx = this_type->GetClangAST (); + if (in_ast_ctx != this_ast_ctx + || !ClangASTContext::AreTypesSame (in_ast_ctx, + in_value.GetClangType(), + this_type->GetClangFullType())) + { + class_type_or_name.SetTypeSP (this_type); + return true; + } + return false; + } + } + } } - - if (!dynamic_type_sp) + else return false; // The offset_to_top is two pointers above the address. Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h Mon May 2 13:13:59 2011 @@ -31,7 +31,7 @@ IsVTableName (const char *name); virtual bool - GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); virtual bool CouldHaveDynamicValue (ValueObject &in_value); Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Mon May 2 13:13:59 2011 @@ -198,7 +198,7 @@ } bool -AppleObjCRuntime::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) +AppleObjCRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) { return false; } Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h Mon May 2 13:13:59 2011 @@ -41,7 +41,7 @@ CouldHaveDynamicValue (ValueObject &in_value); virtual bool - GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); // These are the ObjC specific functions. Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Mon May 2 13:13:59 2011 @@ -41,7 +41,7 @@ static const char *pluginShort = "language.apple.objc.v1"; bool -AppleObjCRuntimeV1::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) +AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) { return false; } Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Mon May 2 13:13:59 2011 @@ -32,7 +32,7 @@ // These are generic runtime functions: virtual bool - GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); virtual ClangUtilityFunction * CreateObjectChecker (const char *); Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Mon May 2 13:13:59 2011 @@ -40,15 +40,359 @@ static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2"; static const char *pluginShort = "language.apple.objc.v2"; + +const char *AppleObjCRuntimeV2::g_find_class_name_function_name = "__lldb_apple_objc_v2_find_class_name"; +const char *AppleObjCRuntimeV2::g_find_class_name_function_body = " \n\ +extern \"C\" \n\ +{ \n\ + extern void *gdb_class_getClass (void *objc_class); \n\ + extern void *class_getName(void *objc_class); \n\ + extern int printf(const char *format, ...); \n\ +} \n\ + \n\ +struct __lldb_objc_object { \n\ + void *isa; \n\ +}; \n\ + \n\ +extern \"C\" void *__lldb_apple_objc_v2_find_class_name ( \n\ + __lldb_objc_object *object_ptr, \n\ + int debug) \n\ +{ \n\ + void *name = 0; \n\ + if (debug) \n\ + printf (\"\\n*** Called in v2_find_class_name with object: 0x%p\\n\", object_ptr); \n\ + // Call gdb_class_getClass so we can tell if the class is good. \n\ + void *objc_class = gdb_class_getClass (object_ptr->isa); \n\ + if (objc_class) \n\ + { \n\ + void *actual_class = (void *) [(id) object_ptr class]; \n\ + if (actual_class != 0) \n\ + name = class_getName((void *) actual_class); \n\ + if (debug) \n\ + printf (\"\\n*** Found name: %s\\n\", name ? name : \"\"); \n\ + } \n\ + else if (debug) \n\ + printf (\"\\n*** gdb_class_getClass returned NULL\\n\"); \n\ + return name; \n\ +} \n\ +"; + +const char *AppleObjCRuntimeV2::g_objc_class_symbol_prefix = "OBJC_CLASS_$_"; +const char *AppleObjCRuntimeV2::g_objc_class_data_section_name = "__objc_data"; + AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, ModuleSP &objc_module_sp) : - lldb_private::AppleObjCRuntime (process) + lldb_private::AppleObjCRuntime (process), + m_get_class_name_args(LLDB_INVALID_ADDRESS), + m_get_class_name_args_mutex(Mutex::eMutexTypeNormal) { m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(ConstString("gdb_object_getClass")) != NULL); } bool -AppleObjCRuntimeV2::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) +AppleObjCRuntimeV2::RunFunctionToFindClassName(lldb::addr_t object_addr, Thread *thread, char *name_dst, size_t max_name_len) +{ + // Since we are going to run code we have to make sure only one thread at a time gets to try this. + Mutex::Locker (m_get_class_name_args_mutex); + + StreamString errors; + + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); // FIXME - a more appropriate log channel? + + int32_t debug; + if (log) + debug = 1; + else + debug = 0; + + ValueList dispatch_values; + + Value void_ptr_value; + ClangASTContext *clang_ast_context = m_process->GetTarget().GetScratchClangASTContext(); + + lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); + void_ptr_value.SetValueType (Value::eValueTypeScalar); + void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + void_ptr_value.GetScalar() = object_addr; + + dispatch_values.PushValue (void_ptr_value); + + Value int_value; + lldb::clang_type_t clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); + int_value.SetValueType (Value::eValueTypeScalar); + int_value.SetContext (Value::eContextTypeClangType, clang_int_type); + int_value.GetScalar() = debug; + + dispatch_values.PushValue (int_value); + + ExecutionContext exe_ctx; + thread->CalculateExecutionContext(exe_ctx); + + Address find_class_name_address; + + if (!m_get_class_name_code.get()) + { + m_get_class_name_code.reset (new ClangUtilityFunction (g_find_class_name_function_body, + g_find_class_name_function_name)); + + if (!m_get_class_name_code->Install(errors, exe_ctx)) + { + if (log) + log->Printf ("Failed to install implementation lookup: %s.", errors.GetData()); + m_get_class_name_code.reset(); + return false; + } + find_class_name_address.Clear(); + find_class_name_address.SetOffset(m_get_class_name_code->StartAddress()); + } + else + { + find_class_name_address.Clear(); + find_class_name_address.SetOffset(m_get_class_name_code->StartAddress()); + } + + // Next make the runner function for our implementation utility function. + if (!m_get_class_name_function.get()) + { + m_get_class_name_function.reset(new ClangFunction (*m_process, + clang_ast_context, + clang_void_ptr_type, + find_class_name_address, + dispatch_values)); + + errors.Clear(); + unsigned num_errors = m_get_class_name_function->CompileFunction(errors); + if (num_errors) + { + if (log) + log->Printf ("Error compiling function: \"%s\".", errors.GetData()); + return false; + } + + errors.Clear(); + if (!m_get_class_name_function->WriteFunctionWrapper(exe_ctx, errors)) + { + if (log) + log->Printf ("Error Inserting function: \"%s\".", errors.GetData()); + return false; + } + } + + if (m_get_class_name_code.get() == NULL || m_get_class_name_function.get() == NULL) + return false; + + // Finally, write down the arguments, and call the function. Note that we will re-use the same space in the target + // for the args. We're locking this to ensure that only one thread at a time gets to call this function, so we don't + // have to worry about overwriting the arguments. + + if (!m_get_class_name_function->WriteFunctionArguments (exe_ctx, m_get_class_name_args, find_class_name_address, dispatch_values, errors)) + return false; + + bool stop_others = true; + bool try_all_threads = true; + bool unwind_on_error = true; + + ExecutionResults results = m_get_class_name_function->ExecuteFunction (exe_ctx, + &m_get_class_name_args, + errors, + stop_others, + 1000000, + try_all_threads, + unwind_on_error, + void_ptr_value); + + if (results != eExecutionCompleted) + { + if (log) + log->Printf("Error evaluating our find class name function: %d.\n", results); + return false; + } + + lldb::addr_t result_ptr = void_ptr_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + size_t chars_read = m_process->ReadCStringFromMemory (result_ptr, name_dst, max_name_len); + + // If we exhausted our buffer before finding a NULL we're probably off in the weeds somewhere... + if (chars_read == max_name_len) + return false; + else + return true; + +} + +bool +AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) { + // The Runtime is attached to a particular process, you shouldn't pass in a value from another process. + assert (in_value.GetUpdatePoint().GetProcess() == m_process); + + // Make sure we can have a dynamic value before starting... + if (CouldHaveDynamicValue (in_value)) + { + // First job, pull out the address at 0 offset from the object That will be the ISA pointer. + AddressType address_type; + lldb::addr_t original_ptr = in_value.GetPointerValue(address_type, true); + + // ObjC only has single inheritance, so the objects all start at the same pointer value. + address.SetSection (NULL); + address.SetOffset (original_ptr); + + if (original_ptr == LLDB_INVALID_ADDRESS) + return false; + + Target *target = m_process->CalculateTarget(); + + char memory_buffer[16]; + DataExtractor data(memory_buffer, sizeof(memory_buffer), + m_process->GetByteOrder(), + m_process->GetAddressByteSize()); + size_t address_byte_size = m_process->GetAddressByteSize(); + Error error; + size_t bytes_read = m_process->ReadMemory (original_ptr, + memory_buffer, + address_byte_size, + error); + if (!error.Success() || (bytes_read != address_byte_size)) + { + return false; + } + + uint32_t offset_ptr = 0; + lldb::addr_t isa_addr = data.GetAddress (&offset_ptr); + + if (offset_ptr == 0) + return false; + + // Make sure the class address is readable, otherwise this is not a good object: + bytes_read = m_process->ReadMemory (isa_addr, + memory_buffer, + address_byte_size, + error); + if (bytes_read != address_byte_size) + return false; + + // First check the cache... + + SymbolContext sc; + + class_type_or_name = LookupInClassNameCache (isa_addr); + + if (!class_type_or_name.IsEmpty()) + { + if (class_type_or_name.GetTypeSP() != NULL) + return true; + else + return false; + } + + const char *class_name = NULL; + Address isa_address; + target->GetSectionLoadList().ResolveLoadAddress (isa_addr, isa_address); + + if (isa_address.IsValid()) + { + // If the ISA pointer points to one of the sections in the binary, then see if we can + // get the class name from the symbols. + + const Section *section = isa_address.GetSection(); + + if (section) + { + // If this points to a section that we know about, then this is + // some static class or nothing. See if it is in the right section + // and if its name is the right form. + ConstString section_name = section->GetName(); + if (section_name == ConstString(g_objc_class_data_section_name)) + { + isa_address.CalculateSymbolContext(&sc); + if (sc.symbol) + { + class_name = sc.symbol->GetName().AsCString(); + if (strstr (class_name, g_objc_class_symbol_prefix) == class_name) + class_name += strlen (g_objc_class_symbol_prefix); + else + return false; + } + } + } + } + + char class_buffer[1024]; + if (class_name == NULL) + { + // If the class address didn't point into the binary, or + // it points into the right section but there wasn't a symbol + // there, try to look it up by calling the class method in the target. + ExecutionContextScope *exe_scope = in_value.GetUpdatePoint().GetExecutionContextScope(); + Thread *thread_to_use; + if (exe_scope) + thread_to_use = exe_scope->CalculateThread(); + + if (thread_to_use == NULL) + thread_to_use = m_process->GetThreadList().GetSelectedThread().get(); + + if (thread_to_use == NULL) + return false; + + if (!RunFunctionToFindClassName (original_ptr, thread_to_use, class_buffer, 1024)) + return false; + + class_name = class_buffer; + + } + + if (class_name != NULL && *class_name != '\0') + { + class_type_or_name.SetName (class_name); + + TypeList class_types; + uint32_t num_matches = target->GetImages().FindTypes (sc, + class_type_or_name.GetName(), + true, + UINT32_MAX, + class_types); + if (num_matches == 1) + { + class_type_or_name.SetTypeSP (class_types.GetTypeAtIndex(0)); + return true; + } + else + { + for (size_t i = 0; i < num_matches; i++) + { + lldb::TypeSP this_type(class_types.GetTypeAtIndex(i)); + if (this_type) + { + if (ClangASTContext::IsObjCClassType(this_type->GetClangFullType())) + { + // There can only be one type with a given name, + // so we've just found duplicate definitions, and this + // one will do as well as any other. + // We don't consider something to have a dynamic type if + // it is the same as the static type. So compare against + // the value we were handed: + + clang::ASTContext *in_ast_ctx = in_value.GetClangAST (); + clang::ASTContext *this_ast_ctx = this_type->GetClangAST (); + if (in_ast_ctx != this_ast_ctx + || !ClangASTContext::AreTypesSame (in_ast_ctx, + in_value.GetClangType(), + this_type->GetClangFullType())) + { + class_type_or_name.SetTypeSP (this_type); + } + break; + } + } + } + } + + AddToClassNameCache (isa_addr, class_type_or_name); + if (class_type_or_name.GetTypeSP()) + return true; + else + return false; + } + } + return false; } Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Mon May 2 13:13:59 2011 @@ -23,7 +23,7 @@ #include "AppleThreadPlanStepThroughObjCTrampoline.h" namespace lldb_private { - + class AppleObjCRuntimeV2 : public AppleObjCRuntime { @@ -32,7 +32,7 @@ // These are generic runtime functions: virtual bool - GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); virtual ClangUtilityFunction * CreateObjectChecker (const char *); @@ -76,7 +76,18 @@ private: AppleObjCRuntimeV2(Process *process, ModuleSP &objc_module_sp); - bool m_has_object_getClass; + bool RunFunctionToFindClassName (lldb::addr_t class_addr, Thread *thread, char *name_dst, size_t max_name_len); + + bool m_has_object_getClass; + std::auto_ptr m_get_class_name_function; + std::auto_ptr m_get_class_name_code; + lldb::addr_t m_get_class_name_args; + Mutex m_get_class_name_args_mutex; + + static const char *g_find_class_name_function_name; + static const char *g_find_class_name_function_body; + static const char *g_objc_class_symbol_prefix; + static const char *g_objc_class_data_section_name; }; } // namespace lldb_private Modified: lldb/trunk/source/Symbol/Type.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Type.cpp (original) +++ lldb/trunk/source/Symbol/Type.cpp Mon May 2 13:13:59 2011 @@ -662,3 +662,75 @@ } +TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name() +{ + +} + +TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp) +{ + if (in_type_sp) + m_type_name = in_type_sp->GetName(); +} + +TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) +{ +} + +TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name) +{ + +} + +TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) +{ +} + +TypeAndOrName & +TypeAndOrName::operator= (const TypeAndOrName &rhs) +{ + if (this != &rhs) + { + m_type_name = rhs.m_type_name; + m_type_sp = rhs.m_type_sp; + } + return *this; +} + +ConstString +TypeAndOrName::GetName () const +{ + if (m_type_sp) + return m_type_sp->GetName(); + else + return m_type_name; +} + +void +TypeAndOrName::SetName (ConstString &type_name_const_str) +{ + m_type_name = type_name_const_str; +} + +void +TypeAndOrName::SetName (const char *type_name_str) +{ + m_type_name.SetCString (type_name_str); +} + +void +TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) +{ + m_type_sp = type_sp; + if (type_sp) + m_type_name = type_sp->GetName(); +} + +bool +TypeAndOrName::IsEmpty() +{ + if (m_type_name || m_type_sp) + return false; + else + return true; +} Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=130701&r1=130700&r2=130701&view=diff ============================================================================== --- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original) +++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Mon May 2 13:13:59 2011 @@ -12,6 +12,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/Type.h" #include "lldb/Target/ObjCLanguageRuntime.h" using namespace lldb; @@ -50,3 +51,45 @@ return (*pos).second; return LLDB_INVALID_ADDRESS; } + +void +ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + { + log->Printf ("Caching: class 0x%llx name: %s.", class_addr, name); + } + + TypeAndOrName class_type_or_name; + + if (type_sp != NULL) + class_type_or_name.SetTypeSP (type_sp); + else if (name && *name != '\0') + class_type_or_name.SetName (name); + else + return; + m_class_name_cache.insert (std::pair (class_addr, class_type_or_name)); +} + +void +ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_type_or_name) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + { + log->Printf ("Caching: class 0x%llx name: %s.", class_addr, class_type_or_name.GetName().AsCString()); + } + + m_class_name_cache.insert (std::pair (class_addr, class_type_or_name)); +} + +TypeAndOrName +ObjCLanguageRuntime::LookupInClassNameCache (lldb::addr_t class_addr) +{ + ClassNameMap::iterator pos, end = m_class_name_cache.end(); + pos = m_class_name_cache.find (class_addr); + if (pos != end) + return (*pos).second; + return TypeAndOrName (); +} Added: lldb/trunk/test/objc-dynamic-value/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-dynamic-value/Makefile?rev=130701&view=auto ============================================================================== --- lldb/trunk/test/objc-dynamic-value/Makefile (added) +++ lldb/trunk/test/objc-dynamic-value/Makefile Mon May 2 13:13:59 2011 @@ -0,0 +1,6 @@ +LEVEL = ../make + +OBJC_SOURCES := dynamic-value.m +LDFLAGS = $(CFLAGS) -lobjc -framework Foundation + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py?rev=130701&view=auto ============================================================================== --- lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py (added) +++ lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py Mon May 2 13:13:59 2011 @@ -0,0 +1,165 @@ +""" +Use lldb Python API to test dynamic values in ObjC +""" + +import os, time +import re +import unittest2 +import lldb, lldbutil +from lldbtest import * + +class ObjCDynamicValueTestCase(TestBase): + + mydir = "objc-dynamic-value" + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test + def test_get_dynamic_objc_vals_with_dsym(self): + """Test fetching ObjC dynamic values.""" + self.buildDsym() + self.do_get_dynamic_vals() + + @python_api_test + def test_get_objc_dynamic_vals_with_dwarf(self): + """Test fetching ObjC dynamic values.""" + self.buildDwarf() + self.do_get_dynamic_vals() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + # Find the line number to break for main.c. + + self.source_name = 'dynamic-value.m' + self.set_property_line = line_number(self.source_name, '// This is the line in setProperty, make sure we step to here.') + self.handle_SourceBase = line_number(self.source_name, + '// Break here to check dynamic values.') + self.main_before_setProperty_line = line_number(self.source_name, + '// Break here to see if we can step into real method.') + + def examine_SourceDerived_ptr (self, object): + self.assertTrue (object.IsValid()) + self.assertTrue (object.GetTypeName().find ('SourceDerived') != -1) + derivedValue = object.GetChildMemberWithName ('_derivedValue') + self.assertTrue (derivedValue.IsValid()) + self.assertTrue (int (derivedValue.GetValue(), 0) == 30) + + def do_get_dynamic_vals(self): + """Make sure we get dynamic values correctly both for compiled in classes and dynamic ones""" + exe = os.path.join(os.getcwd(), "a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget (exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Set up our breakpoints: + + handle_SourceBase_bkpt = target.BreakpointCreateByLocation(self.source_name, self.handle_SourceBase) + self.assertTrue(handle_SourceBase_bkpt.IsValid() and + handle_SourceBase_bkpt.GetNumLocations() == 1, + VALID_BREAKPOINT) + + main_before_setProperty_bkpt = target.BreakpointCreateByLocation(self.source_name, self.main_before_setProperty_line) + self.assertTrue(main_before_setProperty_bkpt.IsValid() and + main_before_setProperty_bkpt.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + self.process = target.LaunchSimple (None, None, os.getcwd()) + + self.assertTrue(self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, main_before_setProperty_bkpt) + self.assertTrue (len(threads) == 1) + thread = threads[0] + + # + # At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived + # make sure we can get that properly: + + frame = thread.GetFrameAtIndex(0) + myObserver = frame.FindVariable('myObserver') + self.assertTrue (myObserver.IsValid()) + myObserver_source = myObserver.GetChildMemberWithName ('_source') + self.examine_SourceDerived_ptr (myObserver_source) + + # The "frame var" code uses another path to get into children, so let's + # make sure that works as well: + + result = lldb.SBCommandReturnObject() + + self.expect('frame var -d 1 myObserver->_source', 'frame var finds its way into a child member', + patterns = ['\(SourceDerived \*\)']) + + # This test is not entirely related to the main thrust of this test case, but since we're here, + # try stepping into setProperty, and make sure we get into the version in Source: + + thread.StepInto() + + threads = lldbutil.get_stopped_threads (self.process, lldb.eStopReasonPlanComplete) + self.assertTrue (len(threads) == 1) + line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry() + self.assertTrue (line_entry.GetLine() == self.set_property_line) + self.assertTrue (line_entry.GetFileSpec().GetFilename() == self.source_name) + + # Okay, back to the main business. Continue to the handle_SourceBase and make sure we get the correct dynamic value. + + threads = lldbutil.continue_to_breakpoint (self.process, handle_SourceBase_bkpt) + self.assertTrue (len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + + # Get "object" using FindVariable: + + noDynamic = False + useDynamic = True + + object_static = frame.FindVariable ('object', noDynamic) + object_dynamic = frame.FindVariable ('object', useDynamic) + + # Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it. + del (object_static) + + self.examine_SourceDerived_ptr (object_dynamic) + + # Get "this" using FindValue, make sure that works too: + object_static = frame.FindValue ('object', lldb.eValueTypeVariableArgument, noDynamic) + object_dynamic = frame.FindValue ('object', lldb.eValueTypeVariableArgument, useDynamic) + del (object_static) + self.examine_SourceDerived_ptr (object_dynamic) + + # Get "this" using the EvaluateExpression: + # These tests fail for now because EvaluateExpression doesn't currently support dynamic typing... + #object_static = frame.EvaluateExpression ('object', False) + #object_dynamic = frame.EvaluateExpression ('object', True) + #self.examine_value_object_of_object_ptr (object_static, object_dynamic, myB_loc) + + # Continue again to the handle_SourceBase and make sure we get the correct dynamic value. + # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so + # its isa pointer points to SourceBase not NSKVOSourceBase or whatever... + + threads = lldbutil.continue_to_breakpoint (self.process, handle_SourceBase_bkpt) + self.assertTrue (len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + + # Get "object" using FindVariable: + + object_static = frame.FindVariable ('object', noDynamic) + object_dynamic = frame.FindVariable ('object', useDynamic) + + # Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it. + del (object_static) + + self.examine_SourceDerived_ptr (object_dynamic) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/objc-dynamic-value/dynamic-value.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-dynamic-value/dynamic-value.m?rev=130701&view=auto ============================================================================== --- lldb/trunk/test/objc-dynamic-value/dynamic-value.m (added) +++ lldb/trunk/test/objc-dynamic-value/dynamic-value.m Mon May 2 13:13:59 2011 @@ -0,0 +1,147 @@ +#import + +// SourceBase will be the base class of Source. We'll pass a Source object into a +// function as a SourceBase, and then see if the dynamic typing can get us through the KVO +// goo and all the way back to Source. + + at interface SourceBase: NSObject +{ + uint32_t _value; +} +- (SourceBase *) init; +- (uint32_t) getValue; + at end + + at implementation SourceBase +- (SourceBase *) init +{ + [super init]; + _value = 10; + return self; +} +- (uint32_t) getValue +{ + return _value; +} + at end + +// Source is a class that will be observed by the Observer class below. +// When Observer sets itself up to observe this property (in initWithASource) +// the KVO system will overwrite the "isa" pointer of the object with the "kvo'ed" +// one. + + at interface Source : SourceBase +{ + int _property; +} +- (Source *) init; +- (void) setProperty: (int) newValue; + at end + + at implementation Source +- (Source *) init +{ + [super init]; + _property = 20; + return self; +} +- (void) setProperty: (int) newValue +{ + _property = newValue; // This is the line in setProperty, make sure we step to here. +} + at end + + at interface SourceDerived : Source +{ + int _derivedValue; +} +- (SourceDerived *) init; +- (uint32_t) getValue; + at end + + at implementation SourceDerived +- (SourceDerived *) init +{ + [super init]; + _derivedValue = 30; + return self; +} +- (uint32_t) getValue +{ + return _derivedValue; +} + at end + +// Observer is the object that will watch Source and cause KVO to swizzle it... + + at interface Observer : NSObject +{ + Source *_source; +} ++ (Observer *) observerWithSource: (Source *) source; +- (Observer *) initWithASource: (Source *) source; +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context; + at end + + at implementation Observer + ++ (Observer *) observerWithSource: (Source *) inSource; +{ + Observer *retval; + + retval = [[Observer alloc] initWithASource: inSource]; + return retval; +} + +- (Observer *) initWithASource: (Source *) source +{ + [super init]; + _source = source; + [_source addObserver: self + forKeyPath: @"property" + options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) + context: NULL]; + return self; +} + +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context +{ + printf ("Observer function called.\n"); + return; +} + at end + +uint32_t +handle_SourceBase (SourceBase *object) +{ + return [object getValue]; // Break here to check dynamic values. +} + +int main () +{ + SourceDerived *mySource; + Observer *myObserver; + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + mySource = [[SourceDerived alloc] init]; + myObserver = [Observer observerWithSource: mySource]; + + [mySource setProperty: 5]; // Break here to see if we can step into real method. + + uint32_t return_value = handle_SourceBase (mySource); + + SourceDerived *unwatchedSource = [[SourceDerived alloc] init]; + + return_value = handle_SourceBase (unwatchedSource); + + [pool release]; + return 0; + +} From johnny.chen at apple.com Mon May 2 14:05:52 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 02 May 2011 19:05:52 -0000 Subject: [Lldb-commits] [lldb] r130709 - in /lldb/trunk: scripts/Python/modify-python-lldb.py test/python_api/lldbutil/TestLLDBIterator.py Message-ID: <20110502190552.88D552A6C12D@llvm.org> Author: johnny Date: Mon May 2 14:05:52 2011 New Revision: 130709 URL: http://llvm.org/viewvc/llvm-project?rev=130709&view=rev Log: Add implementation of '==' and '!=' for SBFileSpec and SBModule. Modify a test case to take advantage of 'ths_module == that_module'. Modified: lldb/trunk/scripts/Python/modify-python-lldb.py lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py Modified: lldb/trunk/scripts/Python/modify-python-lldb.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=130709&r1=130708&r2=130709&view=diff ============================================================================== --- lldb/trunk/scripts/Python/modify-python-lldb.py (original) +++ lldb/trunk/scripts/Python/modify-python-lldb.py Mon May 2 14:05:52 2011 @@ -42,7 +42,7 @@ breakpoint_iter = " def breakpoint_iter(self): return lldb_iter(self, '%s', '%s')" # # This supports the rich comparison methods of __eq__ and __ne__. -eq_def = " def __eq__(self, other): return isinstance(other, %s) and self.%s() == other.%s()" +eq_def = " def __eq__(self, other): return isinstance(other, %s) and %s" ne_def = " def __ne__(self, other): return not self.__eq__(other)" # @@ -69,9 +69,28 @@ } # -# This dictionary defines a mapping from classname to equality method name. +# This dictionary defines a mapping from classname to equality method name(s). # -e = { 'SBBreakpoint': 'GetID' } +e = { 'SBBreakpoint': ['GetID'], + 'SBFileSpec': ['GetFilename', 'GetDirectory'], + 'SBModule': ['GetFileSpec', 'GetUUIDString'] + } + +def list_to_frag(list): + """Transform a list to equality program fragment. + + For example, ['GetID'] is transformed to 'self.GetID() == other.GetID()', + and ['GetFilename', 'GetDirectory'] to 'self.GetFilename() == other.GetFilename() + and self.GetDirectory() == other.GetDirectory()'. + """ + if not list: + raise Exception("list should be non-empty") + frag = StringIO.StringIO() + for i in range(len(list)): + if i > 0: + frag.write(" and ") + frag.write("self.{0}() == other.{0}()".format(list[i])) + return frag.getvalue() # The new content will have the iteration protocol defined for our lldb objects. new_content = StringIO.StringIO() @@ -122,7 +141,7 @@ if (state & DEFINING_ITERATOR): print >> new_content, iter_def % d[cls] if (state & DEFINING_EQUALITY): - print >> new_content, eq_def % (cls, e[cls], e[cls]) + print >> new_content, eq_def % (cls, list_to_frag(e[cls])) print >> new_content, ne_def # Next state will be NORMAL. Modified: lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py?rev=130709&r1=130708&r2=130709&view=diff ============================================================================== --- lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py (original) +++ lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py Mon May 2 14:05:52 2011 @@ -63,8 +63,8 @@ if self.TraceOn(): print "yours[%d]='%s'" % (i, get_description(yours[i])) print "mine[%d]='%s'" % (i, get_description(mine[i])) - self.assertTrue(yours[i].GetUUIDString() == mine[i].GetUUIDString(), - "UUID of yours[{0}] and mine[{0}] matches".format(i)) + self.assertTrue(yours[i] == mine[i], + "UUID+FileSpec of yours[{0}] and mine[{0}] matches".format(i)) def lldb_iter_2(self): exe = os.path.join(os.getcwd(), "a.out") From ctice at apple.com Mon May 2 15:41:46 2011 From: ctice at apple.com (Caroline Tice) Date: Mon, 02 May 2011 20:41:46 -0000 Subject: [Lldb-commits] [lldb] r130721 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Interpreter/ lldb.xcodeproj/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Target/ tools/driver/ Message-ID: <20110502204146.E90682A6C12C@llvm.org> Author: ctice Date: Mon May 2 15:41:46 2011 New Revision: 130721 URL: http://llvm.org/viewvc/llvm-project?rev=130721&view=rev Log: This patch captures and serializes all output being written by the command line driver, including the lldb prompt being output by editline, the asynchronous process output & error messages, and asynchronous messages written by target stop-hooks. As part of this it introduces a new Stream class, StreamAsynchronousIO. A StreamAsynchronousIO object is created with a broadcaster, who will eventually broadcast the stream's data for a listener to handle, and an event type indicating what type of event the broadcaster will broadcast. When the Write method is called on a StreamAsynchronousIO object, the data is appended to an internal string. When the Flush method is called on a StreamAsynchronousIO object, it broadcasts it's data string and clears the string. Anything in lldb-core that needs to generate asynchronous output for the end-user should use the StreamAsynchronousIO objects. I have also added a new notification type for InputReaders, to let them know that a asynchronous output has been written. This is to allow the input readers to, for example, refresh their prompts and lines, if desired. I added the case statements to all the input readers to catch this notification, but I haven't added any code for handling them yet (except to the IOChannel input reader). Added: lldb/trunk/include/lldb/Core/StreamAsynchronousIO.h lldb/trunk/source/Core/StreamAsynchronousIO.cpp Modified: lldb/trunk/include/lldb/API/SBCommandInterpreter.h lldb/trunk/include/lldb/API/SBDebugger.h lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Core/Event.h lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/API/SBDebugger.cpp lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Commands/CommandObjectTarget.cpp lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Core/Event.cpp lldb/trunk/source/Core/InputReader.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp lldb/trunk/source/Target/Process.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/tools/driver/Driver.cpp lldb/trunk/tools/driver/Driver.h lldb/trunk/tools/driver/IOChannel.cpp lldb/trunk/tools/driver/IOChannel.h Modified: lldb/trunk/include/lldb/API/SBCommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCommandInterpreter.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBCommandInterpreter.h (original) +++ lldb/trunk/include/lldb/API/SBCommandInterpreter.h Mon May 2 15:41:46 2011 @@ -21,7 +21,9 @@ { eBroadcastBitThreadShouldExit = (1 << 0), eBroadcastBitResetPrompt = (1 << 1), - eBroadcastBitQuitCommandReceived = (1 << 2) // User entered quit + eBroadcastBitQuitCommandReceived = (1 << 2), // User entered quit + eBroadcastBitAsynchronousOutputData = (1 << 3), + eBroadcastBitAsynchronousErrorData = (1 << 4) }; SBCommandInterpreter (const lldb::SBCommandInterpreter &rhs); Modified: lldb/trunk/include/lldb/API/SBDebugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDebugger.h (original) +++ lldb/trunk/include/lldb/API/SBDebugger.h Mon May 2 15:41:46 2011 @@ -163,6 +163,9 @@ void PushInputReader (lldb::SBInputReader &reader); + void + NotifyTopInputReader (lldb::InputReaderAction notification); + const char * GetInstanceName (); Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Mon May 2 15:41:46 2011 @@ -388,6 +388,9 @@ bool PopInputReader (const lldb::InputReaderSP& reader_sp); + void + NotifyTopInputReader (lldb::InputReaderAction notification); + static lldb::DebuggerSP FindDebuggerWithID (lldb::user_id_t id); Modified: lldb/trunk/include/lldb/Core/Event.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Event.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Event.h (original) +++ lldb/trunk/include/lldb/Core/Event.h Mon May 2 15:41:46 2011 @@ -87,6 +87,9 @@ void SetBytes (const void *src, size_t src_len); + + void + SwapBytes (std::string &new_bytes); void SetBytesFromCString (const char *cstr); Added: lldb/trunk/include/lldb/Core/StreamAsynchronousIO.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/StreamAsynchronousIO.h?rev=130721&view=auto ============================================================================== --- lldb/trunk/include/lldb/Core/StreamAsynchronousIO.h (added) +++ lldb/trunk/include/lldb/Core/StreamAsynchronousIO.h Mon May 2 15:41:46 2011 @@ -0,0 +1,42 @@ +//===-- StreamAsynchronousIO.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_StreamAsynchronousIO_h_ +#define liblldb_StreamAsynchronousIO_h_ + +#include + +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamString.h" + +namespace lldb_private { + +class StreamAsynchronousIO : + public Stream +{ +public: + StreamAsynchronousIO (Broadcaster &broadcaster, uint32_t broadcast_event_type); + + virtual ~StreamAsynchronousIO (); + + virtual void + Flush (); + + virtual int + Write (const void *src, size_t src_len); + + +private: + Broadcaster &m_broadcaster; + uint32_t m_broadcast_event_type; + StreamString m_accumulated_data; +}; + +} // namespace lldb_private +#endif // #ifndef liblldb_StreamAsynchronousIO_h Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Mon May 2 15:41:46 2011 @@ -35,7 +35,9 @@ { eBroadcastBitThreadShouldExit = (1 << 0), eBroadcastBitResetPrompt = (1 << 1), - eBroadcastBitQuitCommandReceived = (1 << 2) // User entered quit + eBroadcastBitQuitCommandReceived = (1 << 2), // User entered quit + eBroadcastBitAsynchronousOutputData = (1 << 3), + eBroadcastBitAsynchronousErrorData = (1 << 4) }; void Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Mon May 2 15:41:46 2011 @@ -265,6 +265,7 @@ typedef enum InputReaderAction { eInputReaderActivate, // reader is newly pushed onto the reader stack + eInputReaderAsynchronousOutputWritten, // an async output event occurred; the reader may want to do something eInputReaderReactivate, // reader is on top of the stack again after another reader was popped off eInputReaderDeactivate, // another reader was pushed on the stack eInputReaderGotToken, // reader got one of its tokens (granularity) Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon May 2 15:41:46 2011 @@ -433,6 +433,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 */; }; + 9A4F35101368A51A00823F52 /* StreamAsynchronousIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */; }; + 9A4F35121368A54100823F52 /* StreamAsynchronousIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A4F35111368A54100823F52 /* StreamAsynchronousIO.h */; }; 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 */; }; @@ -1192,6 +1194,8 @@ 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 = ""; }; 9A48A3A7124AAA5A00922451 /* python-extensions.swig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "python-extensions.swig"; sourceTree = ""; }; + 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamAsynchronousIO.cpp; path = source/Core/StreamAsynchronousIO.cpp; sourceTree = ""; }; + 9A4F35111368A54100823F52 /* StreamAsynchronousIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamAsynchronousIO.h; path = include/lldb/Core/StreamAsynchronousIO.h; 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 = ""; }; @@ -1327,7 +1331,6 @@ 26BC7E7510F1B85900F91463 /* lldb-log.cpp */, 26BC7C2A10F1B3BC00F91463 /* lldb-private.h */, 26217932133BCB850083B112 /* lldb-private-enumerations.h */, - 26BC7C2810F1B3BC00F91463 /* lldb-private-interfaces.h */, 26BC7D5D10F1B77400F91463 /* lldb-private-log.h */, 26217930133BC8640083B112 /* lldb-private-types.h */, 262D3190111B4341004E6F88 /* API */, @@ -1977,6 +1980,8 @@ 26BC7D7810F1B77400F91463 /* STLUtils.h */, 26BC7D7910F1B77400F91463 /* Stream.h */, 26BC7E9110F1B85900F91463 /* Stream.cpp */, + 9A4F35111368A54100823F52 /* StreamAsynchronousIO.h */, + 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */, 26BC7D7A10F1B77400F91463 /* StreamFile.h */, 26BC7E9210F1B85900F91463 /* StreamFile.cpp */, 26BC7D7B10F1B77400F91463 /* StreamString.h */, @@ -2176,6 +2181,7 @@ 26BC7DBE10F1B78200F91463 /* Expression */ = { isa = PBXGroup; children = ( + 26BC7C2810F1B3BC00F91463 /* lldb-private-interfaces.h */, 49D7072611B5AD03001AD875 /* ClangASTSource.h */, 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */, 26BC7DC010F1B79500F91463 /* ClangExpression.h */, @@ -2677,6 +2683,7 @@ 2671A0CE134825F6003A87BB /* ConnectionMachPort.h in Headers */, 4CABA9DD134A8BA800539BDD /* ValueObjectMemory.h in Headers */, 4CD0BD0D134BFAB600CB44D4 /* ValueObjectDynamicValue.h in Headers */, + 9A4F35121368A54100823F52 /* StreamAsynchronousIO.h in Headers */, 4C2FAE2F135E3A70001EDE44 /* SharedCluster.h in Headers */, 2692BA16136610C100F9E14D /* UnwindAssemblyInstEmulation.h in Headers */, ); @@ -3246,6 +3253,7 @@ 26A7A035135E6E4200FB369E /* NamedOptionValue.cpp in Sources */, 9A22A161135E30370024DDC3 /* EmulateInstructionARM.cpp in Sources */, 9A22A163135E30370024DDC3 /* EmulationStateARM.cpp in Sources */, + 9A4F35101368A51A00823F52 /* StreamAsynchronousIO.cpp in Sources */, 2630BFAF1365F3220070C534 /* ArchDefaultUnwindPlan.cpp in Sources */, 2630BFB01365F3220070C534 /* ArchVolatileRegs.cpp in Sources */, 2692BA15136610C100F9E14D /* UnwindAssemblyInstEmulation.cpp in Sources */, @@ -3336,7 +3344,7 @@ __STDC_LIMIT_MACROS, LLDB_CONFIGURATION_DEBUG, ); - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = 4.2; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Mon May 2 15:41:46 2011 @@ -640,6 +640,18 @@ } void +SBDebugger::NotifyTopInputReader (InputReaderAction notification) +{ + LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::NotifyTopInputReader (%d)", m_opaque_sp.get(), notification); + + if (m_opaque_sp) + m_opaque_sp->NotifyTopInputReader (notification); +} + +void SBDebugger::reset (const DebuggerSP &debugger_sp) { m_opaque_sp = debugger_sp; Modified: lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp Mon May 2 15:41:46 2011 @@ -466,6 +466,9 @@ } break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: if (bytes && bytes_len && baton) { Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Mon May 2 15:41:46 2011 @@ -975,7 +975,10 @@ case eInputReaderDeactivate: break; - + + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n')) --bytes_len; Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Mon May 2 15:41:46 2011 @@ -205,6 +205,9 @@ case eInputReaderDeactivate: break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: ++cmd_object_expr->m_expr_line_count; if (bytes && bytes_len) Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Mon May 2 15:41:46 2011 @@ -1032,6 +1032,9 @@ } break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: if (bytes && bytes_len && baton) { Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Mon May 2 15:41:46 2011 @@ -423,6 +423,20 @@ } void +Debugger::NotifyTopInputReader (InputReaderAction notification) +{ + InputReaderSP reader_sp (GetCurrentInputReader()); + if (reader_sp) + { + reader_sp->Notify (notification); + + // Flush out any input readers that are done. + while (CheckIfTopInputReaderIsDone ()) + /* Do nothing. */; + } +} + +void Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) { if (bytes && bytes_len) Modified: lldb/trunk/source/Core/Event.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Event.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Core/Event.cpp (original) +++ lldb/trunk/source/Core/Event.cpp Mon May 2 15:41:46 2011 @@ -198,3 +198,10 @@ return NULL; } +void +EventDataBytes::SwapBytes (std::string &new_bytes) +{ + m_bytes.swap (new_bytes); +} + + Modified: lldb/trunk/source/Core/InputReader.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReader.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Core/InputReader.cpp (original) +++ lldb/trunk/source/Core/InputReader.cpp Mon May 2 15:41:46 2011 @@ -327,6 +327,9 @@ m_active = false; break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderInterrupt: case eInputReaderEndOfFile: break; Added: lldb/trunk/source/Core/StreamAsynchronousIO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/StreamAsynchronousIO.cpp?rev=130721&view=auto ============================================================================== --- lldb/trunk/source/Core/StreamAsynchronousIO.cpp (added) +++ lldb/trunk/source/Core/StreamAsynchronousIO.cpp Mon May 2 15:41:46 2011 @@ -0,0 +1,52 @@ +//===-- StreamBroadcast.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 "lldb/lldb-private.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Core/Event.h" +#include "lldb/Core/StreamAsynchronousIO.h" + +using namespace lldb; +using namespace lldb_private; + + +StreamAsynchronousIO::StreamAsynchronousIO (Broadcaster &broadcaster, uint32_t broadcast_event_type) : + Stream (0, 4, eByteOrderBig), + m_broadcaster (broadcaster), + m_broadcast_event_type (broadcast_event_type), + m_accumulated_data () +{ +} + +StreamAsynchronousIO::~StreamAsynchronousIO () +{ +} + +void +StreamAsynchronousIO::Flush () +{ + if (m_accumulated_data.GetSize() > 0) + { + std::auto_ptr data_bytes_ap (new EventDataBytes); + // Let's swap the bytes to avoid LARGE string copies. + data_bytes_ap->SwapBytes (m_accumulated_data.GetString()); + EventSP new_event_sp (new Event (m_broadcast_event_type, data_bytes_ap.release())); + m_broadcaster.BroadcastEvent (new_event_sp); + m_accumulated_data.Clear(); + } +} + +int +StreamAsynchronousIO::Write (const void *s, size_t length) +{ + m_accumulated_data.Write (s, length); + return length; +} Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Mon May 2 15:41:46 2011 @@ -1226,7 +1226,10 @@ out_file.Flush (); } break; - + + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: if (bytes_len == 0) { @@ -1642,6 +1645,12 @@ } } + if (result.GetImmediateOutputStream()) + result.GetImmediateOutputStream()->Flush(); + + if (result.GetImmediateErrorStream()) + result.GetImmediateErrorStream()->Flush(); + // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution // could be running (for instance in Breakpoint Commands. // So we check the return value to see if it is has running in it. Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon May 2 15:41:46 2011 @@ -639,6 +639,9 @@ script_interpreter->EnterSession (); break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderInterrupt: ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "raise KeyboardInterrupt\n", 24); break; @@ -1047,6 +1050,9 @@ } break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: { std::string temp_string (bytes, bytes_len); Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Mon May 2 15:41:46 2011 @@ -3183,6 +3183,9 @@ case eInputReaderReactivate: break; + case eInputReaderAsynchronousOutputWritten: + break; + case eInputReaderGotToken: { Error error; Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Mon May 2 15:41:46 2011 @@ -20,6 +20,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Event.h" #include "lldb/Core/Log.h" +#include "lldb/Core/StreamAsynchronousIO.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Core/ValueObject.h" @@ -1104,8 +1105,12 @@ if (num_exe_ctx == 0) return; - result.SetImmediateOutputFile (m_debugger.GetOutputFile().GetStream()); - result.SetImmediateErrorFile (m_debugger.GetErrorFile().GetStream()); + StreamSP output_stream (new StreamAsynchronousIO (m_debugger.GetCommandInterpreter(), + CommandInterpreter::eBroadcastBitAsynchronousOutputData)); + StreamSP error_stream (new StreamAsynchronousIO (m_debugger.GetCommandInterpreter(), + CommandInterpreter::eBroadcastBitAsynchronousErrorData)); + result.SetImmediateOutputStream (output_stream); + result.SetImmediateErrorStream (error_stream); bool keep_going = true; bool hooks_ran = false; @@ -1176,6 +1181,9 @@ } if (hooks_ran) result.AppendMessage ("\n** End Stop Hooks **\n"); + + result.GetImmediateOutputStream()->Flush(); + result.GetImmediateErrorStream()->Flush(); } //-------------------------------------------------------------- Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Mon May 2 15:41:46 2011 @@ -658,7 +658,7 @@ size_t total_bytes = 0; while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) { - m_io_channel_ap->OutWrite (stdio_buffer, len); + m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC); total_bytes += len; } return total_bytes; @@ -673,7 +673,7 @@ size_t total_bytes = 0; while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) { - m_io_channel_ap->ErrWrite (stdio_buffer, len); + m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC); total_bytes += len; } return total_bytes; @@ -755,24 +755,20 @@ { // The process has stdout available, get it and write it out to the // appropriate place. - if (GetProcessSTDOUT ()) - m_io_channel_ap->RefreshPrompt(); + GetProcessSTDOUT (); } else if (event_type & SBProcess::eBroadcastBitSTDERR) { // The process has stderr available, get it and write it out to the // appropriate place. - if (GetProcessSTDERR ()) - m_io_channel_ap->RefreshPrompt(); + GetProcessSTDERR (); } else if (event_type & SBProcess::eBroadcastBitStateChanged) { // Drain all stout and stderr so we don't see any output come after // we print our prompts - if (GetProcessSTDOUT () - || GetProcessSTDERR ()) - m_io_channel_ap->RefreshPrompt(); - + GetProcessSTDOUT (); + GetProcessSTDERR (); // Something changed in the process; get the event and report the process's current status and location to // the user. StateType event_state = SBProcess::GetStateFromEvent (event); @@ -795,7 +791,7 @@ char message[1024]; int message_len = ::snprintf (message, sizeof(message), "Process %d %s\n", process.GetProcessID(), m_debugger.StateAsCString (event_state)); - m_io_channel_ap->OutWrite(message, message_len); + m_io_channel_ap->OutWrite(message, message_len, ASYNC); } break; @@ -807,9 +803,8 @@ { SBCommandReturnObject result; m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); - m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize()); - m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize()); - m_io_channel_ap->RefreshPrompt(); + m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); + m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); } break; @@ -823,17 +818,15 @@ char message[1024]; int message_len = ::snprintf (message, sizeof(message), "Process %d stopped and was programmatically restarted.\n", process.GetProcessID()); - m_io_channel_ap->OutWrite(message, message_len); - m_io_channel_ap->RefreshPrompt (); + m_io_channel_ap->OutWrite(message, message_len, ASYNC); } else { SBCommandReturnObject result; UpdateSelectedThread (); m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); - m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize()); - m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize()); - m_io_channel_ap->RefreshPrompt (); + m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); + m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); } break; } @@ -935,11 +928,16 @@ case eInputReaderDeactivate: break; + + case eInputReaderAsynchronousOutputWritten: + if (driver->m_io_channel_ap.get() != NULL) + driver->m_io_channel_ap->RefreshPrompt(); + break; case eInputReaderInterrupt: if (driver->m_io_channel_ap.get() != NULL) { - driver->m_io_channel_ap->OutWrite ("^C\n", 3); + driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC); driver->m_io_channel_ap->RefreshPrompt(); } break; @@ -947,7 +945,7 @@ case eInputReaderEndOfFile: if (driver->m_io_channel_ap.get() != NULL) { - driver->m_io_channel_ap->OutWrite ("^D\n", 3); + driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC); driver->m_io_channel_ap->RefreshPrompt (); } write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5); @@ -996,6 +994,36 @@ } } + lldb_utility::PseudoTerminal editline_output_pty; + FILE *editline_output_slave_fh = NULL; + + if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false) + { + ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str); + exit(1); + } + else + { + const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str)); + if (output_slave_name == NULL) + { + ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str); + exit(2); + } + else + { + editline_output_slave_fh = ::fopen (output_slave_name, "r+"); + if (editline_output_slave_fh == NULL) + { + SBError error; + error.SetErrorToErrno(); + ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s", + error.GetCString()); + exit(3); + } + ::setbuf (editline_output_slave_fh, NULL); + } + } // struct termios stdin_termios; @@ -1038,7 +1066,19 @@ // SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); - m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, stdout, stderr, this)); + m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this)); + + SBCommunication out_comm_2("driver.editline_output"); + out_comm_2.SetCloseOnEOF (false); + out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false); + out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get()); + + if (out_comm_2.ReadThreadStart () == false) + { + ::fprintf (stderr, "error: failed to start libedit output read thread"); + exit (5); + } + struct winsize window_size; if (isatty (STDIN_FILENO) Modified: lldb/trunk/tools/driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.h (original) +++ lldb/trunk/tools/driver/Driver.h Mon May 2 15:41:46 2011 @@ -23,6 +23,8 @@ #include "lldb/API/SBError.h" #include "lldb/API/SBInputReader.h" +#define ASYNC true +#define NO_ASYNC false class IOChannel; Modified: lldb/trunk/tools/driver/IOChannel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.cpp?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.cpp (original) +++ lldb/trunk/tools/driver/IOChannel.cpp Mon May 2 15:41:46 2011 @@ -29,10 +29,6 @@ const char *g_default_prompt = "(lldb) "; PromptMap g_prompt_map; -#define NSEC_PER_USEC 1000ull -#define USEC_PER_SEC 1000000ull -#define NSEC_PER_SEC 1000000000ull - static const char* el_prompt(EditLine *el) { @@ -100,16 +96,16 @@ const char *comment = "\nAvailable completions:"; int num_elements = num_completions + 1; - OutWrite(comment, strlen (comment)); + OutWrite(comment, strlen (comment), NO_ASYNC); if (num_completions < page_size) { for (int i = 1; i < num_elements; i++) { completion_str = completions.GetStringAtIndex(i); - OutWrite("\n\t", 2); - OutWrite(completion_str, strlen (completion_str)); + OutWrite("\n\t", 2, NO_ASYNC); + OutWrite(completion_str, strlen (completion_str), NO_ASYNC); } - OutWrite ("\n", 1); + OutWrite ("\n", 1, NO_ASYNC); } else { @@ -124,17 +120,17 @@ for (; cur_pos < endpoint; cur_pos++) { completion_str = completions.GetStringAtIndex(cur_pos); - OutWrite("\n\t", 2); - OutWrite(completion_str, strlen (completion_str)); + OutWrite("\n\t", 2, NO_ASYNC); + OutWrite(completion_str, strlen (completion_str), NO_ASYNC); } if (cur_pos >= num_elements) { - OutWrite("\n", 1); + OutWrite("\n", 1, NO_ASYNC); break; } - OutWrite("\nMore (Y/n/a): ", strlen ("\nMore (Y/n/a): ")); + OutWrite("\nMore (Y/n/a): ", strlen ("\nMore (Y/n/a): "), NO_ASYNC); reply = 'n'; got_char = el_getc(m_edit_line, &reply); if (got_char == -1 || reply == 'n') @@ -154,8 +150,9 @@ IOChannel::IOChannel ( - FILE *in, - FILE *out, + FILE *editline_in, + FILE *editline_out, + FILE *out, FILE *err, Driver *driver ) : @@ -169,10 +166,12 @@ m_err_file (err), m_command_queue (), m_completion_key ("\t"), - m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), in, out, err)), + m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), editline_in, editline_out, editline_out)), m_history (history_init()), m_history_event(), - m_getting_command (false) + m_getting_command (false), + m_expecting_prompt (false), + m_prompt_str () { assert (m_edit_line); ::el_set (m_edit_line, EL_PROMPT, el_prompt); @@ -252,6 +251,36 @@ } } +void +IOChannel::LibeditOutputBytesReceived (void *baton, const void *src, size_t src_len) +{ + // Make this a member variable. + // static std::string prompt_str; + IOChannel *io_channel = (IOChannel *) baton; + const char *bytes = (const char *) src; + + if (io_channel->IsGettingCommand() && io_channel->m_expecting_prompt) + { + io_channel->m_prompt_str.append (bytes, src_len); + // Log this to make sure the prompt is really what you think it is. + if (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == 0) + { + io_channel->m_expecting_prompt = false; + io_channel->OutWrite (io_channel->m_prompt_str.c_str(), + io_channel->m_prompt_str.size(), NO_ASYNC); + io_channel->m_prompt_str.clear(); + } + else + assert (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == std::string::npos); + } + else + { + if (io_channel->m_prompt_str.size() > 0) + io_channel->m_prompt_str.clear(); + io_channel->OutWrite (bytes, src_len, NO_ASYNC); + } +} + bool IOChannel::LibeditGetInput (std::string &new_line) { @@ -262,12 +291,7 @@ // Set boolean indicating whether or not el_gets is trying to get input (i.e. whether or not to attempt // to refresh the prompt after writing data). SetGettingCommand (true); - - // Get the current time just before calling el_gets; this is used by OutWrite, ErrWrite, and RefreshPrompt - // to make sure they have given el_gets enough time to write the prompt before they attempt to write - // anything. - - ::gettimeofday (&m_enter_elgets_time, NULL); + m_expecting_prompt = true; // Call el_gets to prompt the user and read the user's input. const char *line = ::el_gets (m_edit_line, &line_len); @@ -318,7 +342,9 @@ listener.StartListeningForEvents (interpreter_broadcaster, SBCommandInterpreter::eBroadcastBitResetPrompt | SBCommandInterpreter::eBroadcastBitThreadShouldExit | - SBCommandInterpreter::eBroadcastBitQuitCommandReceived); + SBCommandInterpreter::eBroadcastBitQuitCommandReceived | + SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | + SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); listener.StartListeningForEvents (*this, IOChannel::eBroadcastBitThreadShouldExit); @@ -392,6 +418,18 @@ case SBCommandInterpreter::eBroadcastBitQuitCommandReceived: done = true; break; + case SBCommandInterpreter::eBroadcastBitAsynchronousErrorData: + { + const char *data = SBEvent::GetCStringFromEvent (event); + ErrWrite (data, strlen(data), ASYNC); + } + break; + case SBCommandInterpreter::eBroadcastBitAsynchronousOutputData: + { + const char *data = SBEvent::GetCStringFromEvent (event); + OutWrite (data, strlen(data), ASYNC); + } + break; } } else if (event.BroadcasterMatchesPtr (this)) @@ -448,60 +486,41 @@ if (! IsGettingCommand()) return; - // Compare the current time versus the last time el_gets was called. If less than 40 milliseconds - // (40,0000 microseconds or 40,000,0000 nanoseconds) have elapsed, wait 40,0000 microseconds, to ensure el_gets had - // time to finish writing the prompt before we start writing here. - - if (ElapsedNanoSecondsSinceEnteringElGets() < (40 * 1000 * 1000)) - usleep (40 * 1000); - - // Use the mutex to make sure OutWrite, ErrWrite and Refresh prompt do not interfere with - // each other's output. + // If we haven't finished writing the prompt, there's no need to refresh it. + if (m_expecting_prompt) + return; - IOLocker locker (m_output_mutex); ::el_set (m_edit_line, EL_REFRESH); } void -IOChannel::OutWrite (const char *buffer, size_t len) +IOChannel::OutWrite (const char *buffer, size_t len, bool asynchronous) { if (len == 0) return; - // Compare the current time versus the last time el_gets was called. If less than - // 10000 microseconds (10000000 nanoseconds) have elapsed, wait 10000 microseconds, to ensure el_gets had time - // to finish writing the prompt before we start writing here. - - if (ElapsedNanoSecondsSinceEnteringElGets() < 10000000) - usleep (10000); - - { - // Use the mutex to make sure OutWrite, ErrWrite and Refresh prompt do not interfere with - // each other's output. - IOLocker locker (m_output_mutex); - ::fwrite (buffer, 1, len, m_out_file); - } + // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output. + IOLocker locker (m_output_mutex); + if (asynchronous) + ::fwrite ("\n", 1, 1, m_out_file); + ::fwrite (buffer, 1, len, m_out_file); + if (asynchronous) + m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten); } void -IOChannel::ErrWrite (const char *buffer, size_t len) +IOChannel::ErrWrite (const char *buffer, size_t len, bool asynchronous) { if (len == 0) return; - // Compare the current time versus the last time el_gets was called. If less than - // 10000 microseconds (10000000 nanoseconds) have elapsed, wait 10000 microseconds, to ensure el_gets had time - // to finish writing the prompt before we start writing here. - - if (ElapsedNanoSecondsSinceEnteringElGets() < 10000000) - usleep (10000); - - { - // Use the mutex to make sure OutWrite, ErrWrite and Refresh prompt do not interfere with - // each other's output. - IOLocker locker (m_output_mutex); - ::fwrite (buffer, 1, len, m_err_file); - } + // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output. + IOLocker locker (m_output_mutex); + if (asynchronous) + ::fwrite ("\n", 1, 1, m_err_file); + ::fwrite (buffer, 1, len, m_err_file); + if (asynchronous) + m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten); } void @@ -551,25 +570,6 @@ m_getting_command = new_value; } -uint64_t -IOChannel::Nanoseconds (const struct timeval &time_val) const -{ - uint64_t nanoseconds = time_val.tv_sec * NSEC_PER_SEC + time_val.tv_usec * NSEC_PER_USEC; - - return nanoseconds; -} - -uint64_t -IOChannel::ElapsedNanoSecondsSinceEnteringElGets () -{ - if (! IsGettingCommand()) - return 0; - - struct timeval current_time; - ::gettimeofday (¤t_time, NULL); - return (Nanoseconds (current_time) - Nanoseconds (m_enter_elgets_time)); -} - IOLocker::IOLocker (pthread_mutex_t &mutex) : m_mutex_ptr (&mutex) { Modified: lldb/trunk/tools/driver/IOChannel.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.h?rev=130721&r1=130720&r2=130721&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.h (original) +++ lldb/trunk/tools/driver/IOChannel.h Mon May 2 15:41:46 2011 @@ -35,7 +35,8 @@ eAllEventBits = 0xffffffff }; - IOChannel (FILE *in, + IOChannel (FILE *editline_in, + FILE *editline_out, FILE *out, FILE *err, Driver *driver = NULL); @@ -56,13 +57,16 @@ Run (); void - OutWrite (const char *buffer, size_t len); + OutWrite (const char *buffer, size_t len, bool asynchronous); void - ErrWrite (const char *buffer, size_t len); + ErrWrite (const char *buffer, size_t len, bool asynchronous); bool LibeditGetInput (std::string &); + + static void + LibeditOutputBytesReceived (void *baton, const void *src,size_t src_len); void SetPrompt (); @@ -99,12 +103,6 @@ void SetGettingCommand (bool new_value); - uint64_t - Nanoseconds (const struct timeval &time_val) const; - - uint64_t - ElapsedNanoSecondsSinceEnteringElGets (); - private: pthread_mutex_t m_output_mutex; @@ -122,6 +120,8 @@ History *m_history; HistEvent m_history_event; bool m_getting_command; + bool m_expecting_prompt; + std::string m_prompt_str; // for accumlating the prompt as it gets written out by editline void HistorySaveLoad (bool save); From gclayton at apple.com Mon May 2 16:39:03 2011 From: gclayton at apple.com (Greg Clayton) Date: Mon, 02 May 2011 21:39:03 -0000 Subject: [Lldb-commits] [lldb] r130728 - /lldb/trunk/source/Commands/CommandObjectImage.cpp Message-ID: <20110502213903.E55052A6C12C@llvm.org> Author: gclayton Date: Mon May 2 16:39:03 2011 New Revision: 130728 URL: http://llvm.org/viewvc/llvm-project?rev=130728&view=rev Log: Added a "--triple []" ("-t" as a short option) option to the image list command so we can see the full triple for each target module. Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=130728&r1=130727&r2=130728&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectImage.cpp Mon May 2 16:39:03 2011 @@ -37,14 +37,19 @@ // Static Helper functions //---------------------------------------------------------------------- static void -DumpModuleArchitecture (Stream &strm, Module *module, uint32_t width) +DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) { if (module) { + const char *arch_cstr; + if (full_triple) + arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); + else + arch_cstr = module->GetArchitecture().GetArchitectureName(); if (width) - strm.Printf("%-*s", width, module->GetArchitecture().GetArchitectureName()); + strm.Printf("%-*s", width, arch_cstr); else - strm.PutCString(module->GetArchitecture().GetArchitectureName()); + strm.PutCString(arch_cstr); } } @@ -1278,9 +1283,13 @@ switch (format_char) { case 'a': - DumpModuleArchitecture (strm, module, width); + DumpModuleArchitecture (strm, module, false, width); break; + case 't': + DumpModuleArchitecture (strm, module, true, width); + break; + case 'f': DumpFullpath (strm, &module->GetFileSpec(), width); dump_object_name = true; @@ -1354,6 +1363,7 @@ CommandObjectImageList::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, +{ LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, From ctice at apple.com Mon May 2 17:54:24 2011 From: ctice at apple.com (Caroline Tice) Date: Mon, 02 May 2011 22:54:24 -0000 Subject: [Lldb-commits] [lldb] r130738 - /lldb/trunk/lldb.xcodeproj/project.pbxproj Message-ID: <20110502225424.825652A6C12C@llvm.org> Author: ctice Date: Mon May 2 17:54:24 2011 New Revision: 130738 URL: http://llvm.org/viewvc/llvm-project?rev=130738&view=rev Log: Fix the compiler in the project (accidentally checked in with wrong compiler). Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=130738&r1=130737&r2=130738&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon May 2 17:54:24 2011 @@ -3344,7 +3344,7 @@ __STDC_LIMIT_MACROS, LLDB_CONFIGURATION_DEBUG, ); - GCC_VERSION = 4.2; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; From johnny.chen at apple.com Mon May 2 18:47:55 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 02 May 2011 23:47:55 -0000 Subject: [Lldb-commits] [lldb] r130740 - /lldb/trunk/source/Commands/CommandObjectTarget.cpp Message-ID: <20110502234755.8F14D2A6C12C@llvm.org> Author: johnny Date: Mon May 2 18:47:55 2011 New Revision: 130740 URL: http://llvm.org/viewvc/llvm-project?rev=130740&view=rev Log: Add a one-liner option, for example, "-o 'expr ptr'", to the 'target stop-hook add' command. Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=130740&r1=130739&r2=130740&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Mon May 2 18:47:55 2011 @@ -854,7 +854,9 @@ m_line_end (UINT_MAX), m_func_name_type_mask (eFunctionNameTypeAuto), m_sym_ctx_specified (false), - m_thread_specified (false) + m_thread_specified (false), + m_use_one_liner (false), + m_one_liner() { } @@ -938,6 +940,10 @@ m_thread_specified = true; } break; + case 'o': + m_use_one_liner = true; + m_one_liner = option_arg; + break; default: error.SetErrorStringWithFormat ("Unrecognized option %c."); break; @@ -962,6 +968,9 @@ m_sym_ctx_specified = false; m_thread_specified = false; + + m_use_one_liner = false; + m_one_liner.clear(); } @@ -980,7 +989,9 @@ std::string m_queue_name; bool m_sym_ctx_specified; bool m_thread_specified; - + // Instance variables to hold the values for one_liner options. + bool m_use_one_liner; + std::string m_one_liner; }; Options * @@ -1146,33 +1157,39 @@ new_hook_sp->SetThreadSpecifier (thread_spec); } - // Next gather up the command list, we'll push an input reader and suck the data from that directly into - // the new stop hook's command string. - - InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); - if (!reader_sp) + if (m_options.m_use_one_liner) { - result.AppendError("out of memory\n"); - result.SetStatus (eReturnStatusFailed); - target->RemoveStopHookByID (new_hook_sp->GetID()); - return false; + // Use one-liner. + new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); } - - Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, - new_hook_sp.get(), // baton - eInputReaderGranularityLine, // token size, to pass to callback function - "DONE", // end token - "> ", // prompt - true)); // echo input - if (!err.Success()) - { - result.AppendError (err.AsCString()); - result.SetStatus (eReturnStatusFailed); - target->RemoveStopHookByID (new_hook_sp->GetID()); - return false; + else + { + // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into + // the new stop hook's command string. + InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); + if (!reader_sp) + { + result.AppendError("out of memory\n"); + result.SetStatus (eReturnStatusFailed); + target->RemoveStopHookByID (new_hook_sp->GetID()); + return false; + } + + Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, + new_hook_sp.get(), // baton + eInputReaderGranularityLine, // token size, to pass to callback function + "DONE", // end token + "> ", // prompt + true)); // echo input + if (!err.Success()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + target->RemoveStopHookByID (new_hook_sp->GetID()); + return false; + } + m_interpreter.GetDebugger().PushInputReader (reader_sp); } - m_interpreter.GetDebugger().PushInputReader (reader_sp); - result.SetStatus (eReturnStatusSuccessFinishNoResult); } else @@ -1190,6 +1207,8 @@ OptionDefinition CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = { + { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner, + "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run."}, { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, From johnny.chen at apple.com Mon May 2 19:06:12 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 00:06:12 -0000 Subject: [Lldb-commits] [lldb] r130741 - /lldb/trunk/source/Commands/CommandObjectTarget.cpp Message-ID: <20110503000612.C8AFB2A6C12C@llvm.org> Author: johnny Date: Mon May 2 19:06:12 2011 New Revision: 130741 URL: http://llvm.org/viewvc/llvm-project?rev=130741&view=rev Log: The 'target stop-hook add' command is missing the stop hook added message for one-liner. Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=130741&r1=130740&r2=130741&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Mon May 2 19:06:12 2011 @@ -1161,6 +1161,7 @@ { // Use one-liner. new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); + result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID()); } else { From johnny.chen at apple.com Mon May 2 19:19:01 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 00:19:01 -0000 Subject: [Lldb-commits] [lldb] r130742 - /lldb/trunk/test/stop-hook/TestStopHookCmd.py Message-ID: <20110503001901.4542E2A6C12D@llvm.org> Author: johnny Date: Mon May 2 19:19:01 2011 New Revision: 130742 URL: http://llvm.org/viewvc/llvm-project?rev=130742&view=rev Log: Add a test case to exercise the 'target stop-hook add' command without relying on pexpect to spawn an lldb child command. The test is not "correct" in that the '** Stop Hooks **' message emitted by the Target implementation is invoked asynchronously and is using a separate: CommandReturnObject result; command return object that what the driver passes to the normal command interpreter loop. But it can help test our output serialization work. I need to modify the test case later to maybe only test that "-o 'expr ptr'" option does indeed work. Added: lldb/trunk/test/stop-hook/TestStopHookCmd.py Added: lldb/trunk/test/stop-hook/TestStopHookCmd.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/TestStopHookCmd.py?rev=130742&view=auto ============================================================================== --- lldb/trunk/test/stop-hook/TestStopHookCmd.py (added) +++ lldb/trunk/test/stop-hook/TestStopHookCmd.py Mon May 2 19:19:01 2011 @@ -0,0 +1,71 @@ +""" +Test lldb target stop-hook command. +""" + +import os +import unittest2 +import lldb +import pexpect +from lldbtest import * + +class StopHookCmdTestCase(TestBase): + + mydir = "stop-hook" + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test a sequence of target add-hook commands.""" + self.buildDsym() + self.stop_hook_cmd_sequence() + + def test_with_dwarf(self): + """Test a sequence of target add-hook commands.""" + self.buildDwarf() + self.stop_hook_cmd_sequence() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers inside main.cpp. + self.begl = line_number('main.cpp', '// Set breakpoint here to test target stop-hook.') + self.endl = line_number('main.cpp', '// End of the line range for which stop-hook is to be run.') + self.line = line_number('main.cpp', '// Another breakpoint which is outside of the stop-hook range.') + + def stop_hook_cmd_sequence(self): + """Test a sequence of target stop-hook commands.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + self.expect('breakpoint set -f main.cpp -l %d' % self.begl, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" % + self.begl) + self.expect('breakpoint set -f main.cpp -l %d' % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 2: file ='main.cpp', line = %d" % + self.line) + + self.runCmd("target stop-hook add -f main.cpp -l %d -e %d -o 'expr ptr'" % (self.begl, self.endl)) + + self.runCmd('target stop-hook list') + + # Now run the program, expect to stop at the the first breakpoint which is within the stop-hook range. + #self.expect('run', 'Stop hook fired', + # substrs = '** Stop Hooks **') + self.runCmd('run') + self.runCmd('thread step-over') + self.expect('thread step-over', 'Stop hook fired again', + substrs = '** Stop Hooks **') + + # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range. + self.runCmd('process continue') + # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. + self.expect('thread step-over', 'Stop hook should not be fired', matching=False, + substrs = '** Stop Hooks **') + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From johnny.chen at apple.com Tue May 3 12:38:06 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 17:38:06 -0000 Subject: [Lldb-commits] [lldb] r130767 - in /lldb/trunk/test: lldbtest.py stop-hook/TestStopHook.py Message-ID: <20110503173806.5DF492A6C12C@llvm.org> Author: johnny Date: Tue May 3 12:38:06 2011 New Revision: 130767 URL: http://llvm.org/viewvc/llvm-project?rev=130767&view=rev Log: A more robust pexpect-based test case for testing against the firing of stop hooks. Change one test sequence to detect the '** End Stop Hooks **' marker emitted by the stop hooks mechanism and check for whether the 'expr ptr' stop-hook has been run. Also, change the TestBase.tearDown() to wait for 2 seocnds before forcefully kill the pexpect-spawned child lldb process. Modified: lldb/trunk/test/lldbtest.py lldb/trunk/test/stop-hook/TestStopHook.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=130767&r1=130766&r2=130767&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue May 3 12:38:06 2011 @@ -679,7 +679,10 @@ # This is for the case of directly spawning 'lldb' and interacting with it # using pexpect. if self.child and self.child.isalive(): + with recording(self, traceAlways) as sbuf: + print >> sbuf, "tearing down the child process...." self.child.sendline('quit') + time.sleep(2) self.child.close() # Terminate the current process being debugged, if any. Modified: lldb/trunk/test/stop-hook/TestStopHook.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/TestStopHook.py?rev=130767&r1=130766&r2=130767&view=diff ============================================================================== --- lldb/trunk/test/stop-hook/TestStopHook.py (original) +++ lldb/trunk/test/stop-hook/TestStopHook.py Tue May 3 12:38:06 2011 @@ -34,51 +34,53 @@ def stop_hook_command_sequence(self): """Test a sequence of target stop-hook commands.""" exe = os.path.join(os.getcwd(), "a.out") - prompt = "\r\n\(lldb\) " - add_prompt = "Enter your stop hook command\(s\). Type 'DONE' to end.\r\n> " + prompt = "(lldb) " + add_prompt = "Enter your stop hook command(s). Type 'DONE' to end.\r\n> " add_prompt1 = "\r\n> " - child = pexpect.spawn('%s %s' % (self.lldbExec, exe)) + # So that the child gets torn down after the test. + self.child = pexpect.spawn('%s %s' % (self.lldbExec, exe)) + child = self.child # Turn on logging for what the child sends back. if self.TraceOn(): child.logfile_read = sys.stdout # Set the breakpoint, followed by the target stop-hook commands. - child.expect(prompt) + child.expect_exact(prompt) child.sendline('breakpoint set -f main.cpp -l %d' % self.begl) - child.expect(prompt) + child.expect_exact(prompt) child.sendline('breakpoint set -f main.cpp -l %d' % self.line) - child.expect(prompt) + child.expect_exact(prompt) child.sendline('target stop-hook add -f main.cpp -l %d -e %d' % (self.begl, self.endl)) - child.expect(add_prompt) + child.expect_exact(add_prompt) child.sendline('expr ptr') - child.expect(add_prompt1) + child.expect_exact(add_prompt1) child.sendline('DONE') - child.expect(prompt) + child.expect_exact(prompt) child.sendline('target stop-hook list') # Now run the program, expect to stop at the the first breakpoint which is within the stop-hook range. - child.expect(prompt) + child.expect_exact(prompt) child.sendline('run') - child.expect(prompt) - self.DebugPExpect(child) + child.expect_exact(prompt) child.sendline('thread step-over') - child.expect(prompt) - self.DebugPExpect(child) + #self.DebugPExpect(child) + child.expect_exact('** End Stop Hooks **') + #self.DebugPExpect(child) # Verify that the 'Stop Hooks' mechanism is fired off. self.expect(child.before, exe=False, - substrs = ['Stop Hooks']) + substrs = ['(void *) $0 = 0x']) # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range. child.sendline('process continue') - child.expect(prompt) - self.DebugPExpect(child) + child.expect_exact(prompt) + #self.DebugPExpect(child) child.sendline('thread step-over') - child.expect(prompt) - self.DebugPExpect(child) + child.expect_exact(prompt) + #self.DebugPExpect(child) # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. self.expect(child.before, exe=False, matching=False, - substrs = ['Stop Hooks']) + substrs = ['(void *) $0 = 0x']) if __name__ == '__main__': From johnny.chen at apple.com Tue May 3 13:32:01 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 18:32:01 -0000 Subject: [Lldb-commits] [lldb] r130771 - /lldb/trunk/test/stop-hook/TestStopHookCmd.py Message-ID: <20110503183201.62E6D2A6C12C@llvm.org> Author: johnny Date: Tue May 3 13:32:01 2011 New Revision: 130771 URL: http://llvm.org/viewvc/llvm-project?rev=130771&view=rev Log: Modified to exercise the 'target stop-hook add/disable/enable/delete/list' commands. Modified: lldb/trunk/test/stop-hook/TestStopHookCmd.py Modified: lldb/trunk/test/stop-hook/TestStopHookCmd.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/TestStopHookCmd.py?rev=130771&r1=130770&r2=130771&view=diff ============================================================================== --- lldb/trunk/test/stop-hook/TestStopHookCmd.py (original) +++ lldb/trunk/test/stop-hook/TestStopHookCmd.py Tue May 3 13:32:01 2011 @@ -4,8 +4,8 @@ import os import unittest2 +import StringIO import lldb -import pexpect from lldbtest import * class StopHookCmdTestCase(TestBase): @@ -14,12 +14,12 @@ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym(self): - """Test a sequence of target add-hook commands.""" + """Test a sequence of target stop-hook commands.""" self.buildDsym() self.stop_hook_cmd_sequence() def test_with_dwarf(self): - """Test a sequence of target add-hook commands.""" + """Test a sequence of target stop-hook commands.""" self.buildDwarf() self.stop_hook_cmd_sequence() @@ -47,22 +47,30 @@ self.runCmd("target stop-hook add -f main.cpp -l %d -e %d -o 'expr ptr'" % (self.begl, self.endl)) - self.runCmd('target stop-hook list') + self.expect('target stop-hook list', 'Stop Hook added successfully', + substrs = ['State: enabled', + 'expr ptr']) + + self.runCmd('target stop-hook disable') + + self.expect('target stop-hook list', 'Stop Hook disabled successfully', + substrs = ['State: disabled', + 'expr ptr']) + + self.runCmd('target stop-hook enable') + + self.expect('target stop-hook list', 'Stop Hook enabled successfully', + substrs = ['State: enabled', + 'expr ptr']) + + self.runCmd("settings set auto-confirm true") + self.addTearDownHook(lambda: self.runCmd("settings set -r auto-confirm")) + + self.runCmd('target stop-hook delete') + + self.expect('target stop-hook list', 'Stop Hook deleted successfully', + substrs = ['No stop hooks.']) - # Now run the program, expect to stop at the the first breakpoint which is within the stop-hook range. - #self.expect('run', 'Stop hook fired', - # substrs = '** Stop Hooks **') - self.runCmd('run') - self.runCmd('thread step-over') - self.expect('thread step-over', 'Stop hook fired again', - substrs = '** Stop Hooks **') - - # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range. - self.runCmd('process continue') - # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. - self.expect('thread step-over', 'Stop hook should not be fired', matching=False, - substrs = '** Stop Hooks **') - if __name__ == '__main__': import atexit From johnny.chen at apple.com Tue May 3 13:40:19 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 18:40:19 -0000 Subject: [Lldb-commits] [lldb] r130773 - in /lldb/trunk/test/stop-hook: TestStopHook.py TestStopHookMechanism.py Message-ID: <20110503184019.A2B252A6C12C@llvm.org> Author: johnny Date: Tue May 3 13:40:19 2011 New Revision: 130773 URL: http://llvm.org/viewvc/llvm-project?rev=130773&view=rev Log: Rename TestStopHook.py to the more appropriate TestStopHookMechanism.py, and update the docstrings. Added: lldb/trunk/test/stop-hook/TestStopHookMechanism.py - copied, changed from r130767, lldb/trunk/test/stop-hook/TestStopHook.py Removed: lldb/trunk/test/stop-hook/TestStopHook.py Removed: lldb/trunk/test/stop-hook/TestStopHook.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/TestStopHook.py?rev=130772&view=auto ============================================================================== --- lldb/trunk/test/stop-hook/TestStopHook.py (original) +++ lldb/trunk/test/stop-hook/TestStopHook.py (removed) @@ -1,90 +0,0 @@ -""" -Test lldb target stop-hook command. -""" - -import os -import unittest2 -import lldb -import pexpect -from lldbtest import * - -class StopHookTestCase(TestBase): - - mydir = "stop-hook" - - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - def test_with_dsym(self): - """Test a sequence of target add-hook commands.""" - self.buildDsym() - self.stop_hook_command_sequence() - - def test_with_dwarf(self): - """Test a sequence of target add-hook commands.""" - self.buildDwarf() - self.stop_hook_command_sequence() - - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line numbers inside main.cpp. - self.begl = line_number('main.cpp', '// Set breakpoint here to test target stop-hook.') - self.endl = line_number('main.cpp', '// End of the line range for which stop-hook is to be run.') - self.line = line_number('main.cpp', '// Another breakpoint which is outside of the stop-hook range.') - - def stop_hook_command_sequence(self): - """Test a sequence of target stop-hook commands.""" - exe = os.path.join(os.getcwd(), "a.out") - prompt = "(lldb) " - add_prompt = "Enter your stop hook command(s). Type 'DONE' to end.\r\n> " - add_prompt1 = "\r\n> " - - # So that the child gets torn down after the test. - self.child = pexpect.spawn('%s %s' % (self.lldbExec, exe)) - child = self.child - # Turn on logging for what the child sends back. - if self.TraceOn(): - child.logfile_read = sys.stdout - - # Set the breakpoint, followed by the target stop-hook commands. - child.expect_exact(prompt) - child.sendline('breakpoint set -f main.cpp -l %d' % self.begl) - child.expect_exact(prompt) - child.sendline('breakpoint set -f main.cpp -l %d' % self.line) - child.expect_exact(prompt) - child.sendline('target stop-hook add -f main.cpp -l %d -e %d' % (self.begl, self.endl)) - child.expect_exact(add_prompt) - child.sendline('expr ptr') - child.expect_exact(add_prompt1) - child.sendline('DONE') - child.expect_exact(prompt) - child.sendline('target stop-hook list') - - # Now run the program, expect to stop at the the first breakpoint which is within the stop-hook range. - child.expect_exact(prompt) - child.sendline('run') - child.expect_exact(prompt) - child.sendline('thread step-over') - #self.DebugPExpect(child) - child.expect_exact('** End Stop Hooks **') - #self.DebugPExpect(child) - # Verify that the 'Stop Hooks' mechanism is fired off. - self.expect(child.before, exe=False, - substrs = ['(void *) $0 = 0x']) - - # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range. - child.sendline('process continue') - child.expect_exact(prompt) - #self.DebugPExpect(child) - child.sendline('thread step-over') - child.expect_exact(prompt) - #self.DebugPExpect(child) - # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. - self.expect(child.before, exe=False, matching=False, - substrs = ['(void *) $0 = 0x']) - - -if __name__ == '__main__': - import atexit - lldb.SBDebugger.Initialize() - atexit.register(lambda: lldb.SBDebugger.Terminate()) - unittest2.main() Copied: lldb/trunk/test/stop-hook/TestStopHookMechanism.py (from r130767, lldb/trunk/test/stop-hook/TestStopHook.py) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/TestStopHookMechanism.py?p2=lldb/trunk/test/stop-hook/TestStopHookMechanism.py&p1=lldb/trunk/test/stop-hook/TestStopHook.py&r1=130767&r2=130773&rev=130773&view=diff ============================================================================== --- lldb/trunk/test/stop-hook/TestStopHook.py (original) +++ lldb/trunk/test/stop-hook/TestStopHookMechanism.py Tue May 3 13:40:19 2011 @@ -1,5 +1,5 @@ """ -Test lldb target stop-hook command. +Test lldb target stop-hook mechanism to see whether it fires off correctly . """ import os @@ -8,20 +8,20 @@ import pexpect from lldbtest import * -class StopHookTestCase(TestBase): +class StopHookMechanismTestCase(TestBase): mydir = "stop-hook" @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym(self): - """Test a sequence of target add-hook commands.""" + """Test the stop-hook mechanism.""" self.buildDsym() - self.stop_hook_command_sequence() + self.stop_hook_firing() def test_with_dwarf(self): - """Test a sequence of target add-hook commands.""" + """Test the stop-hook mechanism.""" self.buildDwarf() - self.stop_hook_command_sequence() + self.stop_hook_firing() def setUp(self): # Call super's setUp(). @@ -31,8 +31,8 @@ self.endl = line_number('main.cpp', '// End of the line range for which stop-hook is to be run.') self.line = line_number('main.cpp', '// Another breakpoint which is outside of the stop-hook range.') - def stop_hook_command_sequence(self): - """Test a sequence of target stop-hook commands.""" + def stop_hook_firing(self): + """Test the stop-hook mechanism.""" exe = os.path.join(os.getcwd(), "a.out") prompt = "(lldb) " add_prompt = "Enter your stop hook command(s). Type 'DONE' to end.\r\n> " From johnny.chen at apple.com Tue May 3 13:53:19 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 18:53:19 -0000 Subject: [Lldb-commits] [lldb] r130777 - /lldb/trunk/test/load_unload/TestLoadUnload.py Message-ID: <20110503185320.00D7F2A6C12C@llvm.org> Author: johnny Date: Tue May 3 13:53:19 2011 New Revision: 130777 URL: http://llvm.org/viewvc/llvm-project?rev=130777&view=rev Log: Modify test_image_search_paths(self) to check for the pattern "%s-[^-]*-[^-]*" % self.getArchitecture() from the output of running 'image list -t 3' command which lists the triples of the image list. 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=130777&r1=130776&r2=130777&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Tue May 3 13:53:19 2011 @@ -49,8 +49,11 @@ exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + print "Architecture to test for:", self.getArchitecture() self.expect("image list", substrs = [old_dylib]) + self.expect("image list -t 3", + patterns = ["%s-[^-]*-[^-]*" % self.getArchitecture()]) self.runCmd("target image-search-paths add %s %s" % (os.getcwd(), new_dir)) # Add teardown hook to clear image-search-paths after the test. self.addTearDownHook(lambda: self.runCmd("target image-search-paths clear")) From ctice at apple.com Tue May 3 15:53:11 2011 From: ctice at apple.com (Caroline Tice) Date: Tue, 03 May 2011 20:53:11 -0000 Subject: [Lldb-commits] [lldb] r130789 - in /lldb/trunk/tools/driver: Driver.cpp IOChannel.cpp IOChannel.h Message-ID: <20110503205311.AF9472A6C12C@llvm.org> Author: ctice Date: Tue May 3 15:53:11 2011 New Revision: 130789 URL: http://llvm.org/viewvc/llvm-project?rev=130789&view=rev Log: Make the driver listen for asynchronous output, rather than the IOChannel, so that it can be written out even while the IOChannel is collecting user input. Modified: lldb/trunk/tools/driver/Driver.cpp lldb/trunk/tools/driver/IOChannel.cpp lldb/trunk/tools/driver/IOChannel.h Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=130789&r1=130788&r2=130789&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Tue May 3 15:53:11 2011 @@ -1124,7 +1124,9 @@ bool iochannel_thread_exited = false; listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(), - SBCommandInterpreter::eBroadcastBitQuitCommandReceived); + SBCommandInterpreter::eBroadcastBitQuitCommandReceived | + SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | + SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); // Before we handle any options from the command line, we parse the // .lldbinit file in the user's home directory. @@ -1234,6 +1236,16 @@ { if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived) done = true; + else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData) + { + const char *data = SBEvent::GetCStringFromEvent (event); + m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC); + } + else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData) + { + const char *data = SBEvent::GetCStringFromEvent (event); + m_io_channel_ap->OutWrite (data, strlen(data), ASYNC); + } } } } Modified: lldb/trunk/tools/driver/IOChannel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.cpp?rev=130789&r1=130788&r2=130789&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.cpp (original) +++ lldb/trunk/tools/driver/IOChannel.cpp Tue May 3 15:53:11 2011 @@ -171,7 +171,8 @@ m_history_event(), m_getting_command (false), m_expecting_prompt (false), - m_prompt_str () + m_prompt_str (), + m_refresh_request_pending (false) { assert (m_edit_line); ::el_set (m_edit_line, EL_PROMPT, el_prompt); @@ -257,6 +258,7 @@ // Make this a member variable. // static std::string prompt_str; IOChannel *io_channel = (IOChannel *) baton; + IOLocker locker (io_channel->m_output_mutex); const char *bytes = (const char *) src; if (io_channel->IsGettingCommand() && io_channel->m_expecting_prompt) @@ -266,17 +268,19 @@ if (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == 0) { io_channel->m_expecting_prompt = false; + io_channel->m_refresh_request_pending = false; io_channel->OutWrite (io_channel->m_prompt_str.c_str(), io_channel->m_prompt_str.size(), NO_ASYNC); io_channel->m_prompt_str.clear(); } - else - assert (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == std::string::npos); } else { if (io_channel->m_prompt_str.size() > 0) io_channel->m_prompt_str.clear(); + std::string tmp_str (bytes, src_len); + if (tmp_str.find (el_prompt (io_channel->m_edit_line)) == 0) + io_channel->m_refresh_request_pending = false; io_channel->OutWrite (bytes, src_len, NO_ASYNC); } } @@ -342,9 +346,7 @@ listener.StartListeningForEvents (interpreter_broadcaster, SBCommandInterpreter::eBroadcastBitResetPrompt | SBCommandInterpreter::eBroadcastBitThreadShouldExit | - SBCommandInterpreter::eBroadcastBitQuitCommandReceived | - SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | - SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); + SBCommandInterpreter::eBroadcastBitQuitCommandReceived); listener.StartListeningForEvents (*this, IOChannel::eBroadcastBitThreadShouldExit); @@ -418,18 +420,6 @@ case SBCommandInterpreter::eBroadcastBitQuitCommandReceived: done = true; break; - case SBCommandInterpreter::eBroadcastBitAsynchronousErrorData: - { - const char *data = SBEvent::GetCStringFromEvent (event); - ErrWrite (data, strlen(data), ASYNC); - } - break; - case SBCommandInterpreter::eBroadcastBitAsynchronousOutputData: - { - const char *data = SBEvent::GetCStringFromEvent (event); - OutWrite (data, strlen(data), ASYNC); - } - break; } } else if (event.BroadcasterMatchesPtr (this)) @@ -482,7 +472,7 @@ { // If we are not in the middle of getting input from the user, there is no need to // refresh the prompt. - + IOLocker locker (m_output_mutex); if (! IsGettingCommand()) return; @@ -490,7 +480,11 @@ if (m_expecting_prompt) return; + if (m_refresh_request_pending) + return; + ::el_set (m_edit_line, EL_REFRESH); + m_refresh_request_pending = true; } void Modified: lldb/trunk/tools/driver/IOChannel.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.h?rev=130789&r1=130788&r2=130789&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.h (original) +++ lldb/trunk/tools/driver/IOChannel.h Tue May 3 15:53:11 2011 @@ -122,6 +122,7 @@ bool m_getting_command; bool m_expecting_prompt; std::string m_prompt_str; // for accumlating the prompt as it gets written out by editline + bool m_refresh_request_pending; void HistorySaveLoad (bool save); From ctice at apple.com Tue May 3 15:58:12 2011 From: ctice at apple.com (Caroline Tice) Date: Tue, 03 May 2011 20:58:12 -0000 Subject: [Lldb-commits] [lldb] r130790 - /lldb/trunk/source/Core/EmulateInstruction.cpp Message-ID: <20110503205812.0DDEE2A6C12C@llvm.org> Author: ctice Date: Tue May 3 15:58:11 2011 New Revision: 130790 URL: http://llvm.org/viewvc/llvm-project?rev=130790&view=rev Log: Remove type cast that was causing compiler warning. Modified: lldb/trunk/source/Core/EmulateInstruction.cpp Modified: lldb/trunk/source/Core/EmulateInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/EmulateInstruction.cpp?rev=130790&r1=130789&r2=130790&view=diff ============================================================================== --- lldb/trunk/source/Core/EmulateInstruction.cpp (original) +++ lldb/trunk/source/Core/EmulateInstruction.cpp Tue May 3 15:58:11 2011 @@ -305,7 +305,7 @@ void *dst, size_t length) { - fprintf (stdout, " Read from Memory (address = 0x%llx, length = %zu, context = ", addr, (uint32_t) length); + fprintf (stdout, " Read from Memory (address = 0x%llx, length = %zu, context = ", addr, length); context.Dump (stdout, instruction); *((uint64_t *) dst) = 0xdeadbeef; return length; @@ -319,7 +319,7 @@ const void *dst, size_t length) { - fprintf (stdout, " Write to Memory (address = 0x%llx, length = %zu, context = ", addr, (uint32_t) length); + fprintf (stdout, " Write to Memory (address = 0x%llx, length = %zu, context = ", addr, length); context.Dump (stdout, instruction); return length; } From ctice at apple.com Tue May 3 16:21:50 2011 From: ctice at apple.com (Caroline Tice) Date: Tue, 03 May 2011 21:21:50 -0000 Subject: [Lldb-commits] [lldb] r130792 - /lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Message-ID: <20110503212150.958922A6C12C@llvm.org> Author: ctice Date: Tue May 3 16:21:50 2011 New Revision: 130792 URL: http://llvm.org/viewvc/llvm-project?rev=130792&view=rev Log: Pre-load the Python script interpreter with the following convenience variables (from the ExecutionContext) each time it is entered: lldb.debugger, lldb.target, lldb.process, lldb.thread, lldb.frame. If a frame (or thread, process, etc) does not currently exist, the variable contains the Python value 'None'. Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=130792&r1=130791&r2=130792&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue May 3 16:21:50 2011 @@ -377,8 +377,49 @@ run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %d')", m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID()); PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + run_string.Printf ("run_one_line (%s, 'lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%d)')", + m_dictionary_name.c_str(), + GetCommandInterpreter().GetDebugger().GetID()); + PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + + + ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext(); + + if (exe_ctx.target) + run_string.Printf ("run_one_line (%s, 'lldb.target = lldb.debugger.GetSelectedTarget()')", + m_dictionary_name.c_str()); + else + run_string.Printf ("run_one_line (%s, 'lldb.target = None')", m_dictionary_name.c_str()); + PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + + if (exe_ctx.process) + run_string.Printf ("run_one_line (%s, 'lldb.process = lldb.target.GetProcess()')", m_dictionary_name.c_str()); + else + run_string.Printf ("run_one_line (%s, 'lldb.process = None')", m_dictionary_name.c_str()); + PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + + if (exe_ctx.thread) + run_string.Printf ("run_one_line (%s, 'lldb.thread = lldb.process.GetSelectedThread ()')", + m_dictionary_name.c_str()); + else + run_string.Printf ("run_one_line (%s, 'lldb.thread = None')", m_dictionary_name.c_str()); + PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + + if (exe_ctx.frame) + run_string.Printf ("run_one_line (%s, 'lldb.frame = lldb.thread.GetSelectedFrame ()')", + m_dictionary_name.c_str()); + else + run_string.Printf ("run_one_line (%s, 'lldb.frame = None')", m_dictionary_name.c_str()); + PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + PyObject *sysmod = PyImport_AddModule ("sys"); PyObject *sysdict = PyModule_GetDict (sysmod); From gclayton at apple.com Tue May 3 17:09:39 2011 From: gclayton at apple.com (Greg Clayton) Date: Tue, 03 May 2011 22:09:39 -0000 Subject: [Lldb-commits] [lldb] r130796 - in /lldb/trunk: include/lldb/Interpreter/ lldb.xcodeproj/ source/Commands/ source/Interpreter/ tools/debugserver/source/ tools/debugserver/source/MacOSX/ tools/debugserver/source/MacOSX/i386/ tools/debugserver/source/MacOSX/x86_64/ Message-ID: <20110503220939.D6F432A6C12C@llvm.org> Author: gclayton Date: Tue May 3 17:09:39 2011 New Revision: 130796 URL: http://llvm.org/viewvc/llvm-project?rev=130796&view=rev Log: Added new OptionGroup classes for UInt64, UUID, File and Boolean values. Removed the "image" command and moved it to "target modules". Added an alias for "image" to "target modules". Added some new target commands to be able to add and load modules to a target: (lldb) target modules add (lldb) target modules load [--file ] [--slide ] [ ...] So you can load individual sections without running a target: (lldb) target modules load --file /usr/lib/libSystem.B.dylib __TEXT 0x7fccc80000 __DATA 0x1234000000 Or you can rigidly slide an entire shared library: (lldb) target modules load --file /usr/lib/libSystem.B.dylib --slid 0x7fccc80000 This should improve bare board debugging when symbol files need to be slid around manually. Added: lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h lldb/trunk/include/lldb/Interpreter/OptionGroupFile.h lldb/trunk/include/lldb/Interpreter/OptionGroupUInt64.h lldb/trunk/include/lldb/Interpreter/OptionGroupUUID.h lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp lldb/trunk/source/Interpreter/OptionGroupFile.cpp lldb/trunk/source/Interpreter/OptionGroupUInt64.cpp lldb/trunk/source/Interpreter/OptionGroupUUID.cpp Removed: lldb/trunk/source/Commands/CommandObjectImage.cpp lldb/trunk/source/Commands/CommandObjectImage.h Modified: lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp lldb/trunk/source/Commands/CommandObjectDisassemble.cpp lldb/trunk/source/Commands/CommandObjectProcess.cpp lldb/trunk/source/Commands/CommandObjectSource.cpp lldb/trunk/source/Commands/CommandObjectTarget.cpp lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Interpreter/NamedOptionValue.cpp lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp lldb/trunk/tools/debugserver/source/DNB.cpp lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp lldb/trunk/tools/debugserver/source/RNBContext.cpp lldb/trunk/tools/debugserver/source/RNBRemote.cpp lldb/trunk/tools/debugserver/source/RNBRemote.h Modified: lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h (original) +++ lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h Tue May 3 17:09:39 2011 @@ -18,6 +18,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ConstString.h" +#include "lldb/Core/UUID.h" #include "lldb/Host/FileSpec.h" namespace lldb_private { @@ -28,6 +29,7 @@ class OptionValueString; class OptionValueFileSpec; class OptionValueFormat; + class OptionValueUUID; class OptionValueArray; class OptionValueDictionary; @@ -47,6 +49,7 @@ eTypeFormat, eTypeSInt64, eTypeUInt64, + eTypeUUID, eTypeString } Type; @@ -108,6 +111,9 @@ OptionValueFormat * GetAsFormat (); + OptionValueUUID * + GetAsUUID (); + OptionValueArray * GetAsArray (); @@ -741,6 +747,79 @@ bool m_byte_size_prefix_ok; }; + + + //--------------------------------------------------------------------- + // OptionValueUUID + //--------------------------------------------------------------------- + class OptionValueUUID : public OptionValue + { + public: + OptionValueUUID () : + m_uuid () + { + } + + OptionValueUUID (const UUID &uuid) : + m_uuid (uuid) + { + } + + virtual + ~OptionValueUUID() + { + } + + //--------------------------------------------------------------------- + // Virtual subclass pure virtual overrides + //--------------------------------------------------------------------- + + virtual OptionValue::Type + GetType () + { + return eTypeFileSpec; + } + + virtual void + DumpValue (Stream &strm); + + virtual Error + SetValueFromCString (const char *value); + + virtual bool + Clear () + { + m_uuid.Clear(); + m_value_was_set = false; + return true; + } + + //--------------------------------------------------------------------- + // Subclass specific functions + //--------------------------------------------------------------------- + + UUID & + GetCurrentValue() + { + return m_uuid; + } + + const UUID & + GetCurrentValue() const + { + return m_uuid; + } + + void + SetCurrentValue (const UUID &value) + { + m_uuid = value; + } + + protected: + UUID m_uuid; + }; + //--------------------------------------------------------------------- // OptionValueArray //--------------------------------------------------------------------- Added: lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h?rev=130796&view=auto ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h (added) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h Tue May 3 17:09:39 2011 @@ -0,0 +1,82 @@ +//===-- OptionGroupBoolean.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_OptionGroupBoolean_h_ +#define liblldb_OptionGroupBoolean_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/NamedOptionValue.h" + +namespace lldb_private { + //------------------------------------------------------------------------- + // OptionGroupBoolean + //------------------------------------------------------------------------- + + class OptionGroupBoolean : public OptionGroup + { + public: + + OptionGroupBoolean (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + bool default_value); + + virtual + ~OptionGroupBoolean (); + + + virtual uint32_t + GetNumDefinitions () + { + return 1; + } + + virtual const OptionDefinition* + GetDefinitions () + { + return &m_option_definition; + } + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_value); + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter); + + OptionValueBoolean & + GetOptionValue () + { + return m_value; + } + + const OptionValueBoolean & + GetOptionValue () const + { + return m_value; + } + + protected: + OptionValueBoolean m_value; + OptionDefinition m_option_definition; + + }; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupBoolean_h_ Added: lldb/trunk/include/lldb/Interpreter/OptionGroupFile.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupFile.h?rev=130796&view=auto ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupFile.h (added) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupFile.h Tue May 3 17:09:39 2011 @@ -0,0 +1,81 @@ +//===-- OptionGroupFile.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_OptionGroupFile_h_ +#define liblldb_OptionGroupFile_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/NamedOptionValue.h" + +namespace lldb_private { +//------------------------------------------------------------------------- +// OptionGroupFile +//------------------------------------------------------------------------- + +class OptionGroupFile : public OptionGroup +{ +public: + + OptionGroupFile (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text); + + virtual + ~OptionGroupFile (); + + + virtual uint32_t + GetNumDefinitions () + { + return 1; + } + + virtual const OptionDefinition* + GetDefinitions () + { + return &m_option_definition; + } + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_value); + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter); + + OptionValueFileSpec & + GetOptionValue () + { + return m_file; + } + + const OptionValueFileSpec & + GetOptionValue () const + { + return m_file; + } + +protected: + OptionValueFileSpec m_file; + OptionDefinition m_option_definition; + +}; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupFile_h_ Added: lldb/trunk/include/lldb/Interpreter/OptionGroupUInt64.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupUInt64.h?rev=130796&view=auto ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupUInt64.h (added) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupUInt64.h Tue May 3 17:09:39 2011 @@ -0,0 +1,82 @@ +//===-- OptionGroupUInt64.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_OptionGroupUInt64_h_ +#define liblldb_OptionGroupUInt64_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/NamedOptionValue.h" + +namespace lldb_private { + //------------------------------------------------------------------------- + // OptionGroupUInt64 + //------------------------------------------------------------------------- + + class OptionGroupUInt64 : public OptionGroup + { + public: + + OptionGroupUInt64 (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + uint64_t default_value); + + virtual + ~OptionGroupUInt64 (); + + + virtual uint32_t + GetNumDefinitions () + { + return 1; + } + + virtual const OptionDefinition* + GetDefinitions () + { + return &m_option_definition; + } + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_value); + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter); + + OptionValueUInt64 & + GetOptionValue () + { + return m_value; + } + + const OptionValueUInt64 & + GetOptionValue () const + { + return m_value; + } + + protected: + OptionValueUInt64 m_value; + OptionDefinition m_option_definition; + + }; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupUInt64_h_ Added: lldb/trunk/include/lldb/Interpreter/OptionGroupUUID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupUUID.h?rev=130796&view=auto ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupUUID.h (added) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupUUID.h Tue May 3 17:09:39 2011 @@ -0,0 +1,61 @@ +//===-- OptionGroupUUID.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_OptionGroupUUID_h_ +#define liblldb_OptionGroupUUID_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/NamedOptionValue.h" + +namespace lldb_private { +//------------------------------------------------------------------------- +// OptionGroupUUID +//------------------------------------------------------------------------- + +class OptionGroupUUID : public OptionGroup +{ +public: + + OptionGroupUUID (); + + virtual + ~OptionGroupUUID (); + + + virtual uint32_t + GetNumDefinitions (); + + virtual const OptionDefinition* + GetDefinitions (); + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_value); + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter); + + const OptionValueUUID & + GetOptionValue () const + { + return m_uuid; + } + +protected: + OptionValueUUID m_uuid; +}; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupUUID_h_ Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue May 3 17:09:39 2011 @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 260C876A10F538E700BB2B04 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 260C876910F538E700BB2B04 /* Foundation.framework */; }; + 260E07C6136FA69E00CF21D3 /* OptionGroupUUID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E07C5136FA69E00CF21D3 /* OptionGroupUUID.cpp */; }; + 260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E07C7136FAB9200CF21D3 /* OptionGroupFile.cpp */; }; 261744781168585B005ADD65 /* SBType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261744771168585B005ADD65 /* SBType.cpp */; }; 2617447A11685869005ADD65 /* SBType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2617447911685869005ADD65 /* SBType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; }; @@ -75,6 +77,8 @@ 26744EF41338317700EF765A /* GDBRemoteCommunicationServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */; }; 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; }; 267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; }; + 2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */; }; + 268653701370AE7200D186A3 /* OptionGroupUInt64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */; }; 2689000013353DB600698AC0 /* BreakpointResolverAddress.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D0DD5010FE554D00271C65 /* BreakpointResolverAddress.h */; }; 2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */; }; 2689000213353DB600698AC0 /* BreakpointResolverFileLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */; }; @@ -102,7 +106,6 @@ 2689001813353DDE00698AC0 /* CommandObjectExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */; }; 2689001A13353DDE00698AC0 /* CommandObjectFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2672D8461189055500FF4019 /* CommandObjectFrame.cpp */; }; 2689001B13353DDE00698AC0 /* CommandObjectHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3310F1B84700F91463 /* CommandObjectHelp.cpp */; }; - 2689001C13353DDE00698AC0 /* CommandObjectImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3410F1B84700F91463 /* CommandObjectImage.cpp */; }; 2689001D13353DDE00698AC0 /* CommandObjectLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264AD83711095BA600E0B039 /* CommandObjectLog.cpp */; }; 2689001E13353DDE00698AC0 /* CommandObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3610F1B84700F91463 /* CommandObjectMemory.cpp */; }; 2689001F13353DDE00698AC0 /* CommandObjectPlatform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26879CE71333F58B0012C1F8 /* CommandObjectPlatform.cpp */; }; @@ -616,6 +619,10 @@ 260C89DF10F57C5600BB2B04 /* SymbolFileSymtab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolFileSymtab.h; sourceTree = ""; }; 260C89E210F57C5600BB2B04 /* SymbolVendorMacOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolVendorMacOSX.cpp; sourceTree = ""; }; 260C89E310F57C5600BB2B04 /* SymbolVendorMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolVendorMacOSX.h; sourceTree = ""; }; + 260E07C3136FA68900CF21D3 /* OptionGroupUUID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupUUID.h; path = include/lldb/Interpreter/OptionGroupUUID.h; sourceTree = ""; }; + 260E07C5136FA69E00CF21D3 /* OptionGroupUUID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupUUID.cpp; path = source/Interpreter/OptionGroupUUID.cpp; sourceTree = ""; }; + 260E07C7136FAB9200CF21D3 /* OptionGroupFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupFile.cpp; path = source/Interpreter/OptionGroupFile.cpp; sourceTree = ""; }; + 260E07C9136FABAC00CF21D3 /* OptionGroupFile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupFile.h; path = include/lldb/Interpreter/OptionGroupFile.h; sourceTree = ""; }; 26109B3B1155D70100CC3529 /* LogChannelDWARF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogChannelDWARF.cpp; sourceTree = ""; }; 26109B3C1155D70100CC3529 /* LogChannelDWARF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogChannelDWARF.h; sourceTree = ""; }; 2615DB841208A9C90021781D /* StopInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StopInfo.h; path = include/lldb/Target/StopInfo.h; sourceTree = ""; }; @@ -708,6 +715,10 @@ 2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PseudoTerminal.h; path = include/lldb/Utility/PseudoTerminal.h; sourceTree = ""; }; 2682F284115EF3A700CCFF99 /* SBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBError.cpp; path = source/API/SBError.cpp; sourceTree = ""; }; 2682F286115EF3BD00CCFF99 /* SBError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBError.h; path = include/lldb/API/SBError.h; sourceTree = ""; }; + 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupBoolean.cpp; path = source/Interpreter/OptionGroupBoolean.cpp; sourceTree = ""; }; + 2686536D1370ACC600D186A3 /* OptionGroupBoolean.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupBoolean.h; path = include/lldb/Interpreter/OptionGroupBoolean.h; sourceTree = ""; }; + 2686536E1370AE5A00D186A3 /* OptionGroupUInt64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupUInt64.h; path = include/lldb/Interpreter/OptionGroupUInt64.h; sourceTree = ""; }; + 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupUInt64.cpp; path = source/Interpreter/OptionGroupUInt64.cpp; sourceTree = ""; }; 26879CE51333F5750012C1F8 /* CommandObjectPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectPlatform.h; path = source/Commands/CommandObjectPlatform.h; sourceTree = ""; }; 26879CE71333F58B0012C1F8 /* CommandObjectPlatform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectPlatform.cpp; path = source/Commands/CommandObjectPlatform.cpp; sourceTree = ""; }; 2689B0A4113EE3CD00A4AEDB /* Symbols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Symbols.h; path = include/lldb/Host/Symbols.h; sourceTree = ""; }; @@ -790,7 +801,6 @@ 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 = ""; }; 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 = ""; }; 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 = ""; }; @@ -894,7 +904,6 @@ 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 = ""; }; 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 = ""; }; 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 = ""; }; @@ -2146,8 +2155,6 @@ 2672D8461189055500FF4019 /* CommandObjectFrame.cpp */, 26BC7D1A10F1B76300F91463 /* CommandObjectHelp.h */, 26BC7E3310F1B84700F91463 /* CommandObjectHelp.cpp */, - 26BC7D1B10F1B76300F91463 /* CommandObjectImage.h */, - 26BC7E3410F1B84700F91463 /* CommandObjectImage.cpp */, 264AD83911095BBD00E0B039 /* CommandObjectLog.h */, 264AD83711095BA600E0B039 /* CommandObjectLog.cpp */, 26BC7D1D10F1B76300F91463 /* CommandObjectMemory.h */, @@ -2265,12 +2272,20 @@ 26BC7E8610F1B85900F91463 /* Options.cpp */, 26D5E160135BAEB0006EA0A7 /* OptionGroupArchitecture.h */, 26D5E15E135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp */, + 2686536D1370ACC600D186A3 /* OptionGroupBoolean.h */, + 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */, + 260E07C9136FABAC00CF21D3 /* OptionGroupFile.h */, + 260E07C7136FAB9200CF21D3 /* OptionGroupFile.cpp */, 26BCFC4F1368ADF7006DC050 /* OptionGroupFormat.h */, 26BCFC511368AE38006DC050 /* OptionGroupFormat.cpp */, 26BCFC541368B4B8006DC050 /* OptionGroupOutputFile.h */, 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */, 26D5E161135BB040006EA0A7 /* OptionGroupPlatform.h */, 26D5E162135BB054006EA0A7 /* OptionGroupPlatform.cpp */, + 2686536E1370AE5A00D186A3 /* OptionGroupUInt64.h */, + 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */, + 260E07C3136FA68900CF21D3 /* OptionGroupUUID.h */, + 260E07C5136FA69E00CF21D3 /* OptionGroupUUID.cpp */, 267C0128136880C7006E963E /* OptionGroupValueObjectDisplay.h */, 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */, 26BC7DE510F1B7F900F91463 /* ScriptInterpreter.h */, @@ -2997,7 +3012,6 @@ 2689001813353DDE00698AC0 /* CommandObjectExpression.cpp in Sources */, 2689001A13353DDE00698AC0 /* CommandObjectFrame.cpp in Sources */, 2689001B13353DDE00698AC0 /* CommandObjectHelp.cpp in Sources */, - 2689001C13353DDE00698AC0 /* CommandObjectImage.cpp in Sources */, 2689001D13353DDE00698AC0 /* CommandObjectLog.cpp in Sources */, 2689001E13353DDE00698AC0 /* CommandObjectMemory.cpp in Sources */, 2689001F13353DDE00698AC0 /* CommandObjectPlatform.cpp in Sources */, @@ -3265,6 +3279,10 @@ 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */, 26BCFC521368AE38006DC050 /* OptionGroupFormat.cpp in Sources */, 267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */, + 260E07C6136FA69E00CF21D3 /* OptionGroupUUID.cpp in Sources */, + 260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */, + 2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */, + 268653701370AE7200D186A3 /* OptionGroupUInt64.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Tue May 3 17:09:39 2011 @@ -284,7 +284,7 @@ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { - result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'file' command)."); + result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); result.SetStatus (eReturnStatusFailed); return false; } Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Tue May 3 17:09:39 2011 @@ -214,7 +214,7 @@ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { - result.AppendError ("invalid target, set executable file using 'file' command"); + result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } Removed: lldb/trunk/source/Commands/CommandObjectImage.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=130795&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectImage.cpp (removed) @@ -1,1773 +0,0 @@ -//===-- CommandObjectImage.cpp ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectImage.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Debugger.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/Stream.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Interpreter/Options.h" -#include "lldb/Interpreter/CommandCompletions.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/SymbolVendor.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Static Helper functions -//---------------------------------------------------------------------- -static void -DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) -{ - if (module) - { - const char *arch_cstr; - if (full_triple) - arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); - else - arch_cstr = module->GetArchitecture().GetArchitectureName(); - if (width) - strm.Printf("%-*s", width, arch_cstr); - else - strm.PutCString(arch_cstr); - } -} - -static void -DumpModuleUUID (Stream &strm, Module *module) -{ - module->GetUUID().Dump (&strm); -} - -static uint32_t -DumpCompileUnitLineTable -( - CommandInterpreter &interpreter, - Stream &strm, - Module *module, - const FileSpec &file_spec, - bool load_addresses -) -{ - uint32_t num_matches = 0; - if (module) - { - SymbolContextList sc_list; - num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, - 0, - false, - eSymbolContextCompUnit, - sc_list); - - for (uint32_t i=0; i 0) - strm << "\n\n"; - - strm << "Line table for " << *static_cast (sc.comp_unit) << " in `" - << module->GetFileSpec().GetFilename() << "\n"; - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table) - line_table->GetDescription (&strm, - interpreter.GetExecutionContext().target, - lldb::eDescriptionLevelBrief); - else - strm << "No line table"; - } - } - } - return num_matches; -} - -static void -DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) -{ - if (file_spec_ptr) - { - if (width > 0) - { - char fullpath[PATH_MAX]; - if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath))) - { - strm.Printf("%-*s", width, fullpath); - return; - } - } - else - { - file_spec_ptr->Dump(&strm); - return; - } - } - // Keep the width spacing correct if things go wrong... - if (width > 0) - strm.Printf("%-*s", width, ""); -} - -static void -DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) -{ - if (file_spec_ptr) - { - if (width > 0) - strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); - else - file_spec_ptr->GetDirectory().Dump(&strm); - return; - } - // Keep the width spacing correct if things go wrong... - if (width > 0) - strm.Printf("%-*s", width, ""); -} - -static void -DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) -{ - if (file_spec_ptr) - { - if (width > 0) - strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); - else - file_spec_ptr->GetFilename().Dump(&strm); - return; - } - // Keep the width spacing correct if things go wrong... - if (width > 0) - strm.Printf("%-*s", width, ""); -} - - -static void -DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) -{ - if (module) - { - ObjectFile *objfile = module->GetObjectFile (); - if (objfile) - { - Symtab *symtab = objfile->GetSymtab(); - if (symtab) - symtab->Dump(&strm, interpreter.GetExecutionContext().target, sort_order); - } - } -} - -static void -DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) -{ - if (module) - { - ObjectFile *objfile = module->GetObjectFile (); - if (objfile) - { - SectionList *section_list = objfile->GetSectionList(); - if (section_list) - { - strm.PutCString ("Sections for '"); - strm << module->GetFileSpec(); - if (module->GetObjectName()) - strm << '(' << module->GetObjectName() << ')'; - strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName()); - strm.IndentMore(); - section_list->Dump(&strm, interpreter.GetExecutionContext().target, true, UINT32_MAX); - strm.IndentLess(); - } - } - } -} - -static bool -DumpModuleSymbolVendor (Stream &strm, Module *module) -{ - if (module) - { - SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); - if (symbol_vendor) - { - symbol_vendor->Dump(&strm); - return true; - } - } - return false; -} - -static bool -LookupAddressInModule -( - CommandInterpreter &interpreter, - Stream &strm, - Module *module, - uint32_t resolve_mask, - lldb::addr_t raw_addr, - lldb::addr_t offset, - bool verbose -) -{ - if (module) - { - lldb::addr_t addr = raw_addr - offset; - Address so_addr; - SymbolContext sc; - Target *target = interpreter.GetExecutionContext().target; - if (target && !target->GetSectionLoadList().IsEmpty()) - { - if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) - return false; - else if (so_addr.GetModule() != module) - return false; - } - else - { - if (!module->ResolveFileAddress (addr, so_addr)) - return false; - } - - // If an offset was given, print out the address we ended up looking up - if (offset) - strm.Printf("File Address: 0x%llx\n", addr); - - ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); - strm.IndentMore(); - strm.Indent (" Address: "); - so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); - strm.EOL(); - strm.Indent (" Summary: "); - const uint32_t save_indent = strm.GetIndentLevel (); - strm.SetIndentLevel (save_indent + 11); - so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); - strm.SetIndentLevel (save_indent); - strm.EOL(); - // Print out detailed address information when verbose is enabled - if (verbose) - { - if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext)) - strm.EOL(); - } - strm.IndentLess(); - return true; - } - - return false; -} - -static uint32_t -LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex) -{ - if (module) - { - SymbolContext sc; - - ObjectFile *objfile = module->GetObjectFile (); - if (objfile) - { - Symtab *symtab = objfile->GetSymtab(); - if (symtab) - { - uint32_t i; - std::vector match_indexes; - ConstString symbol_name (name); - uint32_t num_matches = 0; - if (name_is_regex) - { - RegularExpression name_regexp(name); - num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, - eSymbolTypeAny, - match_indexes); - } - else - { - num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); - } - - - if (num_matches > 0) - { - strm.Indent (); - strm.Printf("%u symbols match %s'%s' in ", num_matches, - name_is_regex ? "the regular expression " : "", name); - DumpFullpath (strm, &module->GetFileSpec(), 0); - strm.PutCString(":\n"); - strm.IndentMore (); - Symtab::DumpSymbolHeader (&strm); - for (i=0; i < num_matches; ++i) - { - Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); - strm.Indent (); - symbol->Dump (&strm, interpreter.GetExecutionContext().target, i); - } - strm.IndentLess (); - return num_matches; - } - } - } - } - return 0; -} - - -static void -DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose) -{ - strm.IndentMore (); - uint32_t i; - const uint32_t num_matches = sc_list.GetSize(); - - for (i=0; iGetAddressRange().GetBaseAddress().IsValid()) - { - if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm, - exe_scope, - Address::DumpStyleDetailedSymbolContext)) - strm.PutCString("\n\n"); - } - } - } - } - strm.IndentLess (); -} - -static uint32_t -LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) -{ - if (module && name && name[0]) - { - SymbolContextList sc_list; - const bool include_symbols = false; - const bool append = true; - uint32_t num_matches = 0; - if (name_is_regex) - { - RegularExpression function_name_regex (name); - num_matches = module->FindFunctions (function_name_regex, - include_symbols, - append, - sc_list); - } - else - { - ConstString function_name (name); - num_matches = module->FindFunctions (function_name, - eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, - include_symbols, - append, - sc_list); - } - - if (num_matches) - { - strm.Indent (); - strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); - DumpFullpath (strm, &module->GetFileSpec(), 0); - strm.PutCString(":\n"); - DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); - } - return num_matches; - } - return 0; -} - -static uint32_t -LookupTypeInModule -( - CommandInterpreter &interpreter, - Stream &strm, - Module *module, - const char *name_cstr, - bool name_is_regex -) -{ - if (module && name_cstr && name_cstr[0]) - { - SymbolContextList sc_list; - - SymbolVendor *symbol_vendor = module->GetSymbolVendor(); - if (symbol_vendor) - { - TypeList type_list; - uint32_t num_matches = 0; - SymbolContext sc; -// if (name_is_regex) -// { -// RegularExpression name_regex (name_cstr); -// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list); -// } -// else -// { - ConstString name(name_cstr); - num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list); -// } - - if (num_matches) - { - strm.Indent (); - strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); - DumpFullpath (strm, &module->GetFileSpec(), 0); - strm.PutCString(":\n"); - const uint32_t num_types = type_list.GetSize(); - for (uint32_t i=0; iGetClangFullType (); - type_sp->GetDescription (&strm, eDescriptionLevelFull, true); - } - strm.EOL(); - } - } - return num_matches; - } - } - return 0; -} - -static uint32_t -LookupFileAndLineInModule (CommandInterpreter &interpreter, - Stream &strm, - Module *module, - const FileSpec &file_spec, - uint32_t line, - bool check_inlines, - bool verbose) -{ - if (module && file_spec) - { - SymbolContextList sc_list; - const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, - eSymbolContextEverything, sc_list); - if (num_matches > 0) - { - strm.Indent (); - strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); - strm << file_spec; - if (line > 0) - strm.Printf (":%u", line); - strm << " in "; - DumpFullpath (strm, &module->GetFileSpec(), 0); - strm.PutCString(":\n"); - DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); - return num_matches; - } - } - return 0; - -} - - -//---------------------------------------------------------------------- -// Image symbol table dumping command -//---------------------------------------------------------------------- - -class CommandObjectImageDumpModuleList : public CommandObject -{ -public: - - CommandObjectImageDumpModuleList (CommandInterpreter &interpreter, - const char *name, - const char *help, - const char *syntax) : - CommandObject (interpreter, name, help, syntax) - { - CommandArgumentEntry arg; - CommandArgumentData file_arg; - - // Define the first (and only) variant of this arg. - file_arg.arg_type = eArgTypeFilename; - file_arg.arg_repetition = eArgRepeatStar; - - // There is only one variant this argument could be; put it into the argument entry. - arg.push_back (file_arg); - - // Push the data for the first argument into the m_arguments vector. - m_arguments.push_back (arg); - } - - virtual - ~CommandObjectImageDumpModuleList () - { - } - - virtual int - HandleArgumentCompletion (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) - { - // Arguments are the standard module completer. - std::string completion_str (input.GetArgumentAtIndex(cursor_index)); - completion_str.erase (cursor_char_position); - - CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, - CommandCompletions::eModuleCompletion, - completion_str.c_str(), - match_start_point, - max_return_elements, - NULL, - word_complete, - matches); - return matches.GetSize(); - } -}; - -class CommandObjectImageDumpSourceFileList : public CommandObject -{ -public: - - CommandObjectImageDumpSourceFileList (CommandInterpreter &interpreter, - const char *name, - const char *help, - const char *syntax) : - CommandObject (interpreter, name, help, syntax) - { - CommandArgumentEntry arg; - CommandArgumentData source_file_arg; - - // Define the first (and only) variant of this arg. - source_file_arg.arg_type = eArgTypeSourceFile; - source_file_arg.arg_repetition = eArgRepeatPlus; - - // There is only one variant this argument could be; put it into the argument entry. - arg.push_back (source_file_arg); - - // Push the data for the first argument into the m_arguments vector. - m_arguments.push_back (arg); - } - - virtual - ~CommandObjectImageDumpSourceFileList () - { - } - - virtual int - HandleArgumentCompletion (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) - { - // Arguments are the standard source file completer. - std::string completion_str (input.GetArgumentAtIndex(cursor_index)); - completion_str.erase (cursor_char_position); - - CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, - CommandCompletions::eSourceFileCompletion, - completion_str.c_str(), - match_start_point, - max_return_elements, - NULL, - word_complete, - matches); - return matches.GetSize(); - } -}; - - -class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList -{ -public: - CommandObjectImageDumpSymtab (CommandInterpreter &interpreter) : - CommandObjectImageDumpModuleList (interpreter, - "image dump symtab", - "Dump the symbol table from one or more executable images.", - NULL), - m_options (interpreter) - { - } - - virtual - ~CommandObjectImageDumpSymtab () - { - } - - virtual bool - Execute (Args& command, - CommandReturnObject &result) - { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - uint32_t num_dumped = 0; - - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - - if (command.GetArgumentCount() == 0) - { - // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); - for (uint32_t image_idx = 0; image_idx 0) - { - result.GetOutputStream().EOL(); - result.GetOutputStream().EOL(); - } - num_dumped++; - DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order); - } - } - else - { - result.AppendError ("the target has no associated executable images"); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - else - { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) - { - FileSpec image_file(arg_cstr, false); - ModuleList matching_modules; - size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); - - // Not found in our module list for our target, check the main - // shared module list in case it is a extra file used somewhere - // else - if (num_matching_modules == 0) - num_matching_modules = ModuleList::FindSharedModules (image_file, - target->GetArchitecture(), - NULL, - NULL, - matching_modules); - - if (num_matching_modules > 0) - { - for (size_t i=0; i 0) - { - result.GetOutputStream().EOL(); - result.GetOutputStream().EOL(); - } - num_dumped++; - DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order); - } - } - } - else - result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); - } - } - - if (num_dumped > 0) - result.SetStatus (eReturnStatusSuccessFinishResult); - else - { - result.AppendError ("no matching executable images found"); - result.SetStatus (eReturnStatusFailed); - } - } - return result.Succeeded(); - } - - virtual Options * - GetOptions () - { - return &m_options; - } - - class CommandOptions : public Options - { - public: - - CommandOptions (CommandInterpreter &interpreter) : - Options(interpreter), - m_sort_order (eSortOrderNone) - { - } - - virtual - ~CommandOptions () - { - } - - virtual Error - SetOptionValue (uint32_t option_idx, const char *option_arg) - { - Error error; - char short_option = (char) m_getopt_table[option_idx].val; - - switch (short_option) - { - case 's': - { - bool found_one = false; - m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, - g_option_table[option_idx].enum_values, - eSortOrderNone, - &found_one); - if (!found_one) - error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n", - option_arg, - short_option); - } - break; - - default: - error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); - break; - - } - return error; - } - - void - OptionParsingStarting () - { - m_sort_order = eSortOrderNone; - } - - const OptionDefinition* - GetDefinitions () - { - return g_option_table; - } - - // Options table: Required for subclasses of Options. - static OptionDefinition g_option_table[]; - - SortOrder m_sort_order; - }; - -protected: - - CommandOptions m_options; -}; - -static OptionEnumValueElement -g_sort_option_enumeration[4] = -{ - { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, - { eSortOrderByAddress, "address", "Sort output by symbol address."}, - { eSortOrderByName, "name", "Sort output by symbol name."}, - { 0, NULL, NULL } -}; - - -OptionDefinition -CommandObjectImageDumpSymtab::CommandOptions::g_option_table[] = -{ -{ LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } -}; - - -//---------------------------------------------------------------------- -// Image section dumping command -//---------------------------------------------------------------------- -class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList -{ -public: - CommandObjectImageDumpSections (CommandInterpreter &interpreter) : - CommandObjectImageDumpModuleList (interpreter, - "image dump sections", - "Dump the sections from one or more executable images.", - //"image dump sections [ ...]") - NULL) - { - } - - virtual - ~CommandObjectImageDumpSections () - { - } - - virtual bool - Execute (Args& command, - CommandReturnObject &result) - { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - uint32_t num_dumped = 0; - - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - - if (command.GetArgumentCount() == 0) - { - // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); - for (uint32_t image_idx = 0; image_idxGetImages().GetModulePointerAtIndex(image_idx)); - } - } - else - { - result.AppendError ("the target has no associated executable images"); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - else - { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) - { - FileSpec image_file(arg_cstr, false); - ModuleList matching_modules; - size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); - - // Not found in our module list for our target, check the main - // shared module list in case it is a extra file used somewhere - // else - if (num_matching_modules == 0) - num_matching_modules = ModuleList::FindSharedModules (image_file, - target->GetArchitecture(), - NULL, - NULL, - matching_modules); - - if (num_matching_modules > 0) - { - for (size_t i=0; i 0) - result.SetStatus (eReturnStatusSuccessFinishResult); - else - { - result.AppendError ("no matching executable images found"); - result.SetStatus (eReturnStatusFailed); - } - } - return result.Succeeded(); - } -}; - -//---------------------------------------------------------------------- -// Image debug symbol dumping command -//---------------------------------------------------------------------- -class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList -{ -public: - CommandObjectImageDumpSymfile (CommandInterpreter &interpreter) : - CommandObjectImageDumpModuleList (interpreter, - "image dump symfile", - "Dump the debug symbol file for one or more executable images.", - //"image dump symfile [ ...]") - NULL) - { - } - - virtual - ~CommandObjectImageDumpSymfile () - { - } - - virtual bool - Execute (Args& command, - CommandReturnObject &result) - { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - uint32_t num_dumped = 0; - - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - - if (command.GetArgumentCount() == 0) - { - // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); - for (uint32_t image_idx = 0; image_idxGetImages().GetModulePointerAtIndex(image_idx))) - num_dumped++; - } - } - else - { - result.AppendError ("the target has no associated executable images"); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - else - { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) - { - FileSpec image_file(arg_cstr, false); - ModuleList matching_modules; - size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); - - // Not found in our module list for our target, check the main - // shared module list in case it is a extra file used somewhere - // else - if (num_matching_modules == 0) - num_matching_modules = ModuleList::FindSharedModules (image_file, - target->GetArchitecture(), - NULL, - NULL, - matching_modules); - - if (num_matching_modules > 0) - { - for (size_t i=0; i 0) - result.SetStatus (eReturnStatusSuccessFinishResult); - else - { - result.AppendError ("no matching executable images found"); - result.SetStatus (eReturnStatusFailed); - } - } - return result.Succeeded(); - } -}; - -//---------------------------------------------------------------------- -// Image debug symbol dumping command -//---------------------------------------------------------------------- -class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList -{ -public: - CommandObjectImageDumpLineTable (CommandInterpreter &interpreter) : - CommandObjectImageDumpSourceFileList (interpreter, - "image dump line-table", - "Dump the debug symbol file for one or more executable images.", - NULL) - { - } - - virtual - ~CommandObjectImageDumpLineTable () - { - } - - virtual bool - Execute (Args& command, - CommandReturnObject &result) - { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - uint32_t total_num_dumped = 0; - - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - - if (command.GetArgumentCount() == 0) - { - result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); - result.SetStatus (eReturnStatusFailed); - } - else - { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) - { - FileSpec file_spec(arg_cstr, false); - const uint32_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - uint32_t num_dumped = 0; - for (uint32_t i = 0; iGetImages().GetModulePointerAtIndex(i), - file_spec, - exe_ctx.process != NULL && exe_ctx.process->IsAlive())) - num_dumped++; - } - if (num_dumped == 0) - result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); - else - total_num_dumped += num_dumped; - } - } - } - - if (total_num_dumped > 0) - result.SetStatus (eReturnStatusSuccessFinishResult); - else - { - result.AppendError ("no source filenames matched any command arguments"); - result.SetStatus (eReturnStatusFailed); - } - } - return result.Succeeded(); - } -}; - -//---------------------------------------------------------------------- -// Dump multi-word command -//---------------------------------------------------------------------- -class CommandObjectImageDump : public CommandObjectMultiword -{ -public: - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CommandObjectImageDump(CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "image dump", - "A set of commands for dumping information about one or more executable images; 'line-table' expects a source file name", - "image dump [symtab|sections|symfile|line-table] [ ...]") - { - LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectImageDumpSymtab (interpreter))); - LoadSubCommand ("sections", CommandObjectSP (new CommandObjectImageDumpSections (interpreter))); - LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectImageDumpSymfile (interpreter))); - LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectImageDumpLineTable (interpreter))); - } - - virtual - ~CommandObjectImageDump() - { - } -}; - -//---------------------------------------------------------------------- -// List images with associated information -//---------------------------------------------------------------------- -class CommandObjectImageList : public CommandObject -{ -public: - - class CommandOptions : public Options - { - public: - - CommandOptions (CommandInterpreter &interpreter) : - Options(interpreter), - m_format_array() - { - } - - virtual - ~CommandOptions () - { - } - - virtual Error - SetOptionValue (uint32_t option_idx, const char *option_arg) - { - char short_option = (char) m_getopt_table[option_idx].val; - uint32_t width = 0; - if (option_arg) - width = strtoul (option_arg, NULL, 0); - m_format_array.push_back(std::make_pair(short_option, width)); - Error error; - return error; - } - - void - OptionParsingStarting () - { - m_format_array.clear(); - } - - const OptionDefinition* - GetDefinitions () - { - return g_option_table; - } - - // Options table: Required for subclasses of Options. - - static OptionDefinition g_option_table[]; - - // Instance variables to hold the values for command options. - typedef std::vector< std::pair > FormatWidthCollection; - FormatWidthCollection m_format_array; - }; - - CommandObjectImageList (CommandInterpreter &interpreter) : - CommandObject (interpreter, - "image list", - "List current executable and dependent shared library images.", - "image list []"), - m_options (interpreter) - { - } - - virtual - ~CommandObjectImageList () - { - } - - virtual - Options * - GetOptions () - { - return &m_options; - } - - virtual bool - Execute (Args& command, - CommandReturnObject &result) - { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - Stream &strm = result.GetOutputStream(); - - for (uint32_t image_idx = 0; image_idxGetImages().GetModulePointerAtIndex(image_idx); - strm.Printf("[%3u] ", image_idx); - - bool dump_object_name = false; - if (m_options.m_format_array.empty()) - { - DumpFullpath(strm, &module->GetFileSpec(), 0); - dump_object_name = true; - } - else - { - const size_t num_entries = m_options.m_format_array.size(); - for (size_t i=0; i 0) - strm.PutChar(' '); - char format_char = m_options.m_format_array[i].first; - uint32_t width = m_options.m_format_array[i].second; - switch (format_char) - { - case 'a': - DumpModuleArchitecture (strm, module, false, width); - break; - - case 't': - DumpModuleArchitecture (strm, module, true, width); - break; - - case 'f': - DumpFullpath (strm, &module->GetFileSpec(), width); - dump_object_name = true; - break; - - case 'd': - DumpDirectory (strm, &module->GetFileSpec(), width); - break; - - case 'b': - DumpBasename (strm, &module->GetFileSpec(), width); - dump_object_name = true; - break; - - case 's': - case 'S': - { - SymbolVendor *symbol_vendor = module->GetSymbolVendor(); - if (symbol_vendor) - { - SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); - if (symbol_file) - { - if (format_char == 'S') - DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); - else - DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); - dump_object_name = true; - break; - } - } - strm.Printf("%.*s", width, ""); - } - break; - - case 'u': - DumpModuleUUID(strm, module); - break; - - default: - break; - } - - } - } - if (dump_object_name) - { - const char *object_name = module->GetObjectName().GetCString(); - if (object_name) - strm.Printf ("(%s)", object_name); - } - strm.EOL(); - } - result.SetStatus (eReturnStatusSuccessFinishResult); - } - else - { - result.AppendError ("the target has no associated executable images"); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - return result.Succeeded(); - } -protected: - - CommandOptions m_options; -}; - -OptionDefinition -CommandObjectImageList::CommandOptions::g_option_table[] = -{ -{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, -{ LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, -{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, -{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, -{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, -{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, -{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, -{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } -}; - - - -//---------------------------------------------------------------------- -// Lookup information in images -//---------------------------------------------------------------------- -class CommandObjectImageLookup : public CommandObject -{ -public: - - enum - { - eLookupTypeInvalid = -1, - eLookupTypeAddress = 0, - eLookupTypeSymbol, - eLookupTypeFileLine, // Line is optional - eLookupTypeFunction, - eLookupTypeType, - kNumLookupTypes - }; - - class CommandOptions : public Options - { - public: - - CommandOptions (CommandInterpreter &interpreter) : - Options(interpreter) - { - OptionParsingStarting(); - } - - virtual - ~CommandOptions () - { - } - - virtual Error - SetOptionValue (uint32_t option_idx, const char *option_arg) - { - Error error; - - char short_option = (char) m_getopt_table[option_idx].val; - - switch (short_option) - { - case 'a': - m_type = eLookupTypeAddress; - m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); - if (m_addr == LLDB_INVALID_ADDRESS) - error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg); - break; - - case 'o': - m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); - if (m_offset == LLDB_INVALID_ADDRESS) - error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg); - break; - - case 's': - m_str = option_arg; - m_type = eLookupTypeSymbol; - break; - - case 'f': - m_file.SetFile (option_arg, false); - m_type = eLookupTypeFileLine; - break; - - case 'i': - m_check_inlines = false; - break; - - case 'l': - m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); - if (m_line_number == UINT32_MAX) - error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg); - else if (m_line_number == 0) - error.SetErrorString ("Zero is an invalid line number."); - m_type = eLookupTypeFileLine; - break; - - case 'n': - m_str = option_arg; - m_type = eLookupTypeFunction; - break; - - case 't': - m_str = option_arg; - m_type = eLookupTypeType; - break; - - case 'v': - m_verbose = 1; - break; - - case 'r': - m_use_regex = true; - break; - } - - return error; - } - - void - OptionParsingStarting () - { - m_type = eLookupTypeInvalid; - m_str.clear(); - m_file.Clear(); - m_addr = LLDB_INVALID_ADDRESS; - m_offset = 0; - m_line_number = 0; - m_use_regex = false; - m_check_inlines = true; - m_verbose = false; - } - - const OptionDefinition* - GetDefinitions () - { - return g_option_table; - } - - // Options table: Required for subclasses of Options. - - static OptionDefinition g_option_table[]; - int m_type; // Should be a eLookupTypeXXX enum after parsing options - std::string m_str; // Holds name lookup - FileSpec m_file; // Files for file lookups - lldb::addr_t m_addr; // Holds the address to lookup - lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. - uint32_t m_line_number; // Line number for file+line lookups - bool m_use_regex; // Name lookups in m_str are regular expressions. - bool m_check_inlines;// Check for inline entries when looking up by file/line. - bool m_verbose; // Enable verbose lookup info - - }; - - CommandObjectImageLookup (CommandInterpreter &interpreter) : - CommandObject (interpreter, - "image lookup", - "Look up information within executable and dependent shared library images.", - NULL), - m_options (interpreter) - { - CommandArgumentEntry arg; - CommandArgumentData file_arg; - - // Define the first (and only) variant of this arg. - file_arg.arg_type = eArgTypeFilename; - file_arg.arg_repetition = eArgRepeatStar; - - // There is only one variant this argument could be; put it into the argument entry. - arg.push_back (file_arg); - - // Push the data for the first argument into the m_arguments vector. - m_arguments.push_back (arg); - } - - virtual - ~CommandObjectImageLookup () - { - } - - virtual Options * - GetOptions () - { - return &m_options; - } - - - bool - LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) - { - switch (m_options.m_type) - { - case eLookupTypeAddress: - if (m_options.m_addr != LLDB_INVALID_ADDRESS) - { - if (LookupAddressInModule (m_interpreter, - result.GetOutputStream(), - module, - eSymbolContextEverything, - m_options.m_addr, - m_options.m_offset, - m_options.m_verbose)) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - } - break; - - case eLookupTypeSymbol: - if (!m_options.m_str.empty()) - { - if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex)) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - } - break; - - case eLookupTypeFileLine: - if (m_options.m_file) - { - - if (LookupFileAndLineInModule (m_interpreter, - result.GetOutputStream(), - module, - m_options.m_file, - m_options.m_line_number, - m_options.m_check_inlines, - m_options.m_verbose)) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - } - break; - - case eLookupTypeFunction: - if (!m_options.m_str.empty()) - { - if (LookupFunctionInModule (m_interpreter, - result.GetOutputStream(), - module, - m_options.m_str.c_str(), - m_options.m_use_regex, - m_options.m_verbose)) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - } - break; - - case eLookupTypeType: - if (!m_options.m_str.empty()) - { - if (LookupTypeInModule (m_interpreter, - result.GetOutputStream(), - module, - m_options.m_str.c_str(), - m_options.m_use_regex)) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - } - break; - - default: - m_options.GenerateOptionUsage (result.GetErrorStream(), this); - syntax_error = true; - break; - } - - result.SetStatus (eReturnStatusFailed); - return false; - } - - virtual bool - Execute (Args& command, - CommandReturnObject &result) - { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - bool syntax_error = false; - uint32_t i; - uint32_t num_successful_lookups = 0; - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - // Dump all sections for all modules images - - if (command.GetArgumentCount() == 0) - { - // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - for (i = 0; iGetImages().GetModulePointerAtIndex(i), result, syntax_error)) - { - result.GetOutputStream().EOL(); - num_successful_lookups++; - } - } - } - else - { - result.AppendError ("the target has no associated executable images"); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - else - { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) - { - FileSpec image_file(arg_cstr, false); - ModuleList matching_modules; - size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); - - // Not found in our module list for our target, check the main - // shared module list in case it is a extra file used somewhere - // else - if (num_matching_modules == 0) - num_matching_modules = ModuleList::FindSharedModules (image_file, - target->GetArchitecture(), - NULL, - NULL, - matching_modules); - - if (num_matching_modules > 0) - { - for (size_t j=0; j 0) - result.SetStatus (eReturnStatusSuccessFinishResult); - else - result.SetStatus (eReturnStatusFailed); - } - return result.Succeeded(); - } -protected: - - CommandOptions m_options; -}; - -OptionDefinition -CommandObjectImageLookup::CommandOptions::g_option_table[] = -{ -{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more executable images."}, -{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "When looking up an address subtract from any addresses before doing the lookup."}, -{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more executable images."}, -{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The argument for name lookups are regular expressions."}, -{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more executable images."}, -{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."}, -{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."}, -{ LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more executable images."}, -{ LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more executable images."}, -{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } -}; - - - - - -//---------------------------------------------------------------------- -// CommandObjectImage constructor -//---------------------------------------------------------------------- -CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "image", - "A set of commands for accessing information for one or more executable images.", - "image ...") -{ - LoadSubCommand ("dump", CommandObjectSP (new CommandObjectImageDump (interpreter))); - LoadSubCommand ("list", CommandObjectSP (new CommandObjectImageList (interpreter))); - LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectImageLookup (interpreter))); -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CommandObjectImage::~CommandObjectImage() -{ -} - Removed: lldb/trunk/source/Commands/CommandObjectImage.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.h?rev=130795&view=auto ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.h (original) +++ lldb/trunk/source/Commands/CommandObjectImage.h (removed) @@ -1,45 +0,0 @@ -//===-- CommandObjectImage.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_CommandObjectImage_h_ -#define liblldb_CommandObjectImage_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObjectMultiword.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectImage -//------------------------------------------------------------------------- - -class CommandObjectImage : public CommandObjectMultiword -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CommandObjectImage(CommandInterpreter &interpreter); - - virtual - ~CommandObjectImage(); - -private: - //------------------------------------------------------------------ - // For CommandObjectImage only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (CommandObjectImage); -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectImage_h_ Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Tue May 3 17:09:39 2011 @@ -155,7 +155,7 @@ if (target == NULL) { - result.AppendError ("invalid target, set executable file using 'file' command"); + result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } @@ -166,7 +166,7 @@ if (exe_module == NULL) { - result.AppendError ("no file in target, set executable file using 'file' command"); + result.AppendError ("no file in target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } Modified: lldb/trunk/source/Commands/CommandObjectSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSource.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSource.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSource.cpp Tue May 3 17:09:39 2011 @@ -287,7 +287,7 @@ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { - result.AppendError ("invalid target, set executable file using 'file' command"); + result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } @@ -491,7 +491,7 @@ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { - result.AppendError ("invalid target, set executable file using 'file' command"); + result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Tue May 3 17:09:39 2011 @@ -18,12 +18,21 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/InputReader.h" +#include "lldb/Core/Section.h" #include "lldb/Core/State.h" #include "lldb/Core/Timer.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/OptionGroupArchitecture.h" +#include "lldb/Interpreter/OptionGroupFile.h" #include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Interpreter/OptionGroupUInt64.h" +#include "lldb/Interpreter/OptionGroupUUID.h" +#include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" @@ -388,15 +397,15 @@ }; -#pragma mark CommandObjectTargetImageSearchPaths +#pragma mark CommandObjectTargetModulesSearchPathsAdd -class CommandObjectTargetImageSearchPathsAdd : public CommandObject +class CommandObjectTargetModulesSearchPathsAdd : public CommandObject { public: - CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) : + CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : CommandObject (interpreter, - "target image-search-paths add", + "target modules search-paths add", "Add new image search paths substitution pairs to the current target.", NULL) { @@ -422,7 +431,7 @@ m_arguments.push_back (arg); } - ~CommandObjectTargetImageSearchPathsAdd () + ~CommandObjectTargetModulesSearchPathsAdd () { } @@ -474,19 +483,21 @@ } }; -class CommandObjectTargetImageSearchPathsClear : public CommandObject +#pragma mark CommandObjectTargetModulesSearchPathsClear + +class CommandObjectTargetModulesSearchPathsClear : public CommandObject { public: - CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) : + CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : CommandObject (interpreter, - "target image-search-paths clear", + "target modules search-paths clear", "Clear all current image search path substitution pairs from the current target.", - "target image-search-paths clear") + "target modules search-paths clear") { } - ~CommandObjectTargetImageSearchPathsClear () + ~CommandObjectTargetModulesSearchPathsClear () { } @@ -510,13 +521,15 @@ } }; -class CommandObjectTargetImageSearchPathsInsert : public CommandObject +#pragma mark CommandObjectTargetModulesSearchPathsInsert + +class CommandObjectTargetModulesSearchPathsInsert : public CommandObject { public: - CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) : + CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : CommandObject (interpreter, - "target image-search-paths insert", + "target modules search-paths insert", "Insert a new image search path substitution pair into the current target at the specified index.", NULL) { @@ -553,7 +566,7 @@ m_arguments.push_back (arg2); } - ~CommandObjectTargetImageSearchPathsInsert () + ~CommandObjectTargetModulesSearchPathsInsert () { } @@ -625,19 +638,23 @@ } }; -class CommandObjectTargetImageSearchPathsList : public CommandObject + +#pragma mark CommandObjectTargetModulesSearchPathsList + + +class CommandObjectTargetModulesSearchPathsList : public CommandObject { public: - CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) : + CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : CommandObject (interpreter, - "target image-search-paths list", + "target modules search-paths list", "List all current image search path substitution pairs in the current target.", - "target image-search-paths list") + "target modules search-paths list") { } - ~CommandObjectTargetImageSearchPathsList () + ~CommandObjectTargetModulesSearchPathsList () { } @@ -667,13 +684,15 @@ } }; -class CommandObjectTargetImageSearchPathsQuery : public CommandObject +#pragma mark CommandObjectTargetModulesSearchPathsQuery + +class CommandObjectTargetModulesSearchPathsQuery : public CommandObject { public: - CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) : + CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : CommandObject (interpreter, - "target image-search-paths query", + "target modules search-paths query", "Transform a path using the first applicable image search path.", NULL) { @@ -691,7 +710,7 @@ m_arguments.push_back (arg); } - ~CommandObjectTargetImageSearchPathsQuery () + ~CommandObjectTargetModulesSearchPathsQuery () { } @@ -727,114 +746,2150 @@ } }; -// TODO: implement the target select later when we start doing multiple targets -//#pragma mark CommandObjectTargetSelect -// -////------------------------------------------------------------------------- -//// CommandObjectTargetSelect -////------------------------------------------------------------------------- -// -//class CommandObjectTargetSelect : public CommandObject -//{ -//public: -// -// CommandObjectTargetSelect () : -// CommandObject (interpreter, -// frame select", -// "Select the current frame by index in the current thread.", -// "frame select ") -// { -// } -// -// ~CommandObjectTargetSelect () -// { -// } -// -// bool -// Execute (Args& command, -// Debugger *context, -// CommandInterpreter &m_interpreter, -// CommandReturnObject &result) -// { -// ExecutionContext exe_ctx (context->GetExecutionContext()); -// if (exe_ctx.thread) -// { -// if (command.GetArgumentCount() == 1) -// { -// const char *frame_idx_cstr = command.GetArgumentAtIndex(0); -// -// const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount(); -// const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); -// if (frame_idx < num_frames) -// { -// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx); -// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get(); -// -// if (exe_ctx.frame) -// { -// if (DisplayFrameForExecutionContext (exe_ctx.thread, -// exe_ctx.frame, -// m_interpreter, -// result.GetOutputStream(), -// true, -// true, -// 3, -// 3)) -// { -// result.SetStatus (eReturnStatusSuccessFinishResult); -// return result.Succeeded(); -// } -// } -// } -// if (frame_idx == UINT32_MAX) -// result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr); -// else -// result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx); -// } -// else -// { -// result.AppendError ("invalid arguments"); -// result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str()); -// } -// } -// else -// { -// result.AppendError ("no current thread"); -// } -// result.SetStatus (eReturnStatusFailed); -// return false; -// } -//}; +//---------------------------------------------------------------------- +// Static Helper functions +//---------------------------------------------------------------------- +static void +DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) +{ + if (module) + { + const char *arch_cstr; + if (full_triple) + arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); + else + arch_cstr = module->GetArchitecture().GetArchitectureName(); + if (width) + strm.Printf("%-*s", width, arch_cstr); + else + strm.PutCString(arch_cstr); + } +} +static void +DumpModuleUUID (Stream &strm, Module *module) +{ + module->GetUUID().Dump (&strm); +} -#pragma mark CommandObjectMultiwordImageSearchPaths +static uint32_t +DumpCompileUnitLineTable +( + CommandInterpreter &interpreter, + Stream &strm, + Module *module, + const FileSpec &file_spec, + bool load_addresses + ) +{ + uint32_t num_matches = 0; + if (module) + { + SymbolContextList sc_list; + num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, + 0, + false, + eSymbolContextCompUnit, + sc_list); + + for (uint32_t i=0; i 0) + strm << "\n\n"; + + strm << "Line table for " << *static_cast (sc.comp_unit) << " in `" + << module->GetFileSpec().GetFilename() << "\n"; + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table) + line_table->GetDescription (&strm, + interpreter.GetExecutionContext().target, + lldb::eDescriptionLevelBrief); + else + strm << "No line table"; + } + } + } + return num_matches; +} -//------------------------------------------------------------------------- -// CommandObjectMultiwordImageSearchPaths -//------------------------------------------------------------------------- +static void +DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) +{ + if (file_spec_ptr) + { + if (width > 0) + { + char fullpath[PATH_MAX]; + if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath))) + { + strm.Printf("%-*s", width, fullpath); + return; + } + } + else + { + file_spec_ptr->Dump(&strm); + return; + } + } + // Keep the width spacing correct if things go wrong... + if (width > 0) + strm.Printf("%-*s", width, ""); +} + +static void +DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) +{ + if (file_spec_ptr) + { + if (width > 0) + strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); + else + file_spec_ptr->GetDirectory().Dump(&strm); + return; + } + // Keep the width spacing correct if things go wrong... + if (width > 0) + strm.Printf("%-*s", width, ""); +} -class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword +static void +DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) { -public: + if (file_spec_ptr) + { + if (width > 0) + strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); + else + file_spec_ptr->GetFilename().Dump(&strm); + return; + } + // Keep the width spacing correct if things go wrong... + if (width > 0) + strm.Printf("%-*s", width, ""); +} - CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "target image-search-paths", - "A set of commands for operating on debugger target image search paths.", - "target image-search-paths []") - { - LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter))); - LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter))); - LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter))); - LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter))); - LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter))); + +static void +DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) +{ + if (module) + { + ObjectFile *objfile = module->GetObjectFile (); + if (objfile) + { + Symtab *symtab = objfile->GetSymtab(); + if (symtab) + symtab->Dump(&strm, interpreter.GetExecutionContext().target, sort_order); + } + } +} + +static void +DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) +{ + if (module) + { + ObjectFile *objfile = module->GetObjectFile (); + if (objfile) + { + SectionList *section_list = objfile->GetSectionList(); + if (section_list) + { + strm.PutCString ("Sections for '"); + strm << module->GetFileSpec(); + if (module->GetObjectName()) + strm << '(' << module->GetObjectName() << ')'; + strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName()); + strm.IndentMore(); + section_list->Dump(&strm, interpreter.GetExecutionContext().target, true, UINT32_MAX); + strm.IndentLess(); + } + } + } +} + +static bool +DumpModuleSymbolVendor (Stream &strm, Module *module) +{ + if (module) + { + SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); + if (symbol_vendor) + { + symbol_vendor->Dump(&strm); + return true; + } + } + return false; +} + +static bool +LookupAddressInModule +( + CommandInterpreter &interpreter, + Stream &strm, + Module *module, + uint32_t resolve_mask, + lldb::addr_t raw_addr, + lldb::addr_t offset, + bool verbose + ) +{ + if (module) + { + lldb::addr_t addr = raw_addr - offset; + Address so_addr; + SymbolContext sc; + Target *target = interpreter.GetExecutionContext().target; + if (target && !target->GetSectionLoadList().IsEmpty()) + { + if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) + return false; + else if (so_addr.GetModule() != module) + return false; + } + else + { + if (!module->ResolveFileAddress (addr, so_addr)) + return false; + } + + // If an offset was given, print out the address we ended up looking up + if (offset) + strm.Printf("File Address: 0x%llx\n", addr); + + ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); + strm.IndentMore(); + strm.Indent (" Address: "); + so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); + strm.EOL(); + strm.Indent (" Summary: "); + const uint32_t save_indent = strm.GetIndentLevel (); + strm.SetIndentLevel (save_indent + 11); + so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); + strm.SetIndentLevel (save_indent); + strm.EOL(); + // Print out detailed address information when verbose is enabled + if (verbose) + { + if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext)) + strm.EOL(); + } + strm.IndentLess(); + return true; + } + + return false; +} + +static uint32_t +LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex) +{ + if (module) + { + SymbolContext sc; + + ObjectFile *objfile = module->GetObjectFile (); + if (objfile) + { + Symtab *symtab = objfile->GetSymtab(); + if (symtab) + { + uint32_t i; + std::vector match_indexes; + ConstString symbol_name (name); + uint32_t num_matches = 0; + if (name_is_regex) + { + RegularExpression name_regexp(name); + num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, + eSymbolTypeAny, + match_indexes); + } + else + { + num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); + } + + + if (num_matches > 0) + { + strm.Indent (); + strm.Printf("%u symbols match %s'%s' in ", num_matches, + name_is_regex ? "the regular expression " : "", name); + DumpFullpath (strm, &module->GetFileSpec(), 0); + strm.PutCString(":\n"); + strm.IndentMore (); + Symtab::DumpSymbolHeader (&strm); + for (i=0; i < num_matches; ++i) + { + Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); + strm.Indent (); + symbol->Dump (&strm, interpreter.GetExecutionContext().target, i); + } + strm.IndentLess (); + return num_matches; + } + } + } + } + return 0; +} + + +static void +DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose) +{ + strm.IndentMore (); + uint32_t i; + const uint32_t num_matches = sc_list.GetSize(); + + for (i=0; iGetAddressRange().GetBaseAddress().IsValid()) + { + if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm, + exe_scope, + Address::DumpStyleDetailedSymbolContext)) + strm.PutCString("\n\n"); + } + } + } + } + strm.IndentLess (); +} + +static uint32_t +LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) +{ + if (module && name && name[0]) + { + SymbolContextList sc_list; + const bool include_symbols = false; + const bool append = true; + uint32_t num_matches = 0; + if (name_is_regex) + { + RegularExpression function_name_regex (name); + num_matches = module->FindFunctions (function_name_regex, + include_symbols, + append, + sc_list); + } + else + { + ConstString function_name (name); + num_matches = module->FindFunctions (function_name, + eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, + include_symbols, + append, + sc_list); + } + + if (num_matches) + { + strm.Indent (); + strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); + DumpFullpath (strm, &module->GetFileSpec(), 0); + strm.PutCString(":\n"); + DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); + } + return num_matches; + } + return 0; +} + +static uint32_t +LookupTypeInModule +( + CommandInterpreter &interpreter, + Stream &strm, + Module *module, + const char *name_cstr, + bool name_is_regex + ) +{ + if (module && name_cstr && name_cstr[0]) + { + SymbolContextList sc_list; + + SymbolVendor *symbol_vendor = module->GetSymbolVendor(); + if (symbol_vendor) + { + TypeList type_list; + uint32_t num_matches = 0; + SymbolContext sc; + // if (name_is_regex) + // { + // RegularExpression name_regex (name_cstr); + // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list); + // } + // else + // { + ConstString name(name_cstr); + num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list); + // } + + if (num_matches) + { + strm.Indent (); + strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); + DumpFullpath (strm, &module->GetFileSpec(), 0); + strm.PutCString(":\n"); + const uint32_t num_types = type_list.GetSize(); + for (uint32_t i=0; iGetClangFullType (); + type_sp->GetDescription (&strm, eDescriptionLevelFull, true); + } + strm.EOL(); + } + } + return num_matches; + } + } + return 0; +} + +static uint32_t +LookupFileAndLineInModule (CommandInterpreter &interpreter, + Stream &strm, + Module *module, + const FileSpec &file_spec, + uint32_t line, + bool check_inlines, + bool verbose) +{ + if (module && file_spec) + { + SymbolContextList sc_list; + const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, + eSymbolContextEverything, sc_list); + if (num_matches > 0) + { + strm.Indent (); + strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); + strm << file_spec; + if (line > 0) + strm.Printf (":%u", line); + strm << " in "; + DumpFullpath (strm, &module->GetFileSpec(), 0); + strm.PutCString(":\n"); + DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); + return num_matches; + } } + return 0; + +} + +#pragma mark CommandObjectTargetModulesModuleAutoComplete + +//---------------------------------------------------------------------- +// A base command object class that can auto complete with module file +// paths +//---------------------------------------------------------------------- - ~CommandObjectMultiwordImageSearchPaths() +class CommandObjectTargetModulesModuleAutoComplete : public CommandObject +{ +public: + + CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, + const char *name, + const char *help, + const char *syntax) : + CommandObject (interpreter, name, help, syntax) + { + CommandArgumentEntry arg; + CommandArgumentData file_arg; + + // Define the first (and only) variant of this arg. + file_arg.arg_type = eArgTypeFilename; + file_arg.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (file_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + virtual + ~CommandObjectTargetModulesModuleAutoComplete () + { + } + + virtual int + HandleArgumentCompletion (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) { + // Arguments are the standard module completer. + std::string completion_str (input.GetArgumentAtIndex(cursor_index)); + completion_str.erase (cursor_char_position); + + CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, + CommandCompletions::eModuleCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); } }; +#pragma mark CommandObjectTargetModulesSourceFileAutoComplete + +//---------------------------------------------------------------------- +// A base command object class that can auto complete with module source +// file paths +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject +{ +public: + + CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, + const char *name, + const char *help, + const char *syntax) : + CommandObject (interpreter, name, help, syntax) + { + CommandArgumentEntry arg; + CommandArgumentData source_file_arg; + + // Define the first (and only) variant of this arg. + source_file_arg.arg_type = eArgTypeSourceFile; + source_file_arg.arg_repetition = eArgRepeatPlus; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (source_file_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + virtual + ~CommandObjectTargetModulesSourceFileAutoComplete () + { + } + + virtual int + HandleArgumentCompletion (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) + { + // Arguments are the standard source file completer. + std::string completion_str (input.GetArgumentAtIndex(cursor_index)); + completion_str.erase (cursor_char_position); + + CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, + CommandCompletions::eSourceFileCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); + } +}; + + +#pragma mark CommandObjectTargetModulesDumpSymtab + + +class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete +{ +public: + CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : + CommandObjectTargetModulesModuleAutoComplete (interpreter, + "target modules dump symtab", + "Dump the symbol table from one or more target modules.", + NULL), + m_options (interpreter) + { + } + + virtual + ~CommandObjectTargetModulesDumpSymtab () + { + } + + virtual bool + Execute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + uint32_t num_dumped = 0; + + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + + if (command.GetArgumentCount() == 0) + { + // Dump all sections for all modules images + const uint32_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) + { + result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); + for (uint32_t image_idx = 0; image_idx 0) + { + result.GetOutputStream().EOL(); + result.GetOutputStream().EOL(); + } + num_dumped++; + DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order); + } + } + else + { + result.AppendError ("the target has no associated executable images"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) + { + FileSpec image_file(arg_cstr, false); + ModuleList matching_modules; + size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); + + // Not found in our module list for our target, check the main + // shared module list in case it is a extra file used somewhere + // else + if (num_matching_modules == 0) + num_matching_modules = ModuleList::FindSharedModules (image_file, + target->GetArchitecture(), + NULL, + NULL, + matching_modules); + + if (num_matching_modules > 0) + { + for (size_t i=0; i 0) + { + result.GetOutputStream().EOL(); + result.GetOutputStream().EOL(); + } + num_dumped++; + DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order); + } + } + } + else + result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); + } + } + + if (num_dumped > 0) + result.SetStatus (eReturnStatusSuccessFinishResult); + else + { + result.AppendError ("no matching executable images found"); + result.SetStatus (eReturnStatusFailed); + } + } + return result.Succeeded(); + } + + virtual Options * + GetOptions () + { + return &m_options; + } + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options(interpreter), + m_sort_order (eSortOrderNone) + { + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 's': + { + bool found_one = false; + m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, + g_option_table[option_idx].enum_values, + eSortOrderNone, + &found_one); + if (!found_one) + error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n", + option_arg, + short_option); + } + break; + + default: + error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); + break; + + } + return error; + } + + void + OptionParsingStarting () + { + m_sort_order = eSortOrderNone; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + static OptionDefinition g_option_table[]; + + SortOrder m_sort_order; + }; + +protected: + + CommandOptions m_options; +}; + +static OptionEnumValueElement +g_sort_option_enumeration[4] = +{ + { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, + { eSortOrderByAddress, "address", "Sort output by symbol address."}, + { eSortOrderByName, "name", "Sort output by symbol name."}, + { 0, NULL, NULL } +}; + + +OptionDefinition +CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + +#pragma mark CommandObjectTargetModulesDumpSections + +//---------------------------------------------------------------------- +// Image section dumping command +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete +{ +public: + CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : + CommandObjectTargetModulesModuleAutoComplete (interpreter, + "target modules dump sections", + "Dump the sections from one or more target modules.", + //"target modules dump sections [ ...]") + NULL) + { + } + + virtual + ~CommandObjectTargetModulesDumpSections () + { + } + + virtual bool + Execute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + uint32_t num_dumped = 0; + + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + + if (command.GetArgumentCount() == 0) + { + // Dump all sections for all modules images + const uint32_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) + { + result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); + for (uint32_t image_idx = 0; image_idxGetImages().GetModulePointerAtIndex(image_idx)); + } + } + else + { + result.AppendError ("the target has no associated executable images"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) + { + FileSpec image_file(arg_cstr, false); + ModuleList matching_modules; + size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); + + // Not found in our module list for our target, check the main + // shared module list in case it is a extra file used somewhere + // else + if (num_matching_modules == 0) + num_matching_modules = ModuleList::FindSharedModules (image_file, + target->GetArchitecture(), + NULL, + NULL, + matching_modules); + + if (num_matching_modules > 0) + { + for (size_t i=0; i 0) + result.SetStatus (eReturnStatusSuccessFinishResult); + else + { + result.AppendError ("no matching executable images found"); + result.SetStatus (eReturnStatusFailed); + } + } + return result.Succeeded(); + } +}; + + +#pragma mark CommandObjectTargetModulesDumpSymfile + +//---------------------------------------------------------------------- +// Image debug symbol dumping command +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete +{ +public: + CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : + CommandObjectTargetModulesModuleAutoComplete (interpreter, + "target modules dump symfile", + "Dump the debug symbol file for one or more target modules.", + //"target modules dump symfile [ ...]") + NULL) + { + } + + virtual + ~CommandObjectTargetModulesDumpSymfile () + { + } + + virtual bool + Execute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + uint32_t num_dumped = 0; + + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + + if (command.GetArgumentCount() == 0) + { + // Dump all sections for all modules images + const uint32_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) + { + result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); + for (uint32_t image_idx = 0; image_idxGetImages().GetModulePointerAtIndex(image_idx))) + num_dumped++; + } + } + else + { + result.AppendError ("the target has no associated executable images"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) + { + FileSpec image_file(arg_cstr, false); + ModuleList matching_modules; + size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); + + // Not found in our module list for our target, check the main + // shared module list in case it is a extra file used somewhere + // else + if (num_matching_modules == 0) + num_matching_modules = ModuleList::FindSharedModules (image_file, + target->GetArchitecture(), + NULL, + NULL, + matching_modules); + + if (num_matching_modules > 0) + { + for (size_t i=0; i 0) + result.SetStatus (eReturnStatusSuccessFinishResult); + else + { + result.AppendError ("no matching executable images found"); + result.SetStatus (eReturnStatusFailed); + } + } + return result.Succeeded(); + } +}; + + +#pragma mark CommandObjectTargetModulesDumpLineTable + +//---------------------------------------------------------------------- +// Image debug line table dumping command +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete +{ +public: + CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : + CommandObjectTargetModulesSourceFileAutoComplete (interpreter, + "target modules dump line-table", + "Dump the debug symbol file for one or more target modules.", + NULL) + { + } + + virtual + ~CommandObjectTargetModulesDumpLineTable () + { + } + + virtual bool + Execute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + uint32_t total_num_dumped = 0; + + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + + if (command.GetArgumentCount() == 0) + { + result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); + result.SetStatus (eReturnStatusFailed); + } + else + { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) + { + FileSpec file_spec(arg_cstr, false); + const uint32_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) + { + uint32_t num_dumped = 0; + for (uint32_t i = 0; iGetImages().GetModulePointerAtIndex(i), + file_spec, + exe_ctx.process != NULL && exe_ctx.process->IsAlive())) + num_dumped++; + } + if (num_dumped == 0) + result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); + else + total_num_dumped += num_dumped; + } + } + } + + if (total_num_dumped > 0) + result.SetStatus (eReturnStatusSuccessFinishResult); + else + { + result.AppendError ("no source filenames matched any command arguments"); + result.SetStatus (eReturnStatusFailed); + } + } + return result.Succeeded(); + } +}; + + +#pragma mark CommandObjectTargetModulesDump + +//---------------------------------------------------------------------- +// Dump multi-word command for target modules +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesDump : public CommandObjectMultiword +{ +public: + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "target modules dump", + "A set of commands for dumping information about one or more target modules.", + "target modules dump [symtab|sections|symfile|line-table] [ ...]") + { + LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); + LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); + LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); + LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); + } + + virtual + ~CommandObjectTargetModulesDump() + { + } +}; + +class CommandObjectTargetModulesAdd : public CommandObject +{ +public: + CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "target modules add", + "Add a new module to the current target's modules.", + "target modules add []") + { + } + + virtual + ~CommandObjectTargetModulesAdd () + { + } + + virtual bool + Execute (Args& args, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + const size_t argc = args.GetArgumentCount(); + if (argc == 0) + { + result.AppendError ("one or more executable image paths must be specified"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + for (size_t i=0; iGetSharedModule(file_spec, arch)); + if (!module_sp) + { + result.AppendError ("one or more executable image paths must be specified"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + char resolved_path[PATH_MAX]; + result.SetStatus (eReturnStatusFailed); + if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) + { + if (strcmp (resolved_path, path) != 0) + { + result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); + break; + } + } + result.AppendErrorWithFormat ("invalid module path '%s'\n", path); + break; + } + } + } + } + } + return result.Succeeded(); + } + + int + HandleArgumentCompletion (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 (m_interpreter, + CommandCompletions::eDiskFileCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); + } + +}; + +class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete +{ +public: + CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : + CommandObjectTargetModulesModuleAutoComplete (interpreter, + "target modules load", + "Set the load addresses for one or more sections in a target module.", + "target modules load [--file --uuid ]
[
....]"), + m_option_group (interpreter), + m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."), + m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0) + { + m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); + } + + virtual + ~CommandObjectTargetModulesLoad () + { + } + + virtual bool + Execute (Args& args, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + const size_t argc = args.GetArgumentCount(); + const FileSpec *file_ptr = NULL; + const UUID *uuid_ptr = NULL; + if (m_file_option.GetOptionValue().OptionWasSet()) + file_ptr = &m_file_option.GetOptionValue().GetCurrentValue(); + + if (m_uuid_option_group.GetOptionValue().OptionWasSet()) + uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue(); + + if (file_ptr || uuid_ptr) + { + + ModuleList matching_modules; + const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only) + NULL, // Architecture + uuid_ptr, // UUID to match (can be NULL to not match on UUID) + NULL, // Object name + matching_modules); + + char path[PATH_MAX]; + if (num_matches == 1) + { + Module *module = matching_modules.GetModulePointerAtIndex(0); + if (module) + { + ObjectFile *objfile = module->GetObjectFile(); + if (objfile) + { + SectionList *section_list = objfile->GetSectionList(); + if (section_list) + { + if (argc == 0) + { + if (m_slide_option.GetOptionValue().OptionWasSet()) + { + Module *module = matching_modules.GetModulePointerAtIndex(0); + if (module) + { + ObjectFile *objfile = module->GetObjectFile(); + if (objfile) + { + SectionList *section_list = objfile->GetSectionList(); + if (section_list) + { + const size_t num_sections = section_list->GetSize(); + const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); + for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) + { + SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); + if (section_sp) + target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide); + } + } + } + } + } + else + { + result.AppendError ("one or more section name + load address pair must be specified"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + if (m_slide_option.GetOptionValue().OptionWasSet()) + { + result.AppendError ("The \"--slide \" option can't be used in conjunction with setting section load addresses.\n"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + for (size_t i=0; iFindSectionByName(const_sect_name)); + if (section_sp) + { + target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr); + result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); + } + else + { + result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); + result.SetStatus (eReturnStatusFailed); + break; + } + } + else + { + result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); + result.SetStatus (eReturnStatusFailed); + break; + } + } + else + { + if (sect_name) + result.AppendError ("section names must be followed by a load address.\n"); + else + result.AppendError ("one or more section name + load address pair must be specified.\n"); + result.SetStatus (eReturnStatusFailed); + break; + } + } + } + } + else + { + module->GetFileSpec().GetPath (path, sizeof(path)); + result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + module->GetFileSpec().GetPath (path, sizeof(path)); + result.AppendErrorWithFormat ("no object file for module '%s'\n", path); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + module->GetFileSpec().GetPath (path, sizeof(path)); + result.AppendErrorWithFormat ("invalid module '%s'.\n", path); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + char uuid_cstr[64]; + if (file_ptr) + file_ptr->GetPath (path, sizeof(path)); + else + path[0] = '\0'; + + if (uuid_ptr) + uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr)); + else + uuid_cstr[0] = '\0'; + if (num_matches > 1) + { + result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", + path[0] ? " file=" : "", + path, + uuid_cstr[0] ? " uuid=" : "", + uuid_cstr); + for (size_t i=0; iGetFileSpec().GetPath (path, sizeof(path))) + result.AppendMessageWithFormat("%s\n", path); + } + } + else + { + result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", + path[0] ? " file=" : "", + path, + uuid_cstr[0] ? " uuid=" : "", + uuid_cstr); + } + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("either the \"--file \" or the \"--uuid \" option must be specified.\n"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + return result.Succeeded(); + } + + virtual Options * + GetOptions () + { + return &m_option_group; + } + +protected: + OptionGroupOptions m_option_group; + OptionGroupUUID m_uuid_option_group; + OptionGroupFile m_file_option; + OptionGroupUInt64 m_slide_option; +}; + +//---------------------------------------------------------------------- +// List images with associated information +//---------------------------------------------------------------------- +class CommandObjectTargetModulesList : public CommandObject +{ +public: + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options(interpreter), + m_format_array() + { + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + char short_option = (char) m_getopt_table[option_idx].val; + uint32_t width = 0; + if (option_arg) + width = strtoul (option_arg, NULL, 0); + m_format_array.push_back(std::make_pair(short_option, width)); + Error error; + return error; + } + + void + OptionParsingStarting () + { + m_format_array.clear(); + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + typedef std::vector< std::pair > FormatWidthCollection; + FormatWidthCollection m_format_array; + }; + + CommandObjectTargetModulesList (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "target modules list", + "List current executable and dependent shared library images.", + "target modules list []"), + m_options (interpreter) + { + } + + virtual + ~CommandObjectTargetModulesList () + { + } + + virtual + Options * + GetOptions () + { + return &m_options; + } + + virtual bool + Execute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + // Dump all sections for all modules images + const uint32_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) + { + Stream &strm = result.GetOutputStream(); + + for (uint32_t image_idx = 0; image_idxGetImages().GetModulePointerAtIndex(image_idx); + strm.Printf("[%3u] ", image_idx); + + bool dump_object_name = false; + if (m_options.m_format_array.empty()) + { + DumpFullpath(strm, &module->GetFileSpec(), 0); + dump_object_name = true; + } + else + { + const size_t num_entries = m_options.m_format_array.size(); + for (size_t i=0; i 0) + strm.PutChar(' '); + char format_char = m_options.m_format_array[i].first; + uint32_t width = m_options.m_format_array[i].second; + switch (format_char) + { + case 'a': + DumpModuleArchitecture (strm, module, false, width); + break; + + case 't': + DumpModuleArchitecture (strm, module, true, width); + break; + + case 'f': + DumpFullpath (strm, &module->GetFileSpec(), width); + dump_object_name = true; + break; + + case 'd': + DumpDirectory (strm, &module->GetFileSpec(), width); + break; + + case 'b': + DumpBasename (strm, &module->GetFileSpec(), width); + dump_object_name = true; + break; + + case 's': + case 'S': + { + SymbolVendor *symbol_vendor = module->GetSymbolVendor(); + if (symbol_vendor) + { + SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); + if (symbol_file) + { + if (format_char == 'S') + DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); + else + DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); + dump_object_name = true; + break; + } + } + strm.Printf("%.*s", width, ""); + } + break; + + case 'u': + DumpModuleUUID(strm, module); + break; + + default: + break; + } + + } + } + if (dump_object_name) + { + const char *object_name = module->GetObjectName().GetCString(); + if (object_name) + strm.Printf ("(%s)", object_name); + } + strm.EOL(); + } + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendError ("the target has no associated executable images"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + return result.Succeeded(); + } +protected: + + CommandOptions m_options; +}; + +OptionDefinition +CommandObjectTargetModulesList::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, + { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, + { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, + { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, + { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, + { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, + { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, + { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + + + +//---------------------------------------------------------------------- +// Lookup information in images +//---------------------------------------------------------------------- +class CommandObjectTargetModulesLookup : public CommandObject +{ +public: + + enum + { + eLookupTypeInvalid = -1, + eLookupTypeAddress = 0, + eLookupTypeSymbol, + eLookupTypeFileLine, // Line is optional + eLookupTypeFunction, + eLookupTypeType, + kNumLookupTypes + }; + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options(interpreter) + { + OptionParsingStarting(); + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'a': + m_type = eLookupTypeAddress; + m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); + if (m_addr == LLDB_INVALID_ADDRESS) + error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg); + break; + + case 'o': + m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); + if (m_offset == LLDB_INVALID_ADDRESS) + error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg); + break; + + case 's': + m_str = option_arg; + m_type = eLookupTypeSymbol; + break; + + case 'f': + m_file.SetFile (option_arg, false); + m_type = eLookupTypeFileLine; + break; + + case 'i': + m_check_inlines = false; + break; + + case 'l': + m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); + if (m_line_number == UINT32_MAX) + error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg); + else if (m_line_number == 0) + error.SetErrorString ("Zero is an invalid line number."); + m_type = eLookupTypeFileLine; + break; + + case 'n': + m_str = option_arg; + m_type = eLookupTypeFunction; + break; + + case 't': + m_str = option_arg; + m_type = eLookupTypeType; + break; + + case 'v': + m_verbose = 1; + break; + + case 'r': + m_use_regex = true; + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_type = eLookupTypeInvalid; + m_str.clear(); + m_file.Clear(); + m_addr = LLDB_INVALID_ADDRESS; + m_offset = 0; + m_line_number = 0; + m_use_regex = false; + m_check_inlines = true; + m_verbose = false; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + int m_type; // Should be a eLookupTypeXXX enum after parsing options + std::string m_str; // Holds name lookup + FileSpec m_file; // Files for file lookups + lldb::addr_t m_addr; // Holds the address to lookup + lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. + uint32_t m_line_number; // Line number for file+line lookups + bool m_use_regex; // Name lookups in m_str are regular expressions. + bool m_check_inlines;// Check for inline entries when looking up by file/line. + bool m_verbose; // Enable verbose lookup info + + }; + + CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "target modules lookup", + "Look up information within executable and dependent shared library images.", + NULL), + m_options (interpreter) + { + CommandArgumentEntry arg; + CommandArgumentData file_arg; + + // Define the first (and only) variant of this arg. + file_arg.arg_type = eArgTypeFilename; + file_arg.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (file_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + virtual + ~CommandObjectTargetModulesLookup () + { + } + + virtual Options * + GetOptions () + { + return &m_options; + } + + + bool + LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) + { + switch (m_options.m_type) + { + case eLookupTypeAddress: + if (m_options.m_addr != LLDB_INVALID_ADDRESS) + { + if (LookupAddressInModule (m_interpreter, + result.GetOutputStream(), + module, + eSymbolContextEverything, + m_options.m_addr, + m_options.m_offset, + m_options.m_verbose)) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + } + break; + + case eLookupTypeSymbol: + if (!m_options.m_str.empty()) + { + if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex)) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + } + break; + + case eLookupTypeFileLine: + if (m_options.m_file) + { + + if (LookupFileAndLineInModule (m_interpreter, + result.GetOutputStream(), + module, + m_options.m_file, + m_options.m_line_number, + m_options.m_check_inlines, + m_options.m_verbose)) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + } + break; + + case eLookupTypeFunction: + if (!m_options.m_str.empty()) + { + if (LookupFunctionInModule (m_interpreter, + result.GetOutputStream(), + module, + m_options.m_str.c_str(), + m_options.m_use_regex, + m_options.m_verbose)) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + } + break; + + case eLookupTypeType: + if (!m_options.m_str.empty()) + { + if (LookupTypeInModule (m_interpreter, + result.GetOutputStream(), + module, + m_options.m_str.c_str(), + m_options.m_use_regex)) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + } + break; + + default: + m_options.GenerateOptionUsage (result.GetErrorStream(), this); + syntax_error = true; + break; + } + + result.SetStatus (eReturnStatusFailed); + return false; + } + + virtual bool + Execute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + bool syntax_error = false; + uint32_t i; + uint32_t num_successful_lookups = 0; + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + // Dump all sections for all modules images + + if (command.GetArgumentCount() == 0) + { + // Dump all sections for all modules images + const uint32_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) + { + for (i = 0; iGetImages().GetModulePointerAtIndex(i), result, syntax_error)) + { + result.GetOutputStream().EOL(); + num_successful_lookups++; + } + } + } + else + { + result.AppendError ("the target has no associated executable images"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) + { + FileSpec image_file(arg_cstr, false); + ModuleList matching_modules; + size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); + + // Not found in our module list for our target, check the main + // shared module list in case it is a extra file used somewhere + // else + if (num_matching_modules == 0) + num_matching_modules = ModuleList::FindSharedModules (image_file, + target->GetArchitecture(), + NULL, + NULL, + matching_modules); + + if (num_matching_modules > 0) + { + for (size_t j=0; j 0) + result.SetStatus (eReturnStatusSuccessFinishResult); + else + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } +protected: + + CommandOptions m_options; +}; + +OptionDefinition +CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, + { LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "When looking up an address subtract from any addresses before doing the lookup."}, + { LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."}, + { LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The argument for name lookups are regular expressions."}, + { LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."}, + { LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."}, + { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."}, + { LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, + { LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, + { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + + +#pragma mark CommandObjectMultiwordImageSearchPaths + +//------------------------------------------------------------------------- +// CommandObjectMultiwordImageSearchPaths +//------------------------------------------------------------------------- + +class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword +{ +public: + + CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "target modules search-paths", + "A set of commands for operating on debugger target image search paths.", + "target modules search-paths []") + { + LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); + LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); + LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); + LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); + } + + ~CommandObjectTargetModulesImageSearchPaths() + { + } +}; + + + +#pragma mark CommandObjectTargetModules + +//------------------------------------------------------------------------- +// CommandObjectTargetModules +//------------------------------------------------------------------------- + +class CommandObjectTargetModules : public CommandObjectMultiword +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CommandObjectTargetModules(CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "target modules", + "A set of commands for accessing information for one or more target modules.", + "target modules ...") + { + LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); + LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); + //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); + LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); + LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); + LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); + + } + virtual + ~CommandObjectTargetModules() + { + } + +private: + //------------------------------------------------------------------ + // For CommandObjectTargetModules only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); +}; + + #pragma mark CommandObjectTargetStopHookAdd //------------------------------------------------------------------------- @@ -1491,7 +3546,7 @@ LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); - LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter))); + LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); } CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Tue May 3 17:09:39 2011 @@ -629,7 +629,7 @@ if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) { - result.AppendError ("invalid target, set executable file using 'file' command"); + result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } @@ -893,7 +893,7 @@ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { - result.AppendError ("invalid target, set executable file using 'file' command"); + result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); return false; } Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Tue May 3 17:09:39 2011 @@ -22,7 +22,6 @@ //#include "../Commands/CommandObjectFile.h" #include "../Commands/CommandObjectFrame.h" #include "../Commands/CommandObjectHelp.h" -#include "../Commands/CommandObjectImage.h" #include "../Commands/CommandObjectLog.h" #include "../Commands/CommandObjectMemory.h" #include "../Commands/CommandObjectPlatform.h" @@ -118,6 +117,7 @@ HandleCommand ("command alias up _regexp-up", false, result); HandleCommand ("command alias down _regexp-down", false, result); HandleCommand ("command alias file target create", false, result); + HandleCommand ("command alias image target modules", false, result); } @@ -169,7 +169,7 @@ // m_command_dict["file"] = CommandObjectSP (new CommandObjectFile (*this)); m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this)); m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this)); - m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this)); + /// m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this)); m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this)); m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this)); m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this)); Modified: lldb/trunk/source/Interpreter/NamedOptionValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/NamedOptionValue.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/NamedOptionValue.cpp (original) +++ lldb/trunk/source/Interpreter/NamedOptionValue.cpp Tue May 3 17:09:39 2011 @@ -96,6 +96,16 @@ return NULL; } +OptionValueUUID * +OptionValue::GetAsUUID () +{ + if (GetType () == OptionValue::eTypeUUID) + return static_cast(this); + return NULL; + +} + + OptionValueArray * OptionValue::GetAsArray () { @@ -306,6 +316,24 @@ //------------------------------------------------------------------------- +// OptionValueUUID +//------------------------------------------------------------------------- +void +OptionValueUUID::DumpValue (Stream &strm) +{ + m_uuid.Dump (&strm); +} + +Error +OptionValueUUID::SetValueFromCString (const char *value_cstr) +{ + Error error; + if (m_uuid.SetfromCString(value_cstr) == 0) + error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr); + return error; +} + +//------------------------------------------------------------------------- // OptionValueFormat //------------------------------------------------------------------------- void Added: lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp?rev=130796&view=auto ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp (added) +++ lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp Tue May 3 17:09:39 2011 @@ -0,0 +1,58 @@ +//===-- OptionGroupBoolean.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "OptionGroupBoolean.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +OptionGroupBoolean::OptionGroupBoolean (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + bool default_value) : + m_value (default_value, default_value) +{ + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.option_has_arg = required_argument; + m_option_definition.enum_values = NULL; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; +} + +OptionGroupBoolean::~OptionGroupBoolean () +{ +} + +Error +OptionGroupBoolean::SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) +{ + Error error (m_value.SetValueFromCString (option_arg)); + return error; +} + +void +OptionGroupBoolean::OptionParsingStarting (CommandInterpreter &interpreter) +{ + m_value.Clear(); +} Added: lldb/trunk/source/Interpreter/OptionGroupFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupFile.cpp?rev=130796&view=auto ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupFile.cpp (added) +++ lldb/trunk/source/Interpreter/OptionGroupFile.cpp Tue May 3 17:09:39 2011 @@ -0,0 +1,57 @@ +//===-- OptionGroupFile.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "OptionGroupFile.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +OptionGroupFile::OptionGroupFile (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text) : + m_file () +{ + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.option_has_arg = required_argument; + m_option_definition.enum_values = NULL; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; +} + +OptionGroupFile::~OptionGroupFile () +{ +} + +Error +OptionGroupFile::SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) +{ + Error error (m_file.SetValueFromCString (option_arg)); + return error; +} + +void +OptionGroupFile::OptionParsingStarting (CommandInterpreter &interpreter) +{ + m_file.Clear(); +} Modified: lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp Tue May 3 17:09:39 2011 @@ -83,7 +83,7 @@ { Error error; if (!m_include_platform_option) - --option_idx; + ++option_idx; char short_option = (char) g_option_table[option_idx].short_option; Added: lldb/trunk/source/Interpreter/OptionGroupUInt64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupUInt64.cpp?rev=130796&view=auto ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupUInt64.cpp (added) +++ lldb/trunk/source/Interpreter/OptionGroupUInt64.cpp Tue May 3 17:09:39 2011 @@ -0,0 +1,58 @@ +//===-- OptionGroupUInt64.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "OptionGroupUInt64.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +OptionGroupUInt64::OptionGroupUInt64 (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + uint64_t default_value) : + m_value (default_value, default_value) +{ + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.option_has_arg = required_argument; + m_option_definition.enum_values = NULL; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; +} + +OptionGroupUInt64::~OptionGroupUInt64 () +{ +} + +Error +OptionGroupUInt64::SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) +{ + Error error (m_value.SetValueFromCString (option_arg)); + return error; +} + +void +OptionGroupUInt64::OptionParsingStarting (CommandInterpreter &interpreter) +{ + m_value.Clear(); +} Added: lldb/trunk/source/Interpreter/OptionGroupUUID.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupUUID.cpp?rev=130796&view=auto ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupUUID.cpp (added) +++ lldb/trunk/source/Interpreter/OptionGroupUUID.cpp Tue May 3 17:09:39 2011 @@ -0,0 +1,75 @@ +//===-- OptionGroupUUID.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "OptionGroupUUID.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +OptionGroupUUID::OptionGroupUUID() : + m_uuid () +{ +} + +OptionGroupUUID::~OptionGroupUUID () +{ +} + +static OptionDefinition +g_option_table[] = +{ +{ LLDB_OPT_SET_1 , false, "uuid", 'u', required_argument, NULL, 0, eArgTypeNone, "A module UUID value."}, +}; + +const uint32_t k_num_file_options = sizeof(g_option_table)/sizeof(OptionDefinition); + +uint32_t +OptionGroupUUID::GetNumDefinitions () +{ + return k_num_file_options; +} + +const OptionDefinition * +OptionGroupUUID::GetDefinitions () +{ + return g_option_table; +} + +Error +OptionGroupUUID::SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) +{ + Error error; + char short_option = (char) g_option_table[option_idx].short_option; + + switch (short_option) + { + case 'u': + error = m_uuid.SetValueFromCString (option_arg); + break; + + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; +} + +void +OptionGroupUUID::OptionParsingStarting (CommandInterpreter &interpreter) +{ + m_uuid.Clear(); +} Modified: lldb/trunk/tools/debugserver/source/DNB.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/DNB.cpp (original) +++ lldb/trunk/tools/debugserver/source/DNB.cpp Tue May 3 17:09:39 2011 @@ -705,6 +705,7 @@ { switch (state) { + case eStateInvalid: return "Invalid"; case eStateUnloaded: return "Unloaded"; case eStateAttaching: return "Attaching"; case eStateLaunching: return "Launching"; Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Tue May 3 17:09:39 2011 @@ -334,6 +334,8 @@ case eStateStepping: Resume(); break; + default: + break; } m_arch_ap->ThreadWillResume(); m_stop_exception.Clear(); Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Tue May 3 17:09:39 2011 @@ -525,7 +525,7 @@ if (m_thread->IsStepping()) { // This is the primary thread, let the arch do anything it needs - EnableHardwareSingleStep(true) == KERN_SUCCESS; + EnableHardwareSingleStep(true); } } Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Tue May 3 17:09:39 2011 @@ -454,7 +454,7 @@ if (m_thread->IsStepping()) { // This is the primary thread, let the arch do anything it needs - EnableHardwareSingleStep(true) == KERN_SUCCESS; + EnableHardwareSingleStep(true); } } Modified: lldb/trunk/tools/debugserver/source/RNBContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBContext.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBContext.cpp (original) +++ lldb/trunk/tools/debugserver/source/RNBContext.cpp Tue May 3 17:09:39 2011 @@ -188,6 +188,8 @@ case eStateDetached: done = true; break; + default: + break; } } Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original) +++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Tue May 3 17:09:39 2011 @@ -2068,6 +2068,7 @@ case eStateLaunching: case eStateRunning: case eStateStepping: + case eStateDetached: return rnb_success; // Ignore case eStateSuspended: Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=130796&r1=130795&r2=130796&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBRemote.h (original) +++ lldb/trunk/tools/debugserver/source/RNBRemote.h Tue May 3 17:09:39 2011 @@ -236,6 +236,8 @@ case set_logging_mode: case query_host_info: return true; + default: + break; } return false; } From johnny.chen at apple.com Tue May 3 17:14:20 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 22:14:20 -0000 Subject: [Lldb-commits] [lldb] r130797 - in /lldb/trunk/test: command_regex/TestCommandRegex.py connect_remote/TestConnectRemote.py lldbtest.py Message-ID: <20110503221420.11D612A6C12C@llvm.org> Author: johnny Date: Tue May 3 17:14:19 2011 New Revision: 130797 URL: http://llvm.org/viewvc/llvm-project?rev=130797&view=rev Log: Use a more gentle way of shutting down the child process spawned during the test execution using pexpect. Change some child.expect() to child.expect_exact() as they try to match the string, not a regular expression. Modified: lldb/trunk/test/command_regex/TestCommandRegex.py lldb/trunk/test/connect_remote/TestConnectRemote.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/command_regex/TestCommandRegex.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_regex/TestCommandRegex.py?rev=130797&r1=130796&r2=130797&view=diff ============================================================================== --- lldb/trunk/test/command_regex/TestCommandRegex.py (original) +++ lldb/trunk/test/command_regex/TestCommandRegex.py Tue May 3 17:14:19 2011 @@ -14,7 +14,7 @@ def test_command_regex(self): """Test a simple scenario of 'command regexp' invocation and subsequent use.""" - prompt = "\(lldb\) " + prompt = "(lldb) " regex_prompt = "Enter regular expressions in the form 's///' and terminate with an empty line:\r\n" regex_prompt1 = "\r\n" @@ -25,12 +25,12 @@ # So that the spawned lldb session gets shutdown durng teardown. self.child = child - # Substitute 'Help!' with 'help' using the 'commands regex' mechanism. - child.expect(prompt) + # Substitute 'Help!' for 'help' using the 'commands regex' mechanism. + child.expect_exact(prompt) child.sendline("command regex 'Help!'") - child.expect(regex_prompt) + child.expect_exact(regex_prompt) child.sendline('s/^$/help/') - child.expect(regex_prompt1) + child.expect_exact(regex_prompt1) child.sendline('') # Help! child.sendline('Help!') Modified: lldb/trunk/test/connect_remote/TestConnectRemote.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/connect_remote/TestConnectRemote.py?rev=130797&r1=130796&r2=130797&view=diff ============================================================================== --- lldb/trunk/test/connect_remote/TestConnectRemote.py (original) +++ lldb/trunk/test/connect_remote/TestConnectRemote.py Tue May 3 17:14:19 2011 @@ -29,7 +29,7 @@ self.addTearDownHook(shutdown_fakeserver) # Wait until we receive the server ready message before continuing. - fakeserver.expect('Listening on localhost:12345') + fakeserver.expect_exact('Listening on localhost:12345') # Connect to the fake server.... self.runCmd("process connect connect://localhost:12345") Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=130797&r1=130796&r2=130797&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue May 3 17:14:19 2011 @@ -678,12 +678,15 @@ # This is for the case of directly spawning 'lldb' and interacting with it # using pexpect. + import pexpect if self.child and self.child.isalive(): with recording(self, traceAlways) as sbuf: print >> sbuf, "tearing down the child process...." self.child.sendline('quit') - time.sleep(2) - self.child.close() + try: + self.child.expect(pexpect.EOF) + except: + pass # Terminate the current process being debugged, if any. if self.runStarted: From johnny.chen at apple.com Tue May 3 17:32:16 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 22:32:16 -0000 Subject: [Lldb-commits] [lldb] r130802 - /lldb/trunk/test/load_unload/TestLoadUnload.py Message-ID: <20110503223216.AD69F2A6C12C@llvm.org> Author: johnny Date: Tue May 3 17:32:16 2011 New Revision: 130802 URL: http://llvm.org/viewvc/llvm-project?rev=130802&view=rev Log: Remove debug statement. 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=130802&r1=130801&r2=130802&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Tue May 3 17:32:16 2011 @@ -49,7 +49,7 @@ exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - print "Architecture to test for:", self.getArchitecture() + self.expect("image list", substrs = [old_dylib]) self.expect("image list -t 3", From johnny.chen at apple.com Tue May 3 18:18:45 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 23:18:45 -0000 Subject: [Lldb-commits] [lldb] r130804 - /lldb/trunk/test/help/TestHelp.py Message-ID: <20110503231845.725622A6C12C@llvm.org> Author: johnny Date: Tue May 3 18:18:45 2011 New Revision: 130804 URL: http://llvm.org/viewvc/llvm-project?rev=130804&view=rev Log: Update the golden output strings to match against after the recent change. Modified: lldb/trunk/test/help/TestHelp.py Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=130804&r1=130803&r2=130804&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Tue May 3 18:18:45 2011 @@ -70,7 +70,7 @@ def test_help_image_dump_symtab_should_not_crash(self): """Command 'help image dump symtab' should not crash lldb.""" self.expect("help image dump symtab", - substrs = ['image dump symtab', + substrs = ['dump symtab', 'sort-order']) def test_help_image_du_sym_is_ambiguous(self): @@ -84,7 +84,7 @@ def test_help_image_du_line_should_work(self): """Command 'help image du line' is not ambiguous and should work.""" self.expect("help image du line", - substrs = ['Dump the debug symbol file for one or more executable images']) + substrs = ['Dump the debug symbol file for one or more target modules']) if __name__ == '__main__': From johnny.chen at apple.com Tue May 3 18:55:05 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 03 May 2011 23:55:05 -0000 Subject: [Lldb-commits] [lldb] r130806 - /lldb/trunk/test/help/TestHelp.py Message-ID: <20110503235505.7E33F2A6C12C@llvm.org> Author: johnny Date: Tue May 3 18:55:05 2011 New Revision: 130806 URL: http://llvm.org/viewvc/llvm-project?rev=130806&view=rev Log: Add comments about 'image' being an alias for 'target modules'. Modified: lldb/trunk/test/help/TestHelp.py Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=130806&r1=130805&r2=130806&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Tue May 3 18:55:05 2011 @@ -69,6 +69,7 @@ def test_help_image_dump_symtab_should_not_crash(self): """Command 'help image dump symtab' should not crash lldb.""" + # 'image' is an alias for 'target modules'. self.expect("help image dump symtab", substrs = ['dump symtab', 'sort-order']) @@ -83,6 +84,7 @@ def test_help_image_du_line_should_work(self): """Command 'help image du line' is not ambiguous and should work.""" + # 'image' is an alias for 'target modules'. self.expect("help image du line", substrs = ['Dump the debug symbol file for one or more target modules']) From johnny.chen at apple.com Tue May 3 19:44:20 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 04 May 2011 00:44:20 -0000 Subject: [Lldb-commits] [lldb] r130811 - /lldb/trunk/test/stop-hook/TestStopHookMechanism.py Message-ID: <20110504004420.5B7EB2A6C12C@llvm.org> Author: johnny Date: Tue May 3 19:44:20 2011 New Revision: 130811 URL: http://llvm.org/viewvc/llvm-project?rev=130811&view=rev Log: Make the negative test more robust in light of more than one lldb prompts being emitted in one command invocation. Modified: lldb/trunk/test/stop-hook/TestStopHookMechanism.py Modified: lldb/trunk/test/stop-hook/TestStopHookMechanism.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/TestStopHookMechanism.py?rev=130811&r1=130810&r2=130811&view=diff ============================================================================== --- lldb/trunk/test/stop-hook/TestStopHookMechanism.py (original) +++ lldb/trunk/test/stop-hook/TestStopHookMechanism.py Tue May 3 19:44:20 2011 @@ -73,10 +73,10 @@ # Now continue the inferior, we'll stop at another breakpoint which is outside the stop-hook range. child.sendline('process continue') - child.expect_exact(prompt) + child.expect_exact('// Another breakpoint which is outside of the stop-hook range.') #self.DebugPExpect(child) child.sendline('thread step-over') - child.expect_exact(prompt) + child.expect_exact('// Another breakpoint which is outside of the stop-hook range.') #self.DebugPExpect(child) # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. self.expect(child.before, exe=False, matching=False, From jingham at apple.com Tue May 3 22:43:19 2011 From: jingham at apple.com (Jim Ingham) Date: Wed, 04 May 2011 03:43:19 -0000 Subject: [Lldb-commits] [lldb] r130832 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Target/ test/array_types/ test/bitfields/ test/breakpoint_command/ test/breakpoint_conditions/ test/class_types/ test/cpp/dynamic-value/ test/forward/ test/foundation/ test/function_types/ test/global_v... Message-ID: <20110504034319.875692A6C12C@llvm.org> Author: jingham Date: Tue May 3 22:43:18 2011 New Revision: 130832 URL: http://llvm.org/viewvc/llvm-project?rev=130832&view=rev Log: Change "frame var" over to using OptionGroups (and thus the OptionGroupVariableObjectDisplay). Change the boolean "use_dynamic" over to a tri-state, no-dynamic, dynamic-w/o running target, and dynamic with running target. Modified: lldb/trunk/include/lldb/API/SBFrame.h lldb/trunk/include/lldb/API/SBValue.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/Core/ValueObjectConstResult.h lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h lldb/trunk/include/lldb/Target/LanguageRuntime.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/API/SBValue.cpp lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Commands/CommandObjectMemory.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Core/ValueObjectDynamicValue.cpp lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/cpp/dynamic-value/TestDynamicValue.py lldb/trunk/test/forward/TestForwardDeclaration.py lldb/trunk/test/foundation/TestObjCMethods.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py lldb/trunk/test/set_values/TestSetValues.py lldb/trunk/test/signed_types/TestSignedTypes.py lldb/trunk/test/types/AbstractBase.py lldb/trunk/test/unique-types/TestUniqueTypes.py lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Modified: lldb/trunk/include/lldb/API/SBFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFrame.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFrame.h (original) +++ lldb/trunk/include/lldb/API/SBFrame.h Tue May 3 22:43:18 2011 @@ -76,7 +76,7 @@ EvaluateExpression (const char *expr); lldb::SBValue - EvaluateExpression (const char *expr, bool fetch_dynamic_value); + EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic); // Gets the lexical block that defines the stack frame. Another way to think // of this is it will return the block that contains all of the variables @@ -126,7 +126,7 @@ bool locals, bool statics, bool in_scope_only, - bool use_dynamic); + lldb::DynamicValueType use_dynamic); lldb::SBValueList GetRegisters (); @@ -136,7 +136,7 @@ FindVariable (const char *var_name); lldb::SBValue - FindVariable (const char *var_name, bool use_dynamic); + FindVariable (const char *var_name, lldb::DynamicValueType use_dynamic); // Find variables, register sets, registers, or persistent variables using // the frame as the scope @@ -144,7 +144,7 @@ FindValue (const char *name, ValueType value_type); lldb::SBValue - FindValue (const char *name, ValueType value_type, bool use_dynamic); + FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic); bool GetDescription (lldb::SBStream &description); Modified: lldb/trunk/include/lldb/API/SBValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValue.h (original) +++ lldb/trunk/include/lldb/API/SBValue.h Tue May 3 22:43:18 2011 @@ -100,7 +100,7 @@ GetChildAtIndex (uint32_t idx); lldb::SBValue - GetChildAtIndex (uint32_t idx, bool use_dynamic); + GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic); // Matches children of this object only and will match base classes and // member names if this is a clang typed object. @@ -115,7 +115,7 @@ // Matches child members of this object and child members of any base // classes. lldb::SBValue - GetChildMemberWithName (const char *name, bool use_dynamic); + GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic); uint32_t GetNumChildren (); Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Tue May 3 22:43:18 2011 @@ -366,7 +366,7 @@ GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create); lldb::ValueObjectSP - GetDynamicValue (bool can_create); + GetDynamicValue (lldb::DynamicValueType valueType); virtual lldb::ValueObjectSP CreateConstantValue (const ConstString &name); @@ -403,7 +403,7 @@ bool show_types, bool show_location, bool use_objc, - bool use_dynamic, + lldb::DynamicValueType use_dynamic, bool scope_already_checked, bool flat_output); @@ -533,7 +533,7 @@ UpdateValue () = 0; virtual void - CalculateDynamicValue (); + CalculateDynamicValue (lldb::DynamicValueType use_dynamic); // Should only be called by ValueObject::GetChildAtIndex() // Returns a ValueObject managed by this ValueObject's manager. Modified: lldb/trunk/include/lldb/Core/ValueObjectConstResult.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResult.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectConstResult.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectConstResult.h Tue May 3 22:43:18 2011 @@ -96,12 +96,13 @@ virtual bool UpdateValue (); + // CalculateDynamicValue doesn't change the dynamic value, since this can get + // called at any time and you can't reliably fetch the dynamic value at any time. + // If we want to have dynamic values for ConstResults, then we'll need to make them + // up when we make the const result & stuff them in by hand. virtual void - CalculateDynamicValue () {} // CalculateDynamicValue doesn't change the dynamic value, since this can get - // called at any time and you can't reliably fetch the dynamic value at any time. - // If we want to have dynamic values for ConstResults, then we'll need to make them - // up when we make the const result & stuff them in by hand. - + CalculateDynamicValue (lldb::DynamicValueType use_dynamic) {} + clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from ConstString m_type_name; uint32_t m_byte_size; Modified: lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h Tue May 3 22:43:18 2011 @@ -90,10 +90,11 @@ Address m_address; ///< The variable that this value object is based upon lldb::TypeSP m_type_sp; lldb::ValueObjectSP m_owning_valobj_sp; + lldb::DynamicValueType m_use_dynamic; private: friend class ValueObject; - ValueObjectDynamicValue (ValueObject &parent); + ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic); //------------------------------------------------------------------ // For ValueObject only Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h (original) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h Tue May 3 22:43:18 2011 @@ -53,6 +53,7 @@ bool use_objc; uint32_t max_depth; uint32_t ptr_depth; + lldb::DynamicValueType use_dynamic; }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original) +++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Tue May 3 22:43:18 2011 @@ -43,7 +43,10 @@ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0; virtual bool - GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) = 0; + GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address) = 0; // This should be a fast test to determine whether it is likely that this value would // have a dynamic type. Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Tue May 3 22:43:18 2011 @@ -33,8 +33,7 @@ enum ExpressionPathOption { eExpressionPathOptionCheckPtrVsMember = (1u << 0), - eExpressionPathOptionsNoFragileObjcIvar = (1u << 1), - eExpressionPathOptionsDynamicValue = (1u << 2) + eExpressionPathOptionsNoFragileObjcIvar = (1u << 1) }; //------------------------------------------------------------------ // Constructors and Destructors @@ -104,7 +103,11 @@ // See ExpressionPathOption enumeration for "options" values lldb::ValueObjectSP - GetValueForVariableExpressionPath (const char *var_expr, uint32_t options, Error &error); + GetValueForVariableExpressionPath (const char *var_expr, + lldb::DynamicValueType use_dynamic, + uint32_t options, + lldb::VariableSP &var_sp, + Error &error); bool HasDebugInformation (); @@ -134,10 +137,10 @@ } lldb::ValueObjectSP - GetValueObjectForFrameVariable (const lldb::VariableSP &variable_sp, bool use_dynamic); + GetValueObjectForFrameVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic); lldb::ValueObjectSP - TrackGlobalVariable (const lldb::VariableSP &variable_sp, bool use_dynamic); + TrackGlobalVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic); //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Tue May 3 22:43:18 2011 @@ -40,6 +40,7 @@ class TargetInstanceSettings : public InstanceSettings { public: + static OptionEnumValueElement g_dynamic_value_types[]; TargetInstanceSettings (UserSettingsController &owner, bool live_instance = true, const char *name = NULL); @@ -67,10 +68,10 @@ StringList &value, Error *err); - bool + lldb::DynamicValueType GetPreferDynamicValue() { - return m_prefer_dynamic_value; + return (lldb::DynamicValueType) g_dynamic_value_types[m_prefer_dynamic_value].value; } bool @@ -96,9 +97,10 @@ OptionValueFileSpec m_expr_prefix_file; lldb::DataBufferSP m_expr_prefix_contents_sp; - OptionValueBoolean m_prefer_dynamic_value; + int m_prefer_dynamic_value; OptionValueBoolean m_skip_prologue; PathMappingList m_source_map; + }; @@ -483,7 +485,7 @@ StackFrame *frame, bool unwind_on_error, bool keep_in_memory, - bool fetch_dynamic_value, + lldb::DynamicValueType use_dynamic, lldb::ValueObjectSP &result_valobj_sp); ClangPersistentVariables & Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Tue May 3 22:43:18 2011 @@ -316,7 +316,13 @@ eLanguageTypePython = 0x0014 ///< Python. } LanguageType; - + typedef enum DynamicValueType + { + eNoDynamicValues = 0, + eDynamicCanRunTarget = 1, + eDynamicDontRunTarget = 2 + } DynamicValueType; + typedef enum AccessType { eAccessNone, Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Tue May 3 22:43:18 2011 @@ -343,12 +343,12 @@ SBValue SBFrame::FindVariable (const char *name) { - bool use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); + lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); return FindVariable (name, use_dynamic); } SBValue -SBFrame::FindVariable (const char *name, bool use_dynamic) +SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) { VariableSP var_sp; SBValue sb_value; @@ -389,12 +389,12 @@ SBValue SBFrame::FindValue (const char *name, ValueType value_type) { - bool use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); + lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); return FindValue (name, value_type, use_dynamic); } SBValue -SBFrame::FindValue (const char *name, ValueType value_type, bool use_dynamic) +SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic) { SBValue sb_value; if (m_opaque_sp && name && name[0]) @@ -579,7 +579,7 @@ bool statics, bool in_scope_only) { - bool use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); + lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); return GetVariables (arguments, locals, statics, in_scope_only, use_dynamic); } @@ -588,7 +588,7 @@ bool locals, bool statics, bool in_scope_only, - bool use_dynamic) + lldb::DynamicValueType use_dynamic) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -706,12 +706,12 @@ SBValue SBFrame::EvaluateExpression (const char *expr) { - bool use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); + lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); return EvaluateExpression (expr, use_dynamic); } SBValue -SBFrame::EvaluateExpression (const char *expr, bool fetch_dynamic_value) +SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value) { Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); @@ -732,8 +732,8 @@ exe_results = m_opaque_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr, m_opaque_sp.get(), unwind_on_error, - fetch_dynamic_value, keep_in_memory, + fetch_dynamic_value, *expr_result); } Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Tue May 3 22:43:18 2011 @@ -339,12 +339,12 @@ SBValue SBValue::GetChildAtIndex (uint32_t idx) { - bool use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); + lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); return GetChildAtIndex (idx, use_dynamic_value); } SBValue -SBValue::GetChildAtIndex (uint32_t idx, bool use_dynamic_value) +SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic) { lldb::ValueObjectSP child_sp; @@ -353,11 +353,11 @@ child_sp = m_opaque_sp->GetChildAtIndex (idx, true); } - if (use_dynamic_value) + if (use_dynamic != lldb::eNoDynamicValues) { if (child_sp) { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (true); + lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic); if (dynamic_sp) child_sp = dynamic_sp; } @@ -391,12 +391,12 @@ SBValue SBValue::GetChildMemberWithName (const char *name) { - bool use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); + lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); return GetChildMemberWithName (name, use_dynamic_value); } SBValue -SBValue::GetChildMemberWithName (const char *name, bool use_dynamic_value) +SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) { lldb::ValueObjectSP child_sp; const ConstString str_name (name); @@ -406,11 +406,11 @@ child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); } - if (use_dynamic_value) + if (use_dynamic_value != lldb::eNoDynamicValues) { if (child_sp) { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (true); + lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); if (dynamic_sp) child_sp = dynamic_sp; } Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue May 3 22:43:18 2011 @@ -260,27 +260,22 @@ ExecutionResults exe_results; bool keep_in_memory = true; - bool use_dynamic; + lldb::DynamicValueType use_dynamic; // If use dynamic is not set, get it from the target: switch (m_options.use_dynamic) { case eLazyBoolCalculate: - { - if (m_exe_ctx.target->GetPreferDynamicValue()) - use_dynamic = true; - else - use_dynamic = false; - } + use_dynamic = m_exe_ctx.target->GetPreferDynamicValue(); break; case eLazyBoolYes: - use_dynamic = true; + use_dynamic = lldb::eDynamicCanRunTarget; break; case eLazyBoolNo: - use_dynamic = false; + use_dynamic = lldb::eNoDynamicValues; break; } - exe_results = m_exe_ctx.target->EvaluateExpression(expr, m_exe_ctx.frame, m_options.unwind_on_error, use_dynamic, keep_in_memory, result_valobj_sp); + exe_results = m_exe_ctx.target->EvaluateExpression(expr, m_exe_ctx.frame, m_options.unwind_on_error, keep_in_memory, use_dynamic, result_valobj_sp); if (exe_results == eExecutionInterrupted && !m_options.unwind_on_error) { Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Tue May 3 22:43:18 2011 @@ -25,6 +25,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" @@ -285,73 +286,46 @@ { public: - class CommandOptions : public Options + class OptionGroupFrameVariable : public OptionGroup { public: - CommandOptions (CommandInterpreter &interpreter) : - Options(interpreter) + OptionGroupFrameVariable () { - OptionParsingStarting (); } virtual - ~CommandOptions () + ~OptionGroupFrameVariable () { } + virtual uint32_t + GetNumDefinitions (); + + virtual const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + virtual Error - SetOptionValue (uint32_t option_idx, const char *option_arg) + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) { Error error; - bool success; - char short_option = (char) m_getopt_table[option_idx].val; + char short_option = (char) g_option_table[option_idx].short_option; switch (short_option) { - case 'o': use_objc = true; break; - case 'd': - { - bool success; - bool result; - result = Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid dynamic value setting: \"%s\".\n", option_arg); - else - { - if (result) - use_dynamic = eLazyBoolYes; - else - use_dynamic = eLazyBoolNo; - } - } - break; case 'r': use_regex = true; break; case 'a': show_args = false; break; case 'l': show_locals = false; break; case 'g': show_globals = true; break; - case 't': show_types = true; break; - case 'y': show_summary = false; break; - case 'L': show_location= true; break; case 'c': show_decl = true; break; - case 'D': debug = true; break; case 'f': error = Args::StringToFormat(option_arg, format, NULL); break; - case 'F': flat_output = true; break; - case 'A': - 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': globals.push_back(ConstString (option_arg)); break; - case 's': show_scope = true; break; @@ -364,52 +338,29 @@ return error; } - void - OptionParsingStarting () + virtual void + OptionParsingStarting (CommandInterpreter &interpreter) { - use_objc = false; - use_regex = false; show_args = true; - show_locals = true; - show_globals = false; - show_types = false; - show_scope = false; - show_summary = true; - show_location = false; show_decl = false; - debug = false; - flat_output = false; - use_dynamic = eLazyBoolCalculate; - max_depth = UINT32_MAX; - ptr_depth = 0; format = eFormatDefault; + show_globals = false; + show_locals = true; + use_regex = false; + show_scope = false; globals.clear(); } - const OptionDefinition* - GetDefinitions () - { - return g_option_table; - } - // Options table: Required for subclasses of Options. static OptionDefinition g_option_table[]; - bool use_objc:1, - use_regex:1, + + bool use_regex:1, show_args:1, show_locals:1, show_globals:1, - show_types:1, show_scope:1, - show_summary:1, - show_location:1, - show_decl:1, - debug:1, - flat_output:1; - LazyBool use_dynamic; - 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 + show_decl:1; lldb::Format format; // The format to use when dumping variables or children of variables std::vector globals; // Instance variables to hold the values for command options. @@ -426,7 +377,9 @@ "'var->child.x'.", NULL, eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), - m_options (interpreter) + m_option_group (interpreter), + m_frame_var_options(), + m_varobj_options() { CommandArgumentEntry arg; CommandArgumentData var_name_arg; @@ -440,6 +393,10 @@ // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); + + m_option_group.Append (&m_frame_var_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); } virtual @@ -451,7 +408,7 @@ Options * GetOptions () { - return &m_options; + return &m_option_group; } @@ -479,40 +436,19 @@ VariableSP var_sp; ValueObjectSP valobj_sp; - bool use_dynamic; - - // If use dynamic is not set, get it from the target: - switch (m_options.use_dynamic) - { - case eLazyBoolCalculate: - { - if (exe_ctx.target->GetPreferDynamicValue()) - use_dynamic = true; - else - use_dynamic = false; - } - break; - case eLazyBoolYes: - use_dynamic = true; - break; - case eLazyBoolNo: - use_dynamic = false; - break; - } - const char *name_cstr = NULL; size_t idx; - if (!m_options.globals.empty()) + if (!m_frame_var_options.globals.empty()) { uint32_t fail_count = 0; if (exe_ctx.target) { - const size_t num_globals = m_options.globals.size(); + const size_t num_globals = m_frame_var_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], + = exe_ctx.target->GetImages().FindGlobalVariables (m_frame_var_options.globals[idx], true, UINT32_MAX, global_var_list); @@ -521,7 +457,7 @@ { ++fail_count; result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", - m_options.globals[idx].AsCString()); + m_frame_var_options.globals[idx].AsCString()); } else { @@ -530,16 +466,18 @@ var_sp = global_var_list.GetVariableAtIndex(global_idx); if (var_sp) { - valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, use_dynamic); + valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, + m_varobj_options.use_dynamic); if (!valobj_sp) - valobj_sp = exe_ctx.frame->TrackGlobalVariable (var_sp, use_dynamic); + valobj_sp = exe_ctx.frame->TrackGlobalVariable (var_sp, + m_varobj_options.use_dynamic); if (valobj_sp) { - if (m_options.format != eFormatDefault) - valobj_sp->SetFormat (m_options.format); + if (m_frame_var_options.format != eFormatDefault) + valobj_sp->SetFormat (m_frame_var_options.format); - if (m_options.show_decl && var_sp->GetDeclaration ().GetFile()) + if (m_frame_var_options.show_decl && var_sp->GetDeclaration ().GetFile()) { var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); @@ -548,15 +486,15 @@ ValueObject::DumpValueObject (result.GetOutputStream(), valobj_sp.get(), name_cstr, - m_options.ptr_depth, + m_varobj_options.ptr_depth, 0, - m_options.max_depth, - m_options.show_types, - m_options.show_location, - m_options.use_objc, - use_dynamic, + m_varobj_options.max_depth, + m_varobj_options.show_types, + m_varobj_options.show_location, + m_varobj_options.use_objc, + m_varobj_options.use_dynamic, false, - m_options.flat_output); + m_varobj_options.flat_output); } } } @@ -576,9 +514,9 @@ // variable objects from them... for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx) { - uint32_t ptr_depth = m_options.ptr_depth; + uint32_t ptr_depth = m_varobj_options.ptr_depth; - if (m_options.use_regex) + if (m_frame_var_options.use_regex) { const uint32_t regex_start_index = regex_var_list.GetSize(); RegularExpression regex (name_cstr); @@ -597,13 +535,13 @@ var_sp = regex_var_list.GetVariableAtIndex (regex_idx); if (var_sp) { - valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, use_dynamic); + valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { - if (m_options.format != eFormatDefault) - valobj_sp->SetFormat (m_options.format); + if (m_frame_var_options.format != eFormatDefault) + valobj_sp->SetFormat (m_frame_var_options.format); - if (m_options.show_decl && var_sp->GetDeclaration ().GetFile()) + if (m_frame_var_options.show_decl && var_sp->GetDeclaration ().GetFile()) { var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); @@ -612,15 +550,15 @@ ValueObject::DumpValueObject (result.GetOutputStream(), valobj_sp.get(), var_sp->GetName().AsCString(), - m_options.ptr_depth, + m_varobj_options.ptr_depth, 0, - m_options.max_depth, - m_options.show_types, - m_options.show_location, - m_options.use_objc, - use_dynamic, + m_varobj_options.max_depth, + m_varobj_options.show_types, + m_varobj_options.show_location, + m_varobj_options.use_objc, + m_varobj_options.use_dynamic, false, - m_options.flat_output); + m_varobj_options.flat_output); } } } @@ -643,16 +581,17 @@ { Error error; uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember; - if (use_dynamic) - expr_path_options |= StackFrame::eExpressionPathOptionsDynamicValue; - - valobj_sp = exe_ctx.frame->GetValueForVariableExpressionPath (name_cstr, expr_path_options, error); + lldb::VariableSP var_sp; + valobj_sp = exe_ctx.frame->GetValueForVariableExpressionPath (name_cstr, + m_varobj_options.use_dynamic, + expr_path_options, + var_sp, + error); if (valobj_sp) { - if (m_options.format != eFormatDefault) - valobj_sp->SetFormat (m_options.format); - - if (m_options.show_decl && var_sp->GetDeclaration ().GetFile()) + if (m_frame_var_options.format != eFormatDefault) + valobj_sp->SetFormat (m_frame_var_options.format); + if (m_frame_var_options.show_decl && var_sp && var_sp->GetDeclaration ().GetFile()) { var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); @@ -662,13 +601,13 @@ valobj_sp->GetParent() ? name_cstr : NULL, ptr_depth, 0, - m_options.max_depth, - m_options.show_types, - m_options.show_location, - m_options.use_objc, - use_dynamic, + m_varobj_options.max_depth, + m_varobj_options.show_types, + m_varobj_options.show_location, + m_varobj_options.use_objc, + m_varobj_options.use_dynamic, false, - m_options.flat_output); + m_varobj_options.flat_output); } else { @@ -696,26 +635,26 @@ switch (var_sp->GetScope()) { case eValueTypeVariableGlobal: - dump_variable = m_options.show_globals; - if (dump_variable && m_options.show_scope) + dump_variable = m_frame_var_options.show_globals; + if (dump_variable && m_frame_var_options.show_scope) s.PutCString("GLOBAL: "); break; case eValueTypeVariableStatic: - dump_variable = m_options.show_globals; - if (dump_variable && m_options.show_scope) + dump_variable = m_frame_var_options.show_globals; + if (dump_variable && m_frame_var_options.show_scope) s.PutCString("STATIC: "); break; case eValueTypeVariableArgument: - dump_variable = m_options.show_args; - if (dump_variable && m_options.show_scope) + dump_variable = m_frame_var_options.show_args; + if (dump_variable && m_frame_var_options.show_scope) s.PutCString(" ARG: "); break; case eValueTypeVariableLocal: - dump_variable = m_options.show_locals; - if (dump_variable && m_options.show_scope) + dump_variable = m_frame_var_options.show_locals; + if (dump_variable && m_frame_var_options.show_scope) s.PutCString(" LOCAL: "); break; @@ -729,17 +668,18 @@ // Use the variable object code to make sure we are // using the same APIs as the the public API will be // using... - valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, use_dynamic); + valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, + m_varobj_options.use_dynamic); if (valobj_sp) { - if (m_options.format != eFormatDefault) - valobj_sp->SetFormat (m_options.format); + if (m_frame_var_options.format != eFormatDefault) + valobj_sp->SetFormat (m_frame_var_options.format); // When dumping all variables, don't print any variables // that are not in scope to avoid extra unneeded output if (valobj_sp->IsInScope ()) { - if (m_options.show_decl && var_sp->GetDeclaration ().GetFile()) + if (m_frame_var_options.show_decl && var_sp->GetDeclaration ().GetFile()) { var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); @@ -747,15 +687,15 @@ ValueObject::DumpValueObject (result.GetOutputStream(), valobj_sp.get(), name_cstr, - m_options.ptr_depth, + m_varobj_options.ptr_depth, 0, - m_options.max_depth, - m_options.show_types, - m_options.show_location, - m_options.use_objc, - use_dynamic, + m_varobj_options.max_depth, + m_varobj_options.show_types, + m_varobj_options.show_location, + m_varobj_options.use_objc, + m_varobj_options.use_dynamic, false, - m_options.flat_output); + m_varobj_options.flat_output); } } } @@ -769,31 +709,32 @@ } protected: - CommandOptions m_options; + OptionGroupOptions m_option_group; + OptionGroupFrameVariable m_frame_var_options; + OptionGroupValueObjectDisplay m_varobj_options; }; OptionDefinition -CommandObjectFrameVariable::CommandOptions::g_option_table[] = +CommandObjectFrameVariable::OptionGroupFrameVariable::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "aggregate-depth", 'A', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."}, { LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, eArgTypeNone, "Omit function arguments."}, { LLDB_OPT_SET_1, false, "show-declaration",'c', no_argument, NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."}, -{ LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug information."}, -{ LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, NULL, 0, eArgTypeBoolean, "Show the object as its full dynamic type, not its static type, if available."}, { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format that the variable output should use."}, -{ LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."}, { LLDB_OPT_SET_1, false, "show-globals", 'g', no_argument, NULL, 0, eArgTypeNone, "Show the current frame source file global and static variables."}, { LLDB_OPT_SET_1, false, "find-global", 'G', required_argument, NULL, 0, eArgTypeVarName, "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, eArgTypeNone, "Show variable location information."}, { LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, eArgTypeNone, "Omit local variables."}, -{ LLDB_OPT_SET_1, false, "objc", 'o', no_argument, NULL, 0, eArgTypeNone, "When looking up a variable by name, print as an Objective-C object."}, -{ LLDB_OPT_SET_1, false, "ptr-depth", 'p', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."}, { LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, eArgTypeRegularExpression, "The argument for name lookups are regular expressions."}, { LLDB_OPT_SET_1, false, "scope", 's', no_argument, NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."}, -{ LLDB_OPT_SET_1, false, "show-types", 't', no_argument, NULL, 0, eArgTypeNone, "Show variable types when dumping values."}, -{ LLDB_OPT_SET_1, false, "no-summary", 'y', no_argument, NULL, 0, eArgTypeNone, "Omit summary information."}, { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } }; + +uint32_t +CommandObjectFrameVariable::OptionGroupFrameVariable::GetNumDefinitions () +{ + return sizeof(CommandObjectFrameVariable::OptionGroupFrameVariable::g_option_table)/sizeof(OptionDefinition); +} + + #pragma mark CommandObjectMultiwordFrame //------------------------------------------------------------------------- Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Tue May 3 22:43:18 2011 @@ -643,7 +643,6 @@ if (format != eFormatDefault) valobj_sp->SetFormat (format); - bool use_dynamic = false; bool scope_already_checked = true; ValueObject::DumpValueObject (*output_stream, @@ -655,7 +654,7 @@ m_varobj_options.show_types, m_varobj_options.show_location, m_varobj_options.use_objc, - use_dynamic, + m_varobj_options.use_dynamic, scope_already_checked, m_varobj_options.flat_output); } Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Tue May 3 22:43:18 2011 @@ -986,8 +986,11 @@ } void -ValueObject::CalculateDynamicValue () +ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic) { + if (use_dynamic == lldb::eNoDynamicValues) + return; + if (!m_dynamic_value && !IsDynamic()) { Process *process = m_update_point.GetProcess(); @@ -1013,12 +1016,12 @@ { LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); if (objc_runtime) - worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this); + worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this); } } if (worth_having_dynamic_value) - m_dynamic_value = new ValueObjectDynamicValue (*this); + m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic); // if (worth_having_dynamic_value) // printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager); @@ -1027,11 +1030,14 @@ } ValueObjectSP -ValueObject::GetDynamicValue (bool can_create) +ValueObject::GetDynamicValue (DynamicValueType use_dynamic) { - if (!IsDynamic() && m_dynamic_value == NULL && can_create) + if (use_dynamic == lldb::eNoDynamicValues) + return ValueObjectSP(); + + if (!IsDynamic() && m_dynamic_value == NULL) { - CalculateDynamicValue(); + CalculateDynamicValue(use_dynamic); } if (m_dynamic_value) return m_dynamic_value->GetSP(); @@ -1137,16 +1143,16 @@ bool show_types, bool show_location, bool use_objc, - bool use_dynamic, + lldb::DynamicValueType use_dynamic, bool scope_already_checked, bool flat_output ) { if (valobj && valobj->UpdateValueIfNeeded ()) { - if (use_dynamic) + if (use_dynamic != lldb::eNoDynamicValues) { - ValueObject *dynamic_value = valobj->GetDynamicValue(true).get(); + ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get(); if (dynamic_value) valobj = dynamic_value; } Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original) +++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Tue May 3 22:43:18 2011 @@ -34,10 +34,11 @@ using namespace lldb_private; -ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent) : +ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) : ValueObject(parent), m_address (), - m_type_sp() + m_type_sp(), + m_use_dynamic (use_dynamic) { SetName (parent.GetName().AsCString()); } @@ -122,6 +123,14 @@ return false; } + // Setting our type_sp to NULL will route everything back through our + // parent which is equivalent to not using dynamic values. + if (m_use_dynamic == lldb::eNoDynamicValues) + { + m_type_sp.reset(); + return true; + } + ExecutionContext exe_ctx (GetExecutionContextScope()); if (exe_ctx.target) @@ -144,19 +153,19 @@ { LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); if (runtime) - found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, class_type_or_name, dynamic_address); + found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); } else { LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); if (cpp_runtime) - found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, class_type_or_name, dynamic_address); + found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); if (!found_dynamic_type) { LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); if (objc_runtime) - found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, class_type_or_name, dynamic_address); + found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); } } Modified: lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp Tue May 3 22:43:18 2011 @@ -13,6 +13,8 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Target/Target.h" +#include "lldb/Interpreter/CommandInterpreter.h" using namespace lldb; using namespace lldb_private; @@ -28,6 +30,8 @@ static OptionDefinition g_option_table[] = { + { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, + 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."}, { LLDB_OPT_SET_1, false, "depth", 'D', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."}, { LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."}, { LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, eArgTypeNone, "Show variable location information."}, @@ -64,6 +68,17 @@ switch (short_option) { + case 'd': + { + bool success; + int32_t result; + result = Args::StringToOptionEnum (option_arg, TargetInstanceSettings::g_dynamic_value_types, 2, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid dynamic value setting: \"%s\".\n", option_arg); + else + use_dynamic = (lldb::DynamicValueType) result; + } + break; case 'T': show_types = true; break; case 'Y': show_summary = false; break; case 'L': show_location= true; break; @@ -99,5 +114,13 @@ use_objc = false; max_depth = UINT32_MAX; ptr_depth = 0; -} - + + Target *target = interpreter.GetExecutionContext().target; + if (target != NULL) + use_dynamic = target->GetPreferDynamicValue(); + else + { + // If we don't have any targets, then dynamic values won't do us much good. + use_dynamic = lldb::eNoDynamicValues; + } +} \ No newline at end of file Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Tue May 3 22:43:18 2011 @@ -41,7 +41,10 @@ } bool -ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &dynamic_address) +ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &dynamic_address) { // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0 // in the object. That will point to the "address point" within the vtable (not the beginning of the Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h Tue May 3 22:43:18 2011 @@ -31,7 +31,10 @@ IsVTableName (const char *name); virtual bool - GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address); virtual bool CouldHaveDynamicValue (ValueObject &in_value); Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Tue May 3 22:43:18 2011 @@ -194,11 +194,18 @@ bool AppleObjCRuntime::CouldHaveDynamicValue (ValueObject &in_value) { - return in_value.IsPointerType(); + lldb::LanguageType known_type = in_value.GetObjectRuntimeLanguage(); + if (known_type == lldb::eLanguageTypeObjC) + return true; + else + return in_value.IsPointerType(); } bool -AppleObjCRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) +AppleObjCRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address) { return false; } Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h Tue May 3 22:43:18 2011 @@ -41,7 +41,10 @@ CouldHaveDynamicValue (ValueObject &in_value); virtual bool - GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address); // These are the ObjC specific functions. Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Tue May 3 22:43:18 2011 @@ -41,7 +41,10 @@ static const char *pluginShort = "language.apple.objc.v1"; bool -AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) +AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address) { return false; } Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Tue May 3 22:43:18 2011 @@ -32,7 +32,10 @@ // These are generic runtime functions: virtual bool - GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address); virtual ClangUtilityFunction * CreateObjectChecker (const char *); Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue May 3 22:43:18 2011 @@ -219,7 +219,10 @@ } bool -AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address) +AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address) { // The Runtime is attached to a particular process, you shouldn't pass in a value from another process. assert (in_value.GetUpdatePoint().GetProcess() == m_process); @@ -316,7 +319,7 @@ } char class_buffer[1024]; - if (class_name == NULL) + if (class_name == NULL && use_dynamic != lldb::eDynamicDontRunTarget) { // If the class address didn't point into the binary, or // it points into the right section but there wasn't a symbol Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Tue May 3 22:43:18 2011 @@ -32,7 +32,10 @@ // These are generic runtime functions: virtual bool - GetDynamicTypeAndAddress (ValueObject &in_value, TypeAndOrName &class_type_or_name, Address &address); + GetDynamicTypeAndAddress (ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address); virtual ClangUtilityFunction * CreateObjectChecker (const char *); Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Tue May 3 22:43:18 2011 @@ -807,7 +807,8 @@ dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index))); Value flag_value; - lldb::clang_type_t clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); + lldb::clang_type_t clang_int_type + = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); flag_value.SetValueType (Value::eValueTypeScalar); flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Tue May 3 22:43:18 2011 @@ -486,14 +486,17 @@ } ValueObjectSP -StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32_t options, Error &error) +StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, + lldb::DynamicValueType use_dynamic, + uint32_t options, + lldb::VariableSP &var_sp, + Error &error) { if (var_expr_cstr && var_expr_cstr[0]) { const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; - const bool dynamic_value = (options & eExpressionPathOptionsDynamicValue) != 0; error.Clear(); bool deref = false; bool address_of = false; @@ -526,10 +529,10 @@ else name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); - VariableSP var_sp (variable_list->FindVariable(name_const_string)); + var_sp = variable_list->FindVariable(name_const_string); if (var_sp) { - valobj_sp = GetValueObjectForFrameVariable (var_sp, dynamic_value); + valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); if (!valobj_sp) return valobj_sp; @@ -626,9 +629,9 @@ } // Remove the child name from the path var_path.erase(0, child_name.GetLength()); - if (dynamic_value) + if (use_dynamic != lldb::eNoDynamicValues) { - ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(true)); + ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); if (dynamic_value_sp) child_valobj_sp = dynamic_value_sp; } @@ -688,9 +691,9 @@ // %i is the array index var_path.erase(0, (end - var_path.c_str()) + 1); separator_idx = var_path.find_first_of(".-["); - if (dynamic_value) + if (use_dynamic != lldb::eNoDynamicValues) { - ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(true)); + ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); if (dynamic_value_sp) child_valobj_sp = dynamic_value_sp; } @@ -738,7 +741,8 @@ } else { - error.SetErrorStringWithFormat("no variable named '%s' found in this frame", name_const_string.GetCString()); + error.SetErrorStringWithFormat("no variable named '%s' found in this frame", + name_const_string.GetCString()); } } } @@ -809,7 +813,7 @@ ValueObjectSP -StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, bool use_dynamic) +StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, lldb::DynamicValueType use_dynamic) { ValueObjectSP valobj_sp; VariableList *var_list = GetVariableList (true); @@ -830,9 +834,9 @@ } } } - if (use_dynamic && valobj_sp) + if (use_dynamic != lldb::eNoDynamicValues && valobj_sp) { - ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (true); + ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); if (dynamic_sp) return dynamic_sp; } @@ -840,7 +844,7 @@ } ValueObjectSP -StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, bool use_dynamic) +StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, lldb::DynamicValueType use_dynamic) { // Check to make sure we aren't already tracking this variable? ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Tue May 3 22:43:18 2011 @@ -890,7 +890,7 @@ StackFrame *frame, bool unwind_on_error, bool keep_in_memory, - bool fetch_dynamic_value, + lldb::DynamicValueType use_dynamic, lldb::ValueObjectSP &result_valobj_sp ) { @@ -905,7 +905,12 @@ Error error; const uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsNoFragileObjcIvar; - result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr, expr_path_options, error); + lldb::VariableSP var_sp; + result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr, + use_dynamic, + expr_path_options, + var_sp, + error); } else if (m_process_sp) { @@ -932,9 +937,9 @@ } else { - if (fetch_dynamic_value) + if (use_dynamic != lldb::eNoDynamicValues) { - ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(true); + ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(use_dynamic); if (dynamic_sp) result_valobj_sp = dynamic_sp; } @@ -1390,7 +1395,7 @@ InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), m_expr_prefix_file (), m_expr_prefix_contents_sp (), - m_prefer_dynamic_value (true, true), + m_prefer_dynamic_value (2), m_skip_prologue (true, true), m_source_map (NULL, NULL) { @@ -1486,7 +1491,10 @@ } else if (var_name == GetSettingNameForPreferDynamicValue()) { - err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_prefer_dynamic_value); + int new_value; + UserSettingsController::UpdateEnumVariable (g_dynamic_value_types, &new_value, value, err); + if (err.Success()) + m_prefer_dynamic_value = new_value; } else if (var_name == GetSettingNameForSkipPrologue()) { @@ -1579,10 +1587,7 @@ } else if (var_name == GetSettingNameForPreferDynamicValue()) { - if (m_prefer_dynamic_value) - value.AppendString ("true"); - else - value.AppendString ("false"); + value.AppendString (g_dynamic_value_types[m_prefer_dynamic_value].string_value); } else if (var_name == GetSettingNameForSkipPrologue()) { @@ -1620,6 +1625,14 @@ //-------------------------------------------------- // Target::SettingsController Variable Tables //-------------------------------------------------- +OptionEnumValueElement +TargetInstanceSettings::g_dynamic_value_types[] = +{ +{ eNoDynamicValues, "no-dynamic-values", "Don't calculate the dynamic type of values"}, +{ eDynamicCanRunTarget, "run-target", "Calculate the dynamic type of values even if you have to run the target."}, +{ eDynamicDontRunTarget, "no-run-target", "Calculate the dynamic type of values, but don't run the target."}, +{ 0, NULL, NULL } +}; SettingEntry Target::SettingsController::global_settings_table[] = @@ -1633,11 +1646,11 @@ SettingEntry Target::SettingsController::instance_settings_table[] = { - // var-name var-type default enum init'd hidden help-text - // ================= ================== =========== ==== ====== ====== ========================================================================= - { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, - { TSC_PREFER_DYNAMIC, eSetVarTypeBoolean ,"true" , NULL, false, false, "Should printed values be shown as their dynamic value." }, - { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean ,"true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." }, - { TSC_SOURCE_MAP , eSetVarTypeArray ,NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." }, - { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } + // var-name var-type default enum init'd hidden help-text + // ================= ================== =============== ======================= ====== ====== ========================================================================= + { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, + { TSC_PREFER_DYNAMIC, eSetVarTypeEnum , "no-run-target", g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." }, + { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean ,"true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." }, + { TSC_SOURCE_MAP , eSetVarTypeArray ,NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." }, + { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } }; Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Tue May 3 22:43:18 2011 @@ -69,7 +69,7 @@ # Issue 'variable list' command on several array-type variables. - self.expect("frame variable -t strings", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T strings", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(char *[4])', substrs = ['(char *) [0]', '(char *) [1]', @@ -80,14 +80,14 @@ 'Bonjour', 'Guten Tag']) - self.expect("frame variable -t char_16", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T char_16", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(char) [0]', '(char) [15]']) - self.expect("frame variable -t ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(unsigned short [2][3])') - self.expect("frame variable -t long_6", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T 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=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue May 3 22:43:18 2011 @@ -62,7 +62,7 @@ substrs = [' resolved, hit count = 1']) # This should display correctly. - self.expect("frame variable -t bits", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T bits", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(uint32_t:1) b1 = 1', '(uint32_t:2) b2 = 3', '(uint32_t:3) b3 = 7', @@ -74,7 +74,7 @@ # And so should this. # rdar://problem/8348251 - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(uint32_t:1) b1 = 1', '(uint32_t:2) b2 = 3', '(uint32_t:3) b3 = 7', Modified: lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py (original) +++ lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py Tue May 3 22:43:18 2011 @@ -51,7 +51,7 @@ self.line) # Now add callbacks for the breakpoints just created. - self.runCmd("breakpoint command add -s command -o 'frame variable -t -s' 1") + self.runCmd("breakpoint command add -s command -o 'frame variable -T -s' 1") self.runCmd("breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); print >> here, \"lldb\"; here.close()' 2") # Check that the breakpoint commands are correctly set. @@ -69,7 +69,7 @@ self.expect("breakpoint command list 1", "Breakpoint 1 command ok", substrs = ["Breakpoint commands:", - "frame variable -t -s"]) + "frame variable -T -s"]) self.expect("breakpoint command list 2", "Breakpoint 2 command ok", substrs = ["Breakpoint commands:", "here = open", Modified: lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py (original) +++ lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py Tue May 3 22:43:18 2011 @@ -62,8 +62,8 @@ self.expect("process status", PROCESS_STOPPED, patterns = ['Process .* stopped']) - # 'frame variable -t val' should return 3 due to breakpoint condition. - self.expect("frame variable -t val", VARIABLES_DISPLAYED_CORRECTLY, + # 'frame variable -T val' should return 3 due to breakpoint condition. + self.expect("frame variable -T val", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(int) val = 3') # Also check the hit count, which should be 3, by design. @@ -93,8 +93,8 @@ self.expect("process status", PROCESS_STOPPED, patterns = ['Process .* stopped']) - # 'frame variable -t val' should return 1 since it is the first breakpoint hit. - self.expect("frame variable -t val", VARIABLES_DISPLAYED_CORRECTLY, + # 'frame variable -T val' should return 1 since it is the first breakpoint hit. + self.expect("frame variable -T val", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(int) val = 1') Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Tue May 3 22:43:18 2011 @@ -88,7 +88,7 @@ substrs = [' resolved, hit count = 1']) # We should be stopped on the ctor function of class C. - self.expect("frame variable -t this", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T this", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['C *', ' this = ']) @@ -182,8 +182,8 @@ self.expect("frame variable this",VARIABLES_DISPLAYED_CORRECTLY, substrs = ['C *']) - # Verify that frame variable -t this->m_c_int behaves correctly. - self.expect("frame variable -t this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY, + # Verify that frame variable -T this->m_c_int behaves correctly. + self.expect("frame variable -T this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(int) this->m_c_int = 66') # Verify that 'expression this' gets the data type correct. Modified: lldb/trunk/test/cpp/dynamic-value/TestDynamicValue.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/cpp/dynamic-value/TestDynamicValue.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/cpp/dynamic-value/TestDynamicValue.py (original) +++ lldb/trunk/test/cpp/dynamic-value/TestDynamicValue.py Tue May 3 22:43:18 2011 @@ -61,7 +61,10 @@ # Now read m_b_value which is only in the dynamic value: - this_dynamic_m_b_value = this_dynamic.GetChildMemberWithName('m_b_value', True) + use_dynamic = lldb.eDynamicCanRunTarget + no_dynamic = lldb.eNoDynamicValues + + this_dynamic_m_b_value = this_dynamic.GetChildMemberWithName('m_b_value', use_dynamic) self.assertTrue (this_dynamic_m_b_value.IsValid()) m_b_value = int (this_dynamic_m_b_value.GetValue(), 0) @@ -69,17 +72,17 @@ # Make sure it is not in the static version - this_static_m_b_value = this_static.GetChildMemberWithName('m_b_value', False) + this_static_m_b_value = this_static.GetChildMemberWithName('m_b_value', no_dynamic) self.assertTrue (this_static_m_b_value.IsValid() == False) # Okay, now let's make sure that we can get the dynamic type of a child element: - contained_auto_ptr = this_dynamic.GetChildMemberWithName ('m_client_A', True) + contained_auto_ptr = this_dynamic.GetChildMemberWithName ('m_client_A', use_dynamic) self.assertTrue (contained_auto_ptr.IsValid()) - contained_b = contained_auto_ptr.GetChildMemberWithName ('_M_ptr', True) + contained_b = contained_auto_ptr.GetChildMemberWithName ('_M_ptr', use_dynamic) self.assertTrue (contained_b.IsValid()) - contained_b_static = contained_auto_ptr.GetChildMemberWithName ('_M_ptr', False) + contained_b_static = contained_auto_ptr.GetChildMemberWithName ('_M_ptr', no_dynamic) self.assertTrue (contained_b_static.IsValid()) contained_b_addr = int (contained_b.GetValue(), 16) @@ -128,14 +131,14 @@ # Now find the dynamic addresses of myB and otherB so we can compare them # with the dynamic values we get in doSomething: - noDynamic = False - useDynamic = True + use_dynamic = lldb.eDynamicCanRunTarget + no_dynamic = lldb.eNoDynamicValues - myB = frame.FindVariable ('myB', noDynamic); + myB = frame.FindVariable ('myB', no_dynamic); self.assertTrue (myB.IsValid()) myB_loc = int (myB.GetLocation(), 16) - otherB = frame.FindVariable('otherB', noDynamic) + otherB = frame.FindVariable('otherB', no_dynamic) self.assertTrue (otherB.IsValid()) otherB_loc = int (otherB.GetLocation(), 16) @@ -149,13 +152,13 @@ # Get "this" using FindVariable: - this_static = frame.FindVariable ('this', noDynamic) - this_dynamic = frame.FindVariable ('this', useDynamic) + this_static = frame.FindVariable ('this', no_dynamic) + this_dynamic = frame.FindVariable ('this', use_dynamic) self.examine_value_object_of_this_ptr (this_static, this_dynamic, myB_loc) # Get "this" using FindValue, make sure that works too: - this_static = frame.FindValue ('this', lldb.eValueTypeVariableArgument, noDynamic) - this_dynamic = frame.FindValue ('this', lldb.eValueTypeVariableArgument, useDynamic) + this_static = frame.FindValue ('this', lldb.eValueTypeVariableArgument, no_dynamic) + this_dynamic = frame.FindValue ('this', lldb.eValueTypeVariableArgument, use_dynamic) self.examine_value_object_of_this_ptr (this_static, this_dynamic, myB_loc) # Get "this" using the EvaluateExpression: @@ -167,7 +170,7 @@ # The "frame var" code uses another path to get into children, so let's # make sure that works as well: - self.expect('frame var -d 1 anotherA.m_client_A._M_ptr', 'frame var finds its way into a child member', + self.expect('frame var -d run-target anotherA.m_client_A._M_ptr', 'frame var finds its way into a child member', patterns = ['\(.* B \*\)']) # Now make sure we also get it right for a reference as well: Modified: lldb/trunk/test/forward/TestForwardDeclaration.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/forward/TestForwardDeclaration.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/forward/TestForwardDeclaration.py (original) +++ lldb/trunk/test/forward/TestForwardDeclaration.py Tue May 3 22:43:18 2011 @@ -46,7 +46,7 @@ # This should display correctly. # Note that the member fields of a = 1 and b = 2 is by design. - self.expect("frame variable -t *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(struct bar) *bar_ptr = ', '(int) a = 1', '(int) b = 2']) Modified: lldb/trunk/test/foundation/TestObjCMethods.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestObjCMethods.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestObjCMethods.py (original) +++ lldb/trunk/test/foundation/TestObjCMethods.py Tue May 3 22:43:18 2011 @@ -140,7 +140,7 @@ 'NSString * str;', 'NSDate * date;']) - self.expect("frame variable -t -s", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T -s", VARIABLES_DISPLAYED_CORRECTLY, substrs = ["ARG: (MyString *) self"], patterns = ["ARG: \(.*\) _cmd", "(struct objc_selector *)|(SEL)"]) @@ -152,16 +152,16 @@ # rdar://problem/8492646 # test/foundation fails after updating to tot r115023 # self->str displays nothing as output - self.expect("frame variable -t self->str", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T self->str", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(NSString *) self->str") # rdar://problem/8447030 # 'frame variable self->date' displays the wrong data member - self.expect("frame variable -t self->date", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T self->date", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(NSDate *) self->date") # This should display the str and date member fields as well. - self.expect("frame variable -t *self", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T *self", VARIABLES_DISPLAYED_CORRECTLY, substrs = ["(MyString) *self", "(NSString *) str", "(NSDate *) date"]) Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Tue May 3 22:43:18 2011 @@ -49,7 +49,7 @@ substrs = [' resolved, hit count = 1']) # Check that the 'callback' variable display properly. - self.expect("frame variable -t callback", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T callback", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(int (*)(const char *)) 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=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Tue May 3 22:43:18 2011 @@ -49,7 +49,7 @@ substrs = [' resolved, hit count = 1']) # Check that GLOBAL scopes are indicated for the variables. - self.expect("frame variable -t -s -g -a", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T -s -g -a", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['GLOBAL: (int) g_file_global_int = 42', 'GLOBAL: (const char *) g_file_global_cstr', '"g_file_global_cstr"', Modified: lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py (original) +++ lldb/trunk/test/objc-dynamic-value/TestObjCDynamicValue.py Tue May 3 22:43:18 2011 @@ -81,9 +81,9 @@ # make sure we can get that properly: frame = thread.GetFrameAtIndex(0) - myObserver = frame.FindVariable('myObserver') + myObserver = frame.FindVariable('myObserver', lldb.eDynamicCanRunTarget) self.assertTrue (myObserver.IsValid()) - myObserver_source = myObserver.GetChildMemberWithName ('_source') + myObserver_source = myObserver.GetChildMemberWithName ('_source', lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr (myObserver_source) # The "frame var" code uses another path to get into children, so let's @@ -91,7 +91,7 @@ result = lldb.SBCommandReturnObject() - self.expect('frame var -d 1 myObserver->_source', 'frame var finds its way into a child member', + self.expect('frame var -d run-target myObserver->_source', 'frame var finds its way into a child member', patterns = ['\(SourceDerived \*\)']) # This test is not entirely related to the main thrust of this test case, but since we're here, @@ -115,8 +115,8 @@ # Get "object" using FindVariable: - noDynamic = False - useDynamic = True + noDynamic = lldb.eNoDynamicValues + useDynamic = lldb.eDynamicCanRunTarget object_static = frame.FindVariable ('object', noDynamic) object_dynamic = frame.FindVariable ('object', useDynamic) @@ -134,8 +134,8 @@ # Get "this" using the EvaluateExpression: # These tests fail for now because EvaluateExpression doesn't currently support dynamic typing... - #object_static = frame.EvaluateExpression ('object', False) - #object_dynamic = frame.EvaluateExpression ('object', True) + #object_static = frame.EvaluateExpression ('object', noDynamic) + #object_dynamic = frame.EvaluateExpression ('object', useDynamic) #self.examine_value_object_of_object_ptr (object_static, object_dynamic, myB_loc) # Continue again to the handle_SourceBase and make sure we get the correct dynamic value. Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Tue May 3 22:43:18 2011 @@ -73,63 +73,63 @@ substrs = [' resolved, hit count = 1']) # main.c:15 - # Check that 'frame variable -t' displays the correct data type and value. - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable -T' displays the correct data type and value. + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(char) i = 'a'") # Now set variable 'i' and check that it is correctly displayed. self.runCmd("expression i = 'b'") - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(char) i = 'b'") self.runCmd("continue") # main.c:36 - # Check that 'frame variable -t' displays the correct data type and value. - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable -T' displays the correct data type and value. + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, patterns = ["\((short unsigned int|unsigned short)\) i = 33"]) # Now set variable 'i' and check that it is correctly displayed. self.runCmd("expression i = 333") - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, patterns = ["\((short unsigned int|unsigned short)\) i = 333"]) self.runCmd("continue") # main.c:57 - # Check that 'frame variable -t' displays the correct data type and value. - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable -T' displays the correct data type and value. + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(long int) i = 33") # Now set variable 'i' and check that it is correctly displayed. self.runCmd("expression i = 33333") - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(long int) i = 33333") self.runCmd("continue") # main.c:78 - # Check that 'frame variable -t' displays the correct data type and value. - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + # Check that 'frame variable -T' displays the correct data type and value. + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(double) i = 3.14159") # Now set variable 'i' and check that it is correctly displayed. self.runCmd("expression i = 3.14") - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(double) i = 3.14") self.runCmd("continue") # main.c:85 - # Check that 'frame variable -t' displays the correct data type and value. + # Check that 'frame variable -T' displays the correct data type and value. # rdar://problem/8422727 # set_values test directory: 'frame variable' shows only (long double) i = - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(long double) i = 3.14159") # Now set variable 'i' and check that it is correctly displayed. self.runCmd("expression i = 3.1") - self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(long double) i = 3.1") Modified: lldb/trunk/test/signed_types/TestSignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/signed_types/TestSignedTypes.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/signed_types/TestSignedTypes.py (original) +++ lldb/trunk/test/signed_types/TestSignedTypes.py Tue May 3 22:43:18 2011 @@ -54,7 +54,7 @@ self.runCmd("thread step-over") # Test that signed types display correctly. - self.expect("frame variable -t -a", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T -a", VARIABLES_DISPLAYED_CORRECTLY, patterns = ["\((short int|short)\) the_signed_short = 99"], substrs = ["(signed char) the_signed_char = 'c'", "(int) the_signed_int = 99", Modified: lldb/trunk/test/types/AbstractBase.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/AbstractBase.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/types/AbstractBase.py (original) +++ lldb/trunk/test/types/AbstractBase.py Tue May 3 22:43:18 2011 @@ -9,7 +9,7 @@ def Msg(var, val, using_frame_variable): return "'%s %s' matches the output (from compiled code): %s" % ( - 'frame variable -t' if using_frame_variable else 'expression' ,var, val) + 'frame variable -T' if using_frame_variable else 'expression' ,var, val) class GenericTester(TestBase): @@ -42,25 +42,25 @@ #print "golden list:", gl # Bring the program to the point where we can issue a series of - # 'frame variable -t' command. + # 'frame variable -T' command. self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) self.runCmd("breakpoint set --name Puts") self.runCmd("run", RUN_SUCCEEDED) self.runCmd("thread step-out", STEP_OUT_SUCCEEDED) - #self.runCmd("frame variable -t") + #self.runCmd("frame variable -T") # Now iterate through the golden list, comparing against the output from - # 'frame variable -t var'. + # 'frame variable -T var'. for var, val in gl: - self.runCmd("frame variable -t %s" % var) + self.runCmd("frame variable -T %s" % var) output = self.res.GetOutput() # The input type is in a canonical form as a set of named atoms. # The display type string must conatin each and every element. # # Example: - # runCmd: frame variable -t a_array_bounded[0] + # runCmd: frame variable -T a_array_bounded[0] # output: (char) a_array_bounded[0] = 'a' # try: @@ -108,7 +108,7 @@ self.runCmd("run", RUN_SUCCEEDED) self.runCmd("thread step-out", STEP_OUT_SUCCEEDED) - #self.runCmd("frame variable -t") + #self.runCmd("frame variable -T") # Now iterate through the golden list, comparing against the output from # 'expr var'. Modified: lldb/trunk/test/unique-types/TestUniqueTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unique-types/TestUniqueTypes.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/unique-types/TestUniqueTypes.py (original) +++ lldb/trunk/test/unique-types/TestUniqueTypes.py Tue May 3 22:43:18 2011 @@ -59,8 +59,8 @@ if clang_version < 3: self.skipTest("rdar://problem/9173060 lldb hangs while running unique-types for clang version < 3") - # Do a "frame variable -t longs" and verify "long" is in each line of output. - self.runCmd("frame variable -t longs") + # Do a "frame variable -T longs" and verify "long" is in each line of output. + self.runCmd("frame variable -T longs") output = self.res.GetOutput() for x in [line.strip() for line in output.split(os.linesep)]: # Skip empty line or closing brace. @@ -69,8 +69,8 @@ self.expect(x, "Expect type 'long'", exe=False, substrs = ['long']) - # Do a "frame variable -t shorts" and verify "short" is in each line of output. - self.runCmd("frame variable -t shorts") + # Do a "frame variable -T shorts" and verify "short" is in each line of output. + self.runCmd("frame variable -T shorts") output = self.res.GetOutput() for x in [line.strip() for line in output.split(os.linesep)]: # Skip empty line or closing brace. Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=130832&r1=130831&r2=130832&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Tue May 3 22:43:18 2011 @@ -51,7 +51,7 @@ substrs = [' resolved, hit count = 1']) # Test that unsigned types display correctly. - self.expect("frame variable -t -a", VARIABLES_DISPLAYED_CORRECTLY, + self.expect("frame variable -T -a", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(unsigned char) the_unsigned_char = 'c'", patterns = ["\((short unsigned int|unsigned short)\) the_unsigned_short = 99"], substrs = ["(unsigned int) the_unsigned_int = 99", From ctice at apple.com Wed May 4 11:44:57 2011 From: ctice at apple.com (Caroline Tice) Date: Wed, 04 May 2011 16:44:57 -0000 Subject: [Lldb-commits] [lldb] r130843 - /lldb/trunk/tools/driver/IOChannel.cpp Message-ID: <20110504164458.CECC12A6C12C@llvm.org> Author: ctice Date: Wed May 4 11:44:57 2011 New Revision: 130843 URL: http://llvm.org/viewvc/llvm-project?rev=130843&view=rev Log: Minor cleanup: When asynchronous output comes along, back up over and delete the prompt before writing out the asynchronous output, rather than just going to a new line. Modified: lldb/trunk/tools/driver/IOChannel.cpp Modified: lldb/trunk/tools/driver/IOChannel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.cpp?rev=130843&r1=130842&r2=130843&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.cpp (original) +++ lldb/trunk/tools/driver/IOChannel.cpp Wed May 4 11:44:57 2011 @@ -29,6 +29,9 @@ const char *g_default_prompt = "(lldb) "; PromptMap g_prompt_map; +// Printing the following string causes libedit to back up to the beginning of the line & blank it out. +const char undo_prompt_string[4] = { (char) 13, (char) 27, (char) 91, (char) 75}; + static const char* el_prompt(EditLine *el) { @@ -496,7 +499,7 @@ // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output. IOLocker locker (m_output_mutex); if (asynchronous) - ::fwrite ("\n", 1, 1, m_out_file); + ::fwrite (undo_prompt_string, 1, 4, m_out_file); ::fwrite (buffer, 1, len, m_out_file); if (asynchronous) m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten); @@ -511,7 +514,7 @@ // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output. IOLocker locker (m_output_mutex); if (asynchronous) - ::fwrite ("\n", 1, 1, m_err_file); + ::fwrite (undo_prompt_string, 1, 4, m_err_file); ::fwrite (buffer, 1, len, m_err_file); if (asynchronous) m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten); From johnny.chen at apple.com Wed May 4 13:01:44 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 04 May 2011 18:01:44 -0000 Subject: [Lldb-commits] [lldb] r130848 - /lldb/trunk/test/stop-hook/main.cpp Message-ID: <20110504180144.6CB862A6C12C@llvm.org> Author: johnny Date: Wed May 4 13:01:44 2011 New Revision: 130848 URL: http://llvm.org/viewvc/llvm-project?rev=130848&view=rev Log: Forgot to check in this change with r130811. Modified: lldb/trunk/test/stop-hook/main.cpp Modified: lldb/trunk/test/stop-hook/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stop-hook/main.cpp?rev=130848&r1=130847&r2=130848&view=diff ============================================================================== --- lldb/trunk/test/stop-hook/main.cpp (original) +++ lldb/trunk/test/stop-hook/main.cpp Wed May 4 13:01:44 2011 @@ -44,8 +44,8 @@ int A1 = a(1); printf("a(1) returns %d\n", A1); - int B2 = b(2); // Another breakpoint which is outside of the stop-hook range. - printf("b(2) returns %d\n", B2); + int C2 = c(2); // Another breakpoint which is outside of the stop-hook range. + printf("c(2) returns %d\n", C2); int A3 = a(3); printf("a(3) returns %d\n", A3); From johnny.chen at apple.com Wed May 4 15:38:02 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 04 May 2011 20:38:02 -0000 Subject: [Lldb-commits] [lldb] r130865 - /lldb/trunk/test/alias_tests/TestAliases.py Message-ID: <20110504203803.5A85C2A6C12C@llvm.org> Author: johnny Date: Wed May 4 15:38:01 2011 New Revision: 130865 URL: http://llvm.org/viewvc/llvm-project?rev=130865&view=rev Log: Use '-f c' to print each element of a string as a char. Modified: lldb/trunk/test/alias_tests/TestAliases.py Modified: lldb/trunk/test/alias_tests/TestAliases.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/alias_tests/TestAliases.py?rev=130865&r1=130864&r2=130865&view=diff ============================================================================== --- lldb/trunk/test/alias_tests/TestAliases.py (original) +++ lldb/trunk/test/alias_tests/TestAliases.py Wed May 4 15:38:01 2011 @@ -112,7 +112,7 @@ substrs = [ "(int) $", "= 0x000004d2" ]) - self.expect ('exprf2 s "Hi there!"', + self.expect ('exprf2 c "Hi there!"', substrs = [ "(const char) [0] = 'H'", "(const char) [1] = 'i'", "(const char) [2] = ' '", From ctice at apple.com Wed May 4 16:39:02 2011 From: ctice at apple.com (Caroline Tice) Date: Wed, 04 May 2011 21:39:02 -0000 Subject: [Lldb-commits] [lldb] r130871 - /lldb/trunk/tools/driver/IOChannel.cpp Message-ID: <20110504213902.654942A6C12C@llvm.org> Author: ctice Date: Wed May 4 16:39:02 2011 New Revision: 130871 URL: http://llvm.org/viewvc/llvm-project?rev=130871&view=rev Log: Add ability to search backwards through command history for a particular substring, using ctrl-r key. Modified: lldb/trunk/tools/driver/IOChannel.cpp Modified: lldb/trunk/tools/driver/IOChannel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.cpp?rev=130871&r1=130870&r2=130871&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.cpp (original) +++ lldb/trunk/tools/driver/IOChannel.cpp Wed May 4 16:39:02 2011 @@ -185,10 +185,11 @@ // Source $PWD/.editrc then $HOME/.editrc ::el_source (m_edit_line, NULL); - el_set(m_edit_line, EL_ADDFN, "lldb_complete", + el_set (m_edit_line, EL_ADDFN, "lldb_complete", "LLDB completion function", IOChannel::ElCompletionFn); - el_set(m_edit_line, EL_BIND, m_completion_key, "lldb_complete", NULL); + el_set (m_edit_line, EL_BIND, m_completion_key, "lldb_complete", NULL); + el_set (m_edit_line, EL_BIND, "^r", "em-inc-search-prev", NULL); // Cycle through backwards search, entering string el_set (m_edit_line, EL_CLIENTDATA, this); assert (m_history); From johnny.chen at apple.com Wed May 4 19:36:31 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 05 May 2011 00:36:31 -0000 Subject: [Lldb-commits] [lldb] r130904 - in /lldb/trunk/test: embedded_interpreter/ embedded_interpreter/Makefile embedded_interpreter/TestConvenienceVariables.py embedded_interpreter/main.c lldbtest.py Message-ID: <20110505003631.DE50A2A6C12C@llvm.org> Author: johnny Date: Wed May 4 19:36:31 2011 New Revision: 130904 URL: http://llvm.org/viewvc/llvm-project?rev=130904&view=rev Log: Add a test script for verifying that the convenience variables: o lldb.debugger o lldb.target o lldb.process o lldb.thread o lldb.frame "just works" when we stop at a breakpoint. Added: lldb/trunk/test/embedded_interpreter/ lldb/trunk/test/embedded_interpreter/Makefile lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py lldb/trunk/test/embedded_interpreter/main.c Modified: lldb/trunk/test/lldbtest.py Added: lldb/trunk/test/embedded_interpreter/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/embedded_interpreter/Makefile?rev=130904&view=auto ============================================================================== --- lldb/trunk/test/embedded_interpreter/Makefile (added) +++ lldb/trunk/test/embedded_interpreter/Makefile Wed May 4 19:36:31 2011 @@ -0,0 +1,5 @@ +LEVEL = ../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py?rev=130904&view=auto ============================================================================== --- lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py (added) +++ lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py Wed May 4 19:36:31 2011 @@ -0,0 +1,88 @@ +"""Test convenience variables when you drop in from lldb prompt into an embedded interpreter.""" + +import os +import unittest2 +import lldb +import pexpect +from lldbtest import * + +class ConvenienceVariablesCase(TestBase): + + mydir = "embedded_interpreter" + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" + self.buildDsym() + self.convenience_variables() + + @python_api_test + def test_with_dwarf_and_process_launch_api(self): + """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" + self.buildDwarf() + self.convenience_variables() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break on inside main.cpp. + self.line = line_number('main.c', 'Hello world.') + + def convenience_variables(self): + """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" + exe = os.path.join(os.getcwd(), "a.out") + prompt = "(lldb) " + python_prompt = ">>> " + + # So that the child gets torn down after the test. + self.child = pexpect.spawn('%s %s' % (self.lldbExec, exe)) + child = self.child + # Turn on logging for what the child sends back. + if self.TraceOn(): + child.logfile_read = sys.stdout + + # Set the breakpoint, run the inferior, when it breaks, issue print on + # the various convenience variables. + child.expect_exact(prompt) + child.sendline('breakpoint set -f main.c -l %d' % self.line) + child.expect_exact(prompt) + child.sendline('run') + child.expect_exact(prompt) + child.sendline('script') + child.expect_exact(python_prompt) + + # Set a flag so that we know during teardown time, we need to exit the + # Python interpreter, then the lldb interpreter. + self.child_in_script_interpreter = True + + child.sendline('print lldb.debugger') + child.expect_exact(python_prompt) + self.expect(child.before, exe=False, + patterns = ['Debugger \(instance: .*, id: \d\)']) + + child.sendline('print lldb.target') + child.expect_exact(python_prompt) + self.expect(child.before, exe=False, + substrs = ['a.out']) + + child.sendline('print lldb.process') + child.expect_exact(python_prompt) + self.expect(child.before, exe=False, + patterns = ['SBProcess: pid = \d+, state = stopped, threads = \d, executable = a.out']) + + child.sendline('print lldb.thread') + child.expect_exact(python_prompt) + self.expect(child.before, exe=False, + patterns = ['SBThread: tid = 0x[0-9a-f]+']) + + child.sendline('print lldb.frame') + child.expect_exact(python_prompt) + self.expect(child.before, exe=False, + substrs = ['frame #0', 'main.c:%d' % self.line]) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/embedded_interpreter/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/embedded_interpreter/main.c?rev=130904&view=auto ============================================================================== --- lldb/trunk/test/embedded_interpreter/main.c (added) +++ lldb/trunk/test/embedded_interpreter/main.c Wed May 4 19:36:31 2011 @@ -0,0 +1,6 @@ +#include + +int main(int argc, char const *argv[]) { + printf("Hello world.\n"); + return 0; +} Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=130904&r1=130903&r2=130904&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Wed May 4 19:36:31 2011 @@ -529,6 +529,7 @@ # This is for the case of directly spawning 'lldb' and interacting with it # using pexpect. self.child = None + self.child_in_script_interpreter = False # There is no process associated with the debugger as yet. # See also self.tearDown() where it checks whether self.process has a @@ -682,6 +683,9 @@ if self.child and self.child.isalive(): with recording(self, traceAlways) as sbuf: print >> sbuf, "tearing down the child process...." + if self.child_in_script_interpreter: + self.child.sendline('quit()') + self.child.expect_exact('(lldb) ') self.child.sendline('quit') try: self.child.expect(pexpect.EOF) From jingham at apple.com Wed May 4 20:03:36 2011 From: jingham at apple.com (Jim Ingham) Date: Thu, 05 May 2011 01:03:36 -0000 Subject: [Lldb-commits] [lldb] r130907 - /lldb/trunk/source/Commands/CommandObjectTarget.cpp Message-ID: <20110505010337.04E892A6C12C@llvm.org> Author: jingham Date: Wed May 4 20:03:36 2011 New Revision: 130907 URL: http://llvm.org/viewvc/llvm-project?rev=130907&view=rev Log: Fix the "target stop-hook add" input reader so that it won't say the stop hook was added if the input was interrupted. Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=130907&r1=130906&r2=130907&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Wed May 4 20:03:36 2011 @@ -3077,6 +3077,7 @@ { File &out_file = reader.GetDebugger().GetOutputFile(); Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); + static bool got_interrupted; switch (notification) { @@ -3085,6 +3086,7 @@ if (reader.GetPrompt()) out_file.Printf ("%s", reader.GetPrompt()); out_file.Flush(); + got_interrupted = false; break; case eInputReaderDeactivate: @@ -3096,6 +3098,7 @@ out_file.Printf ("%s", reader.GetPrompt()); out_file.Flush(); } + got_interrupted = false; break; case eInputReaderAsynchronousOutputWritten: @@ -3125,6 +3128,7 @@ reader.SetIsDone (true); } + got_interrupted = true; break; case eInputReaderEndOfFile: @@ -3132,7 +3136,8 @@ break; case eInputReaderDone: - out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID()); + if (!got_interrupted) + out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID()); break; } From gclayton at apple.com Wed May 4 21:16:20 2011 From: gclayton at apple.com (Greg Clayton) Date: Thu, 05 May 2011 02:16:20 -0000 Subject: [Lldb-commits] [lldb] r130910 - /lldb/trunk/source/Commands/CommandObjectRegister.cpp Message-ID: <20110505021620.609DA2A6C12C@llvm.org> Author: gclayton Date: Wed May 4 21:16:20 2011 New Revision: 130910 URL: http://llvm.org/viewvc/llvm-project?rev=130910&view=rev Log: Always try and lookup the address in a register if it is encoded as an integer and the register byte size matches the size of a pointer. This removes the "--lookup" option. Modified: lldb/trunk/source/Commands/CommandObjectRegister.cpp Modified: lldb/trunk/source/Commands/CommandObjectRegister.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectRegister.cpp?rev=130910&r1=130909&r2=130910&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectRegister.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectRegister.cpp Wed May 4 21:16:20 2011 @@ -22,7 +22,9 @@ #include "lldb/Interpreter/NamedOptionValue.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; @@ -90,7 +92,8 @@ format = m_options.format; reg_data.Dump(&strm, 0, format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); - if (m_options.lookup_addresses && ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))) + if (((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) && + (reg_info->byte_size == reg_ctx->GetThread().GetProcess().GetAddressByteSize())) { addr_t reg_addr = reg_ctx->ReadRegisterAsUnsigned (reg, 0); if (reg_addr) @@ -101,9 +104,6 @@ strm.PutCString (" "); so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); } - else - { - } } } strm.EOL(); @@ -246,8 +246,7 @@ CommandOptions (CommandInterpreter &interpreter) : Options(interpreter), set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), - dump_all_sets (false, false), // Initial and default values are false - lookup_addresses (false, false) // Initial and default values are false + dump_all_sets (false, false) // Initial and default values are false { OptionParsingStarting(); } @@ -280,10 +279,6 @@ dump_all_sets.SetCurrentValue(true); break; - case 'l': - lookup_addresses.SetCurrentValue(true); - break; - default: error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); break; @@ -297,7 +292,6 @@ format = eFormatDefault; set_indexes.Clear(); dump_all_sets.Clear(); - lookup_addresses.Clear(); } const OptionDefinition* @@ -314,7 +308,6 @@ lldb::Format format; OptionValueArray set_indexes; OptionValueBoolean dump_all_sets; - OptionValueBoolean lookup_addresses; }; CommandOptions m_options; @@ -324,7 +317,6 @@ CommandObjectRegisterRead::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format to use when dumping register values."}, - { LLDB_OPT_SET_ALL, false, "lookup", 'l', no_argument , NULL, 0, eArgTypeNone , "Lookup the register values as addresses and show that each value maps to in the address space."}, { LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, { LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."}, { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } From johnny.chen at apple.com Thu May 5 13:50:56 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 05 May 2011 18:50:56 -0000 Subject: [Lldb-commits] [lldb] r130940 - /lldb/trunk/test/lldbutil.py Message-ID: <20110505185056.311D72A6C12C@llvm.org> Author: johnny Date: Thu May 5 13:50:56 2011 New Revision: 130940 URL: http://llvm.org/viewvc/llvm-project?rev=130940&view=rev Log: Change the process iteration pattern to a more concise: for thread in process: print >> output, print_stacktrace(thread, string_buffer=True) Modified: lldb/trunk/test/lldbutil.py Modified: lldb/trunk/test/lldbutil.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbutil.py?rev=130940&r1=130939&r2=130940&view=diff ============================================================================== --- lldb/trunk/test/lldbutil.py (original) +++ lldb/trunk/test/lldbutil.py Thu May 5 13:50:56 2011 @@ -399,8 +399,8 @@ print >> output, "Stack traces for " + repr(process) - for i in range(process.GetNumThreads()): - print >> output, print_stacktrace(process.GetThreadAtIndex(i), string_buffer=True) + for thread in process: + print >> output, print_stacktrace(thread, string_buffer=True) if string_buffer: return output.getvalue() From johnny.chen at apple.com Thu May 5 17:17:32 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 05 May 2011 22:17:32 -0000 Subject: [Lldb-commits] [lldb] r130960 - /lldb/trunk/test/lldbtest.py Message-ID: <20110505221732.288EC2A6C12C@llvm.org> Author: johnny Date: Thu May 5 17:17:31 2011 New Revision: 130960 URL: http://llvm.org/viewvc/llvm-project?rev=130960&view=rev Log: Use standard lldb enum -- lldb.eStopReasonBreakpoint. Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=130960&r1=130959&r2=130960&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu May 5 17:17:31 2011 @@ -875,7 +875,7 @@ with recording(self, trace) as sbuf: print >> sbuf, "StopReason =", stop_reason_to_str(SR) - if SR == StopReasonEnum("Breakpoint"): + if SR == lldb.eStopReasonBreakpoint: frame = thread.GetFrameAtIndex(0) name = frame.GetFunction().GetName() with recording(self, trace) as sbuf: From johnny.chen at apple.com Thu May 5 18:20:24 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 05 May 2011 23:20:24 -0000 Subject: [Lldb-commits] [lldb] r130963 - /lldb/trunk/test/lldbtest.py Message-ID: <20110505232103.A51B62A6C12D@llvm.org> Author: johnny Date: Thu May 5 18:18:53 2011 New Revision: 130963 URL: http://llvm.org/viewvc/llvm-project?rev=130963&view=rev Log: Add comment for self.child_in_script_interpreter. Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=130963&r1=130962&r2=130963&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu May 5 18:18:53 2011 @@ -526,9 +526,12 @@ # We want our debugger to be synchronous. self.dbg.SetAsync(False) - # This is for the case of directly spawning 'lldb' and interacting with it - # using pexpect. + # This is for the case of directly spawning 'lldb' and interacting with + # it using pexpect. self.child = None + # If the child is interacting with the embedded script interpreter, + # there are two exits required, first one to quit the embedded script + # interpreter and second one to quit the lldb command interpreter. self.child_in_script_interpreter = False # There is no process associated with the debugger as yet. From johnny.chen at apple.com Thu May 5 18:32:40 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 05 May 2011 23:32:40 -0000 Subject: [Lldb-commits] [lldb] r130965 - /lldb/trunk/test/lldbtest.py Message-ID: <20110505233251.BAE402A6C12C@llvm.org> Author: johnny Date: Thu May 5 18:28:17 2011 New Revision: 130965 URL: http://llvm.org/viewvc/llvm-project?rev=130965&view=rev Log: Comment. Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=130965&r1=130964&r2=130965&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu May 5 18:28:17 2011 @@ -530,8 +530,9 @@ # it using pexpect. self.child = None # If the child is interacting with the embedded script interpreter, - # there are two exits required, first one to quit the embedded script - # interpreter and second one to quit the lldb command interpreter. + # there are two exits required during tear down, first to quit the + # embedded script interpreter and second to quit the lldb command + # interpreter. self.child_in_script_interpreter = False # There is no process associated with the debugger as yet. From gclayton at apple.com Thu May 5 18:33:02 2011 From: gclayton at apple.com (Greg Clayton) Date: Thu, 05 May 2011 23:33:02 -0000 Subject: [Lldb-commits] [lldb] r130966 - in /lldb/trunk: include/lldb/Core/ValueObject.h source/Core/ValueObject.cpp Message-ID: <20110505233302.59D2C2A6C12D@llvm.org> Author: gclayton Date: Thu May 5 18:32:56 2011 New Revision: 130966 URL: http://llvm.org/viewvc/llvm-project?rev=130966&view=rev Log: Added the ability to cast pointer types to another type, no matter what the ValueObject is, as long as the ValueObject that is being asked to be casted is a pointer itself. Modified: lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/source/Core/ValueObject.cpp Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=130966&r1=130965&r2=130966&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Thu May 5 18:32:56 2011 @@ -377,6 +377,14 @@ virtual lldb::ValueObjectSP AddressOf (Error &error); + virtual lldb::ValueObjectSP + CastPointerType (const char *name, + ClangASTType &ast_type); + + virtual lldb::ValueObjectSP + CastPointerType (const char *name, + lldb::TypeSP &type_sp); + // The backing bits of this value object were updated, clear any value // values, summaries or descriptions so we refetch them. virtual void Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=130966&r1=130965&r2=130966&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Thu May 5 18:32:56 2011 @@ -24,6 +24,7 @@ #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectDynamicValue.h" #include "lldb/Core/ValueObjectList.h" +#include "lldb/Core/ValueObjectMemory.h" #include "lldb/Host/Endian.h" @@ -1498,6 +1499,48 @@ return m_addr_of_valobj_sp; } + +lldb::ValueObjectSP +ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type) +{ + lldb::ValueObjectSP valobj_sp; + AddressType address_type; + const bool scalar_is_load_address = true; + lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address); + + if (ptr_value != LLDB_INVALID_ADDRESS) + { + Address ptr_addr (NULL, ptr_value); + + valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(), + name, + ptr_addr, + clang_ast_type); + } + return valobj_sp; +} + +lldb::ValueObjectSP +ValueObject::CastPointerType (const char *name, TypeSP &type_sp) +{ + lldb::ValueObjectSP valobj_sp; + AddressType address_type; + const bool scalar_is_load_address = true; + lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address); + + if (ptr_value != LLDB_INVALID_ADDRESS) + { + Address ptr_addr (NULL, ptr_value); + + valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(), + name, + ptr_addr, + type_sp); + } + return valobj_sp; +} + + ValueObject::EvaluationPoint::EvaluationPoint () : m_thread_id (LLDB_INVALID_UID), m_stop_id (0) From jingham at apple.com Fri May 6 13:34:33 2011 From: jingham at apple.com (Jim Ingham) Date: Fri, 06 May 2011 18:34:33 -0000 Subject: [Lldb-commits] [lldb] r131003 - /lldb/trunk/source/lldb-log.cpp Message-ID: <20110506183433.B02082A6C12C@llvm.org> Author: jingham Date: Fri May 6 13:34:33 2011 New Revision: 131003 URL: http://llvm.org/viewvc/llvm-project?rev=131003&view=rev Log: Make the log message & setter match for "dyld/shlib". The "ListLogCategories" output should really be auto-generated from the settings so you can't make this sort of mistake... Modified: lldb/trunk/source/lldb-log.cpp Modified: lldb/trunk/source/lldb-log.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=131003&r1=131002&r2=131003&view=diff ============================================================================== --- lldb/trunk/source/lldb-log.cpp (original) +++ lldb/trunk/source/lldb-log.cpp Fri May 6 13:34:33 2011 @@ -233,7 +233,7 @@ "\tprocess - log process events and activities\n" "\tthread - log thread events and activities\n" "\tscript - log events about the script interpreter\n" - "\tshlib - log shared library related activities\n" + "\dyld - log shared library related activities\n" "\tstate - log private and public process state changes\n" "\tstep - log step related activities\n" "\tunwind - log stack unwind activities\n" From johnny.chen at apple.com Fri May 6 15:30:22 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 06 May 2011 20:30:22 -0000 Subject: [Lldb-commits] [lldb] r131011 - in /lldb/trunk/test: dotest.py lldbtest.py Message-ID: <20110506203022.5AB522A6C12C@llvm.org> Author: johnny Date: Fri May 6 15:30:22 2011 New Revision: 131011 URL: http://llvm.org/viewvc/llvm-project?rev=131011&view=rev Log: For a test with unexpected success status, we also dump its session info into a unique file. 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=131011&r1=131010&r2=131011&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Fri May 6 15:30:22 2011 @@ -812,7 +812,8 @@ sdir_name = timestamp os.environ["LLDB_SESSION_DIRNAME"] = sdir_name -sys.stderr.write("\nSession logs for test failures/errors will go into directory '%s'\n" % sdir_name) +sys.stderr.write("\nSession logs for test failures/errors/unexpected successes" + " will go into directory '%s'\n" % sdir_name) sys.stderr.write("Command invoked: %s\n" % getMyCommandLine()) # @@ -979,6 +980,14 @@ if method: method() + def addUnexpectedSuccess(self, test): + global sdir_has_content + sdir_has_content = True + super(LLDBTestResult, self).addUnexpectedSuccess(test) + method = getattr(test, "markUnexpectedSuccess", None) + if method: + method() + # Invoke the test runner. if count == 1: result = unittest2.TextTestRunner(stream=sys.stderr, @@ -998,7 +1007,8 @@ if sdir_has_content: - sys.stderr.write("Session logs for test failures/errors can be found in directory '%s'\n" % sdir_name) + sys.stderr.write("Session logs for test failures/errors/unexpected successes" + " can be found in directory '%s'\n" % sdir_name) # Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined. # This should not be necessary now. Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=131011&r1=131010&r2=131011&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri May 6 15:30:22 2011 @@ -563,9 +563,11 @@ # initially. If the test errored/failed, the session info # (self.session) is then dumped into a session specific file for # diagnosis. - self.__errored__ = False - self.__failed__ = False - self.__expected__ = False + self.__errored__ = False + self.__failed__ = False + self.__expected__ = False + # We are also interested in unexpected success. + self.__unexpected__ = False # See addTearDownHook(self, hook) which allows the client to add a hook # function to be run during tearDown() time. @@ -599,6 +601,15 @@ # Once by the Python unittest framework, and a second time by us. print >> sbuf, "expected failure" + def markUnexpectedSuccess(self): + """Callback invoked when an unexpected success occurred.""" + self.__unexpected__ = True + with recording(self, False) as sbuf: + # False because there's no need to write "unexpected success" to the + # stderr twice. + # Once by the Python unittest framework, and a second time by us. + print >> sbuf, "unexpected success" + def dumpSessionInfo(self): """ Dump the debugger interactions leading to a test error/failure. This @@ -628,13 +639,16 @@ elif self.__expected__: pairs = lldb.test_result.expectedFailures prefix = 'ExpectedFailure' + elif self.__unexpected__: + prefix = "UnexpectedSuccess" else: # Simply return, there's no session info to dump! return - for test, traceback in pairs: - if test is self: - print >> self.session, traceback + if not self.__unexpected__: + for test, traceback in pairs: + if test is self: + print >> self.session, traceback dname = os.path.join(os.environ["LLDB_TEST"], os.environ["LLDB_SESSION_DIRNAME"]) From ctice at apple.com Fri May 6 16:42:20 2011 From: ctice at apple.com (Caroline Tice) Date: Fri, 06 May 2011 21:42:20 -0000 Subject: [Lldb-commits] [lldb] r131020 - in /lldb/trunk: include/lldb/Interpreter/CommandInterpreter.h source/Commands/CommandObjectCommands.cpp source/Interpreter/CommandInterpreter.cpp Message-ID: <20110506214227.803C52A6C12C@llvm.org> Author: ctice Date: Fri May 6 16:37:15 2011 New Revision: 131020 URL: http://llvm.org/viewvc/llvm-project?rev=131020&view=rev Log: Replace calls to HandleCommand in lldb core with more appropriate direct function calls. As part of this, collect code that processes arguments & options for aliases into a single function. Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=131020&r1=131019&r2=131020&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Fri May 6 16:37:15 2011 @@ -90,6 +90,12 @@ OptionArgVectorSP GetAliasOptions (const char *alias_name); + + bool + ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, + const char *options_args, + OptionArgVectorSP &option_arg_vector_sp); + void RemoveAliasOptions (const char *alias_name); Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=131020&r1=131019&r2=131020&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Fri May 6 16:37:15 2011 @@ -351,33 +351,13 @@ OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); - // Check to see if there's anything left in the input command string. - if (raw_command_string.size() > 0) + CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); + + if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) { - - // Check to see if the command being aliased can take any command options. - Options *options = cmd_obj->GetOptions(); - if (options) - { - // See if any options were specified as part of the alias; if so, handle them appropriately - options->NotifyOptionParsingStarting (); - Args tmp_args (raw_command_string.c_str()); - args.Unshift ("dummy_arg"); - args.ParseAliasOptions (*options, result, option_arg_vector, raw_command_string); - args.Shift (); - if (result.Succeeded()) - options->VerifyPartialOptions (result); - if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) - { - result.AppendError ("Unable to create requested alias.\n"); - return false; - } - } - // Anything remaining must be plain raw input. Push it in as a single raw input argument. - if (raw_command_string.size() > 0) - option_arg_vector->push_back (OptionArgPair ("", - OptionArgValue (-1, - raw_command_string))); + result.AppendError ("Unable to create requested alias.\n"); + result.SetStatus (eReturnStatusFailed); + return false; } // Create the alias @@ -394,7 +374,6 @@ alias_command.c_str()); } - CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); if (cmd_obj_sp) { m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); @@ -483,37 +462,19 @@ if (args.GetArgumentCount () > 0) { - if ((!use_subcommand && (cmd_obj->GetOptions() != NULL)) - || (use_subcommand && (sub_cmd_obj->GetOptions() != NULL))) - { - Options *options; - if (use_subcommand) - options = sub_cmd_obj->GetOptions(); - else - options = cmd_obj->GetOptions(); - options->NotifyOptionParsingStarting (); - std::string empty_string; - args.Unshift ("dummy_arg"); - args.ParseAliasOptions (*options, result, option_arg_vector, empty_string); - args.Shift (); - if (result.Succeeded()) - options->VerifyPartialOptions (result); - if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) - { - result.AppendError ("Unable to create requested command alias.\n"); - return false; - } - } - - // Anything remaining in args must be a plain argument. - - argc = args.GetArgumentCount(); - for (size_t i = 0; i < argc; ++i) - if (strcmp (args.GetArgumentAtIndex (i), "") != 0) - option_arg_vector->push_back - (OptionArgPair ("", - OptionArgValue (-1, - std::string (args.GetArgumentAtIndex (i))))); + CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); + if (use_subcommand) + tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); + + std::string args_string; + args.GetCommandString (args_string); + + if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) + { + result.AppendError ("Unable to create requested alias.\n"); + result.SetStatus (eReturnStatusFailed); + return false; + } } // Create the alias. Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=131020&r1=131019&r2=131020&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri May 6 16:37:15 2011 @@ -39,6 +39,7 @@ #include "../Commands/CommandObjectVersion.h" #include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/InputReader.h" #include "lldb/Core/Stream.h" @@ -92,33 +93,111 @@ LoadCommandDictionary (); // Set up some initial aliases. - HandleCommand ("command alias q quit", false, result); - HandleCommand ("command alias run process launch --", false, result); - HandleCommand ("command alias r process launch --", false, result); - HandleCommand ("command alias c process continue", false, result); - HandleCommand ("command alias continue process continue", false, result); - HandleCommand ("command alias expr expression", false, result); - HandleCommand ("command alias exit quit", false, result); - HandleCommand ("command alias b _regexp-break", false, result); - HandleCommand ("command alias bt thread backtrace", false, result); - HandleCommand ("command alias si thread step-inst", false, result); - HandleCommand ("command alias step thread step-in", false, result); - HandleCommand ("command alias s thread step-in", false, result); - HandleCommand ("command alias next thread step-over", false, result); - HandleCommand ("command alias n thread step-over", false, result); - HandleCommand ("command alias f thread step-out", false, result); - HandleCommand ("command alias finish thread step-out", false, result); - HandleCommand ("command alias x memory read", false, result); - HandleCommand ("command alias l source list", false, result); - HandleCommand ("command alias list source list", false, result); - HandleCommand ("command alias p expression --", false, result); - HandleCommand ("command alias print expression --", false, result); - HandleCommand ("command alias po expression -o --", false, result); - HandleCommand ("command alias up _regexp-up", false, result); - HandleCommand ("command alias down _regexp-down", false, result); - HandleCommand ("command alias file target create", false, result); - HandleCommand ("command alias image target modules", false, result); + CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false); + if (cmd_obj_sp) + { + AddAlias ("q", cmd_obj_sp); + AddAlias ("exit", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact ("process continue", false); + if (cmd_obj_sp) + { + AddAlias ("c", cmd_obj_sp); + AddAlias ("continue", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact ("_regexp-break",false); + if (cmd_obj_sp) + AddAlias ("b", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("thread backtrace", false); + if (cmd_obj_sp) + AddAlias ("bt", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("thread step-inst", false); + if (cmd_obj_sp) + AddAlias ("si", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("thread step-in", false); + if (cmd_obj_sp) + { + AddAlias ("s", cmd_obj_sp); + AddAlias ("step", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact ("thread step-over", false); + if (cmd_obj_sp) + { + AddAlias ("n", cmd_obj_sp); + AddAlias ("next", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact ("thread step-out", false); + if (cmd_obj_sp) + { + AddAlias ("f", cmd_obj_sp); + AddAlias ("finish", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact ("source list", false); + if (cmd_obj_sp) + { + AddAlias ("l", cmd_obj_sp); + AddAlias ("list", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact ("memory read", false); + if (cmd_obj_sp) + AddAlias ("x", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("_regexp-up", false); + if (cmd_obj_sp) + AddAlias ("up", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("_regexp-down", false); + if (cmd_obj_sp) + AddAlias ("down", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("target create", false); + if (cmd_obj_sp) + AddAlias ("file", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact ("target modules", false); + if (cmd_obj_sp) + AddAlias ("image", cmd_obj_sp); + + + OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector); + cmd_obj_sp = GetCommandSPExact ("expression", false); + if (cmd_obj_sp) + { + AddAlias ("expr", cmd_obj_sp); + + ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp); + AddAlias ("p", cmd_obj_sp); + AddAlias ("print", cmd_obj_sp); + AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp); + AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp); + + alias_arguments_vector_sp.reset (new OptionArgVector); + ProcessAliasOptionsArgs (cmd_obj_sp, "-o --", alias_arguments_vector_sp); + AddAlias ("po", cmd_obj_sp); + AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp); + } + + cmd_obj_sp = GetCommandSPExact ("process launch", false); + if (cmd_obj_sp) + { + alias_arguments_vector_sp.reset (new OptionArgVector); + ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp); + AddAlias ("r", cmd_obj_sp); + AddAlias ("run", cmd_obj_sp); + AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp); + AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp); + } + } const char * @@ -453,6 +532,59 @@ } bool +CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, + const char *options_args, + OptionArgVectorSP &option_arg_vector_sp) +{ + bool success = true; + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + + if (!options_args || (strlen (options_args) < 1)) + return true; + + std::string options_string (options_args); + Args args (options_args); + CommandReturnObject result; + // Check to see if the command being aliased can take any command options. + Options *options = cmd_obj_sp->GetOptions (); + if (options) + { + // See if any options were specified as part of the alias; if so, handle them appropriately. + options->NotifyOptionParsingStarting (); + args.Unshift ("dummy_arg"); + args.ParseAliasOptions (*options, result, option_arg_vector, options_string); + args.Shift (); + if (result.Succeeded()) + options->VerifyPartialOptions (result); + if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) + { + result.AppendError ("Unable to create requested alias.\n"); + return false; + } + } + + if (options_string.size() > 0) + { + if (cmd_obj_sp->WantsRawCommandString ()) + option_arg_vector->push_back (OptionArgPair ("", + OptionArgValue (-1, + options_string))); + else + { + int argc = args.GetArgumentCount(); + for (size_t i = 0; i < argc; ++i) + if (strcmp (args.GetArgumentAtIndex (i), "") != 0) + option_arg_vector->push_back + (OptionArgPair ("", + OptionArgValue (-1, + std::string (args.GetArgumentAtIndex (i))))); + } + } + + return success; +} + +bool CommandInterpreter::AliasExists (const char *cmd) { return m_alias_dict.find(cmd) != m_alias_dict.end(); From johnny.chen at apple.com Fri May 6 17:53:08 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 06 May 2011 22:53:08 -0000 Subject: [Lldb-commits] [lldb] r131033 - /lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py Message-ID: <20110506225308.D0A5C2A6C12C@llvm.org> Author: johnny Date: Fri May 6 17:53:08 2011 New Revision: 131033 URL: http://llvm.org/viewvc/llvm-project?rev=131033&view=rev Log: Fix wrong test method name due to cut-and-paste. Modified: lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py Modified: lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py?rev=131033&r1=131032&r2=131033&view=diff ============================================================================== --- lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py (original) +++ lldb/trunk/test/embedded_interpreter/TestConvenienceVariables.py Fri May 6 17:53:08 2011 @@ -16,8 +16,7 @@ self.buildDsym() self.convenience_variables() - @python_api_test - def test_with_dwarf_and_process_launch_api(self): + def test_with_dwarf_and_run_commands(self): """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" self.buildDwarf() self.convenience_variables() From johnny.chen at apple.com Fri May 6 18:26:12 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 06 May 2011 23:26:12 -0000 Subject: [Lldb-commits] [lldb] r131035 - in /lldb/trunk/test: lldbtest.py python_api/interpreter/ python_api/interpreter/Makefile python_api/interpreter/TestCommandInterpreterAPI.py python_api/interpreter/main.c Message-ID: <20110506232612.718C12A6C12C@llvm.org> Author: johnny Date: Fri May 6 18:26:12 2011 New Revision: 131035 URL: http://llvm.org/viewvc/llvm-project?rev=131035&view=rev Log: Add an API test script file for SBCommandInterpreter. Added: lldb/trunk/test/python_api/interpreter/ lldb/trunk/test/python_api/interpreter/Makefile lldb/trunk/test/python_api/interpreter/TestCommandInterpreterAPI.py lldb/trunk/test/python_api/interpreter/main.c Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=131035&r1=131034&r2=131035&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri May 6 18:26:12 2011 @@ -180,6 +180,8 @@ VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location" +VALID_COMMAND_INTERPRETER = "Got a valid command interpreter" + VALID_FILESPEC = "Got a valid filespec" VALID_MODULE = "Got a valid module" Added: lldb/trunk/test/python_api/interpreter/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/interpreter/Makefile?rev=131035&view=auto ============================================================================== --- lldb/trunk/test/python_api/interpreter/Makefile (added) +++ lldb/trunk/test/python_api/interpreter/Makefile Fri May 6 18:26:12 2011 @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/python_api/interpreter/TestCommandInterpreterAPI.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/interpreter/TestCommandInterpreterAPI.py?rev=131035&view=auto ============================================================================== --- lldb/trunk/test/python_api/interpreter/TestCommandInterpreterAPI.py (added) +++ lldb/trunk/test/python_api/interpreter/TestCommandInterpreterAPI.py Fri May 6 18:26:12 2011 @@ -0,0 +1,80 @@ +"""Test the SBCommandInterpreter APIs.""" + +import os +import unittest2 +import lldb +import pexpect +from lldbtest import * + +class CommandInterpreterAPICase(TestBase): + + mydir = os.path.join("python_api", "interpreter") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test + def test_with_dsym_and_run_command(self): + """Test the SBCommandInterpreter APIs.""" + self.buildDsym() + self.command_interpreter_api() + + @python_api_test + def test_with_dwarf_and_process_launch_api(self): + """Test the SBCommandInterpreter APIs.""" + self.buildDwarf() + self.command_interpreter_api() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break on inside main.cpp. + self.line = line_number('main.c', 'Hello world.') + + def command_interpreter_api(self): + """Test the SBCommandInterpreter APIs.""" + exe = os.path.join(os.getcwd(), "a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Retrieve the associated command interpreter from our debugger. + ci = self.dbg.GetCommandInterpreter() + self.assertTrue(ci.IsValid(), VALID_COMMAND_INTERPRETER) + + # Exercise some APIs.... + + self.assertTrue(ci.HasCommands()) + self.assertTrue(ci.HasAliases()) + self.assertTrue(ci.HasAliasOptions()) + self.assertTrue(ci.CommandExists("breakpoint")) + self.assertTrue(ci.CommandExists("target")) + self.assertTrue(ci.CommandExists("platform")) + self.assertTrue(ci.AliasExists("file")) + self.assertTrue(ci.AliasExists("run")) + self.assertTrue(ci.AliasExists("bt")) + + res = lldb.SBCommandReturnObject() + ci.HandleCommand("breakpoint set -f main.c -l %d" % self.line, res) + self.assertTrue(res.Succeeded()) + ci.HandleCommand("process launch", res) + self.assertTrue(res.Succeeded()) + + # Assigning to self.process so it gets cleaned up during test tear down. + self.process = ci.GetProcess() + self.assertTrue(self.process.IsValid()) + + import lldbutil + if self.process.GetState() != lldb.eStateStopped: + self.fail("Process should be in the 'stopped' state, " + "instead the actual state is: '%s'" % + lldbutil.state_type_to_str(self.process.GetState())) + + if self.TraceOn(): + lldbutil.print_stacktraces(self.process) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/python_api/interpreter/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/interpreter/main.c?rev=131035&view=auto ============================================================================== --- lldb/trunk/test/python_api/interpreter/main.c (added) +++ lldb/trunk/test/python_api/interpreter/main.c Fri May 6 18:26:12 2011 @@ -0,0 +1,6 @@ +#include + +int main(int argc, char const *argv[]) { + printf("Hello world.\n"); + return 0; +} From johnny.chen at apple.com Fri May 6 18:59:10 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 06 May 2011 23:59:10 -0000 Subject: [Lldb-commits] [lldb] r131038 - /lldb/trunk/test/load_unload/TestLoadUnload.py Message-ID: <20110506235910.6A9562A6C12C@llvm.org> Author: johnny Date: Fri May 6 18:59:10 2011 New Revision: 131038 URL: http://llvm.org/viewvc/llvm-project?rev=131038&view=rev Log: Modify the test case related to "target modules search-paths" as it suffers from code rotting. 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=131038&r1=131037&r2=131038&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Fri May 6 18:59:10 2011 @@ -21,8 +21,8 @@ self.line_d_function = line_number('d.c', '// Find this line number within d_dunction().') - def test_image_search_paths(self): - """Test image list after moving libd.dylib, and verifies that it works with 'target image-search-paths add'.""" + def test_modules_search_paths(self): + """Test target modules list after moving libd.dylib, and verifies that it works with 'target modules search-paths add'.""" # Invoke the default build rule. self.buildDefault() @@ -50,14 +50,18 @@ exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - self.expect("image list", + self.expect("target modules list", substrs = [old_dylib]) - self.expect("image list -t 3", + self.expect("target modules list -t 3", patterns = ["%s-[^-]*-[^-]*" % self.getArchitecture()]) - self.runCmd("target image-search-paths add %s %s" % (os.getcwd(), new_dir)) + self.runCmd("target modules search-paths add %s %s" % (os.getcwd(), new_dir)) + + self.expect("target modules search-paths list", + substrs = [os.getcwd(), new_dir]) + # Add teardown hook to clear image-search-paths after the test. - self.addTearDownHook(lambda: self.runCmd("target image-search-paths clear")) - self.expect("image list", "LLDB successfully locates the relocated dynamic library", + self.addTearDownHook(lambda: self.runCmd("target modules search-paths clear")) + self.expect("target modules list", "LLDB successfully locates the relocated dynamic library", substrs = [new_dylib]) From jingham at apple.com Fri May 6 19:10:58 2011 From: jingham at apple.com (Jim Ingham) Date: Sat, 07 May 2011 00:10:58 -0000 Subject: [Lldb-commits] [lldb] r131039 - /lldb/trunk/source/Core/ValueObject.cpp Message-ID: <20110507001058.4C1682A6C12C@llvm.org> Author: jingham Date: Fri May 6 19:10:58 2011 New Revision: 131039 URL: http://llvm.org/viewvc/llvm-project?rev=131039&view=rev Log: Fix an unitialized pointer in ValueObject::CreateChildAtIndex. Modified: lldb/trunk/source/Core/ValueObject.cpp Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=131039&r1=131038&r2=131039&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Fri May 6 19:10:58 2011 @@ -389,7 +389,7 @@ ValueObject * ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) { - ValueObject *valobj; + ValueObject *valobj = NULL; if (UpdateValueIfNeeded()) { From jingham at apple.com Fri May 6 20:03:33 2011 From: jingham at apple.com (Jim Ingham) Date: Sat, 07 May 2011 01:03:33 -0000 Subject: [Lldb-commits] [lldb] r131041 - /lldb/trunk/source/lldb-log.cpp Message-ID: <20110507010333.5B82A2A6C12C@llvm.org> Author: jingham Date: Fri May 6 20:03:33 2011 New Revision: 131041 URL: http://llvm.org/viewvc/llvm-project?rev=131041&view=rev Log: Deleted one too many characters... Modified: lldb/trunk/source/lldb-log.cpp Modified: lldb/trunk/source/lldb-log.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=131041&r1=131040&r2=131041&view=diff ============================================================================== --- lldb/trunk/source/lldb-log.cpp (original) +++ lldb/trunk/source/lldb-log.cpp Fri May 6 20:03:33 2011 @@ -233,7 +233,7 @@ "\tprocess - log process events and activities\n" "\tthread - log thread events and activities\n" "\tscript - log events about the script interpreter\n" - "\dyld - log shared library related activities\n" + "\tdyld - log shared library related activities\n" "\tstate - log private and public process state changes\n" "\tstep - log step related activities\n" "\tunwind - log stack unwind activities\n" From scallanan at apple.com Fri May 6 20:06:41 2011 From: scallanan at apple.com (Sean Callanan) Date: Sat, 07 May 2011 01:06:41 -0000 Subject: [Lldb-commits] [lldb] r131042 - in /lldb/trunk: include/lldb/Expression/ source/Expression/ source/Target/ Message-ID: <20110507010642.1E9952A6C12D@llvm.org> Author: spyffe Date: Fri May 6 20:06:41 2011 New Revision: 131042 URL: http://llvm.org/viewvc/llvm-project?rev=131042&view=rev Log: Made expressions that are just casts of pointer variables be evaluated statically. Also fixed a bug that caused the results of statically-evaluated expressions to be materialized improperly. This bug also removes some duplicate code. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/ClangExpressionParser.h lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h lldb/trunk/include/lldb/Expression/ClangUserExpression.h lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/ClangExpressionParser.cpp lldb/trunk/source/Expression/ClangFunction.cpp lldb/trunk/source/Expression/ClangUserExpression.cpp lldb/trunk/source/Expression/ClangUtilityFunction.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Target/Process.cpp lldb/trunk/source/Target/Target.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Fri May 6 20:06:41 2011 @@ -127,6 +127,28 @@ const llvm::APInt& value); //------------------------------------------------------------------ + /// [Used by IRForTarget] Cast an existing variable given a Decl and + /// a type. + /// + /// @param[in] name + /// The name of the new variable + /// + /// @param[in] decl + /// The Clang variable declaration for the original variable, + /// which must be looked up in the map + /// + /// @param[in] type + /// The desired type of the variable after casting + /// + /// @return + /// The created variable + //------------------------------------------------------------------ + lldb::ClangExpressionVariableSP + BuildCastVariable (const ConstString &name, + clang::VarDecl *decl, + lldb_private::TypeFromParser type); + + //------------------------------------------------------------------ /// [Used by IRForTarget] Add a variable to the list of persistent /// variables for the process. /// @@ -620,7 +642,7 @@ /// @return /// The LLDB Variable found, or NULL if none was found. //------------------------------------------------------------------ - Variable * + lldb::VariableSP FindVariableInScope (StackFrame &frame, const ConstString &name, TypeFromUser *type = NULL); @@ -656,7 +678,7 @@ //------------------------------------------------------------------ Value * GetVariableValue (ExecutionContext &exe_ctx, - Variable *var, + lldb::VariableSP var, clang::ASTContext *parser_ast_context, TypeFromUser *found_type = NULL, TypeFromParser *parser_type = NULL); @@ -673,7 +695,7 @@ //------------------------------------------------------------------ void AddOneVariable (NameSearchContext &context, - Variable *var); + lldb::VariableSP var); //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given Modified: lldb/trunk/include/lldb/Expression/ClangExpressionParser.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionParser.h?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionParser.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionParser.h Fri May 6 20:06:41 2011 @@ -103,9 +103,13 @@ /// The execution context to write the function into. /// /// @param[out] const_result - /// If non-NULL, the result of the expression is constant, and the + /// If the result of the expression is constant, and the /// expression has no side effects, this is set to the result of the - /// expression. + /// expression. + /// + /// @param[in] jit_only_if_needed + /// True if the expression must be compiled, regardless of whether a + /// constant result could be extracted from the IR or no. /// /// @return /// An error code indicating the success or failure of the operation. @@ -116,7 +120,8 @@ lldb::addr_t &func_addr, lldb::addr_t &func_end, ExecutionContext &exe_ctx, - lldb::ClangExpressionVariableSP *const_result = NULL); + lldb::ClangExpressionVariableSP &const_result, + bool jit_only_if_needed = false); //------------------------------------------------------------------ /// Disassemble the machine code for a JITted function from the target Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Fri May 6 20:06:41 2011 @@ -97,7 +97,8 @@ m_parser_type(), m_named_decl (NULL), m_llvm_value (NULL), - m_lldb_value (NULL) + m_lldb_value (NULL), + m_lldb_var () { } @@ -105,6 +106,7 @@ const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable + lldb::VariableSP m_lldb_var; ///< The original variable for this variable private: DISALLOW_COPY_AND_ASSIGN (ParserVars); Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original) +++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Fri May 6 20:06:41 2011 @@ -85,11 +85,6 @@ /// True if the resulting persistent variable should reside in /// target memory, if applicable. /// - /// @param[out] const_result - /// If this is non-NULL, the expression has no side effects, and - /// the expression returns a constant result, then that result - /// is put into this variable. - /// /// @return /// True on success (no errors); false otherwise. //------------------------------------------------------------------ @@ -97,8 +92,7 @@ Parse (Stream &error_stream, ExecutionContext &exe_ctx, TypeFromUser desired_type, - bool keep_result_in_memory, - lldb::ClangExpressionVariableSP *const_result = NULL); + bool keep_result_in_memory); //------------------------------------------------------------------ /// Execute the parsed expression @@ -133,7 +127,6 @@ Execute (Stream &error_stream, ExecutionContext &exe_ctx, bool discard_on_error, - bool keep_in_memory, ClangUserExpressionSP &shared_ptr_to_me, lldb::ClangExpressionVariableSP &result); @@ -244,10 +237,6 @@ /// True if the thread's state should be restored in the case /// of an error. /// - /// @param[in] keep_in_memory - /// True if the resulting persistent variable should reside in - /// target memory, if applicable. - /// /// @param[in] expr_cstr /// A C string containing the expression to be evaluated. /// @@ -264,7 +253,6 @@ static ExecutionResults Evaluate (ExecutionContext &exe_ctx, bool discard_on_error, - bool keep_in_memory, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp); @@ -289,13 +277,15 @@ TypeFromUser m_desired_type; ///< The type to coerce the expression's result to. If NULL, inferred from the expression. std::auto_ptr m_expr_decl_map; ///< The map to use when parsing and materializing the expression. - std::auto_ptr m_local_variables; ///< The local expression variables, if the expression is DWARF. + std::auto_ptr m_local_variables; ///< The local expression variables, if the expression is DWARF. std::auto_ptr m_dwarf_opcodes; ///< The DWARF opcodes for the expression. May be NULL. bool m_cplusplus; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method). bool m_objectivec; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method). bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression doesn't really use them and they can be NULL. bool m_const_object; ///< True if "this" is const. + + lldb::ClangExpressionVariableSP m_const_result; ///< The statically-computed result of the expression. NULL if it could not be computed statically or the expression has side effects. }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Fri May 6 20:06:41 2011 @@ -21,9 +21,11 @@ class CallInst; class Constant; class Function; + class GlobalValue; class GlobalVariable; class Instruction; class Module; + class StoreInst; class Value; } @@ -62,10 +64,9 @@ /// are resolved. /// /// @param[in] const_result - /// If non-NULL, a shared pointer to a ClangExpressionVariable that - /// is populated with the statically-computed result of the function, - /// if it has no side-effects and the result can be computed - /// statically. + /// This variable is populated with the statically-computed result + /// of the function, if it has no side-effects and the result can + /// be computed statically. /// /// @param[in] error_stream /// If non-NULL, a stream on which errors can be printed. @@ -75,7 +76,7 @@ //------------------------------------------------------------------ IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars, - lldb::ClangExpressionVariableSP *const_result, + lldb::ClangExpressionVariableSP &const_result, lldb_private::Stream *error_stream, const char* func_name = "$__lldb_expr"); @@ -153,6 +154,24 @@ /// constant, assuming it can be evaluated. The result variable /// will be reset to NULL later if the expression has side effects. /// + /// @param[in] llvm_module + /// The module currently being processed. + /// + /// @param[in] global + /// The global entity to search for + /// + /// @return + /// The corresponding variable declaration + //------------------------------------------------------------------ + clang::NamedDecl * + DeclForGlobal (llvm::Module &llvm_module, + llvm::GlobalValue *global); + + //------------------------------------------------------------------ + /// Set the constant result variable m_const_result to the provided + /// constant, assuming it can be evaluated. The result variable + /// will be reset to NULL later if the expression has side effects. + /// /// @param[in] initializer /// The constant initializer for the variable. /// @@ -161,9 +180,6 @@ /// /// @param[in] type /// The Clang type of the result variable. - /// - /// @return - /// True on success; false otherwise //------------------------------------------------------------------ void MaybeSetConstantResult (llvm::Constant *initializer, @@ -171,6 +187,21 @@ lldb_private::TypeFromParser type); //------------------------------------------------------------------ + /// If the IR represents a cast of a variable, set m_const_result + /// to the result of the cast. The result variable will be reset to + /// NULL latger if the expression has side effects. + /// + /// @param[in] llvm_module + /// The module currently being processed. + /// + /// @param[in] type + /// The Clang type of the result variable. + //------------------------------------------------------------------ + void + MaybeSetCastResult (llvm::Module &llvm_module, + lldb_private::TypeFromParser type); + + //------------------------------------------------------------------ /// The top-level pass implementation /// /// @param[in] llvm_module @@ -476,10 +507,11 @@ lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type - lldb::ClangExpressionVariableSP *m_const_result; ///< If non-NULL, this value should be set to the return value of the expression if it is constant and the expression has no side effects + lldb::ClangExpressionVariableSP &m_const_result; ///< This value should be set to the return value of the expression if it is constant and the expression has no side effects lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed bool m_has_side_effects; ///< True if the function's result cannot be simply determined statically + llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL. bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in ASTResultSynthesizer::SynthesizeBodyResult) private: Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri May 6 20:06:41 2011 @@ -139,7 +139,7 @@ type.GetASTContext(), type.GetOpaqueQualType()), context); - + if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx->GetBestExecutionContextScope (), name, user_type, @@ -194,7 +194,78 @@ } pvar_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried; + pvar_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; + pvar_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; + + return pvar_sp; +} + +lldb::ClangExpressionVariableSP +ClangExpressionDeclMap::BuildCastVariable (const ConstString &name, + clang::VarDecl *decl, + lldb_private::TypeFromParser type) +{ + assert (m_parser_vars.get()); + + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + ExecutionContext *exe_ctx = m_parser_vars->m_exe_ctx; + clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + + ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl)); + + if (!var_sp) + var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl); + + if (!var_sp) + return ClangExpressionVariableSP(); + + TypeFromUser user_type(ClangASTContext::CopyType(context, + type.GetASTContext(), + type.GetOpaqueQualType()), + context); + + TypeFromUser var_type = var_sp->GetTypeFromUser(); + + VariableSP var = FindVariableInScope (*exe_ctx->frame, var_sp->GetName(), &var_type); + + if (!var) + return lldb::ClangExpressionVariableSP(); // but we should handle this; it may be a persistent variable + + ValueObjectSP var_valobj = exe_ctx->frame->GetValueObjectForFrameVariable(var, lldb::eNoDynamicValues); + if (!var_valobj) + return lldb::ClangExpressionVariableSP(); + + ValueObjectSP var_casted_valobj = var_valobj->CastPointerType(name.GetCString(), user_type); + + if (!var_casted_valobj) + return lldb::ClangExpressionVariableSP(); + + if (log) + { + StreamString my_stream_string; + + ClangASTType::DumpTypeDescription (var_type.GetASTContext(), + var_type.GetOpaqueQualType(), + &my_stream_string); + + + log->Printf("Building cast variable to type: %s", my_stream_string.GetString().c_str()); + } + + ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->CreatePersistentVariable (var_casted_valobj); + + if (!pvar_sp) + return lldb::ClangExpressionVariableSP(); + + if (pvar_sp != m_parser_vars->m_persistent_vars->GetVariable(name)) + return lldb::ClangExpressionVariableSP(); + + pvar_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried; + pvar_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; + pvar_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; + return pvar_sp; } @@ -535,9 +606,9 @@ return false; } - Variable *object_ptr_var = FindVariableInScope (*exe_ctx.frame, - object_name, - (suppress_type_check ? NULL : &m_struct_vars->m_object_pointer_type)); + VariableSP object_ptr_var = FindVariableInScope (*exe_ctx.frame, + object_name, + (suppress_type_check ? NULL : &m_struct_vars->m_object_pointer_type)); if (!object_ptr_var) { @@ -1122,7 +1193,7 @@ if (log) log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), (uint64_t)mem); } - else if (!var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference) + else if (!(var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) { err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported."); return false; @@ -1153,7 +1224,7 @@ const ConstString &name(expr_var->GetName()); TypeFromUser type(expr_var->GetTypeFromUser()); - Variable *var = FindVariableInScope (*exe_ctx.frame, name, &type); + VariableSP var = FindVariableInScope (*exe_ctx.frame, name, &type); if (!var) { @@ -1495,7 +1566,7 @@ return true; } -Variable * +lldb::VariableSP ClangExpressionDeclMap::FindVariableInScope ( StackFrame &frame, @@ -1508,7 +1579,7 @@ VariableList *var_list = frame.GetVariableList(true); if (!var_list) - return NULL; + return lldb::VariableSP(); lldb::VariableSP var_sp (var_list->FindVariable(name)); @@ -1543,17 +1614,17 @@ if (type->GetASTContext() == var_sp->GetType()->GetClangAST()) { if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangFullType())) - return NULL; + return lldb::VariableSP(); } else { if (log) log->PutCString("Skipping a candidate variable because of different AST contexts"); - return NULL; + return lldb::VariableSP(); } } - return var_sp.get(); + return var_sp; } // Interface for ClangASTSource @@ -1590,7 +1661,7 @@ // doesn't start with our phony prefix of '$' if (name_unique_cstr[0] != '$') { - Variable *var = FindVariableInScope(*m_parser_vars->m_exe_ctx->frame, name); + VariableSP var = FindVariableInScope(*m_parser_vars->m_exe_ctx->frame, name); // If we found a variable in scope, no need to pull up function names if (var != NULL) @@ -1797,7 +1868,7 @@ ClangExpressionDeclMap::GetVariableValue ( ExecutionContext &exe_ctx, - Variable *var, + VariableSP var, clang::ASTContext *parser_ast_context, TypeFromUser *user_type, TypeFromParser *parser_type @@ -1904,7 +1975,7 @@ } void -ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, Variable* var) +ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP var) { assert (m_parser_vars.get()); @@ -1936,6 +2007,7 @@ entity->m_parser_vars->m_named_decl = var_decl; entity->m_parser_vars->m_llvm_value = NULL; entity->m_parser_vars->m_lldb_value = var_location; + entity->m_parser_vars->m_lldb_var = var; if (log) { Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Fri May 6 20:06:41 2011 @@ -456,7 +456,8 @@ lldb::addr_t &func_addr, lldb::addr_t &func_end, ExecutionContext &exe_ctx, - lldb::ClangExpressionVariableSP *const_result) + lldb::ClangExpressionVariableSP &const_result, + bool jit_only_if_needed) { func_allocation_addr = LLDB_INVALID_ADDRESS; func_addr = LLDB_INVALID_ADDRESS; @@ -512,6 +513,12 @@ return err; } + if (jit_only_if_needed && const_result.get()) + { + err.Clear(); + return err; + } + if (m_expr.NeedsValidation() && exe_ctx.process->GetDynamicCheckers()) { IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), function_name.c_str()); Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Fri May 6 20:06:41 2011 @@ -251,7 +251,9 @@ if (m_JITted) return true; - Error jit_error (m_parser->MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx)); + lldb::ClangExpressionVariableSP const_result; + + Error jit_error (m_parser->MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx, const_result)); if (!jit_error.Success()) return false; Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangUserExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangUserExpression.cpp Fri May 6 20:06:41 2011 @@ -49,7 +49,8 @@ m_cplusplus (false), m_objectivec (false), m_needs_object_ptr (false), - m_const_object (false) + m_const_object (false), + m_const_result () { } @@ -147,8 +148,7 @@ ClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx, TypeFromUser desired_type, - bool keep_result_in_memory, - lldb::ClangExpressionVariableSP *const_result) + bool keep_result_in_memory) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -284,7 +284,7 @@ m_dwarf_opcodes.reset(); - Error jit_error = parser.MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx, const_result); + Error jit_error = parser.MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx, m_const_result, true); m_expr_decl_map->DidParse(); @@ -457,7 +457,6 @@ ClangUserExpression::Execute (Stream &error_stream, ExecutionContext &exe_ctx, bool discard_on_error, - bool keep_in_memory, ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, lldb::ClangExpressionVariableSP &result) { @@ -556,7 +555,6 @@ ExecutionResults ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, bool discard_on_error, - bool keep_in_memory, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp) @@ -603,13 +601,11 @@ ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix)); StreamString error_stream; - - lldb::ClangExpressionVariableSP const_result; - + if (log) log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); - if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL), &const_result)) + if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL), true)) { if (error_stream.GetString().empty()) error.SetErrorString ("expression failed to parse, unknown error"); @@ -620,12 +616,12 @@ { lldb::ClangExpressionVariableSP expr_result; - if (const_result.get() && !keep_in_memory) + if (user_expression_sp->m_const_result.get()) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Expression evaluated as a constant =="); - result_valobj_sp = const_result->GetValueObject(); + result_valobj_sp = user_expression_sp->m_const_result->GetValueObject(); } else { @@ -637,7 +633,6 @@ execution_results = user_expression_sp->Execute (error_stream, exe_ctx, discard_on_error, - keep_in_memory, user_expression_sp, expr_result); Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Fri May 6 20:06:41 2011 @@ -108,8 +108,10 @@ ////////////////////////////////// // JIT the output of the parser // + + lldb::ClangExpressionVariableSP const_result; - Error jit_error = parser.MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx); + Error jit_error = parser.MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx, const_result); if (exe_ctx.process && m_jit_start_addr != LLDB_INVALID_ADDRESS) m_jit_process_sp = exe_ctx.process->GetSP(); Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Fri May 6 20:06:41 2011 @@ -26,6 +26,7 @@ #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" #include "lldb/Expression/ClangExpressionDeclMap.h" +#include "lldb/Symbol/ClangASTContext.h" #include @@ -35,7 +36,7 @@ IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars, - lldb::ClangExpressionVariableSP *const_result, + lldb::ClangExpressionVariableSP &const_result, lldb_private::Stream *error_stream, const char *func_name) : ModulePass(ID), @@ -44,10 +45,11 @@ m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL), m_sel_registerName(NULL), - m_const_result(const_result), m_error_stream(error_stream), m_has_side_effects(false), - m_result_is_pointer(false) + m_result_store(NULL), + m_result_is_pointer(false), + m_const_result(const_result) { } @@ -87,7 +89,7 @@ { llvm::Function::iterator bbi; BasicBlock::iterator ii; - + for (bbi = llvm_function.begin(); bbi != llvm_function.end(); ++bbi) @@ -108,15 +110,33 @@ Value *store_ptr = store_inst->getPointerOperand(); - if (!isa (store_ptr)) - return true; - else + std::string ptr_name; + + if (store_ptr->hasName()) + ptr_name = store_ptr->getNameStr(); + + if (isa (store_ptr)) break; + + if (ptr_name.find("$__lldb_expr_result") != std::string::npos) + { + if (ptr_name.find("GV") == std::string::npos) + m_result_store = store_inst; + } + else + { + return true; + } + + break; } case Instruction::Load: case Instruction::Alloca: case Instruction::GetElementPtr: + case Instruction::BitCast: case Instruction::Ret: + case Instruction::ICmp: + case Instruction::Br: break; } } @@ -125,18 +145,133 @@ return false; } +clang::NamedDecl * +IRForTarget::DeclForGlobal (llvm::Module &module, GlobalValue *global_val) +{ + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs"); + + if (!named_metadata) + return NULL; + + unsigned num_nodes = named_metadata->getNumOperands(); + unsigned node_index; + + for (node_index = 0; + node_index < num_nodes; + ++node_index) + { + MDNode *metadata_node = named_metadata->getOperand(node_index); + + if (!metadata_node) + return NULL; + + if (metadata_node->getNumOperands() != 2) + continue; + + if (metadata_node->getOperand(0) != global_val) + continue; + + ConstantInt *constant_int = dyn_cast(metadata_node->getOperand(1)); + + if (!constant_int) + return NULL; + + uintptr_t ptr = constant_int->getZExtValue(); + + return reinterpret_cast(ptr); + } + + return NULL; +} + void IRForTarget::MaybeSetConstantResult (llvm::Constant *initializer, const lldb_private::ConstString &name, lldb_private::TypeFromParser type) { - if (!m_const_result) + if (llvm::ConstantExpr *init_expr = dyn_cast(initializer)) + { + switch (init_expr->getOpcode()) + { + default: + return; + case Instruction::IntToPtr: + MaybeSetConstantResult (init_expr->getOperand(0), name, type); + return; + } + } + else if (llvm::ConstantInt *init_int = dyn_cast(initializer)) + { + m_const_result = m_decl_map->BuildIntegerVariable(name, type, init_int->getValue()); + } +} + +void +IRForTarget::MaybeSetCastResult (llvm::Module &llvm_module, lldb_private::TypeFromParser type) +{ + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + if (!m_result_store) return; - if (llvm::ConstantInt *init_int = dyn_cast(initializer)) + LoadInst *original_load = NULL; + + for (llvm::Value *current_value = m_result_store->getValueOperand(), *next_value; + current_value != NULL; + current_value = next_value) { - *m_const_result = m_decl_map->BuildIntegerVariable(name, type, init_int->getValue()); + CastInst *cast_inst = dyn_cast(current_value); + LoadInst *load_inst = dyn_cast(current_value); + + if (cast_inst) + { + next_value = cast_inst->getOperand(0); + } + else if(load_inst) + { + if (isa(load_inst->getPointerOperand())) + { + next_value = load_inst->getPointerOperand(); + } + else + { + original_load = load_inst; + break; + } + } + else + { + return; + } } + + Value *loaded_value = original_load->getPointerOperand(); + GlobalVariable *loaded_global = dyn_cast(loaded_value); + + if (!loaded_global) + return; + + clang::NamedDecl *loaded_decl = DeclForGlobal(llvm_module, loaded_global); + + if (!loaded_decl) + return; + + clang::VarDecl *loaded_var = dyn_cast(loaded_decl); + + if (!loaded_var) + return; + + if (log) + { + lldb_private::StreamString type_desc_stream; + type.DumpTypeDescription(&type_desc_stream); + + log->Printf("Type to cast variable to: \"%s\"", type_desc_stream.GetString().c_str()); + } + + m_const_result = m_decl_map->BuildCastVariable(m_result_name, loaded_var, type); } bool @@ -214,64 +349,50 @@ return false; } - // Find the metadata and follow it to the VarDecl - - NamedMDNode *named_metadata = llvm_module.getNamedMetadata("clang.global.decl.ptrs"); - - if (!named_metadata) + clang::NamedDecl *result_decl = DeclForGlobal (llvm_module, result_global); + if (!result_decl) { if (log) - log->PutCString("No global metadata"); + log->PutCString("Result variable doesn't have a corresponding Decl"); if (m_error_stream) - m_error_stream->Printf("Internal error [IRForTarget]: No metadata\n"); + m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name); return false; } - - unsigned num_nodes = named_metadata->getNumOperands(); - unsigned node_index; - MDNode *metadata_node = NULL; - - for (node_index = 0; - node_index < num_nodes; - ++node_index) + if (log) { - metadata_node = named_metadata->getOperand(node_index); - - if (metadata_node->getNumOperands() != 2) - continue; + std::string decl_desc_str; + raw_string_ostream decl_desc_stream(decl_desc_str); + result_decl->print(decl_desc_stream); + decl_desc_stream.flush(); - if (metadata_node->getOperand(0) == result_global) - break; + log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str()); } - if (!metadata_node) + clang::VarDecl *result_var = dyn_cast(result_decl); + if (!result_var) { if (log) - log->PutCString("Couldn't find result metadata"); + log->PutCString("Result variable Decl isn't a VarDecl"); if (m_error_stream) - m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) is a global variable, but has no metadata\n", result_name); + m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name); return false; } - - ConstantInt *constant_int = dyn_cast(metadata_node->getOperand(1)); - - lldb::addr_t result_decl_intptr = constant_int->getZExtValue(); - clang::VarDecl *result_decl = reinterpret_cast(result_decl_intptr); - // Get the next available result name from m_decl_map and create the persistent // variable for it lldb_private::TypeFromParser result_decl_type; + // If the result is an Lvalue, it is emitted as a pointer; see + // ASTResultSynthesizer::SynthesizeBodyResult. if (m_result_is_pointer) { - clang::QualType pointer_qual_type = result_decl->getType(); + clang::QualType pointer_qual_type = result_var->getType(); const clang::Type *pointer_type = pointer_qual_type.getTypePtr(); const clang::PointerType *pointer_pointertype = dyn_cast(pointer_type); @@ -293,18 +414,19 @@ } else { - result_decl_type = lldb_private::TypeFromParser(result_decl->getType().getAsOpaquePtr(), + result_decl_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(), &result_decl->getASTContext()); } + if (log) + { + lldb_private::StreamString type_desc_stream; + result_decl_type.DumpTypeDescription(&type_desc_stream); + + log->Printf("Result decl type: \"%s\"", type_desc_stream.GetString().c_str()); + } + m_result_name = m_decl_map->GetPersistentResultName(); - // If the result is an Lvalue, it is emitted as a pointer; see - // ASTResultSynthesizer::SynthesizeBodyResult. - m_decl_map->AddPersistentVariable(result_decl, - m_result_name, - result_decl_type, - true, - m_result_is_pointer); if (log) log->Printf("Creating a new result global: \"%s\"", m_result_name.GetCString()); @@ -325,8 +447,8 @@ // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is // fixed up. - ConstantInt *new_constant_int = ConstantInt::get(constant_int->getType(), - result_decl_intptr, + ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(llvm_module.getContext()), + reinterpret_cast(result_decl), false); llvm::Value* values[2]; @@ -334,6 +456,7 @@ values[1] = new_constant_int; MDNode *persistent_global_md = MDNode::get(llvm_module.getContext(), values, 2); + NamedMDNode *named_metadata = llvm_module.getNamedMetadata("clang.global.decl.ptrs"); named_metadata->addOperand(persistent_global_md); if (log) @@ -384,8 +507,20 @@ } else { + if (!m_has_side_effects && lldb_private::ClangASTContext::IsPointerType (result_decl_type.GetOpaqueQualType())) + { + MaybeSetCastResult (llvm_module, result_decl_type); + } + result_global->replaceAllUsesWith(new_result_global); } + + if (!m_const_result) + m_decl_map->AddPersistentVariable(result_decl, + m_result_name, + result_decl_type, + true, + m_result_is_pointer); result_global->eraseFromParent(); @@ -1047,45 +1182,6 @@ return true; } -static clang::NamedDecl * -DeclForGlobalValue(Module &module, GlobalValue *global_value) -{ - NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs"); - - if (!named_metadata) - return NULL; - - unsigned num_nodes = named_metadata->getNumOperands(); - unsigned node_index; - - for (node_index = 0; - node_index < num_nodes; - ++node_index) - { - MDNode *metadata_node = named_metadata->getOperand(node_index); - - if (!metadata_node) - return NULL; - - if (metadata_node->getNumOperands() != 2) - continue; - - if (metadata_node->getOperand(0) != global_value) - continue; - - ConstantInt *constant_int = dyn_cast(metadata_node->getOperand(1)); - - if (!constant_int) - return NULL; - - uintptr_t ptr = constant_int->getZExtValue(); - - return reinterpret_cast(ptr); - } - - return NULL; -} - // This function does not report errors; its callers are responsible. bool IRForTarget::MaybeHandleVariable (Module &llvm_module, Value *llvm_value_ptr) @@ -1110,7 +1206,7 @@ } else if (GlobalVariable *global_variable = dyn_cast(llvm_value_ptr)) { - clang::NamedDecl *named_decl = DeclForGlobalValue(llvm_module, global_variable); + clang::NamedDecl *named_decl = DeclForGlobal(llvm_module, global_variable); if (!named_decl) { @@ -1331,7 +1427,7 @@ str.SetCStringWithLength (fun->getName().data(), fun->getName().size()); } - clang::NamedDecl *fun_decl = DeclForGlobalValue (llvm_module, fun); + clang::NamedDecl *fun_decl = DeclForGlobal (llvm_module, fun); lldb::addr_t fun_addr = LLDB_INVALID_ADDRESS; Value **fun_value_ptr = NULL; @@ -1445,7 +1541,7 @@ if (log) log->Printf("Examining %s, DeclForGlobalValue returns %p", (*global).getName().str().c_str(), - DeclForGlobalValue(llvm_module, global)); + DeclForGlobal(llvm_module, global)); if ((*global).getName().str().find("OBJC_IVAR") == 0) { @@ -1457,7 +1553,7 @@ return false; } } - else if (DeclForGlobalValue(llvm_module, global)) + else if (DeclForGlobal(llvm_module, global)) { if (!MaybeHandleVariable (llvm_module, global)) { @@ -1882,6 +1978,9 @@ return false; } + if (m_const_result) + return true; + /////////////////////////////////////////////////////////////////////////////// // Fix all Objective-C constant strings to use NSStringWithCString:encoding: // Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Fri May 6 20:06:41 2011 @@ -1246,14 +1246,13 @@ ExecutionContext exe_ctx; frame_sp->CalculateExecutionContext (exe_ctx); bool unwind_on_error = true; - bool keep_in_memory = false; StreamString expr; char path[PATH_MAX]; image_spec.GetPath(path, sizeof(path)); expr.Printf("dlopen (\"%s\", 2)", path); const char *prefix = "extern \"C\" void* dlopen (const char *path, int mode);\n"; lldb::ValueObjectSP result_valobj_sp; - ClangUserExpression::Evaluate (exe_ctx, keep_in_memory, unwind_on_error, expr.GetData(), prefix, result_valobj_sp); + ClangUserExpression::Evaluate (exe_ctx, unwind_on_error, expr.GetData(), prefix, result_valobj_sp); if (result_valobj_sp->GetError().Success()) { Scalar scalar; @@ -1314,12 +1313,11 @@ ExecutionContext exe_ctx; frame_sp->CalculateExecutionContext (exe_ctx); bool unwind_on_error = true; - bool keep_in_memory = false; StreamString expr; expr.Printf("dlclose ((void *)0x%llx)", image_addr); const char *prefix = "extern \"C\" int dlclose(void* handle);\n"; lldb::ValueObjectSP result_valobj_sp; - ClangUserExpression::Evaluate (exe_ctx, unwind_on_error, keep_in_memory, expr.GetData(), prefix, result_valobj_sp); + ClangUserExpression::Evaluate (exe_ctx, unwind_on_error, expr.GetData(), prefix, result_valobj_sp); if (result_valobj_sp->GetError().Success()) { Scalar scalar; Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=131042&r1=131041&r2=131042&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Fri May 6 20:06:41 2011 @@ -994,7 +994,6 @@ execution_results = ClangUserExpression::Evaluate (exe_ctx, unwind_on_error, - keep_in_memory, expr_cstr, prefix, result_valobj_sp); From jingham at apple.com Sat May 7 19:56:32 2011 From: jingham at apple.com (Jim Ingham) Date: Sun, 08 May 2011 00:56:32 -0000 Subject: [Lldb-commits] [lldb] r131061 - in /lldb/trunk/source: API/SBThread.cpp Commands/CommandObjectThread.cpp Message-ID: <20110508005632.52EB12A6C12C@llvm.org> Author: jingham Date: Sat May 7 19:56:32 2011 New Revision: 131061 URL: http://llvm.org/viewvc/llvm-project?rev=131061&view=rev Log: StepUntil should check whether the target of the step until is in the current function and if not return an error. Modified: lldb/trunk/source/API/SBThread.cpp lldb/trunk/source/Commands/CommandObjectThread.cpp Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=131061&r1=131060&r2=131061&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Sat May 7 19:56:32 2011 @@ -683,14 +683,28 @@ } } + // Grab the current function, then we will make sure the "until" address is + // within the function. We discard addresses that are out of the current + // function, and then if there are no addresses remaining, give an appropriate + // error message. + + bool all_in_function = true; + AddressRange fun_range = frame_sc.function->GetAddressRange(); + std::vector step_over_until_addrs; const bool abort_other_plans = true; const bool stop_other_threads = true; const bool check_inlines = true; const bool exact = false; + Target *target = &m_opaque_sp->GetProcess().GetTarget(); SymbolContextList sc_list; - const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, sc_list); + const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, + line, + check_inlines, + exact, + eSymbolContextLineEntry, + sc_list); if (num_matches > 0) { SymbolContext sc; @@ -698,19 +712,27 @@ { if (sc_list.GetContextAtIndex(i, sc)) { - addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(&m_opaque_sp->GetProcess().GetTarget()); + addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); if (step_addr != LLDB_INVALID_ADDRESS) { - step_over_until_addrs.push_back(step_addr); + if (fun_range.ContainsLoadAddress(step_addr, target)) + step_over_until_addrs.push_back(step_addr); + else + all_in_function = false; } } } } - + if (step_over_until_addrs.empty()) { - step_file_spec.GetPath (path, sizeof(path)); - sb_error.SetErrorStringWithFormat("No line entries for %s:u", path, line); + if (all_in_function) + { + step_file_spec.GetPath (path, sizeof(path)); + sb_error.SetErrorStringWithFormat("No line entries for %s:u", path, line); + } + else + sb_error.SetErrorString ("Step until target not in current function.\n"); } else { Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=131061&r1=131060&r2=131061&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Sat May 7 19:56:32 2011 @@ -937,7 +937,10 @@ if (thread == NULL) { const uint32_t num_threads = process->GetThreadList().GetSize(); - result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", m_options.m_thread_idx, 0, num_threads); + result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", + m_options.m_thread_idx, + 0, + num_threads); result.SetStatus (eReturnStatusFailed); return false; } @@ -948,7 +951,9 @@ if (frame == NULL) { - result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", m_options.m_frame_idx, m_options.m_thread_idx); + result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", + m_options.m_frame_idx, + m_options.m_thread_idx); result.SetStatus (eReturnStatusFailed); return false; } @@ -980,9 +985,12 @@ Address fun_start_addr = fun_addr_range.GetBaseAddress(); line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr); - Address fun_end_addr(fun_start_addr.GetSection(), fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); + Address fun_end_addr(fun_start_addr.GetSection(), + fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); + bool all_in_function = true; + while (index_ptr <= end_ptr) { LineEntry line_entry; @@ -992,16 +1000,38 @@ addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); if (address != LLDB_INVALID_ADDRESS) - address_list.push_back (address); + { + if (fun_addr_range.ContainsLoadAddress (address, target)) + address_list.push_back (address); + else + all_in_function = false; + } index_ptr++; } - new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, &address_list.front(), address_list.size(), m_options.m_stop_others, thread->GetSelectedFrameIndex ()); + if (address_list.size() == 0) + { + if (all_in_function) + result.AppendErrorWithFormat ("No line entries matching until target.\n"); + else + result.AppendErrorWithFormat ("Until target outside of the current function.\n"); + + result.SetStatus (eReturnStatusFailed); + return false; + } + + new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, + &address_list.front(), + address_list.size(), + m_options.m_stop_others, + thread->GetSelectedFrameIndex ()); new_plan->SetOkayToDiscard(false); } else { - result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", m_options.m_frame_idx, m_options.m_thread_idx); + result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", + m_options.m_frame_idx, + m_options.m_thread_idx); result.SetStatus (eReturnStatusFailed); return false; From scallanan at apple.com Sat May 7 21:21:26 2011 From: scallanan at apple.com (Sean Callanan) Date: Sun, 08 May 2011 02:21:26 -0000 Subject: [Lldb-commits] [lldb] r131063 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangExpressionVariable.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp Message-ID: <20110508022126.C27952A6C12C@llvm.org> Author: spyffe Date: Sat May 7 21:21:26 2011 New Revision: 131063 URL: http://llvm.org/viewvc/llvm-project?rev=131063&view=rev Log: Added support for reading untyped symbols. Right now they are treated as pointers of type (void*). This allows reading of environ, for instance. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/ClangExpressionVariable.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=131063&r1=131062&r2=131063&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Sat May 7 21:21:26 2011 @@ -316,6 +316,10 @@ /// [Used by IRForTarget] Get the address of a symbol given nothing /// but its name. /// + /// @param[in] target + /// The target to find the symbol in. If not provided, + /// then the current parsing context's Target. + /// /// @param[in] name /// The name of the symbol. /// @@ -326,6 +330,11 @@ /// True if the address could be retrieved; false otherwise. //------------------------------------------------------------------ bool + GetSymbolAddress (Target &target, + const ConstString &name, + uint64_t &ptr); + + bool GetSymbolAddress (const ConstString &name, uint64_t &ptr); @@ -648,6 +657,22 @@ TypeFromUser *type = NULL); //------------------------------------------------------------------ + /// Given a target, find a data symbol that has the given name. + /// + /// @param[in] target + /// The target to use as the basis for the search. + /// + /// @param[in] name + /// The name as a plain C string. + /// + /// @return + /// The LLDB Symbol found, or NULL if none was found. + //--------------------------------------------------------- + Symbol * + FindGlobalDataSymbol (Target &target, + const ConstString &name); + + //------------------------------------------------------------------ /// Get the value of a variable in a given execution context and return /// the associated Types if needed. /// @@ -699,7 +724,7 @@ //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given - /// persistent variable, and put it in the Tuple list. + /// persistent variable, and put it in the list of found entities. /// /// @param[in] context /// The NameSearchContext to use when constructing the Decl. @@ -712,6 +737,21 @@ lldb::ClangExpressionVariableSP &pvar_sp); //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given LLDB + /// symbol (treated as a variable), and put it in the list of found + /// entities. + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] var + /// The LLDB Variable that needs a Decl. + //------------------------------------------------------------------ + void + AddOneGenericVariable (NameSearchContext &context, + Symbol &symbol); + + //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given /// function. (Functions are not placed in the Tuple list.) Can /// handle both fully typed functions and generic functions. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=131063&r1=131062&r2=131063&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Sat May 7 21:21:26 2011 @@ -107,6 +107,7 @@ llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable lldb::VariableSP m_lldb_var; ///< The original variable for this variable + lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol private: DISALLOW_COPY_AND_ASSIGN (ParserVars); Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=131063&r1=131062&r2=131063&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Sat May 7 21:21:26 2011 @@ -533,19 +533,14 @@ bool ClangExpressionDeclMap::GetSymbolAddress ( + Target &target, const ConstString &name, uint64_t &ptr ) { - assert (m_parser_vars.get()); - - // Back out in all cases where we're not fully initialized - if (m_parser_vars->m_exe_ctx->target == NULL) - return false; - SymbolContextList sc_list; - m_parser_vars->m_exe_ctx->target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); + target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); if (!sc_list.GetSize()) return false; @@ -555,11 +550,29 @@ const Address *sym_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress(); - ptr = sym_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target); + ptr = sym_address->GetLoadAddress(&target); return true; } +bool +ClangExpressionDeclMap::GetSymbolAddress +( + const ConstString &name, + uint64_t &ptr +) +{ + assert (m_parser_vars.get()); + + if (!m_parser_vars->m_exe_ctx || + !m_parser_vars->m_exe_ctx->target) + return false; + + return GetSymbolAddress(*m_parser_vars->m_exe_ctx->target, + name, + ptr); +} + // Interface for CommandObjectExpression bool @@ -1225,8 +1238,32 @@ TypeFromUser type(expr_var->GetTypeFromUser()); VariableSP var = FindVariableInScope (*exe_ctx.frame, name, &type); + Symbol *sym = FindGlobalDataSymbol(*exe_ctx.target, name); - if (!var) + std::auto_ptr location_value; + + if (var) + { + location_value.reset(GetVariableValue(exe_ctx, + var, + NULL)); + } + else if (sym) + { + location_value.reset(new Value); + + uint64_t location_load_addr; + + if (!GetSymbolAddress(*exe_ctx.target, name, location_load_addr)) + { + if (log) + err.SetErrorStringWithFormat("Couldn't find value for global symbol %s", name.GetCString()); + } + + location_value->SetValueType(Value::eValueTypeLoadAddress); + location_value->GetScalar() = location_load_addr; + } + else { err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString()); return false; @@ -1235,9 +1272,6 @@ if (log) log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType()); - std::auto_ptr location_value(GetVariableValue(exe_ctx, - var, - NULL)); if (!location_value.get()) { @@ -1627,6 +1661,30 @@ return var_sp; } +Symbol * +ClangExpressionDeclMap::FindGlobalDataSymbol +( + Target &target, + const ConstString &name +) +{ + SymbolContextList sc_list; + + target.GetImages().FindSymbolsWithNameAndType(name, + eSymbolTypeData, + sc_list); + + if (sc_list.GetSize()) + { + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(0, sym_ctx); + + return sym_ctx.symbol; + } + + return NULL; +} + // Interface for ClangASTSource void ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name) @@ -1677,48 +1735,61 @@ append, sc_list); - bool found_specific = false; - Symbol *generic_symbol = NULL; - Symbol *non_extern_symbol = NULL; - - for (uint32_t index = 0, num_indices = sc_list.GetSize(); - index < num_indices; - ++index) + if (sc_list.GetSize()) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); - - if (sym_ctx.function) + bool found_specific = false; + Symbol *generic_symbol = NULL; + Symbol *non_extern_symbol = NULL; + + for (uint32_t index = 0, num_indices = sc_list.GetSize(); + index < num_indices; + ++index) { - // TODO only do this if it's a C function; C++ functions may be - // overloaded - if (!found_specific) - AddOneFunction(context, sym_ctx.function, NULL); - found_specific = true; + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(index, sym_ctx); + + if (sym_ctx.function) + { + // TODO only do this if it's a C function; C++ functions may be + // overloaded + if (!found_specific) + AddOneFunction(context, sym_ctx.function, NULL); + found_specific = true; + } + else if (sym_ctx.symbol) + { + if (sym_ctx.symbol->IsExternal()) + generic_symbol = sym_ctx.symbol; + else + non_extern_symbol = sym_ctx.symbol; + } } - else if (sym_ctx.symbol) + + if (!found_specific) { - if (sym_ctx.symbol->IsExternal()) - generic_symbol = sym_ctx.symbol; - else - non_extern_symbol = sym_ctx.symbol; + if (generic_symbol) + AddOneFunction (context, NULL, generic_symbol); + else if (non_extern_symbol) + AddOneFunction (context, NULL, non_extern_symbol); + } + + ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name)); + if (namespace_decl) + { + clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); + if (clang_namespace_decl) + clang_namespace_decl->setHasExternalLexicalStorage(); } } - - if (!found_specific) - { - if (generic_symbol) - AddOneFunction (context, NULL, generic_symbol); - else if (non_extern_symbol) - AddOneFunction (context, NULL, non_extern_symbol); - } - - ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name)); - if (namespace_decl) + else { - clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); - if (clang_namespace_decl) - clang_namespace_decl->setHasExternalLexicalStorage(); + // We couldn't find a variable or function for this. Now we'll hunt for a generic + // data symbol, and -- if it is found -- treat it as a variable. + + Symbol *data_symbol = FindGlobalDataSymbol(*m_parser_vars->m_exe_ctx->target, name); + + if (data_symbol) + AddOneGenericVariable(context, *data_symbol); } } } @@ -2060,6 +2131,68 @@ } void +ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, + Symbol &symbol) +{ + assert(m_parser_vars.get()); + + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + clang::ASTContext *scratch_ast_context = m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext(); + + TypeFromUser user_type (ClangASTContext::GetVoidPtrType(scratch_ast_context, false), + scratch_ast_context); + + TypeFromParser parser_type (ClangASTContext::GetVoidPtrType(context.GetASTContext(), false), + context.GetASTContext()); + + NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType())); + + std::string decl_name(context.m_decl_name.getAsString()); + ConstString entity_name(decl_name.c_str()); + ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope (), + entity_name, + user_type, + m_parser_vars->m_exe_ctx->process->GetByteOrder(), + m_parser_vars->m_exe_ctx->process->GetAddressByteSize())); + assert (entity.get()); + entity->EnableParserVars(); + + std::auto_ptr symbol_location(new Value); + + AddressRange &symbol_range = symbol.GetAddressRangeRef(); + Address &symbol_address = symbol_range.GetBaseAddress(); + lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(m_parser_vars->m_exe_ctx->target); + + symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); + symbol_location->GetScalar() = symbol_load_addr; + symbol_location->SetValueType(Value::eValueTypeLoadAddress); + + entity->m_parser_vars->m_parser_type = parser_type; + entity->m_parser_vars->m_named_decl = var_decl; + entity->m_parser_vars->m_llvm_value = NULL; + entity->m_parser_vars->m_lldb_value = symbol_location.release(); + entity->m_parser_vars->m_lldb_sym = &symbol; + + if (log) + { + std::string var_decl_print_string; + llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string); + var_decl->print(var_decl_print_stream); + var_decl_print_stream.flush(); + + log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str()); + + if (log->GetVerbose()) + { + StreamString var_decl_dump_string; + ASTDumper::DumpDecl(var_decl_dump_string, var_decl); + log->Printf("%s\n", var_decl_dump_string.GetData()); + } + } +} + +void ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, const RegisterInfo *reg_info) { Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=131063&r1=131062&r2=131063&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Sat May 7 21:21:26 2011 @@ -1295,7 +1295,7 @@ bool IRForTarget::HandleSymbol (Module &llvm_module, Value *symbol) -{ +{ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); lldb_private::ConstString name(symbol->getName().str().c_str()); From gclayton at apple.com Sat May 7 23:53:50 2011 From: gclayton at apple.com (Greg Clayton) Date: Sun, 08 May 2011 04:53:50 -0000 Subject: [Lldb-commits] [lldb] r131064 - in /lldb/trunk: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp tools/debugserver/source/RNBRemote.cpp tools/debugserver/source/RNBRemote.h Message-ID: <20110508045350.69F5D2A6C12C@llvm.org> Author: gclayton Date: Sat May 7 23:53:50 2011 New Revision: 131064 URL: http://llvm.org/viewvc/llvm-project?rev=131064&view=rev Log: Fixed not being able to launch the i386 slice of a universal binary by adding a new "QLaunchArch:" where is the architecture name. This allows us to remotely launch a debugserver and then set the architecture for the binary we will launch. Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/tools/debugserver/source/RNBRemote.cpp lldb/trunk/tools/debugserver/source/RNBRemote.h Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=131064&r1=131063&r2=131064&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Sat May 7 23:53:50 2011 @@ -705,6 +705,26 @@ return -1; } +int +GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch) +{ + if (arch && arch[0]) + { + StreamString packet; + packet.Printf("QLaunchArch:%s", arch); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) + { + if (response.IsOKResponse()) + return 0; + uint8_t error = response.GetError(); + if (error) + return error; + } + } + return -1; +} + bool GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, uint32_t &minor, Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=131064&r1=131063&r2=131064&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Sat May 7 23:53:50 2011 @@ -123,6 +123,8 @@ int SendEnvironmentPacket (char const *name_equal_value); + int + SendLaunchArchPacket (const char *arch); //------------------------------------------------------------------ /// Sends a "vAttach:PID" where PID is in hex. /// 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=131064&r1=131063&r2=131064&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sat May 7 23:53:50 2011 @@ -486,6 +486,7 @@ m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR); + m_gdb_comm.SendLaunchArchPacket (m_target.GetArchitecture().GetArchitectureName()); if (working_dir && working_dir[0]) { Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=131064&r1=131063&r2=131064&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original) +++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Sat May 7 23:53:50 2011 @@ -175,6 +175,7 @@ t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle")); t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle")); t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_QEnvironment , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment")); + t.push_back (Packet (set_launch_arch, &RNBRemote::HandlePacket_QLaunchArch , NULL, "QLaunchArch:", "Set the architecture to use when launching a process for hosts that can run multiple architecture slices from universal files.")); t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet")); t.push_back (Packet (set_stdin, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDIN:", "Set the standard input for a process to be launched with the 'A' packet")); t.push_back (Packet (set_stdout, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDOUT:", "Set the standard output for a process to be launched with the 'A' packet")); @@ -1883,6 +1884,15 @@ return SendPacket ("OK"); } +rnb_err_t +RNBRemote::HandlePacket_QLaunchArch (const char *p) +{ + p += sizeof ("QLaunchArch:") - 1; + if (DNBSetArchitecture(p)) + return SendPacket ("OK"); + return SendPacket ("E63"); +} + void append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap) { Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=131064&r1=131063&r2=131064&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBRemote.h (original) +++ lldb/trunk/tools/debugserver/source/RNBRemote.h Sat May 7 23:53:50 2011 @@ -98,6 +98,7 @@ set_max_packet_size, // 'QSetMaxPacketSize:' set_max_payload_size, // 'QSetMaxPayloadSize:' set_environment_variable, // 'QEnvironment:' + set_launch_arch, // 'QLaunchArch:' set_disable_aslr, // 'QSetDisableASLR:' set_stdin, // 'QSetSTDIN:' set_stdout, // 'QSetSTDOUT:' @@ -170,6 +171,7 @@ rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p); rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p); rnb_err_t HandlePacket_QEnvironment (const char *p); + rnb_err_t HandlePacket_QLaunchArch (const char *p); rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p); rnb_err_t HandlePacket_last_signal (const char *p); rnb_err_t HandlePacket_m (const char *p); From johnny.chen at apple.com Sun May 8 12:25:28 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sun, 08 May 2011 17:25:28 -0000 Subject: [Lldb-commits] [lldb] r131069 - in /lldb/trunk/test: lldbutil.py macosx/universal/TestUniversal.py Message-ID: <20110508172528.2288C2A6C12C@llvm.org> Author: johnny Date: Sun May 8 12:25:27 2011 New Revision: 131069 URL: http://llvm.org/viewvc/llvm-project?rev=131069&view=rev Log: Add test scenario to verify 'eax' register is available when launching the i386 slice of a universal binary and 'rax' register is available when launching the x86_64 slice. rdar://problem/9403437 Modified: lldb/trunk/test/lldbutil.py lldb/trunk/test/macosx/universal/TestUniversal.py Modified: lldb/trunk/test/lldbutil.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbutil.py?rev=131069&r1=131068&r2=131069&view=diff ============================================================================== --- lldb/trunk/test/lldbutil.py (original) +++ lldb/trunk/test/lldbutil.py Sun May 8 12:25:27 2011 @@ -404,3 +404,25 @@ if string_buffer: return output.getvalue() + +# =================================== +# Utility functions related to Frames +# =================================== + +def print_registers(frame, string_buffer = False): + """Prints the all the register sets of the frame.""" + + output = StringIO.StringIO() if string_buffer else sys.stdout + + print >> output, "Register sets for " + repr(frame) + + registerList = frame.GetRegisters() + print >> output, "Frame registers (size of register set = %d):" % registerList.GetSize() + for value in registerList: + #print >> output, value + print >> output, "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()) + for child in value: + print >> output, "Name: %s, Value: %s" % (child.GetName(), child.GetValue(frame)) + + if string_buffer: + return output.getvalue() Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=131069&r1=131068&r2=131069&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Sun May 8 12:25:27 2011 @@ -20,6 +20,7 @@ "requires Darwin & i386") def test_process_launch_for_universal(self): """Test process launch of a universal binary.""" + from lldbutil import print_registers # Invoke the default build rule. self.buildDefault() @@ -48,6 +49,11 @@ self.invoke(process, 'GetAddressByteSize') == 8, "64-bit process launched") + frame = process.GetThreadAtIndex(0).GetFrameAtIndex(0) + registers = print_registers(frame, string_buffer=True) + self.expect(registers, exe=False, + substrs = ['Name: rax']) + self.runCmd("continue") # Now specify i386 as the architecture for "testit". @@ -74,6 +80,11 @@ self.assertTrue(pointerSize == 4, "AddressByteSize of 32-bit process should be 4, got %d instead." % pointerSize) + frame = process.GetThreadAtIndex(0).GetFrameAtIndex(0) + registers = print_registers(frame, string_buffer=True) + self.expect(registers, exe=False, + substrs = ['Name: eax']) + self.runCmd("continue") From johnny.chen at apple.com Sun May 8 13:55:37 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sun, 08 May 2011 18:55:37 -0000 Subject: [Lldb-commits] [lldb] r131072 - /lldb/trunk/test/lldbutil.py Message-ID: <20110508185537.6DBC02A6C12C@llvm.org> Author: johnny Date: Sun May 8 13:55:37 2011 New Revision: 131072 URL: http://llvm.org/viewvc/llvm-project?rev=131072&view=rev Log: Fix docstring. Modified: lldb/trunk/test/lldbutil.py Modified: lldb/trunk/test/lldbutil.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbutil.py?rev=131072&r1=131071&r2=131072&view=diff ============================================================================== --- lldb/trunk/test/lldbutil.py (original) +++ lldb/trunk/test/lldbutil.py Sun May 8 13:55:37 2011 @@ -410,7 +410,7 @@ # =================================== def print_registers(frame, string_buffer = False): - """Prints the all the register sets of the frame.""" + """Prints all the register sets of the frame.""" output = StringIO.StringIO() if string_buffer else sys.stdout From jingham at apple.com Sun May 8 20:06:45 2011 From: jingham at apple.com (Jim Ingham) Date: Mon, 09 May 2011 01:06:45 -0000 Subject: [Lldb-commits] [lldb] r131079 - /lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Message-ID: <20110509010645.858522A6C12C@llvm.org> Author: jingham Date: Sun May 8 20:06:45 2011 New Revision: 131079 URL: http://llvm.org/viewvc/llvm-project?rev=131079&view=rev Log: Change an unconditional log to a conditional one. Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=131079&r1=131078&r2=131079&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Sun May 8 20:06:45 2011 @@ -107,7 +107,7 @@ if (force || m_state.GetError(e_regSetGPR, Read)) { kern_return_t kret = ::thread_abort_safely(m_thread->ThreadID()); - DNBLogThreaded("thread = 0x%4.4x calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount()); + DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount()); #if DEBUG_GPR_VALUES m_state.context.gpr.__rax = ('a' << 8) + 'x'; @@ -395,7 +395,7 @@ DNBArchImplX86_64::SetGPRState() { kern_return_t kret = ::thread_abort_safely(m_thread->ThreadID()); - DNBLogThreaded("thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount()); + DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount()); m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR)); DNBLogThreadedIf (LOG_THREAD, "::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x" From gclayton at apple.com Sun May 8 22:39:34 2011 From: gclayton at apple.com (Greg Clayton) Date: Mon, 09 May 2011 03:39:34 -0000 Subject: [Lldb-commits] [lldb] r131081 - /lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Message-ID: <20110509033934.C8EDF2A6C12C@llvm.org> Author: gclayton Date: Sun May 8 22:39:34 2011 New Revision: 131081 URL: http://llvm.org/viewvc/llvm-project?rev=131081&view=rev Log: Fixed an issue with the MacOSX backchain register context where the pc was being returned for both the PC and FP. Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp?rev=131081&r1=131080&r2=131081&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Sun May 8 22:39:34 2011 @@ -102,7 +102,7 @@ case LLDB_REGNUM_GENERIC_FP: if (m_cursor.fp == LLDB_INVALID_ADDRESS) return false; - reg_value = m_cursor.pc; + reg_value = m_cursor.fp; break; default: