[llvm-branch-commits] [lldb] r183468 - Update platform branch with top of tree.

Greg Clayton gclayton at apple.com
Thu Jun 6 17:08:26 PDT 2013


Modified: lldb/branches/lldb-platform-work/source/Target/ObjCLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ObjCLanguageRuntime.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ObjCLanguageRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ObjCLanguageRuntime.cpp Thu Jun  6 19:06:43 2013
@@ -9,13 +9,19 @@
 #include "clang/AST/Type.h"
 
 #include "lldb/Core/Log.h"
+#include "lldb/Core/MappedHash.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Timer.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Target.h"
 
+#include "llvm/ADT/StringRef.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -28,18 +34,33 @@ ObjCLanguageRuntime::~ObjCLanguageRuntim
 
 ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
     LanguageRuntime (process),
-    m_has_new_literals_and_indexing (eLazyBoolCalculate)
+    m_has_new_literals_and_indexing (eLazyBoolCalculate),
+    m_isa_to_descriptor(),
+    m_isa_to_descriptor_stop_id (UINT32_MAX)
 {
 
 }
 
+bool
+ObjCLanguageRuntime::AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name)
+{
+    if (isa != 0)
+    {
+        m_isa_to_descriptor[isa] = descriptor_sp;
+        // class_name is assumed to be valid
+        m_hash_to_isa_map.insert(std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa));
+        return true;
+    }
+    return false;
+}
+
 void
 ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
     {
-        log->Printf ("Caching: class 0x%llx selector 0x%llx implementation 0x%llx.", class_addr, selector, impl_addr);
+        log->Printf ("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 " implementation 0x%" PRIx64 ".", class_addr, selector, impl_addr);
     }
     m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr));
 }
@@ -54,209 +75,531 @@ ObjCLanguageRuntime::LookupInMethodCache
     return LLDB_INVALID_ADDRESS;
 }
 
-void
-ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp)
+
+lldb::TypeSP
+ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
+    CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
+    
+    if (complete_class_iter != m_complete_class_cache.end())
     {
-        log->Printf ("Caching: class 0x%llx name: %s.", class_addr, name);
+        // Check the weak pointer to make sure the type hasn't been unloaded
+        TypeSP complete_type_sp (complete_class_iter->second.lock());
+        
+        if (complete_type_sp)
+            return complete_type_sp;
+        else
+            m_complete_class_cache.erase(name);
     }
     
-    TypeAndOrName class_type_or_name;
+    if (m_negative_complete_class_cache.count(name) > 0)
+        return TypeSP();
     
-    if (type_sp)
-        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<lldb::addr_t,TypeAndOrName> (class_addr, class_type_or_name));
+    const ModuleList &modules = m_process->GetTarget().GetImages();
+
+    SymbolContextList sc_list;
+    const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name,
+                                                                        eSymbolTypeObjCClass,
+                                                                        sc_list);
+    
+    if (matching_symbols)
+    {
+        SymbolContext sc;
+        
+        sc_list.GetContextAtIndex(0, sc);
+        
+        ModuleSP module_sp(sc.module_sp);
+        
+        if (!module_sp)
+            return TypeSP();
+        
+        const SymbolContext null_sc;
+        const bool exact_match = true;
+        const uint32_t max_matches = UINT32_MAX;
+        TypeList types;
+        
+        const uint32_t num_types = module_sp->FindTypes (null_sc,
+                                                         name,
+                                                         exact_match,
+                                                         max_matches,
+                                                         types);
+        
+        if (num_types)
+        {            
+            uint32_t i;
+            for (i = 0; i < num_types; ++i)
+            {
+                TypeSP type_sp (types.GetTypeAtIndex(i));
+                
+                if (ClangASTContext::IsObjCClassType(type_sp->GetClangForwardType()))
+                {
+                    if (type_sp->IsCompleteObjCClass())
+                    {
+                        m_complete_class_cache[name] = type_sp;
+                        return type_sp;
+                    }
+                }
+            }
+        }
+    }
+    m_negative_complete_class_cache.insert(name);
+    return TypeSP();
+}
+
+size_t
+ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
+{
+    return LLDB_INVALID_IVAR_OFFSET;
 }
 
 void
-ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_type_or_name)
+ObjCLanguageRuntime::MethodName::Clear()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
+    m_full.Clear();
+    m_class.Clear();
+    m_category.Clear();
+    m_selector.Clear();
+    m_type = eTypeUnspecified;
+    m_category_is_valid = false;
+}
+
+//bool
+//ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
+//{
+//    Clear();
+//    if (name && name[0])
+//    {
+//        // If "strict" is true. then the method must be specified with a
+//        // '+' or '-' at the beginning. If "strict" is false, then the '+'
+//        // or '-' can be omitted
+//        bool valid_prefix = false;
+//        
+//        if (name[0] == '+' || name[0] == '-')
+//        {
+//            valid_prefix = name[1] == '[';
+//        }
+//        else if (!strict)
+//        {
+//            // "strict" is false, the name just needs to start with '['
+//            valid_prefix = name[0] == '[';
+//        }
+//
+//        if (valid_prefix)
+//        {
+//            static RegularExpression g_regex("^([-+]?)\\[([A-Za-z_][A-Za-z_0-9]*)(\\([A-Za-z_][A-Za-z_0-9]*\\))? ([A-Za-z_][A-Za-z_0-9:]*)\\]$");
+//            llvm::StringRef matches[4];
+//            // Since we are using a global regular expression, we must use the threadsafe version of execute
+//            if (g_regex.ExecuteThreadSafe(name, matches, 4))
+//            {
+//                m_full.SetCString(name);
+//                if (matches[0].empty())
+//                    m_type = eTypeUnspecified;
+//                else if (matches[0][0] == '+')
+//                    m_type = eTypeClassMethod;
+//                else
+//                    m_type = eTypeInstanceMethod;
+//                m_class.SetString(matches[1]);
+//                m_selector.SetString(matches[3]);
+//                if (!matches[2].empty())
+//                    m_category.SetString(matches[2]);
+//            }
+//        }
+//    }
+//    return IsValid(strict);
+//}
+
+bool
+ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
+{
+    Clear();
+    if (name && name[0])
     {
-        log->Printf ("Caching: class 0x%llx name: %s.", class_addr, class_type_or_name.GetName().AsCString());
+        // If "strict" is true. then the method must be specified with a
+        // '+' or '-' at the beginning. If "strict" is false, then the '+'
+        // or '-' can be omitted
+        bool valid_prefix = false;
+        
+        if (name[0] == '+' || name[0] == '-')
+        {
+            valid_prefix = name[1] == '[';
+            if (name[0] == '+')
+                m_type = eTypeClassMethod;
+            else
+                m_type = eTypeInstanceMethod;
+        }
+        else if (!strict)
+        {
+            // "strict" is false, the name just needs to start with '['
+            valid_prefix = name[0] == '[';
+        }
+        
+        if (valid_prefix)
+        {
+            int name_len = strlen (name);
+            // Objective C methods must have at least:
+            //      "-[" or "+[" prefix
+            //      One character for a class name
+            //      One character for the space between the class name
+            //      One character for the method name
+            //      "]" suffix
+            if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
+            {
+                m_full.SetCStringWithLength(name, name_len);
+            }
+        }
     }
-    
-    m_class_name_cache.insert (std::pair<lldb::addr_t,TypeAndOrName> (class_addr, class_type_or_name));
+    return IsValid(strict);
 }
 
-TypeAndOrName
-ObjCLanguageRuntime::LookupInClassNameCache (lldb::addr_t class_addr)
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetClassName ()
 {
-    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 ();
+    if (!m_class)
+    {
+        if (IsValid(false))
+        {
+            const char *full = m_full.GetCString();
+            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+            const char *paren_pos = strchr (class_start, '(');
+            if (paren_pos)
+            {
+                m_class.SetCStringWithLength (class_start, paren_pos - class_start);
+            }
+            else
+            {
+                // No '(' was found in the full name, we can definitively say
+                // that our category was valid (and empty).
+                m_category_is_valid = true;
+                const char *space_pos = strchr (full, ' ');
+                if (space_pos)
+                {
+                    m_class.SetCStringWithLength (class_start, space_pos - class_start);
+                    if (!m_class_category)
+                    {
+                        // No category in name, so we can also fill in the m_class_category
+                        m_class_category = m_class;
+                    }
+                }
+            }
+        }
+    }
+    return m_class;
 }
 
-lldb::TypeSP
-ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetClassNameWithCategory () 
 {
-    CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
-    
-    if (complete_class_iter != m_complete_class_cache.end())
+    if (!m_class_category)
     {
-        TypeSP ret(complete_class_iter->second);
-        
-        if (!ret)
-            m_complete_class_cache.erase(name);
-        else
-            return TypeSP(complete_class_iter->second);
+        if (IsValid(false))
+        {
+            const char *full = m_full.GetCString();
+            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+            const char *space_pos = strchr (full, ' ');
+            if (space_pos)
+            {
+                m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
+                // If m_class hasn't been filled in and the class with category doesn't
+                // contain a '(', then we can also fill in the m_class
+                if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL)
+                {
+                    m_class = m_class_category;
+                    // No '(' was found in the full name, we can definitively say
+                    // that our category was valid (and empty).
+                    m_category_is_valid = true;
+
+                }
+            }
+        }
     }
-    
-    ModuleList &modules = m_process->GetTarget().GetImages();
-    
-    SymbolContextList sc_list;
-    
-    modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
-    
-    if (sc_list.GetSize() == 0)
-        return TypeSP();
-    
-    SymbolContext sc;
-    
-    sc_list.GetContextAtIndex(0, sc);
-    
-    ModuleSP module_sp(sc.module_sp);
-    
-    if (!module_sp)
-        return TypeSP();
-    
-    const SymbolContext null_sc;
-    const bool exact_match = true;
-    const uint32_t max_matches = UINT32_MAX;
-    TypeList types;
-    
-    module_sp->FindTypes (null_sc,
-                          name,
-                          exact_match,
-                          max_matches,
-                          types);
-    
-    if (types.GetSize() == 1)
+    return m_class_category;
+}
+
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetSelector ()
+{
+    if (!m_selector)
     {
-        TypeSP candidate_type = types.GetTypeAtIndex(0);
-        
-        if (ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        if (IsValid(false))
         {
-            m_complete_class_cache[name] = TypeWP(candidate_type);
-            return candidate_type;
+            const char *full = m_full.GetCString();
+            const char *space_pos = strchr (full, ' ');
+            if (space_pos)
+            {
+                ++space_pos; // skip the space
+                m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
+            }
         }
-        else
+    }
+    return m_selector;
+}
+
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetCategory ()
+{
+    if (!m_category_is_valid && !m_category)
+    {
+        if (IsValid(false))
         {
-            return TypeSP();
+            m_category_is_valid = true;
+            const char *full = m_full.GetCString();
+            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+            const char *open_paren_pos = strchr (class_start, '(');
+            if (open_paren_pos)
+            {
+                ++open_paren_pos; // Skip the open paren
+                const char *close_paren_pos = strchr (open_paren_pos, ')');
+                if (close_paren_pos)
+                    m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
+            }
         }
     }
-    
-    for (uint32_t ti = 0, te = types.GetSize();
-         ti < te;
-         ++ti)
+    return m_category;
+}
+
+ConstString
+ObjCLanguageRuntime::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
+{
+    if (IsValid(false))
     {
-        TypeSP candidate_type = types.GetTypeAtIndex(ti);
+        if (HasCategory())
+        {
+            StreamString strm;
+            if (m_type == eTypeClassMethod)
+                strm.PutChar('+');
+            else if (m_type == eTypeInstanceMethod)
+                strm.PutChar('-');
+            strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
+            return ConstString(strm.GetString().c_str());
+        }
         
-        if (candidate_type->IsCompleteObjCClass() &&
-            ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        if (!empty_if_no_category)
         {
-            m_complete_class_cache[name] = TypeWP(candidate_type);
-            return candidate_type;                                       
+            // Just return the full name since it doesn't have a category
+            return GetFullName();
         }
     }
-    
-    return TypeSP();
+    return ConstString();
 }
 
 size_t
-ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
+ObjCLanguageRuntime::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
 {
-    return LLDB_INVALID_IVAR_OFFSET;
+    if (!append)
+        names.clear();
+    if (IsValid(false))
+    {
+        StreamString strm;
+        const bool is_class_method = m_type == eTypeClassMethod;
+        const bool is_instance_method = m_type == eTypeInstanceMethod;
+        const ConstString &category = GetCategory();
+        if (is_class_method || is_instance_method)
+        {
+            names.push_back (m_full);
+            if (category)
+            {
+                strm.Printf("%c[%s %s]",
+                            is_class_method ? '+' : '-',
+                            GetClassName().GetCString(),
+                            GetSelector().GetCString());
+                names.push_back(ConstString(strm.GetString().c_str()));
+            }
+        }
+        else
+        {
+            const ConstString &class_name = GetClassName();
+            const ConstString &selector = GetSelector();
+            strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
+            names.push_back(ConstString(strm.GetString().c_str()));
+            strm.Clear();
+            strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
+            names.push_back(ConstString(strm.GetString().c_str()));
+            strm.Clear();
+            if (category)
+            {
+                strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
+                names.push_back(ConstString(strm.GetString().c_str()));
+                strm.Clear();
+                strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
+                names.push_back(ConstString(strm.GetString().c_str()));
+            }
+        }
+    }
+    return names.size();
 }
 
 
-uint32_t
-ObjCLanguageRuntime::ParseMethodName (const char *name, 
-                                      ConstString *class_name,              // Class name (with category if any)
-                                      ConstString *selector_name,           // selector on its own
-                                      ConstString *name_sans_category,      // Full function prototype with no category
-                                      ConstString *class_name_sans_category)// Class name with no category (or empty if no category as answer will be in "class_name"
-{
-    if (class_name)
-        class_name->Clear();
-    if (selector_name)
-        selector_name->Clear();
-    if (name_sans_category)
-        name_sans_category->Clear();
-    if (class_name_sans_category)
-        class_name_sans_category->Clear();
-    
-    uint32_t result = 0;
+bool
+ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
+                                                      uint32_t ptr_size,
+                                                      bool allow_NULLs,
+                                                      bool allow_tagged,
+                                                      bool check_version_specific) const
+{
+    if (!value)
+        return allow_NULLs;
+    if ( (value % 2) == 1  && allow_tagged)
+        return true;
+    if ((value % ptr_size) == 0)
+        return (check_version_specific ? CheckPointer(value,ptr_size) : true);
+    else
+        return false;
+}
+
+ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetISA(const ConstString &name)
+{
+    ISAToDescriptorIterator pos = GetDescriptorIterator (name);
+    if (pos != m_isa_to_descriptor.end())
+        return pos->first;
+    return 0;
+}
 
-    if (IsPossibleObjCMethodName (name))
+ObjCLanguageRuntime::ISAToDescriptorIterator
+ObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name)
+{
+    ISAToDescriptorIterator end = m_isa_to_descriptor.end();
+
+    if (name)
     {
-        int name_len = strlen (name);
-        // Objective C methods must have at least:
-        //      "-[" or "+[" prefix
-        //      One character for a class name
-        //      One character for the space between the class name
-        //      One character for the method name
-        //      "]" suffix
-        if (name_len >= 6 && name[name_len - 1] == ']')
+        UpdateISAToDescriptorMap();
+        if (m_hash_to_isa_map.empty())
         {
-            const char *selector_name_ptr = strchr (name, ' ');
-            if (selector_name_ptr)
+            // No name hashes were provided, we need to just linearly power through the
+            // names and find a match
+            for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin(); pos != end; ++pos)
             {
-                if (class_name)
-                {
-                    class_name->SetCStringWithLength (name + 2, selector_name_ptr - name - 2);
-                    ++result;
-                }    
-                
-                // Skip the space
-                ++selector_name_ptr;
-                // Extract the objective C basename and add it to the
-                // accelerator tables
-                size_t selector_name_len = name_len - (selector_name_ptr - name) - 1;
-                if (selector_name)
-                {
-                    selector_name->SetCStringWithLength (selector_name_ptr, selector_name_len);                                
-                    ++result;
-                }
-                
-                // Also see if this is a "category" on our class.  If so strip off the category name,
-                // and add the class name without it to the basename table. 
-                
-                if (name_sans_category || class_name_sans_category)
+                if (pos->second->GetClassName() == name)
+                    return pos;
+            }
+        }
+        else
+        {
+            // Name hashes were provided, so use them to efficiently lookup name to isa/descriptor
+            const uint32_t name_hash = MappedHash::HashStringUsingDJB (name.GetCString());
+            std::pair <HashToISAIterator, HashToISAIterator> range = m_hash_to_isa_map.equal_range(name_hash);
+            for (HashToISAIterator range_pos = range.first; range_pos != range.second; ++range_pos)
+            {
+                ISAToDescriptorIterator pos = m_isa_to_descriptor.find (range_pos->second);
+                if (pos != m_isa_to_descriptor.end())
                 {
-                    const char *open_paren = strchr (name, '(');
-                    if (open_paren)
-                    {
-                        if (class_name_sans_category)
-                        {
-                            class_name_sans_category->SetCStringWithLength (name + 2, open_paren - name - 2);
-                            ++result;
-                        }
-                        
-                        if (name_sans_category)
-                        {
-                            const char *close_paren = strchr (open_paren, ')');
-                            if (open_paren < close_paren)
-                            {
-                                std::string buffer (name, open_paren - name);
-                                buffer.append (close_paren + 1);
-                                name_sans_category->SetCString (buffer.c_str());
-                                ++result;
-                            }
-                        }
-                    }
+                    if (pos->second->GetClassName() == name)
+                        return pos;
                 }
             }
         }
     }
-    return result;
+    return end;
+}
+
+
+ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
+{
+    ClassDescriptorSP objc_class_sp (GetClassDescriptorFromISA(isa));
+    if (objc_class_sp)
+    {
+        ClassDescriptorSP objc_super_class_sp (objc_class_sp->GetSuperclass());
+        if (objc_super_class_sp)
+            return objc_super_class_sp->GetISA();
+    }
+    return 0;
+}
+
+ConstString
+ObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
+{
+    ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor(isa));
+    if (objc_class_sp)
+        return objc_class_sp->GetClassName();
+    return ConstString();
 }
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetClassDescriptorFromClassName (const ConstString &class_name)
+{
+    ISAToDescriptorIterator pos = GetDescriptorIterator (class_name);
+    if (pos != m_isa_to_descriptor.end())
+        return pos->second;
+    return ClassDescriptorSP();
+
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj)
+{
+    ClassDescriptorSP objc_class_sp;
+    // if we get an invalid VO (which might still happen when playing around
+    // with pointers returned by the expression parser, don't consider this
+    // a valid ObjC object)
+    if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
+    {
+        addr_t isa_pointer = valobj.GetPointerValue();
+        if (isa_pointer != LLDB_INVALID_ADDRESS)
+        {
+            ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+            
+            Process *process = exe_ctx.GetProcessPtr();
+            if (process)
+            {
+                Error error;
+                ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
+                if (isa != LLDB_INVALID_ADDRESS)
+                    objc_class_sp = GetClassDescriptorFromISA (isa);
+            }
+        }
+    }
+    return objc_class_sp;
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetNonKVOClassDescriptor (ValueObject& valobj)
+{
+    ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (GetClassDescriptor (valobj));
+    if (objc_class_sp)
+    {
+        if (!objc_class_sp->IsKVO())
+            return objc_class_sp;
+        
+        ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
+        if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
+            return non_kvo_objc_class_sp;
+    }
+    return ClassDescriptorSP();
+}
+
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetClassDescriptorFromISA (ObjCISA isa)
+{
+    if (isa)
+    {
+        UpdateISAToDescriptorMap();
+        ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa);    
+        if (pos != m_isa_to_descriptor.end())
+            return pos->second;
+    }
+    return ClassDescriptorSP();
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetNonKVOClassDescriptor (ObjCISA isa)
+{
+    if (isa)
+    {
+        ClassDescriptorSP objc_class_sp = GetClassDescriptorFromISA (isa);
+        if (objc_class_sp && objc_class_sp->IsValid())
+        {
+            if (!objc_class_sp->IsKVO())
+                return objc_class_sp;
+
+            ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
+            if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
+                return non_kvo_objc_class_sp;
+        }
+    }
+    return ClassDescriptorSP();
+}
+
+
+

Modified: lldb/branches/lldb-platform-work/source/Target/OperatingSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/OperatingSystem.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/OperatingSystem.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/OperatingSystem.cpp Thu Jun  6 19:06:43 2013
@@ -13,7 +13,7 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "lldb/Core/PluginManager.h"
-
+#include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -25,10 +25,11 @@ OperatingSystem::FindPlugin (Process *pr
     OperatingSystemCreateInstance create_callback = NULL;
     if (plugin_name)
     {
-        create_callback  = PluginManager::GetOperatingSystemCreateCallbackForPluginName (plugin_name);
+        ConstString const_plugin_name(plugin_name);
+        create_callback  = PluginManager::GetOperatingSystemCreateCallbackForPluginName (const_plugin_name);
         if (create_callback)
         {
-            std::auto_ptr<OperatingSystem> instance_ap(create_callback(process, true));
+            std::unique_ptr<OperatingSystem> instance_ap(create_callback(process, true));
             if (instance_ap.get())
                 return instance_ap.release();
         }
@@ -37,7 +38,7 @@ OperatingSystem::FindPlugin (Process *pr
     {
         for (uint32_t idx = 0; (create_callback = PluginManager::GetOperatingSystemCreateCallbackAtIndex(idx)) != NULL; ++idx)
         {
-            std::auto_ptr<OperatingSystem> instance_ap(create_callback(process, false));
+            std::unique_ptr<OperatingSystem> instance_ap(create_callback(process, false));
             if (instance_ap.get())
                 return instance_ap.release();
         }
@@ -54,3 +55,13 @@ OperatingSystem::OperatingSystem (Proces
 OperatingSystem::~OperatingSystem()
 {
 }
+
+
+bool
+OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp)
+{
+    if (thread_sp)
+        return thread_sp->IsOperatingSystemPluginThread();
+    return false;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Target/PathMappingList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/PathMappingList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/PathMappingList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/PathMappingList.cpp Thu Jun  6 19:06:43 2013
@@ -28,18 +28,17 @@ using namespace lldb_private;
 PathMappingList::PathMappingList () :
     m_pairs (),
     m_callback (NULL),
-    m_callback_baton (NULL)
+    m_callback_baton (NULL),
+    m_mod_id (0)
 {
 }
 
-PathMappingList::PathMappingList 
-(
-    ChangedCallback callback,
-    void *callback_baton
-) :
+PathMappingList::PathMappingList (ChangedCallback callback,
+                                  void *callback_baton) :
     m_pairs (),
     m_callback (callback),
-    m_callback_baton (callback_baton)
+    m_callback_baton (callback_baton),
+    m_mod_id (0)
 {
 }
 
@@ -47,7 +46,8 @@ PathMappingList::PathMappingList
 PathMappingList::PathMappingList (const PathMappingList &rhs) :
     m_pairs (rhs.m_pairs),
     m_callback (NULL),
-    m_callback_baton (NULL)
+    m_callback_baton (NULL),
+    m_mod_id (0)
 {
     
 }
@@ -60,6 +60,7 @@ PathMappingList::operator =(const PathMa
         m_pairs = rhs.m_pairs;
         m_callback = NULL;
         m_callback_baton = NULL;
+        m_mod_id = rhs.m_mod_id;
     }
     return *this;
 }
@@ -77,6 +78,7 @@ PathMappingList::Append (const ConstStri
                          const ConstString &replacement,
                          bool notify)
 {
+    ++m_mod_id;
     m_pairs.push_back(pair(path, replacement));
     if (notify && m_callback)
         m_callback (*this, m_callback_baton);
@@ -85,6 +87,7 @@ PathMappingList::Append (const ConstStri
 void
 PathMappingList::Append (const PathMappingList &rhs, bool notify)
 {
+    ++m_mod_id;
     if (!rhs.m_pairs.empty())
     {
         const_iterator pos, end = rhs.m_pairs.end();
@@ -101,6 +104,7 @@ PathMappingList::Insert (const ConstStri
                          uint32_t index,
                          bool notify)
 {
+    ++m_mod_id;
     iterator insert_iter;
     if (index >= m_pairs.size())
         insert_iter = m_pairs.end();
@@ -112,11 +116,28 @@ PathMappingList::Insert (const ConstStri
 }
 
 bool
+PathMappingList::Replace (const ConstString &path,
+                          const ConstString &replacement,
+                          uint32_t index,
+                          bool notify)
+{
+    iterator insert_iter;
+    if (index >= m_pairs.size())
+        return false;
+    ++m_mod_id;
+    m_pairs[index] = pair(path, replacement);
+    if (notify && m_callback)
+        m_callback (*this, m_callback_baton);
+    return true;
+}
+
+bool
 PathMappingList::Remove (off_t index, bool notify)
 {
     if (index >= m_pairs.size())
         return false;
 
+    ++m_mod_id;
     iterator iter = m_pairs.begin() + index;
     m_pairs.erase(iter);
     if (notify && m_callback)
@@ -149,6 +170,8 @@ PathMappingList::Dump (Stream *s, int pa
 void
 PathMappingList::Clear (bool notify)
 {
+    if (!m_pairs.empty())
+        ++m_mod_id;
     m_pairs.clear();
     if (notify && m_callback)
         m_callback (*this, m_callback_baton);
@@ -157,12 +180,17 @@ PathMappingList::Clear (bool notify)
 bool
 PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const
 {
+    const char *path_cstr = path.GetCString();
+    
+    if (!path_cstr)
+        return false;
+    
     const_iterator pos, end = m_pairs.end();
     for (pos = m_pairs.begin(); pos != end; ++pos)
     {
         const size_t prefixLen = pos->first.GetLength();
 
-        if (::strncmp (pos->first.GetCString(), path.GetCString(), prefixLen) == 0)
+        if (::strncmp (pos->first.GetCString(), path_cstr, prefixLen) == 0)
         {
             std::string new_path_str (pos->second.GetCString());
             new_path_str.append(path.GetCString() + prefixLen);
@@ -235,6 +263,7 @@ PathMappingList::Replace (const ConstStr
     uint32_t idx = FindIndexForPath (path);
     if (idx < m_pairs.size())
     {
+        ++m_mod_id;
         m_pairs[idx].second = new_path;
         if (notify && m_callback)
             m_callback (*this, m_callback_baton);
@@ -249,6 +278,7 @@ PathMappingList::Remove (const ConstStri
     iterator pos = FindIteratorForPath (path);
     if (pos != m_pairs.end())
     {
+        ++m_mod_id;
         m_pairs.erase (pos);
         if (notify && m_callback)
             m_callback (*this, m_callback_baton);

Modified: lldb/branches/lldb-platform-work/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Platform.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Platform.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Platform.cpp Thu Jun  6 19:06:43 2013
@@ -16,6 +16,7 @@
 #include "lldb/Breakpoint/BreakpointIDList.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
@@ -89,6 +90,43 @@ Platform::GetFile (const FileSpec &platf
     return Error();
 }
 
+FileSpecList
+Platform::LocateExecutableScriptingResources (Target *target, Module &module)
+{
+    return FileSpecList();
+}
+
+Platform*
+Platform::FindPlugin (Process *process, const ConstString &plugin_name)
+{
+    PlatformCreateInstance create_callback = NULL;
+    if (plugin_name)
+    {
+        create_callback  = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name);
+        if (create_callback)
+        {
+            ArchSpec arch;
+            if (process)
+            {
+                arch = process->GetTarget().GetArchitecture();
+            }
+            std::unique_ptr<Platform> instance_ap(create_callback(process, &arch));
+            if (instance_ap.get())
+                return instance_ap.release();
+        }
+    }
+    else
+    {
+        for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx)
+        {
+            std::unique_ptr<Platform> instance_ap(create_callback(process, nullptr));
+            if (instance_ap.get())
+                return instance_ap.release();
+        }
+    }
+    return NULL;
+}
+
 Error
 Platform::GetSharedModule (const ModuleSpec &module_spec,
                            ModuleSP &module_sp,
@@ -119,7 +157,8 @@ Platform::Create (const char *platform_n
     lldb::PlatformSP platform_sp;
     if (platform_name && platform_name[0])
     {
-        create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
+        ConstString const_platform_name (platform_name);
+        create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (const_platform_name);
         if (create_callback)
             platform_sp.reset(create_callback(true, NULL));
         else
@@ -139,12 +178,27 @@ Platform::Create (const ArchSpec &arch,
     {
         uint32_t idx;
         PlatformCreateInstance create_callback;
+        // First try exact arch matches across all platform plug-ins
+        bool exact = true;
         for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
         {
             if (create_callback)
+            {
                 platform_sp.reset(create_callback(false, &arch));
-            if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, platform_arch_ptr))
-                return platform_sp;
+                if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
+                    return platform_sp;
+            }
+        }
+        // Next try compatible arch matches across all platform plug-ins
+        exact = false;
+        for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
+        {
+            if (create_callback)
+            {
+                platform_sp.reset(create_callback(false, &arch));
+                if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
+                    return platform_sp;
+            }
         }
     }
     else
@@ -202,7 +256,7 @@ Platform::Platform (bool is_host) :
     m_ssh_opts (),
     m_ignores_remote_hostname (false)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Platform::Platform()", this);
 }
@@ -215,7 +269,7 @@ Platform::Platform (bool is_host) :
 //------------------------------------------------------------------
 Platform::~Platform()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Platform::~Platform()", this);
 }
@@ -227,7 +281,7 @@ Platform::GetStatus (Stream &strm)
     uint32_t minor = UINT32_MAX;
     uint32_t update = UINT32_MAX;
     std::string s;
-    strm.Printf ("  Platform: %s\n", GetShortPluginName());
+    strm.Printf ("  Platform: %s\n", GetPluginName().GetCString());
 
     ArchSpec arch (GetSystemArchitecture());
     if (arch.IsValid())
@@ -350,13 +404,13 @@ Platform::GetOSKernelDescription (std::s
         return GetRemoteOSKernelDescription (s);
 }
 
-const char *
+ConstString
 Platform::GetName ()
 {
     const char *name = GetHostname();
     if (name == NULL || name[0] == '\0')
-        name = GetShortPluginName();
-    return name;
+        return GetPluginName();
+    return ConstString (name);
 }
 
 const char *
@@ -472,14 +526,28 @@ Platform::ResolveExecutable (const FileS
     }
     else
     {
-        error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
-                                        exe_file.GetDirectory().AsCString(""),
-                                        exe_file.GetDirectory() ? "/" : "",
-                                        exe_file.GetFilename().AsCString(""));
+        error.SetErrorStringWithFormat ("'%s' does not exist",
+                                        exe_file.GetPath().c_str());
     }
     return error;
 }
 
+Error
+Platform::ResolveSymbolFile (Target &target,
+                             const ModuleSpec &sym_spec,
+                             FileSpec &sym_file)
+{
+    Error error;
+    if (sym_spec.GetSymbolFileSpec().Exists())
+        sym_file = sym_spec.GetSymbolFileSpec();
+    else
+        error.SetErrorString("unable to resolve symbol file");
+    return error;
+    
+}
+
+
+
 bool
 Platform::ResolveRemotePath (const FileSpec &platform_path,
                              FileSpec &resolved_platform_path)
@@ -540,9 +608,9 @@ Platform::ConnectRemote (Args& args)
 {
     Error error;
     if (IsHost())
-        error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
+        error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString());
     else
-        error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
+        error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString());
     return error;
 }
 
@@ -551,9 +619,9 @@ Platform::DisconnectRemote ()
 {
     Error error;
     if (IsHost())
-        error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
+        error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString());
     else
-        error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
+        error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString());
     return error;
 }
 
@@ -672,19 +740,35 @@ Platform::GetPlatformForArchitecture (co
 /// architecture and the target triple contained within.
 //------------------------------------------------------------------
 bool
-Platform::IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr)
+Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr)
 {
     // If the architecture is invalid, we must answer true...
     if (arch.IsValid())
     {
         ArchSpec platform_arch;
-        for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
+        // Try for an exact architecture match first.
+        if (exact_arch_match)
         {
-            if (arch == platform_arch)
+            for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
             {
-                if (compatible_arch_ptr)
-                    *compatible_arch_ptr = platform_arch;
-                return true;
+                if (arch.IsExactMatch(platform_arch))
+                {
+                    if (compatible_arch_ptr)
+                        *compatible_arch_ptr = platform_arch;
+                    return true;
+                }
+            }
+        }
+        else
+        {
+            for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
+            {
+                if (arch.IsCompatibleMatch(platform_arch))
+                {
+                    if (compatible_arch_ptr)
+                        *compatible_arch_ptr = platform_arch;
+                    return true;
+                }
             }
         }
     }
@@ -697,8 +781,7 @@ uint32_t
 Platform::MakeDirectory (const FileSpec &spec,
                          mode_t mode)
 {
-    std::string path;
-    spec.GetPath(path);
+    std::string path(spec.GetPath());
     return this->MakeDirectory(path,mode);
 }
 
@@ -952,3 +1035,10 @@ OptionGroupPlatformCaching::GetNumDefini
 {
     return llvm::array_lengthof(g_caching_option_table);
 }
+
+size_t
+Platform::GetEnvironment (StringList &environment)
+{
+    environment.Clear();
+    return false;
+}

Modified: lldb/branches/lldb-platform-work/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Process.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Process.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Process.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Target/Process.h"
 
 #include "lldb/lldb-private-log.h"
@@ -18,6 +20,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/InputReader.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/State.h"
 #include "lldb/Expression/ClangUserExpression.h"
@@ -41,15 +44,200 @@
 using namespace lldb;
 using namespace lldb_private;
 
+
+// Comment out line below to disable memory caching, overriding the process setting
+// target.process.disable-memory-cache
+#define ENABLE_MEMORY_CACHING
+
+#ifdef ENABLE_MEMORY_CACHING
+#define DISABLE_MEM_CACHE_DEFAULT false
+#else
+#define DISABLE_MEM_CACHE_DEFAULT true
+#endif
+
+class ProcessOptionValueProperties : public OptionValueProperties
+{
+public:
+    ProcessOptionValueProperties (const ConstString &name) :
+        OptionValueProperties (name)
+    {
+    }
+    
+    // This constructor is used when creating ProcessOptionValueProperties when it
+    // is part of a new lldb_private::Process instance. It will copy all current
+    // global property values as needed
+    ProcessOptionValueProperties (ProcessProperties *global_properties) :
+        OptionValueProperties(*global_properties->GetValueProperties())
+    {
+    }
+    
+    virtual const Property *
+    GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
+    {
+        // When gettings the value for a key from the process options, we will always
+        // try and grab the setting from the current process if there is one. Else we just
+        // use the one from this instance.
+        if (exe_ctx)
+        {
+            Process *process = exe_ctx->GetProcessPtr();
+            if (process)
+            {
+                ProcessOptionValueProperties *instance_properties = static_cast<ProcessOptionValueProperties *>(process->GetValueProperties().get());
+                if (this != instance_properties)
+                    return instance_properties->ProtectedGetPropertyAtIndex (idx);
+            }
+        }
+        return ProtectedGetPropertyAtIndex (idx);
+    }
+};
+
+static PropertyDefinition
+g_properties[] =
+{
+    { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, NULL, NULL, "Disable reading and caching of memory in fixed-size units." },
+    { "extra-startup-command", OptionValue::eTypeArray  , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used.  "
+                                                                                                       "For instance, to turn on debugserver logging set this to \"QSetLogging:bitmask=LOG_DEFAULT;\"" },
+    { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, breakpoints will be ignored during expression evaluation." },
+    { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
+    { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
+    { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." },
+    { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, detach will attempt to keep the process stopped." },
+    {  NULL                  , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL  }
+};
+
+enum {
+    ePropertyDisableMemCache,
+    ePropertyExtraStartCommand,
+    ePropertyIgnoreBreakpointsInExpressions,
+    ePropertyUnwindOnErrorInExpressions,
+    ePropertyPythonOSPluginPath,
+    ePropertyStopOnSharedLibraryEvents,
+    ePropertyDetachKeepsStopped
+};
+
+ProcessProperties::ProcessProperties (bool is_global) :
+    Properties ()
+{
+    if (is_global)
+    {
+        m_collection_sp.reset (new ProcessOptionValueProperties(ConstString("process")));
+        m_collection_sp->Initialize(g_properties);
+        m_collection_sp->AppendProperty(ConstString("thread"),
+                                        ConstString("Settings specific to threads."),
+                                        true,
+                                        Thread::GetGlobalProperties()->GetValueProperties());
+    }
+    else
+        m_collection_sp.reset (new ProcessOptionValueProperties(Process::GetGlobalProperties().get()));
+}
+
+ProcessProperties::~ProcessProperties()
+{
+}
+
+bool
+ProcessProperties::GetDisableMemoryCache() const
+{
+    const uint32_t idx = ePropertyDisableMemCache;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+Args
+ProcessProperties::GetExtraStartupCommands () const
+{
+    Args args;
+    const uint32_t idx = ePropertyExtraStartCommand;
+    m_collection_sp->GetPropertyAtIndexAsArgs(NULL, idx, args);
+    return args;
+}
+
+void
+ProcessProperties::SetExtraStartupCommands (const Args &args)
+{
+    const uint32_t idx = ePropertyExtraStartCommand;
+    m_collection_sp->SetPropertyAtIndexFromArgs(NULL, idx, args);
+}
+
+FileSpec
+ProcessProperties::GetPythonOSPluginPath () const
+{
+    const uint32_t idx = ePropertyPythonOSPluginPath;
+    return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+}
+
+void
+ProcessProperties::SetPythonOSPluginPath (const FileSpec &file)
+{
+    const uint32_t idx = ePropertyPythonOSPluginPath;
+    m_collection_sp->SetPropertyAtIndexAsFileSpec(NULL, idx, file);
+}
+
+
+bool
+ProcessProperties::GetIgnoreBreakpointsInExpressions () const
+{
+    const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+    
+void
+ProcessProperties::SetIgnoreBreakpointsInExpressions (bool ignore)
+{
+    const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
+    m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+}
+
+bool
+ProcessProperties::GetUnwindOnErrorInExpressions () const
+{
+    const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+    
+void
+ProcessProperties::SetUnwindOnErrorInExpressions (bool ignore)
+{
+    const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
+    m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+}
+
+bool
+ProcessProperties::GetStopOnSharedLibraryEvents () const
+{
+    const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+    
+void
+ProcessProperties::SetStopOnSharedLibraryEvents (bool stop)
+{
+    const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
+    m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+}
+
+bool
+ProcessProperties::GetDetachKeepsStopped () const
+{
+    const uint32_t idx = ePropertyDetachKeepsStopped;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+    
+void
+ProcessProperties::SetDetachKeepsStopped (bool stop)
+{
+    const uint32_t idx = ePropertyDetachKeepsStopped;
+    m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+}
+
 void
 ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
 {
     const char *cstr;
     if (m_pid != LLDB_INVALID_PROCESS_ID)       
-        s.Printf ("    pid = %llu\n", m_pid);
+        s.Printf ("    pid = %" PRIu64 "\n", m_pid);
 
     if (m_parent_pid != LLDB_INVALID_PROCESS_ID)
-        s.Printf (" parent = %llu\n", m_parent_pid);
+        s.Printf (" parent = %" PRIu64 "\n", m_parent_pid);
 
     if (m_executable)
     {
@@ -136,7 +324,7 @@ ProcessInstanceInfo::DumpAsTableRow (Str
     if (m_pid != LLDB_INVALID_PROCESS_ID)
     {
         const char *cstr;
-        s.Printf ("%-6llu %-6llu ", m_pid, m_parent_pid);
+        s.Printf ("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
 
     
         if (verbose)
@@ -198,9 +386,7 @@ ProcessInstanceInfo::DumpAsTableRow (Str
 
 
 void
-ProcessInfo::SetArguments (char const **argv,
-                           bool first_arg_is_executable,
-                           bool first_arg_is_executable_and_argument)
+ProcessInfo::SetArguments (char const **argv, bool first_arg_is_executable)
 {
     m_arguments.SetArguments (argv);
         
@@ -215,18 +401,11 @@ ProcessInfo::SetArguments (char const **
             // could be a remote platform path
             const bool resolve = false;
             m_executable.SetFile(first_arg, resolve); 
-            
-            // If argument zero is an executable and shouldn't be included
-            // in the arguments, remove it from the front of the arguments
-            if (first_arg_is_executable_and_argument == false)
-                m_arguments.DeleteArgumentAtIndex (0);
         }
     }
 }
 void
-ProcessInfo::SetArguments (const Args& args, 
-                           bool first_arg_is_executable,
-                           bool first_arg_is_executable_and_argument)
+ProcessInfo::SetArguments (const Args& args, bool first_arg_is_executable)
 {
     // Copy all arguments
     m_arguments = args;
@@ -242,11 +421,6 @@ ProcessInfo::SetArguments (const Args& a
             // could be a remote platform path
             const bool resolve = false;
             m_executable.SetFile(first_arg, resolve); 
-    
-            // If argument zero is an executable and shouldn't be included
-            // in the arguments, remove it from the front of the arguments
-            if (first_arg_is_executable_and_argument == false)
-                m_arguments.DeleteArgumentAtIndex (0);
         }
     }
 }
@@ -270,9 +444,9 @@ ProcessLaunchInfo::FinalizeFileActions (
             // (lldb) settings set target.input-path
             // (lldb) settings set target.output-path
             // (lldb) settings set target.error-path
-            const char *in_path = NULL;
-            const char *out_path = NULL;
-            const char *err_path = NULL;
+            FileSpec in_path;
+            FileSpec out_path;
+            FileSpec err_path;
             if (target)
             {
                 in_path = target->GetStandardInputPath();
@@ -280,23 +454,28 @@ ProcessLaunchInfo::FinalizeFileActions (
                 err_path = target->GetStandardErrorPath();
             }
             
-            if (default_to_use_pty && (!in_path && !out_path && !err_path))
+            if (in_path || out_path || err_path)
+            {
+                char path[PATH_MAX];
+                if (in_path && in_path.GetPath(path, sizeof(path)))
+                    AppendOpenFileAction(STDIN_FILENO, path, true, false);
+                
+                if (out_path && out_path.GetPath(path, sizeof(path)))
+                    AppendOpenFileAction(STDOUT_FILENO, path, false, true);
+                
+                if (err_path && err_path.GetPath(path, sizeof(path)))
+                    AppendOpenFileAction(STDERR_FILENO, path, false, true);
+            }
+            else if (default_to_use_pty)
             {
                 if (m_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, NULL, 0))
                 {
-                    in_path = out_path = err_path = m_pty.GetSlaveName (NULL, 0);
+                    const char *slave_path = m_pty.GetSlaveName (NULL, 0);
+                    AppendOpenFileAction(STDIN_FILENO, slave_path, true, false);
+                    AppendOpenFileAction(STDOUT_FILENO, slave_path, false, true);
+                    AppendOpenFileAction(STDERR_FILENO, slave_path, false, true);
                 }
             }
-
-            if (in_path)
-                AppendOpenFileAction(STDIN_FILENO, in_path, true, false);
-            
-            if (out_path)
-                AppendOpenFileAction(STDOUT_FILENO, out_path, false, true);
-
-            if (err_path)
-                AppendOpenFileAction(STDERR_FILENO, err_path, false, true);
-
         }
     }
 }
@@ -334,19 +513,57 @@ ProcessLaunchInfo::ConvertArgumentsForLa
                 shell_executable = shell_resolved_path;
             }
             
+            const char **argv = GetArguments().GetConstArgumentVector ();
+            if (argv == NULL || argv[0] == NULL)
+                return false;
             Args shell_arguments;
             std::string safe_arg;
             shell_arguments.AppendArgument (shell_executable);
             shell_arguments.AppendArgument ("-c");
-
             StreamString shell_command;
             if (will_debug)
             {
+                // Add a modified PATH environment variable in case argv[0]
+                // is a relative path
+                const char *argv0 = argv[0];
+                if (argv0 && (argv0[0] != '/' && argv0[0] != '~'))
+                {
+                    // We have a relative path to our executable which may not work if
+                    // we just try to run "a.out" (without it being converted to "./a.out")
+                    const char *working_dir = GetWorkingDirectory();
+                    // Be sure to put quotes around PATH's value in case any paths have spaces...
+                    std::string new_path("PATH=\"");
+                    const size_t empty_path_len = new_path.size();
+                    
+                    if (working_dir && working_dir[0])
+                    {
+                        new_path += working_dir;
+                    }
+                    else
+                    {
+                        char current_working_dir[PATH_MAX];
+                        const char *cwd = getcwd(current_working_dir, sizeof(current_working_dir));
+                        if (cwd && cwd[0])
+                            new_path += cwd;
+                    }
+                    const char *curr_path = getenv("PATH");
+                    if (curr_path)
+                    {
+                        if (new_path.size() > empty_path_len)
+                            new_path += ':';
+                        new_path += curr_path;
+                    }
+                    new_path += "\" ";
+                    shell_command.PutCString(new_path.c_str());
+                }
+
                 shell_command.PutCString ("exec");
+
+                // Only Apple supports /usr/bin/arch being able to specify the architecture
                 if (GetArchitecture().IsValid())
                 {
                     shell_command.Printf(" /usr/bin/arch -arch %s", GetArchitecture().GetArchitectureName());
-                    // Set the resume count to 2: 
+                    // Set the resume count to 2:
                     // 1 - stop in shell
                     // 2 - stop in /usr/bin/arch
                     // 3 - then we will stop in our program
@@ -354,39 +571,30 @@ ProcessLaunchInfo::ConvertArgumentsForLa
                 }
                 else
                 {
-                    // Set the resume count to 1: 
+                    // Set the resume count to 1:
                     // 1 - stop in shell
                     // 2 - then we will stop in our program
                     SetResumeCount(1);
                 }
             }
-            
-            const char **argv = GetArguments().GetConstArgumentVector ();
-            if (argv)
+        
+            if (first_arg_is_full_shell_command)
             {
-                if (first_arg_is_full_shell_command)
-                {
-                    // There should only be one argument that is the shell command itself to be used as is
-                    if (argv[0] && !argv[1])
-                        shell_command.Printf("%s", argv[0]);
-                    else
-                        return false;
-                }
+                // There should only be one argument that is the shell command itself to be used as is
+                if (argv[0] && !argv[1])
+                    shell_command.Printf("%s", argv[0]);
                 else
-                {
-                    for (size_t i=0; argv[i] != NULL; ++i)
-                    {
-                        const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg);
-                        shell_command.Printf(" %s", arg);
-                    }
-                }
-                shell_arguments.AppendArgument (shell_command.GetString().c_str());
+                    return false;
             }
             else
             {
-                return false;
+                for (size_t i=0; argv[i] != NULL; ++i)
+                {
+                    const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg);
+                    shell_command.Printf(" %s", arg);
+                }
             }
-
+            shell_arguments.AppendArgument (shell_command.GetString().c_str());
             m_executable.SetFile(shell_executable, false);
             m_arguments = shell_arguments;
             return true;
@@ -522,10 +730,6 @@ ProcessLaunchInfo::FileAction::AddPosixS
                                    file_actions, info->m_fd, info->m_path.c_str(), oflag, mode);
             }
             break;
-        
-        default:
-            error.SetErrorStringWithFormat ("invalid file action: %i", info->m_action);
-            break;
     }
     return error.Success();
 }
@@ -534,7 +738,7 @@ Error
 ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
 {
     Error error;
-    char short_option = (char) m_getopt_table[option_idx].val;
+    const int short_option = m_getopt_table[option_idx].val;
     
     switch (short_option)
     {
@@ -625,14 +829,14 @@ ProcessLaunchCommandOptions::g_option_ta
 { LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,          "Stop at the entry point of the program when launching a process."},
 { LLDB_OPT_SET_ALL, false, "disable-aslr",  'A', no_argument,       NULL, 0, eArgTypeNone,          "Disable address space layout randomization when launching a process."},
 { LLDB_OPT_SET_ALL, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
-{ LLDB_OPT_SET_ALL, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypePath,          "Set the current working directory to <path> when running the inferior."},
+{ LLDB_OPT_SET_ALL, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypeDirectoryName,          "Set the current working directory to <path> when running the inferior."},
 { LLDB_OPT_SET_ALL, false, "arch",          'a', required_argument, NULL, 0, eArgTypeArchitecture,  "Set the architecture for the process to launch when ambiguous."},
 { LLDB_OPT_SET_ALL, false, "environment",   'v', required_argument, NULL, 0, eArgTypeNone,          "Specify an environment variable name/value stirng (--environement NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
-{ LLDB_OPT_SET_ALL, false, "shell",         'c', optional_argument, NULL, 0, eArgTypePath,          "Run the process in a shell (not supported on all platforms)."},
+{ LLDB_OPT_SET_ALL, false, "shell",         'c', optional_argument, NULL, 0, eArgTypeFilename,          "Run the process in a shell (not supported on all platforms)."},
 
-{ LLDB_OPT_SET_1  , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
-{ LLDB_OPT_SET_1  , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
-{ LLDB_OPT_SET_1  , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
+{ LLDB_OPT_SET_1  , false, "stdin",         'i', required_argument, NULL, 0, eArgTypeFilename,    "Redirect stdin for the process to <filename>."},
+{ LLDB_OPT_SET_1  , false, "stdout",        'o', required_argument, NULL, 0, eArgTypeFilename,    "Redirect stdout for the process to <filename>."},
+{ LLDB_OPT_SET_1  , false, "stderr",        'e', required_argument, NULL, 0, eArgTypeFilename,    "Redirect stderr for the process to <filename>."},
 
 { LLDB_OPT_SET_2  , false, "tty",           't', no_argument,       NULL, 0, eArgTypeNone,    "Start the process in a terminal (not supported on all platforms)."},
 
@@ -686,7 +890,7 @@ ProcessInstanceInfoMatch::Matches (const
         return false;
     
     if (m_match_info.GetArchitecture().IsValid() && 
-        m_match_info.GetArchitecture() != proc_info.GetArchitecture())
+        !m_match_info.GetArchitecture().IsCompatibleMatch(proc_info.GetArchitecture()))
         return false;
     return true;
 }
@@ -736,17 +940,24 @@ ProcessInstanceInfoMatch::Clear()
 ProcessSP
 Process::FindPlugin (Target &target, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path)
 {
+    static uint32_t g_process_unique_id = 0;
+
     ProcessSP process_sp;
     ProcessCreateInstance create_callback = NULL;
     if (plugin_name)
     {
-        create_callback  = PluginManager::GetProcessCreateCallbackForPluginName (plugin_name);
+        ConstString const_plugin_name(plugin_name);
+        create_callback  = PluginManager::GetProcessCreateCallbackForPluginName (const_plugin_name);
         if (create_callback)
         {
             process_sp = create_callback(target, listener, crash_file_path);
             if (process_sp)
             {
-                if (!process_sp->CanDebug(target, true))
+                if (process_sp->CanDebug(target, true))
+                {
+                    process_sp->m_process_unique_id = ++g_process_unique_id;
+                }
+                else
                     process_sp.reset();
             }
         }
@@ -758,10 +969,13 @@ Process::FindPlugin (Target &target, con
             process_sp = create_callback(target, listener, crash_file_path);
             if (process_sp)
             {
-                if (!process_sp->CanDebug(target, false))
-                    process_sp.reset();
-                else
+                if (process_sp->CanDebug(target, false))
+                {
+                    process_sp->m_process_unique_id = ++g_process_unique_id;
                     break;
+                }
+                else
+                    process_sp.reset();
             }
         }
     }
@@ -779,9 +993,10 @@ Process::GetStaticBroadcasterClass ()
 // Process constructor
 //----------------------------------------------------------------------
 Process::Process(Target &target, Listener &listener) :
+    ProcessProperties (false),
     UserID (LLDB_INVALID_PROCESS_ID),
     Broadcaster (&(target.GetDebugger()), "lldb.process"),
-    ProcessInstanceSettings (GetSettingsController()),
+    m_reservation_cache (*this),
     m_target (target),
     m_public_state (eStateUnloaded),
     m_private_state (eStateUnloaded),
@@ -791,9 +1006,13 @@ Process::Process(Target &target, Listene
     m_private_state_control_wait(),
     m_private_state_thread (LLDB_INVALID_HOST_THREAD),
     m_mod_id (),
+    m_process_unique_id(0),
     m_thread_index_id (0),
+    m_thread_id_to_index_id_map (),
     m_exit_status (-1),
     m_exit_string (),
+    m_thread_mutex (Mutex::eMutexTypeRecursive),
+    m_thread_list_real (this),
     m_thread_list (this),
     m_notifications (),
     m_image_tokens (),
@@ -807,19 +1026,24 @@ Process::Process(Target &target, Listene
     m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
     m_stdout_data (),
     m_stderr_data (),
+    m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
+    m_profile_data (),
     m_memory_cache (*this),
     m_allocated_memory_cache (*this),
     m_should_detach (false),
     m_next_event_action_ap(),
-    m_run_lock (),
+    m_public_run_lock (),
+    m_private_run_lock (),
     m_currently_handling_event(false),
+    m_finalize_called(false),
+    m_clear_thread_plans_on_stop (false),
+    m_last_broadcast_state (eStateInvalid),
+    m_destroy_in_process (false),
     m_can_jit(eCanJITDontKnow)
 {
-    UpdateInstanceName();
-    
     CheckInWithManager ();
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Process::Process()", this);
 
@@ -827,12 +1051,18 @@ Process::Process(Target &target, Listene
     SetEventName (eBroadcastBitInterrupt, "interrupt");
     SetEventName (eBroadcastBitSTDOUT, "stdout-available");
     SetEventName (eBroadcastBitSTDERR, "stderr-available");
+    SetEventName (eBroadcastBitProfileData, "profile-data-available");
     
+    m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop  , "control-stop"  );
+    m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
+    m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume");
+
     listener.StartListeningForEvents (this,
                                       eBroadcastBitStateChanged |
                                       eBroadcastBitInterrupt |
                                       eBroadcastBitSTDOUT |
-                                      eBroadcastBitSTDERR);
+                                      eBroadcastBitSTDERR |
+                                      eBroadcastBitProfileData);
 
     m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
                                                      eBroadcastBitStateChanged |
@@ -849,12 +1079,21 @@ Process::Process(Target &target, Listene
 //----------------------------------------------------------------------
 Process::~Process()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Process::~Process()", this);
     StopPrivateStateThread();
 }
 
+const ProcessPropertiesSP &
+Process::GetGlobalProperties()
+{
+    static ProcessPropertiesSP g_settings_sp;
+    if (!g_settings_sp)
+        g_settings_sp.reset (new ProcessProperties (true));
+    return g_settings_sp;
+}
+
 void
 Process::Finalize()
 {
@@ -869,7 +1108,11 @@ Process::Finalize()
         case eStateCrashed:
         case eStateSuspended:
             if (GetShouldDetach())
-                Detach();
+            {
+                // FIXME: This will have to be a process setting:
+                bool keep_stopped = false;
+                Detach(keep_stopped);
+            }
             else
                 Destroy();
             break;
@@ -893,6 +1136,7 @@ Process::Finalize()
     m_abi_sp.reset();
     m_os_ap.reset();
     m_dyld_ap.reset();
+    m_thread_list_real.Destroy();
     m_thread_list.Destroy();
     std::vector<Notifications> empty_notifications;
     m_notifications.swap(empty_notifications);
@@ -901,6 +1145,24 @@ Process::Finalize()
     m_allocated_memory_cache.Clear();
     m_language_runtimes.clear();
     m_next_event_action_ap.reset();
+//#ifdef LLDB_CONFIGURATION_DEBUG
+//    StreamFile s(stdout, false);
+//    EventSP event_sp;
+//    while (m_private_state_listener.GetNextEvent(event_sp))
+//    {
+//        event_sp->Dump (&s);
+//        s.EOL();
+//    }
+//#endif
+    // We have to be very careful here as the m_private_state_listener might
+    // contain events that have ProcessSP values in them which can keep this
+    // process around forever. These events need to be cleared out.
+    m_private_state_listener.Clear();
+    m_public_run_lock.WriteTryLock(); // This will do nothing if already locked
+    m_public_run_lock.WriteUnlock();
+    m_private_run_lock.WriteTryLock(); // This will do nothing if already locked
+    m_private_run_lock.WriteUnlock();
+    m_finalize_called = true;
 }
 
 void
@@ -960,12 +1222,13 @@ Process::GetNextEvent (EventSP &event_sp
 
 
 StateType
-Process::WaitForProcessToStop (const TimeValue *timeout)
+Process::WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr)
 {
     // We can't just wait for a "stopped" event, because the stopped event may have restarted the target.
     // We have to actually check each event, and in the case of a stopped event check the restarted flag
     // on the event.
-    EventSP event_sp;
+    if (event_sp_ptr)
+        event_sp_ptr->reset();
     StateType state = GetState();
     // If we are exited or detached, we won't ever get back to any
     // other valid state...
@@ -974,7 +1237,11 @@ Process::WaitForProcessToStop (const Tim
 
     while (state != eStateInvalid)
     {
+        EventSP event_sp;
         state = WaitForStateChangedEvents (timeout, event_sp);
+        if (event_sp_ptr && event_sp)
+            *event_sp_ptr = event_sp;
+
         switch (state)
         {
         case eStateCrashed:
@@ -1060,7 +1327,7 @@ Process::RestorePrivateProcessEvents ()
 StateType
 Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
     if (log)
         log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
@@ -1088,7 +1355,7 @@ Process::WaitForStateChangedEvents (cons
 Event *
 Process::PeekAtStateChangedEvents ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
     if (log)
         log->Printf ("Process::%s...", __FUNCTION__);
@@ -1116,7 +1383,7 @@ Process::PeekAtStateChangedEvents ()
 StateType
 Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &event_sp)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
     if (log)
         log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
@@ -1145,7 +1412,7 @@ Process::WaitForStateChangedEventsPrivat
 bool
 Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool control_only)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
     if (log)
         log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
@@ -1182,7 +1449,7 @@ Process::GetExitDescription ()
 bool
 Process::SetExitStatus (int status, const char *cstr)
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
     if (log)
         log->Printf("Process::SetExitStatus (status=%i (0x%8.8x), description=%s%s%s)", 
                     status, status,
@@ -1222,9 +1489,9 @@ Process::SetProcessExitStatus (void *cal
                                int exit_status     // Exit value of process if signal is zero
 )
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
     if (log)
-        log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%llu, exited=%i, signal=%i, exit_status=%i)\n", 
+        log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n",
                      callback_baton,
                      pid,
                      exited,
@@ -1265,14 +1532,38 @@ Process::UpdateThreadListIfNeeded ()
             // m_thread_list does have its own mutex, but we need to
             // hold onto the mutex between the call to UpdateThreadList(...)
             // and the os->UpdateThreadList(...) so it doesn't change on us
+            ThreadList &old_thread_list = m_thread_list;
+            ThreadList real_thread_list(this);
             ThreadList new_thread_list(this);
             // Always update the thread list with the protocol specific
             // thread list, but only update if "true" is returned
-            if (UpdateThreadList (m_thread_list, new_thread_list))
+            if (UpdateThreadList (m_thread_list_real, real_thread_list))
             {
-                OperatingSystem *os = GetOperatingSystem ();
-                if (os)
-                    os->UpdateThreadList (m_thread_list, new_thread_list);
+                // Don't call into the OperatingSystem to update the thread list if we are shutting down, since
+                // that may call back into the SBAPI's, requiring the API lock which is already held by whoever is
+                // shutting us down, causing a deadlock.
+                if (!m_destroy_in_process)
+                {
+                    OperatingSystem *os = GetOperatingSystem ();
+                    if (os)
+                    {
+                        // Clear any old backing threads where memory threads might have been
+                        // backed by actual threads from the lldb_private::Process subclass
+                        size_t num_old_threads = old_thread_list.GetSize(false);
+                        for (size_t i=0; i<num_old_threads; ++i)
+                            old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
+
+                        // Now let the OperatingSystem plug-in update the thread list
+                        os->UpdateThreadList (old_thread_list,  // Old list full of threads created by OS plug-in
+                                              real_thread_list, // The actual thread list full of threads created by each lldb_private::Process subclass
+                                              new_thread_list); // The new thread list that we will show to the user that gets filled in
+                    }
+                    else
+                    {
+                        // No OS plug-in, the new thread list is the same as the real thread list
+                        new_thread_list = real_thread_list;
+                    }
+                }
                 m_thread_list.Update (new_thread_list);
                 m_thread_list.SetStopID (stop_id);
             }
@@ -1280,12 +1571,62 @@ Process::UpdateThreadListIfNeeded ()
     }
 }
 
+ThreadSP
+Process::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context)
+{
+    OperatingSystem *os = GetOperatingSystem ();
+    if (os)
+        return os->CreateThread(tid, context);
+    return ThreadSP();
+}
+
+
+
+// This is obsoleted. Staged removal for Xcode.
 uint32_t
 Process::GetNextThreadIndexID ()
 {
     return ++m_thread_index_id;
 }
 
+uint32_t
+Process::GetNextThreadIndexID (uint64_t thread_id)
+{
+    return AssignIndexIDToThread(thread_id);
+}
+
+bool
+Process::HasAssignedIndexIDToThread(uint64_t thread_id)
+{
+    std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_index_id_map.find(thread_id);
+    if (iterator == m_thread_id_to_index_id_map.end())
+    {
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+uint32_t
+Process::AssignIndexIDToThread(uint64_t thread_id)
+{
+    uint32_t result = 0;
+    std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_index_id_map.find(thread_id);
+    if (iterator == m_thread_id_to_index_id_map.end())
+    {
+        result = ++m_thread_index_id;
+        m_thread_id_to_index_id_map[thread_id] = result;
+    }
+    else
+    {
+        result = iterator->second;
+    }
+    
+    return result;
+}
+
 StateType
 Process::GetState()
 {
@@ -1294,11 +1635,11 @@ Process::GetState()
 }
 
 void
-Process::SetPublicState (StateType new_state)
+Process::SetPublicState (StateType new_state, bool restarted)
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
     if (log)
-        log->Printf("Process::SetPublicState (%s)", StateAsCString(new_state));
+        log->Printf("Process::SetPublicState (state = %s, restarted = %i)", StateAsCString(new_state), restarted);
     const StateType old_state = m_public_state.GetValue();
     m_public_state.SetValue (new_state);
     
@@ -1311,19 +1652,19 @@ Process::SetPublicState (StateType new_s
         {
             if (log)
                 log->Printf("Process::SetPublicState (%s) -- unlocking run lock for detach", StateAsCString(new_state));
-            m_run_lock.WriteUnlock();
+            m_public_run_lock.WriteUnlock();
         }
         else
         {
             const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
             const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
-            if (old_state_is_stopped != new_state_is_stopped)
+            if ((old_state_is_stopped != new_state_is_stopped))
             {
-                if (new_state_is_stopped)
+                if (new_state_is_stopped && !restarted)
                 {
                     if (log)
                         log->Printf("Process::SetPublicState (%s) -- unlocking run lock", StateAsCString(new_state));
-                    m_run_lock.WriteUnlock();
+                    m_public_run_lock.WriteUnlock();
                 }
             }
         }
@@ -1333,10 +1674,10 @@ Process::SetPublicState (StateType new_s
 Error
 Process::Resume ()
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
     if (log)
         log->Printf("Process::Resume -- locking run lock");
-    if (!m_run_lock.WriteTryLock())
+    if (!m_public_run_lock.WriteTryLock())
     {
         Error error("Resume request failed - process still running.");
         if (log)
@@ -1355,12 +1696,13 @@ Process::GetPrivateState ()
 void
 Process::SetPrivateState (StateType new_state)
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
     bool state_changed = false;
 
     if (log)
         log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
 
+    Mutex::Locker thread_locker(m_thread_list.GetMutex());
     Mutex::Locker locker(m_private_state.GetMutex());
 
     const StateType old_state = m_private_state.GetValueNoLock ();
@@ -1369,28 +1711,44 @@ Process::SetPrivateState (StateType new_
     // the private process state with another run lock. Right now it doesn't
     // seem like we need to do this, but if we ever do, we can uncomment and
     // use this code.
-//    const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
-//    const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
-//    if (old_state_is_stopped != new_state_is_stopped)
-//    {
-//        if (new_state_is_stopped)
-//            m_private_run_lock.WriteUnlock();
-//        else
-//            m_private_run_lock.WriteLock();
-//    }
+    const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
+    const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
+    if (old_state_is_stopped != new_state_is_stopped)
+    {
+        if (new_state_is_stopped)
+            m_private_run_lock.WriteUnlock();
+        else
+            m_private_run_lock.WriteLock();
+    }
 
     if (state_changed)
     {
         m_private_state.SetValueNoLock (new_state);
         if (StateIsStoppedState(new_state, false))
         {
+            // Note, this currently assumes that all threads in the list
+            // stop when the process stops.  In the future we will want to
+            // support a debugging model where some threads continue to run
+            // while others are stopped.  When that happens we will either need
+            // a way for the thread list to identify which threads are stopping
+            // or create a special thread list containing only threads which
+            // actually stopped.
+            //
+            // The process plugin is responsible for managing the actual
+            // behavior of the threads and should have stopped any threads
+            // that are going to stop before we get here.
+            m_thread_list.DidStop();
+
             m_mod_id.BumpStopID();
             m_memory_cache.Clear();
             if (log)
                 log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_mod_id.GetStopID());
         }
         // Use our target to get a shared pointer to ourselves...
-        m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (GetTarget().GetProcessSP(), new_state));
+        if (m_finalize_called && PrivateStateThreadIsValid() == false)
+            BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
+        else
+            m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
     }
     else
     {
@@ -1445,12 +1803,23 @@ Process::LoadImage (const FileSpec &imag
             {
                 ExecutionContext exe_ctx;
                 frame_sp->CalculateExecutionContext (exe_ctx);
-                bool unwind_on_error = true;
+                const bool unwind_on_error = true;
+                const bool ignore_breakpoints = true;
                 StreamString expr;
                 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, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
+                ClangUserExpression::Evaluate (exe_ctx,
+                                               eExecutionPolicyAlways,
+                                               lldb::eLanguageTypeUnknown,
+                                               ClangUserExpression::eResultTypeAny,
+                                               unwind_on_error,
+                                               ignore_breakpoints,
+                                               expr.GetData(),
+                                               prefix,
+                                               result_valobj_sp,
+                                               true,
+                                               ClangUserExpression::kDefaultTimeout);
                 error = result_valobj_sp->GetError();
                 if (error.Success())
                 {
@@ -1511,12 +1880,23 @@ Process::UnloadImage (uint32_t image_tok
                     {
                         ExecutionContext exe_ctx;
                         frame_sp->CalculateExecutionContext (exe_ctx);
-                        bool unwind_on_error = true;
+                        const bool unwind_on_error = true;
+                        const bool ignore_breakpoints = true;
                         StreamString expr;
-                        expr.Printf("dlclose ((void *)0x%llx)", image_addr);
+                        expr.Printf("dlclose ((void *)0x%" PRIx64 ")", image_addr);
                         const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
                         lldb::ValueObjectSP result_valobj_sp;
-                        ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
+                        ClangUserExpression::Evaluate (exe_ctx,
+                                                       eExecutionPolicyAlways,
+                                                       lldb::eLanguageTypeUnknown,
+                                                       ClangUserExpression::eResultTypeAny,
+                                                       unwind_on_error,
+                                                       ignore_breakpoints,
+                                                       expr.GetData(),
+                                                       prefix,
+                                                       result_valobj_sp,
+                                                       true,
+                                                       ClangUserExpression::kDefaultTimeout);
                         if (result_valobj_sp->GetError().Success())
                         {
                             Scalar scalar;
@@ -1631,7 +2011,7 @@ Process::DisableAllBreakpointSites ()
     size_t num_sites = m_breakpoint_site_list.GetSize();
     for (size_t i = 0; i < num_sites; i++)
     {
-        DisableBreakpoint (m_breakpoint_site_list.GetByIndex(i).get());
+        DisableBreakpointSite (m_breakpoint_site_list.GetByIndex(i).get());
     }
 }
 
@@ -1654,11 +2034,11 @@ Process::DisableBreakpointSiteByID (lldb
     if (bp_site_sp)
     {
         if (bp_site_sp->IsEnabled())
-            error = DisableBreakpoint (bp_site_sp.get());
+            error = DisableBreakpointSite (bp_site_sp.get());
     }
     else
     {
-        error.SetErrorStringWithFormat("invalid breakpoint site ID: %llu", break_id);
+        error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64, break_id);
     }
 
     return error;
@@ -1672,11 +2052,11 @@ Process::EnableBreakpointSiteByID (lldb:
     if (bp_site_sp)
     {
         if (!bp_site_sp->IsEnabled())
-            error = EnableBreakpoint (bp_site_sp.get());
+            error = EnableBreakpointSite (bp_site_sp.get());
     }
     else
     {
-        error.SetErrorStringWithFormat("invalid breakpoint site ID: %llu", break_id);
+        error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64, break_id);
     }
     return error;
 }
@@ -1702,10 +2082,10 @@ Process::CreateBreakpointSite (const Bre
         }
         else
         {
-            bp_site_sp.reset (new BreakpointSite (&m_breakpoint_site_list, owner, load_addr, LLDB_INVALID_THREAD_ID, use_hardware));
+            bp_site_sp.reset (new BreakpointSite (&m_breakpoint_site_list, owner, load_addr, use_hardware));
             if (bp_site_sp)
             {
-                if (EnableBreakpoint (bp_site_sp.get()).Success())
+                if (EnableBreakpointSite (bp_site_sp.get()).Success())
                 {
                     owner->SetBreakpointSite (bp_site_sp);
                     return m_breakpoint_site_list.Add (bp_site_sp);
@@ -1724,7 +2104,9 @@ Process::RemoveOwnerFromBreakpointSite (
     uint32_t num_owners = bp_site_sp->RemoveOwner (owner_id, owner_loc_id);
     if (num_owners == 0)
     {
-        DisableBreakpoint(bp_site_sp.get());
+        // Don't try to disable the site if we don't have a live process anymore.
+        if (IsAlive())
+            DisableBreakpointSite (bp_site_sp.get());
         m_breakpoint_site_list.RemoveByAddress(bp_site_sp->GetLoadAddress());
     }
 }
@@ -1777,14 +2159,14 @@ Process::EnableSoftwareBreakpoint (Break
 {
     Error error;
     assert (bp_site != NULL);
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     const addr_t bp_addr = bp_site->GetLoadAddress();
     if (log)
-        log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx", bp_site->GetID(), (uint64_t)bp_addr);
+        log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64, bp_site->GetID(), (uint64_t)bp_addr);
     if (bp_site->IsEnabled())
     {
         if (log)
-            log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already enabled", bp_site->GetID(), (uint64_t)bp_addr);
+            log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- already enabled", bp_site->GetID(), (uint64_t)bp_addr);
         return error;
     }
 
@@ -1799,7 +2181,7 @@ Process::EnableSoftwareBreakpoint (Break
 
     if (bp_opcode_size == 0)
     {
-        error.SetErrorStringWithFormat ("Process::GetSoftwareBreakpointTrapOpcode() returned zero, unable to get breakpoint trap for address 0x%llx", bp_addr);
+        error.SetErrorStringWithFormat ("Process::GetSoftwareBreakpointTrapOpcode() returned zero, unable to get breakpoint trap for address 0x%" PRIx64, bp_addr);
     }
     else
     {
@@ -1825,7 +2207,7 @@ Process::EnableSoftwareBreakpoint (Break
                         bp_site->SetEnabled(true);
                         bp_site->SetType (BreakpointSite::eSoftware);
                         if (log)
-                            log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS",
+                            log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- SUCCESS",
                                          bp_site->GetID(),
                                          (uint64_t)bp_addr);
                     }
@@ -1842,7 +2224,7 @@ Process::EnableSoftwareBreakpoint (Break
             error.SetErrorString("Unable to read memory at breakpoint address.");
     }
     if (log && error.Fail())
-        log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
+        log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- FAILED: %s",
                      bp_site->GetID(),
                      (uint64_t)bp_addr,
                      error.AsCString());
@@ -1854,11 +2236,11 @@ Process::DisableSoftwareBreakpoint (Brea
 {
     Error error;
     assert (bp_site != NULL);
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     addr_t bp_addr = bp_site->GetLoadAddress();
     lldb::user_id_t breakID = bp_site->GetID();
     if (log)
-        log->Printf ("Process::DisableBreakpoint (breakID = %llu) addr = 0x%llx", breakID, (uint64_t)bp_addr);
+        log->Printf ("Process::DisableSoftwareBreakpoint (breakID = %" PRIu64 ") addr = 0x%" PRIx64, breakID, (uint64_t)bp_addr);
 
     if (bp_site->IsHardware())
     {
@@ -1912,7 +2294,7 @@ Process::DisableSoftwareBreakpoint (Brea
                             // SUCCESS
                             bp_site->SetEnabled(false);
                             if (log)
-                                log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS", bp_site->GetID(), (uint64_t)bp_addr);
+                                log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- SUCCESS", bp_site->GetID(), (uint64_t)bp_addr);
                             return error;
                         }
                         else
@@ -1932,12 +2314,12 @@ Process::DisableSoftwareBreakpoint (Brea
     else
     {
         if (log)
-            log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already disabled", bp_site->GetID(), (uint64_t)bp_addr);
+            log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- already disabled", bp_site->GetID(), (uint64_t)bp_addr);
         return error;
     }
 
     if (log)
-        log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
+        log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- FAILED: %s",
                      bp_site->GetID(),
                      (uint64_t)bp_addr,
                      error.AsCString());
@@ -1945,9 +2327,6 @@ Process::DisableSoftwareBreakpoint (Brea
 
 }
 
-// Comment out line below to disable memory caching, overriding the process setting
-// target.process.disable-memory-cache
-#define ENABLE_MEMORY_CACHING
 // Uncomment to verify memory caching works after making changes to caching code
 //#define VERIFY_MEMORY_READS
 
@@ -2018,6 +2397,60 @@ Process::ReadCStringFromMemory (addr_t a
 
 
 size_t
+Process::ReadStringFromMemory (addr_t addr, char *dst, size_t max_bytes, Error &error,
+                                size_t type_width)
+{
+    size_t total_bytes_read = 0;
+    if (dst && max_bytes && type_width && max_bytes >= type_width)
+    {
+        // Ensure a null terminator independent of the number of bytes that is read.
+        memset (dst, 0, max_bytes);
+        size_t bytes_left = max_bytes - type_width;
+
+        const char terminator[4] = {'\0', '\0', '\0', '\0'};
+        assert(sizeof(terminator) >= type_width &&
+               "Attempting to validate a string with more than 4 bytes per character!");
+
+        addr_t curr_addr = addr;
+        const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize();
+        char *curr_dst = dst;
+
+        error.Clear();
+        while (bytes_left > 0 && error.Success())
+        {
+            addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
+            addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+            size_t bytes_read = ReadMemory (curr_addr, curr_dst, bytes_to_read, error);
+
+            if (bytes_read == 0)
+                break;
+
+            // Search for a null terminator of correct size and alignment in bytes_read
+            size_t aligned_start = total_bytes_read - total_bytes_read % type_width;
+            for (size_t i = aligned_start; i + type_width <= total_bytes_read + bytes_read; i += type_width)
+                if (::strncmp(&dst[i], terminator, type_width) == 0)
+                {
+                    error.Clear();
+                    return i;
+                }
+
+            total_bytes_read += bytes_read;
+            curr_dst += bytes_read;
+            curr_addr += bytes_read;
+            bytes_left -= bytes_read;
+        }
+    }
+    else
+    {
+        if (max_bytes)
+            error.SetErrorString("invalid arguments");
+    }
+    return total_bytes_read;
+}
+
+// Deprecated in favor of ReadStringFromMemory which has wchar support and correct code to find
+// null terminators.
+size_t
 Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Error &result_error)
 {
     size_t total_cstr_len = 0;
@@ -2224,7 +2657,7 @@ Process::WriteMemory (addr_t addr, const
 }
 
 size_t
-Process::WriteScalarToMemory (addr_t addr, const Scalar &scalar, uint32_t byte_size, Error &error)
+Process::WriteScalarToMemory (addr_t addr, const Scalar &scalar, size_t byte_size, Error &error)
 {
     if (byte_size == UINT32_MAX)
         byte_size = scalar.GetByteSize();
@@ -2251,20 +2684,26 @@ Process::ReadScalarIntegerFromMemory (ad
                                       Scalar &scalar, 
                                       Error &error)
 {
-    uint64_t uval;
-
-    if (byte_size <= sizeof(uval))
+    uint64_t uval = 0;
+    if (byte_size == 0)
     {
-        size_t bytes_read = ReadMemory (addr, &uval, byte_size, error);
+        error.SetErrorString ("byte size is zero");
+    }
+    else if (byte_size & (byte_size - 1))
+    {
+        error.SetErrorStringWithFormat ("byte size %u is not a power of 2", byte_size);
+    }
+    else if (byte_size <= sizeof(uval))
+    {
+        const size_t bytes_read = ReadMemory (addr, &uval, byte_size, error);
         if (bytes_read == byte_size)
         {
             DataExtractor data (&uval, sizeof(uval), GetByteOrder(), GetAddressByteSize());
-            uint32_t offset = 0;
+            lldb::offset_t offset = 0;
             if (byte_size <= 4)
                 scalar = data.GetMaxU32 (&offset, byte_size);
             else
                 scalar = data.GetMaxU64 (&offset, byte_size);
-
             if (is_signed)
                 scalar.SignExtend(byte_size * 8);
             return bytes_read;
@@ -2288,9 +2727,9 @@ Process::AllocateMemory(size_t size, uin
     return m_allocated_memory_cache.AllocateMemory(size, permissions, error);
 #else
     addr_t allocated_addr = DoAllocateMemory (size, permissions, error);
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
     if (log)
-        log->Printf("Process::AllocateMemory(size=%4zu, permissions=%s) => 0x%16.16llx (m_stop_id = %u m_memory_id = %u)", 
+        log->Printf("Process::AllocateMemory(size=%4zu, permissions=%s) => 0x%16.16" PRIx64 " (m_stop_id = %u m_memory_id = %u)",
                     size, 
                     GetPermissionsAsCString (permissions),
                     (uint64_t)allocated_addr,
@@ -2335,14 +2774,14 @@ Process::DeallocateMemory (addr_t ptr)
 #if defined (USE_ALLOCATE_MEMORY_CACHE)
     if (!m_allocated_memory_cache.DeallocateMemory(ptr))
     {
-        error.SetErrorStringWithFormat ("deallocation of memory at 0x%llx failed.", (uint64_t)ptr);
+        error.SetErrorStringWithFormat ("deallocation of memory at 0x%" PRIx64 " failed.", (uint64_t)ptr);
     }
 #else
     error = DoDeallocateMemory (ptr);
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
     if (log)
-        log->Printf("Process::DeallocateMemory(addr=0x%16.16llx) => err = %s (m_stop_id = %u, m_memory_id = %u)", 
+        log->Printf("Process::DeallocateMemory(addr=0x%16.16" PRIx64 ") => err = %s (m_stop_id = %u, m_memory_id = %u)",
                     ptr, 
                     error.AsCString("SUCCESS"),
                     m_mod_id.GetStopID(),
@@ -2351,11 +2790,10 @@ Process::DeallocateMemory (addr_t ptr)
     return error;
 }
 
+
 ModuleSP
 Process::ReadModuleFromMemory (const FileSpec& file_spec, 
-                               lldb::addr_t header_addr, 
-                               bool add_image_to_target,
-                               bool load_sections_in_target)
+                               lldb::addr_t header_addr)
 {
     ModuleSP module_sp (new Module (file_spec, ArchSpec()));
     if (module_sp)
@@ -2363,24 +2801,13 @@ Process::ReadModuleFromMemory (const Fil
         Error error;
         ObjectFile *objfile = module_sp->GetMemoryObjectFile (shared_from_this(), header_addr, error);
         if (objfile)
-        {
-            if (add_image_to_target)
-            {
-                m_target.GetImages().Append(module_sp);
-                if (load_sections_in_target)
-                {
-                    bool changed = false;
-                    module_sp->SetLoadAddress (m_target, 0, changed);
-                }
-            }
             return module_sp;
-        }
     }
     return ModuleSP();
 }
 
 Error
-Process::EnableWatchpoint (Watchpoint *watchpoint)
+Process::EnableWatchpoint (Watchpoint *watchpoint, bool notify)
 {
     Error error;
     error.SetErrorString("watchpoints are not supported");
@@ -2388,7 +2815,7 @@ Process::EnableWatchpoint (Watchpoint *w
 }
 
 Error
-Process::DisableWatchpoint (Watchpoint *watchpoint)
+Process::DisableWatchpoint (Watchpoint *watchpoint, bool notify)
 {
     Error error;
     error.SetErrorString("watchpoints are not supported");
@@ -2443,11 +2870,20 @@ Process::Launch (const ProcessLaunchInfo
             error = WillLaunch (exe_module);
             if (error.Success())
             {
-                SetPublicState (eStateLaunching);
+                const bool restarted = false;
+                SetPublicState (eStateLaunching, restarted);
                 m_should_detach = false;
 
-                // Now launch using these arguments.
-                error = DoLaunch (exe_module, launch_info);
+                if (m_public_run_lock.WriteTryLock())
+                {
+                    // Now launch using these arguments.
+                    error = DoLaunch (exe_module, launch_info);
+                }
+                else
+                {
+                    // This shouldn't happen
+                    error.SetErrorString("failed to acquire process run lock");
+                }
 
                 if (error.Fail())
                 {
@@ -2562,11 +2998,13 @@ Process::AttachCompletionHandler::Perfor
                 // During attach, prior to sending the eStateStopped event, 
                 // lldb_private::Process subclasses must set the new process ID.
                 assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
+                // We don't want these events to be reported, so go set the ShouldReportStop here:
+                m_process->GetThreadList().SetShouldReportStop (eVoteNo);
+                
                 if (m_exec_count > 0)
                 {
                     --m_exec_count;
-                    m_process->PrivateResume ();
-                    Process::ProcessEventData::SetRestartedInEvent (event_sp.get(), true);
+                    RequestResume();
                     return eEventActionRetry;
                 }
                 else
@@ -2622,10 +3060,20 @@ Process::Attach (ProcessAttachInfo &atta
                 error = WillAttachToProcessWithName(process_name, wait_for_launch);
                 if (error.Success())
                 {
-                    m_should_detach = true;
+                    if (m_public_run_lock.WriteTryLock())
+                    {
+                        m_should_detach = true;
+                        const bool restarted = false;
+                        SetPublicState (eStateAttaching, restarted);
+                        // Now attach using these arguments.
+                        error = DoAttachToProcessWithName (process_name, wait_for_launch, attach_info);
+                    }
+                    else
+                    {
+                        // This shouldn't happen
+                        error.SetErrorString("failed to acquire process run lock");
+                    }
 
-                    SetPublicState (eStateAttaching);
-                    error = DoAttachToProcessWithName (process_name, wait_for_launch, attach_info);
                     if (error.Fail())
                     {
                         if (GetID() != LLDB_INVALID_PROCESS_ID)
@@ -2689,11 +3137,22 @@ Process::Attach (ProcessAttachInfo &atta
         error = WillAttachToProcessWithID(attach_pid);
         if (error.Success())
         {
-            m_should_detach = true;
-            SetPublicState (eStateAttaching);
 
-            error = DoAttachToProcessWithID (attach_pid, attach_info);
-            if (error.Success())
+            if (m_public_run_lock.WriteTryLock())
+            {
+                // Now attach using these arguments.
+                m_should_detach = true;
+                const bool restarted = false;
+                SetPublicState (eStateAttaching, restarted);
+                error = DoAttachToProcessWithID (attach_pid, attach_info);
+            }
+            else
+            {
+                // This shouldn't happen
+                error.SetErrorString("failed to acquire process run lock");
+            }
+
+            if (error.Success())
             {
                 
                 SetNextEventAction(new Process::AttachCompletionHandler(this, attach_info.GetResumeCount()));
@@ -2730,7 +3189,7 @@ Process::CompleteAttach ()
     if (platform_sp)
     {
         const ArchSpec &target_arch = m_target.GetArchitecture();
-        if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch))
+        if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch, false, NULL))
         {
             ArchSpec platform_arch;
             platform_sp = platform_sp->GetPlatformForArchitecture (target_arch, &platform_arch);
@@ -2745,7 +3204,7 @@ Process::CompleteAttach ()
             ProcessInstanceInfo process_info;
             platform_sp->GetProcessInfo (GetID(), process_info);
             const ArchSpec &process_arch = process_info.GetArchitecture();
-            if (process_arch.IsValid() && m_target.GetArchitecture() != process_arch)
+            if (process_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(process_arch))
                 m_target.SetArchitecture (process_arch);
         }
     }
@@ -2758,7 +3217,7 @@ Process::CompleteAttach ()
 
     m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
     // Figure out which one is the executable, and set that in our target:
-    ModuleList &target_modules = m_target.GetImages();
+    const ModuleList &target_modules = m_target.GetImages();
     Mutex::Locker modules_locker(target_modules.GetMutex());
     size_t num_modules = target_modules.GetSize();
     ModuleSP new_executable_module_sp;
@@ -2778,7 +3237,7 @@ Process::CompleteAttach ()
 }
 
 Error
-Process::ConnectRemote (const char *remote_url)
+Process::ConnectRemote (Stream *strm, const char *remote_url)
 {
     m_abi_sp.reset();
     m_process_input_reader.reset();
@@ -2786,7 +3245,7 @@ Process::ConnectRemote (const char *remo
     // Find the process and its architecture.  Make sure it matches the architecture
     // of the current Target, and if not adjust it.
     
-    Error error (DoConnectRemote (remote_url));
+    Error error (DoConnectRemote (strm, remote_url));
     if (error.Success())
     {
         if (GetID() != LLDB_INVALID_PROCESS_ID)
@@ -2819,9 +3278,9 @@ Process::ConnectRemote (const char *remo
 Error
 Process::PrivateResume ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_STEP));
     if (log)
-        log->Printf("Process::Resume() m_stop_id = %u, public state: %s private state: %s", 
+        log->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s private state: %s", 
                     m_mod_id.GetStopID(),
                     StateAsCString(m_public_state.GetValue()),
                     StateAsCString(m_private_state.GetValue()));
@@ -2837,13 +3296,13 @@ Process::PrivateResume ()
         // that they are supposed to have when the process is resumed
         // (suspended/running/stepping). Threads should also check
         // their resume signal in lldb::Thread::GetResumeSignal()
-        // to see if they are suppoed to start back up with a signal.
+        // to see if they are supposed to start back up with a signal.
         if (m_thread_list.WillResume())
         {
             // Last thing, do the PreResumeActions.
             if (!RunPreResumeActions())
             {
-                error.SetErrorStringWithFormat ("Process::Resume PreResumeActions failed, not resuming.");
+                error.SetErrorStringWithFormat ("Process::PrivateResume PreResumeActions failed, not resuming.");
             }
             else
             {
@@ -2860,17 +3319,28 @@ Process::PrivateResume ()
         }
         else
         {
-            error.SetErrorStringWithFormat("Process::WillResume() thread list returned false after WillResume");
+            // Somebody wanted to run without running.  So generate a continue & a stopped event,
+            // and let the world handle them.
+            if (log)
+                log->Printf ("Process::PrivateResume() asked to simulate a start & stop.");
+            
+            SetPrivateState(eStateRunning);
+            SetPrivateState(eStateStopped);
         }
     }
     else if (log)
-        log->Printf ("Process::WillResume() got an error \"%s\".", error.AsCString("<unknown error>"));
+        log->Printf ("Process::PrivateResume() got an error \"%s\".", error.AsCString("<unknown error>"));
     return error;
 }
 
 Error
-Process::Halt ()
+Process::Halt (bool clear_thread_plans)
 {
+    // Don't clear the m_clear_thread_plans_on_stop, only set it to true if
+    // in case it was already set and some thread plan logic calls halt on its
+    // own.
+    m_clear_thread_plans_on_stop |= clear_thread_plans;
+    
     // First make sure we aren't in the middle of handling an event, or we might restart.  This is pretty weak, since
     // we could just straightaway get another event.  It just narrows the window...
     m_currently_handling_event.WaitForValueEqualTo(false);
@@ -2931,7 +3401,7 @@ Process::Halt ()
                         }
                         else
                         {
-                            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+                            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
                             if (log)
                                 log->Printf("Process::Halt() failed to stop, state is: %s", StateAsCString(state));
                             error.SetErrorString ("Did not get stopped event after halt.");
@@ -2956,65 +3426,134 @@ Process::Halt ()
 }
 
 Error
-Process::Detach ()
+Process::HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp)
 {
-    Error error (WillDetach());
+    Error error;
+    if (m_public_state.GetValue() == eStateRunning)
+    {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+        if (log)
+            log->Printf("Process::Destroy() About to halt.");
+        error = Halt();
+        if (error.Success())
+        {
+            // Consume the halt event.
+            TimeValue timeout (TimeValue::Now());
+            timeout.OffsetWithSeconds(1);
+            StateType state = WaitForProcessToStop (&timeout, &exit_event_sp);
+            
+            // If the process exited while we were waiting for it to stop, put the exited event into
+            // the shared pointer passed in and return.  Our caller doesn't need to do anything else, since
+            // they don't have a process anymore...
+            
+            if (state == eStateExited || m_private_state.GetValue() == eStateExited)
+            {
+                if (log)
+                    log->Printf("Process::HaltForDestroyOrDetach() Process exited while waiting to Halt.");
+                return error;
+            }
+            else
+                exit_event_sp.reset(); // It is ok to consume any non-exit stop events
+    
+            if (state != eStateStopped)
+            {
+                if (log)
+                    log->Printf("Process::HaltForDestroyOrDetach() Halt failed to stop, state is: %s", StateAsCString(state));
+                // If we really couldn't stop the process then we should just error out here, but if the
+                // lower levels just bobbled sending the event and we really are stopped, then continue on.
+                StateType private_state = m_private_state.GetValue();
+                if (private_state != eStateStopped)
+                {
+                    return error;
+                }
+            }
+        }
+        else
+        {
+            if (log)
+                log->Printf("Process::HaltForDestroyOrDetach() Halt got error: %s", error.AsCString());
+        }
+    }
+    return error;
+}
+
+Error
+Process::Detach (bool keep_stopped)
+{
+    EventSP exit_event_sp;
+    Error error;
+    m_destroy_in_process = true;
+    
+    error = WillDetach();
 
     if (error.Success())
     {
-        DisableAllBreakpointSites();
-        error = DoDetach(); 
+        if (DetachRequiresHalt())
+        {
+            error = HaltForDestroyOrDetach (exit_event_sp);
+            if (!error.Success())
+            {
+                m_destroy_in_process = false;
+                return error;
+            }
+            else if (exit_event_sp)
+            {
+                // We shouldn't need to do anything else here.  There's no process left to detach from...
+                StopPrivateStateThread();
+                m_destroy_in_process = false;
+                return error;
+            }
+        }
+    
+        error = DoDetach(keep_stopped);
         if (error.Success())
         {
             DidDetach();
             StopPrivateStateThread();
         }
+        else
+        {
+            return error;
+        }
+    }
+    m_destroy_in_process = false;
+    
+    // If we exited when we were waiting for a process to stop, then
+    // forward the event here so we don't lose the event
+    if (exit_event_sp)
+    {
+        // Directly broadcast our exited event because we shut down our
+        // private state thread above
+        BroadcastEvent(exit_event_sp);
     }
+
+    // If we have been interrupted (to kill us) in the middle of running, we may not end up propagating
+    // the last events through the event system, in which case we might strand the write lock.  Unlock
+    // it here so when we do to tear down the process we don't get an error destroying the lock.
+    
+    m_public_run_lock.WriteUnlock();
     return error;
 }
 
 Error
 Process::Destroy ()
 {
+    
+    // Tell ourselves we are in the process of destroying the process, so that we don't do any unnecessary work
+    // that might hinder the destruction.  Remember to set this back to false when we are done.  That way if the attempt
+    // failed and the process stays around for some reason it won't be in a confused state.
+    
+    m_destroy_in_process = true;
+
     Error error (WillDestroy());
     if (error.Success())
     {
-        if (m_public_state.GetValue() == eStateRunning)
+        EventSP exit_event_sp;
+        if (DestroyRequiresHalt())
         {
-            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY));
-            if (log)
-                log->Printf("Process::Destroy() About to halt.");
-            error = Halt();
-            if (error.Success())
-            {
-                // Consume the halt event.
-                EventSP stop_event;
-                TimeValue timeout (TimeValue::Now());
-                timeout.OffsetWithSeconds(1);
-                StateType state = WaitForProcessToStop (&timeout);
-                if (state != eStateStopped)
-                {
-                    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY));
-                    if (log)
-                        log->Printf("Process::Destroy() Halt failed to stop, state is: %s", StateAsCString(state));
-                    // If we really couldn't stop the process then we should just error out here, but if the
-                    // lower levels just bobbled sending the event and we really are stopped, then continue on.
-                    StateType private_state = m_private_state.GetValue();
-                    if (private_state != eStateStopped && private_state != eStateExited)
-                    {
-                        return error;
-                    }
-                }
-            }
-            else
-            {
-                    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY));
-                    if (log)
-                        log->Printf("Process::Destroy() Halt got error: %s", error.AsCString());
-                    return error;
-            }
+            error = HaltForDestroyOrDetach(exit_event_sp);
         }
-
+        
         if (m_public_state.GetValue() != eStateRunning)
         {
             // Ditch all thread plans, and remove all our breakpoints: in case we have to restart the target to
@@ -3024,7 +3563,7 @@ Process::Destroy ()
             m_thread_list.DiscardThreadPlans();
             DisableAllBreakpointSites();
         }
-        
+
         error = DoDestroy();
         if (error.Success())
         {
@@ -3037,12 +3576,24 @@ Process::Destroy ()
             m_target.GetDebugger().PopInputReader (m_process_input_reader);
         if (m_process_input_reader)
             m_process_input_reader.reset();
-            
+        
+        // If we exited when we were waiting for a process to stop, then
+        // forward the event here so we don't lose the event
+        if (exit_event_sp)
+        {
+            // Directly broadcast our exited event because we shut down our
+            // private state thread above
+            BroadcastEvent(exit_event_sp);
+        }
+
         // If we have been interrupted (to kill us) in the middle of running, we may not end up propagating
         // the last events through the event system, in which case we might strand the write lock.  Unlock
         // it here so when we do to tear down the process we don't get an error destroying the lock.
-        m_run_lock.WriteUnlock();
+        m_public_run_lock.WriteUnlock();
     }
+    
+    m_destroy_in_process = false;
+    
     return error;
 }
 
@@ -3077,8 +3628,8 @@ Process::ShouldBroadcastEvent (Event *ev
 {
     const StateType state = Process::ProcessEventData::GetStateFromEvent (event_ptr);
     bool return_value = true;
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
-
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS | LIBLLDB_LOG_PROCESS));
+    
     switch (state)
     {
         case eStateConnected:
@@ -3103,7 +3654,7 @@ Process::ShouldBroadcastEvent (Event *ev
             // stopped -> running: Report except when there is one or more no votes
             //     and no yes votes.
             SynchronouslyNotifyStateChanged (state);
-            switch (m_public_state.GetValue())
+            switch (m_last_broadcast_state)
             {
                 case eStateRunning:
                 case eStateStepping:
@@ -3121,7 +3672,6 @@ Process::ShouldBroadcastEvent (Event *ev
                     // This is a transition from stop to run.
                     switch (m_thread_list.ShouldReportRun (event_ptr))
                     {
-                        default:
                         case eVoteYes:
                         case eVoteNoOpinion:
                             return_value = true;
@@ -3141,33 +3691,57 @@ Process::ShouldBroadcastEvent (Event *ev
             // If we are going to stop, then we always broadcast the event.
             // If we aren't going to stop, let the thread plans decide if we're going to report this event.
             // If no thread has an opinion, we don't report it.
-            
+
             RefreshStateAfterStop ();
             if (ProcessEventData::GetInterruptedFromEvent (event_ptr))
             {
                 if (log)
-                    log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state));
-                return true;
+                    log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s",
+                                 event_ptr,
+                                 StateAsCString(state));
+                return_value = true;
             }
             else
             {
-
-                if (m_thread_list.ShouldStop (event_ptr) == false)
+                bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr);
+                bool should_resume = false;
+                
+                // It makes no sense to ask "ShouldStop" if we've already been restarted...
+                // Asking the thread list is also not likely to go well, since we are running again.
+                // So in that case just report the event.
+                
+                if (!was_restarted)
+                    should_resume = m_thread_list.ShouldStop (event_ptr) == false;
+                
+                if (was_restarted || should_resume || m_resume_requested)
                 {
-                    switch (m_thread_list.ShouldReportStop (event_ptr))
+                    Vote stop_vote = m_thread_list.ShouldReportStop (event_ptr);
+                    if (log)
+                        log->Printf ("Process::ShouldBroadcastEvent: should_stop: %i state: %s was_restarted: %i stop_vote: %d.",
+                                     should_resume,
+                                     StateAsCString(state),
+                                     was_restarted,
+                                     stop_vote);
+                    
+                    switch (stop_vote)
                     {
                         case eVoteYes:
-                            Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
-                            // Intentional fall-through here.
+                            return_value = true;
+                            break;
                         case eVoteNoOpinion:
                         case eVoteNo:
                             return_value = false;
                             break;
                     }
-
-                    if (log)
-                        log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process from state: %s", event_ptr, StateAsCString(state));
-                    PrivateResume ();
+                    
+                    if (!was_restarted)
+                    {
+                        if (log)
+                            log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process from state: %s", event_ptr, StateAsCString(state));
+                        ProcessEventData::SetRestartedInEvent(event_ptr, true);
+                        PrivateResume ();
+                    }
+                    
                 }
                 else
                 {
@@ -3176,10 +3750,25 @@ Process::ShouldBroadcastEvent (Event *ev
                 }
             }
         }
+        break;
     }
-
+    
+    // We do some coalescing of events (for instance two consecutive running events get coalesced.)
+    // But we only coalesce against events we actually broadcast.  So we use m_last_broadcast_state
+    // to track that.  NB - you can't use "m_public_state.GetValue()" for that purpose, as was originally done,
+    // because the PublicState reflects the last event pulled off the queue, and there may be several
+    // events stacked up on the queue unserviced.  So the PublicState may not reflect the last broadcasted event
+    // yet.  m_last_broadcast_state gets updated here.
+    
+    if (return_value)
+        m_last_broadcast_state = state;
+    
     if (log)
-        log->Printf ("Process::ShouldBroadcastEvent (%p) => %s - %s", event_ptr, StateAsCString(state), return_value ? "YES" : "NO");
+        log->Printf ("Process::ShouldBroadcastEvent (%p) => new state: %s, last broadcast state: %s - %s",
+                     event_ptr,
+                     StateAsCString(state),
+                     StateAsCString(m_last_broadcast_state),
+                     return_value ? "YES" : "NO");
     return return_value;
 }
 
@@ -3187,7 +3776,7 @@ Process::ShouldBroadcastEvent (Event *ev
 bool
 Process::StartPrivateStateThread (bool force)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
 
     bool already_running = PrivateStateThreadIsValid ();
     if (log)
@@ -3200,9 +3789,9 @@ Process::StartPrivateStateThread (bool f
     // events make it to clients (into the DCProcess event queue).
     char thread_name[1024];
     if (already_running)
-        snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state-override(pid=%llu)>", GetID());
+        snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state-override(pid=%" PRIu64 ")>", GetID());
     else
-        snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%llu)>", GetID());
+        snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%" PRIu64 ")>", GetID());
         
     // Create the private state thread, and start it running.
     m_private_state_thread = Host::ThreadCreate (thread_name, Process::PrivateStateThread, this, NULL);
@@ -3235,16 +3824,16 @@ Process::StopPrivateStateThread ()
         ControlPrivateStateThread (eBroadcastInternalStateControlStop);
     else
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
         if (log)
-            printf ("Went to stop the private state thread, but it was already invalid.");
+            log->Printf ("Went to stop the private state thread, but it was already invalid.");
     }
 }
 
 void
 Process::ControlPrivateStateThread (uint32_t signal)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
 
     assert (signal == eBroadcastInternalStateControlStop ||
             signal == eBroadcastInternalStateControlPause ||
@@ -3310,7 +3899,9 @@ Process::SendAsyncInterrupt ()
 void
 Process::HandlePrivateEvent (EventSP &event_sp)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    m_resume_requested = false;
+    
     m_currently_handling_event.SetValue(true, eBroadcastNever);
     
     const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
@@ -3319,6 +3910,9 @@ Process::HandlePrivateEvent (EventSP &ev
     if (m_next_event_action_ap.get() != NULL)
     {
         NextEventAction::EventActionResult action_result = m_next_event_action_ap->PerformAction(event_sp);
+        if (log)
+            log->Printf ("Ran next event action, result was %d.", action_result);
+        
         switch (action_result)
         {
             case NextEventAction::eEventActionSuccess:
@@ -3336,6 +3930,7 @@ Process::HandlePrivateEvent (EventSP &ev
                 {
                     // FIXME: should cons up an exited event, and discard this one.
                     SetExitStatus(0, m_next_event_action_ap->GetExitString());
+                    m_currently_handling_event.SetValue(false, eBroadcastAlways);
                     SetNextEventAction(NULL);
                     return;
                 }
@@ -3351,7 +3946,7 @@ Process::HandlePrivateEvent (EventSP &ev
     {
         if (log)
         {
-            log->Printf ("Process::%s (pid = %llu) broadcasting new state %s (old state %s) to %s", 
+            log->Printf ("Process::%s (pid = %" PRIu64 ") broadcasting new state %s (old state %s) to %s",
                          __FUNCTION__, 
                          GetID(), 
                          StateAsCString(new_state), 
@@ -3361,7 +3956,7 @@ Process::HandlePrivateEvent (EventSP &ev
         Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
         if (StateIsRunningState (new_state))
             PushProcessInputReader ();
-        else 
+        else if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
             PopProcessInputReader ();
 
         BroadcastEvent (event_sp);
@@ -3370,7 +3965,7 @@ Process::HandlePrivateEvent (EventSP &ev
     {
         if (log)
         {
-            log->Printf ("Process::%s (pid = %llu) suppressing state %s (old state %s): should_broadcast == false", 
+            log->Printf ("Process::%s (pid = %" PRIu64 ") suppressing state %s (old state %s): should_broadcast == false",
                          __FUNCTION__, 
                          GetID(), 
                          StateAsCString(new_state), 
@@ -3394,9 +3989,9 @@ Process::RunPrivateStateThread ()
     bool control_only = true;
     m_private_state_control_wait.SetValue (false, eBroadcastNever);
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
     if (log)
-        log->Printf ("Process::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, this, GetID());
+        log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, this, GetID());
 
     bool exit_now = false;
     while (!exit_now)
@@ -3406,7 +4001,7 @@ Process::RunPrivateStateThread ()
         if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster))
         {
             if (log)
-                log->Printf ("Process::%s (arg = %p, pid = %llu) got a control event: %d", __FUNCTION__, this, GetID(), event_sp->GetType());
+                log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") got a control event: %d", __FUNCTION__, this, GetID(), event_sp->GetType());
 
             switch (event_sp->GetType())
             {
@@ -3431,13 +4026,13 @@ Process::RunPrivateStateThread ()
             if (m_public_state.GetValue() == eStateAttaching)
             {
                 if (log)
-                    log->Printf ("Process::%s (arg = %p, pid = %llu) woke up with an interrupt while attaching - forwarding interrupt.", __FUNCTION__, this, GetID());
+                    log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt while attaching - forwarding interrupt.", __FUNCTION__, this, GetID());
                 BroadcastEvent (eBroadcastBitInterrupt, NULL);
             }
             else
             {
                 if (log)
-                    log->Printf ("Process::%s (arg = %p, pid = %llu) woke up with an interrupt - Halting.", __FUNCTION__, this, GetID());
+                    log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt - Halting.", __FUNCTION__, this, GetID());
                 Halt();
             }
             continue;
@@ -3447,6 +4042,12 @@ Process::RunPrivateStateThread ()
 
         if (internal_state != eStateInvalid)
         {
+            if (m_clear_thread_plans_on_stop &&
+                StateIsStoppedState(internal_state, true))
+            {
+                m_clear_thread_plans_on_stop = false;
+                m_thread_list.DiscardThreadPlans();
+            }
             HandlePrivateEvent (event_sp);
         }
 
@@ -3455,7 +4056,7 @@ Process::RunPrivateStateThread ()
             internal_state == eStateDetached )
         {
             if (log)
-                log->Printf ("Process::%s (arg = %p, pid = %llu) about to exit with internal state %s...", __FUNCTION__, this, GetID(), StateAsCString(internal_state));
+                log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") about to exit with internal state %s...", __FUNCTION__, this, GetID(), StateAsCString(internal_state));
 
             break;
         }
@@ -3463,8 +4064,9 @@ Process::RunPrivateStateThread ()
 
     // Verify log is still enabled before attempting to write to it...
     if (log)
-        log->Printf ("Process::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, this, GetID());
+        log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, this, GetID());
 
+    m_public_run_lock.WriteUnlock();
     m_private_state_control_wait.SetValue (true, eBroadcastAlways);
     m_private_state_thread = LLDB_INVALID_HOST_THREAD;
     return NULL;
@@ -3519,12 +4121,11 @@ Process::ProcessEventData::DoOnRemoval (
     // the public event queue, then other times when we're pretending that this is where we stopped at the
     // end of expression evaluation.  m_update_state is used to distinguish these
     // three cases; it is 0 when we're just pulling it off for private handling, 
-    // and > 1 for expression evaluation, and we don't want to do the breakpoint command handling then.
-    
+    // and > 1 for expression evaluation, and we don't want to do the breakpoint command handling then.    
     if (m_update_state != 1)
         return;
-        
-    m_process_sp->SetPublicState (m_state);
+    
+    m_process_sp->SetPublicState (m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
         
     // If we're stopped and haven't restarted, then do the breakpoint commands here:
     if (m_state == eStateStopped && ! m_restarted)
@@ -3545,14 +4146,24 @@ Process::ProcessEventData::DoOnRemoval (
         for (idx = 0; idx < num_threads; ++idx)
             thread_index_array[idx] = curr_thread_list.GetThreadAtIndex(idx)->GetIndexID();
         
-        bool still_should_stop = true;
+        // Use this to track whether we should continue from here.  We will only continue the target running if
+        // no thread says we should stop.  Of course if some thread's PerformAction actually sets the target running,
+        // then it doesn't matter what the other threads say...
+        
+        bool still_should_stop = false;
+        
+        // Sometimes - for instance if we have a bug in the stub we are talking to, we stop but no thread has a
+        // valid stop reason.  In that case we should just stop, because we have no way of telling what the right
+        // thing to do is, and it's better to let the user decide than continue behind their backs.
+        
+        bool does_anybody_have_an_opinion = false;
         
         for (idx = 0; idx < num_threads; ++idx)
         {
             curr_thread_list = m_process_sp->GetThreadList();
             if (curr_thread_list.GetSize() != num_threads)
             {
-                lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
+                Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
                 if (log)
                     log->Printf("Number of threads changed from %u to %u while processing event.", num_threads, curr_thread_list.GetSize());
                 break;
@@ -3562,7 +4173,7 @@ Process::ProcessEventData::DoOnRemoval (
             
             if (thread_sp->GetIndexID() != thread_index_array[idx])
             {
-                lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
+                Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
                 if (log)
                     log->Printf("The thread at position %u changed from %u to %u while processing event.", 
                                 idx, 
@@ -3572,37 +4183,47 @@ Process::ProcessEventData::DoOnRemoval (
             }
             
             StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
-            if (stop_info_sp)
+            if (stop_info_sp && stop_info_sp->IsValid())
             {
-                stop_info_sp->PerformAction(event_ptr);
-                // The stop action might restart the target.  If it does, then we want to mark that in the
-                // event so that whoever is receiving it will know to wait for the running event and reflect
-                // that state appropriately.
-                // We also need to stop processing actions, since they aren't expecting the target to be running.
-                
-                // FIXME: we might have run.
-                if (stop_info_sp->HasTargetRunSinceMe())
+                does_anybody_have_an_opinion = true;
+                bool this_thread_wants_to_stop;
+                if (stop_info_sp->GetOverrideShouldStop())
                 {
-                    SetRestarted (true);
-                    break;
+                    this_thread_wants_to_stop = stop_info_sp->GetOverriddenShouldStopValue();
                 }
-                else if (!stop_info_sp->ShouldStop(event_ptr))
+                else
                 {
-                    still_should_stop = false;
+                    stop_info_sp->PerformAction(event_ptr);
+                    // The stop action might restart the target.  If it does, then we want to mark that in the
+                    // event so that whoever is receiving it will know to wait for the running event and reflect
+                    // that state appropriately.
+                    // We also need to stop processing actions, since they aren't expecting the target to be running.
+                    
+                    // FIXME: we might have run.
+                    if (stop_info_sp->HasTargetRunSinceMe())
+                    {
+                        SetRestarted (true);
+                        break;
+                    }
+                    
+                    this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
                 }
+                
+                if (still_should_stop == false)
+                    still_should_stop = this_thread_wants_to_stop;
             }
         }
 
         
-        if (m_process_sp->GetPrivateState() != eStateRunning)
+        if (!GetRestarted())
         {
-            if (!still_should_stop)
+            if (!still_should_stop && does_anybody_have_an_opinion)
             {
                 // We've been asked to continue, so do that here.
                 SetRestarted(true);
                 // Use the public resume method here, since this is just
                 // extending a public resume.
-                m_process_sp->Resume();
+                m_process_sp->PrivateResume();
             }
             else
             {
@@ -3613,7 +4234,6 @@ Process::ProcessEventData::DoOnRemoval (
                     SetRestarted(true);
             }
         }
-        
     }
 }
 
@@ -3621,7 +4241,7 @@ void
 Process::ProcessEventData::Dump (Stream *s) const
 {
     if (m_process_sp)
-        s->Printf(" process = %p (pid = %llu), ", m_process_sp.get(), m_process_sp->GetID());
+        s->Printf(" process = %p (pid = %" PRIu64 "), ", m_process_sp.get(), m_process_sp->GetID());
 
     s->Printf("state = %s", StateAsCString(GetState()));
 }
@@ -3676,6 +4296,34 @@ Process::ProcessEventData::SetRestartedI
         data->SetRestarted(new_value);
 }
 
+size_t
+Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        return data->GetNumRestartedReasons();
+    else
+        return 0;
+}
+
+const char *
+Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        return data->GetRestartedReasonAtIndex(idx);
+    else
+        return NULL;
+}
+
+void
+Process::ProcessEventData::AddRestartedReason (Event *event_ptr, const char *reason)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        data->AddRestartedReason(reason);
+}
+
 bool
 Process::ProcessEventData::GetInterruptedFromEvent (const Event *event_ptr)
 {
@@ -3744,7 +4392,7 @@ Process::AppendSTDOUT (const char * s, s
 {
     Mutex::Locker locker (m_stdio_communication_mutex);
     m_stdout_data.append (s, len);
-    BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (GetTarget().GetProcessSP(), GetState()));
+    BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (shared_from_this(), GetState()));
 }
 
 void
@@ -3752,9 +4400,46 @@ Process::AppendSTDERR (const char * s, s
 {
     Mutex::Locker locker (m_stdio_communication_mutex);
     m_stderr_data.append (s, len);
-    BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (GetTarget().GetProcessSP(), GetState()));
+    BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState()));
 }
 
+void
+Process::BroadcastAsyncProfileData(const char *s, size_t len)
+{
+    Mutex::Locker locker (m_profile_data_comm_mutex);
+    m_profile_data.push_back(s);
+    BroadcastEventIfUnique (eBroadcastBitProfileData, new ProcessEventData (shared_from_this(), GetState()));
+}
+
+size_t
+Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
+{
+    Mutex::Locker locker(m_profile_data_comm_mutex);
+    if (m_profile_data.empty())
+        return 0;
+
+    size_t bytes_available = m_profile_data.front().size();
+    if (bytes_available > 0)
+    {
+        Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+        if (log)
+            log->Printf ("Process::GetProfileData (buf = %p, size = %" PRIu64 ")", buf, (uint64_t)buf_size);
+        if (bytes_available > buf_size)
+        {
+            memcpy(buf, m_profile_data.front().data(), buf_size);
+            m_profile_data.front().erase(0, buf_size);
+            bytes_available = buf_size;
+        }
+        else
+        {
+            memcpy(buf, m_profile_data.front().data(), bytes_available);
+            m_profile_data.erase(m_profile_data.begin());
+        }
+    }
+    return bytes_available;
+}
+
+
 //------------------------------------------------------------------
 // Process STDIO
 //------------------------------------------------------------------
@@ -3766,9 +4451,9 @@ Process::GetSTDOUT (char *buf, size_t bu
     size_t bytes_available = m_stdout_data.size();
     if (bytes_available > 0)
     {
-        LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+        Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
         if (log)
-            log->Printf ("Process::GetSTDOUT (buf = %p, size = %zu)", buf, buf_size);
+            log->Printf ("Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")", buf, (uint64_t)buf_size);
         if (bytes_available > buf_size)
         {
             memcpy(buf, m_stdout_data.c_str(), buf_size);
@@ -3792,9 +4477,9 @@ Process::GetSTDERR (char *buf, size_t bu
     size_t bytes_available = m_stderr_data.size();
     if (bytes_available > 0)
     {
-        LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+        Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
         if (log)
-            log->Printf ("Process::GetSTDERR (buf = %p, size = %zu)", buf, buf_size);
+            log->Printf ("Process::GetSTDERR (buf = %p, size = %" PRIu64 ")", buf, (uint64_t)buf_size);
         if (bytes_available > buf_size)
         {
             memcpy(buf, m_stderr_data.c_str(), buf_size);
@@ -3874,7 +4559,7 @@ Process::SetSTDIOFileDescriptor (int fil
 {
     // First set up the Read Thread for reading/handling process I/O
     
-    std::auto_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (file_descriptor, true));
+    std::unique_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (file_descriptor, true));
     
     if (conn_ap.get())
     {
@@ -3921,96 +4606,53 @@ Process::PopProcessInputReader ()
 void
 Process::SettingsInitialize ()
 {
-    static std::vector<OptionEnumValueElement> g_plugins;
-    
-    int i=0; 
-    const char *name;
-    OptionEnumValueElement option_enum;
-    while ((name = PluginManager::GetProcessPluginNameAtIndex (i)) != NULL)
-    {
-        if (name)
-        {
-            option_enum.value = i;
-            option_enum.string_value = name;
-            option_enum.usage = PluginManager::GetProcessPluginDescriptionAtIndex (i);
-            g_plugins.push_back (option_enum);
-        }
-        ++i;
-    }
-    option_enum.value = 0;
-    option_enum.string_value = NULL;
-    option_enum.usage = NULL;
-    g_plugins.push_back (option_enum);
-    
-    for (i=0; (name = SettingsController::instance_settings_table[i].var_name); ++i)
-    {
-        if (::strcmp (name, "plugin") == 0)
-        {
-            SettingsController::instance_settings_table[i].enum_values = &g_plugins[0];
-            break;
-        }
-    }
-    UserSettingsControllerSP &usc = GetSettingsController();
-    UserSettingsController::InitializeSettingsController (usc,
-                                                          SettingsController::global_settings_table,
-                                                          SettingsController::instance_settings_table);
-                                                          
-    // Now call SettingsInitialize() for each 'child' of Process settings
+//    static std::vector<OptionEnumValueElement> g_plugins;
+//    
+//    int i=0; 
+//    const char *name;
+//    OptionEnumValueElement option_enum;
+//    while ((name = PluginManager::GetProcessPluginNameAtIndex (i)) != NULL)
+//    {
+//        if (name)
+//        {
+//            option_enum.value = i;
+//            option_enum.string_value = name;
+//            option_enum.usage = PluginManager::GetProcessPluginDescriptionAtIndex (i);
+//            g_plugins.push_back (option_enum);
+//        }
+//        ++i;
+//    }
+//    option_enum.value = 0;
+//    option_enum.string_value = NULL;
+//    option_enum.usage = NULL;
+//    g_plugins.push_back (option_enum);
+//    
+//    for (i=0; (name = SettingsController::instance_settings_table[i].var_name); ++i)
+//    {
+//        if (::strcmp (name, "plugin") == 0)
+//        {
+//            SettingsController::instance_settings_table[i].enum_values = &g_plugins[0];
+//            break;
+//        }
+//    }
+//                                                          
     Thread::SettingsInitialize ();
 }
 
 void
 Process::SettingsTerminate ()
 {
-    // Must call SettingsTerminate() on each 'child' of Process settings before terminating Process settings.
-    
     Thread::SettingsTerminate ();
-    
-    // Now terminate Process Settings.
-    
-    UserSettingsControllerSP &usc = GetSettingsController();
-    UserSettingsController::FinalizeSettingsController (usc);
-    usc.reset();
-}
-
-UserSettingsControllerSP &
-Process::GetSettingsController ()
-{
-    static UserSettingsControllerSP g_settings_controller_sp;
-    if (!g_settings_controller_sp)
-    {
-        g_settings_controller_sp.reset (new Process::SettingsController);
-        // The first shared pointer to Process::SettingsController in
-        // g_settings_controller_sp must be fully created above so that 
-        // the TargetInstanceSettings can use a weak_ptr to refer back 
-        // to the master setttings controller
-        InstanceSettingsSP default_instance_settings_sp (new ProcessInstanceSettings (g_settings_controller_sp, 
-                                                                                      false,
-                                                                                      InstanceSettings::GetDefaultName().AsCString()));
-        g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp);
-    }
-    return g_settings_controller_sp;
-
-}
-
-void
-Process::UpdateInstanceName ()
-{
-    Module *module = GetTarget().GetExecutableModulePointer();
-    if (module && module->GetFileSpec().GetFilename())
-    {
-        GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(),
-                                                         module->GetFileSpec().GetFilename().AsCString());
-    }
 }
 
 ExecutionResults
 Process::RunThreadPlan (ExecutionContext &exe_ctx,
                         lldb::ThreadPlanSP &thread_plan_sp,
                         bool stop_others,
-                        bool try_all_threads,
-                        bool discard_on_error,
-                        uint32_t single_thread_timeout_usec,
+                        bool run_others,
+                        bool unwind_on_error,
+                        bool ignore_breakpoints,
+                        uint32_t timeout_usec,
                         Stream &errors)
 {
     ExecutionResults return_value = eExecutionSetupError;
@@ -4020,7 +4662,13 @@ Process::RunThreadPlan (ExecutionContext
         errors.Printf("RunThreadPlan called with empty thread plan.");
         return eExecutionSetupError;
     }
-
+    
+    if (!thread_plan_sp->ValidatePlan(NULL))
+    {
+        errors.Printf ("RunThreadPlan called with an invalid thread plan.");
+        return eExecutionSetupError;
+    }
+    
     if (exe_ctx.GetProcessPtr() != this)
     {
         errors.Printf("RunThreadPlan called on wrong process.");
@@ -4049,7 +4697,19 @@ Process::RunThreadPlan (ExecutionContext
     
     // Save the thread & frame from the exe_ctx for restoration after we run
     const uint32_t thread_idx_id = thread->GetIndexID();
-    StackID ctx_frame_id = thread->GetSelectedFrame()->GetStackID();
+    StackFrameSP selected_frame_sp = thread->GetSelectedFrame();
+    if (!selected_frame_sp)
+    {
+        thread->SetSelectedFrame(0);
+        selected_frame_sp = thread->GetSelectedFrame();
+        if (!selected_frame_sp)
+        {
+            errors.Printf("RunThreadPlan called without a selected frame on thread %d", thread_idx_id);
+            return eExecutionSetupError;
+        }
+    }
+    
+    StackID ctx_frame_id = selected_frame_sp->GetStackID();
 
     // N.B. Running the target may unset the currently selected thread and frame.  We don't want to do that either, 
     // so we should arrange to reset them as well.
@@ -4072,7 +4732,7 @@ Process::RunThreadPlan (ExecutionContext
     lldb::StateType old_state;
     lldb::ThreadPlanSP stopper_base_plan_sp;
     
-    lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
     if (Host::GetCurrentThread() == m_private_state_thread)
     {
         // Yikes, we are running on the private state thread!  So we can't wait for public events on this thread, since
@@ -4080,7 +4740,7 @@ Process::RunThreadPlan (ExecutionContext
         // The simplest thing to do is to spin up a temporary thread to handle private state thread events while
         // we are fielding public events here.
         if (log)
-			log->Printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.");
+            log->Printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.");
             
 
         backup_private_state_thread = m_private_state_thread;
@@ -4120,7 +4780,7 @@ Process::RunThreadPlan (ExecutionContext
         {
             StreamString s;
             thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
-            log->Printf ("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4llx to run thread plan \"%s\".",  
+            log->Printf ("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64 " to run thread plan \"%s\".",
                          thread->GetIndexID(), 
                          thread->GetID(), 
                          s.GetData());
@@ -4133,49 +4793,113 @@ Process::RunThreadPlan (ExecutionContext
         TimeValue* timeout_ptr = NULL;
         TimeValue real_timeout;
         
-        bool first_timeout = true;
+        bool before_first_timeout = true;  // This is set to false the first time that we have to halt the target.
         bool do_resume = true;
+        bool handle_running_event = true;
+        const uint64_t default_one_thread_timeout_usec = 250000;
+        
+        // This is just for accounting:
+        uint32_t num_resumes = 0;
+        
+        TimeValue one_thread_timeout = TimeValue::Now();
+        TimeValue final_timeout = one_thread_timeout;
+        
+        if (run_others)
+        {
+            // If we are running all threads then we take half the time to run all threads, bounded by
+            // .25 sec.
+            if (timeout_usec == 0)
+                one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec);
+            else
+            {
+                uint64_t computed_timeout = timeout_usec / 2;
+                if (computed_timeout > default_one_thread_timeout_usec)
+                    computed_timeout = default_one_thread_timeout_usec;
+                one_thread_timeout.OffsetWithMicroSeconds(computed_timeout);
+            }
+            final_timeout.OffsetWithMicroSeconds (timeout_usec);
+        }
+        else
+        {
+            if (timeout_usec != 0)
+                final_timeout.OffsetWithMicroSeconds(timeout_usec);
+        }
+
+        // This while loop must exit out the bottom, there's cleanup that we need to do when we are done.
+        // So don't call return anywhere within it.
         
         while (1)
         {
             // We usually want to resume the process if we get to the top of the loop.
             // The only exception is if we get two running events with no intervening
             // stop, which can happen, we will just wait for then next stop event.
+            if (log)
+                log->Printf ("Top of while loop: do_resume: %i handle_running_event: %i before_first_timeout: %i.",
+                             do_resume,
+                             handle_running_event,
+                             before_first_timeout);
             
-            if (do_resume)
+            if (do_resume || handle_running_event)
             {
                 // Do the initial resume and wait for the running event before going further.
         
-                Error resume_error = PrivateResume ();
-                if (!resume_error.Success())
+                if (do_resume)
                 {
-                    errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
-                    return_value = eExecutionSetupError;
-                    break;
+                    num_resumes++;
+                    Error resume_error = PrivateResume ();
+                    if (!resume_error.Success())
+                    {
+                        errors.Printf("Error resuming inferior the %d time: \"%s\".\n",
+                                      num_resumes,
+                                      resume_error.AsCString());
+                        return_value = eExecutionSetupError;
+                        break;
+                    }
                 }
-        
-                real_timeout = TimeValue::Now();
-                real_timeout.OffsetWithMicroSeconds(500000);
-                timeout_ptr = &real_timeout;
                 
-                got_event = listener.WaitForEvent(timeout_ptr, event_sp);
+                TimeValue resume_timeout = TimeValue::Now();
+                resume_timeout.OffsetWithMicroSeconds(500000);
+                
+                got_event = listener.WaitForEvent(&resume_timeout, event_sp);
                 if (!got_event)
                 {
                     if (log)
-                        log->PutCString("Process::RunThreadPlan(): didn't get any event after initial resume, exiting.");
+                        log->Printf ("Process::RunThreadPlan(): didn't get any event after resume %d, exiting.",
+                                        num_resumes);
 
-                    errors.Printf("Didn't get any event after initial resume, exiting.");
+                    errors.Printf("Didn't get any event after resume %d, exiting.", num_resumes);
                     return_value = eExecutionSetupError;
                     break;
                 }
                 
                 stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
                 if (stop_state != eStateRunning)
                 {
-                    if (log)
-                        log->Printf("Process::RunThreadPlan(): didn't get running event after initial resume, got %s instead.", StateAsCString(stop_state));
-
-                    errors.Printf("Didn't get running event after initial resume, got %s instead.", StateAsCString(stop_state));
+                    bool restarted = false;
+                    
+                    if (stop_state == eStateStopped)
+                    {
+                        restarted = Process::ProcessEventData::GetRestartedFromEvent(event_sp.get());
+                        if (log)
+                            log->Printf("Process::RunThreadPlan(): didn't get running event after "
+                                        "resume %d, got %s instead (restarted: %i, do_resume: %i, handle_running_event: %i).",
+                                        num_resumes,
+                                        StateAsCString(stop_state),
+                                        restarted,
+                                        do_resume,
+                                        handle_running_event);
+                    }
+                    
+                    if (restarted)
+                    {
+                        // This is probably an overabundance of caution, I don't think I should ever get a stopped & restarted
+                        // event here.  But if I do, the best thing is to Halt and then get out of here.
+                        Halt();
+                    }
+                    
+                    errors.Printf("Didn't get running event after initial resume, got %s instead.",
+                                  StateAsCString(stop_state));
                     return_value = eExecutionSetupError;
                     break;
                 }
@@ -4187,37 +4911,35 @@ Process::RunThreadPlan (ExecutionContext
                 // won't be able to gather the result at this point.
                 // We set the timeout AFTER the resume, since the resume takes some time and we
                 // don't want to charge that to the timeout.
-                
-                if (single_thread_timeout_usec != 0)
-                {
-                    // we have a > 0 timeout, let us set it so that we stop after the deadline
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
+            }
+            else
+            {
+                if (log)
+                    log->PutCString ("Process::RunThreadPlan(): waiting for next event.");
+            }
                         
-                    timeout_ptr = &real_timeout;
-                }
-                else if (first_timeout)
-                {
-                    // if we are willing to wait "forever" we still need to have an initial timeout
-                    // this timeout is going to induce all threads to run when hit. we do this so that
-                    // we can avoid ending locked up because of multithreaded contention issues
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithNanoSeconds(500000000UL);
-                    timeout_ptr = &real_timeout;
-                }
+            if (before_first_timeout)
+            {
+                if (run_others)
+                    timeout_ptr = &one_thread_timeout;
                 else
                 {
-                    timeout_ptr = NULL; // if we are in a no-timeout scenario, then we only need a fake timeout the first time through
-                    // at this point in the code, all threads will be running so we are willing to wait forever, and do not
-                    // need a timeout
+                    if (timeout_usec == 0)
+                        timeout_ptr = NULL;
+                    else
+                        timeout_ptr = &final_timeout;
                 }
             }
             else
             {
-                if (log)
-                    log->PutCString ("Process::RunThreadPlan(): handled an extra running event.");
-                do_resume = true;
+                if (timeout_usec == 0)
+                    timeout_ptr = NULL;
+                else
+                    timeout_ptr = &final_timeout;
             }
+        
+            do_resume = true;
+            handle_running_event = true;
             
             // Now wait for the process to stop again:
             event_sp.reset();
@@ -4226,12 +4948,9 @@ Process::RunThreadPlan (ExecutionContext
             {
                 if (timeout_ptr)
                 {
-                    StreamString s;
-                    s.Printf ("about to wait - timeout is:\n   ");
-                    timeout_ptr->Dump (&s, 120);
-                    s.Printf ("\nNow is:\n    ");
-                    TimeValue::Now().Dump (&s, 120);
-                    log->Printf ("Process::RunThreadPlan(): %s", s.GetData());
+                    log->Printf ("Process::RunThreadPlan(): about to wait - now is %" PRIu64 " - endpoint is %" PRIu64,
+                                 TimeValue::Now().GetAsMicroSecondsSinceJan1_1970(),
+                                 timeout_ptr->GetAsMicroSecondsSinceJan1_1970());
                 }
                 else
                 {
@@ -4249,11 +4968,11 @@ Process::RunThreadPlan (ExecutionContext
                     if (event_sp->GetType() == eBroadcastBitInterrupt)
                     {
                         Halt();
-                        keep_going = false;
                         return_value = eExecutionInterrupted;
                         errors.Printf ("Execution halted by user interrupt.");
                         if (log)
                             log->Printf ("Process::RunThreadPlan(): Got  interrupted by eBroadcastBitInterrupted, exiting.");
+                        break;
                     }
                     else
                     {
@@ -4265,7 +4984,7 @@ Process::RunThreadPlan (ExecutionContext
                         {
                         case lldb::eStateStopped:
                             {
-                                // Yay, we're done.  Now make sure that our thread plan actually completed.
+                                // We stopped, figure out what we are going to do now.
                                 ThreadSP thread_sp = GetThreadList().FindThreadByIndexID (thread_idx_id);
                                 if (!thread_sp)
                                 {
@@ -4276,40 +4995,66 @@ Process::RunThreadPlan (ExecutionContext
                                 }
                                 else
                                 {
-                                    StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
-                                    StopReason stop_reason = eStopReasonInvalid;
-                                    if (stop_info_sp)
-                                         stop_reason = stop_info_sp->GetStopReason();
-                                    if (stop_reason == eStopReasonPlanComplete)
+                                    // If we were restarted, we just need to go back up to fetch another event.
+                                    if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
                                     {
                                         if (log)
-                                            log->PutCString ("Process::RunThreadPlan(): execution completed successfully.");
-                                        // Now mark this plan as private so it doesn't get reported as the stop reason
-                                        // after this point.  
-                                        if (thread_plan_sp)
-                                            thread_plan_sp->SetPrivate (orig_plan_private);
-                                        return_value = eExecutionCompleted;
+                                        {
+                                            log->Printf ("Process::RunThreadPlan(): Got a stop and restart, so we'll continue waiting.");
+                                        }
+                                       keep_going = true;
+                                       do_resume = false;
+                                       handle_running_event = true;
+                                       
                                     }
                                     else
                                     {
-                                        if (log)
-                                            log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
-
-                                        return_value = eExecutionInterrupted;
+                                    
+                                        StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
+                                        StopReason stop_reason = eStopReasonInvalid;
+                                        if (stop_info_sp)
+                                             stop_reason = stop_info_sp->GetStopReason();
+                                        
+                                        
+                                        // FIXME: We only check if the stop reason is plan complete, should we make sure that
+                                        // it is OUR plan that is complete?
+                                        if (stop_reason == eStopReasonPlanComplete)
+                                        {
+                                            if (log)
+                                                log->PutCString ("Process::RunThreadPlan(): execution completed successfully.");
+                                            // Now mark this plan as private so it doesn't get reported as the stop reason
+                                            // after this point.  
+                                            if (thread_plan_sp)
+                                                thread_plan_sp->SetPrivate (orig_plan_private);
+                                            return_value = eExecutionCompleted;
+                                        }
+                                        else
+                                        {
+                                            // Something restarted the target, so just wait for it to stop for real.
+                                            if (stop_reason == eStopReasonBreakpoint)
+                                            {
+                                                if (log)
+                                                    log->Printf ("Process::RunThreadPlan() stopped for breakpoint: %s.", stop_info_sp->GetDescription());
+                                                return_value = eExecutionHitBreakpoint;
+                                            }
+                                            else
+                                            {
+                                                if (log)
+                                                    log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
+                                                return_value = eExecutionInterrupted;
+                                            }
+                                        }
                                     }
                                 }
                             }        
                             break;
 
-                        case lldb::eStateCrashed:
-                            if (log)
-                                log->PutCString ("Process::RunThreadPlan(): execution crashed.");
-                            return_value = eExecutionInterrupted;
-                            break;
-
                         case lldb::eStateRunning:
+                            // This shouldn't really happen, but sometimes we do get two running events without an
+                            // intervening stop, and in that case we should just go back to waiting for the stop.
                             do_resume = false;
                             keep_going = true;
+                            handle_running_event = false;
                             break;
 
                         default:
@@ -4343,170 +5088,143 @@ Process::RunThreadPlan (ExecutionContext
                 // If we didn't get an event that means we've timed out...
                 // We will interrupt the process here.  Depending on what we were asked to do we will
                 // either exit, or try with all threads running for the same timeout.
-                // Not really sure what to do if Halt fails here...
                 
                 if (log) {
-                    if (try_all_threads)
+                    if (run_others)
                     {
-                        if (first_timeout)
-                            log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, "
-                                         "trying with all threads enabled.",
-                                         single_thread_timeout_usec);
+                        uint64_t remaining_time = final_timeout - TimeValue::Now();
+                        if (before_first_timeout)
+                            log->Printf ("Process::RunThreadPlan(): Running function with one thread timeout timed out, "
+                                         "running till  for %" PRId64 " usec with all threads enabled.",
+                                         remaining_time);
                         else
                             log->Printf ("Process::RunThreadPlan(): Restarting function with all threads enabled "
-                                         "and timeout: %d timed out.",
-                                         single_thread_timeout_usec);
+                                         "and timeout: %d timed out, abandoning execution.",
+                                         timeout_usec);
                     }
                     else
                         log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, "
-                                     "halt and abandoning execution.", 
-                                     single_thread_timeout_usec);
+                                     "abandoning execution.", 
+                                     timeout_usec);
                 }
                 
-                Error halt_error = Halt();
-                if (halt_error.Success())
-                {
-                    if (log)
-                        log->PutCString ("Process::RunThreadPlan(): Halt succeeded.");
-                        
-                    // If halt succeeds, it always produces a stopped event.  Wait for that:
-                    
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithMicroSeconds(500000);
-
-                    got_event = listener.WaitForEvent(&real_timeout, event_sp);
-                    
-                    if (got_event)
-                    {
-                        stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
-                        if (log)
-                        {
-                            log->Printf ("Process::RunThreadPlan(): Stopped with event: %s", StateAsCString(stop_state));
-                            if (stop_state == lldb::eStateStopped 
-                                && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
-                                log->PutCString ("    Event was the Halt interruption event.");
-                        }
-                        
-                        if (stop_state == lldb::eStateStopped)
-                        {
-                            // Between the time we initiated the Halt and the time we delivered it, the process could have
-                            // already finished its job.  Check that here:
-                            
-                            if (thread->IsThreadPlanDone (thread_plan_sp.get()))
-                            {
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done.  "
-                                                 "Exiting wait loop.");
-                                return_value = eExecutionCompleted;
-                                break;
-                            }
-
-                            if (!try_all_threads)
-                            {
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
-                                return_value = eExecutionInterrupted;
-                                break;
-                            }
-                            
-                            if (first_timeout)
-                            {
-                                // Set all the other threads to run, and return to the top of the loop, which will continue;
-                                first_timeout = false;
-                                thread_plan_sp->SetStopOthers (false);
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): about to resume.");
-
-                                continue;
-                            }
-                            else
-                            {
-                                // Running all threads failed, so return Interrupted.
-                                if (log)
-                                    log->PutCString("Process::RunThreadPlan(): running all threads timed out.");
-                                return_value = eExecutionInterrupted;
-                                break;
-                            }
-                        }
-                    }
-                    else
-                    {   if (log)
-                            log->PutCString("Process::RunThreadPlan(): halt said it succeeded, but I got no event.  "
-                                    "I'm getting out of here passing Interrupted.");
-                        return_value = eExecutionInterrupted;
-                        break;
-                    }
-                }
-                else
+                // It is possible that between the time we issued the Halt, and we get around to calling Halt the target
+                // could have stopped.  That's fine, Halt will figure that out and send the appropriate Stopped event.
+                // BUT it is also possible that we stopped & restarted (e.g. hit a signal with "stop" set to false.)  In
+                // that case, we'll get the stopped & restarted event, and we should go back to waiting for the Halt's
+                // stopped event.  That's what this while loop does.
+                
+                bool back_to_top = true;
+                uint32_t try_halt_again = 0;
+                bool do_halt = true;
+                const uint32_t num_retries = 5;
+                while (try_halt_again < num_retries)
                 {
-                    // This branch is to work around some problems with gdb-remote's Halt.  It is a little racy, and can return 
-                    // an error from halt, but if you wait a bit you'll get a stopped event anyway.
-                    if (log)
-                        log->Printf ("Process::RunThreadPlan(): halt failed: error = \"%s\", I'm just going to wait a little longer and see if I get a stopped event.", 
-                                     halt_error.AsCString());                
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithMicroSeconds(500000);
-                    timeout_ptr = &real_timeout;
-                    got_event = listener.WaitForEvent(&real_timeout, event_sp);
-                    if (!got_event || event_sp.get() == NULL)
+                    Error halt_error;
+                    if (do_halt)
                     {
-                        // This is not going anywhere, bag out.
                         if (log)
-                            log->PutCString ("Process::RunThreadPlan(): halt failed: and waiting for the stopped event failed.");
-                        return_value = eExecutionInterrupted;
-                        break;                
+                            log->Printf ("Process::RunThreadPlan(): Running Halt.");
+                        halt_error = Halt();
                     }
-                    else
+                    if (halt_error.Success())
                     {
-                        stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
                         if (log)
-                            log->PutCString ("Process::RunThreadPlan(): halt failed: but then I got a stopped event.  Whatever...");
-                        if (stop_state == lldb::eStateStopped)
-                        {
-                            // Between the time we initiated the Halt and the time we delivered it, the process could have
-                            // already finished its job.  Check that here:
+                            log->PutCString ("Process::RunThreadPlan(): Halt succeeded.");
                             
-                            if (thread->IsThreadPlanDone (thread_plan_sp.get()))
-                            {
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done.  "
-                                                 "Exiting wait loop.");
-                                return_value = eExecutionCompleted;
-                                break;
-                            }
+                        real_timeout = TimeValue::Now();
+                        real_timeout.OffsetWithMicroSeconds(500000);
 
-                            if (first_timeout)
+                        got_event = listener.WaitForEvent(&real_timeout, event_sp);
+                        
+                        if (got_event)
+                        {
+                            stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+                            if (log)
                             {
-                                // Set all the other threads to run, and return to the top of the loop, which will continue;
-                                first_timeout = false;
-                                thread_plan_sp->SetStopOthers (false);
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): About to resume.");
-
-                                continue;
+                                log->Printf ("Process::RunThreadPlan(): Stopped with event: %s", StateAsCString(stop_state));
+                                if (stop_state == lldb::eStateStopped 
+                                    && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
+                                    log->PutCString ("    Event was the Halt interruption event.");
                             }
-                            else
+                            
+                            if (stop_state == lldb::eStateStopped)
                             {
-                                // Running all threads failed, so return Interrupted.
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): running all threads timed out.");
-                                return_value = eExecutionInterrupted;
-                                break;
+                                // Between the time we initiated the Halt and the time we delivered it, the process could have
+                                // already finished its job.  Check that here:
+                                
+                                if (thread->IsThreadPlanDone (thread_plan_sp.get()))
+                                {
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done.  "
+                                                     "Exiting wait loop.");
+                                    return_value = eExecutionCompleted;
+                                    back_to_top = false;
+                                    break;
+                                }
+                                
+                                if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
+                                {
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): Went to halt but got a restarted event, there must be an un-restarted stopped event so try again...  "
+                                                     "Exiting wait loop.");
+                                    try_halt_again++;
+                                    do_halt = false;
+                                    continue;
+                                }
+
+                                if (!run_others)
+                                {
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
+                                    return_value = eExecutionInterrupted;
+                                    back_to_top = false;
+                                    break;
+                                }
+                                
+                                if (before_first_timeout)
+                                {
+                                    // Set all the other threads to run, and return to the top of the loop, which will continue;
+                                    before_first_timeout = false;
+                                    thread_plan_sp->SetStopOthers (false);
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): about to resume.");
+
+                                    back_to_top = true;
+                                    break;
+                                }
+                                else
+                                {
+                                    // Running all threads failed, so return Interrupted.
+                                    if (log)
+                                        log->PutCString("Process::RunThreadPlan(): running all threads timed out.");
+                                    return_value = eExecutionInterrupted;
+                                    back_to_top = false;
+                                    break;
+                                }
                             }
                         }
                         else
-                        {
-                            if (log)
-                                log->Printf ("Process::RunThreadPlan(): halt failed, I waited and didn't get"
-                                             " a stopped event, instead got %s.", StateAsCString(stop_state));
+                        {   if (log)
+                                log->PutCString("Process::RunThreadPlan(): halt said it succeeded, but I got no event.  "
+                                        "I'm getting out of here passing Interrupted.");
                             return_value = eExecutionInterrupted;
-                            break;                
+                            back_to_top = false;
+                            break;
                         }
                     }
+                    else
+                    {
+                        try_halt_again++;
+                        continue;
+                    }
                 }
-
+                
+                if (!back_to_top || try_halt_again > num_retries)
+                    break;
+                else
+                    continue;
             }
-            
         }  // END WAIT LOOP
         
         // If we had to start up a temporary private state thread to run this thread plan, shut it down now.
@@ -4523,9 +5241,22 @@ Process::RunThreadPlan (ExecutionContext
 
         }
         
+        // Restore the thread state if we are going to discard the plan execution.  There are three cases where this
+        // could happen:
+        // 1) The execution successfully completed
+        // 2) We hit a breakpoint, and ignore_breakpoints was true
+        // 3) We got some other error, and discard_on_error was true
+        bool should_unwind = (return_value == eExecutionInterrupted && unwind_on_error)
+                             || (return_value == eExecutionHitBreakpoint && ignore_breakpoints);
+        
+        if (return_value == eExecutionCompleted
+            || should_unwind)
+        {
+            thread_plan_sp->RestoreThreadState();
+        }
         
         // Now do some processing on the results of the run:
-        if (return_value == eExecutionInterrupted)
+        if (return_value == eExecutionInterrupted || return_value == eExecutionHitBreakpoint)
         {
             if (log)
             {
@@ -4590,11 +5321,11 @@ Process::RunThreadPlan (ExecutionContext
                                 continue;
                             }
                             
-                            ts.Printf("<0x%4.4llx ", thread->GetID());
+                            ts.Printf("<0x%4.4" PRIx64 " ", thread->GetID());
                             RegisterContext *register_context = thread->GetRegisterContext().get();
                             
                             if (register_context)
-                                ts.Printf("[ip 0x%llx] ", register_context->GetPC());
+                                ts.Printf("[ip 0x%" PRIx64 "] ", register_context->GetPC());
                             else
                                 ts.Printf("[ip unknown] ");
                             
@@ -4618,7 +5349,7 @@ Process::RunThreadPlan (ExecutionContext
                     log->Printf("Process::RunThreadPlan(): execution interrupted: %s", s.GetData());
             }
             
-            if (discard_on_error && thread_plan_sp)
+            if (should_unwind && thread_plan_sp)
             {
                 if (log)
                     log->Printf ("Process::RunThreadPlan: ExecutionInterrupted - discarding thread plans up to %p.", thread_plan_sp.get());
@@ -4636,7 +5367,7 @@ Process::RunThreadPlan (ExecutionContext
             if (log)
                 log->PutCString("Process::RunThreadPlan(): execution set up error.");
                 
-            if (discard_on_error && thread_plan_sp)
+            if (unwind_on_error && thread_plan_sp)
             {
                 thread->DiscardThreadPlansUpToPlan (thread_plan_sp);
                 thread_plan_sp->SetPrivate (orig_plan_private);
@@ -4660,10 +5391,10 @@ Process::RunThreadPlan (ExecutionContext
             {
                 if (log)
                     log->PutCString("Process::RunThreadPlan(): thread plan stopped in mid course");
-                if (discard_on_error && thread_plan_sp)
+                if (unwind_on_error && thread_plan_sp)
                 {
                     if (log)
-                        log->PutCString("Process::RunThreadPlan(): discarding thread plan 'cause discard_on_error is set.");
+                        log->PutCString("Process::RunThreadPlan(): discarding thread plan 'cause unwind_on_error is set.");
                     thread->DiscardThreadPlansUpToPlan (thread_plan_sp);
                     thread_plan_sp->SetPrivate (orig_plan_private);
                 }
@@ -4722,6 +5453,9 @@ Process::ExecutionResultAsCString (Execu
         case eExecutionInterrupted:
             result_name = "eExecutionInterrupted";
             break;
+        case eExecutionHitBreakpoint:
+            result_name = "eExecutionHitBreakpoint";
+            break;
         case eExecutionSetupError:
             result_name = "eExecutionSetupError";
             break;
@@ -4742,7 +5476,7 @@ Process::GetStatus (Stream &strm)
         {
             int exit_status = GetExitStatus();
             const char *exit_description = GetExitDescription();
-            strm.Printf ("Process %llu exited with status = %i (0x%8.8x) %s\n",
+            strm.Printf ("Process %" PRIu64 " exited with status = %i (0x%8.8x) %s\n",
                           GetID(),
                           exit_status,
                           exit_status,
@@ -4753,12 +5487,12 @@ Process::GetStatus (Stream &strm)
             if (state == eStateConnected)
                 strm.Printf ("Connected to remote target.\n");
             else
-                strm.Printf ("Process %llu %s\n", GetID(), StateAsCString (state));
+                strm.Printf ("Process %" PRIu64 " %s\n", GetID(), StateAsCString (state));
         }
     }
     else
     {
-        strm.Printf ("Process %llu is running.\n", GetID());
+        strm.Printf ("Process %" PRIu64 " is running.\n", GetID());
     }
 }
 
@@ -4771,6 +5505,7 @@ Process::GetThreadStatus (Stream &strm,
 {
     size_t num_thread_infos_dumped = 0;
     
+    Mutex::Locker locker (GetThreadList().GetMutex());
     const size_t num_threads = GetThreadList().GetSize();
     for (uint32_t i = 0; i < num_threads; i++)
     {
@@ -4779,7 +5514,8 @@ Process::GetThreadStatus (Stream &strm,
         {
             if (only_threads_with_stop_reason)
             {
-                if (thread->GetStopInfo().get() == NULL)
+                StopInfoSP stop_info_sp = thread->GetStopInfo();
+                if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid())
                     continue;
             }
             thread->GetStatus (strm, 
@@ -4836,221 +5572,80 @@ Process::Flush ()
     m_thread_list.Flush();
 }
 
-//--------------------------------------------------------------
-// class Process::SettingsController
-//--------------------------------------------------------------
-
-Process::SettingsController::SettingsController () :
-    UserSettingsController ("process", Target::GetSettingsController())
+void
+Process::DidExec ()
 {
+    Target &target = GetTarget();
+    target.CleanupProcess ();
+    ModuleList unloaded_modules (target.GetImages());
+    target.ModulesDidUnload (unloaded_modules);
+    target.GetSectionLoadList().Clear();
+    m_dynamic_checkers_ap.reset();
+    m_abi_sp.reset();
+    m_os_ap.reset();
+    m_dyld_ap.reset();
+    m_image_tokens.clear();
+    m_allocated_memory_cache.Clear();
+    m_language_runtimes.clear();
+    m_thread_list.DiscardThreadPlans();
+    m_memory_cache.Clear(true);
+    DoDidExec();
+    CompleteAttach ();
 }
 
-Process::SettingsController::~SettingsController ()
+Process::ReservationCache::ReservationCache (Process &process) : m_process(process)
 {
+    m_mod_id = process.GetModID();
 }
 
-lldb::InstanceSettingsSP
-Process::SettingsController::CreateInstanceSettings (const char *instance_name)
+void
+Process::ReservationCache::Reserve (lldb::addr_t addr, size_t size)
 {
-    lldb::InstanceSettingsSP new_settings_sp (new ProcessInstanceSettings (GetSettingsController(),
-                                                                           false, 
-                                                                           instance_name));
-    return new_settings_sp;
+    CheckModID();
+    m_reserved_cache[addr] = size;
 }
 
-//--------------------------------------------------------------
-// class ProcessInstanceSettings
-//--------------------------------------------------------------
-
-ProcessInstanceSettings::ProcessInstanceSettings
-(
-    const UserSettingsControllerSP &owner_sp, 
-    bool live_instance, 
-    const char *name
-) :
-    InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance)
+void
+Process::ReservationCache::Unreserve (lldb::addr_t addr)
 {
-    // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
-    // until the vtables for ProcessInstanceSettings are properly set up, i.e. AFTER all the initializers.
-    // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
-    // This is true for CreateInstanceName() too.
-    
-    if (GetInstanceName () == InstanceSettings::InvalidName())
-    {
-        ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
-        owner_sp->RegisterInstanceSettings (this);
-    }
+    CheckModID();
+    ReservedMap::iterator iter = m_reserved_cache.find(addr);
     
-    if (live_instance)
+    if (iter != m_reserved_cache.end())
     {
-        const lldb::InstanceSettingsSP &pending_settings = owner_sp->FindPendingSettings (m_instance_name);
-        CopyInstanceSettings (pending_settings,false);
+        size_t size = iter->second;
+        m_reserved_cache.erase(iter);
+        m_free_cache[size].push_back(addr);
     }
 }
 
-ProcessInstanceSettings::ProcessInstanceSettings (const ProcessInstanceSettings &rhs) :
-    InstanceSettings (Process::GetSettingsController(), CreateInstanceName().AsCString()),
-    m_disable_memory_cache(rhs.m_disable_memory_cache),
-    m_extra_startup_commands (rhs.m_extra_startup_commands)
+lldb::addr_t
+Process::ReservationCache::Find (size_t size)
 {
-    if (m_instance_name != InstanceSettings::GetDefaultName())
+    CheckModID();
+    lldb::addr_t ret = LLDB_INVALID_ADDRESS;
+    FreeMap::iterator map_iter = m_free_cache.find(size);
+    if (map_iter != m_free_cache.end())
     {
-        UserSettingsControllerSP owner_sp (m_owner_wp.lock());
-        if (owner_sp)
+        if (!map_iter->second.empty())
         {
-            CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false);
-            owner_sp->RemovePendingSettings (m_instance_name);
+            ret = map_iter->second.back();
+            map_iter->second.pop_back();
+            m_reserved_cache[ret] = size;
         }
     }
-}
-
-ProcessInstanceSettings::~ProcessInstanceSettings ()
-{
-}
-
-ProcessInstanceSettings&
-ProcessInstanceSettings::operator= (const ProcessInstanceSettings &rhs)
-{
-    if (this != &rhs)
-    {
-        m_disable_memory_cache = rhs.m_disable_memory_cache;
-        m_extra_startup_commands = rhs.m_extra_startup_commands;
-    }
-
-    return *this;
-}
-
-
-void
-ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
-                                                         const char *index_value,
-                                                         const char *value,
-                                                         const ConstString &instance_name,
-                                                         const SettingEntry &entry,
-                                                         VarSetOperationType op,
-                                                         Error &err,
-                                                         bool pending)
-{
-    if (var_name == GetDisableMemoryCacheVarName())
-    {
-        bool success;
-        bool result = Args::StringToBoolean(value, false, &success);
-        
-        if (success)
-        {
-            m_disable_memory_cache = result;
-        }
-        else
-        {
-            err.SetErrorStringWithFormat ("Bad value \"%s\" for %s, should be Boolean.", value, GetDisableMemoryCacheVarName().AsCString());
-        }
-        
-    }
-    else if (var_name == GetExtraStartupCommandVarName())
-    {
-        UserSettingsController::UpdateStringArrayVariable (op, index_value, m_extra_startup_commands, value, err);
-    }
-}
-
-void
-ProcessInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
-                                               bool pending)
-{
-    if (new_settings.get() == NULL)
-        return;
-    
-    ProcessInstanceSettings *new_settings_ptr = static_cast <ProcessInstanceSettings *> (new_settings.get());
-    
-    if (!new_settings_ptr)
-        return;
     
-    *this = *new_settings_ptr;
+    return ret;
 }
 
-bool
-ProcessInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
-                                                   const ConstString &var_name,
-                                                   StringList &value,
-                                                   Error *err)
+void
+Process::ReservationCache::CheckModID()
 {
-    if (var_name == GetDisableMemoryCacheVarName())
-    {
-        value.AppendString(m_disable_memory_cache ? "true" : "false");
-        return true;
-    }
-    else if (var_name == GetExtraStartupCommandVarName())
-    {
-        if (m_extra_startup_commands.GetArgumentCount() > 0)
-        {
-            for (int i = 0; i < m_extra_startup_commands.GetArgumentCount(); ++i)
-                value.AppendString (m_extra_startup_commands.GetArgumentAtIndex (i));
-        }
-        return true;
-    }
-    else
+    if (m_mod_id != m_process.GetModID())
     {
-        if (err)
-            err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
-        return false;
+        // wipe all our caches, they're invalid
+        m_reserved_cache.clear();
+        m_free_cache.clear();
+        m_mod_id = m_process.GetModID();
     }
 }
-
-const ConstString
-ProcessInstanceSettings::CreateInstanceName ()
-{
-    static int instance_count = 1;
-    StreamString sstr;
-
-    sstr.Printf ("process_%d", instance_count);
-    ++instance_count;
-
-    const ConstString ret_val (sstr.GetData());
-    return ret_val;
-}
-
-const ConstString &
-ProcessInstanceSettings::GetDisableMemoryCacheVarName () const
-{
-    static ConstString disable_memory_cache_var_name ("disable-memory-cache");
-    
-    return disable_memory_cache_var_name;
-}
-
-const ConstString &
-ProcessInstanceSettings::GetExtraStartupCommandVarName () const
-{
-    static ConstString extra_startup_command_var_name ("extra-startup-command");
-    
-    return extra_startup_command_var_name;
-}
-
-//--------------------------------------------------
-// SettingsController Variable Tables
-//--------------------------------------------------
-
-SettingEntry
-Process::SettingsController::global_settings_table[] =
-{
-  //{ "var-name",    var-type  ,        "default", enum-table, init'd, hidden, "help-text"},
-    {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
-};
-
-
-SettingEntry
-Process::SettingsController::instance_settings_table[] =
-{
-  //{ "var-name",       var-type,              "default",       enum-table, init'd, hidden, "help-text"},
-    {  "disable-memory-cache", eSetVarTypeBoolean,
-#ifdef ENABLE_MEMORY_CACHING
-        "false",
-#else
-        "true",
-#endif
-        NULL,       false,  false,  "Disable reading and caching of memory in fixed-size units." },
-    { "extra-startup-command", eSetVarTypeArray, NULL, NULL, false,  false,  "A list containing extra commands understood by the particular process plugin used." },
-    {  NULL,            eSetVarTypeNone,        NULL,           NULL,       false,  false,  NULL }
-};
-
-
-
-

Modified: lldb/branches/lldb-platform-work/source/Target/RegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/RegisterContext.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/RegisterContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/RegisterContext.cpp Thu Jun  6 19:06:43 2013
@@ -196,6 +196,47 @@ RegisterContext::WriteRegisterFromUnsign
     return false;
 }
 
+bool
+RegisterContext::CopyFromRegisterContext (lldb::RegisterContextSP context)
+{
+    uint32_t num_register_sets = context->GetRegisterSetCount();
+    // We don't know that two threads have the same register context, so require the threads to be the same.
+    if (context->GetThreadID() != GetThreadID())
+        return false;
+    
+    if (num_register_sets != GetRegisterSetCount())
+        return false;
+    
+    RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
+    
+    for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx)
+    {
+        const RegisterSet * const reg_set = GetRegisterSet(set_idx);
+        
+        const uint32_t num_registers = reg_set->num_registers;
+        for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
+        {
+            const uint32_t reg = reg_set->registers[reg_idx];
+            const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+            if (!reg_info || reg_info->value_regs)
+                continue;
+            RegisterValue reg_value;
+            
+            // If we can reconstruct the register from the frame we are copying from, then do so, otherwise
+            // use the value from frame 0.
+            if (context->ReadRegister(reg_info, reg_value))
+            {
+                WriteRegister(reg_info, reg_value);
+            }
+            else if (frame_zero_context->ReadRegister(reg_info, reg_value))
+            {
+                WriteRegister(reg_info, reg_value);
+            }
+        }
+    }
+    return true;
+}
+
 lldb::tid_t
 RegisterContext::GetThreadID() const
 {

Modified: lldb/branches/lldb-platform-work/source/Target/SectionLoadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/SectionLoadList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/SectionLoadList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/SectionLoadList.cpp Thu Jun  6 19:06:43 2013
@@ -59,17 +59,15 @@ SectionLoadList::GetSectionLoadAddress (
 bool
 SectionLoadList::SetSectionLoadAddress (const lldb::SectionSP &section, addr_t load_addr, bool warn_multiple)
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
 
     if (log)
     {
         const FileSpec &module_file_spec (section->GetModule()->GetFileSpec());
-        log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16llx)",
+        log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")",
                      __FUNCTION__,
                      section.get(),
-                     module_file_spec.GetDirectory().AsCString(),
-                     module_file_spec.GetDirectory() ? "/" : "",
-                     module_file_spec.GetFilename().AsCString(),
+                     module_file_spec.GetPath().c_str(),
                      section->GetName().AsCString(),
                      load_addr);
     }
@@ -112,7 +110,7 @@ SectionLoadList::SetSectionLoadAddress (
                 ModuleSP curr_module_sp (ats_pos->second->GetModule());
                 if (curr_module_sp)
                 {
-                    module_sp->ReportWarning ("address 0x%16.16llx maps to more than one section: %s.%s and %s.%s",
+                    module_sp->ReportWarning ("address 0x%16.16" PRIx64 " maps to more than one section: %s.%s and %s.%s",
                                               load_addr, 
                                               module_sp->GetFileSpec().GetFilename().GetCString(), 
                                               section->GetName().GetCString(),
@@ -136,17 +134,15 @@ SectionLoadList::SetSectionUnloaded (con
 
     if (section_sp)
     {
-        LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
+        Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
 
         if (log)
         {
             const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
-            log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s))",
+            log->Printf ("SectionLoadList::%s (section = %p (%s.%s))",
                          __FUNCTION__,
                          section_sp.get(),
-                         module_file_spec.GetDirectory().AsCString(),
-                         module_file_spec.GetDirectory() ? "/" : "",
-                         module_file_spec.GetFilename().AsCString(),
+                         module_file_spec.GetPath().c_str(),
                          section_sp->GetName().AsCString());
         }
 
@@ -155,6 +151,7 @@ SectionLoadList::SetSectionUnloaded (con
         sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
         if (sta_pos != m_sect_to_addr.end())
         {
+            ++unload_count;
             addr_t load_addr = sta_pos->second;
             m_sect_to_addr.erase (sta_pos);
 
@@ -169,17 +166,15 @@ SectionLoadList::SetSectionUnloaded (con
 bool
 SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t load_addr)
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
 
     if (log)
     {
         const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
-        log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16llx)",
+        log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")",
                      __FUNCTION__,
                      section_sp.get(),
-                     module_file_spec.GetDirectory().AsCString(),
-                     module_file_spec.GetDirectory() ? "/" : "",
-                     module_file_spec.GetFilename().AsCString(),
+                     module_file_spec.GetPath().c_str(),
                      section_sp->GetName().AsCString(),
                      load_addr);
     }
@@ -215,9 +210,10 @@ SectionLoadList::ResolveLoadAddress (add
         {
             if (load_addr != pos->first && pos != m_addr_to_sect.begin())
                 --pos;
-            if (load_addr >= pos->first)
+            const addr_t pos_load_addr = pos->first;
+            if (load_addr >= pos_load_addr)
             {
-                addr_t offset = load_addr - pos->first;
+                addr_t offset = load_addr - pos_load_addr;
                 if (offset < pos->second->GetByteSize())
                 {
                     // We have found the top level section, now we need to find the
@@ -254,7 +250,7 @@ SectionLoadList::Dump (Stream &s, Target
     addr_to_sect_collection::const_iterator pos, end;
     for (pos = m_addr_to_sect.begin(), end = m_addr_to_sect.end(); pos != end; ++pos)
     {
-        s.Printf("addr = 0x%16.16llx, section = %p: ", pos->first, pos->second.get());
+        s.Printf("addr = 0x%16.16" PRIx64 ", section = %p: ", pos->first, pos->second.get());
         pos->second->Dump (&s, target, 0);
     }
 }

Modified: lldb/branches/lldb-platform-work/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/StackFrame.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/StackFrame.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/StackFrame.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Target/StackFrame.h"
 
 // C Includes
@@ -19,7 +21,10 @@
 #include "lldb/Core/Value.h"
 #include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContextScope.h"
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
@@ -194,6 +199,16 @@ StackFrame::GetStackID()
     return m_id;
 }
 
+uint32_t
+StackFrame::GetFrameIndex () const
+{
+    ThreadSP thread_sp = GetThread();
+    if (thread_sp)
+        return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
+    else
+        return m_frame_index;
+}
+
 void
 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
 {
@@ -235,7 +250,7 @@ void
 StackFrame::ChangePC (addr_t pc)
 {
     m_frame_code_addr.SetRawAddress(pc);
-    m_sc.Clear();
+    m_sc.Clear(false);
     m_flags.Reset(0);
     ThreadSP thread_sp (GetThread());
     if (thread_sp)
@@ -251,9 +266,12 @@ StackFrame::Disassemble ()
         Target *target = exe_ctx.GetTargetPtr();
         if (target)
         {
+            const char *plugin_name = NULL;
+            const char *flavor = NULL;
             Disassembler::Disassemble (target->GetDebugger(),
                                        target->GetArchitecture(),
-                                       NULL,
+                                       plugin_name,
+                                       flavor,
                                        exe_ctx,
                                        0,
                                        0,
@@ -304,6 +322,17 @@ StackFrame::GetSymbolContext (uint32_t r
     // Copy our internal symbol context into "sc".
     if ((m_flags.Get() & resolve_scope) != resolve_scope)
     {
+        uint32_t resolved = 0;
+
+        // If the target was requested add that:
+        if (!m_sc.target_sp)
+        {
+            m_sc.target_sp = CalculateTarget();
+            if (m_sc.target_sp)
+                resolved |= eSymbolContextTarget;
+        }
+        
+
         // Resolve our PC to section offset if we haven't alreday done so
         // and if we don't have a module. The resolved address section will
         // contain the module to which it belongs
@@ -323,7 +352,6 @@ StackFrame::GetSymbolContext (uint32_t r
         }
 
 
-        uint32_t resolved = 0;
         if (m_sc.module_sp)
         {
             // We have something in our stack frame symbol context, lets check
@@ -407,9 +435,18 @@ StackFrame::GetSymbolContext (uint32_t r
                     m_sc.block = sc.block;
                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)  
                     m_sc.symbol = sc.symbol;
-                if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 
+                if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
+                {
                     m_sc.line_entry = sc.line_entry;
-
+                    if (m_sc.target_sp)
+                    {
+                        // Be sure to apply and file remappings to our file and line
+                        // entries when handing out a line entry
+                        FileSpec new_file_spec;
+                        if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
+                            m_sc.line_entry.file = new_file_spec;
+                    }
+                }
             }
         }
         else
@@ -417,17 +454,10 @@ StackFrame::GetSymbolContext (uint32_t r
             // If we don't have a module, then we can't have the compile unit,
             // function, block, line entry or symbol, so we can safely call
             // ResolveSymbolContextForAddress with our symbol context member m_sc.
-            TargetSP target_sp (CalculateTarget());
-            if (target_sp)
-                resolved |= target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
-        }
-
-        // If the target was requested add that:
-        if (!m_sc.target_sp)
-        {
-            m_sc.target_sp = CalculateTarget();
             if (m_sc.target_sp)
-                resolved |= eSymbolContextTarget;
+            {
+                resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
+            }
         }
 
         // Update our internal flags so we remember what we have tried to locate so
@@ -767,6 +797,7 @@ StackFrame::GetValueForVariableExpressio
                                     deref = false;
                                 }
                                 
+                                bool is_incomplete_array = false;
                                 if (valobj_sp->IsPointerType ())
                                 {
                                     bool is_objc_pointer = true;
@@ -830,11 +861,14 @@ StackFrame::GetValueForVariableExpressio
                                         }
                                     }
                                 }
-                                else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL))
+                                else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL, &is_incomplete_array))
                                 {
                                     // Pass false to dynamic_value here so we can tell the difference between
                                     // no dynamic value and no member of this type...
                                     child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
+                                    if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false))
+                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
+
                                     if (!child_valobj_sp)
                                     {
                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
@@ -1248,13 +1282,12 @@ StackFrame::DumpUsingSettingsFormat (Str
 
     GetSymbolContext(eSymbolContextEverything);
     ExecutionContext exe_ctx (shared_from_this());
-    const char *end = NULL;
     StreamString s;
     const char *frame_format = NULL;
     Target *target = exe_ctx.GetTargetPtr();
     if (target)
         frame_format = target->GetDebugger().GetFrameFormat();
-    if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end))
+    if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s))
     {
         strm->Write(s.GetData(), s.GetSize());
     }
@@ -1275,7 +1308,7 @@ StackFrame::Dump (Stream *strm, bool sho
         strm->Printf("frame #%u: ", m_frame_index);
     ExecutionContext exe_ctx (shared_from_this());
     Target *target = exe_ctx.GetTargetPtr();
-    strm->Printf("0x%0*llx ", 
+    strm->Printf("0x%0*" PRIx64 " ",
                  target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
                  GetFrameCodeAddress().GetLoadAddress(target));
     GetSymbolContext(eSymbolContextEverything);
@@ -1350,7 +1383,7 @@ StackFrame::GetStatus (Stream& strm,
     {
         ExecutionContext exe_ctx (shared_from_this());
         bool have_source = false;
-        DebuggerInstanceSettings::StopDisassemblyType disasm_display = DebuggerInstanceSettings::eStopDisassemblyTypeNever;
+        Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
         Target *target = exe_ctx.GetTargetPtr();
         if (target)
         {
@@ -1365,27 +1398,25 @@ StackFrame::GetStatus (Stream& strm,
 
                 if (m_sc.comp_unit && m_sc.line_entry.IsValid())
                 {
-                    if (target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
+                    have_source = true;
+                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
                                                                                       m_sc.line_entry.line,
                                                                                       source_lines_before,
                                                                                       source_lines_after,
                                                                                       "->",
-                                                                                      &strm))
-                    {
-                        have_source = true;
-                    }
+                                                                                      &strm);
                 }
             }
             switch (disasm_display)
             {
-            case DebuggerInstanceSettings::eStopDisassemblyTypeNever:
+            case Debugger::eStopDisassemblyTypeNever:
                 break;
                 
-            case DebuggerInstanceSettings::eStopDisassemblyTypeNoSource:
+            case Debugger::eStopDisassemblyTypeNoSource:
                 if (have_source)
                     break;
                 // Fall through to next case
-            case DebuggerInstanceSettings::eStopDisassemblyTypeAlways:
+            case Debugger::eStopDisassemblyTypeAlways:
                 if (target)
                 {
                     const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
@@ -1395,9 +1426,12 @@ StackFrame::GetStatus (Stream& strm,
                         AddressRange pc_range;
                         pc_range.GetBaseAddress() = GetFrameCodeAddress();
                         pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
+                        const char *plugin_name = NULL;
+                        const char *flavor = NULL;
                         Disassembler::Disassemble (target->GetDebugger(),
                                                    target_arch,
-                                                   NULL,
+                                                   plugin_name,
+                                                   flavor,
                                                    exe_ctx,
                                                    pc_range,
                                                    disasm_lines,

Modified: lldb/branches/lldb-platform-work/source/Target/StackFrameList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/StackFrameList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/StackFrameList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/StackFrameList.cpp Thu Jun  6 19:06:43 2013
@@ -13,6 +13,9 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Core/Log.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/SourceManager.h"
 #include "lldb/Symbol/Block.h"
@@ -21,6 +24,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StackFrame.h"
+#include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/Unwind.h"
@@ -45,8 +49,15 @@ StackFrameList::StackFrameList
     m_frames (),
     m_selected_frame_idx (0),
     m_concrete_frames_fetched (0),
+    m_current_inlined_depth (UINT32_MAX),
+    m_current_inlined_pc (LLDB_INVALID_ADDRESS),
     m_show_inlined_frames (show_inline_frames)
 {
+    if (prev_frames_sp)
+    {
+        m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
+        m_current_inlined_pc =    prev_frames_sp->m_current_inlined_pc;
+    }
 }
 
 //----------------------------------------------------------------------
@@ -54,11 +65,198 @@ StackFrameList::StackFrameList
 //----------------------------------------------------------------------
 StackFrameList::~StackFrameList()
 {
+    // Call clear since this takes a lock and clears the stack frame list
+    // in case another thread is currently using this stack frame list
+    Clear();
+}
+
+void
+StackFrameList::CalculateCurrentInlinedDepth()
+{
+    uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
+    if (cur_inlined_depth == UINT32_MAX)
+    {
+        ResetCurrentInlinedDepth();
+    }
+}
+
+uint32_t
+StackFrameList::GetCurrentInlinedDepth ()
+{
+    if (m_show_inlined_frames && m_current_inlined_pc != LLDB_INVALID_ADDRESS)
+    {
+        lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
+        if (cur_pc != m_current_inlined_pc)
+        {
+            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+            m_current_inlined_depth = UINT32_MAX;
+            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+            if (log && log->GetVerbose())
+                log->Printf ("GetCurrentInlinedDepth: invalidating current inlined depth.\n");
+        }
+        return m_current_inlined_depth;
+    }
+    else
+    {
+        return UINT32_MAX;
+    }
+}
+
+void
+StackFrameList::ResetCurrentInlinedDepth ()
+{
+    if (m_show_inlined_frames)
+    {        
+        GetFramesUpTo(0);
+        if (!m_frames[0]->IsInlined())
+        {
+            m_current_inlined_depth = UINT32_MAX;
+            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+            if (log && log->GetVerbose())
+                log->Printf ("ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
+        }
+        else
+        {
+            // We only need to do something special about inlined blocks when we
+            // are at the beginning of an inlined function:
+            // FIXME: We probably also have to do something special if the PC is at the END
+            // of an inlined function, which coincides with the end of either its containing
+            // function or another inlined function.
+            
+            lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+            Block *block_ptr = m_frames[0]->GetFrameBlock();
+            if (block_ptr)
+            {
+                Address pc_as_address;
+                pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget()));
+                AddressRange containing_range;
+                if (block_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
+                {
+                    if (pc_as_address == containing_range.GetBaseAddress())
+                    {
+                        // If we got here because of a breakpoint hit, then set the inlined depth depending on where
+                        // the breakpoint was set.
+                        // If we got here because of a crash, then set the inlined depth to the deepest most block.
+                        // Otherwise, we stopped here naturally as the result of a step, so set ourselves in the
+                        // containing frame of the whole set of nested inlines, so the user can then "virtually"
+                        // step into the frames one by one, or next over the whole mess.
+                        // Note: We don't have to handle being somewhere in the middle of the stack here, since
+                        // ResetCurrentInlinedDepth doesn't get called if there is a valid inlined depth set.
+                        StopInfoSP stop_info_sp = m_thread.GetStopInfo();
+                        if (stop_info_sp)
+                        {
+                            switch (stop_info_sp->GetStopReason())
+                            {
+                            case eStopReasonWatchpoint:
+                            case eStopReasonException:
+                            case eStopReasonExec:
+                            case eStopReasonSignal:
+                                // In all these cases we want to stop in the deepest most frame.
+                                m_current_inlined_pc = curr_pc;
+                                m_current_inlined_depth = 0;
+                                break;
+                            case eStopReasonBreakpoint:
+                                {
+                                    // FIXME: Figure out what this break point is doing, and set the inline depth
+                                    // appropriately.  Be careful to take into account breakpoints that implement
+                                    // step over prologue, since that should do the default calculation.
+                                    // For now, if the breakpoints corresponding to this hit are all internal,
+                                    // I set the stop location to the top of the inlined stack, since that will make
+                                    // things like stepping over prologues work right.  But if there are any non-internal
+                                    // breakpoints I do to the bottom of the stack, since that was the old behavior.
+                                    uint32_t bp_site_id = stop_info_sp->GetValue();
+                                    BreakpointSiteSP bp_site_sp(m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id));
+                                    bool all_internal = true;
+                                    if (bp_site_sp)
+                                    {
+                                        uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
+                                        for (uint32_t i = 0; i < num_owners; i++)
+                                        {
+                                            Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+                                            if (!bp_ref.IsInternal())
+                                            {
+                                                all_internal = false;
+                                            }
+                                        }
+                                    }
+                                    if (!all_internal)
+                                    {
+                                        m_current_inlined_pc = curr_pc;
+                                        m_current_inlined_depth = 0;
+                                        break;
+                                    }
+                                }
+                            default:
+                                {
+                                    // Otherwise, we should set ourselves at the container of the inlining, so that the
+                                    // user can descend into them.
+                                    // So first we check whether we have more than one inlined block sharing this PC:
+                                    int num_inlined_functions = 0;
+                                    
+                                    for  (Block *container_ptr = block_ptr->GetInlinedParent();
+                                              container_ptr != NULL;
+                                              container_ptr = container_ptr->GetInlinedParent())
+                                    {
+                                        if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
+                                            break;
+                                        if (pc_as_address != containing_range.GetBaseAddress())
+                                            break;
+                                        
+                                        num_inlined_functions++;
+                                    }
+                                    m_current_inlined_pc = curr_pc;
+                                    m_current_inlined_depth = num_inlined_functions + 1;
+                                    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                                    if (log && log->GetVerbose())
+                                        log->Printf ("ResetCurrentInlinedDepth: setting inlined depth: %d 0x%" PRIx64 ".\n", m_current_inlined_depth, curr_pc);
+                                    
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+bool
+StackFrameList::DecrementCurrentInlinedDepth ()
+{
+    if (m_show_inlined_frames)
+    {
+        uint32_t current_inlined_depth = GetCurrentInlinedDepth();
+        if (current_inlined_depth != UINT32_MAX)
+        {
+            if (current_inlined_depth > 0)
+            {
+                m_current_inlined_depth--;
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+void
+StackFrameList::SetCurrentInlinedDepth (uint32_t new_depth)
+{
+    m_current_inlined_depth = new_depth;
+    if (new_depth == UINT32_MAX)
+        m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+    else
+        m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC();
 }
 
 void
 StackFrameList::GetFramesUpTo(uint32_t end_idx)
 {
+    // this makes sure we do not fetch frames for an invalid thread
+    if (m_thread.IsValid() == false)
+        return;
+
     // We've already gotten more frames than asked for, or we've already finished unwinding, return.
     if (m_frames.size() > end_idx || GetAllFramesFetched())
         return;
@@ -70,6 +268,21 @@ StackFrameList::GetFramesUpTo(uint32_t e
 #if defined (DEBUG_STACK_FRAMES)
         StreamFile s(stdout, false);
 #endif
+        // If we are hiding some frames from the outside world, we need to add those onto the total count of
+        // frames to fetch.  However, we don't need ot do that if end_idx is 0 since in that case we always
+        // get the first concrete frame and all the inlined frames below it...  And of course, if end_idx is
+        // UINT32_MAX that means get all, so just do that...
+        
+        uint32_t inlined_depth = 0;
+        if (end_idx > 0 && end_idx != UINT32_MAX)
+        {
+            inlined_depth = GetCurrentInlinedDepth();
+            if (inlined_depth != UINT32_MAX)
+            {
+                if (end_idx > 0)
+                    end_idx += inlined_depth;
+            }
+        }
         
         StackFrameSP unwind_frame_sp;
         do
@@ -83,27 +296,30 @@ StackFrameList::GetFramesUpTo(uint32_t e
                 // if we need to
                 if (m_frames.empty())
                 {
-                    m_thread.GetRegisterContext();
-                    assert (m_thread.m_reg_context_sp.get());
-
-                    const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
-                    // There shouldn't be any way not to get the frame info for frame 0.
-                    // But if the unwinder can't make one, lets make one by hand with the
-                    // SP as the CFA and see if that gets any further.
-                    if (!success)
+                    RegisterContextSP reg_ctx_sp (m_thread.GetRegisterContext());
+                    
+                    if (reg_ctx_sp)
                     {
-                        cfa = m_thread.GetRegisterContext()->GetSP();
-                        pc = m_thread.GetRegisterContext()->GetPC();
+
+                        const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+                        // There shouldn't be any way not to get the frame info for frame 0.
+                        // But if the unwinder can't make one, lets make one by hand with the
+                        // SP as the CFA and see if that gets any further.
+                        if (!success)
+                        {
+                            cfa = reg_ctx_sp->GetSP();
+                            pc = reg_ctx_sp->GetPC();
+                        }
+                        
+                        unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
+                                                               m_frames.size(), 
+                                                               idx,
+                                                               reg_ctx_sp,
+                                                               cfa,
+                                                               pc,
+                                                               NULL));
+                        m_frames.push_back (unwind_frame_sp);
                     }
-                    
-                    unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
-                                                           m_frames.size(), 
-                                                           idx, 
-                                                           m_thread.m_reg_context_sp,
-                                                           cfa,
-                                                           pc,
-                                                           NULL));
-                    m_frames.push_back (unwind_frame_sp);
                 }
                 else
                 {
@@ -162,6 +378,10 @@ StackFrameList::GetFramesUpTo(uint32_t e
         {
             StackFrameList *prev_frames = m_prev_frames_sp.get();
             StackFrameList *curr_frames = this;
+            
+            //curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth;
+            //curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc;
+            //printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);
 
 #if defined (DEBUG_STACK_FRAMES)
             s.PutCString("\nprev_frames:\n");
@@ -246,7 +466,12 @@ StackFrameList::GetNumFrames (bool can_c
 
     if (can_create)
         GetFramesUpTo (UINT32_MAX);
-    return m_frames.size();
+
+    uint32_t inlined_depth = GetCurrentInlinedDepth();
+    if (inlined_depth == UINT32_MAX)
+        return m_frames.size();
+    else
+        return m_frames.size() - inlined_depth;
 }
 
 void
@@ -278,50 +503,75 @@ StackFrameList::GetFrameAtIndex (uint32_
 {
     StackFrameSP frame_sp;
     Mutex::Locker locker (m_mutex);
+    uint32_t original_idx = idx;
+    
+    uint32_t inlined_depth = GetCurrentInlinedDepth();
+    if (inlined_depth != UINT32_MAX)
+        idx += inlined_depth;
+    
     if (idx < m_frames.size())
         frame_sp = m_frames[idx];
 
     if (frame_sp)
         return frame_sp;
         
-        // GetFramesUpTo will fill m_frames with as many frames as you asked for,
-        // if there are that many.  If there weren't then you asked for too many
-        // frames.
-        GetFramesUpTo (idx);
-        if (idx < m_frames.size())
+    // GetFramesUpTo will fill m_frames with as many frames as you asked for,
+    // if there are that many.  If there weren't then you asked for too many
+    // frames.
+    GetFramesUpTo (idx);
+    if (idx < m_frames.size())
+    {
+        if (m_show_inlined_frames)
         {
-            if (m_show_inlined_frames)
-            {
-                // When inline frames are enabled we actually create all the frames in GetFramesUpTo.
-                frame_sp = m_frames[idx];
-            }
-            else
+            // When inline frames are enabled we actually create all the frames in GetFramesUpTo.
+            frame_sp = m_frames[idx];
+        }
+        else
+        {
+            Unwind *unwinder = m_thread.GetUnwinder ();
+            if (unwinder)
             {
-                Unwind *unwinder = m_thread.GetUnwinder ();
-                if (unwinder)
+                addr_t pc, cfa;
+                if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
                 {
-                    addr_t pc, cfa;
-                    if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
+                    frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, pc, NULL));
+                    
+                    Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
+                    if (function)
                     {
-                        frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, pc, NULL));
-                        
-                        Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
-                        if (function)
-                        {
-                            // When we aren't showing inline functions we always use
-                            // the top most function block as the scope.
-                            frame_sp->SetSymbolContextScope (&function->GetBlock(false));
-                        }
-                        else 
-                        {
-                            // Set the symbol scope from the symbol regardless if it is NULL or valid.
-                            frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
-                        }
-                        SetFrameAtIndex(idx, frame_sp);
+                        // When we aren't showing inline functions we always use
+                        // the top most function block as the scope.
+                        frame_sp->SetSymbolContextScope (&function->GetBlock(false));
+                    }
+                    else 
+                    {
+                        // Set the symbol scope from the symbol regardless if it is NULL or valid.
+                        frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
                     }
+                    SetFrameAtIndex(idx, frame_sp);
                 }
             }
         }
+    }
+    else if (original_idx == 0)
+    {
+        // There should ALWAYS be a frame at index 0.  If something went wrong with the CurrentInlinedDepth such that
+        // there weren't as many frames as we thought taking that into account, then reset the current inlined depth
+        // and return the real zeroth frame.
+        if (m_frames.size() > 0)
+        {
+            ResetCurrentInlinedDepth();
+            frame_sp = m_frames[original_idx];
+        }
+        else
+        {
+            // Why do we have a thread with zero frames, that should not ever happen...
+            if (m_thread.IsValid())
+                assert ("A valid thread has no frames.");
+            
+        }
+    }
+    
     return frame_sp;
 }
 
@@ -345,19 +595,42 @@ StackFrameList::GetFrameWithConcreteFram
     return frame_sp;
 }
 
+static bool
+CompareStackID (const StackFrameSP &stack_sp, const StackID &stack_id)
+{
+    return stack_sp->GetStackID() < stack_id;
+}
+
 StackFrameSP
 StackFrameList::GetFrameWithStackID (const StackID &stack_id)
 {
-    uint32_t frame_idx = 0;
     StackFrameSP frame_sp;
-    do
+    
+    if (stack_id.IsValid())
     {
-        frame_sp = GetFrameAtIndex (frame_idx);
-        if (frame_sp && frame_sp->GetStackID() == stack_id)
-            break;
-        frame_idx++;
+        Mutex::Locker locker (m_mutex);
+        uint32_t frame_idx = 0;
+        // Do a binary search in case the stack frame is already in our cache
+        collection::const_iterator begin = m_frames.begin();
+        collection::const_iterator end = m_frames.end();
+        if (begin != end)
+        {
+            collection::const_iterator pos = std::lower_bound (begin, end, stack_id, CompareStackID);
+            if (pos != end && (*pos)->GetStackID() == stack_id)
+                return *pos;
+            
+            if (m_frames.back()->GetStackID() < stack_id)
+                frame_idx = m_frames.size();
+        }
+        do
+        {
+            frame_sp = GetFrameAtIndex (frame_idx);
+            if (frame_sp && frame_sp->GetStackID() == stack_id)
+                break;
+            frame_idx++;
+        }
+        while (frame_sp);
     }
-    while (frame_sp);
     return frame_sp;
 }
 
@@ -396,6 +669,9 @@ StackFrameList::SetSelectedFrame (lldb_p
         if (pos->get() == frame)
         {
             m_selected_frame_idx = std::distance (begin, pos);
+            uint32_t inlined_depth = GetCurrentInlinedDepth();
+            if (inlined_depth != UINT32_MAX)
+                m_selected_frame_idx -= inlined_depth;
             break;
         }
     }
@@ -464,7 +740,7 @@ StackFrameList::InvalidateFrames (uint32
 }
 
 void
-StackFrameList::Merge (std::auto_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
+StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
 {
     Mutex::Locker curr_locker (curr_ap.get() ? &curr_ap->m_mutex : NULL);
     Mutex::Locker prev_locker (prev_sp.get() ? &prev_sp->m_mutex : NULL);

Modified: lldb/branches/lldb-platform-work/source/Target/StackID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/StackID.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/StackID.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/StackID.cpp Thu Jun  6 19:06:43 2013
@@ -24,14 +24,14 @@ using namespace lldb_private;
 void
 StackID::Dump (Stream *s)
 {
-    s->Printf("StackID (pc = 0x%16.16llx, cfa = 0x%16.16llx, symbol_scope = %p", (uint64_t)m_pc, (uint64_t)m_cfa, m_symbol_scope);
+    s->Printf("StackID (pc = 0x%16.16" PRIx64 ", cfa = 0x%16.16" PRIx64 ", symbol_scope = %p", (uint64_t)m_pc, (uint64_t)m_cfa, m_symbol_scope);
     if (m_symbol_scope)
     {
         SymbolContext sc;
     
         m_symbol_scope->CalculateSymbolContext (&sc);
         if (sc.block)
-            s->Printf(" (Block {0x%8.8llx})", sc.block->GetID());
+            s->Printf(" (Block {0x%8.8" PRIx64 "})", sc.block->GetID());
         else if (sc.symbol)
             s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID());
     }

Modified: lldb/branches/lldb-platform-work/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/StopInfo.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/StopInfo.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/StopInfo.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Target/StopInfo.h"
 
 // C Includes
@@ -33,51 +35,65 @@ using namespace lldb;
 using namespace lldb_private;
 
 StopInfo::StopInfo (Thread &thread, uint64_t value) :
-    m_thread (thread),
+    m_thread_wp (thread.shared_from_this()),
     m_stop_id (thread.GetProcess()->GetStopID()),
     m_resume_id (thread.GetProcess()->GetResumeID()),
-    m_value (value)
+    m_value (value),
+    m_override_should_notify (eLazyBoolCalculate),
+    m_override_should_stop (eLazyBoolCalculate)
 {
 }
 
 bool
 StopInfo::IsValid () const
 {
-    return m_thread.GetProcess()->GetStopID() == m_stop_id;
+    ThreadSP thread_sp (m_thread_wp.lock());
+    if (thread_sp)
+        return thread_sp->GetProcess()->GetStopID() == m_stop_id;
+    return false;
 }
 
 void
 StopInfo::MakeStopInfoValid ()
 {
-    m_stop_id = m_thread.GetProcess()->GetStopID();
-    m_resume_id = m_thread.GetProcess()->GetResumeID();
+    ThreadSP thread_sp (m_thread_wp.lock());
+    if (thread_sp)
+    {
+        m_stop_id = thread_sp->GetProcess()->GetStopID();
+        m_resume_id = thread_sp->GetProcess()->GetResumeID();
+    }
 }
 
 bool
 StopInfo::HasTargetRunSinceMe ()
 {
-    lldb::StateType ret_type = m_thread.GetProcess()->GetPrivateState();
-    if (ret_type == eStateRunning)
-    {
-        return true;
-    }
-    else if (ret_type == eStateStopped)
+    ThreadSP thread_sp (m_thread_wp.lock());
+
+    if (thread_sp)
     {
-        // This is a little tricky.  We want to count "run and stopped again before you could
-        // ask this question as a "TRUE" answer to HasTargetRunSinceMe.  But we don't want to 
-        // include any running of the target done for expressions.  So we track both resumes,
-        // and resumes caused by expressions, and check if there are any resumes NOT caused
-        // by expressions.
-        
-        uint32_t curr_resume_id = m_thread.GetProcess()->GetResumeID();
-        uint32_t last_user_expression_id = m_thread.GetProcess()->GetLastUserExpressionResumeID ();
-        if (curr_resume_id == m_resume_id)
+        lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
+        if (ret_type == eStateRunning)
         {
-            return false;
+            return true;
         }
-        else if (curr_resume_id > last_user_expression_id)
+        else if (ret_type == eStateStopped)
         {
-            return true;
+            // This is a little tricky.  We want to count "run and stopped again before you could
+            // ask this question as a "TRUE" answer to HasTargetRunSinceMe.  But we don't want to 
+            // include any running of the target done for expressions.  So we track both resumes,
+            // and resumes caused by expressions, and check if there are any resumes NOT caused
+            // by expressions.
+            
+            uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
+            uint32_t last_user_expression_id = thread_sp->GetProcess()->GetLastUserExpressionResumeID ();
+            if (curr_resume_id == m_resume_id)
+            {
+                return false;
+            }
+            else if (curr_resume_id > last_user_expression_id)
+            {
+                return true;
+            }
         }
     }
     return false;
@@ -99,13 +115,11 @@ public:
         m_should_stop (false),
         m_should_stop_is_valid (false),
         m_should_perform_action (true),
-        m_address (LLDB_INVALID_ADDRESS)
+        m_address (LLDB_INVALID_ADDRESS),
+        m_break_id(LLDB_INVALID_BREAK_ID),
+        m_was_one_shot (false)
     {
-        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-        if (bp_site_sp)
-        {
-          m_address = bp_site_sp->GetLoadAddress();
-        }
+        StoreBPInfo();
     }
     
     StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
@@ -114,12 +128,33 @@ public:
         m_should_stop (should_stop),
         m_should_stop_is_valid (true),
         m_should_perform_action (true),
-        m_address (LLDB_INVALID_ADDRESS)
+        m_address (LLDB_INVALID_ADDRESS),
+        m_break_id(LLDB_INVALID_BREAK_ID),
+        m_was_one_shot (false)
+    {
+        StoreBPInfo();
+    }
+
+    void
+    StoreBPInfo ()
     {
-        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-        if (bp_site_sp)
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
         {
-          m_address = bp_site_sp->GetLoadAddress();
+            BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
+            if (bp_site_sp)
+            {
+                if (bp_site_sp->GetNumberOfOwners() == 1)
+                {
+                    BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
+                    if (bp_loc_sp)
+                    {
+                        m_break_id = bp_loc_sp->GetBreakpoint().GetID();
+                        m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot();
+                    }
+                }
+                m_address = bp_site_sp->GetLoadAddress();
+            }
         }
     }
 
@@ -136,30 +171,134 @@ public:
     virtual bool
     ShouldStopSynchronous (Event *event_ptr)
     {
-        if (!m_should_stop_is_valid)
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
         {
-            // Only check once if we should stop at a breakpoint
-            BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-            if (bp_site_sp)
+            if (!m_should_stop_is_valid)
             {
-                ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
-                StoppointCallbackContext context (event_ptr, exe_ctx, true);
-                m_should_stop = bp_site_sp->ShouldStop (&context);
+                // Only check once if we should stop at a breakpoint
+                BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
+                if (bp_site_sp)
+                {
+                    ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
+                    StoppointCallbackContext context (event_ptr, exe_ctx, true);
+                    m_should_stop = bp_site_sp->ShouldStop (&context);
+                }
+                else
+                {
+                    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+
+                    if (log)
+                        log->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
+
+                    m_should_stop = true;
+                }
+                m_should_stop_is_valid = true;
             }
-            else
+            return m_should_stop;
+        }
+        return false;
+    }
+    
+    virtual bool
+    DoShouldNotify (Event *event_ptr)
+    {
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+        {
+            BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
+            if (bp_site_sp)
             {
-                LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+                bool all_internal = true;
 
-                if (log)
-                    log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
+                for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
+                {
+                    if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
+                    {
+                        all_internal = false;
+                        break;
+                    }
+                }
+                return all_internal == false;
+            }
+        }
+        return true;
+    }
 
-                m_should_stop = true;
+    virtual const char *
+    GetDescription ()
+    {
+        if (m_description.empty())
+        {
+            ThreadSP thread_sp (m_thread_wp.lock());
+            if (thread_sp)
+            {
+                BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
+                if (bp_site_sp)
+                {
+                    StreamString strm;
+                    // If we have just hit an internal breakpoint, and it has a kind description, print that instead of the
+                    // full breakpoint printing:
+                    if (bp_site_sp->IsInternal())
+                    {
+                        size_t num_owners = bp_site_sp->GetNumberOfOwners();
+                        for (size_t idx = 0; idx < num_owners; idx++)
+                        {
+                            const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind();
+                            if (kind != NULL)
+                            {
+                                m_description.assign (kind);
+                                return kind;
+                            }
+                        }
+                    }
+                    
+                    strm.Printf("breakpoint ");
+                    bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
+                    m_description.swap (strm.GetString());
+                }
+                else
+                {
+                    StreamString strm;
+                    if (m_break_id != LLDB_INVALID_BREAK_ID)
+                    {
+                        BreakpointSP break_sp = thread_sp->GetProcess()->GetTarget().GetBreakpointByID(m_break_id);
+                        if (break_sp)
+                        {
+                            if (break_sp->IsInternal())
+                            {
+                                const char *kind = break_sp->GetBreakpointKind();
+                                if (kind)
+                                    strm.Printf ("internal %s breakpoint(%d).", kind, m_break_id);
+                                else
+                                    strm.Printf ("internal breakpoint(%d).", m_break_id);
+                            }
+                            else
+                            {
+                                strm.Printf ("breakpoint %d.", m_break_id);
+                            }
+                        } 
+                        else
+                        {
+                            if (m_was_one_shot)
+                                strm.Printf ("one-shot breakpoint %d", m_break_id);
+                            else
+                                strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
+                        }
+                    }
+                    else if (m_address == LLDB_INVALID_ADDRESS)
+                        strm.Printf("breakpoint site %" PRIi64 " which has been deleted - unknown address", m_value);
+                    else
+                        strm.Printf("breakpoint site %" PRIi64 " which has been deleted - was at 0x%" PRIx64, m_value, m_address);
+                    
+                    m_description.swap (strm.GetString());
+                }
             }
-            m_should_stop_is_valid = true;
         }
-        return m_should_stop;
+        return m_description.c_str();
     }
-    
+
+protected:
     bool
     ShouldStop (Event *event_ptr)
     {
@@ -176,200 +315,191 @@ public:
             return;
         m_should_perform_action = false;
         
-        LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
-        
-        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-        
-        if (bp_site_sp)
+        ThreadSP thread_sp (m_thread_wp.lock());
+
+        if (thread_sp)
         {
-            size_t num_owners = bp_site_sp->GetNumberOfOwners();
-                
-            if (num_owners == 0)
+            Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+            
+            if (!thread_sp->IsValid())
             {
+                // This shouldn't ever happen, but just in case, don't do more harm.
+                log->Printf ("PerformAction got called with an invalid thread.");
                 m_should_stop = true;
+                m_should_stop_is_valid = true;
+                return;
             }
-            else
+            
+            BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
+            
+            if (bp_site_sp)
             {
-                // We go through each location, and test first its condition.  If the condition says to stop,
-                // then we run the callback for that location.  If that callback says to stop as well, then 
-                // we set m_should_stop to true; we are going to stop.
-                // But we still want to give all the breakpoints whose conditions say we are going to stop a
-                // chance to run their callbacks.
-                // Of course if any callback restarts the target by putting "continue" in the callback, then 
-                // we're going to restart, without running the rest of the callbacks.  And in this case we will
-                // end up not stopping even if another location said we should stop.  But that's better than not
-                // running all the callbacks.
-                
-                m_should_stop = false;
-
-                ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
-                StoppointCallbackContext context (event_ptr, exe_ctx, false);
-
-                for (size_t j = 0; j < num_owners; j++)
+                size_t num_owners = bp_site_sp->GetNumberOfOwners();
+                    
+                if (num_owners == 0)
+                {
+                    m_should_stop = true;
+                }
+                else
                 {
-                    lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
-                                                      
-                    // First run the condition for the breakpoint.  If that says we should stop, then we'll run
-                    // the callback for the breakpoint.  If the callback says we shouldn't stop that will win.
+                    // We go through each location, and test first its condition.  If the condition says to stop,
+                    // then we run the callback for that location.  If that callback says to stop as well, then 
+                    // we set m_should_stop to true; we are going to stop.
+                    // But we still want to give all the breakpoints whose conditions say we are going to stop a
+                    // chance to run their callbacks.
+                    // Of course if any callback restarts the target by putting "continue" in the callback, then 
+                    // we're going to restart, without running the rest of the callbacks.  And in this case we will
+                    // end up not stopping even if another location said we should stop.  But that's better than not
+                    // running all the callbacks.
                     
-                    bool condition_says_stop = true;
-                    if (bp_loc_sp->GetConditionText() != NULL)
+                    m_should_stop = false;
+
+                    ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
+                    Process *process  = exe_ctx.GetProcessPtr();
+                    if (process->GetModIDRef().IsLastResumeForUserExpression())
                     {
-                        // We need to make sure the user sees any parse errors in their condition, so we'll hook the
-                        // constructor errors up to the debugger's Async I/O.
-                        
-                        ValueObjectSP result_valobj_sp;
+                        // If we are in the middle of evaluating an expression, don't run asynchronous breakpoint commands or
+                        // expressions.  That could lead to infinite recursion if the command or condition re-calls the function
+                        // with this breakpoint.
+                        // TODO: We can keep a list of the breakpoints we've seen while running expressions in the nested
+                        // PerformAction calls that can arise when the action runs a function that hits another breakpoint,
+                        // and only stop running commands when we see the same breakpoint hit a second time.
                         
-                        ExecutionResults result_code;
-                        ValueObjectSP result_value_sp;
-                        const bool discard_on_error = true;
-                        Error error;
-                        result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
-                                                                              eExecutionPolicyOnlyWhenNeeded,
-                                                                              lldb::eLanguageTypeUnknown,
-                                                                              ClangUserExpression::eResultTypeAny,
-                                                                              discard_on_error,
-                                                                              bp_loc_sp->GetConditionText(),
-                                                                              NULL,
-                                                                              result_value_sp,
-                                                                              error);
-                        if (result_code == eExecutionCompleted)
+                        m_should_stop_is_valid = true;
+                        if (log)
+                            log->Printf ("StopInfoBreakpoint::PerformAction - Hit a breakpoint while running an expression,"
+                                         " not running commands to avoid recursion.");
+                        bool ignoring_breakpoints = process->GetIgnoreBreakpointsInExpressions();
+                        if (ignoring_breakpoints)
                         {
-                            if (result_value_sp)
+                            m_should_stop = false;
+                            // Internal breakpoints will always stop.  
+                            for (size_t j = 0; j < num_owners; j++)
                             {
-                                Scalar scalar_value;
-                                if (result_value_sp->ResolveValue (scalar_value))
-                                {
-                                    if (scalar_value.ULongLong(1) == 0)
-                                        condition_says_stop = false;
-                                    else
-                                        condition_says_stop = true;
-                                    if (log)
-                                        log->Printf("Condition successfully evaluated, result is %s.\n", 
-                                                    m_should_stop ? "true" : "false");
-                                }
-                                else
+                                lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
+                                if (bp_loc_sp->GetBreakpoint().IsInternal())
                                 {
-                                    condition_says_stop = true;
-                                    if (log)
-                                        log->Printf("Failed to get an integer result from the expression.");
+                                    m_should_stop = true;
+                                    break;
                                 }
                             }
                         }
                         else
                         {
-                            Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
-                            StreamSP error_sp = debugger.GetAsyncErrorStream ();
-                            error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
-                            bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
-                            error_sp->Printf (": \"%s\"", 
-                                              bp_loc_sp->GetConditionText());
-                            error_sp->EOL();
-                            const char *err_str = error.AsCString("<Unknown Error>");
-                            if (log)
-                                log->Printf("Error evaluating condition: \"%s\"\n", err_str);
-                            
-                            error_sp->PutCString (err_str);
-                            error_sp->EOL();                       
-                            error_sp->Flush();
-                            // If the condition fails to be parsed or run, we should stop.
-                            condition_says_stop = true;
+                            m_should_stop = true;
                         }
+                        if (log)
+                            log->Printf ("StopInfoBreakpoint::PerformAction - in expression, continuing: %s.",
+                                         m_should_stop ? "true" : "false");
+                        process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: hit breakpoint while "
+                                               "running function, skipping commands and conditions to prevent recursion.");
+                        return;
                     }
-                                            
-                    // If this location's condition says we should aren't going to stop, 
-                    // then don't run the callback for this location.
-                    if (!condition_says_stop)
-                        continue;
-                                
-                    bool callback_says_stop;
-                    
-                    // FIXME: For now the callbacks have to run in async mode - the first time we restart we need
-                    // to get out of there.  So set it here.
-                    // When we figure out how to nest breakpoint hits then this will change.
                     
-                    Debugger &debugger = m_thread.CalculateTarget()->GetDebugger();
-                    bool old_async = debugger.GetAsyncExecution();
-                    debugger.SetAsyncExecution (true);
+                    StoppointCallbackContext context (event_ptr, exe_ctx, false);
                     
-                    callback_says_stop = bp_loc_sp->InvokeCallback (&context);
+                    // Let's copy the breakpoint locations out of the site and store them in a local list.  That way if
+                    // one of the breakpoint actions changes the site, then we won't be operating on a bad list.
                     
-                    debugger.SetAsyncExecution (old_async);
-                    
-                    if (callback_says_stop)
-                        m_should_stop = true;
-                        
-                    // Also make sure that the callback hasn't continued the target.  
-                    // If it did, when we'll set m_should_start to false and get out of here.
-                    if (HasTargetRunSinceMe ())
+                    BreakpointLocationCollection site_locations;
+                    for (size_t j = 0; j < num_owners; j++)
+                        site_locations.Add(bp_site_sp->GetOwnerAtIndex(j));
+
+                    for (size_t j = 0; j < num_owners; j++)
                     {
-                        m_should_stop = false;
-                        break;
+                        lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
+                        
+                        // If another action disabled this breakpoint or its location, then don't run the actions.
+                        if (!bp_loc_sp->IsEnabled() || !bp_loc_sp->GetBreakpoint().IsEnabled())
+                            continue;
+                        
+                        // The breakpoint site may have many locations associated with it, not all of them valid for
+                        // this thread.  Skip the ones that aren't:
+                        if (!bp_loc_sp->ValidForThisThread(thread_sp.get()))
+                            continue;
+                                                          
+                        // First run the condition for the breakpoint.  If that says we should stop, then we'll run
+                        // the callback for the breakpoint.  If the callback says we shouldn't stop that will win.                    
+                        
+                        if (bp_loc_sp->GetConditionText() != NULL)
+                        {
+                            Error condition_error;
+                            bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
+                            
+                            if (!condition_error.Success())
+                            {
+                                Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
+                                StreamSP error_sp = debugger.GetAsyncErrorStream ();
+                                error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
+                                bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
+                                error_sp->Printf (": \"%s\"",
+                                                  bp_loc_sp->GetConditionText());
+                                error_sp->EOL();
+                                const char *err_str = condition_error.AsCString("<Unknown Error>");
+                                if (log)
+                                    log->Printf("Error evaluating condition: \"%s\"\n", err_str);
+                                
+                                error_sp->PutCString (err_str);
+                                error_sp->EOL();
+                                error_sp->Flush();
+                                // If the condition fails to be parsed or run, we should stop.
+                                condition_says_stop = true;
+                            }
+                            else
+                            {
+                                if (!condition_says_stop)
+                                    continue;
+                            }
+                        }
+                                    
+                        bool callback_says_stop;
+                        
+                        // FIXME: For now the callbacks have to run in async mode - the first time we restart we need
+                        // to get out of there.  So set it here.
+                        // When we figure out how to nest breakpoint hits then this will change.
+                        
+                        Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
+                        bool old_async = debugger.GetAsyncExecution();
+                        debugger.SetAsyncExecution (true);
+                        
+                        callback_says_stop = bp_loc_sp->InvokeCallback (&context);
+                        
+                        debugger.SetAsyncExecution (old_async);
+                        
+                        if (callback_says_stop)
+                            m_should_stop = true;
+                        
+                        // If we are going to stop for this breakpoint, then remove the breakpoint.
+                        if (callback_says_stop && bp_loc_sp && bp_loc_sp->GetBreakpoint().IsOneShot())
+                        {
+                            thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID (bp_loc_sp->GetBreakpoint().GetID());
+                        }
+                            
+                        // Also make sure that the callback hasn't continued the target.  
+                        // If it did, when we'll set m_should_start to false and get out of here.
+                        if (HasTargetRunSinceMe ())
+                        {
+                            m_should_stop = false;
+                            break;
+                        }
                     }
                 }
-            }
-            // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again.
-            m_should_stop_is_valid = true;
-
-        }
-        else
-        {
-            m_should_stop = true;
-            m_should_stop_is_valid = true;
-            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
-            if (log)
-                log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
-        }
-        if (log)
-            log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
-    }
-        
-    virtual bool
-    ShouldNotify (Event *event_ptr)
-    {
-        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-        if (bp_site_sp)
-        {
-            bool all_internal = true;
-
-            for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
-            {
-                if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
-                {
-                    all_internal = false;
-                    break;
-                }
-            }
-            return all_internal == false;
-        }
-        return true;
-    }
+                // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again.
+                m_should_stop_is_valid = true;
 
-    virtual const char *
-    GetDescription ()
-    {
-        if (m_description.empty())
-        {
-            BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-            if (bp_site_sp)
-            {
-                StreamString strm;
-                strm.Printf("breakpoint ");
-                bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
-                m_description.swap (strm.GetString());
             }
             else
             {
-                StreamString strm;
-                if (m_address == LLDB_INVALID_ADDRESS)
-                    strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value);
-                else
-                    strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address);
-                m_description.swap (strm.GetString());
+                m_should_stop = true;
+                m_should_stop_is_valid = true;
+                Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+
+                if (log_process)
+                    log_process->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
             }
+            if (log)
+                log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
         }
-        return m_description.c_str();
     }
 
 private:
@@ -381,6 +511,8 @@ private:
     lldb::addr_t m_address;       // We use this to capture the breakpoint site address when we create the StopInfo,
                                   // in case somebody deletes it between the time the StopInfo is made and the
                                   // description is asked for.
+    lldb::break_id_t m_break_id;
+    bool m_was_one_shot;
 };
 
 
@@ -391,6 +523,36 @@ private:
 class StopInfoWatchpoint : public StopInfo
 {
 public:
+    // Make sure watchpoint is properly disabled and subsequently enabled while performing watchpoint actions.
+    class WatchpointSentry {
+    public:
+        WatchpointSentry(Process *p, Watchpoint *w):
+            process(p),
+            watchpoint(w)
+        {
+            if (process && watchpoint)
+            {
+                const bool notify = false;
+                watchpoint->TurnOnEphemeralMode();
+                process->DisableWatchpoint(watchpoint, notify);
+            }
+        }
+        ~WatchpointSentry()
+        {
+            if (process && watchpoint)
+            {
+                if (!watchpoint->IsDisabledDuringEphemeralMode())
+                {
+                    const bool notify = false;
+                    process->EnableWatchpoint(watchpoint, notify);
+                }
+                watchpoint->TurnOffEphemeralMode();
+            }
+        }
+    private:
+        Process *process;
+        Watchpoint *watchpoint;
+    };
 
     StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
         StopInfo(thread, watch_id),
@@ -410,8 +572,21 @@ public:
         return eStopReasonWatchpoint;
     }
 
+    virtual const char *
+    GetDescription ()
+    {
+        if (m_description.empty())
+        {
+            StreamString strm;
+            strm.Printf("watchpoint %" PRIi64, m_value);
+            m_description.swap (strm.GetString());
+        }
+        return m_description.c_str();
+    }
+
+protected:
     virtual bool
-    ShouldStop (Event *event_ptr)
+    ShouldStopSynchronous (Event *event_ptr)
     {
         // ShouldStop() method is idempotent and should not affect hit count.
         // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
@@ -423,240 +598,204 @@ public:
         if (m_should_stop_is_valid)
             return m_should_stop;
 
-        WatchpointSP wp_sp =
-            m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
-        if (wp_sp)
-        {
-            // Check if we should stop at a watchpoint.
-            ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
-            StoppointCallbackContext context (event_ptr, exe_ctx, true);
-            m_should_stop = wp_sp->ShouldStop (&context);
-        }
-        else
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
         {
-            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+            WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
+            if (wp_sp)
+            {
+                // Check if we should stop at a watchpoint.
+                ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
+                StoppointCallbackContext context (event_ptr, exe_ctx, true);
+                m_should_stop = wp_sp->ShouldStop (&context);
+            }
+            else
+            {
+                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
-            if (log)
-                log->Printf ("Process::%s could not find watchpoint location id: %lld...",
-                             __FUNCTION__, GetValue());
+                if (log)
+                    log->Printf ("Process::%s could not find watchpoint location id: %" PRId64 "...",
+                                 __FUNCTION__, GetValue());
 
-            m_should_stop = true;
+                m_should_stop = true;
+            }
         }
         m_should_stop_is_valid = true;
         return m_should_stop;
     }
     
-    // Perform any action that is associated with this stop.  This is done as the
-    // Event is removed from the event queue.
+    bool
+    ShouldStop (Event *event_ptr)
+    {
+        // This just reports the work done by PerformAction or the synchronous stop.  It should
+        // only ever get called after they have had a chance to run.
+        assert (m_should_stop_is_valid);
+        return m_should_stop;
+    }
+    
     virtual void
     PerformAction (Event *event_ptr)
     {
-        LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
         // We're going to calculate if we should stop or not in some way during the course of
         // this code.  Also by default we're going to stop, so set that here.
         m_should_stop = true;
         
-        WatchpointSP wp_sp =
-            m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
-        if (wp_sp)
-        {
-            ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
-            Process* process = exe_ctx.GetProcessPtr();
-            {
-                // check if this process is running on an architecture where watchpoints trigger
-				// before the associated instruction runs. if so, disable the WP, single-step and then
-				// re-enable the watchpoint
-                if (process)
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+        {
+
+            WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
+            if (wp_sp)
+            {
+                ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
+                Process* process = exe_ctx.GetProcessPtr();
+
+                // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions,
+                // and it is then enabled after we are finished.
+                WatchpointSentry sentry(process, wp_sp.get());
+
                 {
-                    uint32_t num; bool wp_triggers_after;
-                    if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
+                    // check if this process is running on an architecture where watchpoints trigger
+                    // before the associated instruction runs. if so, disable the WP, single-step and then
+                    // re-enable the watchpoint
+                    if (process)
                     {
-                        if (!wp_triggers_after)
+                        uint32_t num;
+                        bool wp_triggers_after;
+                        if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
                         {
-                            process->DisableWatchpoint(wp_sp.get());
-                            
-                            ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over
-                                                                                                    false, // abort_other_plans
-                                                                                                    true); // stop_other_threads
-                            new_plan->SetIsMasterPlan (true);
-                            new_plan->SetOkayToDiscard (false);
-                            process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
-                            process->Resume ();
-                            process->WaitForProcessToStop (NULL);
-                            process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
-                            MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above
-                            
-                            process->EnableWatchpoint(wp_sp.get());
+                            if (!wp_triggers_after)
+                            {
+                                ThreadPlan *new_plan = thread_sp->QueueThreadPlanForStepSingleInstruction(false, // step-over
+                                                                                                        false, // abort_other_plans
+                                                                                                        true); // stop_other_threads
+                                new_plan->SetIsMasterPlan (true);
+                                new_plan->SetOkayToDiscard (false);
+                                process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
+                                process->Resume ();
+                                process->WaitForProcessToStop (NULL);
+                                process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
+                                MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above
+                            }
                         }
                     }
                 }
-            }
 
-            // Record the snapshot of our watchpoint.
-            VariableSP var_sp;
-            ValueObjectSP valobj_sp;        
-            StackFrame *frame = exe_ctx.GetFramePtr();
-            if (frame)
-            {
-                if (!wp_sp->IsWatchVariable())
+                if (m_should_stop && wp_sp->GetConditionText() != NULL)
                 {
-                    // We are not watching a variable, just read from the process memory for the watched location.
-                    assert (process);
+                    // We need to make sure the user sees any parse errors in their condition, so we'll hook the
+                    // constructor errors up to the debugger's Async I/O.
+                    ExecutionResults result_code;
+                    ValueObjectSP result_value_sp;
+                    const bool unwind_on_error = true;
+                    const bool ignore_breakpoints = true;
                     Error error;
-                    uint64_t val = process->ReadUnsignedIntegerFromMemory(wp_sp->GetLoadAddress(),
-                                                                          wp_sp->GetByteSize(),
-                                                                          0,
-                                                                          error);
-                    if (log)
-                    {
-                        if (error.Success())
-                            log->Printf("Watchpoint snapshot val taken: 0x%llx\n", val);
-                        else
-                            log->Printf("Watchpoint snapshot val taking failed.\n");
-                    }                        
-                    wp_sp->SetNewSnapshotVal(val);
-                }
-                else if (!wp_sp->GetWatchSpec().empty())
-                {
-                    // Use our frame to evaluate the variable expression.
-                    Error error;
-                    uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
-                                                 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
-                    valobj_sp = frame->GetValueForVariableExpressionPath (wp_sp->GetWatchSpec().c_str(), 
-                                                                          eNoDynamicValues, 
-                                                                          expr_path_options,
-                                                                          var_sp,
-                                                                          error);
-                    if (valobj_sp)
-                    {
-                        // We're in business.
-                        StreamString ss;
-                        ValueObject::DumpValueObject(ss, valobj_sp.get());
-                        wp_sp->SetNewSnapshot(ss.GetString());
-                    }
-                    else
-                        wp_sp->SetNewSnapshot("snapshot attempt failed.");
-
-                    if (log)
-                        log->Printf("Watchpoint snapshot taken: '%s'\n", wp_sp->GetNewSnapshot().c_str());
-                }
-
-                // Now dump the snapshots we have taken.
-                Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
-                StreamSP output_sp = debugger.GetAsyncOutputStream ();
-                wp_sp->DumpSnapshots("!!! ", output_sp.get());
-                //output_sp->EOL();
-                output_sp->Flush();
-            }
-
-            if (m_should_stop && wp_sp->GetConditionText() != NULL)
-            {
-                // We need to make sure the user sees any parse errors in their condition, so we'll hook the
-                // constructor errors up to the debugger's Async I/O.
-                ExecutionResults result_code;
-                ValueObjectSP result_value_sp;
-                const bool discard_on_error = true;
-                Error error;
-                result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
-                                                                      eExecutionPolicyAlways,
-                                                                      lldb::eLanguageTypeUnknown,
-                                                                      ClangUserExpression::eResultTypeAny,
-                                                                      discard_on_error,
-                                                                      wp_sp->GetConditionText(),
-                                                                      NULL,
-                                                                      result_value_sp,
-                                                                      error,
-                                                                      500000);
-                if (result_code == eExecutionCompleted)
-                {
-                    if (result_value_sp)
+                    result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
+                                                                          eExecutionPolicyOnlyWhenNeeded,
+                                                                          lldb::eLanguageTypeUnknown,
+                                                                          ClangUserExpression::eResultTypeAny,
+                                                                          unwind_on_error,
+                                                                          ignore_breakpoints,
+                                                                          wp_sp->GetConditionText(),
+                                                                          NULL,
+                                                                          result_value_sp,
+                                                                          error,
+                                                                          true,
+                                                                          ClangUserExpression::kDefaultTimeout);
+                    if (result_code == eExecutionCompleted)
                     {
-                        Scalar scalar_value;
-                        if (result_value_sp->ResolveValue (scalar_value))
+                        if (result_value_sp)
                         {
-                            if (scalar_value.ULongLong(1) == 0)
+                            Scalar scalar_value;
+                            if (result_value_sp->ResolveValue (scalar_value))
                             {
-                                // We have been vetoed.  This takes precedence over querying
-                                // the watchpoint whether it should stop (aka ignore count and
-                                // friends).  See also StopInfoWatchpoint::ShouldStop() as well
-                                // as Process::ProcessEventData::DoOnRemoval().
-                                m_should_stop = false;
+                                if (scalar_value.ULongLong(1) == 0)
+                                {
+                                    // We have been vetoed.  This takes precedence over querying
+                                    // the watchpoint whether it should stop (aka ignore count and
+                                    // friends).  See also StopInfoWatchpoint::ShouldStop() as well
+                                    // as Process::ProcessEventData::DoOnRemoval().
+                                    m_should_stop = false;
+                                }
+                                else
+                                    m_should_stop = true;
+                                if (log)
+                                    log->Printf("Condition successfully evaluated, result is %s.\n", 
+                                                m_should_stop ? "true" : "false");
                             }
                             else
+                            {
                                 m_should_stop = true;
-                            if (log)
-                                log->Printf("Condition successfully evaluated, result is %s.\n", 
-                                            m_should_stop ? "true" : "false");
-                        }
-                        else
-                        {
-                            m_should_stop = true;
-                            if (log)
-                                log->Printf("Failed to get an integer result from the expression.");
+                                if (log)
+                                    log->Printf("Failed to get an integer result from the expression.");
+                            }
                         }
                     }
+                    else
+                    {
+                        Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
+                        StreamSP error_sp = debugger.GetAsyncErrorStream ();
+                        error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
+                        wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
+                        error_sp->Printf (": \"%s\"", 
+                                          wp_sp->GetConditionText());
+                        error_sp->EOL();
+                        const char *err_str = error.AsCString("<Unknown Error>");
+                        if (log)
+                            log->Printf("Error evaluating condition: \"%s\"\n", err_str);
+
+                        error_sp->PutCString (err_str);
+                        error_sp->EOL();                       
+                        error_sp->Flush();
+                        // If the condition fails to be parsed or run, we should stop.
+                        m_should_stop = true;
+                    }
                 }
-                else
-                {
-                    Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
-                    StreamSP error_sp = debugger.GetAsyncErrorStream ();
-                    error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
-                    wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
-                    error_sp->Printf (": \"%s\"", 
-                                      wp_sp->GetConditionText());
-                    error_sp->EOL();
-                    const char *err_str = error.AsCString("<Unknown Error>");
-                    if (log)
-                        log->Printf("Error evaluating condition: \"%s\"\n", err_str);
 
-                    error_sp->PutCString (err_str);
-                    error_sp->EOL();                       
-                    error_sp->Flush();
-                    // If the condition fails to be parsed or run, we should stop.
-                    m_should_stop = true;
+                // If the condition says to stop, we run the callback to further decide whether to stop.
+                if (m_should_stop)
+                {
+                    StoppointCallbackContext context (event_ptr, exe_ctx, false);
+                    bool stop_requested = wp_sp->InvokeCallback (&context);
+                    // Also make sure that the callback hasn't continued the target.  
+                    // If it did, when we'll set m_should_stop to false and get out of here.
+                    if (HasTargetRunSinceMe ())
+                        m_should_stop = false;
+                    
+                    if (m_should_stop && !stop_requested)
+                    {
+                        // We have been vetoed by the callback mechanism.
+                        m_should_stop = false;
+                    }
                 }
-            }
-
-            // If the condition says to stop, we run the callback to further decide whether to stop.
-            if (m_should_stop)
-            {
-                StoppointCallbackContext context (event_ptr, exe_ctx, false);
-                bool stop_requested = wp_sp->InvokeCallback (&context);
-                // Also make sure that the callback hasn't continued the target.  
-                // If it did, when we'll set m_should_stop to false and get out of here.
-                if (HasTargetRunSinceMe ())
-                    m_should_stop = false;
-                
-                if (m_should_stop && !stop_requested)
+                // Finally, if we are going to stop, print out the new & old values:
+                if (m_should_stop)
                 {
-                    // We have been vetoed by the callback mechanism.
-                    m_should_stop = false;
+                    wp_sp->CaptureWatchedValue(exe_ctx);
+                    
+                    Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
+                    StreamSP output_sp = debugger.GetAsyncOutputStream ();
+                    wp_sp->DumpSnapshots(output_sp.get());
+                    output_sp->EOL();
+                    output_sp->Flush();
                 }
+                
             }
-        }
-        else
-        {
-            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+            else
+            {
+                Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
+                if (log_process)
+                    log_process->Printf ("Process::%s could not find watchpoint id: %" PRId64 "...", __FUNCTION__, m_value);
+            }
             if (log)
-                log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value);
+                log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
+            
+            m_should_stop_is_valid = true;
         }
-        if (log)
-            log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
     }
         
-    virtual const char *
-    GetDescription ()
-    {
-        if (m_description.empty())
-        {
-            StreamString strm;
-            strm.Printf("watchpoint %lli", m_value);
-            m_description.swap (strm.GetString());
-        }
-        return m_description.c_str();
-    }
-
 private:
     std::string m_description;
     bool m_should_stop;
@@ -690,25 +829,55 @@ public:
     }
 
     virtual bool
+    ShouldStopSynchronous (Event *event_ptr)
+    {
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+            return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value);
+        return false;
+    }
+
+    virtual bool
     ShouldStop (Event *event_ptr)
     {
-        return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+            return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value);
+        return false;
     }
     
     
     // If should stop returns false, check if we should notify of this event
     virtual bool
-    ShouldNotify (Event *event_ptr)
+    DoShouldNotify (Event *event_ptr)
     {
-        return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+        {
+            bool should_notify = thread_sp->GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
+            if (should_notify)
+            {
+                StreamString strm;
+                strm.Printf ("thread %d received signal: %s",
+                             thread_sp->GetIndexID(),
+                             thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value));
+                Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData());
+            }
+            return should_notify;
+        }
+        return true;
     }
 
     
     virtual void
     WillResume (lldb::StateType resume_state)
     {
-        if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
-            m_thread.SetResumeSignal(m_value);
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+        {
+            if (thread_sp->GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
+                thread_sp->SetResumeSignal(m_value);
+        }
     }
 
     virtual const char *
@@ -716,13 +885,17 @@ public:
     {
         if (m_description.empty())
         {
-            StreamString strm;
-            const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
-            if (signal_name)
-                strm.Printf("signal %s", signal_name);
-            else
-                strm.Printf("signal %lli", m_value);
-            m_description.swap (strm.GetString());
+            ThreadSP thread_sp (m_thread_wp.lock());
+            if (thread_sp)
+            {
+                StreamString strm;
+                const char *signal_name = thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
+                if (signal_name)
+                    strm.Printf("signal %s", signal_name);
+                else
+                    strm.Printf("signal %" PRIi64, m_value);
+                m_description.swap (strm.GetString());
+            }
         }
         return m_description.c_str();
     }
@@ -841,11 +1014,65 @@ public:
     {
         return m_return_valobj_sp;
     }
+    
+protected:
+    virtual bool
+    ShouldStop (Event *event_ptr)
+    {
+        if (m_plan_sp)
+            return m_plan_sp->ShouldStop(event_ptr);
+        else
+            return StopInfo::ShouldStop(event_ptr);
+    }
 
 private:
     ThreadPlanSP m_plan_sp;
     ValueObjectSP m_return_valobj_sp;
 };
+    
+class StopInfoExec : public StopInfo
+{
+public:
+    
+    StopInfoExec (Thread &thread) :
+        StopInfo (thread, LLDB_INVALID_UID),
+        m_performed_action (false)
+    {
+    }
+    
+    virtual
+    ~StopInfoExec ()
+    {
+    }
+    
+    virtual StopReason
+    GetStopReason () const
+    {
+        return eStopReasonExec;
+    }
+    
+    virtual const char *
+    GetDescription ()
+    {
+        return "exec";
+    }
+protected:
+    
+    virtual void
+    PerformAction (Event *event_ptr)
+    {
+        // Only perform the action once
+        if (m_performed_action)
+            return;
+        m_performed_action = true;
+        ThreadSP thread_sp (m_thread_wp.lock());
+        if (thread_sp)
+            thread_sp->GetProcess()->DidExec();
+    }
+    
+    bool m_performed_action;
+};
+
 } // namespace lldb_private
 
 StopInfoSP
@@ -890,6 +1117,12 @@ StopInfo::CreateStopReasonWithException
     return StopInfoSP (new StopInfoException (thread, description));
 }
 
+StopInfoSP
+StopInfo::CreateStopReasonWithExec (Thread &thread)
+{
+    return StopInfoSP (new StopInfoExec (thread));
+}
+
 ValueObjectSP
 StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
 {

Modified: lldb/branches/lldb-platform-work/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Target.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Target.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Target.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Target/Target.h"
 
 // C Includes
@@ -22,6 +24,10 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Event.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/SourceManager.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/ValueObject.h"
@@ -31,6 +37,8 @@
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/OptionGroupWatchpoint.h"
+#include "lldb/Interpreter/OptionValues.h"
+#include "lldb/Interpreter/Property.h"
 #include "lldb/lldb-private-log.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Process.h"
@@ -52,14 +60,14 @@ Target::GetStaticBroadcasterClass ()
 // Target constructor
 //----------------------------------------------------------------------
 Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp) :
-    Broadcaster (&debugger, "lldb.target"),
+    TargetProperties (this),
+    Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()),
     ExecutionContextScope (),
-    TargetInstanceSettings (GetSettingsController()),
     m_debugger (debugger),
     m_platform_sp (platform_sp),
     m_mutex (Mutex::eMutexTypeRecursive), 
     m_arch (target_arch),
-    m_images (),
+    m_images (this),
     m_section_load_list (),
     m_breakpoint_list (false),
     m_internal_breakpoint_list (true),
@@ -68,11 +76,11 @@ Target::Target(Debugger &debugger, const
     m_valid (true),
     m_search_filter_sp (),
     m_image_search_paths (ImageSearchPathsChanged, this),
-    m_scratch_ast_context_ap (NULL),
-    m_scratch_ast_source_ap (NULL),
-    m_ast_importer_ap (NULL),
+    m_scratch_ast_context_ap (),
+    m_scratch_ast_source_ap (),
+    m_ast_importer_ap (),
     m_persistent_variables (),
-    m_source_manager(*this),
+    m_source_manager_ap(),
     m_stop_hooks (),
     m_stop_hook_next_id (0),
     m_suppress_stop_hooks (false),
@@ -81,12 +89,18 @@ Target::Target(Debugger &debugger, const
     SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
     SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
     SetEventName (eBroadcastBitModulesUnloaded, "modules-unloaded");
+    SetEventName (eBroadcastBitWatchpointChanged, "watchpoint-changed");
+    SetEventName (eBroadcastBitSymbolsLoaded, "symbols-loaded");
     
     CheckInWithManager();
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Target::Target()", this);
+    if (m_arch.IsValid())
+    {
+        LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+    }
 }
 
 //----------------------------------------------------------------------
@@ -94,7 +108,7 @@ Target::Target(Debugger &debugger, const
 //----------------------------------------------------------------------
 Target::~Target()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Target::~Target()", this);
     DeleteCurrentProcess ();
@@ -125,6 +139,21 @@ Target::Dump (Stream *s, lldb::Descripti
 }
 
 void
+Target::CleanupProcess ()
+{
+    // Do any cleanup of the target we need to do between process instances.
+    // NB It is better to do this before destroying the process in case the
+    // clean up needs some help from the process.
+    m_breakpoint_list.ClearAllBreakpointSites();
+    m_internal_breakpoint_list.ClearAllBreakpointSites();
+    // Disable watchpoints just on the debugger side.
+    Mutex::Locker locker;
+    this->GetWatchpointList().GetListMutex(locker);
+    DisableAllWatchpoints(false);
+    ClearAllWatchpointHitCounts();
+}
+
+void
 Target::DeleteCurrentProcess ()
 {
     if (m_process_sp.get())
@@ -135,16 +164,8 @@ Target::DeleteCurrentProcess ()
         
         m_process_sp->Finalize();
 
-        // Do any cleanup of the target we need to do between process instances.
-        // NB It is better to do this before destroying the process in case the
-        // clean up needs some help from the process.
-        m_breakpoint_list.ClearAllBreakpointSites();
-        m_internal_breakpoint_list.ClearAllBreakpointSites();
-        // Disable watchpoints just on the debugger side.
-        Mutex::Locker locker;
-        this->GetWatchpointList().GetListMutex(locker);
-        DisableAllWatchpoints(false);
-        ClearAllWatchpointHitCounts();
+        CleanupProcess ();
+
         m_process_sp.reset();
     }
 }
@@ -224,9 +245,9 @@ Target::GetBreakpointByID (break_id_t br
 
 BreakpointSP
 Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
-                  const FileSpecList *source_file_spec_list,
-                  RegularExpression &source_regex,
-                  bool internal)
+                                     const FileSpecList *source_file_spec_list,
+                                     RegularExpression &source_regex,
+                                     bool internal)
 {
     SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
     BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex));
@@ -238,14 +259,51 @@ BreakpointSP
 Target::CreateBreakpoint (const FileSpecList *containingModules,
                           const FileSpec &file,
                           uint32_t line_no,
-                          bool check_inlines,
+                          LazyBool check_inlines,
                           LazyBool skip_prologue,
                           bool internal)
 {
-    SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
-    
-    BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL, file, line_no, check_inlines,
-                                                                     skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
+    if (check_inlines == eLazyBoolCalculate)
+    {
+        const InlineStrategy inline_strategy = GetInlineStrategy();
+        switch (inline_strategy)
+        {
+            case eInlineBreakpointsNever:
+                check_inlines = eLazyBoolNo;
+                break;
+                
+            case eInlineBreakpointsHeaders:
+                if (file.IsSourceImplementationFile())
+                    check_inlines = eLazyBoolNo;
+                else
+                    check_inlines = eLazyBoolYes;
+                break;
+
+            case eInlineBreakpointsAlways:
+                check_inlines = eLazyBoolYes;
+                break;
+        }
+    }
+    SearchFilterSP filter_sp;
+    if (check_inlines == eLazyBoolNo)
+    {
+        // Not checking for inlines, we are looking only for matching compile units
+        FileSpecList compile_unit_list;
+        compile_unit_list.Append (file);
+        filter_sp = GetSearchFilterForModuleAndCUList (containingModules, &compile_unit_list);
+    }
+    else
+    {
+        filter_sp = GetSearchFilterForModuleList (containingModules);
+    }
+    if (skip_prologue == eLazyBoolCalculate)
+        skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+
+    BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL,
+                                                                     file,
+                                                                     line_no,
+                                                                     check_inlines,
+                                                                     skip_prologue));
     return CreateBreakpoint (filter_sp, resolver_sp, internal);
 }
 
@@ -288,12 +346,15 @@ Target::CreateBreakpoint (const FileSpec
     if (func_name)
     {
         SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
-        
+
+        if (skip_prologue == eLazyBoolCalculate)
+            skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+
         BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, 
                                                                       func_name, 
                                                                       func_name_type_mask, 
                                                                       Breakpoint::Exact, 
-                                                                      skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
+                                                                      skip_prologue));
         bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal);
     }
     return bp_sp;
@@ -312,11 +373,14 @@ Target::CreateBreakpoint (const FileSpec
     if (num_names > 0)
     {
         SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
-        
-        BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, 
+
+        if (skip_prologue == eLazyBoolCalculate)
+            skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+
+        BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
                                                                       func_names,
                                                                       func_name_type_mask,
-                                                                      skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
+                                                                      skip_prologue));
         bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal);
     }
     return bp_sp;
@@ -336,11 +400,14 @@ Target::CreateBreakpoint (const FileSpec
     {
         SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
         
-        BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, 
+        if (skip_prologue == eLazyBoolCalculate)
+            skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+
+        BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
                                                                       func_names,
                                                                       num_names, 
                                                                       func_name_type_mask,
-                                                                      skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
+                                                                      skip_prologue));
         bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal);
     }
     return bp_sp;
@@ -441,7 +508,7 @@ Target::CreateBreakpoint (SearchFilterSP
         else
             m_breakpoint_list.Add (bp_sp, true);
 
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
         if (log)
         {
             StreamString s;
@@ -484,12 +551,12 @@ CheckIfWatchpointsExhausted(Target *targ
 // See also Watchpoint::SetWatchpointType(uint32_t type) and
 // the OptionGroupWatchpoint::WatchType enum type.
 WatchpointSP
-Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type, Error &error)
+Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const ClangASTType *type, uint32_t kind, Error &error)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
-        log->Printf("Target::%s (addr = 0x%8.8llx size = %zu type = %u)\n",
-                    __FUNCTION__, addr, size, type);
+        log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64 " type = %u)\n",
+                    __FUNCTION__, addr, (uint64_t)size, kind);
 
     WatchpointSP wp_sp;
     if (!ProcessIsValid())
@@ -502,7 +569,7 @@ Target::CreateWatchpoint(lldb::addr_t ad
         if (size == 0)
             error.SetErrorString("cannot set a watchpoint with watch_size of 0");
         else
-            error.SetErrorStringWithFormat("invalid watch address: %llu", addr);
+            error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);
         return wp_sp;
     }
 
@@ -510,6 +577,7 @@ Target::CreateWatchpoint(lldb::addr_t ad
     // of watchpoints limited by the hardware which the inferior is running on.
 
     // Grab the list mutex while doing operations.
+    const bool notify = false;   // Don't notify about all the state changes we do on creating the watchpoint.
     Mutex::Locker locker;
     this->GetWatchpointList().GetListMutex(locker);
     WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
@@ -520,39 +588,35 @@ Target::CreateWatchpoint(lldb::addr_t ad
             (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |
             (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0);
         // Return the existing watchpoint if both size and type match.
-        if (size == old_size && type == old_type) {
+        if (size == old_size && kind == old_type) {
             wp_sp = matched_sp;
-            wp_sp->SetEnabled(false);
+            wp_sp->SetEnabled(false, notify);
         } else {
             // Nil the matched watchpoint; we will be creating a new one.
-            m_process_sp->DisableWatchpoint(matched_sp.get());
-            m_watchpoint_list.Remove(matched_sp->GetID());
+            m_process_sp->DisableWatchpoint(matched_sp.get(), notify);
+            m_watchpoint_list.Remove(matched_sp->GetID(), true);
         }
     }
 
-    if (!wp_sp) {
-        Watchpoint *new_wp = new Watchpoint(addr, size);
-        if (!new_wp) {
-            printf("Watchpoint ctor failed, out of memory?\n");
-            return wp_sp;
-        }
-        new_wp->SetWatchpointType(type);
-        new_wp->SetTarget(this);
-        wp_sp.reset(new_wp);
-        m_watchpoint_list.Add(wp_sp);
+    if (!wp_sp) 
+    {
+        wp_sp.reset(new Watchpoint(*this, addr, size, type));
+        wp_sp->SetWatchpointType(kind, notify);
+        m_watchpoint_list.Add (wp_sp, true);
     }
 
-    error = m_process_sp->EnableWatchpoint(wp_sp.get());
+    error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
     if (log)
-            log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
-                        __FUNCTION__,
-                        error.Success() ? "succeeded" : "failed",
-                        wp_sp->GetID());
+        log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
+                    __FUNCTION__,
+                    error.Success() ? "succeeded" : "failed",
+                    wp_sp->GetID());
 
-    if (error.Fail()) {
+    if (error.Fail()) 
+    {
         // Enabling the watchpoint on the device side failed.
         // Remove the said watchpoint from the list maintained by the target instance.
-        m_watchpoint_list.Remove(wp_sp->GetID());
+        m_watchpoint_list.Remove (wp_sp->GetID(), true);
         // See if we could provide more helpful error message.
         if (!CheckIfWatchpointsExhausted(this, error))
         {
@@ -569,7 +633,7 @@ Target::CreateWatchpoint(lldb::addr_t ad
 void
 Target::RemoveAllBreakpoints (bool internal_also)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
 
@@ -583,7 +647,7 @@ Target::RemoveAllBreakpoints (bool inter
 void
 Target::DisableAllBreakpoints (bool internal_also)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
 
@@ -595,7 +659,7 @@ Target::DisableAllBreakpoints (bool inte
 void
 Target::EnableAllBreakpoints (bool internal_also)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
 
@@ -607,7 +671,7 @@ Target::EnableAllBreakpoints (bool inter
 bool
 Target::RemoveBreakpointByID (break_id_t break_id)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
 
@@ -632,7 +696,7 @@ Target::RemoveBreakpointByID (break_id_t
 bool
 Target::DisableBreakpointByID (break_id_t break_id)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
 
@@ -653,7 +717,7 @@ Target::DisableBreakpointByID (break_id_
 bool
 Target::EnableBreakpointByID (break_id_t break_id)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf ("Target::%s (break_id = %i, internal = %s)\n",
                      __FUNCTION__,
@@ -683,12 +747,12 @@ Target::EnableBreakpointByID (break_id_t
 bool
 Target::RemoveAllWatchpoints (bool end_to_end)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s\n", __FUNCTION__);
 
     if (!end_to_end) {
-        m_watchpoint_list.RemoveAll();
+        m_watchpoint_list.RemoveAll(true);
         return true;
     }
 
@@ -708,7 +772,7 @@ Target::RemoveAllWatchpoints (bool end_t
         if (rc.Fail())
             return false;
     }
-    m_watchpoint_list.RemoveAll ();
+    m_watchpoint_list.RemoveAll (true);
     return true; // Success!
 }
 
@@ -717,7 +781,7 @@ Target::RemoveAllWatchpoints (bool end_t
 bool
 Target::DisableAllWatchpoints (bool end_to_end)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s\n", __FUNCTION__);
 
@@ -750,7 +814,7 @@ Target::DisableAllWatchpoints (bool end_
 bool
 Target::EnableAllWatchpoints (bool end_to_end)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s\n", __FUNCTION__);
 
@@ -782,7 +846,7 @@ Target::EnableAllWatchpoints (bool end_t
 bool
 Target::ClearAllWatchpointHitCounts ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s\n", __FUNCTION__);
 
@@ -803,7 +867,7 @@ Target::ClearAllWatchpointHitCounts ()
 bool
 Target::IgnoreAllWatchpoints (uint32_t ignore_count)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s\n", __FUNCTION__);
 
@@ -826,7 +890,7 @@ Target::IgnoreAllWatchpoints (uint32_t i
 bool
 Target::DisableWatchpointByID (lldb::watch_id_t watch_id)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
@@ -849,7 +913,7 @@ Target::DisableWatchpointByID (lldb::wat
 bool
 Target::EnableWatchpointByID (lldb::watch_id_t watch_id)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
@@ -872,13 +936,13 @@ Target::EnableWatchpointByID (lldb::watc
 bool
 Target::RemoveWatchpointByID (lldb::watch_id_t watch_id)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
     if (DisableWatchpointByID (watch_id))
     {
-        m_watchpoint_list.Remove(watch_id);
+        m_watchpoint_list.Remove(watch_id, true);
         return true;
     }
     return false;
@@ -888,7 +952,7 @@ Target::RemoveWatchpointByID (lldb::watc
 bool
 Target::IgnoreWatchpointByID (lldb::watch_id_t watch_id, uint32_t ignore_count)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
@@ -916,9 +980,27 @@ Target::GetExecutableModulePointer ()
     return m_images.GetModulePointerAtIndex(0);
 }
 
+static void
+LoadScriptingResourceForModule (const ModuleSP &module_sp, Target *target)
+{
+    Error error;
+    StreamString feedback_stream;
+    if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error, &feedback_stream))
+    {
+        if (error.AsCString())
+            target->GetDebugger().GetErrorStream().Printf("unable to load scripting data for module %s - error reported was %s\n",
+                                                           module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
+                                                           error.AsCString());
+        if (feedback_stream.GetSize())
+            target->GetDebugger().GetOutputStream().Printf("%s\n",
+                                                           feedback_stream.GetData());
+    }
+}
+
 void
 Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
 {
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
     m_images.Clear();
     m_scratch_ast_context_ap.reset();
     m_scratch_ast_source_ap.reset();
@@ -927,16 +1009,19 @@ Target::SetExecutableModule (ModuleSP& e
     if (executable_sp.get())
     {
         Timer scoped_timer (__PRETTY_FUNCTION__,
-                            "Target::SetExecutableModule (executable = '%s/%s')",
-                            executable_sp->GetFileSpec().GetDirectory().AsCString(),
-                            executable_sp->GetFileSpec().GetFilename().AsCString());
+                            "Target::SetExecutableModule (executable = '%s')",
+                            executable_sp->GetFileSpec().GetPath().c_str());
 
         m_images.Append(executable_sp); // The first image is our exectuable file
 
         // If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
         if (!m_arch.IsValid())
+        {
             m_arch = executable_sp->GetArchitecture();
-        
+            if (log)
+              log->Printf ("Target::SetExecutableModule setting architecture to %s (%s) based on executable file", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+        }
+
         FileSpecList dependent_files;
         ObjectFile *executable_objfile = executable_sp->GetObjectFile();
 
@@ -963,26 +1048,29 @@ Target::SetExecutableModule (ModuleSP& e
             }
         }
     }
-
-    UpdateInstanceName();
 }
 
 
 bool
 Target::SetArchitecture (const ArchSpec &arch_spec)
 {
-    if (m_arch == arch_spec || !m_arch.IsValid())
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
+    if (m_arch.IsCompatibleMatch(arch_spec) || !m_arch.IsValid())
     {
         // If we haven't got a valid arch spec, or the architectures are
         // compatible, so just update the architecture. Architectures can be
         // equal, yet the triple OS and vendor might change, so we need to do
         // the assignment here just in case.
         m_arch = arch_spec;
+        if (log)
+            log->Printf ("Target::SetArchitecture setting architecture to %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
         return true;
     }
     else
     {
         // If we have an executable file, try to reset the executable to the desired architecture
+        if (log)
+          log->Printf ("Target::SetArchitecture changing architecture to %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
         m_arch = arch_spec;
         ModuleSP executable_sp = GetExecutableModule ();
         m_images.Clear();
@@ -993,6 +1081,8 @@ Target::SetArchitecture (const ArchSpec
         
         if (executable_sp)
         {
+            if (log)
+              log->Printf("Target::SetArchitecture Trying to select executable file architecture %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
             ModuleSpec module_spec (executable_sp->GetFileSpec(), arch_spec);
             Error error = ModuleList::GetSharedModule (module_spec, 
                                                        executable_sp, 
@@ -1011,16 +1101,31 @@ Target::SetArchitecture (const ArchSpec
 }
 
 void
-Target::ModuleAdded (ModuleSP &module_sp)
+Target::WillClearList (const ModuleList& module_list)
+{
+}
+
+void
+Target::ModuleAdded (const ModuleList& module_list, const ModuleSP &module_sp)
+{
+    // A module is being added to this target for the first time
+    ModuleList my_module_list;
+    my_module_list.Append(module_sp);
+    LoadScriptingResourceForModule(module_sp, this);
+    ModulesDidLoad (my_module_list);
+}
+
+void
+Target::ModuleRemoved (const ModuleList& module_list, const ModuleSP &module_sp)
 {
     // A module is being added to this target for the first time
-    ModuleList module_list;
-    module_list.Append(module_sp);
-    ModulesDidLoad (module_list);
+    ModuleList my_module_list;
+    my_module_list.Append(module_sp);
+    ModulesDidUnload (my_module_list);
 }
 
 void
-Target::ModuleUpdated (ModuleSP &old_module_sp, ModuleSP &new_module_sp)
+Target::ModuleUpdated (const ModuleList& module_list, const ModuleSP &old_module_sp, const ModuleSP &new_module_sp)
 {
     // A module is replacing an already added module
     m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, new_module_sp);
@@ -1029,31 +1134,49 @@ Target::ModuleUpdated (ModuleSP &old_mod
 void
 Target::ModulesDidLoad (ModuleList &module_list)
 {
-    m_breakpoint_list.UpdateBreakpoints (module_list, true);
-    // TODO: make event data that packages up the module_list
-    BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
+    if (module_list.GetSize())
+    {
+        m_breakpoint_list.UpdateBreakpoints (module_list, true);
+        // TODO: make event data that packages up the module_list
+        BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
+    }
 }
 
 void
-Target::ModulesDidUnload (ModuleList &module_list)
+Target::SymbolsDidLoad (ModuleList &module_list)
 {
-    m_breakpoint_list.UpdateBreakpoints (module_list, false);
-
-    // Remove the images from the target image list
-    m_images.Remove(module_list);
-
-    // TODO: make event data that packages up the module_list
-    BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
+    if (module_list.GetSize())
+    {
+        if (m_process_sp)
+        {
+            LanguageRuntime* runtime = m_process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+            if (runtime)
+            {
+                ObjCLanguageRuntime *objc_runtime = (ObjCLanguageRuntime*)runtime;
+                objc_runtime->SymbolsDidLoad(module_list);
+            }
+        }
+        
+        m_breakpoint_list.UpdateBreakpoints (module_list, true);
+        BroadcastEvent(eBroadcastBitSymbolsLoaded, NULL);
+    }
 }
 
+void
+Target::ModulesDidUnload (ModuleList &module_list)
+{
+    if (module_list.GetSize())
+    {
+        m_breakpoint_list.UpdateBreakpoints (module_list, false);
+        // TODO: make event data that packages up the module_list
+        BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
+    }
+}
 
 bool
 Target::ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_file_spec)
 {
-
-    if (!m_breakpoints_use_platform_avoid)
-        return false;
-    else
+    if (GetBreakpointsConsultPlatformAvoidList())
     {
         ModuleList matchingModules;
         ModuleSpec module_spec (module_file_spec);
@@ -1070,22 +1193,19 @@ Target::ModuleIsExcludedForNonModuleSpec
             }
             return true;
         }
-        else
-            return false;
     }
+    return false;
 }
 
 bool
 Target::ModuleIsExcludedForNonModuleSpecificSearches (const lldb::ModuleSP &module_sp)
 {
-    if (!m_breakpoints_use_platform_avoid)
-        return false;
-    else if (GetPlatform())
+    if (GetBreakpointsConsultPlatformAvoidList())
     {
-        return GetPlatform()->ModuleIsExcludedForNonModuleSpecificSearches (*this, module_sp);
+        if (m_platform_sp)
+            return m_platform_sp->ModuleIsExcludedForNonModuleSpecificSearches (*this, module_sp);
     }
-    else
-        return false;
+    return false;
 }
 
 size_t
@@ -1186,12 +1306,12 @@ Target::ReadMemory (const Address& addr,
         {
             ModuleSP addr_module_sp (resolved_addr.GetModule());
             if (addr_module_sp && addr_module_sp->GetFileSpec())
-                error.SetErrorStringWithFormat("%s[0x%llx] can't be resolved, %s in not currently loaded", 
+                error.SetErrorStringWithFormat("%s[0x%" PRIx64 "] can't be resolved, %s in not currently loaded",
                                                addr_module_sp->GetFileSpec().GetFilename().AsCString(), 
                                                resolved_addr.GetFileAddress(),
                                                addr_module_sp->GetFileSpec().GetFilename().AsCString());
             else
-                error.SetErrorStringWithFormat("0x%llx can't be resolved", resolved_addr.GetFileAddress());
+                error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved", resolved_addr.GetFileAddress());
         }
         else
         {
@@ -1201,9 +1321,9 @@ Target::ReadMemory (const Address& addr,
                 if (error.Success())
                 {
                     if (bytes_read == 0)
-                        error.SetErrorStringWithFormat("read memory from 0x%llx failed", load_addr);
+                        error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", load_addr);
                     else
-                        error.SetErrorStringWithFormat("only %zu of %zu bytes were read from memory at 0x%llx", bytes_read, dst_len, load_addr);
+                        error.SetErrorStringWithFormat("only %" PRIu64 " of %" PRIu64 " bytes were read from memory at 0x%" PRIx64, (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
                 }
             }
             if (bytes_read)
@@ -1232,6 +1352,82 @@ Target::ReadMemory (const Address& addr,
 }
 
 size_t
+Target::ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error)
+{
+    char buf[256];
+    out_str.clear();
+    addr_t curr_addr = addr.GetLoadAddress(this);
+    Address address(addr);
+    while (1)
+    {
+        size_t length = ReadCStringFromMemory (address, buf, sizeof(buf), error);
+        if (length == 0)
+            break;
+        out_str.append(buf, length);
+        // If we got "length - 1" bytes, we didn't get the whole C string, we
+        // need to read some more characters
+        if (length == sizeof(buf) - 1)
+            curr_addr += length;
+        else
+            break;
+        address = Address(curr_addr);
+    }
+    return out_str.size();
+}
+
+
+size_t
+Target::ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error)
+{
+    size_t total_cstr_len = 0;
+    if (dst && dst_max_len)
+    {
+        result_error.Clear();
+        // NULL out everything just to be safe
+        memset (dst, 0, dst_max_len);
+        Error error;
+        addr_t curr_addr = addr.GetLoadAddress(this);
+        Address address(addr);
+        const size_t cache_line_size = 512;
+        size_t bytes_left = dst_max_len - 1;
+        char *curr_dst = dst;
+        
+        while (bytes_left > 0)
+        {
+            addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
+            addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+            size_t bytes_read = ReadMemory (address, false, curr_dst, bytes_to_read, error);
+            
+            if (bytes_read == 0)
+            {
+                result_error = error;
+                dst[total_cstr_len] = '\0';
+                break;
+            }
+            const size_t len = strlen(curr_dst);
+            
+            total_cstr_len += len;
+            
+            if (len < bytes_to_read)
+                break;
+            
+            curr_dst += bytes_read;
+            curr_addr += bytes_read;
+            bytes_left -= bytes_read;
+            address = Address(curr_addr);
+        }
+    }
+    else
+    {
+        if (dst == NULL)
+            result_error.SetErrorString("invalid arguments");
+        else
+            result_error.Clear();
+    }
+    return total_cstr_len;
+}
+
+size_t
 Target::ReadScalarIntegerFromMemory (const Address& addr, 
                                      bool prefer_file_cache,
                                      uint32_t byte_size, 
@@ -1247,7 +1443,7 @@ Target::ReadScalarIntegerFromMemory (con
         if (bytes_read == byte_size)
         {
             DataExtractor data (&uval, sizeof(uval), m_arch.GetByteOrder(), m_arch.GetAddressByteSize());
-            uint32_t offset = 0;
+            lldb::offset_t offset = 0;
             if (byte_size <= 4)
                 scalar = data.GetMaxU32 (&offset, byte_size);
             else
@@ -1374,7 +1570,7 @@ Target::GetSharedModule (const ModuleSpe
                 error = ModuleList::GetSharedModule (module_spec,
                                                      module_sp, 
                                                      &GetExecutableSearchPaths(),
-                                                     &old_module_sp, 
+                                                     &old_module_sp,
                                                      &did_create_module);
             }
 
@@ -1388,7 +1584,7 @@ Target::GetSharedModule (const ModuleSpe
                     error = m_platform_sp->GetSharedModule (module_spec, 
                                                             module_sp, 
                                                             &GetExecutableSearchPaths(),
-                                                            &old_module_sp, 
+                                                            &old_module_sp,
                                                             &did_create_module);
                 }
                 else
@@ -1402,40 +1598,63 @@ Target::GetSharedModule (const ModuleSpe
         // module in the list already, and if there was, let's remove it.
         if (module_sp)
         {
-            // GetSharedModule is not guaranteed to find the old shared module, for instance
-            // in the common case where you pass in the UUID, it is only going to find the one
-            // module matching the UUID.  In fact, it has no good way to know what the "old module"
-            // relevant to this target is, since there might be many copies of a module with this file spec
-            // in various running debug sessions, but only one of them will belong to this target.
-            // So let's remove the UUID from the module list, and look in the target's module list.
-            // Only do this if there is SOMETHING else in the module spec...
-            if (!old_module_sp)
+            ObjectFile *objfile = module_sp->GetObjectFile();
+            if (objfile)
             {
-                if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
+                switch (objfile->GetType())
+                {
+                    case ObjectFile::eTypeCoreFile:      /// A core file that has a checkpoint of a program's execution state
+                    case ObjectFile::eTypeExecutable:    /// A normal executable
+                    case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker executable
+                    case ObjectFile::eTypeObjectFile:    /// An intermediate object file
+                    case ObjectFile::eTypeSharedLibrary: /// A shared library that can be used during execution
+                        break;
+                    case ObjectFile::eTypeDebugInfo:     /// An object file that contains only debug information
+                        if (error_ptr)
+                            error_ptr->SetErrorString("debug info files aren't valid target modules, please specify an executable");
+                        return ModuleSP();
+                    case ObjectFile::eTypeStubLibrary:   /// A library that can be linked against but not used for execution
+                        if (error_ptr)
+                            error_ptr->SetErrorString("stub libraries aren't valid target modules, please specify an executable");
+                        return ModuleSP();
+                    default:
+                        if (error_ptr)
+                            error_ptr->SetErrorString("unsupported file type, please specify an executable");
+                        return ModuleSP();
+                }
+                // GetSharedModule is not guaranteed to find the old shared module, for instance
+                // in the common case where you pass in the UUID, it is only going to find the one
+                // module matching the UUID.  In fact, it has no good way to know what the "old module"
+                // relevant to this target is, since there might be many copies of a module with this file spec
+                // in various running debug sessions, but only one of them will belong to this target.
+                // So let's remove the UUID from the module list, and look in the target's module list.
+                // Only do this if there is SOMETHING else in the module spec...
+                if (!old_module_sp)
                 {
-                    ModuleSpec module_spec_copy(module_spec.GetFileSpec());
-                    module_spec_copy.GetUUID().Clear();
-                    
-                    ModuleList found_modules;
-                    size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
-                    if (num_found == 1)
+                    if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
                     {
-                        old_module_sp = found_modules.GetModuleAtIndex(0);
+                        ModuleSpec module_spec_copy(module_spec.GetFileSpec());
+                        module_spec_copy.GetUUID().Clear();
+                        
+                        ModuleList found_modules;
+                        size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
+                        if (num_found == 1)
+                        {
+                            old_module_sp = found_modules.GetModuleAtIndex(0);
+                        }
                     }
                 }
+                
+                if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
+                {
+                    m_images.ReplaceModule(old_module_sp, module_sp);
+                    Module *old_module_ptr = old_module_sp.get();
+                    old_module_sp.reset();
+                    ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
+                }
+                else
+                    m_images.Append(module_sp);
             }
-            
-            m_images.Append (module_sp);
-            if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
-            {
-                ModuleUpdated(old_module_sp, module_sp);
-                m_images.Remove (old_module_sp);
-                Module *old_module_ptr = old_module_sp.get();
-                old_module_sp.reset();
-                ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
-            }
-            else
-                ModuleAdded(module_sp);
         }
     }
     if (error_ptr)
@@ -1529,78 +1748,42 @@ Target::GetClangASTImporter()
 void
 Target::SettingsInitialize ()
 {
-    UserSettingsController::InitializeSettingsController (GetSettingsController(),
-                                                          SettingsController::global_settings_table,
-                                                          SettingsController::instance_settings_table);
-                                                          
-    // Now call SettingsInitialize() on each 'child' setting of Target
     Process::SettingsInitialize ();
 }
 
 void
 Target::SettingsTerminate ()
 {
-
-    // Must call SettingsTerminate() on each settings 'child' of Target, before terminating Target's Settings.
-    
     Process::SettingsTerminate ();
-    
-    // Now terminate Target Settings.
-    
-    UserSettingsControllerSP &usc = GetSettingsController();
-    UserSettingsController::FinalizeSettingsController (usc);
-    usc.reset();
-}
-
-UserSettingsControllerSP &
-Target::GetSettingsController ()
-{
-    static UserSettingsControllerSP g_settings_controller_sp;
-    if (!g_settings_controller_sp)
-    {
-        g_settings_controller_sp.reset (new Target::SettingsController);
-        // The first shared pointer to Target::SettingsController in
-        // g_settings_controller_sp must be fully created above so that 
-        // the TargetInstanceSettings can use a weak_ptr to refer back 
-        // to the master setttings controller
-        InstanceSettingsSP default_instance_settings_sp (new TargetInstanceSettings (g_settings_controller_sp, 
-                                                                                     false,
-                                                                                     InstanceSettings::GetDefaultName().AsCString()));
-        g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp);
-    }
-    return g_settings_controller_sp;
 }
 
 FileSpecList
 Target::GetDefaultExecutableSearchPaths ()
 {
-    lldb::UserSettingsControllerSP settings_controller_sp (GetSettingsController());
-    if (settings_controller_sp)
-    {
-        lldb::InstanceSettingsSP instance_settings_sp (settings_controller_sp->GetDefaultInstanceSettings ());
-        if (instance_settings_sp)
-            return static_cast<TargetInstanceSettings *>(instance_settings_sp.get())->GetExecutableSearchPaths ();
-    }
+    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+    if (properties_sp)
+        return properties_sp->GetExecutableSearchPaths();
     return FileSpecList();
 }
 
-
 ArchSpec
 Target::GetDefaultArchitecture ()
 {
-    lldb::UserSettingsControllerSP settings_controller_sp (GetSettingsController());
-    if (settings_controller_sp)
-        return static_cast<Target::SettingsController *>(settings_controller_sp.get())->GetArchitecture ();
+    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+    if (properties_sp)
+        return properties_sp->GetDefaultArchitecture();
     return ArchSpec();
 }
 
 void
-Target::SetDefaultArchitecture (const ArchSpec& arch)
+Target::SetDefaultArchitecture (const ArchSpec &arch)
 {
-    lldb::UserSettingsControllerSP settings_controller_sp (GetSettingsController());
-
-    if (settings_controller_sp)
-        static_cast<Target::SettingsController *>(settings_controller_sp.get())->GetArchitecture () = arch;
+    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+    if (properties_sp)
+    {
+        LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::SetDefaultArchitecture setting target's default architecture to  %s (%s)", arch.GetArchitectureName(), arch.GetTriple().getTriple().c_str());
+        return properties_sp->SetDefaultArchitecture(arch);
+    }
 }
 
 Target *
@@ -1618,47 +1801,18 @@ Target::GetTargetFromContexts (const Exe
     return target;
 }
 
-
-void
-Target::UpdateInstanceName ()
-{
-    StreamString sstr;
-    
-    Module *exe_module = GetExecutableModulePointer();
-    if (exe_module)
-    {
-        sstr.Printf ("%s_%s", 
-                     exe_module->GetFileSpec().GetFilename().AsCString(), 
-                     exe_module->GetArchitecture().GetArchitectureName());
-        GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData());
-    }
-}
-
-const char *
-Target::GetExpressionPrefixContentsAsCString ()
-{
-    if (!m_expr_prefix_contents.empty())
-        return m_expr_prefix_contents.c_str();
-    return NULL;
-}
-
 ExecutionResults
 Target::EvaluateExpression
 (
     const char *expr_cstr,
     StackFrame *frame,
-    lldb_private::ExecutionPolicy execution_policy,
-    bool coerce_to_id,
-    bool unwind_on_error,
-    bool keep_in_memory,
-    lldb::DynamicValueType use_dynamic,
     lldb::ValueObjectSP &result_valobj_sp,
-    uint32_t single_thread_timeout_usec
+    const EvaluateExpressionOptions& options
 )
 {
-    ExecutionResults execution_results = eExecutionSetupError;
-
     result_valobj_sp.reset();
+    
+    ExecutionResults execution_results = eExecutionSetupError;
 
     if (expr_cstr == NULL || expr_cstr[0] == '\0')
         return execution_results;
@@ -1669,31 +1823,10 @@ Target::EvaluateExpression
     m_suppress_stop_hooks = true;
 
     ExecutionContext exe_ctx;
-
-    const size_t expr_cstr_len = ::strlen (expr_cstr);
-
+    
     if (frame)
     {
         frame->CalculateExecutionContext(exe_ctx);
-        Error error;
-        const uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
-                                           StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
-                                           StackFrame::eExpressionPathOptionsNoSyntheticChildren;
-        lldb::VariableSP var_sp;
-        
-        // Make sure we don't have any things that we know a variable expression
-        // won't be able to deal with before calling into it
-        if (::strcspn (expr_cstr, "()+*&|!~<=/^%,?") == expr_cstr_len)
-        {
-            result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr, 
-                                                                         use_dynamic, 
-                                                                         expr_path_options, 
-                                                                         var_sp, 
-                                                                         error);
-            // if this expression results in a bitfield, we give up and let the IR handle it
-            if (result_valobj_sp && result_valobj_sp->IsBitfield())
-                result_valobj_sp.reset();
-        }
     }
     else if (m_process_sp)
     {
@@ -1704,87 +1837,33 @@ Target::EvaluateExpression
         CalculateExecutionContext(exe_ctx);
     }
     
-    if (result_valobj_sp)
+    // Make sure we aren't just trying to see the value of a persistent
+    // variable (something like "$0")
+    lldb::ClangExpressionVariableSP persistent_var_sp;
+    // Only check for persistent variables the expression starts with a '$' 
+    if (expr_cstr[0] == '$')
+        persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr);
+
+    if (persistent_var_sp)
     {
+        result_valobj_sp = persistent_var_sp->GetValueObject ();
         execution_results = eExecutionCompleted;
-        // We got a result from the frame variable expression path above...
-        ConstString persistent_variable_name (m_persistent_variables.GetNextPersistentVariableName());
-
-        lldb::ValueObjectSP const_valobj_sp;
-        
-        // Check in case our value is already a constant value
-        if (result_valobj_sp->GetIsConstant())
-        {
-            const_valobj_sp = result_valobj_sp;
-            const_valobj_sp->SetName (persistent_variable_name);
-        }
-        else
-        {
-            if (use_dynamic != lldb::eNoDynamicValues)
-            {
-                ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(use_dynamic);
-                if (dynamic_sp)
-                    result_valobj_sp = dynamic_sp;
-            }
-
-            const_valobj_sp = result_valobj_sp->CreateConstantValue (persistent_variable_name);
-        }
-
-        lldb::ValueObjectSP live_valobj_sp = result_valobj_sp;
-        
-        result_valobj_sp = const_valobj_sp;
-
-        ClangExpressionVariableSP clang_expr_variable_sp(m_persistent_variables.CreatePersistentVariable(result_valobj_sp));        
-        assert (clang_expr_variable_sp.get());
-        
-        // Set flags and live data as appropriate
-
-        const Value &result_value = live_valobj_sp->GetValue();
-        
-        switch (result_value.GetValueType())
-        {
-        case Value::eValueTypeHostAddress:
-        case Value::eValueTypeFileAddress:
-            // we don't do anything with these for now
-            break;
-        case Value::eValueTypeScalar:
-            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
-            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
-            break;
-        case Value::eValueTypeLoadAddress:
-            clang_expr_variable_sp->m_live_sp = live_valobj_sp;
-            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
-            break;
-        }
     }
     else
     {
-        // Make sure we aren't just trying to see the value of a persistent 
-        // variable (something like "$0")
-        lldb::ClangExpressionVariableSP persistent_var_sp;
-        // Only check for persistent variables the expression starts with a '$' 
-        if (expr_cstr[0] == '$')
-            persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr);
-
-        if (persistent_var_sp)
-        {
-            result_valobj_sp = persistent_var_sp->GetValueObject ();
-            execution_results = eExecutionCompleted;
-        }
-        else
-        {
-            const char *prefix = GetExpressionPrefixContentsAsCString();
-                    
-            execution_results = ClangUserExpression::Evaluate (exe_ctx, 
-                                                               execution_policy,
-                                                               lldb::eLanguageTypeUnknown,
-                                                               coerce_to_id ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
-                                                               unwind_on_error,
-                                                               expr_cstr, 
-                                                               prefix, 
-                                                               result_valobj_sp,
-                                                               single_thread_timeout_usec);
-        }
+        const char *prefix = GetExpressionPrefixContentsAsCString();
+                
+        execution_results = ClangUserExpression::Evaluate (exe_ctx, 
+                                                           options.GetExecutionPolicy(),
+                                                           lldb::eLanguageTypeUnknown,
+                                                           options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
+                                                           options.DoesUnwindOnError(),
+                                                           options.DoesIgnoreBreakpoints(),
+                                                           expr_cstr, 
+                                                           prefix, 
+                                                           result_valobj_sp,
+                                                           options.GetRunOthers(),
+                                                           options.GetTimeoutUsec());
     }
     
     m_suppress_stop_hooks = old_suppress_value;
@@ -1867,6 +1946,15 @@ Target::GetOpcodeLoadAddress (lldb::addr
     return opcode_addr;
 }
 
+SourceManager &
+Target::GetSourceManager ()
+{
+    if (m_source_manager_ap.get() == NULL)
+        m_source_manager_ap.reset (new SourceManager(shared_from_this()));
+    return *m_source_manager_ap;
+}
+
+
 lldb::user_id_t
 Target::AddStopHook (Target::StopHookSP &new_hook_sp)
 {
@@ -2025,9 +2113,9 @@ Target::RunStopHooks ()
                                        cur_hook_sp->GetCommands().GetStringAtIndex(0) :
                                        NULL);
                     if (cmd)
-                        result.AppendMessageWithFormat("\n- Hook %llu (%s)\n", cur_hook_sp->GetID(), cmd);
+                        result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(), cmd);
                     else
-                        result.AppendMessageWithFormat("\n- Hook %llu\n", cur_hook_sp->GetID());
+                        result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());
                     any_thread_matched = true;
                 }
                 
@@ -2052,7 +2140,7 @@ Target::RunStopHooks ()
                 if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || 
                     (result.GetStatus() == eReturnStatusSuccessContinuingResult))
                 {
-                    result.AppendMessageWithFormat ("Aborting stop hooks, hook %llu set the program running.", cur_hook_sp->GetID());
+                    result.AppendMessageWithFormat ("Aborting stop hooks, hook %" PRIu64 " set the program running.", cur_hook_sp->GetID());
                     keep_going = false;
                 }
             }
@@ -2074,7 +2162,7 @@ Target::StopHook::StopHook (lldb::Target
         m_target_sp (target_sp),
         m_commands (),
         m_specifier_sp (),
-        m_thread_spec_ap(NULL),
+        m_thread_spec_ap(),
         m_active (true)
 {
 }
@@ -2084,7 +2172,7 @@ Target::StopHook::StopHook (const StopHo
         m_target_sp (rhs.m_target_sp),
         m_commands (rhs.m_commands),
         m_specifier_sp (rhs.m_specifier_sp),
-        m_thread_spec_ap (NULL),
+        m_thread_spec_ap (),
         m_active (rhs.m_active)
 {
     if (rhs.m_thread_spec_ap.get() != NULL)
@@ -2110,7 +2198,7 @@ Target::StopHook::GetDescription (Stream
 
     s->SetIndentLevel(indent_level + 2);
 
-    s->Printf ("Hook: %llu\n", GetID());
+    s->Printf ("Hook: %" PRIu64 "\n", GetID());
     if (m_active)
         s->Indent ("State: enabled\n");
     else
@@ -2147,799 +2235,495 @@ Target::StopHook::GetDescription (Stream
     s->SetIndentLevel (indent_level);
 }
 
-
 //--------------------------------------------------------------
-// class Target::SettingsController
+// class TargetProperties
 //--------------------------------------------------------------
 
-Target::SettingsController::SettingsController () :
-    UserSettingsController ("target", Debugger::GetSettingsController()),
-    m_default_architecture ()
+OptionEnumValueElement
+lldb_private::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 }
+};
 
-Target::SettingsController::~SettingsController ()
+static OptionEnumValueElement
+g_inline_breakpoint_enums[] =
 {
-}
+    { eInlineBreakpointsNever,   "never",     "Never look for inline breakpoint locations (fastest). This setting should only be used if you know that no inlining occurs in your programs."},
+    { eInlineBreakpointsHeaders, "headers",   "Only check for inline breakpoint locations when setting breakpoints in header files, but not when setting breakpoint in implementation source files (default)."},
+    { eInlineBreakpointsAlways,  "always",    "Always look for inline breakpoint locations when setting file and line breakpoints (slower but most accurate)."},
+    { 0, NULL, NULL }
+};
 
-lldb::InstanceSettingsSP
-Target::SettingsController::CreateInstanceSettings (const char *instance_name)
+typedef enum x86DisassemblyFlavor
 {
-    lldb::InstanceSettingsSP new_settings_sp (new TargetInstanceSettings (GetSettingsController(),
-                                                                          false, 
-                                                                          instance_name));
-    return new_settings_sp;
-}
+    eX86DisFlavorDefault,
+    eX86DisFlavorIntel,
+    eX86DisFlavorATT
+} x86DisassemblyFlavor;
+
+static OptionEnumValueElement
+g_x86_dis_flavor_value_types[] =
+{
+    { eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
+    { eX86DisFlavorIntel,   "intel",   "Intel disassembler flavor."},
+    { eX86DisFlavorATT,     "att",     "AT&T disassembler flavor."},
+    { 0, NULL, NULL }
+};
 
+static OptionEnumValueElement
+g_load_script_from_sym_file_values[] =
+{
+    { eLoadScriptFromSymFileTrue,    "true",    "Load debug scripts inside symbol files"},
+    { eLoadScriptFromSymFileFalse,   "false",   "Do not load debug scripts inside symbol files."},
+    { eLoadScriptFromSymFileWarn,    "warn",    "Warn about debug scripts inside symbol files but do not load them."},
+    { 0, NULL, NULL }
+};
 
-#define TSC_DEFAULT_ARCH        "default-arch"
-#define TSC_EXPR_PREFIX         "expr-prefix"
-#define TSC_PREFER_DYNAMIC      "prefer-dynamic-value"
-#define TSC_ENABLE_SYNTHETIC    "enable-synthetic-value"
-#define TSC_SKIP_PROLOGUE       "skip-prologue"
-#define TSC_SOURCE_MAP          "source-map"
-#define TSC_EXE_SEARCH_PATHS    "exec-search-paths"
-#define TSC_MAX_CHILDREN        "max-children-count"
-#define TSC_MAX_STRLENSUMMARY   "max-string-summary-length"
-#define TSC_PLATFORM_AVOID      "breakpoints-use-platform-avoid-list"
-#define TSC_RUN_ARGS            "run-args"
-#define TSC_ENV_VARS            "env-vars"
-#define TSC_INHERIT_ENV         "inherit-env"
-#define TSC_STDIN_PATH          "input-path"
-#define TSC_STDOUT_PATH         "output-path"
-#define TSC_STDERR_PATH         "error-path"
-#define TSC_DISABLE_ASLR        "disable-aslr"
-#define TSC_DISABLE_STDIO       "disable-stdio"
+static PropertyDefinition
+g_properties[] =
+{
+    { "default-arch"                       , OptionValue::eTypeArch      , true , 0                         , NULL, NULL, "Default architecture to choose, when there's a choice." },
+    { "expr-prefix"                        , OptionValue::eTypeFileSpec  , false, 0                         , NULL, NULL, "Path to a file containing expressions to be prepended to all expressions." },
+    { "prefer-dynamic-value"               , OptionValue::eTypeEnum      , false, eNoDynamicValues          , NULL, g_dynamic_value_types, "Should printed values be shown as their dynamic value." },
+    { "enable-synthetic-value"             , OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Should synthetic values be used by default whenever available." },
+    { "skip-prologue"                      , OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Skip function prologues when setting breakpoints by name." },
+    { "source-map"                         , OptionValue::eTypePathMap   , false, 0                         , NULL, NULL, "Source path remappings used to track the change of location between a source file when built, and "
+      "where it exists on the current system.  It consists of an array of duples, the first element of each duple is "
+      "some part (starting at the root) of the path to the file when it was built, "
+      "and the second is where the remainder of the original build hierarchy is rooted on the local system.  "
+      "Each element of the array is checked in order and the first one that results in a match wins." },
+    { "exec-search-paths"                  , OptionValue::eTypeFileSpecList, false, 0                       , NULL, NULL, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
+    { "max-children-count"                 , OptionValue::eTypeSInt64    , false, 256                       , NULL, NULL, "Maximum number of children to expand in any level of depth." },
+    { "max-string-summary-length"          , OptionValue::eTypeSInt64    , false, 1024                      , NULL, NULL, "Maximum number of characters to show when using %s in summary strings." },
+    { "max-memory-read-size"               , OptionValue::eTypeSInt64    , false, 1024                      , NULL, NULL, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." },
+    { "breakpoints-use-platform-avoid-list", OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Consult the platform module avoid list when setting non-module specific breakpoints." },
+    { "arg0"                               , OptionValue::eTypeString    , false, 0                         , NULL, NULL, "The first argument passed to the program in the argument array which can be different from the executable itself." },
+    { "run-args"                           , OptionValue::eTypeArgs      , false, 0                         , NULL, NULL, "A list containing all the arguments to be passed to the executable when it is run. Note that this does NOT include the argv[0] which is in target.arg0." },
+    { "env-vars"                           , OptionValue::eTypeDictionary, false, OptionValue::eTypeString  , NULL, NULL, "A list of all the environment variables to be passed to the executable's environment, and their values." },
+    { "inherit-env"                        , OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Inherit the environment from the process that is running LLDB." },
+    { "input-path"                         , OptionValue::eTypeFileSpec  , false, 0                         , NULL, NULL, "The file/path to be used by the executable program for reading its standard input." },
+    { "output-path"                        , OptionValue::eTypeFileSpec  , false, 0                         , NULL, NULL, "The file/path to be used by the executable program for writing its standard output." },
+    { "error-path"                         , OptionValue::eTypeFileSpec  , false, 0                         , NULL, NULL, "The file/path to be used by the executable program for writing its standard error." },
+    { "disable-aslr"                       , OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Disable Address Space Layout Randomization (ASLR)" },
+    { "disable-stdio"                      , OptionValue::eTypeBoolean   , false, false                     , NULL, NULL, "Disable stdin/stdout for process (e.g. for a GUI application)" },
+    { "inline-breakpoint-strategy"         , OptionValue::eTypeEnum      , false, eInlineBreakpointsHeaders , NULL, g_inline_breakpoint_enums, "The strategy to use when settings breakpoints by file and line. "
+        "Breakpoint locations can end up being inlined by the compiler, so that a compile unit 'a.c' might contain an inlined function from another source file. "
+        "Usually this is limitted to breakpoint locations from inlined functions from header or other include files, or more accurately non-implementation source files. "
+        "Sometimes code might #include implementation files and cause inlined breakpoint locations in inlined implementation files. "
+        "Always checking for inlined breakpoint locations can be expensive (memory and time), so we try to minimize the "
+        "times we look for inlined locations. This setting allows you to control exactly which strategy is used when settings "
+        "file and line breakpoints." },
+    // FIXME: This is the wrong way to do per-architecture settings, but we don't have a general per architecture settings system in place yet.
+    { "x86-disassembly-flavor"             , OptionValue::eTypeEnum      , false, eX86DisFlavorDefault,       NULL, g_x86_dis_flavor_value_types, "The default disassembly flavor to use for x86 or x86-64 targets." },
+    { "use-fast-stepping"                  , OptionValue::eTypeBoolean   , false, true,                       NULL, NULL, "Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping." },
+    { "load-script-from-symbol-file"       , OptionValue::eTypeEnum   ,    false, eLoadScriptFromSymFileWarn, NULL, g_load_script_from_sym_file_values, "Allow LLDB to load scripting resources embedded in symbol files when available." },
+    { NULL                                 , OptionValue::eTypeInvalid   , false, 0                         , NULL, NULL, NULL }
+};
+enum
+{
+    ePropertyDefaultArch,
+    ePropertyExprPrefix,
+    ePropertyPreferDynamic,
+    ePropertyEnableSynthetic,
+    ePropertySkipPrologue,
+    ePropertySourceMap,
+    ePropertyExecutableSearchPaths,
+    ePropertyMaxChildrenCount,
+    ePropertyMaxSummaryLength,
+    ePropertyMaxMemReadSize,
+    ePropertyBreakpointUseAvoidList,
+    ePropertyArg0,
+    ePropertyRunArgs,
+    ePropertyEnvVars,
+    ePropertyInheritEnv,
+    ePropertyInputPath,
+    ePropertyOutputPath,
+    ePropertyErrorPath,
+    ePropertyDisableASLR,
+    ePropertyDisableSTDIO,
+    ePropertyInlineStrategy,
+    ePropertyDisassemblyFlavor,
+    ePropertyUseFastStepping,
+    ePropertyLoadScriptFromSymbolFile,
+};
 
 
-static const ConstString &
-GetSettingNameForDefaultArch ()
+class TargetOptionValueProperties : public OptionValueProperties
 {
-    static ConstString g_const_string (TSC_DEFAULT_ARCH);
-    return g_const_string;
-}
+public:
+    TargetOptionValueProperties (const ConstString &name) :
+        OptionValueProperties (name),
+        m_target (NULL),
+        m_got_host_env (false)
+    {
+    }
+
+    // This constructor is used when creating TargetOptionValueProperties when it
+    // is part of a new lldb_private::Target instance. It will copy all current
+    // global property values as needed
+    TargetOptionValueProperties (Target *target, const TargetPropertiesSP &target_properties_sp) :
+        OptionValueProperties(*target_properties_sp->GetValueProperties()),
+        m_target (target),
+        m_got_host_env (false)
+    {
+    }
+
+    virtual const Property *
+    GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
+    {
+        // When gettings the value for a key from the target options, we will always
+        // try and grab the setting from the current target if there is one. Else we just
+        // use the one from this instance.
+        if (idx == ePropertyEnvVars)
+            GetHostEnvironmentIfNeeded ();
+            
+        if (exe_ctx)
+        {
+            Target *target = exe_ctx->GetTargetPtr();
+            if (target)
+            {
+                TargetOptionValueProperties *target_properties = static_cast<TargetOptionValueProperties *>(target->GetValueProperties().get());
+                if (this != target_properties)
+                    return target_properties->ProtectedGetPropertyAtIndex (idx);
+            }
+        }
+        return ProtectedGetPropertyAtIndex (idx);
+    }
+    
+    lldb::TargetSP
+    GetTargetSP ()
+    {
+        return m_target->shared_from_this();
+    }
+    
+protected:
+    
+    void
+    GetHostEnvironmentIfNeeded () const
+    {
+        if (!m_got_host_env)
+        {
+            if (m_target)
+            {
+                m_got_host_env = true;
+                const uint32_t idx = ePropertyInheritEnv;
+                if (GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0))
+                {
+                    PlatformSP platform_sp (m_target->GetPlatform());
+                    if (platform_sp)
+                    {
+                        StringList env;
+                        if (platform_sp->GetEnvironment(env))
+                        {
+                            OptionValueDictionary *env_dict = GetPropertyAtIndexAsOptionValueDictionary (NULL, ePropertyEnvVars);
+                            if (env_dict)
+                            {
+                                const bool can_replace = false;
+                                const size_t envc = env.GetSize();
+                                for (size_t idx=0; idx<envc; idx++)
+                                {
+                                    const char *env_entry = env.GetStringAtIndex (idx);
+                                    if (env_entry)
+                                    {
+                                        const char *equal_pos = ::strchr(env_entry, '=');
+                                        ConstString key;
+                                        // It is ok to have environment variables with no values
+                                        const char *value = NULL;
+                                        if (equal_pos)
+                                        {
+                                            key.SetCStringWithLength(env_entry, equal_pos - env_entry);
+                                            if (equal_pos[1])
+                                                value = equal_pos + 1;
+                                        }
+                                        else
+                                        {
+                                            key.SetCString(env_entry);
+                                        }
+                                        // Don't allow existing keys to be replaced with ones we get from the platform environment
+                                        env_dict->SetValueForKey(key, OptionValueSP(new OptionValueString(value)), can_replace);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    Target *m_target;
+    mutable bool m_got_host_env;
+};
 
-static const ConstString &
-GetSettingNameForExpressionPrefix ()
+TargetProperties::TargetProperties (Target *target) :
+    Properties ()
 {
-    static ConstString g_const_string (TSC_EXPR_PREFIX);
-    return g_const_string;
+    if (target)
+    {
+        m_collection_sp.reset (new TargetOptionValueProperties(target, Target::GetGlobalProperties()));
+    }
+    else
+    {
+        m_collection_sp.reset (new TargetOptionValueProperties(ConstString("target")));
+        m_collection_sp->Initialize(g_properties);
+        m_collection_sp->AppendProperty(ConstString("process"),
+                                        ConstString("Settings specify to processes."),
+                                        true,
+                                        Process::GetGlobalProperties()->GetValueProperties());
+    }
 }
 
-static const ConstString &
-GetSettingNameForPreferDynamicValue ()
+TargetProperties::~TargetProperties ()
 {
-    static ConstString g_const_string (TSC_PREFER_DYNAMIC);
-    return g_const_string;
 }
-
-static const ConstString &
-GetSettingNameForEnableSyntheticValue ()
+ArchSpec
+TargetProperties::GetDefaultArchitecture () const
 {
-    static ConstString g_const_string (TSC_ENABLE_SYNTHETIC);
-    return g_const_string;
+    OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch (NULL, ePropertyDefaultArch);
+    if (value)
+        return value->GetCurrentValue();
+    return ArchSpec();
 }
 
-static const ConstString &
-GetSettingNameForSourcePathMap ()
+void
+TargetProperties::SetDefaultArchitecture (const ArchSpec& arch)
 {
-    static ConstString g_const_string (TSC_SOURCE_MAP);
-    return g_const_string;
+    OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch (NULL, ePropertyDefaultArch);
+    if (value)
+        return value->SetCurrentValue(arch, true);
 }
 
-static const ConstString &
-GetSettingNameForExecutableSearchPaths ()
+lldb::DynamicValueType
+TargetProperties::GetPreferDynamicValue() const
 {
-    static ConstString g_const_string (TSC_EXE_SEARCH_PATHS);
-    return g_const_string;
+    const uint32_t idx = ePropertyPreferDynamic;
+    return (lldb::DynamicValueType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
 }
 
-static const ConstString &
-GetSettingNameForSkipPrologue ()
+bool
+TargetProperties::GetDisableASLR () const
 {
-    static ConstString g_const_string (TSC_SKIP_PROLOGUE);
-    return g_const_string;
+    const uint32_t idx = ePropertyDisableASLR;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
-static const ConstString &
-GetSettingNameForMaxChildren ()
+void
+TargetProperties::SetDisableASLR (bool b)
 {
-    static ConstString g_const_string (TSC_MAX_CHILDREN);
-    return g_const_string;
+    const uint32_t idx = ePropertyDisableASLR;
+    m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
 }
 
-static const ConstString &
-GetSettingNameForMaxStringSummaryLength ()
+bool
+TargetProperties::GetDisableSTDIO () const
 {
-    static ConstString g_const_string (TSC_MAX_STRLENSUMMARY);
-    return g_const_string;
+    const uint32_t idx = ePropertyDisableSTDIO;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
-static const ConstString &
-GetSettingNameForPlatformAvoid ()
+void
+TargetProperties::SetDisableSTDIO (bool b)
 {
-    static ConstString g_const_string (TSC_PLATFORM_AVOID);
-    return g_const_string;
+    const uint32_t idx = ePropertyDisableSTDIO;
+    m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
 }
 
-const ConstString &
-GetSettingNameForRunArgs ()
+const char *
+TargetProperties::GetDisassemblyFlavor () const
 {
-    static ConstString g_const_string (TSC_RUN_ARGS);
-    return g_const_string;
+    const uint32_t idx = ePropertyDisassemblyFlavor;
+    const char *return_value;
+    
+    x86DisassemblyFlavor flavor_value = (x86DisassemblyFlavor) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+    return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
+    return return_value;
 }
 
-const ConstString &
-GetSettingNameForEnvVars ()
+InlineStrategy
+TargetProperties::GetInlineStrategy () const
 {
-    static ConstString g_const_string (TSC_ENV_VARS);
-    return g_const_string;
+    const uint32_t idx = ePropertyInlineStrategy;
+    return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
 }
 
-const ConstString &
-GetSettingNameForInheritHostEnv ()
+const char *
+TargetProperties::GetArg0 () const
 {
-    static ConstString g_const_string (TSC_INHERIT_ENV);
-    return g_const_string;
+    const uint32_t idx = ePropertyArg0;
+    return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, NULL);
 }
 
-const ConstString &
-GetSettingNameForInputPath ()
+void
+TargetProperties::SetArg0 (const char *arg)
 {
-    static ConstString g_const_string (TSC_STDIN_PATH);
-    return g_const_string;
+    const uint32_t idx = ePropertyArg0;
+    m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, arg);
 }
 
-const ConstString &
-GetSettingNameForOutputPath ()
+bool
+TargetProperties::GetRunArguments (Args &args) const
 {
-    static ConstString g_const_string (TSC_STDOUT_PATH);
-    return g_const_string;
+    const uint32_t idx = ePropertyRunArgs;
+    return m_collection_sp->GetPropertyAtIndexAsArgs (NULL, idx, args);
 }
 
-const ConstString &
-GetSettingNameForErrorPath ()
+void
+TargetProperties::SetRunArguments (const Args &args)
 {
-    static ConstString g_const_string (TSC_STDERR_PATH);
-    return g_const_string;
+    const uint32_t idx = ePropertyRunArgs;
+    m_collection_sp->SetPropertyAtIndexFromArgs (NULL, idx, args);
 }
 
-const ConstString &
-GetSettingNameForDisableASLR ()
+size_t
+TargetProperties::GetEnvironmentAsArgs (Args &env) const
 {
-    static ConstString g_const_string (TSC_DISABLE_ASLR);
-    return g_const_string;
+    const uint32_t idx = ePropertyEnvVars;
+    return m_collection_sp->GetPropertyAtIndexAsArgs (NULL, idx, env);
 }
 
-const ConstString &
-GetSettingNameForDisableSTDIO ()
+bool
+TargetProperties::GetSkipPrologue() const
 {
-    static ConstString g_const_string (TSC_DISABLE_STDIO);
-    return g_const_string;
+    const uint32_t idx = ePropertySkipPrologue;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-Target::SettingsController::SetGlobalVariable (const ConstString &var_name,
-                                               const char *index_value,
-                                               const char *value,
-                                               const SettingEntry &entry,
-                                               const VarSetOperationType op,
-                                               Error&err)
+PathMappingList &
+TargetProperties::GetSourcePathMap () const
 {
-    if (var_name == GetSettingNameForDefaultArch())
-    {
-        m_default_architecture.SetTriple (value);
-        if (!m_default_architecture.IsValid())
-            err.SetErrorStringWithFormat ("'%s' is not a valid architecture or triple.", value);
-    }
-    return true;
+    const uint32_t idx = ePropertySourceMap;
+    OptionValuePathMappings *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings (NULL, false, idx);
+    assert(option_value);
+    return option_value->GetCurrentValue();
 }
 
+FileSpecList &
+TargetProperties::GetExecutableSearchPaths ()
+{
+    const uint32_t idx = ePropertyExecutableSearchPaths;
+    OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList (NULL, false, idx);
+    assert(option_value);
+    return option_value->GetCurrentValue();
+}
 
 bool
-Target::SettingsController::GetGlobalVariable (const ConstString &var_name,
-                                               StringList &value,
-                                               Error &err)
-{
-    if (var_name == GetSettingNameForDefaultArch())
-    {
-        // If the arch is invalid (the default), don't show a string for it
-        if (m_default_architecture.IsValid())
-            value.AppendString (m_default_architecture.GetArchitectureName());
-        return true;
-    }
-    else
-        err.SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
-
-    return false;
+TargetProperties::GetEnableSyntheticValue () const
+{
+    const uint32_t idx = ePropertyEnableSynthetic;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
-//--------------------------------------------------------------
-// class TargetInstanceSettings
-//--------------------------------------------------------------
-
-TargetInstanceSettings::TargetInstanceSettings
-(
-    const lldb::UserSettingsControllerSP &owner_sp, 
-    bool live_instance, 
-    const char *name
-) :
-    InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
-    m_expr_prefix_file (),
-    m_expr_prefix_contents (),
-    m_prefer_dynamic_value (2),
-    m_enable_synthetic_value(true, true),
-    m_skip_prologue (true, true),
-    m_source_map (NULL, NULL),
-    m_exe_search_paths (),
-    m_max_children_display(256),
-    m_max_strlen_length(1024),
-    m_breakpoints_use_platform_avoid (true, true),
-    m_run_args (),
-    m_env_vars (),
-    m_input_path (),
-    m_output_path (),
-    m_error_path (),
-    m_disable_aslr (true),
-    m_disable_stdio (false),
-    m_inherit_host_env (true),
-    m_got_host_env (false)
-{
-    // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
-    // until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers.
-    // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
-    // This is true for CreateInstanceName() too.
-
-    if (GetInstanceName () == InstanceSettings::InvalidName())
-    {
-        ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
-        owner_sp->RegisterInstanceSettings (this);
-    }
-
-    if (live_instance)
-    {
-        const lldb::InstanceSettingsSP &pending_settings = owner_sp->FindPendingSettings (m_instance_name);
-        CopyInstanceSettings (pending_settings,false);
-    }
-}
-
-TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rhs) :
-    InstanceSettings (Target::GetSettingsController(), CreateInstanceName().AsCString()),
-    m_expr_prefix_file (rhs.m_expr_prefix_file),
-    m_expr_prefix_contents (rhs.m_expr_prefix_contents),
-    m_prefer_dynamic_value (rhs.m_prefer_dynamic_value),
-    m_enable_synthetic_value(rhs.m_enable_synthetic_value),
-    m_skip_prologue (rhs.m_skip_prologue),
-    m_source_map (rhs.m_source_map),
-    m_exe_search_paths (rhs.m_exe_search_paths),
-    m_max_children_display (rhs.m_max_children_display),
-    m_max_strlen_length (rhs.m_max_strlen_length),
-    m_breakpoints_use_platform_avoid (rhs.m_breakpoints_use_platform_avoid),
-    m_run_args (rhs.m_run_args),
-    m_env_vars (rhs.m_env_vars),
-    m_input_path (rhs.m_input_path),
-    m_output_path (rhs.m_output_path),
-    m_error_path (rhs.m_error_path),
-    m_disable_aslr (rhs.m_disable_aslr),
-    m_disable_stdio (rhs.m_disable_stdio),
-    m_inherit_host_env (rhs.m_inherit_host_env)
-{
-    if (m_instance_name != InstanceSettings::GetDefaultName())
-    {
-        UserSettingsControllerSP owner_sp (m_owner_wp.lock());
-        if (owner_sp)
-            CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name),false);
-    }
-}
-
-TargetInstanceSettings::~TargetInstanceSettings ()
-{
-}
-
-TargetInstanceSettings&
-TargetInstanceSettings::operator= (const TargetInstanceSettings &rhs)
-{
-    if (this != &rhs)
-    {
-        m_expr_prefix_file = rhs.m_expr_prefix_file;
-        m_expr_prefix_contents = rhs.m_expr_prefix_contents;
-        m_prefer_dynamic_value = rhs.m_prefer_dynamic_value;
-        m_enable_synthetic_value = rhs.m_enable_synthetic_value;
-        m_skip_prologue = rhs.m_skip_prologue;
-        m_source_map = rhs.m_source_map;
-        m_exe_search_paths = rhs.m_exe_search_paths;
-        m_max_children_display = rhs.m_max_children_display;
-        m_max_strlen_length = rhs.m_max_strlen_length;
-        m_breakpoints_use_platform_avoid = rhs.m_breakpoints_use_platform_avoid;
-        m_run_args = rhs.m_run_args;
-        m_env_vars = rhs.m_env_vars;
-        m_input_path = rhs.m_input_path;
-        m_output_path = rhs.m_output_path;
-        m_error_path = rhs.m_error_path;
-        m_disable_aslr = rhs.m_disable_aslr;
-        m_disable_stdio = rhs.m_disable_stdio;
-        m_inherit_host_env = rhs.m_inherit_host_env;
-    }
-
-    return *this;
-}
-
-void
-TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
-                                                        const char *index_value,
-                                                        const char *value,
-                                                        const ConstString &instance_name,
-                                                        const SettingEntry &entry,
-                                                        VarSetOperationType op,
-                                                        Error &err,
-                                                        bool pending)
+uint32_t
+TargetProperties::GetMaximumNumberOfChildrenToDisplay() const
 {
-    if (var_name == GetSettingNameForExpressionPrefix ())
-    {
-        err = UserSettingsController::UpdateFileSpecOptionValue (value, op, m_expr_prefix_file);
-        if (err.Success())
-        {
-            switch (op)
-            {
-            default:
-                break;
-            case eVarSetOperationAssign:
-            case eVarSetOperationAppend:
-                {
-                    m_expr_prefix_contents.clear();
+    const uint32_t idx = ePropertyMaxChildrenCount;
+    return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
+}
 
-                    if (!m_expr_prefix_file.GetCurrentValue().Exists())
-                    {
-                        err.SetErrorToGenericError ();
-                        err.SetErrorStringWithFormat ("%s does not exist", value);
-                        return;
-                    }
-            
-                    DataBufferSP file_data_sp (m_expr_prefix_file.GetCurrentValue().ReadFileContents(0, SIZE_MAX, &err));
-                    
-                    if (err.Success())
-                    {
-                        if (file_data_sp && file_data_sp->GetByteSize() > 0)
-                        {
-                            m_expr_prefix_contents.assign((const char*)file_data_sp->GetBytes(), file_data_sp->GetByteSize());
-                        }
-                        else
-                        {
-                            err.SetErrorStringWithFormat ("couldn't read data from '%s'", value);
-                        }
-                    }
-                }
-                break;
-            case eVarSetOperationClear:
-                m_expr_prefix_contents.clear();
-            }
-        }
-    }
-    else if (var_name == GetSettingNameForPreferDynamicValue())
-    {
-        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 == GetSettingNameForEnableSyntheticValue())
-    {
-        bool ok;
-        bool new_value = Args::StringToBoolean(value, true, &ok);
-        if (ok)
-            m_enable_synthetic_value.SetCurrentValue(new_value);
-    }
-    else if (var_name == GetSettingNameForSkipPrologue())
-    {
-        err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_skip_prologue);
-    }
-    else if (var_name == GetSettingNameForMaxChildren())
-    {
-        bool ok;
-        uint32_t new_value = Args::StringToUInt32(value, 0, 10, &ok);
-        if (ok)
-            m_max_children_display = new_value;
-    }
-    else if (var_name == GetSettingNameForMaxStringSummaryLength())
-    {
-        bool ok;
-        uint32_t new_value = Args::StringToUInt32(value, 0, 10, &ok);
-        if (ok)
-            m_max_strlen_length = new_value;
-    }
-    else if (var_name == GetSettingNameForExecutableSearchPaths())
-    {
-        switch (op)
-        {
-            case eVarSetOperationReplace:
-            case eVarSetOperationInsertBefore:
-            case eVarSetOperationInsertAfter:
-            case eVarSetOperationRemove:
-            default:
-                break;
-            case eVarSetOperationAssign:
-                m_exe_search_paths.Clear();
-                // Fall through to append....
-            case eVarSetOperationAppend:
-            {   
-                Args args(value);
-                const uint32_t argc = args.GetArgumentCount();
-                if (argc > 0)
-                {
-                    const char *exe_search_path_dir;
-                    for (uint32_t idx = 0; (exe_search_path_dir = args.GetArgumentAtIndex(idx)) != NULL; ++idx)
-                    {
-                        FileSpec file_spec;
-                        file_spec.GetDirectory().SetCString(exe_search_path_dir);
-                        FileSpec::FileType file_type = file_spec.GetFileType();
-                        if (file_type == FileSpec::eFileTypeDirectory || file_type == FileSpec::eFileTypeInvalid)
-                        {
-                            m_exe_search_paths.Append(file_spec);
-                        }
-                        else
-                        {
-                            err.SetErrorStringWithFormat("executable search path '%s' exists, but it does not resolve to a directory", exe_search_path_dir);
-                        }
-                    }
-                }
-            }
-                break;
-                
-            case eVarSetOperationClear:
-                m_exe_search_paths.Clear();
-                break;
-        }
-    }
-    else if (var_name == GetSettingNameForSourcePathMap ())
-    {
-        switch (op)
-        {
-            case eVarSetOperationReplace:
-            case eVarSetOperationInsertBefore:
-            case eVarSetOperationInsertAfter:
-            case eVarSetOperationRemove:
-            default:
-                break;
-            case eVarSetOperationAssign:
-                m_source_map.Clear(true);
-                // Fall through to append....
-            case eVarSetOperationAppend:
-                {   
-                    Args args(value);
-                    const uint32_t argc = args.GetArgumentCount();
-                    if (argc & 1 || argc == 0)
-                    {
-                        err.SetErrorStringWithFormat ("an even number of paths must be supplied to to the source-map setting: %u arguments given", argc);
-                    }
-                    else
-                    {
-                        char resolved_new_path[PATH_MAX];
-                        FileSpec file_spec;
-                        const char *old_path;
-                        for (uint32_t idx = 0; (old_path = args.GetArgumentAtIndex(idx)) != NULL; idx += 2)
-                        {
-                            const char *new_path = args.GetArgumentAtIndex(idx+1);
-                            assert (new_path); // We have an even number of paths, this shouldn't happen!
+uint32_t
+TargetProperties::GetMaximumSizeOfStringSummary() const
+{
+    const uint32_t idx = ePropertyMaxSummaryLength;
+    return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
+}
 
-                            file_spec.SetFile(new_path, true);
-                            if (file_spec.Exists())
-                            {
-                                if (file_spec.GetPath (resolved_new_path, sizeof(resolved_new_path)) >= sizeof(resolved_new_path))
-                                {
-                                    err.SetErrorStringWithFormat("new path '%s' is too long", new_path);
-                                    return;
-                                }
-                            }
-                            else
-                            {
-                                err.SetErrorStringWithFormat("new path '%s' doesn't exist", new_path);
-                                return;
-                            }
-                            m_source_map.Append(ConstString (old_path), ConstString (resolved_new_path), true);
-                        }
-                    }
-                }
-                break;
+uint32_t
+TargetProperties::GetMaximumMemReadSize () const
+{
+    const uint32_t idx = ePropertyMaxMemReadSize;
+    return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
+}
 
-            case eVarSetOperationClear:
-                m_source_map.Clear(true);
-                break;
-        }        
-    }
-    else if (var_name == GetSettingNameForPlatformAvoid ())
-    {
-        err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_breakpoints_use_platform_avoid);
-    }
-    else if (var_name == GetSettingNameForRunArgs())
-    {
-        UserSettingsController::UpdateStringArrayVariable (op, index_value, m_run_args, value, err);
-    }
-    else if (var_name == GetSettingNameForEnvVars())
-    {
-        // This is nice for local debugging, but it is isn't correct for
-        // remote debugging. We need to stop process.env-vars from being 
-        // populated with the host environment and add this as a launch option
-        // and get the correct environment from the Target's platform.
-        // GetHostEnvironmentIfNeeded ();
-        UserSettingsController::UpdateDictionaryVariable (op, index_value, m_env_vars, value, err);
-    }
-    else if (var_name == GetSettingNameForInputPath())
-    {
-        UserSettingsController::UpdateStringVariable (op, m_input_path, value, err);
-    }
-    else if (var_name == GetSettingNameForOutputPath())
-    {
-        UserSettingsController::UpdateStringVariable (op, m_output_path, value, err);
-    }
-    else if (var_name == GetSettingNameForErrorPath())
-    {
-        UserSettingsController::UpdateStringVariable (op, m_error_path, value, err);
-    }
-    else if (var_name == GetSettingNameForDisableASLR())
-    {
-        UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, true, err);
-    }
-    else if (var_name == GetSettingNameForDisableSTDIO ())
-    {
-        UserSettingsController::UpdateBooleanVariable (op, m_disable_stdio, value, false, err);
-    }
+FileSpec
+TargetProperties::GetStandardInputPath () const
+{
+    const uint32_t idx = ePropertyInputPath;
+    return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
 }
 
 void
-TargetInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, bool pending)
+TargetProperties::SetStandardInputPath (const char *p)
 {
-    TargetInstanceSettings *new_settings_ptr = static_cast <TargetInstanceSettings *> (new_settings.get());
-    
-    if (!new_settings_ptr)
-        return;
-    
-    *this = *new_settings_ptr;
+    const uint32_t idx = ePropertyInputPath;
+    m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
 }
 
-bool
-TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
-                                                  const ConstString &var_name,
-                                                  StringList &value,
-                                                  Error *err)
+FileSpec
+TargetProperties::GetStandardOutputPath () const
 {
-    if (var_name == GetSettingNameForExpressionPrefix ())
-    {
-        char path[PATH_MAX];
-        const size_t path_len = m_expr_prefix_file.GetCurrentValue().GetPath (path, sizeof(path));
-        if (path_len > 0)
-            value.AppendString (path, path_len);
-    }
-    else if (var_name == GetSettingNameForPreferDynamicValue())
-    {
-        value.AppendString (g_dynamic_value_types[m_prefer_dynamic_value].string_value);
-    }
-    else if (var_name == GetSettingNameForEnableSyntheticValue())
-    {
-        if (m_skip_prologue)
-            value.AppendString ("true");
-        else
-            value.AppendString ("false");
-    }
-    else if (var_name == GetSettingNameForSkipPrologue())
-    {
-        if (m_skip_prologue)
-            value.AppendString ("true");
-        else
-            value.AppendString ("false");
-    }
-    else if (var_name == GetSettingNameForExecutableSearchPaths())
-    {
-        if (m_exe_search_paths.GetSize())
-        {
-            for (size_t i = 0, n = m_exe_search_paths.GetSize(); i < n; ++i) 
-            {
-                value.AppendString(m_exe_search_paths.GetFileSpecAtIndex (i).GetDirectory().AsCString());
-            }
-        }
-    }
-    else if (var_name == GetSettingNameForSourcePathMap ())
-    {
-        if (m_source_map.GetSize())
-        {
-            size_t i;
-            for (i = 0; i < m_source_map.GetSize(); ++i) {
-                StreamString sstr;
-                m_source_map.Dump(&sstr, i);
-                value.AppendString(sstr.GetData());
-            }
-        }
-    }
-    else if (var_name == GetSettingNameForMaxChildren())
-    {
-        StreamString count_str;
-        count_str.Printf ("%d", m_max_children_display);
-        value.AppendString (count_str.GetData());
-    }
-    else if (var_name == GetSettingNameForMaxStringSummaryLength())
-    {
-        StreamString count_str;
-        count_str.Printf ("%d", m_max_strlen_length);
-        value.AppendString (count_str.GetData());
-    }
-    else if (var_name == GetSettingNameForPlatformAvoid())
-    {
-        if (m_breakpoints_use_platform_avoid)
-            value.AppendString ("true");
-        else
-            value.AppendString ("false");
-    }
-    else if (var_name == GetSettingNameForRunArgs())
-    {
-        if (m_run_args.GetArgumentCount() > 0)
-        {
-            for (int i = 0; i < m_run_args.GetArgumentCount(); ++i)
-                value.AppendString (m_run_args.GetArgumentAtIndex (i));
-        }
-    }
-    else if (var_name == GetSettingNameForEnvVars())
-    {
-        GetHostEnvironmentIfNeeded ();
-        
-        if (m_env_vars.size() > 0)
-        {
-            std::map<std::string, std::string>::iterator pos;
-            for (pos = m_env_vars.begin(); pos != m_env_vars.end(); ++pos)
-            {
-                StreamString value_str;
-                value_str.Printf ("%s=%s", pos->first.c_str(), pos->second.c_str());
-                value.AppendString (value_str.GetData());
-            }
-        }
-    }
-    else if (var_name == GetSettingNameForInputPath())
-    {
-        value.AppendString (m_input_path.c_str());
-    }
-    else if (var_name == GetSettingNameForOutputPath())
-    {
-        value.AppendString (m_output_path.c_str());
-    }
-    else if (var_name == GetSettingNameForErrorPath())
-    {
-        value.AppendString (m_error_path.c_str());
-    }
-    else if (var_name == GetSettingNameForInheritHostEnv())
-    {
-        if (m_inherit_host_env)
-            value.AppendString ("true");
-        else
-            value.AppendString ("false");
-    }
-    else if (var_name == GetSettingNameForDisableASLR())
-    {
-        if (m_disable_aslr)
-            value.AppendString ("true");
-        else
-            value.AppendString ("false");
-    }
-    else if (var_name == GetSettingNameForDisableSTDIO())
-    {
-        if (m_disable_stdio)
-            value.AppendString ("true");
-        else
-            value.AppendString ("false");
-    }
-    else 
-    {
-        if (err)
-            err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
-        return false;
-    }
-    return true;
+    const uint32_t idx = ePropertyOutputPath;
+    return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
 }
 
 void
-Target::TargetInstanceSettings::GetHostEnvironmentIfNeeded ()
+TargetProperties::SetStandardOutputPath (const char *p)
 {
-    if (m_inherit_host_env && !m_got_host_env)
-    {
-        m_got_host_env = true;
-        StringList host_env;
-        const size_t host_env_count = Host::GetEnvironment (host_env);
-        for (size_t idx=0; idx<host_env_count; idx++)
-        {
-            const char *env_entry = host_env.GetStringAtIndex (idx);
-            if (env_entry)
-            {
-                const char *equal_pos = ::strchr(env_entry, '=');
-                if (equal_pos)
-                {
-                    std::string key (env_entry, equal_pos - env_entry);
-                    std::string value (equal_pos + 1);
-                    if (m_env_vars.find (key) == m_env_vars.end())
-                        m_env_vars[key] = value;
-                }
-            }
-        }
-    }
+    const uint32_t idx = ePropertyOutputPath;
+    m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
 }
 
+FileSpec
+TargetProperties::GetStandardErrorPath () const
+{
+    const uint32_t idx = ePropertyErrorPath;
+    return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+}
 
-size_t
-Target::TargetInstanceSettings::GetEnvironmentAsArgs (Args &env)
+const char *
+TargetProperties::GetExpressionPrefixContentsAsCString ()
 {
-    GetHostEnvironmentIfNeeded ();
-    
-    dictionary::const_iterator pos, end = m_env_vars.end();
-    for (pos = m_env_vars.begin(); pos != end; ++pos)
-    {
-        std::string env_var_equal_value (pos->first);
-        env_var_equal_value.append(1, '=');
-        env_var_equal_value.append (pos->second);
-        env.AppendArgument (env_var_equal_value.c_str());
+    const uint32_t idx = ePropertyExprPrefix;
+    OptionValueFileSpec *file = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec (NULL, false, idx);
+    if (file)
+    {
+        const bool null_terminate = true;
+        DataBufferSP data_sp(file->GetFileContents(null_terminate));
+        if (data_sp)
+            return (const char *) data_sp->GetBytes();
     }
-    return env.GetArgumentCount();
+    return NULL;
 }
 
-
-const ConstString
-TargetInstanceSettings::CreateInstanceName ()
+void
+TargetProperties::SetStandardErrorPath (const char *p)
 {
-    StreamString sstr;
-    static int instance_count = 1;
-    
-    sstr.Printf ("target_%d", instance_count);
-    ++instance_count;
+    const uint32_t idx = ePropertyErrorPath;
+    m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
+}
 
-    const ConstString ret_val (sstr.GetData());
-    return ret_val;
+bool
+TargetProperties::GetBreakpointsConsultPlatformAvoidList ()
+{
+    const uint32_t idx = ePropertyBreakpointUseAvoidList;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
-//--------------------------------------------------
-// Target::SettingsController Variable Tables
-//--------------------------------------------------
-OptionEnumValueElement
-TargetInstanceSettings::g_dynamic_value_types[] =
+bool
+TargetProperties::GetUseFastStepping () const
 {
-{ 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 }
-};
+    const uint32_t idx = ePropertyUseFastStepping;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
 
-SettingEntry
-Target::SettingsController::global_settings_table[] =
+LoadScriptFromSymFile
+TargetProperties::GetLoadScriptFromSymbolFile () const
 {
-    // var-name           var-type           default      enum  init'd hidden help-text
-    // =================  ================== ===========  ====  ====== ====== =========================================================================
-    { TSC_DEFAULT_ARCH  , eSetVarTypeString , NULL      , NULL, false, false, "Default architecture to choose, when there's a choice." },
-    { NULL              , eSetVarTypeNone   , NULL      , NULL, false, false, NULL }
-};
+    const uint32_t idx = ePropertyLoadScriptFromSymbolFile;
+    return (LoadScriptFromSymFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(NULL, idx, g_properties[idx].default_uint_value);
+}
 
-SettingEntry
-Target::SettingsController::instance_settings_table[] =
+const TargetPropertiesSP &
+Target::GetGlobalProperties()
 {
-    // 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   , NULL          , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
-    { TSC_ENABLE_SYNTHETIC  , eSetVarTypeBoolean, "true"        , NULL,                  false, false, "Should synthetic values be used by default whenever available." },
-    { 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 used to track the change of location between a source file when built, and "
-                                                                                                       "where it exists on the current system.  It consists of an array of duples, the first element of each duple is "
-                                                                                                       "some part (starting at the root) of the path to the file when it was built, "
-                                                                                                       "and the second is where the remainder of the original build hierarchy is rooted on the local system.  "
-                                                                                                       "Each element of the array is checked in order and the first one that results in a match wins." },
-    { TSC_EXE_SEARCH_PATHS  , eSetVarTypeArray  , NULL          , NULL,                  false, false, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
-    { TSC_MAX_CHILDREN      , eSetVarTypeInt    , "256"         , NULL,                  true,  false, "Maximum number of children to expand in any level of depth." },
-    { TSC_MAX_STRLENSUMMARY , eSetVarTypeInt    , "1024"        , NULL,                  true,  false, "Maximum number of characters to show when using %s in summary strings." },
-    { TSC_PLATFORM_AVOID    , eSetVarTypeBoolean, "true"        , NULL,                  false, false, "Consult the platform module avoid list when setting non-module specific breakpoints." },
-    { TSC_RUN_ARGS          , eSetVarTypeArray  , NULL          , NULL,                  false,  false,  "A list containing all the arguments to be passed to the executable when it is run." },
-    { TSC_ENV_VARS          , eSetVarTypeDictionary, NULL       , NULL,                  false,  false,  "A list of all the environment variables to be passed to the executable's environment, and their values." },
-    { TSC_INHERIT_ENV       , eSetVarTypeBoolean, "true"        , NULL,                  false,  false,  "Inherit the environment from the process that is running LLDB." },
-    { TSC_STDIN_PATH        , eSetVarTypeString , NULL          , NULL,                  false,  false,  "The file/path to be used by the executable program for reading its standard input." },
-    { TSC_STDOUT_PATH       , eSetVarTypeString , NULL          , NULL,                  false,  false,  "The file/path to be used by the executable program for writing its standard output." },
-    { TSC_STDERR_PATH       , eSetVarTypeString , NULL          , NULL,                  false,  false,  "The file/path to be used by the executable program for writing its standard error." },
-//    { "plugin",         eSetVarTypeEnum,        NULL,           NULL,                  false,  false,  "The plugin to be used to run the process." }, 
-    { TSC_DISABLE_ASLR      , eSetVarTypeBoolean, "true"        , NULL,                  false,  false,  "Disable Address Space Layout Randomization (ASLR)" },
-    { TSC_DISABLE_STDIO     , eSetVarTypeBoolean, "false"       , NULL,                  false,  false,  "Disable stdin/stdout for process (e.g. for a GUI application)" },
-    { NULL                  , eSetVarTypeNone   , NULL          , NULL,                  false, false, NULL }
-};
+    static TargetPropertiesSP g_settings_sp;
+    if (!g_settings_sp)
+    {
+        g_settings_sp.reset (new TargetProperties (NULL));
+    }
+    return g_settings_sp;
+}
 
 const ConstString &
 Target::TargetEventData::GetFlavorString ()

Modified: lldb/branches/lldb-platform-work/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/TargetList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/TargetList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/TargetList.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 // C Includes
 // C++ Includes
 // Other libraries and framework includes
@@ -14,11 +16,14 @@
 #include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Event.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/State.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/OptionGroupPlatform.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/TargetList.h"
@@ -37,7 +42,7 @@ TargetList::GetStaticBroadcasterClass ()
 // TargetList constructor
 //----------------------------------------------------------------------
 TargetList::TargetList(Debugger &debugger) :
-    Broadcaster(&debugger, "TargetList"),
+    Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
     m_target_list(),
     m_target_list_mutex (Mutex::eMutexTypeRecursive),
     m_selected_target_idx (0)
@@ -56,7 +61,7 @@ TargetList::~TargetList()
 
 Error
 TargetList::CreateTarget (Debugger &debugger,
-                          const FileSpec& file,
+                          const char *user_exe_path,
                           const char *triple_cstr,
                           bool get_dependent_files,
                           const OptionGroupPlatform *platform_options,
@@ -77,8 +82,67 @@ TargetList::CreateTarget (Debugger &debu
             return error;
         }
     }
-
+    
     ArchSpec platform_arch(arch);
+
+    
+    if (user_exe_path && user_exe_path[0])
+    {
+        ModuleSpecList module_specs;
+        ModuleSpec module_spec;
+        module_spec.GetFileSpec().SetFile(user_exe_path, true);
+        lldb::offset_t file_offset = 0;
+        const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, module_specs);
+        if (num_specs > 0)
+        {
+            ModuleSpec matching_module_spec;
+
+            if (num_specs == 1)
+            {
+                if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
+                {
+                    if (platform_arch.IsValid())
+                    {
+                        if (!platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
+                        {
+                            error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
+                                                           platform_arch.GetTriple().str().c_str(),
+                                                           matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
+                                                           module_spec.GetFileSpec().GetPath().c_str());
+                            return error;
+                        }
+                    }
+                    else
+                    {
+                        // Only one arch and none was specified
+                        platform_arch = matching_module_spec.GetArchitecture();
+                    }
+                }
+            }
+            else
+            {
+                if (arch.IsValid())
+                {
+                    module_spec.GetArchitecture() = arch;
+                    if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
+                    {
+                        platform_arch = matching_module_spec.GetArchitecture();
+                    }
+                }
+                // Don't just select the first architecture, we want to let the platform select
+                // the best architecture first when there are multiple archs.
+//                else
+//                {
+//                    // No arch specified, select the first arch
+//                    if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
+//                    {
+//                        platform_arch = matching_module_spec.GetArchitecture();
+//                    }
+//                }
+            }
+        }
+    }
+
     CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
     if (platform_options)
     {
@@ -101,7 +165,7 @@ TargetList::CreateTarget (Debugger &debu
         // current architecture if we have a valid architecture.
         platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
         
-        if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
+        if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
         {
             platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
         }
@@ -111,39 +175,25 @@ TargetList::CreateTarget (Debugger &debu
         platform_arch = arch;
 
     error = TargetList::CreateTarget (debugger,
-                                      file,
+                                      user_exe_path,
                                       platform_arch,
                                       get_dependent_files,
                                       platform_sp,
                                       target_sp);
-
-    if (target_sp)
-    {
-        if (file.GetDirectory())
-        {
-            FileSpec file_dir;
-            file_dir.GetDirectory() = file.GetDirectory();
-            target_sp->GetExecutableSearchPaths ().Append (file_dir);
-        }
-    }
     return error;
 }
 
 Error
-TargetList::CreateTarget
-(
-    Debugger &debugger,
-    const FileSpec& file,
-    const ArchSpec& specified_arch,
-    bool get_dependent_files,
-    PlatformSP &platform_sp,
-    TargetSP &target_sp
-)
+TargetList::CreateTarget (Debugger &debugger,
+                          const char *user_exe_path,
+                          const ArchSpec& specified_arch,
+                          bool get_dependent_files,
+                          PlatformSP &platform_sp,
+                          TargetSP &target_sp)
 {
     Timer scoped_timer (__PRETTY_FUNCTION__,
-                        "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
-                        file.GetDirectory().AsCString(),
-                        file.GetFilename().AsCString(),
+                        "TargetList::CreateTarget (file = '%s', arch = '%s')",
+                        user_exe_path,
                         specified_arch.GetArchitectureName());
     Error error;
 
@@ -153,7 +203,7 @@ TargetList::CreateTarget
     {
         if (arch.IsValid())
         {
-            if (!platform_sp->IsCompatibleArchitecture(arch))
+            if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
                 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
         }
     }
@@ -167,12 +217,40 @@ TargetList::CreateTarget
 
     if (!arch.IsValid())
         arch = specified_arch;
-    
 
+    FileSpec file (user_exe_path, false);
+    if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
+    {
+        file = FileSpec(user_exe_path, true);
+    }
+    bool user_exe_path_is_bundle = false;
+    char resolved_bundle_exe_path[PATH_MAX];
+    resolved_bundle_exe_path[0] = '\0';
     if (file)
     {
+        if (file.GetFileType() == FileSpec::eFileTypeDirectory)
+            user_exe_path_is_bundle = true;
+
+        if (file.IsRelativeToCurrentWorkingDirectory())
+        {
+            // Ignore paths that start with "./" and "../"
+            if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
+                  (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
+            {
+                char cwd[PATH_MAX];
+                if (getcwd (cwd, sizeof(cwd)))
+                {
+                    std::string cwd_user_exe_path (cwd);
+                    cwd_user_exe_path += '/';
+                    cwd_user_exe_path += user_exe_path;
+                    FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
+                    if (cwd_file.Exists())
+                        file = cwd_file;
+                }
+            }
+        }
+
         ModuleSP exe_module_sp;
-        FileSpec resolved_file(file);
         if (platform_sp)
         {
             FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
@@ -188,23 +266,21 @@ TargetList::CreateTarget
             {
                 if (arch.IsValid())
                 {
-                    error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
-                                                   file.GetDirectory().AsCString(),
-                                                   file.GetDirectory() ? "/" : "",
-                                                   file.GetFilename().AsCString(),
+                    error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
+                                                   file.GetPath().c_str(),
                                                    arch.GetArchitectureName());
                 }
                 else
                 {
-                    error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
-                                                   file.GetDirectory().AsCString(),
-                                                   file.GetDirectory() ? "/" : "",
-                                                   file.GetFilename().AsCString());
+                    error.SetErrorStringWithFormat("unsupported file type \"%s\"",
+                                                   file.GetPath().c_str());
                 }
                 return error;
             }
             target_sp.reset(new Target(debugger, arch, platform_sp));
             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
+            if (user_exe_path_is_bundle)
+                exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
         }
     }
     else
@@ -216,11 +292,33 @@ TargetList::CreateTarget
 
     if (target_sp)
     {
-        target_sp->UpdateInstanceName();        
-
+        // Set argv0 with what the user typed, unless the user specified a
+        // directory. If the user specified a directory, then it is probably a
+        // bundle that was resolved and we need to use the resolved bundle path
+        if (user_exe_path)
+        {
+            // Use exactly what the user typed as the first argument when we exec or posix_spawn
+            if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
+            {
+                target_sp->SetArg0 (resolved_bundle_exe_path);
+            }
+            else
+            {
+                // Just use what the user typed
+                target_sp->SetArg0 (user_exe_path);
+            }
+        }
+        if (file.GetDirectory())
+        {
+            FileSpec file_dir;
+            file_dir.GetDirectory() = file.GetDirectory();
+            target_sp->GetExecutableSearchPaths ().Append (file_dir);
+        }
         Mutex::Locker locker(m_target_list_mutex);
         m_selected_target_idx = m_target_list.size();
         m_target_list.push_back(target_sp);
+        
+        
     }
 
     return error;
@@ -266,7 +364,7 @@ TargetList::FindTargetWithExecutableAndA
             {
                 if (exe_arch_ptr)
                 {
-                    if (*exe_arch_ptr != exe_module->GetArchitecture())
+                    if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
                         continue;
                 }
                 target_sp = *pos;

Modified: lldb/branches/lldb-platform-work/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Thread.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Thread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Thread.cpp Thu Jun  6 19:06:43 2013
@@ -7,14 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/lldb-private-log.h"
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Symbol/Function.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
@@ -43,12 +47,205 @@
 using namespace lldb;
 using namespace lldb_private;
 
-Thread::Thread (const ProcessSP &process_sp, lldb::tid_t tid) :
+
+const ThreadPropertiesSP &
+Thread::GetGlobalProperties()
+{
+    static ThreadPropertiesSP g_settings_sp;
+    if (!g_settings_sp)
+        g_settings_sp.reset (new ThreadProperties (true));
+    return g_settings_sp;
+}
+
+static PropertyDefinition
+g_properties[] =
+{
+    { "step-avoid-regexp",  OptionValue::eTypeRegex  , true , REG_EXTENDED, "^std::", NULL, "A regular expression defining functions step-in won't stop in." },
+    { "trace-thread",       OptionValue::eTypeBoolean, false, false, NULL, NULL, "If true, this thread will single-step and log execution." },
+    {  NULL               , OptionValue::eTypeInvalid, false, 0    , NULL, NULL, NULL  }
+};
+
+enum {
+    ePropertyStepAvoidRegex,
+    ePropertyEnableThreadTrace
+};
+
+
+class ThreadOptionValueProperties : public OptionValueProperties
+{
+public:
+    ThreadOptionValueProperties (const ConstString &name) :
+        OptionValueProperties (name)
+    {
+    }
+    
+    // This constructor is used when creating ThreadOptionValueProperties when it
+    // is part of a new lldb_private::Thread instance. It will copy all current
+    // global property values as needed
+    ThreadOptionValueProperties (ThreadProperties *global_properties) :
+        OptionValueProperties(*global_properties->GetValueProperties())
+    {
+    }
+    
+    virtual const Property *
+    GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
+    {
+        // When gettings the value for a key from the thread options, we will always
+        // try and grab the setting from the current thread if there is one. Else we just
+        // use the one from this instance.
+        if (exe_ctx)
+        {
+            Thread *thread = exe_ctx->GetThreadPtr();
+            if (thread)
+            {
+                ThreadOptionValueProperties *instance_properties = static_cast<ThreadOptionValueProperties *>(thread->GetValueProperties().get());
+                if (this != instance_properties)
+                    return instance_properties->ProtectedGetPropertyAtIndex (idx);
+            }
+        }
+        return ProtectedGetPropertyAtIndex (idx);
+    }
+};
+
+
+
+ThreadProperties::ThreadProperties (bool is_global) :
+    Properties ()
+{
+    if (is_global)
+    {
+        m_collection_sp.reset (new ThreadOptionValueProperties(ConstString("thread")));
+        m_collection_sp->Initialize(g_properties);
+    }
+    else
+        m_collection_sp.reset (new ThreadOptionValueProperties(Thread::GetGlobalProperties().get()));
+}
+
+ThreadProperties::~ThreadProperties()
+{
+}
+
+const RegularExpression *
+ThreadProperties::GetSymbolsToAvoidRegexp()
+{
+    const uint32_t idx = ePropertyStepAvoidRegex;
+    return m_collection_sp->GetPropertyAtIndexAsOptionValueRegex (NULL, idx);
+}
+
+bool
+ThreadProperties::GetTraceEnabledState() const
+{
+    const uint32_t idx = ePropertyEnableThreadTrace;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+//------------------------------------------------------------------
+// Thread Event Data
+//------------------------------------------------------------------
+
+
+const ConstString &
+Thread::ThreadEventData::GetFlavorString ()
+{
+    static ConstString g_flavor ("Thread::ThreadEventData");
+    return g_flavor;
+}
+
+Thread::ThreadEventData::ThreadEventData (const lldb::ThreadSP thread_sp) :
+    m_thread_sp (thread_sp),
+    m_stack_id ()
+{
+}
+
+Thread::ThreadEventData::ThreadEventData (const lldb::ThreadSP thread_sp, const StackID &stack_id) :
+    m_thread_sp (thread_sp),
+    m_stack_id (stack_id)
+{
+}
+
+Thread::ThreadEventData::ThreadEventData () :
+    m_thread_sp (),
+    m_stack_id ()
+{
+}
+
+Thread::ThreadEventData::~ThreadEventData ()
+{
+}
+
+void
+Thread::ThreadEventData::Dump (Stream *s) const
+{
+
+}
+
+const Thread::ThreadEventData *
+Thread::ThreadEventData::GetEventDataFromEvent (const Event *event_ptr)
+{
+    if (event_ptr)
+    {
+        const EventData *event_data = event_ptr->GetData();
+        if (event_data && event_data->GetFlavor() == ThreadEventData::GetFlavorString())
+            return static_cast <const ThreadEventData *> (event_ptr->GetData());
+    }
+    return NULL;
+}
+
+ThreadSP
+Thread::ThreadEventData::GetThreadFromEvent (const Event *event_ptr)
+{
+    ThreadSP thread_sp;
+    const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr);
+    if (event_data)
+        thread_sp = event_data->GetThread();
+    return thread_sp;
+}
+
+StackID
+Thread::ThreadEventData::GetStackIDFromEvent (const Event *event_ptr)
+{
+    StackID stack_id;
+    const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr);
+    if (event_data)
+        stack_id = event_data->GetStackID();
+    return stack_id;
+}
+
+StackFrameSP
+Thread::ThreadEventData::GetStackFrameFromEvent (const Event *event_ptr)
+{
+    const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr);
+    StackFrameSP frame_sp;
+    if (event_data)
+    {
+        ThreadSP thread_sp = event_data->GetThread();
+        if (thread_sp)
+        {
+            frame_sp = thread_sp->GetStackFrameList()->GetFrameWithStackID (event_data->GetStackID());
+        }
+    }
+    return frame_sp;
+}
+
+//------------------------------------------------------------------
+// Thread class
+//------------------------------------------------------------------
+
+ConstString &
+Thread::GetStaticBroadcasterClass ()
+{
+    static ConstString class_name ("lldb.thread");
+    return class_name;
+}
+
+Thread::Thread (Process &process, lldb::tid_t tid) :
+    ThreadProperties (false),
     UserID (tid),
-    ThreadInstanceSettings (GetSettingsController()),
-    m_process_wp (process_sp),
-    m_actual_stop_info_sp (),
-    m_index_id (process_sp->GetNextThreadIndexID ()),
+    Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
+    m_process_wp (process.shared_from_this()),
+    m_stop_info_sp (),
+    m_stop_info_stop_id (0),
+    m_index_id (process.GetNextThreadIndexID(tid)),
     m_reg_context_sp (),
     m_state (eStateUnloaded),
     m_state_mutex (Mutex::eMutexTypeRecursive),
@@ -62,23 +259,22 @@ Thread::Thread (const ProcessSP &process
     m_temporary_resume_state (eStateRunning),
     m_unwinder_ap (),
     m_destroy_called (false),
-    m_thread_stop_reason_stop_id (0)
-
+    m_override_should_notify (eLazyBoolCalculate)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
-        log->Printf ("%p Thread::Thread(tid = 0x%4.4llx)", this, GetID());
+        log->Printf ("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")", this, GetID());
 
+    CheckInWithManager();
     QueueFundamentalPlan(true);
-    UpdateInstanceName();
 }
 
 
 Thread::~Thread()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
-        log->Printf ("%p Thread::~Thread(tid = 0x%4.4llx)", this, GetID());
+        log->Printf ("%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")", this, GetID());
     /// If you hit this assert, it means your derived class forgot to call DoDestroy in its destructor.
     assert (m_destroy_called);
 }
@@ -86,43 +282,182 @@ Thread::~Thread()
 void 
 Thread::DestroyThread ()
 {
+    // Tell any plans on the plan stack that the thread is being destroyed since
+    // any active plans that have a thread go away in the middle of might need
+    // to do cleanup.
+    for (auto plan : m_plan_stack)
+        plan->ThreadDestroyed();
+
+    m_destroy_called = true;
     m_plan_stack.clear();
     m_discarded_plan_stack.clear();
     m_completed_plan_stack.clear();
-    m_actual_stop_info_sp.reset();
-    m_destroy_called = true;
+    m_stop_info_sp.reset();
+    m_reg_context_sp.reset();
+    m_unwinder_ap.reset();
+    Mutex::Locker locker(m_frame_mutex);
+    m_curr_frames_sp.reset();
+    m_prev_frames_sp.reset();
 }
 
+void
+Thread::BroadcastSelectedFrameChange(StackID &new_frame_id)
+{
+    if (EventTypeHasListeners(eBroadcastBitSelectedFrameChanged))
+        BroadcastEvent(eBroadcastBitSelectedFrameChanged, new ThreadEventData (this->shared_from_this(), new_frame_id));
+}
+
+uint32_t
+Thread::SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast)
+{
+    uint32_t ret_value = GetStackFrameList()->SetSelectedFrame(frame);
+    if (broadcast)
+        BroadcastSelectedFrameChange(frame->GetStackID());
+    return ret_value;
+}
+
+bool
+Thread::SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast)
+{
+    StackFrameSP frame_sp(GetStackFrameList()->GetFrameAtIndex (frame_idx));
+    if (frame_sp)
+    {
+        GetStackFrameList()->SetSelectedFrame(frame_sp.get());
+        if (broadcast)
+            BroadcastSelectedFrameChange(frame_sp->GetStackID());
+        return true;
+    }
+    else
+        return false;
+}
+
+bool
+Thread::SetSelectedFrameByIndexNoisily (uint32_t frame_idx, Stream &output_stream)
+{
+    const bool broadcast = true;
+    bool success = SetSelectedFrameByIndex (frame_idx, broadcast);
+    if (success)
+    {
+        StackFrameSP frame_sp = GetSelectedFrame();
+        if (frame_sp)
+        {
+            bool already_shown = false;
+            SymbolContext frame_sc(frame_sp->GetSymbolContext(eSymbolContextLineEntry));
+            if (GetProcess()->GetTarget().GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
+            {
+                already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
+            }
+
+            bool show_frame_info = true;
+            bool show_source = !already_shown;
+            return frame_sp->GetStatus (output_stream, show_frame_info, show_source);
+        }
+        return false;
+    }
+    else
+        return false;
+}
+
+
 lldb::StopInfoSP
 Thread::GetStopInfo ()
 {
     ThreadPlanSP plan_sp (GetCompletedPlan());
+    ProcessSP process_sp (GetProcess());
+    const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX;
     if (plan_sp && plan_sp->PlanSucceeded())
+    {
         return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject());
+    }
     else
     {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp 
-            && m_actual_stop_info_sp 
-            && m_actual_stop_info_sp->IsValid()
-            && m_thread_stop_reason_stop_id == process_sp->GetStopID())
-            return m_actual_stop_info_sp;
+        if ((m_stop_info_stop_id == stop_id) ||   // Stop info is valid, just return what we have (even if empty)
+            (m_stop_info_sp && m_stop_info_sp->IsValid()))  // Stop info is valid, just return what we have
+        {
+            return m_stop_info_sp;
+        }
         else
-            return GetPrivateStopReason ();
+        {
+            GetPrivateStopInfo ();
+            return m_stop_info_sp;
+        }
+    }
+}
+
+lldb::StopInfoSP
+Thread::GetPrivateStopInfo ()
+{
+    ProcessSP process_sp (GetProcess());
+    if (process_sp)
+    {
+        const uint32_t process_stop_id = process_sp->GetStopID();
+        if (m_stop_info_stop_id != process_stop_id)
+        {
+            if (m_stop_info_sp)
+            {
+                if (m_stop_info_sp->IsValid()
+                    || IsStillAtLastBreakpointHit()
+                    || GetCurrentPlan()->IsVirtualStep())
+                    SetStopInfo (m_stop_info_sp);
+                else
+                    m_stop_info_sp.reset();
+            }
+
+            if (!m_stop_info_sp)
+            {
+                if (CalculateStopInfo() == false)
+                    SetStopInfo (StopInfoSP());
+            }
+        }
     }
+    return m_stop_info_sp;
+}
+
+
+lldb::StopReason
+Thread::GetStopReason()
+{
+    lldb::StopInfoSP stop_info_sp (GetStopInfo ());
+    if (stop_info_sp)
+        return stop_info_sp->GetStopReason();
+    return eStopReasonNone;
 }
 
+
+
 void
 Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp)
 {
-    m_actual_stop_info_sp = stop_info_sp;
-    if (m_actual_stop_info_sp)
-        m_actual_stop_info_sp->MakeStopInfoValid();
+    m_stop_info_sp = stop_info_sp;
+    if (m_stop_info_sp)
+    {
+        m_stop_info_sp->MakeStopInfoValid();
+        // If we are overriding the ShouldReportStop, do that here:
+        if (m_override_should_notify != eLazyBoolCalculate)
+            m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
+    }
+    
     ProcessSP process_sp (GetProcess());
     if (process_sp)
-        m_thread_stop_reason_stop_id = process_sp->GetStopID();
+        m_stop_info_stop_id = process_sp->GetStopID();
     else
-        m_thread_stop_reason_stop_id = UINT32_MAX;
+        m_stop_info_stop_id = UINT32_MAX;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf("%p: tid = 0x%" PRIx64 ": stop info = %s (stop_id = %u)\n", this, GetID(), stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>", m_stop_info_stop_id);
+}
+
+void
+Thread::SetShouldReportStop (Vote vote)
+{
+    if (vote == eVoteNoOpinion)
+        return;
+    else
+    {
+        m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo);
+        if (m_stop_info_sp)
+            m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
+    }
 }
 
 void
@@ -136,7 +471,7 @@ Thread::SetStopInfoToNothing()
 bool
 Thread::ThreadStoppedForAReason (void)
 {
-    return (bool) GetPrivateStopReason ();
+    return (bool) GetPrivateStopInfo ();
 }
 
 bool
@@ -149,16 +484,25 @@ Thread::CheckpointThreadState (ThreadSta
     ProcessSP process_sp (GetProcess());
     if (process_sp)
         saved_state.orig_stop_id = process_sp->GetStopID();
+    saved_state.current_inlined_depth = GetCurrentInlinedDepth();
+    
     return true;
 }
 
 bool
-Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
+Thread::RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
 {
     RestoreSaveFrameZero(saved_state.register_backup);
+    return true;
+}
+
+bool
+Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
+{
     if (saved_state.stop_info_sp)
         saved_state.stop_info_sp->MakeStopInfoValid();
     SetStopInfo(saved_state.stop_info_sp);
+    GetStackFrameList()->SetCurrentInlinedDepth (saved_state.current_inlined_depth);
     return true;
 }
 
@@ -201,29 +545,37 @@ Thread::SetupForResume ()
         // telling the current plan it will resume, since we might change what the current
         // plan is.
 
-        lldb::addr_t pc = GetRegisterContext()->GetPC();
-        BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-        if (bp_site_sp && bp_site_sp->IsEnabled())
+//      StopReason stop_reason = lldb::eStopReasonInvalid;
+//      StopInfoSP stop_info_sp = GetStopInfo();
+//      if (stop_info_sp.get())
+//          stop_reason = stop_info_sp->GetStopReason();
+//      if (stop_reason == lldb::eStopReasonBreakpoint)
+        lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
+        if (reg_ctx_sp)
         {
-            // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
-            // special to step over a breakpoint.
-                
-            ThreadPlan *cur_plan = GetCurrentPlan();
-
-            if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
+            BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(reg_ctx_sp->GetPC());
+            if (bp_site_sp)
             {
-                ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
-                if (step_bp_plan)
-                {
-                    ThreadPlanSP step_bp_plan_sp;
-                    step_bp_plan->SetPrivate (true);
+                // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
+                // special to step over a breakpoint.
+                    
+                ThreadPlan *cur_plan = GetCurrentPlan();
 
-                    if (GetCurrentPlan()->RunState() != eStateStepping)
+                if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
+                {
+                    ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
+                    if (step_bp_plan)
                     {
-                        step_bp_plan->SetAutoContinue(true);
+                        ThreadPlanSP step_bp_plan_sp;
+                        step_bp_plan->SetPrivate (true);
+
+                        if (GetCurrentPlan()->RunState() != eStateStepping)
+                        {
+                            step_bp_plan->SetAutoContinue(true);
+                        }
+                        step_bp_plan_sp.reset (step_bp_plan);
+                        QueueThreadPlan (step_bp_plan_sp, false);
                     }
-                    step_bp_plan_sp.reset (step_bp_plan);
-                    QueueThreadPlan (step_bp_plan_sp, false);
                 }
             }
         }
@@ -231,23 +583,31 @@ Thread::SetupForResume ()
 }
 
 bool
-Thread::WillResume (StateType resume_state)
+Thread::ShouldResume (StateType resume_state)
 {
     // At this point clear the completed plan stack.
     m_completed_plan_stack.clear();
     m_discarded_plan_stack.clear();
+    m_override_should_notify = eLazyBoolCalculate;
 
-    SetTemporaryResumeState(resume_state);
+    m_temporary_resume_state = resume_state;
+    
+    lldb::ThreadSP backing_thread_sp (GetBackingThread ());
+    if (backing_thread_sp)
+        backing_thread_sp->m_temporary_resume_state = resume_state;
+
+    // Make sure m_stop_info_sp is valid
+    GetPrivateStopInfo();
     
     // This is a little dubious, but we are trying to limit how often we actually fetch stop info from
     // the target, 'cause that slows down single stepping.  So assume that if we got to the point where
     // we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
     // about the fact that we are resuming...
         const uint32_t process_stop_id = GetProcess()->GetStopID();
-    if (m_thread_stop_reason_stop_id == process_stop_id &&
-        (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid()))
+    if (m_stop_info_stop_id == process_stop_id &&
+        (m_stop_info_sp && m_stop_info_sp->IsValid()))
     {
-        StopInfo *stop_info = GetPrivateStopReason().get();
+        StopInfo *stop_info = GetPrivateStopInfo().get();
         if (stop_info)
             stop_info->WillResume (resume_state);
     }
@@ -256,16 +616,34 @@ Thread::WillResume (StateType resume_sta
     // We distinguish between the plan on the top of the stack and the lower
     // plans in case a plan needs to do any special business before it runs.
     
+    bool need_to_resume = false;
     ThreadPlan *plan_ptr = GetCurrentPlan();
-    plan_ptr->WillResume(resume_state, true);
+    if (plan_ptr)
+    {
+        need_to_resume = plan_ptr->WillResume(resume_state, true);
+
+        while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
+        {
+            plan_ptr->WillResume (resume_state, false);
+        }
+        
+        // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info.
+        // In that case, don't reset it here.
+        
+        if (need_to_resume && resume_state != eStateSuspended)
+        {
+            m_stop_info_sp.reset();
+        }
+    }
 
-    while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
+    if (need_to_resume)
     {
-        plan_ptr->WillResume (resume_state, false);
+        ClearStackFrames();
+        // Let Thread subclasses do any special work they need to prior to resuming
+        WillResume (resume_state);
     }
-    
-    m_actual_stop_info_sp.reset();
-    return true;
+
+    return need_to_resume;
 }
 
 void
@@ -274,56 +652,63 @@ Thread::DidResume ()
     SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
 }
 
+void
+Thread::DidStop ()
+{
+    SetState (eStateStopped);
+}
+
 bool
 Thread::ShouldStop (Event* event_ptr)
 {
     ThreadPlan *current_plan = GetCurrentPlan();
+    
     bool should_stop = true;
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     
     if (GetResumeState () == eStateSuspended)
     {
         if (log)
-            log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)", 
+            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
                          __FUNCTION__, 
-                         GetID ());
-//            log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)", 
-//                         __FUNCTION__, 
-//                         GetID (), 
-//                         GetRegisterContext()->GetPC());
+                         GetID (),
+                         GetProtocolID());
         return false;
     }
     
     if (GetTemporaryResumeState () == eStateSuspended)
     {
         if (log)
-            log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)", 
+            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
                          __FUNCTION__, 
-                         GetID ());
-//            log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)", 
-//                         __FUNCTION__, 
-//                         GetID (), 
-//                         GetRegisterContext()->GetPC());
+                         GetID (),
+                         GetProtocolID());
         return false;
     }
     
+    // Based on the current thread plan and process stop info, check if this
+    // thread caused the process to stop. NOTE: this must take place before
+    // the plan is moved from the current plan stack to the completed plan
+    // stack.
     if (ThreadStoppedForAReason() == false)
     {
         if (log)
-            log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since no stop reason)", 
+            log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64 ", should_stop = 0 (ignore since no stop reason)",
                          __FUNCTION__, 
-                         GetID (), 
-                         GetRegisterContext()->GetPC());
+                         GetID (),
+                         GetProtocolID(),
+                         GetRegisterContext() ? GetRegisterContext()->GetPC() : LLDB_INVALID_ADDRESS);
         return false;
     }
-
+    
     if (log)
     {
-        log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx", 
+        log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64,
                      __FUNCTION__, 
-                     GetID (), 
-                     GetRegisterContext()->GetPC());
+                     GetID (),
+                     GetProtocolID (),
+                     GetRegisterContext() ? GetRegisterContext()->GetPC() : LLDB_INVALID_ADDRESS);
         log->Printf ("^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
         StreamString s;
         s.IndentMore();
@@ -337,7 +722,7 @@ Thread::ShouldStop (Event* event_ptr)
     // First query the stop info's ShouldStopSynchronous.  This handles "synchronous" stop reasons, for example the breakpoint
     // command on internal breakpoints.  If a synchronous stop reason says we should not stop, then we don't have to
     // do any more work on this stop.
-    StopInfoSP private_stop_info (GetPrivateStopReason());
+    StopInfoSP private_stop_info (GetPrivateStopInfo());
     if (private_stop_info && private_stop_info->ShouldStopSynchronous(event_ptr) == false)
     {
         if (log)
@@ -345,6 +730,13 @@ Thread::ShouldStop (Event* event_ptr)
         return false;
     }
 
+    // If we've already been restarted, don't query the plans since the state they would examine is not current.
+    if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr))
+        return false;
+
+    // Before the plans see the state of the world, calculate the current inlined depth.
+    GetStackFrameList()->CalculateCurrentInlinedDepth();
+
     // If the base plan doesn't understand why we stopped, then we have to find a plan that does.
     // If that plan is still working, then we don't need to do any more work.  If the plan that explains 
     // the stop is done, then we should pop all the plans below it, and pop it, and then let the plans above it decide
@@ -352,7 +744,7 @@ Thread::ShouldStop (Event* event_ptr)
     
     bool done_processing_current_plan = false;
     
-    if (!current_plan->PlanExplainsStop())
+    if (!current_plan->PlanExplainsStop(event_ptr))
     {
         if (current_plan->TracerExplainsStop())
         {
@@ -366,7 +758,7 @@ Thread::ShouldStop (Event* event_ptr)
             ThreadPlan *plan_ptr = current_plan;
             while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
             {
-                if (plan_ptr->PlanExplainsStop())
+                if (plan_ptr->PlanExplainsStop(event_ptr))
                 {
                     should_stop = plan_ptr->ShouldStop (event_ptr);
                     
@@ -505,26 +897,26 @@ Thread::ShouldReportStop (Event* event_p
     StateType thread_state = GetResumeState ();
     StateType temp_thread_state = GetTemporaryResumeState();
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (thread_state == eStateSuspended || thread_state == eStateInvalid)
     {
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (state was suspended or invalid)", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
     }
 
     if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid)
     {
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (temporary state was suspended or invalid)", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
     }
 
     if (!ThreadStoppedForAReason())
     {
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (thread didn't stop for a reason.)", GetID(), eVoteNoOpinion);
         return eVoteNoOpinion;
     }
 
@@ -532,14 +924,29 @@ Thread::ShouldReportStop (Event* event_p
     {
         // Don't use GetCompletedPlan here, since that suppresses private plans.
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote  for complete stack's back plan\n", GetID());
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote  for complete stack's back plan", GetID());
         return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
     }
     else
     {
+        Vote thread_vote = eVoteNoOpinion;
+        ThreadPlan *plan_ptr = GetCurrentPlan();
+        while (1)
+        {
+            if (plan_ptr->PlanExplainsStop(event_ptr))
+            {
+                thread_vote = plan_ptr->ShouldReportStop(event_ptr);
+                break;
+            }
+            if (PlanIsBasePlan(plan_ptr))
+                break;
+            else
+                plan_ptr = GetPreviousPlan(plan_ptr);
+        }
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote  for current plan\n", GetID());
-        return GetCurrentPlan()->ShouldReportStop (event_ptr);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i for current plan", GetID(), thread_vote);
+
+        return thread_vote;
     }
 }
 
@@ -554,14 +961,15 @@ Thread::ShouldReportRun (Event* event_pt
         return eVoteNoOpinion;
     }
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (m_completed_plan_stack.size() > 0)
     {
         // Don't use GetCompletedPlan here, since that suppresses private plans.
         if (log)
-            log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.", 
+            log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 ", %s): %s being asked whether we should report run.",
                          GetIndexID(), 
                          GetID(),
+                         StateAsCString(GetTemporaryResumeState()),
                          m_completed_plan_stack.back()->GetName());
                          
         return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
@@ -569,9 +977,10 @@ Thread::ShouldReportRun (Event* event_pt
     else
     {
         if (log)
-            log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.", 
+            log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 ", %s): %s being asked whether we should report run.",
                          GetIndexID(), 
                          GetID(),
+                         StateAsCString(GetTemporaryResumeState()),
                          GetCurrentPlan()->GetName());
                          
         return GetCurrentPlan()->ShouldReportRun (event_ptr);
@@ -599,12 +1008,12 @@ Thread::PushPlan (ThreadPlanSP &thread_p
             
         thread_plan_sp->DidPush();
 
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
         {
             StreamString s;
             thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
-            log->Printf("Pushing plan: \"%s\", tid = 0x%4.4llx.",
+            log->Printf("Pushing plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
                         s.GetData(),
                         thread_plan_sp->GetThread().GetID());
         }
@@ -614,16 +1023,16 @@ Thread::PushPlan (ThreadPlanSP &thread_p
 void
 Thread::PopPlan ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
-    if (m_plan_stack.empty())
+    if (m_plan_stack.size() <= 1)
         return;
     else
     {
         ThreadPlanSP &plan = m_plan_stack.back();
         if (log)
         {
-            log->Printf("Popping plan: \"%s\", tid = 0x%4.4llx.", plan->GetName(), plan->GetThread().GetID());
+            log->Printf("Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".", plan->GetName(), plan->GetThread().GetID());
         }
         m_completed_plan_stack.push_back (plan);
         plan->WillPop();
@@ -648,8 +1057,8 @@ Thread::GetCurrentPlan ()
 {
     // There will always be at least the base plan.  If somebody is mucking with a
     // thread with an empty plan stack, we should assert right away.
-    assert (!m_plan_stack.empty());
-
+    if (m_plan_stack.empty())
+        return NULL;
     return m_plan_stack.back().get();
 }
 
@@ -785,10 +1194,10 @@ Thread::DiscardThreadPlansUpToPlan (lldb
 void
 Thread::DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
     {
-        log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_ptr);
+        log->Printf("Discarding thread plans for thread tid = 0x%4.4" PRIx64 ", up to %p", GetID(), up_to_plan_ptr);
     }
 
     int stack_size = m_plan_stack.size();
@@ -826,10 +1235,10 @@ Thread::DiscardThreadPlansUpToPlan (Thre
 void
 Thread::DiscardThreadPlans(bool force)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
     {
-        log->Printf("Discarding thread plans for thread (tid = 0x%4.4llx, force %d)", GetID(), force);
+        log->Printf("Discarding thread plans for thread (tid = 0x%4.4" PRIx64 ", force %d)", GetID(), force);
     }
 
     if (force)
@@ -846,7 +1255,7 @@ Thread::DiscardThreadPlans(bool force)
     {
 
         int master_plan_idx;
-        bool discard;
+        bool discard = true;
 
         // Find the first master plan, see if it wants discarding, and if yes discard up to it.
         for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
@@ -898,6 +1307,28 @@ Thread::PlanIsBasePlan (ThreadPlan *plan
        return m_plan_stack[0].get() == plan_ptr;
 }
 
+Error
+Thread::UnwindInnermostExpression()
+{
+    Error error;
+    int stack_size = m_plan_stack.size();
+    
+    // If the input plan is NULL, discard all plans.  Otherwise make sure this plan is in the
+    // stack, and if so discard up to and including it.
+    
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        if (m_plan_stack[i]->GetKind() == ThreadPlan::eKindCallFunction)
+        {
+            DiscardThreadPlansUpToPlan(m_plan_stack[i].get());
+            return error;
+        }
+    }
+    error.SetErrorString("No expressions currently active on this thread");
+    return error;
+}
+
+
 ThreadPlan *
 Thread::QueueFundamentalPlan (bool abort_other_plans)
 {
@@ -920,28 +1351,41 @@ Thread::QueueThreadPlanForStepSingleInst
 }
 
 ThreadPlan *
-Thread::QueueThreadPlanForStepRange 
+Thread::QueueThreadPlanForStepOverRange
 (
     bool abort_other_plans, 
-    StepType type, 
     const AddressRange &range, 
-    const SymbolContext &addr_context, 
+    const SymbolContext &addr_context,
+    lldb::RunMode stop_other_threads
+)
+{
+    ThreadPlanSP thread_plan_sp;
+    thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
+
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepInRange
+(
+    bool abort_other_plans, 
+    const AddressRange &range, 
+    const SymbolContext &addr_context,
+    const char *step_in_target,
     lldb::RunMode stop_other_threads,
     bool avoid_code_without_debug_info
 )
 {
     ThreadPlanSP thread_plan_sp;
-    if (type == eStepTypeInto)
-    {
-        ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
-        if (avoid_code_without_debug_info)
-            plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
-        else
-            plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
-        thread_plan_sp.reset (plan);
-    }
+    ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
+    if (avoid_code_without_debug_info)
+        plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
     else
-        thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
+        plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
+    if (step_in_target)
+        plan->SetStepInTarget(step_in_target);
+    thread_plan_sp.reset (plan);
 
     QueueThreadPlan (thread_plan_sp, abort_other_plans);
     return thread_plan_sp.get();
@@ -1003,9 +1447,16 @@ Thread::QueueThreadPlanForCallFunction (
                                         Address& function,
                                         lldb::addr_t arg,
                                         bool stop_other_threads,
-                                        bool discard_on_error)
+                                        bool unwind_on_error,
+                                        bool ignore_breakpoints)
 {
-    ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error));
+    ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this,
+                                                             function,
+                                                             ClangASTType(),
+                                                             arg,
+                                                             stop_other_threads,
+                                                             unwind_on_error,
+                                                             ignore_breakpoints));
     QueueThreadPlan (thread_plan_sp, abort_other_plans);
     return thread_plan_sp.get();
 }
@@ -1045,7 +1496,7 @@ Thread::DumpThreadPlans (lldb_private::S
     uint32_t stack_size = m_plan_stack.size();
     int i;
     s->Indent();
-    s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4llx, stack_size = %d\n", GetIndexID(), GetID(), stack_size);
+    s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4" PRIx64 ", stack_size = %d\n", GetIndexID(), GetID(), stack_size);
     for (i = stack_size - 1; i >= 0; i--)
     {
         s->IndentMore();
@@ -1148,6 +1599,10 @@ Thread::ClearStackFrames ()
 {
     Mutex::Locker locker(m_frame_mutex);
 
+    Unwind *unwinder = GetUnwinder ();
+    if (unwinder)
+        unwinder->Clear();
+
     // Only store away the old "reference" StackFrameList if we got all its frames:
     // FIXME: At some point we can try to splice in the frames we have fetched into
     // the new frame as we make it, but let's not try that now.
@@ -1162,6 +1617,114 @@ Thread::GetFrameWithConcreteFrameIndex (
     return GetStackFrameList()->GetFrameWithConcreteFrameIndex (unwind_idx);
 }
 
+
+Error
+Thread::ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp, bool broadcast)
+{
+    StackFrameSP frame_sp = GetStackFrameAtIndex (frame_idx);
+    Error return_error;
+    
+    if (!frame_sp)
+    {
+        return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%" PRIx64 ".", frame_idx, GetID());
+    }
+    
+    return ReturnFromFrame(frame_sp, return_value_sp, broadcast);
+}
+
+Error
+Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp, bool broadcast)
+{
+    Error return_error;
+    
+    if (!frame_sp)
+    {
+        return_error.SetErrorString("Can't return to a null frame.");
+        return return_error;
+    }
+    
+    Thread *thread = frame_sp->GetThread().get();
+    uint32_t older_frame_idx = frame_sp->GetFrameIndex() + 1;
+    StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx);
+    if (!older_frame_sp)
+    {
+        return_error.SetErrorString("No older frame to return to.");
+        return return_error;
+    }
+    
+    if (return_value_sp)
+    {    
+        lldb::ABISP abi = thread->GetProcess()->GetABI();
+        if (!abi)
+        {
+            return_error.SetErrorString("Could not find ABI to set return value.");
+            return return_error;
+        }
+        SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextFunction);
+        
+        // FIXME: ValueObject::Cast doesn't currently work correctly, at least not for scalars.
+        // Turn that back on when that works.
+        if (0 && sc.function != NULL)
+        {
+            Type *function_type = sc.function->GetType();
+            if (function_type)
+            {
+                clang_type_t return_type = sc.function->GetReturnClangType();
+                if (return_type)
+                {
+                    ClangASTType ast_type (function_type->GetClangAST(), return_type);
+                    StreamString s;
+                    ast_type.DumpTypeDescription(&s);
+                    ValueObjectSP cast_value_sp = return_value_sp->Cast(ast_type);
+                    if (cast_value_sp)
+                    {
+                        cast_value_sp->SetFormat(eFormatHex);
+                        return_value_sp = cast_value_sp;
+                    }
+                }
+            }
+        }
+
+        return_error = abi->SetReturnValueObject(older_frame_sp, return_value_sp);
+        if (!return_error.Success())
+            return return_error;
+    }
+    
+    // Now write the return registers for the chosen frame:
+    // Note, we can't use ReadAllRegisterValues->WriteAllRegisterValues, since the read & write
+    // cook their data
+    
+    StackFrameSP youngest_frame_sp = thread->GetStackFrameAtIndex(0);
+    if (youngest_frame_sp)
+    {
+        lldb::RegisterContextSP reg_ctx_sp (youngest_frame_sp->GetRegisterContext());
+        if (reg_ctx_sp)
+        {
+            bool copy_success = reg_ctx_sp->CopyFromRegisterContext(older_frame_sp->GetRegisterContext());
+            if (copy_success)
+            {
+                thread->DiscardThreadPlans(true);
+                thread->ClearStackFrames();
+                if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged))
+                    BroadcastEvent(eBroadcastBitStackChanged, new ThreadEventData (this->shared_from_this()));
+            }
+            else
+            {
+                return_error.SetErrorString("Could not reset register values.");
+            }
+        }
+        else
+        {
+            return_error.SetErrorString("Frame has no register context.");
+        }
+    }
+    else
+    {
+        return_error.SetErrorString("Returned past top frame.");
+    }
+    return return_error;
+}
+
 void
 Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
 {
@@ -1184,72 +1747,21 @@ Thread::DumpUsingSettingsFormat (Stream
 
     const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat();
     assert (thread_format);
-    const char *end = NULL;
     Debugger::FormatPrompt (thread_format, 
                             frame_sp ? &frame_sc : NULL,
                             &exe_ctx, 
                             NULL,
-                            strm, 
-                            &end);
+                            strm);
 }
 
 void
 Thread::SettingsInitialize ()
 {
-    UserSettingsController::InitializeSettingsController (GetSettingsController(),
-                                                          SettingsController::global_settings_table,
-                                                          SettingsController::instance_settings_table);
-                                                          
-    // Now call SettingsInitialize() on each 'child' setting of Thread.
-    // Currently there are none.
 }
 
 void
 Thread::SettingsTerminate ()
 {
-    // Must call SettingsTerminate() on each 'child' setting of Thread before terminating Thread settings.
-    // Currently there are none.
-    
-    // Now terminate Thread Settings.
-    
-    UserSettingsControllerSP &usc = GetSettingsController();
-    UserSettingsController::FinalizeSettingsController (usc);
-    usc.reset();
-}
-
-UserSettingsControllerSP &
-Thread::GetSettingsController ()
-{
-    static UserSettingsControllerSP g_settings_controller_sp;
-    if (!g_settings_controller_sp)
-    {
-        g_settings_controller_sp.reset (new Thread::SettingsController);
-        // The first shared pointer to Target::SettingsController in
-        // g_settings_controller_sp must be fully created above so that 
-        // the TargetInstanceSettings can use a weak_ptr to refer back 
-        // to the master setttings controller
-        InstanceSettingsSP default_instance_settings_sp (new ThreadInstanceSettings (g_settings_controller_sp, 
-                                                                                     false, 
-                                                                                     InstanceSettings::GetDefaultName().AsCString()));
-
-        g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp);
-    }
-    return g_settings_controller_sp;
-}
-
-void
-Thread::UpdateInstanceName ()
-{
-    StreamString sstr;
-    const char *name = GetName();
-
-    if (name && name[0] != '\0')
-        sstr.Printf ("%s", name);
-    else if ((GetIndexID() != 0) || (GetID() != 0))
-        sstr.Printf ("0x%4.4x", GetIndexID());
-
-    if (sstr.GetSize() > 0)
-	Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData());
 }
 
 lldb::StackFrameSP
@@ -1263,14 +1775,16 @@ Thread::StopReasonAsCString (lldb::StopR
 {
     switch (reason)
     {
-    case eStopReasonInvalid:      return "invalid";
-    case eStopReasonNone:         return "none";
-    case eStopReasonTrace:        return "trace";
-    case eStopReasonBreakpoint:   return "breakpoint";
-    case eStopReasonWatchpoint:   return "watchpoint";
-    case eStopReasonSignal:       return "signal";
-    case eStopReasonException:    return "exception";
-    case eStopReasonPlanComplete: return "plan complete";
+    case eStopReasonInvalid:       return "invalid";
+    case eStopReasonNone:          return "none";
+    case eStopReasonTrace:         return "trace";
+    case eStopReasonBreakpoint:    return "breakpoint";
+    case eStopReasonWatchpoint:    return "watchpoint";
+    case eStopReasonSignal:        return "signal";
+    case eStopReasonException:     return "exception";
+    case eStopReasonExec:          return "exec";
+    case eStopReasonPlanComplete:  return "plan complete";
+    case eStopReasonThreadExiting: return "thread exiting";
     }
 
 
@@ -1362,7 +1876,9 @@ Thread::SaveFrameZeroState (RegisterChec
     if (frame_sp)
     {
         checkpoint.SetStackID(frame_sp->GetStackID());
-        return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData());
+        lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
+        if (reg_ctx_sp)
+            return reg_ctx_sp->ReadAllRegisterValues (checkpoint.GetData());
     }
     return false;
 }
@@ -1370,16 +1886,27 @@ Thread::SaveFrameZeroState (RegisterChec
 bool
 Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
 {
+    return ResetFrameZeroRegisters (checkpoint.GetData());
+}
+
+bool
+Thread::ResetFrameZeroRegisters (lldb::DataBufferSP register_data_sp)
+{
     lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
     if (frame_sp)
     {
-        bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
-
-        // Clear out all stack frames as our world just changed.
-        ClearStackFrames();
-        frame_sp->GetRegisterContext()->InvalidateIfNeeded(true);
+        lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
+        if (reg_ctx_sp)
+        {
+            bool ret = reg_ctx_sp->WriteAllRegisterValues (register_data_sp);
 
-        return ret;
+            // Clear out all stack frames as our world just changed.
+            ClearStackFrames();
+            reg_ctx_sp->InvalidateIfNeeded(true);
+            if (m_unwinder_ap.get())
+                m_unwinder_ap->Clear();
+            return ret;
+        }
     }
     return false;
 }
@@ -1417,230 +1944,25 @@ Thread::Flush ()
     m_reg_context_sp.reset();
 }
 
-
-#pragma mark "Thread::SettingsController"
-//--------------------------------------------------------------
-// class Thread::SettingsController
-//--------------------------------------------------------------
-
-Thread::SettingsController::SettingsController () :
-    UserSettingsController ("thread", Process::GetSettingsController())
-{
-}
-
-Thread::SettingsController::~SettingsController ()
-{
-}
-
-lldb::InstanceSettingsSP
-Thread::SettingsController::CreateInstanceSettings (const char *instance_name)
-{
-    lldb::InstanceSettingsSP new_settings_sp (new ThreadInstanceSettings (GetSettingsController(),
-                                                                          false, 
-                                                                          instance_name));
-    return new_settings_sp;
-}
-
-#pragma mark "ThreadInstanceSettings"
-//--------------------------------------------------------------
-// class ThreadInstanceSettings
-//--------------------------------------------------------------
-
-ThreadInstanceSettings::ThreadInstanceSettings (const UserSettingsControllerSP &owner_sp, bool live_instance, const char *name) :
-    InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 
-    m_avoid_regexp_ap (),
-    m_trace_enabled (false)
-{
-    // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
-    // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers.
-    // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
-    // This is true for CreateInstanceName() too.
-   
-    if (GetInstanceName() == InstanceSettings::InvalidName())
-    {
-        ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
-        owner_sp->RegisterInstanceSettings (this);
-    }
-
-    if (live_instance)
-    {
-        CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name),false);
-    }
-}
-
-ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) :
-    InstanceSettings (Thread::GetSettingsController(), CreateInstanceName().AsCString()),
-    m_avoid_regexp_ap (),
-    m_trace_enabled (rhs.m_trace_enabled)
-{
-    if (m_instance_name != InstanceSettings::GetDefaultName())
-    {
-        UserSettingsControllerSP owner_sp (m_owner_wp.lock());
-        if (owner_sp)
-        {
-            CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false);
-            owner_sp->RemovePendingSettings (m_instance_name);
-        }
-    }
-    if (rhs.m_avoid_regexp_ap.get() != NULL)
-        m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
-}
-
-ThreadInstanceSettings::~ThreadInstanceSettings ()
-{
-}
-
-ThreadInstanceSettings&
-ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs)
-{
-    if (this != &rhs)
-    {
-        if (rhs.m_avoid_regexp_ap.get() != NULL)
-            m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
-        else
-            m_avoid_regexp_ap.reset(NULL);
-    }
-    m_trace_enabled = rhs.m_trace_enabled;
-    return *this;
-}
-
-
-void
-ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
-                                                         const char *index_value,
-                                                         const char *value,
-                                                         const ConstString &instance_name,
-                                                         const SettingEntry &entry,
-                                                         VarSetOperationType op,
-                                                         Error &err,
-                                                         bool pending)
+bool
+Thread::IsStillAtLastBreakpointHit ()
 {
-    if (var_name == StepAvoidRegexpVarName())
-    {
-        std::string regexp_text;
-        if (m_avoid_regexp_ap.get() != NULL)
-            regexp_text.append (m_avoid_regexp_ap->GetText());
-        UserSettingsController::UpdateStringVariable (op, regexp_text, value, err);
-        if (regexp_text.empty())
-            m_avoid_regexp_ap.reset();
-        else
-        {
-            m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str()));
-            
-        }
-    }
-    else if (var_name == GetTraceThreadVarName())
-    {
-        bool success;
-        bool result = Args::StringToBoolean(value, false, &success);
-
-        if (success)
-        {
-            m_trace_enabled = result;
-            if (!pending)
+    // If we are currently stopped at a breakpoint, always return that stopinfo and don't reset it.
+    // This allows threads to maintain their breakpoint stopinfo, such as when thread-stepping in
+    // multithreaded programs.
+    if (m_stop_info_sp) {
+        StopReason stop_reason = m_stop_info_sp->GetStopReason();
+        if (stop_reason == lldb::eStopReasonBreakpoint) {
+            uint64_t value = m_stop_info_sp->GetValue();
+            lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
+            if (reg_ctx_sp)
             {
-                Thread *myself = static_cast<Thread *> (this);
-                myself->EnableTracer(m_trace_enabled, true);
+                lldb::addr_t pc = reg_ctx_sp->GetPC();
+                BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+                if (bp_site_sp && value == bp_site_sp->GetID())
+                    return true;
             }
         }
-        else
-        {
-            err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value);
-        }
-
-    }
-}
-
-void
-ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
-                                               bool pending)
-{
-    if (new_settings.get() == NULL)
-        return;
-
-    ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get();
-    if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL)
-        m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText()));
-    else 
-        m_avoid_regexp_ap.reset ();
-}
-
-bool
-ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
-                                                  const ConstString &var_name,
-                                                  StringList &value,
-                                                  Error *err)
-{
-    if (var_name == StepAvoidRegexpVarName())
-    {
-        if (m_avoid_regexp_ap.get() != NULL)
-        {
-            std::string regexp_text("\"");
-            regexp_text.append(m_avoid_regexp_ap->GetText());
-            regexp_text.append ("\"");
-            value.AppendString (regexp_text.c_str());
-        }
-
-    }
-    else if (var_name == GetTraceThreadVarName())
-    {
-        value.AppendString(m_trace_enabled ? "true" : "false");
-    }
-    else
-    {
-        if (err)
-            err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
-        return false;
     }
-    return true;
-}
-
-const ConstString
-ThreadInstanceSettings::CreateInstanceName ()
-{
-    static int instance_count = 1;
-    StreamString sstr;
-
-    sstr.Printf ("thread_%d", instance_count);
-    ++instance_count;
-
-    const ConstString ret_val (sstr.GetData());
-    return ret_val;
-}
-
-const ConstString &
-ThreadInstanceSettings::StepAvoidRegexpVarName ()
-{
-    static ConstString step_avoid_var_name ("step-avoid-regexp");
-
-    return step_avoid_var_name;
-}
-
-const ConstString &
-ThreadInstanceSettings::GetTraceThreadVarName ()
-{
-    static ConstString trace_thread_var_name ("trace-thread");
-
-    return trace_thread_var_name;
+    return false;
 }
-
-//--------------------------------------------------
-// SettingsController Variable Tables
-//--------------------------------------------------
-
-SettingEntry
-Thread::SettingsController::global_settings_table[] =
-{
-  //{ "var-name",    var-type  ,        "default", enum-table, init'd, hidden, "help-text"},
-    {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
-};
-
-
-SettingEntry
-Thread::SettingsController::instance_settings_table[] =
-{
-  //{ "var-name",    var-type,              "default",      enum-table, init'd, hidden, "help-text"},
-    { "step-avoid-regexp",  eSetVarTypeString,      "",  NULL,       false,  false,  "A regular expression defining functions step-in won't stop in." },
-    { "trace-thread",  eSetVarTypeBoolean,      "false",  NULL,       false,  false,  "If true, this thread will single-step and log execution." },
-    {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
-};

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp Thu Jun  6 19:06:43 2013
@@ -11,6 +11,7 @@
 #include <algorithm>
 
 #include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/ThreadList.h"
 #include "lldb/Target/Thread.h"
@@ -24,16 +25,14 @@ ThreadList::ThreadList (Process *process
     m_process (process),
     m_stop_id (0),
     m_threads(),
-    m_threads_mutex (Mutex::eMutexTypeRecursive),
     m_selected_tid (LLDB_INVALID_THREAD_ID)
 {
 }
 
 ThreadList::ThreadList (const ThreadList &rhs) :
-    m_process (),
-    m_stop_id (),
+    m_process (rhs.m_process),
+    m_stop_id (rhs.m_stop_id),
     m_threads (),
-    m_threads_mutex (Mutex::eMutexTypeRecursive),
     m_selected_tid ()
 {
     // Use the assignment operator since it uses the mutex
@@ -47,8 +46,7 @@ ThreadList::operator = (const ThreadList
     {
         // Lock both mutexes to make sure neither side changes anyone on us
         // while the assignement occurs
-        Mutex::Locker locker_lhs(m_threads_mutex);
-        Mutex::Locker locker_rhs(rhs.m_threads_mutex);
+        Mutex::Locker locker(GetMutex());
         m_process = rhs.m_process;
         m_stop_id = rhs.m_stop_id;
         m_threads = rhs.m_threads;
@@ -60,6 +58,10 @@ ThreadList::operator = (const ThreadList
 
 ThreadList::~ThreadList()
 {
+    // Clear the thread list. Clear will take the mutex lock
+    // which will ensure that if anyone is using the list
+    // they won't get it removed while using it.
+    Clear();
 }
 
 
@@ -79,14 +81,14 @@ ThreadList::SetStopID (uint32_t stop_id)
 void
 ThreadList::AddThread (const ThreadSP &thread_sp)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     m_threads.push_back(thread_sp);
 }
 
 uint32_t
 ThreadList::GetSize (bool can_update)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     if (can_update)
         m_process->UpdateThreadListIfNeeded();
     return m_threads.size();
@@ -95,7 +97,7 @@ ThreadList::GetSize (bool can_update)
 ThreadSP
 ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     if (can_update)
         m_process->UpdateThreadListIfNeeded();
 
@@ -108,7 +110,7 @@ ThreadList::GetThreadAtIndex (uint32_t i
 ThreadSP
 ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
 
     if (can_update)
         m_process->UpdateThreadListIfNeeded();
@@ -128,12 +130,81 @@ ThreadList::FindThreadByID (lldb::tid_t
 }
 
 ThreadSP
+ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetProtocolID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+
+ThreadSP
+ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            m_threads.erase(m_threads.begin()+idx);
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
+ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetProtocolID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            m_threads.erase(m_threads.begin()+idx);
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
 ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
 {
     ThreadSP thread_sp;
     if (thread_ptr)
     {
-        Mutex::Locker locker(m_threads_mutex);
+        Mutex::Locker locker(GetMutex());
 
         uint32_t idx = 0;
         const uint32_t num_threads = m_threads.size();
@@ -154,7 +225,7 @@ ThreadList::GetThreadSPForThreadPtr (Thr
 ThreadSP
 ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
 
     if (can_update)
         m_process->UpdateThreadListIfNeeded();
@@ -175,38 +246,77 @@ ThreadList::FindThreadByIndexID (uint32_
 bool
 ThreadList::ShouldStop (Event *event_ptr)
 {
-    Mutex::Locker locker(m_threads_mutex);
-
     // Running events should never stop, obviously...
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
-    bool should_stop = false;    
-    m_process->UpdateThreadListIfNeeded();
+    // The ShouldStop method of the threads can do a whole lot of work,
+    // running breakpoint commands & conditions, etc.  So we don't want
+    // to keep the ThreadList locked the whole time we are doing this.
+    // FIXME: It is possible that running code could cause new threads
+    // to be created.  If that happens we will miss asking them whether
+    // then should stop.  This is not a big deal, since we haven't had
+    // a chance to hang any interesting operations on those threads yet.
+    
+    collection threads_copy;
+    {
+        // Scope for locker
+        Mutex::Locker locker(GetMutex());
 
-    collection::iterator pos, end = m_threads.end();
+        m_process->UpdateThreadListIfNeeded();
+        threads_copy = m_threads;
+    }
+
+    collection::iterator pos, end = threads_copy.end();
 
     if (log)
     {
         log->PutCString("");
-        log->Printf ("ThreadList::%s: %zu threads", __FUNCTION__, m_threads.size());
+        log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
     }
 
-    for (pos = m_threads.begin(); pos != end; ++pos)
+    bool did_anybody_stop_for_a_reason = false;
+    bool should_stop = false;
+    
+    // Now we run through all the threads and get their stop info's.  We want to make sure to do this first before
+    // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a
+    // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly.
+    // We don't need to use it here, we just want to make sure it gets computed.
+    
+    for (pos = threads_copy.begin(); pos != end; ++pos)
     {
         ThreadSP thread_sp(*pos);
+        thread_sp->GetStopInfo();
+    }
+    
+    for (pos = threads_copy.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        
+        did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
         
         const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
         if (thread_should_stop)
             should_stop |= true;
     }
 
+    // We should never get a stop for which no thread had a stop reason, but sometimes we do see this -
+    // for instance when we first connect to a remote stub.  In that case we should stop, since we can't figure out
+    // the right thing to do and stopping gives the user control over what to do in this instance.
+    
+    if (!should_stop && !did_anybody_stop_for_a_reason)
+    {
+        should_stop = true;
+        if (log)
+            log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__);
+    }
+    
     if (log)
         log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop);
 
     if (should_stop)
     {
-        for (pos = m_threads.begin(); pos != end; ++pos)
+        for (pos = threads_copy.begin(); pos != end; ++pos)
         {
             ThreadSP thread_sp(*pos);
             thread_sp->WillStop ();
@@ -219,16 +329,16 @@ ThreadList::ShouldStop (Event *event_ptr
 Vote
 ThreadList::ShouldReportStop (Event *event_ptr)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
 
     Vote result = eVoteNoOpinion;
     m_process->UpdateThreadListIfNeeded();
     collection::iterator pos, end = m_threads.end();
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (log)
-        log->Printf ("ThreadList::%s %zu threads", __FUNCTION__, m_threads.size());
+        log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
 
     // Run through the threads and ask whether we should report this event.
     // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
@@ -253,7 +363,7 @@ ThreadList::ShouldReportStop (Event *eve
             else
             {
                 if (log)
-                    log->Printf ("ThreadList::%s thread 0x%4.4llx: voted %s, but lost out because result was %s", 
+                    log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
                                  __FUNCTION__,
                                  thread_sp->GetID (), 
                                  GetVoteAsCString (vote),
@@ -267,11 +377,24 @@ ThreadList::ShouldReportStop (Event *eve
     return result;
 }
 
+void
+ThreadList::SetShouldReportStop (Vote vote)
+{
+    Mutex::Locker locker(GetMutex());
+    m_process->UpdateThreadListIfNeeded();
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        thread_sp->SetShouldReportStop (vote);
+    }
+}
+
 Vote
 ThreadList::ShouldReportRun (Event *event_ptr)
 {
 
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
 
     Vote result = eVoteNoOpinion;
     m_process->UpdateThreadListIfNeeded();
@@ -280,7 +403,7 @@ ThreadList::ShouldReportRun (Event *even
     // Run through the threads and ask whether we should report this event.
     // The rule is NO vote wins over everything, a YES vote wins over no opinion.
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     
     for (pos = m_threads.begin(); pos != end; ++pos)
     {
@@ -296,7 +419,7 @@ ThreadList::ShouldReportRun (Event *even
                     break;
                 case eVoteNo:
                     if (log)
-                        log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4llx) says don't report.", 
+                        log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
                                      (*pos)->GetIndexID(), 
                                      (*pos)->GetID());
                     result = eVoteNo;
@@ -310,7 +433,7 @@ ThreadList::ShouldReportRun (Event *even
 void
 ThreadList::Clear()
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     m_stop_id = 0;
     m_threads.clear();
     m_selected_tid = LLDB_INVALID_THREAD_ID;
@@ -319,7 +442,7 @@ ThreadList::Clear()
 void
 ThreadList::Destroy()
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     const uint32_t num_threads = m_threads.size();
     for (uint32_t idx = 0; idx < num_threads; ++idx)
     {
@@ -330,11 +453,11 @@ ThreadList::Destroy()
 void
 ThreadList::RefreshStateAfterStop ()
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
 
     m_process->UpdateThreadListIfNeeded();
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log && log->GetVerbose())
         log->Printf ("Turning off notification of new threads while single stepping a thread.");
 
@@ -348,7 +471,7 @@ ThreadList::DiscardThreadPlans ()
 {
     // You don't need to update the thread list here, because only threads
     // that you currently know about have any thread plans.
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
 
     collection::iterator pos, end = m_threads.end();
     for (pos = m_threads.begin(); pos != end; ++pos)
@@ -362,9 +485,8 @@ ThreadList::WillResume ()
     // Run through the threads and perform their momentary actions.
     // But we only do this for threads that are running, user suspended
     // threads stay where they are.
-    bool success = true;
 
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     m_process->UpdateThreadListIfNeeded();
 
     collection::iterator pos, end = m_threads.end();
@@ -383,6 +505,8 @@ ThreadList::WillResume ()
         if ((*pos)->GetResumeState() != eStateSuspended &&
                  (*pos)->GetCurrentPlan()->StopOthers())
         {
+            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
+                continue;
             wants_solo_run = true;
             break;
         }
@@ -390,14 +514,14 @@ ThreadList::WillResume ()
 
     if (wants_solo_run)
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log && log->GetVerbose())
             log->Printf ("Turning on notification of new threads while single stepping a thread.");
         m_process->StartNoticingNewThreads();
     }
     else
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log && log->GetVerbose())
             log->Printf ("Turning off notification of new threads while single stepping a thread.");
         m_process->StopNoticingNewThreads();
@@ -413,6 +537,8 @@ ThreadList::WillResume ()
         if ((*pos)->GetResumeState() != eStateSuspended
             && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers()))
         {
+            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
+                continue;
             (*pos)->SetupForResume ();
         }
     }
@@ -424,7 +550,6 @@ ThreadList::WillResume ()
     
     run_me_only_list.SetStopID(m_process->GetStopID());
 
-    ThreadSP immediate_thread_sp;
     bool run_only_current_thread = false;
 
     for (pos = m_threads.begin(); pos != end; ++pos)
@@ -433,6 +558,9 @@ ThreadList::WillResume ()
         if (thread_sp->GetResumeState() != eStateSuspended &&
                  thread_sp->GetCurrentPlan()->StopOthers())
         {
+            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
+                continue;
+
             // You can't say "stop others" and also want yourself to be suspended.
             assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
 
@@ -449,18 +577,9 @@ ThreadList::WillResume ()
 
     }
 
-    if (immediate_thread_sp)
-    {
-        for (pos = m_threads.begin(); pos != end; ++pos)
-        {
-            ThreadSP thread_sp(*pos);
-            if (thread_sp.get() == immediate_thread_sp.get())
-                thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
-            else
-                thread_sp->WillResume (eStateSuspended);
-        }
-    }
-    else if (run_me_only_list.GetSize (false) == 0)
+    bool need_to_resume = true;
+    
+    if (run_me_only_list.GetSize (false) == 0)
     {
         // Everybody runs as they wish:
         for (pos = m_threads.begin(); pos != end; ++pos)
@@ -471,7 +590,8 @@ ThreadList::WillResume ()
                 run_state = thread_sp->GetCurrentPlan()->RunState();
             else
                 run_state = eStateSuspended;
-            thread_sp->WillResume(run_state);
+            if (!thread_sp->ShouldResume(run_state))
+                need_to_resume = false;
         }
     }
     else
@@ -497,19 +617,22 @@ ThreadList::WillResume ()
         {
             ThreadSP thread_sp(*pos);
             if (thread_sp == thread_to_run)
-                thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+            {
+                if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
+                    need_to_resume = false;
+            }
             else
-                thread_sp->WillResume (eStateSuspended);
+                thread_sp->ShouldResume (eStateSuspended);
         }
     }
 
-    return success;
+    return need_to_resume;
 }
 
 void
 ThreadList::DidResume ()
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     collection::iterator pos, end = m_threads.end();
     for (pos = m_threads.begin(); pos != end; ++pos)
     {
@@ -521,10 +644,31 @@ ThreadList::DidResume ()
     }
 }
 
+void
+ThreadList::DidStop ()
+{
+    Mutex::Locker locker(GetMutex());
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        // Notify threads that the process just stopped.
+        // Note, this currently assumes that all threads in the list
+        // stop when the process stops.  In the future we will want to support
+        // a debugging model where some threads continue to run while others
+        // are stopped.  We either need to handle that somehow here or
+        // create a special thread list containing only threads which will
+        // stop in the code that calls this method (currently
+        // Process::SetPrivateState).
+        ThreadSP thread_sp(*pos);
+        if (StateIsRunningState(thread_sp->GetState()))
+            thread_sp->DidStop ();
+    }
+}
+
 ThreadSP
 ThreadList::GetSelectedThread ()
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     ThreadSP thread_sp = FindThreadByID(m_selected_tid);
     if (!thread_sp.get())
     {
@@ -537,9 +681,9 @@ ThreadList::GetSelectedThread ()
 }
 
 bool
-ThreadList::SetSelectedThreadByID (lldb::tid_t tid)
+ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     ThreadSP selected_thread_sp(FindThreadByID(tid));
     if  (selected_thread_sp)
     {
@@ -549,13 +693,16 @@ ThreadList::SetSelectedThreadByID (lldb:
     else
         m_selected_tid = LLDB_INVALID_THREAD_ID;
 
+    if (notify)
+        NotifySelectedThreadChanged(m_selected_tid);
+    
     return m_selected_tid != LLDB_INVALID_THREAD_ID;
 }
 
 bool
-ThreadList::SetSelectedThreadByIndexID (uint32_t index_id)
+ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
 {
-    Mutex::Locker locker(m_threads_mutex);
+    Mutex::Locker locker(GetMutex());
     ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
     if  (selected_thread_sp.get())
     {
@@ -565,18 +712,29 @@ ThreadList::SetSelectedThreadByIndexID (
     else
         m_selected_tid = LLDB_INVALID_THREAD_ID;
 
+    if (notify)
+        NotifySelectedThreadChanged(m_selected_tid);
+    
     return m_selected_tid != LLDB_INVALID_THREAD_ID;
 }
 
 void
+ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
+{
+    ThreadSP selected_thread_sp (FindThreadByID(tid));
+    if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
+        selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
+                                           new Thread::ThreadEventData(selected_thread_sp));
+}
+
+void
 ThreadList::Update (ThreadList &rhs)
 {
     if (this != &rhs)
     {
         // Lock both mutexes to make sure neither side changes anyone on us
         // while the assignement occurs
-        Mutex::Locker locker_lhs(m_threads_mutex);
-        Mutex::Locker locker_rhs(rhs.m_threads_mutex);
+        Mutex::Locker locker(GetMutex());
         m_process = rhs.m_process;
         m_stop_id = rhs.m_stop_id;
         m_threads.swap(rhs.m_threads);
@@ -613,9 +771,15 @@ ThreadList::Update (ThreadList &rhs)
 void
 ThreadList::Flush ()
 {
-    Mutex::Locker locker(m_threads_mutex);    
+    Mutex::Locker locker(GetMutex());
     collection::iterator pos, end = m_threads.end();
     for (pos = m_threads.begin(); pos != end; ++pos)
         (*pos)->Flush ();
 }
 
+Mutex &
+ThreadList::GetMutex ()
+{
+    return m_process->m_thread_mutex;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Target/ThreadPlan.h"
 
 // C Includes
@@ -34,6 +36,7 @@ ThreadPlan::ThreadPlan(ThreadPlanKind ki
     m_kind (kind),
     m_name (name),
     m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
+    m_cached_plan_explains_stop (eLazyBoolCalculate),
     m_plan_complete (false),
     m_plan_private (false),
     m_okay_to_discard (true),
@@ -51,6 +54,21 @@ ThreadPlan::~ThreadPlan()
 }
 
 bool
+ThreadPlan::PlanExplainsStop (Event *event_ptr)
+{
+    if (m_cached_plan_explains_stop == eLazyBoolCalculate)
+    {
+        bool actual_value = DoPlanExplainsStop(event_ptr);
+        m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo;
+        return actual_value;
+    }
+    else
+    {
+        return m_cached_plan_explains_stop == eLazyBoolYes;
+    }
+}
+
+bool
 ThreadPlan::IsPlanComplete ()
 {
     Mutex::Locker locker(m_plan_complete_mutex);
@@ -77,7 +95,7 @@ ThreadPlan::MischiefManaged ()
 Vote
 ThreadPlan::ShouldReportStop (Event *event_ptr)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (m_stop_vote == eVoteNoOpinion)
     {
@@ -129,9 +147,11 @@ ThreadPlan::SetStopOthers (bool new_valu
 bool
 ThreadPlan::WillResume (StateType resume_state, bool current_plan)
 {
+    m_cached_plan_explains_stop = eLazyBoolCalculate;
+    
     if (current_plan)
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
         if (log)
         {
@@ -139,7 +159,7 @@ ThreadPlan::WillResume (StateType resume
             addr_t pc = reg_ctx->GetPC();
             addr_t sp = reg_ctx->GetSP();
             addr_t fp = reg_ctx->GetFP();
-            log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, "
+            log->Printf("%s Thread #%u: tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
                         "plan = '%s', state = %s, stop others = %d", 
                         __FUNCTION__,
                         m_thread.GetIndexID(), 
@@ -152,7 +172,7 @@ ThreadPlan::WillResume (StateType resume
                         StopOthers());
         }
     }
-    return true;
+    return DoWillResume (resume_state, current_plan);
 }
 
 lldb::user_id_t

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanBase.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanBase.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanBase.cpp Thu Jun  6 19:06:43 2013
@@ -68,7 +68,7 @@ ThreadPlanBase::ValidatePlan (Stream *er
 }
 
 bool
-ThreadPlanBase::PlanExplainsStop ()
+ThreadPlanBase::DoPlanExplainsStop (Event *event_ptr)
 {
     // The base plan should defer to its tracer, since by default it
     // always handles the stop.
@@ -78,18 +78,34 @@ ThreadPlanBase::PlanExplainsStop ()
         return true;
 }
 
+Vote
+ThreadPlanBase::ShouldReportStop(Event *event_ptr)
+{
+    StopInfoSP stop_info_sp = m_thread.GetStopInfo ();
+    if (stop_info_sp)
+    {
+        bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
+        if (should_notify)
+            return eVoteYes;
+        else
+            return eVoteNoOpinion;
+    }
+    else
+        return eVoteNoOpinion;
+}
+
 bool
 ThreadPlanBase::ShouldStop (Event *event_ptr)
 {
     m_stop_vote = eVoteYes;
     m_run_vote = eVoteYes;
 
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     if (stop_info_sp)
     {
-        StopReason reason = stop_info_sp->GetStopReason();
+        StopReason reason = stop_info_sp->GetStopReason ();
         switch (reason)
         {
         case eStopReasonInvalid:
@@ -101,13 +117,13 @@ ThreadPlanBase::ShouldStop (Event *event
 
         case eStopReasonBreakpoint:
         case eStopReasonWatchpoint:
-            if (stop_info_sp->ShouldStop(event_ptr))
+            if (stop_info_sp->ShouldStopSynchronous(event_ptr))
             {
                 // If we are going to stop for a breakpoint, then unship the other plans
                 // at this point.  Don't force the discard, however, so Master plans can stay
                 // in place if they want to.
                 if (log)
-                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (breakpoint hit.)", m_thread.GetID());
+                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (breakpoint hit.)", m_thread.GetID());
                 m_thread.DiscardThreadPlans(false);
                 return true;
             }
@@ -135,15 +151,24 @@ ThreadPlanBase::ShouldStop (Event *event
             // If we crashed, discard thread plans and stop.  Don't force the discard, however,
             // since on rerun the target may clean up this exception and continue normally from there.
                 if (log)
-                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (exception.)", m_thread.GetID());
+                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exception.)", m_thread.GetID());
+            m_thread.DiscardThreadPlans(false);
+            return true;
+
+        case eStopReasonExec:
+            // If we crashed, discard thread plans and stop.  Don't force the discard, however,
+            // since on rerun the target may clean up this exception and continue normally from there.
+            if (log)
+                log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exec.)", m_thread.GetID());
             m_thread.DiscardThreadPlans(false);
             return true;
 
+        case eStopReasonThreadExiting:
         case eStopReasonSignal:
             if (stop_info_sp->ShouldStop(event_ptr))
             {
                 if (log)
-                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (signal.)", m_thread.GetID());
+                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (signal.)", m_thread.GetID());
                 m_thread.DiscardThreadPlans(false);
                 return true;
             }
@@ -192,7 +217,7 @@ ThreadPlanBase::WillStop ()
 }
 
 bool 
-ThreadPlanBase::WillResume (lldb::StateType resume_state, bool current_plan)
+ThreadPlanBase::DoWillResume (lldb::StateType resume_state, bool current_plan)
 {
     // Reset these to the default values so we don't set them wrong, then not get asked
     // for a while, then return the wrong answer.

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp Thu Jun  6 19:06:43 2013
@@ -19,7 +19,9 @@
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -42,6 +44,7 @@ ThreadPlanCallFunction::ConstructorSetup
 {
     SetIsMasterPlan (true);
     SetOkayToDiscard (false);
+    SetPrivate (true);
 
     ProcessSP process_sp (thread.GetProcess());
     if (!process_sp)
@@ -54,7 +57,7 @@ ThreadPlanCallFunction::ConstructorSetup
     
     TargetSP target_sp (thread.CalculateTarget());
 
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
     
     SetBreakpoints();
     
@@ -65,8 +68,9 @@ ThreadPlanCallFunction::ConstructorSetup
     process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
     if (!error.Success())
     {
+        m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
         if (log)
-            log->Printf ("ThreadPlanCallFunction(%p): Trying to put the stack in unreadable memory at: 0x%llx.", this, m_function_sp);
+            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
         return false;
     }
     
@@ -74,8 +78,9 @@ ThreadPlanCallFunction::ConstructorSetup
 
     if (exe_module == NULL)
     {
+        m_constructor_errors.Printf ("Can't execute code without an executable module.");
         if (log)
-            log->Printf ("ThreadPlanCallFunction(%p): Can't execute code without an executable module.", this);
+            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
         return false;
     }
     else
@@ -83,17 +88,21 @@ ThreadPlanCallFunction::ConstructorSetup
         ObjectFile *objectFile = exe_module->GetObjectFile();
         if (!objectFile)
         {
+            m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 
+                                         exe_module->GetFileSpec().GetFilename().AsCString());
+
             if (log)
-                log->Printf ("ThreadPlanCallFunction(%p): Could not find object file for module \"%s\".", 
-                             this, exe_module->GetFileSpec().GetFilename().AsCString());
+                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
             return false;
         }
+        
         m_start_addr = objectFile->GetEntryPointAddress();
         if (!m_start_addr.IsValid())
         {
+            m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 
+                                         exe_module->GetFileSpec().GetFilename().AsCString());
             if (log)
-                log->Printf ("ThreadPlanCallFunction(%p): Could not find entry point address for executable module \"%s\".", 
-                             this, exe_module->GetFileSpec().GetFilename().AsCString());
+                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
             return false;
         }
     }
@@ -106,35 +115,35 @@ ThreadPlanCallFunction::ConstructorSetup
 
     if (!thread.CheckpointThreadState (m_stored_thread_state))
     {
+        m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
         if (log)
-            log->Printf ("ThreadPlanCallFunction(%p): Setting up ThreadPlanCallFunction, failed to checkpoint thread state.", this);
+            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
         return false;
     }
-    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
-    thread.SetStopInfoToNothing();
-    
     function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
     
     return true;
 }
 
 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
-                                                Address &function,
+                                                const Address &function,
                                                 const ClangASTType &return_type,
                                                 addr_t arg,
                                                 bool stop_other_threads,
-                                                bool discard_on_error,
+                                                bool unwind_on_error,
+                                                bool ignore_breakpoints,
                                                 addr_t *this_arg,
                                                 addr_t *cmd_arg) :
     ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
     m_valid (false),
     m_stop_other_threads (stop_other_threads),
     m_function_addr (function),
-    m_function_sp (NULL),
+    m_function_sp (0),
     m_return_type (return_type),
     m_takedown_done (false),
     m_stop_address (LLDB_INVALID_ADDRESS),
-    m_discard_on_error (discard_on_error)
+    m_unwind_on_error (unwind_on_error),
+    m_ignore_breakpoints (ignore_breakpoints)
 {
     lldb::addr_t start_load_addr;
     ABI *abi;
@@ -180,10 +189,11 @@ ThreadPlanCallFunction::ThreadPlanCallFu
 
 
 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
-                                                Address &function,
+                                                const Address &function,
                                                 const ClangASTType &return_type,
                                                 bool stop_other_threads,
-                                                bool discard_on_error,
+                                                bool unwind_on_error,
+                                                bool ignore_breakpoints,
                                                 addr_t *arg1_ptr,
                                                 addr_t *arg2_ptr,
                                                 addr_t *arg3_ptr,
@@ -194,10 +204,12 @@ ThreadPlanCallFunction::ThreadPlanCallFu
     m_valid (false),
     m_stop_other_threads (stop_other_threads),
     m_function_addr (function),
-    m_function_sp(NULL),
+    m_function_sp (0),
     m_return_type (return_type),
     m_takedown_done (false),
-    m_stop_address (LLDB_INVALID_ADDRESS)
+    m_stop_address (LLDB_INVALID_ADDRESS),
+    m_unwind_on_error (unwind_on_error),
+    m_ignore_breakpoints (ignore_breakpoints)
 {
     lldb::addr_t start_load_addr;
     ABI *abi;
@@ -226,13 +238,13 @@ ThreadPlanCallFunction::ThreadPlanCallFu
 
 ThreadPlanCallFunction::~ThreadPlanCallFunction ()
 {
-    DoTakedown(true);
+    DoTakedown(PlanSucceeded());
 }
 
 void
 ThreadPlanCallFunction::ReportRegisterState (const char *message)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
     if (log)
     {
         StreamString strm;
@@ -260,7 +272,7 @@ ThreadPlanCallFunction::ReportRegisterSt
 void
 ThreadPlanCallFunction::DoTakedown (bool success)
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
     
     if (!m_valid)
     {
@@ -283,11 +295,11 @@ ThreadPlanCallFunction::DoTakedown (bool
             }
         }
         if (log)
-            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4llx, m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
+            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
         m_takedown_done = true;
         m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
-        m_real_stop_info_sp = GetPrivateStopReason();
-        m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
+        m_real_stop_info_sp = GetPrivateStopInfo ();
+        m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
         SetPlanComplete(success);
         ClearBreakpoints();
         if (log && log->GetVerbose())
@@ -297,14 +309,14 @@ ThreadPlanCallFunction::DoTakedown (bool
     else
     {
         if (log)
-            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4llx, m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
+            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
     }
 }
 
 void
 ThreadPlanCallFunction::WillPop ()
 {
-    DoTakedown(true);
+    DoTakedown(PlanSucceeded());
 }
 
 void
@@ -317,7 +329,7 @@ ThreadPlanCallFunction::GetDescription (
     else
     {
         TargetSP target_sp (m_thread.CalculateTarget());
-        s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(target_sp.get()));
+        s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
     }
 }
 
@@ -325,20 +337,43 @@ bool
 ThreadPlanCallFunction::ValidatePlan (Stream *error)
 {
     if (!m_valid)
+    {
+        if (error)
+        {
+            if (m_constructor_errors.GetSize() > 0)
+                error->PutCString (m_constructor_errors.GetData());
+            else
+                error->PutCString ("Unknown error");
+        }
         return false;
+    }
 
     return true;
 }
 
+
+Vote
+ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
+{
+    if (m_takedown_done || IsPlanComplete())
+        return eVoteYes;
+    else
+        return ThreadPlan::ShouldReportStop(event_ptr);
+}
+
 bool
-ThreadPlanCallFunction::PlanExplainsStop ()
+ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
 {    
-    m_real_stop_info_sp = GetPrivateStopReason();
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
+    m_real_stop_info_sp = GetPrivateStopInfo ();
     
     // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
     // we answer yes.
-    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
+    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
+    {
+        SetPlanComplete();
         return true;
+    }
     
     // Check if the breakpoint is one of ours.
     
@@ -347,16 +382,15 @@ ThreadPlanCallFunction::PlanExplainsStop
         stop_reason = eStopReasonNone;
     else
         stop_reason = m_real_stop_info_sp->GetStopReason();
+    if (log)
+        log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
 
     if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
         return true;
     
-    // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
-    if (!m_discard_on_error)
-        return false;
-            
-    // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
-    // If it is not an internal breakpoint, consult OkayToDiscard.
+    // We control breakpoints separately from other "stop reasons."  So first,
+    // check the case where we stopped for an internal breakpoint, in that case, continue on.
+    // If it is not an internal breakpoint, consult m_ignore_breakpoints.
     
     
     if (stop_reason == eStopReasonBreakpoint)
@@ -373,6 +407,8 @@ ThreadPlanCallFunction::PlanExplainsStop
             for (uint32_t i = 0; i < num_owners; i++)
             {
                 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+                if (log)
+                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
                 
                 if (!bp.IsInternal())
                 {
@@ -381,16 +417,32 @@ ThreadPlanCallFunction::PlanExplainsStop
                 }
             }
             if (is_internal)
+            {
+                if (log)
+                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
                 return false;
+            }
         }
-        
-        if (m_discard_on_error)
+
+        if (m_ignore_breakpoints)
         {
-            DoTakedown(false);
+            if (log)
+                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
+            m_real_stop_info_sp->OverrideShouldStop(false);
             return true;
         }
         else
+        {
+            if (log)
+                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
+            m_real_stop_info_sp->OverrideShouldStop(true);
             return false;
+        }
+    }
+    else if (!m_unwind_on_error)
+    {
+        // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
+        return false;
     }
     else
     {
@@ -398,30 +450,38 @@ ThreadPlanCallFunction::PlanExplainsStop
         // If we want to discard the plan, then we say we explain the stop
         // but if we are going to be discarded, let whoever is above us
         // explain the stop.
-        if (m_subplan_sp)
+        // But don't discard the plan if the stop would restart itself (for instance if it is a
+        // signal that is set not to stop.  Check that here first.  We just say we explain the stop
+        // but aren't done and everything will continue on from there.
+        
+        if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
         {
-            if (m_discard_on_error)
+            SetPlanComplete(false);
+            if (m_subplan_sp)
             {
-                DoTakedown(false);
-                return true;
+                if (m_unwind_on_error)
+                    return true;
+                else
+                    return false;
             }
             else
                 return false;
         }
         else
-            return false;
+            return true;
     }
 }
 
 bool
 ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
 {
-    if (IsPlanComplete() || PlanExplainsStop())
+    // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete.
+    // We need to do that here to make sure our state is correct.
+    DoPlanExplainsStop(event_ptr);
+    
+    if (IsPlanComplete())
     {
         ReportRegisterState ("Function completed.  Register state was:");
-        
-        DoTakedown(true);
-        
         return true;
     }
     else
@@ -458,6 +518,11 @@ ThreadPlanCallFunction::DidPush ()
 {
 //#define SINGLE_STEP_EXPRESSIONS
     
+    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
+    // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
+    
+    GetThread().SetStopInfoToNothing();
+    
 #ifndef SINGLE_STEP_EXPRESSIONS
     m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
     
@@ -475,10 +540,10 @@ ThreadPlanCallFunction::WillStop ()
 bool
 ThreadPlanCallFunction::MischiefManaged ()
 {
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    
     if (IsPlanComplete())
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
         if (log)
             log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);
 
@@ -519,15 +584,31 @@ ThreadPlanCallFunction::ClearBreakpoints
 bool
 ThreadPlanCallFunction::BreakpointsExplainStop()
 {
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
-    
-    if (m_cxx_language_runtime &&
-        m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
-        return true;
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     
-    if (m_objc_language_runtime &&
-        m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
+    if ((m_cxx_language_runtime &&
+            m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
+       ||(m_objc_language_runtime &&
+            m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
+    {
+        Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
+        if (log)
+            log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
+        
+        SetPlanComplete(false);
+        
+        // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
+        // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
+        stop_info_sp->OverrideShouldStop (true);
         return true;
+    }
     
     return false;
 }
+
+bool
+ThreadPlanCallFunction::RestoreThreadState()
+{
+    return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
+}
+

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallUserExpression.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallUserExpression.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallUserExpression.cpp Thu Jun  6 19:06:43 2013
@@ -40,11 +40,12 @@ ThreadPlanCallUserExpression::ThreadPlan
                                                 Address &function,
                                                 lldb::addr_t arg,
                                                 bool stop_other_threads,
-                                                bool discard_on_error,
+                                                bool unwind_on_error,
+                                                bool ignore_breakpoints,
                                                 lldb::addr_t *this_arg,
                                                 lldb::addr_t *cmd_arg,
                                                 ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
-    ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, discard_on_error, this_arg, cmd_arg),
+    ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, unwind_on_error, ignore_breakpoints, this_arg, cmd_arg),
     m_user_expression_sp (user_expression_sp)
 {
     // User expressions are generally "User generated" so we should set them up to stop when done.
@@ -66,12 +67,16 @@ StopInfoSP
 ThreadPlanCallUserExpression::GetRealStopInfo()
 {
     StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo();
-    lldb::addr_t addr = GetStopAddress();
-    DynamicCheckerFunctions *checkers = m_thread.GetProcess()->GetDynamicCheckers();
-    StreamString s;
     
-    if (checkers && checkers->DoCheckersExplainStop(addr, s))
-        stop_info_sp->SetDescription(s.GetData());
+    if (stop_info_sp)
+    {
+        lldb::addr_t addr = GetStopAddress();
+        DynamicCheckerFunctions *checkers = m_thread.GetProcess()->GetDynamicCheckers();
+        StreamString s;
+        
+        if (checkers && checkers->DoCheckersExplainStop(addr, s))
+            stop_info_sp->SetDescription(s.GetData());
+    }
 
     return stop_info_sp;
 }

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanRunToAddress.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanRunToAddress.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanRunToAddress.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanRunToAddress.cpp Thu Jun  6 19:06:43 2013
@@ -93,6 +93,7 @@ ThreadPlanRunToAddress::SetInitialBreakp
         {
             m_break_ids[i] = breakpoint->GetID();
             breakpoint->SetThreadID(m_thread.GetID());
+            breakpoint->SetBreakpointKind("run-to-address");
         }
     }
 }
@@ -187,7 +188,7 @@ ThreadPlanRunToAddress::ValidatePlan (St
 }
 
 bool
-ThreadPlanRunToAddress::PlanExplainsStop ()
+ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr)
 {
     return AtOurAddress();
 }
@@ -225,7 +226,7 @@ ThreadPlanRunToAddress::WillStop ()
 bool
 ThreadPlanRunToAddress::MischiefManaged ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (AtOurAddress())
     {

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanShouldStopHere.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanShouldStopHere.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanShouldStopHere.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanShouldStopHere.cpp Thu Jun  6 19:06:43 2013
@@ -51,7 +51,7 @@ ThreadPlanShouldStopHere::InvokeShouldSt
     if (m_callback)
     {
         ThreadPlan *return_plan = m_callback (m_owner, m_flags, m_baton);
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
         {
             lldb::addr_t current_addr = m_owner->GetThread().GetRegisterContext()->GetPC(0);
@@ -60,11 +60,11 @@ ThreadPlanShouldStopHere::InvokeShouldSt
             {
                 StreamString s;
                 return_plan->GetDescription (&s, lldb::eDescriptionLevelFull);
-                log->Printf ("ShouldStopHere callback found a step out plan from 0x%llx: %s.", current_addr, s.GetData()); 
+                log->Printf ("ShouldStopHere callback found a step out plan from 0x%" PRIx64 ": %s.", current_addr, s.GetData());
             }
             else
             {
-                log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%llx.", current_addr);
+                log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%" PRIx64 ".", current_addr);
             }
         }
         return return_plan;

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInRange.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInRange.cpp Thu Jun  6 19:06:43 2013
@@ -46,7 +46,25 @@ ThreadPlanStepInRange::ThreadPlanStepInR
 ) :
     ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
     ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
-    m_step_past_prologue (true)
+    m_step_past_prologue (true),
+    m_virtual_step (false)
+{
+    SetFlagsToDefault ();
+}
+
+ThreadPlanStepInRange::ThreadPlanStepInRange
+(
+    Thread &thread,
+    const AddressRange &range,
+    const SymbolContext &addr_context,
+    const char *step_into_target,
+    lldb::RunMode stop_others
+) :
+    ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
+    ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
+    m_step_past_prologue (true),
+    m_virtual_step (false),
+    m_step_into_target (step_into_target)
 {
     SetFlagsToDefault ();
 }
@@ -64,13 +82,14 @@ ThreadPlanStepInRange::GetDescription (S
     {
         s->Printf ("Stepping through range (stepping into functions): ");
         DumpRanges(s);
+        s->Printf ("targeting %s.", m_step_into_target.AsCString());
     }
 }
 
 bool
 ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     m_no_more_plans = false;
     
     if (log)
@@ -86,113 +105,123 @@ ThreadPlanStepInRange::ShouldStop (Event
         
     ThreadPlan* new_plan = NULL;
 
-    // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
-    // continuing...
-    
-    bool stop_others;
-    if (m_stop_others != lldb::eAllThreads)
-        stop_others = true;
-    else
-        stop_others = false;
-        
-    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
-    
-    if (frame_order == eFrameCompareOlder)
+    if (m_virtual_step)
     {
-        // If we're in an older frame then we should stop.
-        //
-        // A caveat to this is if we think the frame is older but we're actually in a trampoline.
-        // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
-        // in a trampoline we think the frame is older because the trampoline confused the backtracer.
-        new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-        if (new_plan == NULL)
-            return true;
-        else if (log)
-        {
-            log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
-        }
-
-    }
-    else if (frame_order == eFrameCompareEqual && InSymbol())
-    {
-        // If we are not in a place we should step through, we're done.
-        // One tricky bit here is that some stubs don't push a frame, so we have to check
-        // both the case of a frame that is younger, or the same as this frame.  
-        // However, if the frame is the same, and we are still in the symbol we started
-        // in, the we don't need to do this.  This first check isn't strictly necessary,
-        // but it is more efficient.
-        
-        // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
-        // stepping.
-        if (InRange())
-        {
-            SetNextBranchBreakpoint();
-            return false;
-        }
-    
-        SetPlanComplete();
-        return true;
+        // If we've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
+        // we're done.
+        new_plan = InvokeShouldStopHereCallback();
     }
-    
-    // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
-    ClearNextBranchBreakpoint();
-    
-    // We may have set the plan up above in the FrameIsOlder section:
-    
-    if (new_plan == NULL)
-        new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-    
-    if (log)
+    else
     {
-        if (new_plan != NULL)
-            log->Printf ("Found a step through plan: %s", new_plan->GetName());
+        // Stepping through should be done running other threads in general, since we're setting a breakpoint and
+        // continuing.  So only stop others if we are explicitly told to do so.
+        
+        bool stop_others;
+        if (m_stop_others == lldb::eOnlyThisThread)
+            stop_others = false;
         else
-            log->Printf ("No step through plan found.");
-    }
-    
-    // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
-    // But only do that if we actually have stepped in.
-    if (!new_plan && frame_order == eFrameCompareYounger)
-        new_plan = InvokeShouldStopHereCallback();
-
-    // If we've stepped in and we are going to stop here, check to see if we were asked to
-    // run past the prologue, and if so do that.
-    
-    if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue)
-    {
-        lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
-        if (curr_frame)
-        {
-            size_t bytes_to_skip = 0;
-            lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
-            Address func_start_address;
-            
-            SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+            stop_others = true;
             
-            if (sc.function)
+        FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+        
+        if (frame_order == eFrameCompareOlder)
+        {
+            // If we're in an older frame then we should stop.
+            //
+            // A caveat to this is if we think the frame is older but we're actually in a trampoline.
+            // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
+            // in a trampoline we think the frame is older because the trampoline confused the backtracer.
+            new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
+            if (new_plan == NULL)
+                return true;
+            else if (log)
             {
-                func_start_address = sc.function->GetAddressRange().GetBaseAddress();
-                if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
-                    bytes_to_skip = sc.function->GetPrologueByteSize();
+                log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
             }
-            else if (sc.symbol)
+
+        }
+        else if (frame_order == eFrameCompareEqual && InSymbol())
+        {
+            // If we are not in a place we should step through, we're done.
+            // One tricky bit here is that some stubs don't push a frame, so we have to check
+            // both the case of a frame that is younger, or the same as this frame.  
+            // However, if the frame is the same, and we are still in the symbol we started
+            // in, the we don't need to do this.  This first check isn't strictly necessary,
+            // but it is more efficient.
+            
+            // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
+            // stepping.
+            if (InRange())
             {
-                func_start_address = sc.symbol->GetAddress();
-                if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
-                    bytes_to_skip = sc.symbol->GetPrologueByteSize();
+                SetNextBranchBreakpoint();
+                return false;
             }
-            
-            if (bytes_to_skip != 0)
+        
+            SetPlanComplete();
+            m_no_more_plans = true;
+            return true;
+        }
+        
+        // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
+        ClearNextBranchBreakpoint();
+        
+        // We may have set the plan up above in the FrameIsOlder section:
+        
+        if (new_plan == NULL)
+            new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
+        
+        if (log)
+        {
+            if (new_plan != NULL)
+                log->Printf ("Found a step through plan: %s", new_plan->GetName());
+            else
+                log->Printf ("No step through plan found.");
+        }
+        
+        // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
+        // But only do that if we actually have stepped in.
+        if (!new_plan && frame_order == eFrameCompareYounger)
+            new_plan = InvokeShouldStopHereCallback();
+
+        // If we've stepped in and we are going to stop here, check to see if we were asked to
+        // run past the prologue, and if so do that.
+        
+        if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue)
+        {
+            lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
+            if (curr_frame)
             {
-                func_start_address.Slide (bytes_to_skip);
-                log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
-                if (log)
-                    log->Printf ("Pushing past prologue ");
-                    
-                new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
+                size_t bytes_to_skip = 0;
+                lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
+                Address func_start_address;
+                
+                SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+                
+                if (sc.function)
+                {
+                    func_start_address = sc.function->GetAddressRange().GetBaseAddress();
+                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
+                        bytes_to_skip = sc.function->GetPrologueByteSize();
+                }
+                else if (sc.symbol)
+                {
+                    func_start_address = sc.symbol->GetAddress();
+                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
+                        bytes_to_skip = sc.symbol->GetPrologueByteSize();
+                }
+                
+                if (bytes_to_skip != 0)
+                {
+                    func_start_address.Slide (bytes_to_skip);
+                    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+                    if (log)
+                        log->Printf ("Pushing past prologue ");
+                        
+                    new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
+                }
             }
         }
-    }
+     }
     
      if (new_plan == NULL)
      {
@@ -234,9 +263,7 @@ ThreadPlanStepInRange::FrameMatchesAvoid
 {
     StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get();
 
-    RegularExpression *avoid_regexp_to_use;
-    
-    avoid_regexp_to_use = m_avoid_regexp_ap.get();
+    const RegularExpression *avoid_regexp_to_use = m_avoid_regexp_ap.get();
     if (avoid_regexp_to_use == NULL)
         avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp();
         
@@ -247,7 +274,30 @@ ThreadPlanStepInRange::FrameMatchesAvoid
         {
             const char *frame_function_name = sc.GetFunctionName().GetCString();
             if (frame_function_name)
-               return avoid_regexp_to_use->Execute(frame_function_name);
+            {
+                size_t num_matches = 0;
+                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                if (log)
+                    num_matches = 1;
+                
+                RegularExpression::Match regex_match(num_matches);
+
+                bool return_value = avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
+                if (return_value)
+                {
+                    if (log)
+                    {
+                        std::string match;
+                        regex_match.GetMatchAtIndex(frame_function_name,0, match);
+                        log->Printf ("Stepping out of function \"%s\" because it matches the avoid regexp \"%s\" - match substring: \"%s\".",
+                                     frame_function_name,
+                                     avoid_regexp_to_use->GetText(),
+                                     match.c_str());
+                    }
+
+                }
+                return return_value;
+            }
         }
     }
     return false;
@@ -258,7 +308,7 @@ ThreadPlanStepInRange::DefaultShouldStop
 {
     bool should_step_out = false;
     StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (flags.Test(eAvoidNoDebug))
     {
@@ -271,22 +321,55 @@ ThreadPlanStepInRange::DefaultShouldStop
         }
     }
     
-    if (!should_step_out)
+    if (current_plan->GetKind() == eKindStepInRange)
     {
-        if (current_plan->GetKind() == eKindStepInRange)
+        ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
+        if (step_in_range_plan->m_step_into_target)
+        {
+            SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
+            if (sc.symbol != NULL)
+            {
+                // First try an exact match, since that's cheap with ConstStrings.  Then do a strstr compare.
+                if (step_in_range_plan->m_step_into_target == sc.GetFunctionName())
+                {
+                    should_step_out = false;
+                }
+                else
+                {
+                    const char *target_name = step_in_range_plan->m_step_into_target.AsCString();
+                    const char *function_name = sc.GetFunctionName().AsCString();
+                    
+                    if (function_name == NULL)
+                        should_step_out = true;
+                    else if (strstr (function_name, target_name) == NULL)
+                        should_step_out = true;
+                }
+                if (log && should_step_out)
+                    log->Printf("Stepping out of frame %s which did not match step into target %s.",
+                                sc.GetFunctionName().AsCString(),
+                                step_in_range_plan->m_step_into_target.AsCString());
+            }
+        }
+        
+        if (!should_step_out)
         {
             ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
+            // Don't log the should_step_out here, it's easier to do it in FrameMatchesAvoidRegexp.
             should_step_out = step_in_range_plan->FrameMatchesAvoidRegexp ();
         }
     }
     
+    
     if (should_step_out)
     {
         // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions.
+        // We really should have all plans take the tri-state for "stop others" so we can do the right
+        // thing.  For now let's be safe and always run others when we are likely to run arbitrary code.
+        const bool stop_others = false;
         return current_plan->GetThread().QueueThreadPlanForStepOut (false, 
                                                                     NULL, 
                                                                     true, 
-                                                                    current_plan->StopOthers(), 
+                                                                    stop_others,
                                                                     eVoteNo, 
                                                                     eVoteNoOpinion,
                                                                     0); // Frame index
@@ -296,39 +379,93 @@ ThreadPlanStepInRange::DefaultShouldStop
 }
 
 bool
-ThreadPlanStepInRange::PlanExplainsStop ()
+ThreadPlanStepInRange::DoPlanExplainsStop (Event *event_ptr)
 {
     // We always explain a stop.  Either we've just done a single step, in which
     // case we'll do our ordinary processing, or we stopped for some
     // reason that isn't handled by our sub-plans, in which case we want to just stop right
     // away.
-    // We also set ourselves complete when we stop for this sort of unintended reason, but mark
-    // success as false so we don't end up being the reason for the stop.
+    // In general, we don't want to mark the plan as complete for unexplained stops.
+    // For instance, if you step in to some code with no debug info, so you step out
+    // and in the course of that hit a breakpoint, then you want to stop & show the user
+    // the breakpoint, but not unship the step in plan, since you still may want to complete that
+    // plan when you continue.  This is particularly true when doing "step in to target function."
+    // stepping.
     //
     // The only variation is that if we are doing "step by running to next branch" in which case
     // if we hit our branch breakpoint we don't set the plan to complete.
+            
+    bool return_value;
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
-    if (stop_info_sp)
+    if (m_virtual_step)
+    {
+        return_value = true;
+    }
+    else
     {
-        StopReason reason = stop_info_sp->GetStopReason();
+        StopInfoSP stop_info_sp = GetPrivateStopInfo ();
+        if (stop_info_sp)
+        {
+            StopReason reason = stop_info_sp->GetStopReason();
+
+            switch (reason)
+            {
+            case eStopReasonBreakpoint:
+                if (NextRangeBreakpointExplainsStop(stop_info_sp))
+                {
+                    return_value = true;
+                    break;
+                }
+            case eStopReasonWatchpoint:
+            case eStopReasonSignal:
+            case eStopReasonException:
+            case eStopReasonExec:
+            case eStopReasonThreadExiting:
+                {
+                    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                    if (log)
+                        log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
+                }
+                return_value = false;
+                break;
+            default:
+                return_value = true;
+                break;
+            }
+        }
+        else
+            return_value = true;
+    }
+    
+    return return_value;
+}
 
-        switch (reason)
+bool
+ThreadPlanStepInRange::DoWillResume (lldb::StateType resume_state, bool current_plan)
+{
+    if (resume_state == eStateStepping && current_plan)
+    {
+        // See if we are about to step over a virtual inlined call.
+        bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
+        if (step_without_resume)
         {
-        case eStopReasonBreakpoint:
-            if (NextRangeBreakpointExplainsStop(stop_info_sp))
-                return true;
-        case eStopReasonWatchpoint:
-        case eStopReasonSignal:
-        case eStopReasonException:
+            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
             if (log)
-                log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
-            SetPlanComplete(false);
-            break;
-        default:
-            break;
+                log->Printf ("ThreadPlanStepInRange::DoWillResume: returning false, inline_depth: %d",
+                             m_thread.GetCurrentInlinedDepth());
+            SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
+            
+            // FIXME: Maybe it would be better to create a InlineStep stop reason, but then
+            // the whole rest of the world would have to handle that stop reason.
+            m_virtual_step = true;
         }
+        return !step_without_resume;
     }
     return true;
 }
+
+bool
+ThreadPlanStepInRange::IsVirtualStep()
+{
+  return m_virtual_step;
+}

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp Thu Jun  6 19:06:43 2013
@@ -81,9 +81,9 @@ ThreadPlanStepInstruction::ValidatePlan
 }
 
 bool
-ThreadPlanStepInstruction::PlanExplainsStop ()
+ThreadPlanStepInstruction::DoPlanExplainsStop (Event *event_ptr)
 {
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     if (stop_info_sp)
     {
         StopReason reason = stop_info_sp->GetStopReason();
@@ -100,7 +100,7 @@ ThreadPlanStepInstruction::ShouldStop (E
 {
     if (m_step_over)
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         
         StackID cur_frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
         
@@ -131,10 +131,14 @@ ThreadPlanStepInstruction::ShouldStop (E
                     s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
                     log->Printf("%s.", s.GetData());
                 }
+                
+                // StepInstruction should probably have the tri-state RunMode, but for now it is safer to
+                // run others.
+                const bool stop_others = false;
                 m_thread.QueueThreadPlanForStepOut(false,
                                                    NULL,
                                                    true,
-                                                   m_stop_other_threads,
+                                                   stop_others,
                                                    eVoteNo,
                                                    eVoteNoOpinion,
                                                    0);
@@ -186,7 +190,7 @@ ThreadPlanStepInstruction::MischiefManag
 {
     if (IsPlanComplete())
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
             log->Printf("Completed single instruction step plan.");
         ThreadPlan::MischiefManaged ();

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp Thu Jun  6 19:06:43 2013
@@ -18,6 +18,9 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Type.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
@@ -104,6 +107,7 @@ ThreadPlanStepOut::ThreadPlanStepOut
         {
             return_bp->SetThreadID(m_thread.GetID());
             m_return_bp_id = return_bp->GetID();
+            return_bp->SetBreakpointKind ("step-out");
         }
         
         if (immediate_return_from_sp)
@@ -145,7 +149,7 @@ ThreadPlanStepOut::GetDescription (Strea
         else if (m_step_through_inline_plan_sp)
             s->Printf ("Stepping out by stepping through inlined function.");
         else
-            s->Printf ("Stepping out from address 0x%llx to return address 0x%llx using breakpoint site %d",
+            s->Printf ("Stepping out from address 0x%" PRIx64 " to return address 0x%" PRIx64 " using breakpoint site %d",
                        (uint64_t)m_step_from_insn,
                        (uint64_t)m_return_addr,
                        m_return_bp_id);
@@ -170,7 +174,7 @@ ThreadPlanStepOut::ValidatePlan (Stream
 }
 
 bool
-ThreadPlanStepOut::PlanExplainsStop ()
+ThreadPlanStepOut::DoPlanExplainsStop (Event *event_ptr)
 {
     // If one of our child plans just finished, then we do explain the stop.
     if (m_step_out_plan_sp)
@@ -196,7 +200,7 @@ ThreadPlanStepOut::PlanExplainsStop ()
     // We don't explain signals or breakpoints (breakpoints that handle stepping in or
     // out will be handled by a child plan.
     
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     if (stop_info_sp)
     {
         StopReason reason = stop_info_sp->GetStopReason();
@@ -248,6 +252,8 @@ ThreadPlanStepOut::PlanExplainsStop ()
         case eStopReasonWatchpoint:
         case eStopReasonSignal:
         case eStopReasonException:
+        case eStopReasonExec:
+        case eStopReasonThreadExiting:
             return false;
 
         default:
@@ -330,9 +336,8 @@ ThreadPlanStepOut::GetPlanRunState ()
 }
 
 bool
-ThreadPlanStepOut::WillResume (StateType resume_state, bool current_plan)
+ThreadPlanStepOut::DoWillResume (StateType resume_state, bool current_plan)
 {
-    ThreadPlan::WillResume (resume_state, current_plan);
     if (m_step_out_plan_sp || m_step_through_inline_plan_sp)
         return true;
         
@@ -372,7 +377,7 @@ ThreadPlanStepOut::MischiefManaged ()
         // reason and we're now stopping for some other reason altogether, then we're done
         // with this step out operation.
 
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
             log->Printf("Completed step out plan.");
         if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
@@ -400,7 +405,7 @@ ThreadPlanStepOut::QueueInlinedStepPlan
     if (!immediate_return_from_sp)
         return false;
         
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
     {   
         StreamString s;

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverBreakpoint.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverBreakpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverBreakpoint.cpp Thu Jun  6 19:06:43 2013
@@ -34,7 +34,8 @@ ThreadPlanStepOverBreakpoint::ThreadPlan
                             // first in the thread plan stack when stepping
                             // over a breakpoint
     m_breakpoint_addr (LLDB_INVALID_ADDRESS),
-    m_auto_continue(false)
+    m_auto_continue(false),
+    m_reenabled_breakpoint_site (false)
 
 {
     m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
@@ -48,7 +49,7 @@ ThreadPlanStepOverBreakpoint::~ThreadPla
 void
 ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
 {
-    s->Printf("Single stepping past breakpoint site %llu at 0x%llx", m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
+    s->Printf("Single stepping past breakpoint site %" PRIu64 " at 0x%" PRIx64, m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
 }
 
 bool
@@ -58,9 +59,9 @@ ThreadPlanStepOverBreakpoint::ValidatePl
 }
 
 bool
-ThreadPlanStepOverBreakpoint::PlanExplainsStop ()
+ThreadPlanStepOverBreakpoint::DoPlanExplainsStop (Event *event_ptr)
 {
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     if (stop_info_sp)
     {
         StopReason reason = stop_info_sp->GetStopReason();
@@ -91,15 +92,13 @@ ThreadPlanStepOverBreakpoint::GetPlanRun
 }
 
 bool
-ThreadPlanStepOverBreakpoint::WillResume (StateType resume_state, bool current_plan)
+ThreadPlanStepOverBreakpoint::DoWillResume (StateType resume_state, bool current_plan)
 {
-    ThreadPlan::WillResume (resume_state, current_plan);
-
     if (current_plan)
     {
         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
         if (bp_site_sp  && bp_site_sp->IsEnabled())
-            m_thread.GetProcess()->DisableBreakpoint (bp_site_sp.get());
+            m_thread.GetProcess()->DisableBreakpointSite (bp_site_sp.get());
     }
     return true;
 }
@@ -107,9 +106,7 @@ ThreadPlanStepOverBreakpoint::WillResume
 bool
 ThreadPlanStepOverBreakpoint::WillStop ()
 {
-    BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
-    if (bp_site_sp)
-        m_thread.GetProcess()->EnableBreakpoint (bp_site_sp.get());
+    ReenableBreakpointSite ();
     return true;
 }
 
@@ -126,19 +123,36 @@ ThreadPlanStepOverBreakpoint::MischiefMa
     }
     else
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
             log->Printf("Completed step over breakpoint plan.");
         // Otherwise, re-enable the breakpoint we were stepping over, and we're done.
-        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
-        if (bp_site_sp)
-            m_thread.GetProcess()->EnableBreakpoint (bp_site_sp.get());
+        ReenableBreakpointSite ();
         ThreadPlan::MischiefManaged ();
         return true;
     }
 }
 
 void
+ThreadPlanStepOverBreakpoint::ReenableBreakpointSite ()
+{
+    if (!m_reenabled_breakpoint_site)
+    {
+        m_reenabled_breakpoint_site = true;
+        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
+        if (bp_site_sp)
+        {
+            m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get());
+        }
+    }
+}
+void
+ThreadPlanStepOverBreakpoint::ThreadDestroyed ()
+{
+    ReenableBreakpointSite ();
+}
+
+void
 ThreadPlanStepOverBreakpoint::SetAutoContinue (bool do_it)
 {
     m_auto_continue = do_it;

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp Thu Jun  6 19:06:43 2013
@@ -17,6 +17,10 @@
 #include "lldb/lldb-private-log.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/LineTable.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
@@ -40,7 +44,8 @@ ThreadPlanStepOverRange::ThreadPlanStepO
     const SymbolContext &addr_context,
     lldb::RunMode stop_others
 ) :
-    ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others)
+    ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others),
+    m_first_resume(true)
 {
 }
 
@@ -63,7 +68,7 @@ ThreadPlanStepOverRange::GetDescription
 bool
 ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (log)
     {
@@ -75,7 +80,7 @@ ThreadPlanStepOverRange::ShouldStop (Eve
     
     // If we're out of the range but in the same frame or in our caller's frame
     // then we should stop.
-    // When stepping out we only step if we are forcing running one thread.
+    // When stepping out we only stop others if we are forcing running one thread.
     bool stop_others;
     if (m_stop_others == lldb::eOnlyThisThread)
         stop_others = true;
@@ -116,7 +121,7 @@ ThreadPlanStepOverRange::ShouldStop (Eve
             // in so I left out the target check.  And sometimes the module comes in as the .o file from the
             // inlined range, so I left that out too...
             
-            bool older_ctx_is_equivalent = false;
+            bool older_ctx_is_equivalent = true;
             if (m_addr_context.comp_unit)
             {
                 if (m_addr_context.comp_unit == older_context.comp_unit)
@@ -126,10 +131,6 @@ ThreadPlanStepOverRange::ShouldStop (Eve
                         if (m_addr_context.block && m_addr_context.block == older_context.block)
                         {
                             older_ctx_is_equivalent = true;
-                            if (m_addr_context.line_entry.IsValid() && LineEntry::Compare(m_addr_context.line_entry, older_context.line_entry) != 0)
-                            {
-                                older_ctx_is_equivalent = false;
-                            }
                         }
                     }
                 }
@@ -174,6 +175,99 @@ ThreadPlanStepOverRange::ShouldStop (Eve
             // stub, and then it will be straight-forward to step out.        
             new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
         }
+        else
+        {
+            // The current clang (at least through 424) doesn't always get the address range for the 
+            // DW_TAG_inlined_subroutines right, so that when you leave the inlined range the line table says 
+            // you are still in the source file of the inlining function.  This is bad, because now you are missing 
+            // the stack frame for the function containing the inlining, and if you sensibly do "finish" to get
+            // out of this function you will instead exit the containing function.
+            // To work around this, we check whether we are still in the source file we started in, and if not assume
+            // it is an error, and push a plan to get us out of this line and back to the containing file.
+
+            if (m_addr_context.line_entry.IsValid())
+            {
+                SymbolContext sc;
+                StackFrameSP frame_sp = m_thread.GetStackFrameAtIndex(0);
+                sc = frame_sp->GetSymbolContext (eSymbolContextEverything);
+                if (sc.line_entry.IsValid())
+                {
+                    if (sc.line_entry.file != m_addr_context.line_entry.file
+                         && sc.comp_unit == m_addr_context.comp_unit
+                         && sc.function == m_addr_context.function)
+                    {
+                        // Okay, find the next occurance of this file in the line table:
+                        LineTable *line_table = m_addr_context.comp_unit->GetLineTable();
+                        if (line_table)
+                        {
+                            Address cur_address = frame_sp->GetFrameCodeAddress();
+                            uint32_t entry_idx;
+                            LineEntry line_entry;
+                            if (line_table->FindLineEntryByAddress (cur_address, line_entry, &entry_idx))
+                            {
+                                LineEntry next_line_entry;
+                                bool step_past_remaining_inline = false;
+                                if (entry_idx > 0)
+                                {
+                                    // We require the the previous line entry and the current line entry come
+                                    // from the same file.
+                                    // The other requirement is that the previous line table entry be part of an
+                                    // inlined block, we don't want to step past cases where people have inlined
+                                    // some code fragment by using #include <source-fragment.c> directly.
+                                    LineEntry prev_line_entry;
+                                    if (line_table->GetLineEntryAtIndex(entry_idx - 1, prev_line_entry)
+                                        && prev_line_entry.file == line_entry.file)
+                                    {
+                                        SymbolContext prev_sc;
+                                        Address prev_address = prev_line_entry.range.GetBaseAddress();
+                                        prev_address.CalculateSymbolContext(&prev_sc);
+                                        if (prev_sc.block)
+                                        {
+                                            Block *inlined_block = prev_sc.block->GetContainingInlinedBlock();
+                                            if (inlined_block)
+                                            {
+                                                AddressRange inline_range;
+                                                inlined_block->GetRangeContainingAddress(prev_address, inline_range);
+                                                if (!inline_range.ContainsFileAddress(cur_address))
+                                                {
+                                                    
+                                                    step_past_remaining_inline = true;
+                                                }
+                                                
+                                            }
+                                        }
+                                    }
+                                }
+                                
+                                if (step_past_remaining_inline)
+                                {
+                                    uint32_t look_ahead_step = 1;
+                                    while (line_table->GetLineEntryAtIndex(entry_idx + look_ahead_step, next_line_entry))
+                                    {
+                                        // Make sure we haven't wandered out of the function we started from...
+                                        Address next_line_address = next_line_entry.range.GetBaseAddress();
+                                        Function *next_line_function = next_line_address.CalculateSymbolContextFunction();
+                                        if (next_line_function != m_addr_context.function)
+                                            break;
+                                        
+                                        if (next_line_entry.file == m_addr_context.line_entry.file)
+                                        {
+                                            const bool abort_other_plans = false;
+                                            const bool stop_other_threads = false;
+                                            new_plan = m_thread.QueueThreadPlanForRunToAddress(abort_other_plans,
+                                                                                               next_line_address,
+                                                                                               stop_other_threads);
+                                            break;
+                                        }
+                                        look_ahead_step++;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
@@ -196,7 +290,7 @@ ThreadPlanStepOverRange::ShouldStop (Eve
 }
 
 bool
-ThreadPlanStepOverRange::PlanExplainsStop ()
+ThreadPlanStepOverRange::DoPlanExplainsStop (Event *event_ptr)
 {
     // For crashes, breakpoint hits, signals, etc, let the base plan (or some plan above us)
     // handle the stop.  That way the user can see the stop, step around, and then when they
@@ -205,30 +299,90 @@ ThreadPlanStepOverRange::PlanExplainsSto
     // Note, unlike the step in range plan, we don't mark ourselves complete if we hit an
     // unexplained breakpoint/crash.
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
+    bool return_value;
+    
     if (stop_info_sp)
     {
         StopReason reason = stop_info_sp->GetStopReason();
 
         switch (reason)
         {
+        case eStopReasonTrace:
+            return_value = true;
+            break;
         case eStopReasonBreakpoint:
             if (NextRangeBreakpointExplainsStop(stop_info_sp))
-                return true;
+                return_value = true;
             else
-                return false;
+                return_value = false;
             break;
         case eStopReasonWatchpoint:
         case eStopReasonSignal:
         case eStopReasonException:
+        case eStopReasonExec:
+        case eStopReasonThreadExiting:
+        default:
             if (log)
                 log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
-            return false;
-            break;
-        default:
+            return_value = false;
             break;
         }
     }
+    else
+        return_value = true;
+
+    return return_value;
+}
+
+bool
+ThreadPlanStepOverRange::DoWillResume (lldb::StateType resume_state, bool current_plan)
+{
+    if (resume_state != eStateSuspended && m_first_resume)
+    {
+        m_first_resume = false;
+        if (resume_state == eStateStepping && current_plan)
+        {
+            // See if we are about to step over an inlined call in the middle of the inlined stack, if so figure
+            // out its extents and reset our range to step over that.
+            bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth();
+            if (in_inlined_stack)
+            {
+                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                if (log)
+                    log->Printf ("ThreadPlanStepInRange::DoWillResume: adjusting range to the frame at inlined depth %d.",
+                                 m_thread.GetCurrentInlinedDepth());
+                StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0);
+                if (stack_sp)
+                {
+                    Block *frame_block = stack_sp->GetFrameBlock();
+                    lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+                    AddressRange my_range;
+                    if (frame_block->GetRangeContainingLoadAddress(curr_pc, m_thread.GetProcess()->GetTarget(), my_range))
+                    {
+                        m_address_ranges.clear();
+                        m_address_ranges.push_back(my_range);
+                        if (log)
+                        {
+                            StreamString s;
+                            const InlineFunctionInfo *inline_info = frame_block->GetInlinedFunctionInfo();
+                            const char *name;
+                            if (inline_info)
+                                name = inline_info->GetName().AsCString();
+                            else
+                                name = "<unknown-notinlined>";
+                            
+                            s.Printf ("Stepping over inlined function \"%s\" in inlined stack: ", name);
+                            DumpRanges(&s);
+                            log->PutCString(s.GetData());
+                        }
+                    }
+                    
+                }
+            }
+        }
+    }
+    
     return true;
 }

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp Thu Jun  6 19:06:43 2013
@@ -15,6 +15,8 @@
 // Project includes
 
 #include "lldb/lldb-private-log.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/BreakpointSite.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
@@ -49,8 +51,10 @@ ThreadPlanStepRange::ThreadPlanStepRange
     m_stop_others (stop_others),
     m_stack_id (),
     m_no_more_plans (false),
-    m_first_run_event (true)
+    m_first_run_event (true),
+    m_use_fast_step(false)
 {
+    m_use_fast_step = GetTarget().GetUseFastStepping();
     AddRange(range);
     m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
 }
@@ -76,7 +80,7 @@ ThreadPlanStepRange::ValidatePlan (Strea
 Vote
 ThreadPlanStepRange::ShouldReportStop (Event *event_ptr)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     const Vote vote = IsPlanComplete() ? eVoteYes : eVoteNo;
     if (log)
@@ -115,7 +119,7 @@ ThreadPlanStepRange::DumpRanges(Stream *
 bool
 ThreadPlanStepRange::InRange ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     bool ret_value = false;
 
     lldb::addr_t pc_load_addr = m_thread.GetRegisterContext()->GetPC();
@@ -146,9 +150,12 @@ ThreadPlanStepRange::InRange ()
                     if (log)
                     {
                         StreamString s;
-                        m_addr_context.line_entry.range.Dump (&s, 
-                                                              m_thread.CalculateTarget().get(), 
-                                                              Address::DumpStyleLoadAddress);
+                        m_addr_context.line_entry.Dump (&s,
+                                                        m_thread.CalculateTarget().get(),
+                                                        true,
+                                                        Address::DumpStyleLoadAddress,
+                                                        Address::DumpStyleLoadAddress,
+                                                        true);
 
                         log->Printf ("Step range plan stepped to another range of same line: %s", s.GetData());
                     }
@@ -167,9 +174,12 @@ ThreadPlanStepRange::InRange ()
                     if (log)
                     {
                         StreamString s;
-                        m_addr_context.line_entry.range.Dump (&s, 
-                                                              m_thread.CalculateTarget().get(), 
-                                                              Address::DumpStyleLoadAddress);
+                        m_addr_context.line_entry.Dump (&s, 
+                                                        m_thread.CalculateTarget().get(),
+                                                        true,
+                                                        Address::DumpStyleLoadAddress,
+                                                        Address::DumpStyleLoadAddress,
+                                                        true);
 
                         log->Printf ("Step range plan stepped to the middle of new line(%d): %s, continuing to clear this line.", 
                                      new_context.line_entry.line, 
@@ -184,7 +194,7 @@ ThreadPlanStepRange::InRange ()
     }
 
     if (!ret_value && log)
-        log->Printf ("Step range plan out of range to 0x%llx", pc_load_addr);
+        log->Printf ("Step range plan out of range to 0x%" PRIx64, pc_load_addr);
 
     return ret_value;
 }
@@ -259,8 +269,11 @@ ThreadPlanStepRange::GetInstructionsForA
             {
                 //Disassemble the address range given:
                 ExecutionContext exe_ctx (m_thread.GetProcess());
+                const char *plugin_name = NULL;
+                const char *flavor = NULL;
                 m_instruction_ranges[i] = Disassembler::DisassembleRange(GetTarget().GetArchitecture(),
-                                                                         NULL,
+                                                                         plugin_name,
+                                                                         flavor,
                                                                          exe_ctx,
                                                                          m_address_ranges[i]);
                 
@@ -291,6 +304,9 @@ ThreadPlanStepRange::ClearNextBranchBrea
 {
     if (m_next_branch_bp_sp)
     {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        if (log)
+            log->Printf ("Removing next branch breakpoint: %d.", m_next_branch_bp_sp->GetID());
         GetTarget().RemoveBreakpointByID (m_next_branch_bp_sp->GetID());
         m_next_branch_bp_sp.reset();
     }
@@ -299,11 +315,15 @@ ThreadPlanStepRange::ClearNextBranchBrea
 bool
 ThreadPlanStepRange::SetNextBranchBreakpoint ()
 {
+    if (m_next_branch_bp_sp)
+        return true;
+
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     // Stepping through ranges using breakpoints doesn't work yet, but with this off we fall back to instruction
     // single stepping.
-    return false;
-    // Always clear the next branch breakpoint, we don't want to leave one of these stranded.
-    ClearNextBranchBreakpoint();
+    if (!m_use_fast_step)
+         return false;
+
     lldb::addr_t cur_addr = GetThread().GetRegisterContext()->GetPC();
     // Find the current address in our address ranges, and fetch the disassembly if we haven't already:
     size_t pc_index;
@@ -321,15 +341,39 @@ ThreadPlanStepRange::SetNextBranchBreakp
         // If we didn't find a branch, run to the end of the range.
         if (branch_index == UINT32_MAX)
         {
-            branch_index = instructions->GetSize() - 2;
+            branch_index = instructions->GetSize() - 1;
         }
+        
         if (branch_index - pc_index > 1)
         {
             const bool is_internal = true;
             run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress();
             m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal);
-            m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
-            return true;
+            if (m_next_branch_bp_sp)
+            {
+                if (log)
+                {
+                    lldb::break_id_t bp_site_id = LLDB_INVALID_BREAK_ID;
+                    BreakpointLocationSP bp_loc = m_next_branch_bp_sp->GetLocationAtIndex(0);
+                    if (bp_loc)
+                    {
+                        BreakpointSiteSP bp_site = bp_loc->GetBreakpointSite();
+                        if (bp_site)
+                        {
+                            bp_site_id = bp_site->GetID();
+                        }
+                    }
+                    log->Printf ("ThreadPlanStepRange::SetNextBranchBreakpoint - Setting breakpoint %d (site %d) to run to address 0x%" PRIx64,
+                                 m_next_branch_bp_sp->GetID(),
+                                 bp_site_id,
+                                 run_to_address.GetLoadAddress(&m_thread.GetProcess()->GetTarget()));
+                }
+                m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
+                m_next_branch_bp_sp->SetBreakpointKind ("next-branch-location");
+                return true;
+            }
+            else
+                return false;
         }
     }
     return false;
@@ -338,15 +382,39 @@ ThreadPlanStepRange::SetNextBranchBreakp
 bool
 ThreadPlanStepRange::NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info_sp)
 {
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (!m_next_branch_bp_sp)
         return false;
     
     break_id_t bp_site_id = stop_info_sp->GetValue();
     BreakpointSiteSP bp_site_sp = m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id);
-    if (!bp_site_sp->IsBreakpointAtThisSite (m_next_branch_bp_sp->GetID()))
+    if (!bp_site_sp)
+        return false;
+    else if (!bp_site_sp->IsBreakpointAtThisSite (m_next_branch_bp_sp->GetID()))
         return false;
     else
-        return bp_site_sp->GetNumberOfOwners() == 1;
+    {
+        // If we've hit the next branch breakpoint, then clear it.
+        size_t num_owners = bp_site_sp->GetNumberOfOwners();
+        bool explains_stop = true;
+        // If all the owners are internal, then we are probably just stepping over this range from multiple threads,
+        // or multiple frames, so we want to continue.  If one is not internal, then we should not explain the stop,
+        // and let the user breakpoint handle the stop.
+        for (size_t i = 0; i < num_owners; i++)
+        {
+            if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
+            {
+                explains_stop = false;
+                break;
+            }
+        }
+        if (log)
+            log->Printf ("ThreadPlanStepRange::NextRangeBreakpointExplainsStop - Hit next range breakpoint which has %zu owners - explains stop: %u.",
+                        num_owners,
+                        explains_stop);
+        ClearNextBranchBreakpoint();
+        return  explains_stop;
+    }
 }
 
 bool
@@ -367,6 +435,14 @@ ThreadPlanStepRange::GetPlanRunState ()
 bool
 ThreadPlanStepRange::MischiefManaged ()
 {
+    // If we have pushed some plans between ShouldStop & MischiefManaged, then we're not done...
+    // I do this check first because we might have stepped somewhere that will fool InRange into
+    // thinking it needs to step past the end of that line.  This happens, for instance, when stepping
+    // over inlined code that is in the middle of the current line.
+    
+    if (!m_no_more_plans)
+        return false;
+    
     bool done = true;
     if (!IsPlanComplete())
     {
@@ -391,9 +467,10 @@ ThreadPlanStepRange::MischiefManaged ()
 
     if (done)
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
             log->Printf("Completed step through range plan.");
+        ClearNextBranchBreakpoint();
         ThreadPlan::MischiefManaged ();
         return true;
     }
@@ -407,7 +484,7 @@ ThreadPlanStepRange::MischiefManaged ()
 bool
 ThreadPlanStepRange::IsPlanStale ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     FrameComparison frame_order = CompareCurrentFrameToStartFrame();
     
     if (frame_order == eFrameCompareOlder)

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepThrough.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepThrough.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepThrough.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepThrough.cpp Thu Jun  6 19:06:43 2013
@@ -61,11 +61,12 @@ ThreadPlanStepThrough::ThreadPlanStepThr
             {
                 return_bp->SetThreadID(m_thread.GetID());
                 m_backstop_bkpt_id = return_bp->GetID();
+                return_bp->SetBreakpointKind("step-through-backstop");
             }
-            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
             if (log)
             {
-                log->Printf ("Setting backstop breakpoint %d at address: 0x%llx", m_backstop_bkpt_id, m_backstop_addr);
+                log->Printf ("Setting backstop breakpoint %d at address: 0x%" PRIx64, m_backstop_bkpt_id, m_backstop_addr);
             }
         }
     }
@@ -95,7 +96,7 @@ ThreadPlanStepThrough::LookForPlanToStep
             m_sub_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
     }
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
     {
         lldb::addr_t current_address = GetThread().GetRegisterContext()->GetPC(0);
@@ -103,11 +104,11 @@ ThreadPlanStepThrough::LookForPlanToStep
         {
             StreamString s;
             m_sub_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
-            log->Printf ("Found step through plan from 0x%llx: %s", current_address, s.GetData());
+            log->Printf ("Found step through plan from 0x%" PRIx64 ": %s", current_address, s.GetData());
         }
         else
         {
-            log->Printf ("Couldn't find step through plan from address 0x%llx.", current_address);
+            log->Printf ("Couldn't find step through plan from address 0x%" PRIx64 ".", current_address);
         }
     }
 }
@@ -138,7 +139,7 @@ ThreadPlanStepThrough::ValidatePlan (Str
 }
 
 bool
-ThreadPlanStepThrough::PlanExplainsStop ()
+ThreadPlanStepThrough::DoPlanExplainsStop (Event *event_ptr)
 {
     // If we have a sub-plan, it will have been asked first if we explain the stop, and
     // we won't get asked.  The only time we would be the one directly asked this question
@@ -222,9 +223,8 @@ ThreadPlanStepThrough::GetPlanRunState (
 }
 
 bool
-ThreadPlanStepThrough::WillResume (StateType resume_state, bool current_plan)
+ThreadPlanStepThrough::DoWillResume (StateType resume_state, bool current_plan)
 {
-    ThreadPlan::WillResume(resume_state, current_plan);
     return true;
 }
 
@@ -247,7 +247,7 @@ ThreadPlanStepThrough::ClearBackstopBrea
 bool
 ThreadPlanStepThrough::MischiefManaged ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (!IsPlanComplete())
     {
@@ -278,7 +278,7 @@ ThreadPlanStepThrough::HitOurBackstopBre
             
             if (cur_frame_zero_id == m_return_stack_id)
             {
-                LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
                 if (log)
                     log->PutCString ("ThreadPlanStepThrough hit backstop breakpoint.");
                 return true;

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp Thu Jun  6 19:06:43 2013
@@ -73,6 +73,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
             {
                 return_bp->SetThreadID(thread_id);
                 m_return_bp_id = return_bp->GetID();
+                return_bp->SetBreakpointKind ("until-return-backstop");
             }
         }
 
@@ -86,6 +87,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
             {
                 until_bp->SetThreadID(thread_id);
                 m_until_points[address_list[i]] = until_bp->GetID();
+                until_bp->SetBreakpointKind("until-target");
             }
             else
             {
@@ -133,21 +135,21 @@ ThreadPlanStepUntil::GetDescription (Str
     else
     {
         if (m_until_points.size() == 1)
-            s->Printf ("Stepping from address 0x%llx until we reach 0x%llx using breakpoint %d",
+            s->Printf ("Stepping from address 0x%" PRIx64 " until we reach 0x%" PRIx64 " using breakpoint %d",
                        (uint64_t)m_step_from_insn,
                        (uint64_t) (*m_until_points.begin()).first,
                        (*m_until_points.begin()).second);
         else
         {
             until_collection::iterator pos, end = m_until_points.end();
-            s->Printf ("Stepping from address 0x%llx until we reach one of:",
+            s->Printf ("Stepping from address 0x%" PRIx64 " until we reach one of:",
                        (uint64_t)m_step_from_insn);
             for (pos = m_until_points.begin(); pos != end; pos++)
             {
-                s->Printf ("\n\t0x%llx (bp: %d)", (uint64_t) (*pos).first, (*pos).second);
+                s->Printf ("\n\t0x%" PRIx64 " (bp: %d)", (uint64_t) (*pos).first, (*pos).second);
             }
         }
-        s->Printf(" stepped out address is 0x%llx.", (uint64_t) m_return_addr);
+        s->Printf(" stepped out address is 0x%" PRIx64 ".", (uint64_t) m_return_addr);
     }
 }
 
@@ -174,7 +176,7 @@ ThreadPlanStepUntil::AnalyzeStop()
     if (m_ran_analyze)
         return;
         
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     m_should_stop = true;
     m_explains_stop = false;
     
@@ -291,6 +293,8 @@ ThreadPlanStepUntil::AnalyzeStop()
             case eStopReasonWatchpoint:
             case eStopReasonSignal:
             case eStopReasonException:
+            case eStopReasonExec:
+            case eStopReasonThreadExiting:
                 m_explains_stop = false;
                 break;
             default:
@@ -301,7 +305,7 @@ ThreadPlanStepUntil::AnalyzeStop()
 }
 
 bool
-ThreadPlanStepUntil::PlanExplainsStop ()
+ThreadPlanStepUntil::DoPlanExplainsStop (Event *event_ptr)
 {
     // We don't explain signals or breakpoints (breakpoints that handle stepping in or
     // out will be handled by a child plan.
@@ -316,7 +320,7 @@ ThreadPlanStepUntil::ShouldStop (Event *
     // do so here.  Otherwise, as long as this thread has stopped for a reason,
     // we will stop.
 
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     if (!stop_info_sp || stop_info_sp->GetStopReason() == eStopReasonNone)
         return false;
 
@@ -337,9 +341,8 @@ ThreadPlanStepUntil::GetPlanRunState ()
 }
 
 bool
-ThreadPlanStepUntil::WillResume (StateType resume_state, bool current_plan)
+ThreadPlanStepUntil::DoWillResume (StateType resume_state, bool current_plan)
 {
-    ThreadPlan::WillResume (resume_state, current_plan);
     if (current_plan)
     {
         TargetSP target_sp (m_thread.CalculateTarget());
@@ -394,7 +397,7 @@ ThreadPlanStepUntil::MischiefManaged ()
     bool done = false;
     if (IsPlanComplete())
     {
-        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
         if (log)
             log->Printf("Completed step until plan.");
 

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanTracer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanTracer.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanTracer.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanTracer.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Target/ThreadPlan.h"
 
 // C Includes
@@ -19,6 +21,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/State.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Symbol/TypeList.h"
@@ -71,9 +74,12 @@ ThreadPlanTracer::Log()
     bool show_fullpaths = false;
     
     Stream *stream = GetLogStream();
-    m_thread.GetStackFrameAtIndex(0)->Dump (stream, show_frame_index, show_fullpaths);
-    stream->Printf("\n");
-    stream->Flush();
+    if (stream)
+    {
+        m_thread.GetStackFrameAtIndex(0)->Dump (stream, show_frame_index, show_fullpaths);
+        stream->Printf("\n");
+        stream->Flush();
+    }
     
 }
 
@@ -114,7 +120,7 @@ Disassembler *
 ThreadPlanAssemblyTracer::GetDisassembler ()
 {
     if (m_disassembler_sp.get() == NULL)
-        m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL);
+        m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
     return m_disassembler_sp.get();
 }
 
@@ -202,10 +208,11 @@ ThreadPlanAssemblyTracer::Log ()
                                     process_sp->GetByteOrder(), 
                                     process_sp->GetAddressByteSize());
             
+			bool data_from_file = false;
             if (addr_valid)
-                disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false);
+                disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false, data_from_file);
             else
-                disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false);
+                disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false, data_from_file);
             
             InstructionList &instruction_list = disassembler->GetInstructionList();
             const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadSpec.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadSpec.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadSpec.cpp Thu Jun  6 19:06:43 2013
@@ -140,7 +140,7 @@ ThreadSpec::GetDescription (Stream *s, l
         else
         {
             if (GetTID() != LLDB_INVALID_THREAD_ID)
-                s->Printf("tid: 0x%llx ", GetTID());
+                s->Printf("tid: 0x%" PRIx64 " ", GetTID());
                 
             if (GetIndex() != UINT32_MAX)
                 s->Printf("index: %d ", GetIndex());

Modified: lldb/branches/lldb-platform-work/source/Target/UnwindAssembly.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/UnwindAssembly.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/UnwindAssembly.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/UnwindAssembly.cpp Thu Jun  6 19:06:43 2013
@@ -24,7 +24,7 @@ UnwindAssembly::FindPlugin (const ArchSp
          (create_callback = PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(idx)) != NULL;
          ++idx)
     {
-        std::auto_ptr<UnwindAssembly> assembly_profiler_ap (create_callback (arch));
+        std::unique_ptr<UnwindAssembly> assembly_profiler_ap (create_callback (arch));
         if (assembly_profiler_ap.get ())
             return assembly_profiler_ap.release ();
     }

Modified: lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.cpp Thu Jun  6 19:06:43 2013
@@ -81,8 +81,8 @@ GetARMDWARFRegisterName (unsigned reg_nu
         case dwarf_f6:  return "f6";
         case dwarf_f7:  return "f7";
             
-        // Intel wireless MMX general purpose registers 0–7
-        // XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7)
+        // Intel wireless MMX general purpose registers 0 - 7
+        // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
         case dwarf_wCGR0: return "wCGR0/ACC0";   
         case dwarf_wCGR1: return "wCGR1/ACC1";
         case dwarf_wCGR2: return "wCGR2/ACC2";
@@ -92,7 +92,7 @@ GetARMDWARFRegisterName (unsigned reg_nu
         case dwarf_wCGR6: return "wCGR6/ACC6";
         case dwarf_wCGR7: return "wCGR7/ACC7";
             
-        // Intel wireless MMX data registers 0–15
+        // Intel wireless MMX data registers 0 - 15
         case dwarf_wR0:   return "wR0";
         case dwarf_wR1:   return "wR1";
         case dwarf_wR2:   return "wR2";
@@ -140,7 +140,7 @@ GetARMDWARFRegisterName (unsigned reg_nu
         case dwarf_r13_svc:     return "r13_svc";
         case dwarf_r14_svc:     return "r14_svc";
             
-        // Intel wireless MMX control register in co-processor 0–7
+        // Intel wireless MMX control register in co-processor 0 - 7
         case dwarf_wC0:         return "wC0";
         case dwarf_wC1:         return "wC1";
         case dwarf_wC2:         return "wC2";
@@ -183,6 +183,24 @@ GetARMDWARFRegisterName (unsigned reg_nu
         case dwarf_d29:         return "d29";
         case dwarf_d30:         return "d30";
         case dwarf_d31:         return "d31";
+
+        // NEON 128-bit vector registers (overlays the d registers)
+        case dwarf_q0:          return "q0"; 
+        case dwarf_q1:          return "q1"; 
+        case dwarf_q2:          return "q2"; 
+        case dwarf_q3:          return "q3"; 
+        case dwarf_q4:          return "q4"; 
+        case dwarf_q5:          return "q5"; 
+        case dwarf_q6:          return "q6"; 
+        case dwarf_q7:          return "q7"; 
+        case dwarf_q8:          return "q8"; 
+        case dwarf_q9:          return "q9"; 
+        case dwarf_q10:         return "q10";
+        case dwarf_q11:         return "q11";
+        case dwarf_q12:         return "q12";
+        case dwarf_q13:         return "q13";
+        case dwarf_q14:         return "q14";
+        case dwarf_q15:         return "q15";
     }
     return 0;
 }
@@ -192,6 +210,13 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
 {
     ::memset (&reg_info, 0, sizeof(RegisterInfo));
     ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+    if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15)
+    {
+        reg_info.byte_size = 16;
+        reg_info.format = eFormatVectorOfUInt8;
+        reg_info.encoding = eEncodingVector;
+    }
     
     if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31)
     {
@@ -273,7 +298,7 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
         case dwarf_s30: reg_info.name = "s30"; break;
         case dwarf_s31: reg_info.name = "s31"; break;
             
-            // FPA Registers 0-7
+        // FPA Registers 0-7
         case dwarf_f0:  reg_info.name = "f0"; break;
         case dwarf_f1:  reg_info.name = "f1"; break;
         case dwarf_f2:  reg_info.name = "f2"; break;
@@ -283,8 +308,8 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
         case dwarf_f6:  reg_info.name = "f6"; break;
         case dwarf_f7:  reg_info.name = "f7"; break;
             
-            // Intel wireless MMX general purpose registers 0–7
-            // XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7)
+        // Intel wireless MMX general purpose registers 0 - 7
+        // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
         case dwarf_wCGR0: reg_info.name = "wCGR0/ACC0"; break;   
         case dwarf_wCGR1: reg_info.name = "wCGR1/ACC1"; break;
         case dwarf_wCGR2: reg_info.name = "wCGR2/ACC2"; break;
@@ -294,7 +319,7 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
         case dwarf_wCGR6: reg_info.name = "wCGR6/ACC6"; break;
         case dwarf_wCGR7: reg_info.name = "wCGR7/ACC7"; break;
             
-            // Intel wireless MMX data registers 0–15
+        // Intel wireless MMX data registers 0 - 15
         case dwarf_wR0:   reg_info.name = "wR0"; break;
         case dwarf_wR1:   reg_info.name = "wR1"; break;
         case dwarf_wR2:   reg_info.name = "wR2"; break;
@@ -342,7 +367,7 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
         case dwarf_r13_svc:     reg_info.name = "r13_svc"; break;
         case dwarf_r14_svc:     reg_info.name = "r14_svc"; break;
             
-            // Intel wireless MMX control register in co-processor 0–7
+        // Intel wireless MMX control register in co-processor 0 - 7
         case dwarf_wC0:         reg_info.name = "wC0"; break;
         case dwarf_wC1:         reg_info.name = "wC1"; break;
         case dwarf_wC2:         reg_info.name = "wC2"; break;
@@ -352,7 +377,7 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
         case dwarf_wC6:         reg_info.name = "wC6"; break;
         case dwarf_wC7:         reg_info.name = "wC7"; break;
             
-            // VFP-v3/Neon
+        // VFP-v3/Neon
         case dwarf_d0:          reg_info.name = "d0"; break;
         case dwarf_d1:          reg_info.name = "d1"; break;
         case dwarf_d2:          reg_info.name = "d2"; break;
@@ -385,6 +410,25 @@ GetARMDWARFRegisterInfo (unsigned reg_nu
         case dwarf_d29:         reg_info.name = "d29"; break;
         case dwarf_d30:         reg_info.name = "d30"; break;
         case dwarf_d31:         reg_info.name = "d31"; break;
+
+        // NEON 128-bit vector registers (overlays the d registers)
+        case dwarf_q0:          reg_info.name = "q0"; break;
+        case dwarf_q1:          reg_info.name = "q1"; break;
+        case dwarf_q2:          reg_info.name = "q2"; break;
+        case dwarf_q3:          reg_info.name = "q3"; break;
+        case dwarf_q4:          reg_info.name = "q4"; break;
+        case dwarf_q5:          reg_info.name = "q5"; break;
+        case dwarf_q6:          reg_info.name = "q6"; break;
+        case dwarf_q7:          reg_info.name = "q7"; break;
+        case dwarf_q8:          reg_info.name = "q8"; break;
+        case dwarf_q9:          reg_info.name = "q9"; break;
+        case dwarf_q10:         reg_info.name = "q10"; break;
+        case dwarf_q11:         reg_info.name = "q11"; break;
+        case dwarf_q12:         reg_info.name = "q12"; break;
+        case dwarf_q13:         reg_info.name = "q13"; break;
+        case dwarf_q14:         reg_info.name = "q14"; break;
+        case dwarf_q15:         reg_info.name = "q15"; break;
+
         default: return false;
     }
     return true;

Modified: lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.h (original)
+++ lldb/branches/lldb-platform-work/source/Utility/ARM_DWARF_Registers.h Thu Jun  6 19:06:43 2013
@@ -75,7 +75,7 @@ enum
     dwarf_f6,
     dwarf_f7,
 
-    // Intel wireless MMX general purpose registers 0–7
+    // Intel wireless MMX general purpose registers 0 - 7
     dwarf_wCGR0 = 104,
     dwarf_wCGR1,
     dwarf_wCGR2,
@@ -85,7 +85,7 @@ enum
     dwarf_wCGR6,
     dwarf_wCGR7,
 
-    // XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7)
+    // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
     dwarf_ACC0 = 104,
     dwarf_ACC1,
     dwarf_ACC2,
@@ -95,7 +95,7 @@ enum
     dwarf_ACC6,
     dwarf_ACC7,
 
-    // Intel wireless MMX data registers 0–15
+    // Intel wireless MMX data registers 0 - 15
     dwarf_wR0 = 112,
     dwarf_wR1,
     dwarf_wR2,
@@ -143,7 +143,7 @@ enum
     dwarf_r13_svc,
     dwarf_r14_svc,
 
-    // Intel wireless MMX control register in co-processor 0–7
+    // Intel wireless MMX control register in co-processor 0 - 7
     dwarf_wC0 = 192,
     dwarf_wC1,
     dwarf_wC2,

Modified: lldb/branches/lldb-platform-work/source/Utility/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/Makefile (original)
+++ lldb/branches/lldb-platform-work/source/Utility/Makefile Thu Jun  6 19:06:43 2013
@@ -10,5 +10,6 @@
 LLDB_LEVEL := ../..
 LIBRARYNAME := lldbUtility
 BUILD_ARCHIVE = 1
+NO_PEDANTIC = 1
 
 include $(LLDB_LEVEL)/Makefile

Modified: lldb/branches/lldb-platform-work/source/Utility/StringExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/StringExtractor.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/StringExtractor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Utility/StringExtractor.cpp Thu Jun  6 19:06:43 2013
@@ -16,6 +16,43 @@
 // Other libraries and framework includes
 // Project includes
 
+static const uint8_t
+g_hex_ascii_to_hex_integer[256] = {
+    
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+    0x8, 0x9, 255, 255, 255, 255, 255, 255,
+    255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+};
+
 static inline int
 xdigit_to_sint (char ch)
 {
@@ -97,36 +134,7 @@ StringExtractor::GetChar (char fail_valu
         ++m_index;
         return ch;
     }
-    m_index = UINT32_MAX;
-    return fail_value;
-}
-
-uint32_t
-StringExtractor::GetNumHexASCIICharsAtFilePos (uint32_t max) const
-{
-    uint32_t idx = m_index;
-    const size_t size = m_packet.size();
-    while (idx < size && idx - m_index < max && isxdigit(m_packet[idx]))
-        ++idx;
-    return idx - m_index;
-}
-//----------------------------------------------------------------------
-// Extract a signed character from two hex ASCII chars in the packet
-// string
-//----------------------------------------------------------------------
-int8_t
-StringExtractor::GetHexS8 (int8_t fail_value)
-{
-    if (GetNumHexASCIICharsAtFilePos(2))
-    {
-        char hi_nibble_char = m_packet[m_index];
-        char lo_nibble_char = m_packet[m_index+1];
-        char hi_nibble = xdigit_to_sint (hi_nibble_char);
-        char lo_nibble = xdigit_to_sint (lo_nibble_char);
-        m_index += 2;
-        return (hi_nibble << 4) + lo_nibble;
-    }
-    m_index = UINT32_MAX;
+    m_index = UINT64_MAX;
     return fail_value;
 }
 
@@ -137,17 +145,19 @@ StringExtractor::GetHexS8 (int8_t fail_v
 uint8_t
 StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)
 {
-    if (GetNumHexASCIICharsAtFilePos(2))
+    uint32_t i = m_index;
+    if ((i + 2) <= m_packet.size())
     {
-        uint8_t hi_nibble_char = m_packet[m_index];
-        uint8_t lo_nibble_char = m_packet[m_index+1];
-        uint8_t hi_nibble = xdigit_to_uint (hi_nibble_char);
-        uint8_t lo_nibble = xdigit_to_uint (lo_nibble_char);
-        m_index += 2;
-        return (hi_nibble << 4) + lo_nibble;
+        const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i])];
+        const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i+1])];
+        if (hi_nibble < 16 && lo_nibble < 16)
+        {
+            m_index += 2;
+            return (hi_nibble << 4) + lo_nibble;
+        }
     }
     if (set_eof_on_fail || m_index >= m_packet.size())
-        m_index = UINT32_MAX;
+        m_index = UINT64_MAX;
     return fail_value;
 }
 
@@ -158,10 +168,68 @@ StringExtractor::GetU32 (uint32_t fail_v
     {
         char *end = NULL;
         const char *start = m_packet.c_str();
-        const char *uint_cstr = start + m_index;
-        uint32_t result = ::strtoul (uint_cstr, &end, base);
+        const char *cstr = start + m_index;
+        uint32_t result = ::strtoul (cstr, &end, base);
+
+        if (end && end != cstr)
+        {
+            m_index = end - start;
+            return result;
+        }
+    }
+    return fail_value;
+}
+
+int32_t
+StringExtractor::GetS32 (int32_t fail_value, int base)
+{
+    if (m_index < m_packet.size())
+    {
+        char *end = NULL;
+        const char *start = m_packet.c_str();
+        const char *cstr = start + m_index;
+        int32_t result = ::strtol (cstr, &end, base);
+        
+        if (end && end != cstr)
+        {
+            m_index = end - start;
+            return result;
+        }
+    }
+    return fail_value;
+}
+
+
+uint64_t
+StringExtractor::GetU64 (uint64_t fail_value, int base)
+{
+    if (m_index < m_packet.size())
+    {
+        char *end = NULL;
+        const char *start = m_packet.c_str();
+        const char *cstr = start + m_index;
+        uint64_t result = ::strtoull (cstr, &end, base);
+        
+        if (end && end != cstr)
+        {
+            m_index = end - start;
+            return result;
+        }
+    }
+    return fail_value;
+}
 
-        if (end && end != uint_cstr)
+int64_t
+StringExtractor::GetS64 (int64_t fail_value, int base)
+{
+    if (m_index < m_packet.size())
+    {
+        char *end = NULL;
+        const char *start = m_packet.c_str();
+        const char *cstr = start + m_index;
+        int64_t result = ::strtoll (cstr, &end, base);
+        
+        if (end && end != cstr)
         {
             m_index = end - start;
             return result;
@@ -185,7 +253,7 @@ StringExtractor::GetHexMaxU32 (bool litt
             // Make sure we don't exceed the size of a uint32_t...
             if (nibble_count >= (sizeof(uint32_t) * 2))
             {
-                m_index = UINT32_MAX;
+                m_index = UINT64_MAX;
                 return fail_value;
             }
 
@@ -217,7 +285,7 @@ StringExtractor::GetHexMaxU32 (bool litt
             // Make sure we don't exceed the size of a uint32_t...
             if (nibble_count >= (sizeof(uint32_t) * 2))
             {
-                m_index = UINT32_MAX;
+                m_index = UINT64_MAX;
                 return fail_value;
             }
 
@@ -247,7 +315,7 @@ StringExtractor::GetHexMaxU64 (bool litt
             // Make sure we don't exceed the size of a uint64_t...
             if (nibble_count >= (sizeof(uint64_t) * 2))
             {
-                m_index = UINT32_MAX;
+                m_index = UINT64_MAX;
                 return fail_value;
             }
 
@@ -279,7 +347,7 @@ StringExtractor::GetHexMaxU64 (bool litt
             // Make sure we don't exceed the size of a uint64_t...
             if (nibble_count >= (sizeof(uint64_t) * 2))
             {
-                m_index = UINT32_MAX;
+                m_index = UINT64_MAX;
                 return fail_value;
             }
 
@@ -331,7 +399,7 @@ StringExtractor::GetHexWithFixedSize (ui
             // Little Endian
             uint32_t shift_amount;
             for (i = 0, shift_amount = 0;
-                 i < byte_size && m_index != UINT32_MAX;
+                 i < byte_size && IsGood();
                  ++i, shift_amount += 8)
             {
                 result |= ((uint64_t)GetHexU8() << shift_amount);
@@ -340,14 +408,14 @@ StringExtractor::GetHexWithFixedSize (ui
         else
         {
             // Big Endian
-            for (i = 0; i < byte_size && m_index != UINT32_MAX; ++i)
+            for (i = 0; i < byte_size && IsGood(); ++i)
             {
                 result <<= 8;
                 result |= GetHexU8();
             }
         }
     }
-    m_index = UINT32_MAX;
+    m_index = UINT64_MAX;
     return fail_value;
 }
 
@@ -396,6 +464,6 @@ StringExtractor::GetNameColonValue (std:
             }
         }
     }
-    m_index = UINT32_MAX;
+    m_index = UINT64_MAX;
     return false;
 }

Modified: lldb/branches/lldb-platform-work/source/Utility/StringExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/StringExtractor.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/StringExtractor.h (original)
+++ lldb/branches/lldb-platform-work/source/Utility/StringExtractor.h Thu Jun  6 19:06:43 2013
@@ -45,10 +45,10 @@ public:
     bool
     IsGood() const
     {
-        return m_index != UINT32_MAX;
+        return m_index != UINT64_MAX;
     }
 
-    uint32_t
+    uint64_t
     GetFilePos () const
     {
         return m_index;
@@ -73,13 +73,19 @@ public:
         return m_packet;
     }
 
+    const std::string &
+    GetStringRef () const
+    {
+        return m_packet;
+    }
+
     bool
     Empty()
     {
         return m_packet.empty();
     }
 
-    uint32_t
+    size_t
     GetBytesLeft ()
     {
         if (m_index < m_packet.size())
@@ -89,18 +95,24 @@ public:
     char
     GetChar (char fail_value = '\0');
 
-    int8_t
-    GetHexS8 (int8_t fail_value = 0);
-
     uint8_t
     GetHexU8 (uint8_t fail_value = 0, bool set_eof_on_fail = true);
 
     bool
     GetNameColonValue (std::string &name, std::string &value);
 
+    int32_t
+    GetS32 (int32_t fail_value, int base = 0);
+
     uint32_t
     GetU32 (uint32_t fail_value, int base = 0);
 
+    int64_t
+    GetS64 (int64_t fail_value, int base = 0);
+    
+    uint64_t
+    GetU64 (uint64_t fail_value, int base = 0);
+
     uint32_t
     GetHexMaxU32 (bool little_endian, uint32_t fail_value);
 
@@ -133,13 +145,10 @@ protected:
     // For StringExtractor only
     //------------------------------------------------------------------
     std::string m_packet;   // The string in which to extract data.
-    uint32_t m_index;       // When extracting data from a packet, this index
+    uint64_t m_index;       // When extracting data from a packet, this index
                             // will march along as things get extracted. If set
-                            // to UINT32_MAX the end of the packet data was
+                            // to UINT64_MAX the end of the packet data was
                             // reached when decoding information
-
-    uint32_t
-    GetNumHexASCIICharsAtFilePos (uint32_t max = UINT32_MAX) const;
 };
 
 #endif  // utility_StringExtractor_h_

Modified: lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp Thu Jun  6 19:06:43 2013
@@ -123,8 +123,12 @@ StringExtractorGDBRemote::GetServerPacke
             if (PACKET_MATCHES ("qHostInfo"))                   return eServerPacketType_qHostInfo;
             break;
 
+        case 'K':
+            if (PACKET_STARTS_WITH ("qKillSpawnedProcess"))     return eServerPacketType_qKillSpawnedProcess;
+            break;
+        
         case 'L':
-            if (PACKET_MATCHES ("qLaunchGDBServer"))            return eServerPacketType_qLaunchGDBServer;
+            if (PACKET_STARTS_WITH ("qLaunchGDBServer"))        return eServerPacketType_qLaunchGDBServer;
             if (PACKET_MATCHES ("qLaunchSuccess"))              return eServerPacketType_qLaunchSuccess;
             break;
             
@@ -154,6 +158,7 @@ StringExtractorGDBRemote::GetServerPacke
                 else if (PACKET_STARTS_WITH("vFile:size"))           return eServerPacketType_vFile_Size;
                 else if (PACKET_STARTS_WITH("vFile:exists"))         return eServerPacketType_vFile_Exists;
                 else if (PACKET_STARTS_WITH("vFile:stat"))           return eServerPacketType_vFile_Stat;
+                else if (PACKET_STARTS_WITH("vFile:mode"))           return eServerPacketType_vFile_Mode;
                 else if (PACKET_STARTS_WITH("vFile:MD5"))            return eServerPacketType_vFile_MD5;
 
             }

Modified: lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h Thu Jun  6 19:06:43 2013
@@ -53,6 +53,7 @@ public:
         eServerPacketType_qGroupName,
         eServerPacketType_qHostInfo,
         eServerPacketType_qLaunchGDBServer,
+        eServerPacketType_qKillSpawnedProcess,
         eServerPacketType_qLaunchSuccess,
         eServerPacketType_qProcessInfoPID,
         eServerPacketType_qSpeedTest,
@@ -72,6 +73,7 @@ public:
         eServerPacketType_vFile_pRead,
         eServerPacketType_vFile_pWrite,
         eServerPacketType_vFile_Size,
+        eServerPacketType_vFile_Mode,
         eServerPacketType_vFile_Exists,
         eServerPacketType_vFile_MD5,
         eServerPacketType_vFile_Stat

Modified: lldb/branches/lldb-platform-work/source/lldb-log.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/lldb-log.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/lldb-log.cpp (original)
+++ lldb/branches/lldb-platform-work/source/lldb-log.cpp Thu Jun  6 19:06:43 2013
@@ -26,17 +26,21 @@ using namespace lldb_private;
 // control access to our static g_log_sp by hiding it in a singleton function
 // that will construct the static g_lob_sp the first time this function is 
 // called.
-static LogSP &
+
+static bool g_log_enabled = false;
+static Log * g_log = NULL;
+static Log *
 GetLog ()
 {
-    static LogSP g_log_sp;
-    return g_log_sp;
+    if (!g_log_enabled)
+        return NULL;
+    return g_log;
 }
 
 uint32_t
 lldb_private::GetLogMask ()
 {
-    LogSP log(GetLog ());
+    Log *log(GetLog ());
     if (log)
         return log->GetMask().Get();
     return 0;
@@ -49,15 +53,15 @@ lldb_private::IsLogVerbose ()
     return (mask & LIBLLDB_LOG_VERBOSE);
 }
 
-LogSP
+Log *
 lldb_private::GetLogIfAllCategoriesSet (uint32_t mask)
 {
-    LogSP log(GetLog ());
+    Log *log(GetLog ());
     if (log && mask)
     {
         uint32_t log_mask = log->GetMask().Get();
         if ((log_mask & mask) != mask)
-            return LogSP();
+            return NULL;
     }
     return log;
 }
@@ -65,7 +69,7 @@ lldb_private::GetLogIfAllCategoriesSet (
 void
 lldb_private::LogIfAllCategoriesSet (uint32_t mask, const char *format, ...)
 {
-    LogSP log(GetLogIfAllCategoriesSet (mask));
+    Log *log(GetLogIfAllCategoriesSet (mask));
     if (log)
     {
         va_list args;
@@ -78,7 +82,7 @@ lldb_private::LogIfAllCategoriesSet (uin
 void
 lldb_private::LogIfAnyCategoriesSet (uint32_t mask, const char *format, ...)
 {
-    LogSP log(GetLogIfAnyCategoriesSet (mask));
+    Log *log(GetLogIfAnyCategoriesSet (mask));
     if (log)
     {
         va_list args;
@@ -88,19 +92,19 @@ lldb_private::LogIfAnyCategoriesSet (uin
     }
 }
 
-LogSP
+Log *
 lldb_private::GetLogIfAnyCategoriesSet (uint32_t mask)
 {
-    LogSP log(GetLog ());
+    Log *log(GetLog ());
     if (log && mask && (mask & log->GetMask().Get()))
         return log;
-    return LogSP();
+    return NULL;
 }
 
 void
 lldb_private::DisableLog (const char **categories, Stream *feedback_strm)
 {
-    LogSP log(GetLog ());
+    Log *log(GetLog ());
 
     if (log)
     {
@@ -126,6 +130,7 @@ lldb_private::DisableLog (const char **c
                 else if (0 == ::strcasecmp(arg, "state"))       flag_bits &= ~LIBLLDB_LOG_STATE;
                 else if (0 == ::strcasecmp(arg, "step"))        flag_bits &= ~LIBLLDB_LOG_STEP;
                 else if (0 == ::strcasecmp(arg, "thread"))      flag_bits &= ~LIBLLDB_LOG_THREAD;
+                else if (0 == ::strcasecmp(arg, "target"))      flag_bits &= ~LIBLLDB_LOG_TARGET;
                 else if (0 == ::strcasecmp(arg, "verbose"))     flag_bits &= ~LIBLLDB_LOG_VERBOSE;
                 else if (0 == ::strncasecmp(arg, "watch", 5))   flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS;
                 else if (0 == ::strncasecmp(arg, "temp", 4))    flag_bits &= ~LIBLLDB_LOG_TEMPORARY;
@@ -135,6 +140,9 @@ lldb_private::DisableLog (const char **c
                 else if (0 == ::strncasecmp(arg, "unwind", 6))  flag_bits &= ~LIBLLDB_LOG_UNWIND;
                 else if (0 == ::strncasecmp(arg, "types", 5))   flag_bits &= ~LIBLLDB_LOG_TYPES;
                 else if (0 == ::strncasecmp(arg, "symbol", 6))  flag_bits &= ~LIBLLDB_LOG_SYMBOLS;
+                else if (0 == ::strncasecmp(arg, "module", 6))  flag_bits &= ~LIBLLDB_LOG_MODULES;
+                else if (0 == ::strncasecmp(arg, "mmap", 4))    flag_bits &= ~LIBLLDB_LOG_MMAP;
+                else if (0 == ::strcasecmp(arg, "os"))          flag_bits &= ~LIBLLDB_LOG_OS;
                 else
                 {
                     feedback_strm->Printf ("error:  unrecognized log category '%s'\n", arg);
@@ -144,35 +152,35 @@ lldb_private::DisableLog (const char **c
                 
             }
         }
+        log->GetMask().Reset (flag_bits);
         if (flag_bits == 0)
-            GetLog ().reset();
-        else
-            log->GetMask().Reset (flag_bits);
+            g_log_enabled = false;
     }
 
     return;
 }
 
-LogSP
+Log *
 lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
 {
     // Try see if there already is a log - that way we can reuse its settings.
     // We could reuse the log in toto, but we don't know that the stream is the same.
     uint32_t flag_bits;
-    LogSP log(GetLog ());
-    if (log)
-        flag_bits = log->GetMask().Get();
+    if (g_log)
+        flag_bits = g_log->GetMask().Get();
     else
         flag_bits = 0;
 
     // Now make a new log with this stream if one was provided
     if (log_stream_sp)
     {
-        log.reset (new Log(log_stream_sp));
-        GetLog () = log;
+        if (g_log)
+            g_log->SetStream(log_stream_sp);
+        else
+            g_log = new Log(log_stream_sp);
     }
 
-    if (log)
+    if (g_log)
     {
         for (size_t i=0; categories[i] != NULL; ++i)
         {
@@ -192,6 +200,7 @@ lldb_private::EnableLog (StreamSP &log_s
             else if (0 == ::strcasecmp(arg, "state"))       flag_bits |= LIBLLDB_LOG_STATE;
             else if (0 == ::strcasecmp(arg, "step"))        flag_bits |= LIBLLDB_LOG_STEP;
             else if (0 == ::strcasecmp(arg, "thread"))      flag_bits |= LIBLLDB_LOG_THREAD;
+            else if (0 == ::strcasecmp(arg, "target"))      flag_bits |= LIBLLDB_LOG_TARGET;
             else if (0 == ::strcasecmp(arg, "verbose"))     flag_bits |= LIBLLDB_LOG_VERBOSE;
             else if (0 == ::strncasecmp(arg, "watch", 5))   flag_bits |= LIBLLDB_LOG_WATCHPOINTS;
             else if (0 == ::strncasecmp(arg, "temp", 4))    flag_bits |= LIBLLDB_LOG_TEMPORARY;
@@ -201,18 +210,22 @@ lldb_private::EnableLog (StreamSP &log_s
             else if (0 == ::strncasecmp(arg, "unwind", 6))  flag_bits |= LIBLLDB_LOG_UNWIND;
             else if (0 == ::strncasecmp(arg, "types", 5))   flag_bits |= LIBLLDB_LOG_TYPES;
             else if (0 == ::strncasecmp(arg, "symbol", 6))  flag_bits |= LIBLLDB_LOG_SYMBOLS;
+            else if (0 == ::strncasecmp(arg, "module", 6))  flag_bits |= LIBLLDB_LOG_MODULES;
+            else if (0 == ::strncasecmp(arg, "mmap", 4))    flag_bits |= LIBLLDB_LOG_MMAP;
+            else if (0 == ::strcasecmp(arg, "os"))          flag_bits |= LIBLLDB_LOG_OS;
             else
             {
                 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
                 ListLogCategories (feedback_strm);
-                return log;
+                return g_log;
             }
         }
 
-        log->GetMask().Reset(flag_bits);
-        log->GetOptions().Reset(log_options);
+        g_log->GetMask().Reset(flag_bits);
+        g_log->GetOptions().Reset(log_options);
     }
-    return log;
+    g_log_enabled = true;
+    return g_log;
 }
 
 
@@ -220,23 +233,25 @@ void
 lldb_private::ListLogCategories (Stream *strm)
 {
     strm->Printf("Logging categories for 'lldb':\n"
-        "  all - turn on all available logging categories\n"
-        "  api - enable logging of API calls and return values\n"
-        "  command - log command argument parsing\n"
-        "  default - enable the default set of logging categories for liblldb\n"
-        "  break - log breakpoints\n"
-        "  events - log broadcaster, listener and event queue activities\n"
-        "  expr - log expressions\n"
-        "  object - log object construction/destruction for important objects\n"
-        "  process - log process events and activities\n"
-        "  thread - log thread events and activities\n"
-        "  script - log events about the script interpreter\n"
-        "  dyld - log shared library related activities\n"
-        "  state - log private and public process state changes\n"
-        "  step - log step related activities\n"
-        "  unwind - log stack unwind activities\n"
-        "  verbose - enable verbose logging\n"
-        "  symbol - log symbol related issues and warnings\n"
-        "  watch - log watchpoint related activities\n"
-        "  types - log type system related activities\n");
+                 "  all - turn on all available logging categories\n"
+                 "  api - enable logging of API calls and return values\n"
+                 "  break - log breakpoints\n"
+                 "  commands - log command argument parsing\n"
+                 "  default - enable the default set of logging categories for liblldb\n"
+                 "  dyld - log shared library related activities\n"
+                 "  events - log broadcaster, listener and event queue activities\n"
+                 "  expr - log expressions\n"
+                 "  object - log object construction/destruction for important objects\n"
+                 "  module - log module activities such as when modules are created, detroyed, replaced, and more\n"
+                 "  process - log process events and activities\n"
+                 "  script - log events about the script interpreter\n"
+                 "  state - log private and public process state changes\n"
+                 "  step - log step related activities\n"
+                 "  symbol - log symbol related issues and warnings\n"
+                 "  target - log target events and activities\n"
+                 "  thread - log thread events and activities\n"
+                 "  types - log type system related activities\n"
+                 "  unwind - log stack unwind activities\n"
+                 "  verbose - enable verbose logging\n"
+                 "  watch - log watchpoint related activities\n");
 }

Modified: lldb/branches/lldb-platform-work/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/lldb.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/lldb.cpp (original)
+++ lldb/branches/lldb-platform-work/source/lldb.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/lldb-private.h"
 #include "lldb/lldb-private-log.h"
 #include "lldb/Core/ArchSpec.h"
@@ -25,7 +27,6 @@
 #include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
 #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
 #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
-#include "Plugins/Disassembler/llvm/DisassemblerLLVM.h"
 #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
 #include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
 #include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
@@ -41,19 +42,21 @@
 #include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
 #include "Plugins/Platform/Linux/PlatformLinux.h"
 #include "Plugins/Platform/POSIX/PlatformPOSIX.h"
+#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
+#ifndef LLDB_DISABLE_PYTHON
+#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h"
+#endif
 #if defined (__APPLE__)
 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
-#include "Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h"
-#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
 #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
 #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
 #include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 #include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
-#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
 #include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
 #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
+#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
 #include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
 #endif
 
@@ -64,12 +67,12 @@
 #endif
 
 #if defined (__FreeBSD__)
-#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
 #include "Plugins/Process/POSIX/ProcessPOSIX.h"
 #include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
 #endif
 
 #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 
 using namespace lldb;
@@ -94,7 +97,6 @@ lldb_private::Initialize ()
         ABIMacOSX_arm::Initialize();
         ABISysV_x86_64::Initialize();
         DisassemblerLLVMC::Initialize();
-        DisassemblerLLVM::Initialize();
         ObjectContainerBSDArchive::Initialize();
         ObjectFileELF::Initialize();
         SymbolFileDWARF::Initialize();
@@ -106,23 +108,26 @@ lldb_private::Initialize ()
         DynamicLoaderPOSIXDYLD::Initialize ();
         PlatformFreeBSD::Initialize();
         PlatformLinux::Initialize();
+        SymbolFileDWARFDebugMap::Initialize();
+        ItaniumABILanguageRuntime::Initialize();
+#ifndef LLDB_DISABLE_PYTHON
+        OperatingSystemPython::Initialize();
+#endif
+
 #if defined (__APPLE__)
         //----------------------------------------------------------------------
         // Apple/Darwin hosted plugins
         //----------------------------------------------------------------------
         DynamicLoaderMacOSXDYLD::Initialize();
         DynamicLoaderDarwinKernel::Initialize();
-        OperatingSystemDarwinKernel::Initialize();
-        SymbolFileDWARFDebugMap::Initialize();
-        ItaniumABILanguageRuntime::Initialize();
         AppleObjCRuntimeV2::Initialize();
         AppleObjCRuntimeV1::Initialize();
         ObjectContainerUniversalMachO::Initialize();
         ObjectFileMachO::Initialize();
-        ProcessGDBRemote::Initialize();
         ProcessKDP::Initialize();
         ProcessMachCore::Initialize();
         SymbolVendorMacOSX::Initialize();
+        PlatformDarwinKernel::Initialize();
         PlatformRemoteiOS::Initialize();
         PlatformMacOSX::Initialize();
         PlatformiOSSimulator::Initialize();
@@ -135,12 +140,12 @@ lldb_private::Initialize ()
 #endif
 #if defined (__FreeBSD__)
         ProcessFreeBSD::Initialize();
-        ProcessGDBRemote::Initialize();
 #endif
         //----------------------------------------------------------------------
         // Platform agnostic plugins
         //----------------------------------------------------------------------
         PlatformRemoteGDBServer::Initialize ();
+        ProcessGDBRemote::Initialize();
         DynamicLoaderStatic::Initialize();
 
         // Scan for any system or user LLDB plug-ins
@@ -171,7 +176,6 @@ lldb_private::Terminate ()
     ABIMacOSX_arm::Terminate();
     ABISysV_x86_64::Terminate();
     DisassemblerLLVMC::Terminate();
-    DisassemblerLLVM::Terminate();
     ObjectContainerBSDArchive::Terminate();
     ObjectFileELF::Terminate();
     SymbolFileDWARF::Terminate();
@@ -183,21 +187,24 @@ lldb_private::Terminate ()
     DynamicLoaderPOSIXDYLD::Terminate ();
     PlatformFreeBSD::Terminate();
     PlatformLinux::Terminate();
+    SymbolFileDWARFDebugMap::Terminate();
+    ItaniumABILanguageRuntime::Terminate();
+#ifndef LLDB_DISABLE_PYTHON
+    OperatingSystemPython::Terminate();
+#endif
+
 #if defined (__APPLE__)
     DynamicLoaderMacOSXDYLD::Terminate();
     DynamicLoaderDarwinKernel::Terminate();
-    OperatingSystemDarwinKernel::Terminate();
-    SymbolFileDWARFDebugMap::Terminate();
-    ItaniumABILanguageRuntime::Terminate();
     AppleObjCRuntimeV2::Terminate();
     AppleObjCRuntimeV1::Terminate();
     ObjectContainerUniversalMachO::Terminate();
     ObjectFileMachO::Terminate();
     ProcessMachCore::Terminate();
-    ProcessGDBRemote::Terminate();
     ProcessKDP::Terminate();
     SymbolVendorMacOSX::Terminate();
     PlatformMacOSX::Terminate();
+    PlatformDarwinKernel::Terminate();
     PlatformRemoteiOS::Terminate();
     PlatformiOSSimulator::Terminate();
 #endif
@@ -210,23 +217,105 @@ lldb_private::Terminate ()
 
 #if defined (__FreeBSD__)
     ProcessFreeBSD::Terminate();
-    ProcessGDBRemote::Terminate();
 #endif
     
+    ProcessGDBRemote::Terminate();
     DynamicLoaderStatic::Terminate();
 
     Log::Terminate();
 }
 
-extern "C" const double liblldb_coreVersionNumber;
+#if defined (__APPLE__)
+extern "C" const unsigned char liblldb_coreVersionString[];
+#else
+
+#include "clang/Basic/Version.h"
+
+static const char *
+GetLLDBRevision()
+{
+#ifdef LLDB_REVISION
+    return LLDB_REVISION;
+#else
+    return NULL;
+#endif
+}
+
+static const char *
+GetLLDBRepository()
+{
+#ifdef LLDB_REPOSITORY
+    return LLDB_REPOSITORY;
+#else
+    return NULL;
+#endif
+}
+
+#endif
+
 const char *
 lldb_private::GetVersion ()
 {
+#if defined (__APPLE__)
     static char g_version_string[32];
     if (g_version_string[0] == '\0')
-        ::snprintf (g_version_string, sizeof(g_version_string), "LLDB-%g", liblldb_coreVersionNumber);
+    {
+        const char *version_string = ::strstr ((const char *)liblldb_coreVersionString, "PROJECT:");
+        
+        if (version_string)
+            version_string += sizeof("PROJECT:") - 1;
+        else
+            version_string = "unknown";
+        
+        const char *newline_loc = strchr(version_string, '\n');
+        
+        size_t version_len = sizeof(g_version_string);
+        
+        if (newline_loc && (newline_loc - version_string < version_len))
+            version_len = newline_loc - version_string;
+        
+        ::strncpy(g_version_string, version_string, version_len);
+    }
 
     return g_version_string;
+#else
+    // On Linux/FreeBSD/Windows, report a version number in the same style as the clang tool.
+    static std::string g_version_str;
+    if (g_version_str.empty())
+    {
+        g_version_str += "lldb version ";
+        g_version_str += CLANG_VERSION_STRING;
+        const char * lldb_repo = GetLLDBRepository();
+        if (lldb_repo)
+        {
+            g_version_str += " (";
+            g_version_str += lldb_repo;
+        }
+
+        const char *lldb_rev = GetLLDBRevision();
+        if (lldb_rev)
+        {
+            g_version_str += " revision ";
+            g_version_str += lldb_rev;
+        }
+        std::string clang_rev (clang::getClangRevision());
+        if (clang_rev.length() > 0)
+        {
+            g_version_str += " clang revision ";
+            g_version_str += clang_rev;
+        }
+        std::string llvm_rev (clang::getLLVMRevision());
+        if (llvm_rev.length() > 0)
+        {
+            g_version_str += " llvm revision ";
+            g_version_str += llvm_rev;
+        }
+
+        if (lldb_repo)
+            g_version_str += ")";
+    }
+    return g_version_str.c_str();
+#endif
 }
 
 const char *
@@ -237,8 +326,6 @@ lldb_private::GetVoteAsCString (Vote vot
     case eVoteNo:           return "no";
     case eVoteNoOpinion:    return "no opinion";
     case eVoteYes:          return "yes";
-    default:
-        break;
     }
     return "invalid";
 }
@@ -315,9 +402,6 @@ lldb_private::NameMatches (const char *n
                 return regex.Execute (name);
             }
             break;
-        default:
-            assert (!"unhandled NameMatchType in lldb_private::NameMatches()");
-            break;
         }
     }
     return false;

Modified: lldb/branches/lldb-platform-work/test/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/Makefile Thu Jun  6 19:06:43 2013
@@ -29,10 +29,5 @@ clean::
 # Run the tests
 #----------------------------------------------------------------------
 check-local::
-	rm -rf ../test-rdir
-	env PATH="$(ToolDir):$(PATH)" \
-	    PYTHONPATH=$(LibDir)/python \
-	    LLDB_EXEC=$(ToolDir)/lldb \
-		LLDB_BUILD_TYPE=Makefile \
-	    $(SHLIBPATH_VAR)=$(LibDir):$($(SHLIBPATH_VAR)) \
-	     python $(PROJ_SRC_DIR)/dotest.py -i -v -r ../test-rdir
+	rm -rf lldb-test-traces
+	python $(PROJ_SRC_DIR)/dosep.ty -o "--executable $(ToolDir)/lldb -q -s lldb-test-traces -u CXXFLAGS -u CFLAGS -C $(subst ccache,,$(CC))"

Modified: lldb/branches/lldb-platform-work/test/api/check_public_api_headers/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/api/check_public_api_headers/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/api/check_public_api_headers/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/api/check_public_api_headers/Makefile Thu Jun  6 19:06:43 2013
@@ -2,15 +2,4 @@ LEVEL = ../../make
 
 CXX_SOURCES := main.cpp
 
-MY_OS = $(shell uname -s)
-ifeq "$(MY_OS)" "Darwin"
-    LD_EXTRAS ?= -framework LLDB
-else
-    LD_EXTRAS ?= $(LLDB_BUILD_DIR)/_lldb.so
-endif
-
-# Example dictionary to pass to the Python build method:
-# 
-# FRAMEWORK_INCLUDES=-F/Volumes/data/lldb/svn/trunk/build/Debug
-
 include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/api/check_public_api_headers/TestPublicAPIHeaders.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/api/check_public_api_headers/TestPublicAPIHeaders.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/api/check_public_api_headers/TestPublicAPIHeaders.py (original)
+++ lldb/branches/lldb-platform-work/test/api/check_public_api_headers/TestPublicAPIHeaders.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ should compile and link with the LLDB fr
 import os, re, StringIO
 import unittest2
 from lldbtest import *
+import lldbutil
 
 class SBDirCheckerCase(TestBase):
 
@@ -13,9 +14,10 @@ class SBDirCheckerCase(TestBase):
 
     def setUp(self):
         TestBase.setUp(self)
-        self.build_dir = os.environ["LLDB_BUILD_DIR"]
+        self.lib_dir = os.environ["LLDB_LIB_DIR"]
         self.template = 'main.cpp.template'
         self.source = 'main.cpp'
+        self.exe_name = 'a.out'
 
     def test_sb_api_directory(self):
         """Test the SB API directory and make sure there's no unwanted stuff."""
@@ -23,16 +25,12 @@ class SBDirCheckerCase(TestBase):
         # Only proceed if this is "darwin", "x86_64", and local platform.
         if not (sys.platform.startswith("darwin") and self.getArchitecture() == "x86_64" and not lldb.test_remote):
             self.skipTest("This test is only for LLDB.framework built 64-bit and !lldb.test_remote")
+        if self.getArchitecture() == "i386":
+            self.skipTest("LLDB is 64-bit and cannot be linked to 32-bit test program.")
 
-        # Call the program generator to produce main.cpp.
+        # Generate main.cpp, build it, and execute.
         self.generate_main_cpp()
-
-        if sys.platform.startswith("darwin"):
-            d = {'FRAMEWORK_INCLUDES' : "-F%s" % self.build_dir}
-        if sys.platform.startswith("linux") or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
-            d = {'FRAMEWORK_INCLUDES' : "-I%s" % os.path.join(os.environ["LLDB_SRC"], "include")}
-        self.buildDefault(dictionary=d)
-        self.exe_name = 'a.out'
+        self.buildDriver(self.source, self.exe_name)
         self.sanity_check_executable(self.exe_name)
 
     def generate_main_cpp(self):
@@ -69,23 +67,13 @@ class SBDirCheckerCase(TestBase):
 
         self.line_to_break = line_number(self.source, '// Set breakpoint here.')
 
-        if sys.platform.startswith("darwin"):
-            env_var = 'DYLD_FRAMEWORK_PATH'
-            env_val = self.build_dir
-        if sys.platform.startswith("linux"):
-            env_var = 'LD_LIBRARY_PATH'
-            env_val = self.build_dir
-
-        env_cmd = "settings set target.env-vars %s=%s" %(env_var, env_val)
+        env_cmd = "settings set target.env-vars %s=%s" %(self.dylibPath, self.getLLDBLibraryEnvVal())
         if self.TraceOn():
             print "Set environment to: ", env_cmd
         self.runCmd(env_cmd)
-        self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars %s" % env_var))
+        self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars %s" % self.dylibPath))
 
-        self.expect('breakpoint set -f %s -l %d' % (self.source, self.line_to_break),
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='%s', line = %d" %
-                        (self.source, self.line_to_break))
+        lldbutil.run_break_set_by_file_and_line (self, self.source, self.line_to_break, num_expected_locations = -1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/attic/tester.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/attic/tester.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/attic/tester.py (original)
+++ lldb/branches/lldb-platform-work/test/attic/tester.py Thu Jun  6 19:06:43 2013
@@ -98,11 +98,15 @@ class LLDBTestCase(unittest.TestCase):
     else:
       self.fail("Command " + command + " returned an error")
       return None
+  def getCategories(self):
+    return []
 
 class SanityCheckTestCase(LLDBTestCase):
   def runTest(self):
     ret = self.runCommand("show arch", "show-arch")
     #print ret
+  def getCategories(self):
+    return []
 
 suite = unittest.TestLoader().loadTestsFromTestCase(SanityCheckTestCase)
 unittest.TextTestRunner(verbosity=2).run(suite)

Modified: lldb/branches/lldb-platform-work/test/dosep.ty
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/dosep.ty?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/dosep.ty (original)
+++ lldb/branches/lldb-platform-work/test/dosep.ty Thu Jun  6 19:06:43 2013
@@ -4,7 +4,7 @@
 Run the test suite using a separate process for each test file.
 """
 
-import os, sys
+import os, sys, platform
 from optparse import OptionParser
 
 # Command template of the invocation of the test driver.
@@ -12,6 +12,8 @@ template = '%s/dotest.py %s -p %s %s'
 
 def walk_and_invoke(test_root, dotest_options):
     """Look for matched file and invoke test driver on it."""
+    failed = []
+    passed = []
     for root, dirs, files in os.walk(test_root, topdown=False):
         for name in files:
             path = os.path.join(root, name)
@@ -25,8 +27,11 @@ def walk_and_invoke(test_root, dotest_op
                 continue
 
             command = template % (test_root, dotest_options if dotest_options else "", name, root)
-            print "Running %s" % (command)
-            os.system(command)
+            if 0 != os.system(command):
+                failed.append(name) 
+            else:
+                passed.append(name)
+    return (failed, passed)
 
 def main():
     test_root = sys.path[0]
@@ -42,10 +47,17 @@ Run lldb test suite using a separate pro
     opts, args = parser.parse_args()
     dotest_options = opts.dotest_options
 
-    print "dotest.py options:", dotest_options
-
-    walk_and_invoke(test_root, dotest_options)
-
+    system_info = " ".join(platform.uname())
+    (failed, passed) = walk_and_invoke(test_root, dotest_options)
+    num_tests = len(failed) + len(passed)
+
+    print "Ran %d tests." % num_tests
+    if len(failed) > 0:
+        print "Failing Tests (%d)" % len(failed)
+        for f in failed:
+          print "FAIL: LLDB (suite) :: %s (%s)" % (f, system_info)
+        sys.exit(1)
+    sys.exit(0)
 
 if __name__ == '__main__':
     main()

Modified: lldb/branches/lldb-platform-work/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/dotest.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/dotest.py (original)
+++ lldb/branches/lldb-platform-work/test/dotest.py Thu Jun  6 19:06:43 2013
@@ -20,9 +20,20 @@ Type:
 for available options.
 """
 
-import os, signal, sys, time
+import os
+import platform
+import signal
 import subprocess
+import sys
+import textwrap
+import time
 import unittest2
+import progress
+
+if sys.version_info >= (2, 7):
+    argparse = __import__('argparse')
+else:
+    argparse = __import__('argparse_compat')
 
 def is_exe(fpath):
     """Returns true if fpath is an executable."""
@@ -60,6 +71,18 @@ class _WritelnDecorator(object):
 # Global variables:
 #
 
+# Dictionary of categories
+# When you define a new category for your testcases, be sure to add it here, or the test suite
+# will gladly complain as soon as you try to use it. This allows us to centralize which categories
+# exist, and to provide a description for each one
+validCategories = {
+'dataformatters':'Tests related to the type command and the data formatters subsystem',
+'expression':'Tests related to the expression parser',
+'objc':'Tests related to the Objective-C programming language support',
+'pyapi':'Tests related to the Python API',
+'basic_process': 'Basic process execution sniff tests.'
+}
+
 # The test suite.
 suite = unittest2.TestSuite()
 
@@ -78,7 +101,7 @@ just_do_benchmarks_test = False
 # Use @dsym_test or @dwarf_test decorators, defined in lldbtest.py, to mark a test
 # as a dsym or dwarf test.  Use '-N dsym' or '-N dwarf' to exclude dsym or dwarf
 # tests from running.
-dont_do_dsym_test = False
+dont_do_dsym_test = "linux" in sys.platform
 dont_do_dwarf_test = False
 
 # The blacklist is optional (-b blacklistFile) and allows a central place to skip
@@ -88,6 +111,19 @@ blacklist = None
 # The dictionary as a result of sourcing blacklistFile.
 blacklistConfig = {}
 
+# The list of categories we said we care about
+categoriesList = None
+# set to true if we are going to use categories for cherry-picking test cases
+useCategories = False
+# use this to track per-category failures
+failuresPerCategory = {}
+
+# The path to LLDB.framework is optional.
+lldbFrameworkPath = None
+
+# The path to lldb is optional
+lldbExecutablePath = None
+
 # The config file is optional.
 configFile = None
 
@@ -104,11 +140,11 @@ lldbtest_remote_sandbox = None
 lldbtest_remote_shell_template = None
 
 # The 'archs' and 'compilers' can be specified via either command line or configFile,
-# with the command line overriding the configFile.  When specified, they should be
-# of the list type.  For example, "-A x86_64^i386" => archs=['x86_64', 'i386'] and
-# "-C gcc^clang" => compilers=['gcc', 'clang'].
-archs = ['x86_64', 'i386']
-compilers = ['clang']
+# with the command line overriding the configFile.  The corresponding options can be
+# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
+# and "-C gcc -C clang" => compilers=['gcc', 'clang'].
+archs = None        # Must be initialized after option parsing
+compilers = None    # Must be initialized after option parsing
 
 # The arch might dictate some specific CFLAGS to be passed to the toolchain to build
 # the inferior programs.  The global variable cflags_extras provides a hook to do
@@ -159,6 +195,10 @@ skip_long_running_test = True
 # turn it off.
 noHeaders = False
 
+# Parsable mode silences headers, and any other output this script might generate, and instead
+# prints machine-readable output similar to what clang tests produce.
+parsable = False
+
 # The regular expression pattern to match against eligible filenames as our test cases.
 regexp = None
 
@@ -179,11 +219,11 @@ sdir_has_content = False
 # svn_info stores the output from 'svn info lldb.base.dir'.
 svn_info = ''
 
-# The environment variables to unset before running the test cases.
-unsets = []
+# svn_silent means do not try to obtain svn status
+svn_silent = True
 
 # Default verbosity is 0.
-verbose = 0
+verbose = 1
 
 # Set to True only if verbose is 0 and LLDB trace mode is off.
 progress_bar = False
@@ -194,90 +234,10 @@ testdirs = [ sys.path[0] ]
 # Separator string.
 separator = '-' * 70
 
+failed = False
 
-def usage():
-    print """
-Usage: dotest.py [option] [args]
-where options:
--h   : print this help message and exit.  Add '-v' for more detailed help.
--A   : specify the architecture(s) to launch for the inferior process
-       -A i386 => launch inferior with i386 architecture
-       -A x86_64^i386 => launch inferior with x86_64 and i386 architectures
--C   : specify the compiler(s) used to build the inferior executable
-       -C clang => build debuggee using clang compiler
-       -C /my/full/path/to/clang => specify a full path to the clang binary
-       -C clang^gcc => build debuggee using clang and gcc compilers
--D   : dump the Python sys.path variable
--E   : specify the extra flags to be passed to the toolchain when building the
-       inferior programs to be debugged
-       suggestions: do not lump the -A arch1^arch2 together such that the -E
-       option applies to only one of the architectures
--N   : don't do test cases marked with the @dsym decorator by passing 'dsym' as the option arg, or
-       don't do test cases marked with the @dwarf decorator by passing 'dwarf' as the option arg
--a   : don't do lldb Python API tests
-       use @python_api_test to decorate a test case as lldb Python API test
-+a   : just do lldb Python API tests
-       do not specify both '-a' and '+a' at the same time
-+b   : just do benchmark tests
-       use @benchmark_test to decorate a test case as such
--b   : read a blacklist file specified after this option
--c   : read a config file specified after this option
-       the architectures and compilers (note the plurals) specified via '-A' and '-C'
-       will override those specified via a config file
-       (see also lldb-trunk/example/test/usage-config)
--d   : delay startup for 10 seconds (in order for the debugger to attach)
--e   : specify the full path of an executable used for benchmark purpose;
-       see also '-x', which provides the breakpoint sepcification
--F   : failfast, stop the test suite on the first error/failure
--f   : specify a filter, which consists of the test class name, a dot, followed by
-       the test method, to only admit such test into the test suite
-       e.g., -f 'ClassTypesTestCase.test_with_dwarf_and_python_api'
--g   : if specified, the filterspec by -f is not exclusive, i.e., if a test module
-       does not match the filterspec (testclass.testmethod), the whole module is
-       still admitted to the test suite
--i   : ignore (don't bailout) if 'lldb.py' module cannot be located in the build
-       tree relative to this script; use PYTHONPATH to locate the module
--k   : specify a runhook, which is an lldb command to be executed by the debugger;
-       '-k' option can occur multiple times, the commands are executed one after the
-       other to bring the debugger to a desired state, so that, for example, further
-       benchmarking can be done
--l   : don't skip long running test
--n   : don't print the headers like build dir, lldb version, and svn info at all
--p   : specify a regexp filename pattern for inclusion in the test suite
--R   : specify a dir to relocate the tests and their intermediate files to;
-       BE WARNED THAT the directory, if exists, will be deleted before running this test driver;
-       no cleanup of intermediate test files is performed in this case
--r   : similar to '-R',
-       except that the directory must not exist before running this test driver
--S   : skip the build and cleanup while running the test
-       use this option with care as you would need to build the inferior(s) by hand
-       and build the executable(s) with the correct name(s)
-       this can be used with '-# n' to stress test certain test cases for n number of
-       times
--s   : specify the name of the dir created to store the session files of tests
-       with errored or failed status; if not specified, the test driver uses the
-       timestamp as the session dir name
--t   : turn on tracing of lldb command and other detailed test executions
--u   : specify an environment variable to unset before running the test cases
-       e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble'
--v   : do verbose mode of unittest framework (print out each test case invocation)
--X   : exclude a directory from consideration for test discovery
-       -X types => if 'types' appear in the pathname components of a potential testfile
-                   it will be ignored
--x   : specify the breakpoint specification for the benchmark executable;
-       see also '-e', which provides the full path of the executable
--y   : specify the iteration count used to collect our benchmarks; an example is
-       the number of times to do 'thread step-over' to measure stepping speed
-       see also '-e' and '-x' options
--w   : insert some wait time (currently 0.5 sec) between consecutive test cases
--#   : Repeat the test suite for a specified number of times
-
-and:
-args : specify a list of directory names to search for test modules named after
-       Test*.py (test discovery)
-       if empty, search from the current working directory, instead
-"""
-
+def usage(parser):
+    parser.print_help()
     if verbose > 0:
         print """
 Examples:
@@ -361,6 +321,15 @@ o GDB_REMOTE_LOG: if defined, specifies
     sys.exit(0)
 
 
+def unique_string_match(yourentry,list):
+	candidate = None
+	for item in list:
+		if item.startswith(yourentry):
+			if candidate:
+				return None
+			candidate = item
+	return candidate
+
 def parseOptionsAndInitTestdirs():
     """Initialize the list of directories containing our unittest scripts.
 
@@ -374,6 +343,11 @@ def parseOptionsAndInitTestdirs():
     global dont_do_dwarf_test
     global blacklist
     global blacklistConfig
+    global categoriesList
+    global validCategories
+    global useCategories
+    global lldbFrameworkPath
+    global lldbExecutablePath
     global configFile
     global archs
     global compilers
@@ -392,241 +366,293 @@ def parseOptionsAndInitTestdirs():
     global skip_build_and_cleanup
     global skip_long_running_test
     global noHeaders
+    global parsable
     global regexp
     global rdir
     global sdir_name
-    global unsets
+    global svn_silent
     global verbose
     global testdirs
 
     do_help = False
 
-    # Process possible trace and/or verbose flag, among other things.
-    index = 1
-    while index < len(sys.argv):
-        if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
-            # We should continue processing...
-            pass
+    parser = argparse.ArgumentParser(description='description', prefix_chars='+-', add_help=False)
+    group = None
+
+    # Helper function for boolean options (group will point to the current group when executing X)
+    X = lambda optstr, helpstr, **kwargs: group.add_argument(optstr, help=helpstr, action='store_true', **kwargs)
+
+    group = parser.add_argument_group('Help')
+    group.add_argument('-h', '--help', dest='h', action='store_true', help="Print this help message and exit.  Add '-v' for more detailed help.")
+
+    # C and Python toolchain options
+    group = parser.add_argument_group('Toolchain options')
+    group.add_argument('-A', '--arch', metavar='arch', action='append', dest='archs', help=textwrap.dedent('''Specify the architecture(s) to test. This option can be specified more than once'''))
+    group.add_argument('-C', '--compiler', metavar='compiler', dest='compilers', action='append', help=textwrap.dedent('''Specify the compiler(s) used to build the inferior executables. The compiler path can be an executable basename or a full path to a compiler executable. This option can be specified multiple times.'''))
+    # FIXME? This won't work for different extra flags according to each arch.
+    group.add_argument('-E', metavar='extra-flags', help=textwrap.dedent('''Specify the extra flags to be passed to the toolchain when building the inferior programs to be debugged
+                                                           suggestions: do not lump the "-A arch1 -A arch2" together such that the -E option applies to only one of the architectures'''))
+    X('-D', 'Dump the Python sys.path variable')
+
+    # Test filtering options
+    group = parser.add_argument_group('Test filtering options')
+    group.add_argument('-N', choices=['dwarf', 'dsym'], help="Don't do test cases marked with the @dsym decorator by passing 'dsym' as the option arg, or don't do test cases marked with the @dwarf decorator by passing 'dwarf' as the option arg")
+    X('-a', "Don't do lldb Python API tests")
+    X('+a', "Just do lldb Python API tests. Do not specify along with '+a'", dest='plus_a')
+    X('+b', 'Just do benchmark tests', dest='plus_b')
+    group.add_argument('-b', metavar='blacklist', help='Read a blacklist file specified after this option')
+    group.add_argument('-f', metavar='filterspec', action='append', help='Specify a filter, which consists of the test class name, a dot, followed by the test method, to only admit such test into the test suite')  # FIXME: Example?
+    X('-g', 'If specified, the filterspec by -f is not exclusive, i.e., if a test module does not match the filterspec (testclass.testmethod), the whole module is still admitted to the test suite')
+    X('-l', "Don't skip long running tests")
+    group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
+    group.add_argument('-X', metavar='directory', help="Exclude a directory from consideration for test discovery. -X types => if 'types' appear in the pathname components of a potential testfile, it will be ignored")
+    group.add_argument('-G', '--category', metavar='category', action='append', dest='categoriesList', help=textwrap.dedent('''Specify categories of test cases of interest. Can be specified more than once.'''))
+
+    # Configuration options
+    group = parser.add_argument_group('Configuration options')
+    group.add_argument('-c', metavar='config-file', help='Read a config file specified after this option')  # FIXME: additional doc.
+    group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
+    group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
+    group.add_argument('-e', metavar='benchmark-exe', help='Specify the full path of an executable used for benchmark purposes (see also: -x)')
+    group.add_argument('-k', metavar='command', action='append', help="Specify a runhook, which is an lldb command to be executed by the debugger; The option can occur multiple times. The commands are executed one after the other to bring the debugger to a desired state, so that, for example, further benchmarking can be done")
+    group.add_argument('-R', metavar='dir', help='Specify a directory to relocate the tests and their intermediate files to. BE WARNED THAT the directory, if exists, will be deleted before running this test driver. No cleanup of intermediate test files is performed in this case')
+    group.add_argument('-r', metavar='dir', help="Similar to '-R', except that the directory must not exist before running this test driver")
+    group.add_argument('-s', metavar='name', help='Specify the name of the dir created to store the session files of tests with errored or failed status. If not specified, the test driver uses the timestamp as the session dir name')
+    group.add_argument('-x', metavar='breakpoint-spec', help='Specify the breakpoint specification for the benchmark executable')
+    group.add_argument('-y', type=int, metavar='count', help="Specify the iteration count used to collect our benchmarks. An example is the number of times to do 'thread step-over' to measure stepping speed.")
+    group.add_argument('-#', type=int, metavar='sharp', dest='sharp', help='Repeat the test suite for a specified number of times')
+
+    # Test-suite behaviour
+    group = parser.add_argument_group('Runtime behaviour options')
+    X('-d', 'Delay startup for 10 seconds (in order for the debugger to attach)')
+    X('-F', 'Fail fast. Stop the test suite on the first error/failure')
+    X('-i', "Ignore (don't bailout) if 'lldb.py' module cannot be located in the build tree relative to this script; use PYTHONPATH to locate the module")
+    X('-n', "Don't print the headers like build dir, lldb version, and svn info at all")
+    X('-P', "Use the graphic progress bar.")
+    X('-q', "Don't print extra output from this script.")
+    X('-S', "Skip the build and cleanup while running the test. Use this option with care as you would need to build the inferior(s) by hand and build the executable(s) with the correct name(s). This can be used with '-# n' to stress test certain test cases for n number of times")
+    X('-t', 'Turn on tracing of lldb command and other detailed test executions')
+    group.add_argument('-u', dest='unset_env_varnames', metavar='variable', action='append', help='Specify an environment variable to unset before running the test cases. e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble')
+    X('-v', 'Do verbose mode of unittest framework (print out each test case invocation)')
+    X('-w', 'Insert some wait time (currently 0.5 sec) between consecutive test cases')
+    X('-T', 'Obtain and dump svn information for this checkout of LLDB (off by default)')
+
+    # Remove the reference to our helper function
+    del X
+
+    group = parser.add_argument_group('Test directories')
+    group.add_argument('args', metavar='test-dir', nargs='*', help='Specify a list of directory names to search for test modules named after Test*.py (test discovery). If empty, search from the current working directory instead.')
+    args = parser.parse_args()
+
+    platform_system = platform.system()
+    platform_machine = platform.machine()
+    
+    if args.unset_env_varnames:
+        for env_var in args.unset_env_varnames:
+            if env_var in os.environ:
+                # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
+                # is automatically translated into a corresponding call to unsetenv().
+                del os.environ[env_var]
+                #os.unsetenv(env_var)
+    
+    # only print the args if being verbose (and parsable is off)
+    if args.v and not args.q:
+        print args
+
+    if args.h:
+        do_help = True
+
+    if args.archs:
+        archs = args.archs
+    else:
+        if platform_system == 'Darwin' and platform_machine == 'x86_64':
+            archs = ['x86_64', 'i386']
         else:
-            # End of option processing.
-            break
+            archs = [platform_machine]
 
-        if sys.argv[index].find('-h') != -1:
-            index += 1
-            do_help = True
-        elif sys.argv[index].startswith('-A'):
-            # Increment by 1 to fetch the ARCH spec.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            archs = sys.argv[index].split('^')
-            index += 1
-        elif sys.argv[index].startswith('-C'):
-            # Increment by 1 to fetch the CC spec.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            compilers = sys.argv[index].split('^')
-            index += 1
-        elif sys.argv[index].startswith('-D'):
-            dumpSysPath = True
-            index += 1
-        elif sys.argv[index].startswith('-E'):
-            # Increment by 1 to fetch the CFLAGS_EXTRAS spec.
-            index += 1
-            if index >= len(sys.argv):
-                usage()
-            cflags_extras = sys.argv[index]
-            os.environ["CFLAGS_EXTRAS"] = cflags_extras
-            index += 1
-        elif sys.argv[index].startswith('-N'):
-            # Increment by 1 to fetch 'dsym' or 'dwarf'.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            dont_do = sys.argv[index]
-            if dont_do.lower() == 'dsym':
-                dont_do_dsym_test = True
-            elif dont_do.lower() == 'dwarf':
-                dont_do_dwarf_test = True
-            else:
-                print "!!!"
-                print "Warning: -N only accepts either 'dsym' or 'dwarf' as the option arg; you passed in '%s'?" % dont_do
-                print "!!!"
-            index += 1
-        elif sys.argv[index].startswith('-a'):
-            dont_do_python_api_test = True
-            index += 1
-        elif sys.argv[index].startswith('+a'):
-            just_do_python_api_test = True
-            index += 1
-        elif sys.argv[index].startswith('+b'):
-            just_do_benchmarks_test = True
-            index += 1
-        elif sys.argv[index].startswith('-b'):
-            # Increment by 1 to fetch the blacklist file name option argument.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            blacklistFile = sys.argv[index]
-            if not os.path.isfile(blacklistFile):
-                print "Blacklist file:", blacklistFile, "does not exist!"
-                usage()
-            index += 1
-            # Now read the blacklist contents and assign it to blacklist.
-            execfile(blacklistFile, globals(), blacklistConfig)
-            blacklist = blacklistConfig.get('blacklist')
-        elif sys.argv[index].startswith('-c'):
-            # Increment by 1 to fetch the config file name option argument.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            configFile = sys.argv[index]
-            if not os.path.isfile(configFile):
-                print "Config file:", configFile, "does not exist!"
-                usage()
-            index += 1
-        elif sys.argv[index].startswith('-d'):
-            delay = True
-            index += 1
-        elif sys.argv[index].startswith('-e'):
-            # Increment by 1 to fetch the full path of the benchmark executable.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            bmExecutable = sys.argv[index]
-            if not is_exe(bmExecutable):
-                usage()
-            index += 1
-        elif sys.argv[index].startswith('-F'):
-            failfast = True
-            index += 1
-        elif sys.argv[index].startswith('-f'):
-            # Increment by 1 to fetch the filter spec.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            filters.append(sys.argv[index])
-            index += 1
-        elif sys.argv[index].startswith('-g'):
-            fs4all = False
-            index += 1
-        elif sys.argv[index].startswith('-i'):
-            ignore = True
-            index += 1
-        elif sys.argv[index].startswith('-k'):
-            # Increment by 1 to fetch the runhook lldb command.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            runHooks.append(sys.argv[index])
-            index += 1
-        elif sys.argv[index].startswith('-l'):
-            skip_long_running_test = False
-            index += 1
-        elif sys.argv[index].startswith('-n'):
-            noHeaders = True
-            index += 1
-        elif sys.argv[index].startswith('-p'):
-            # Increment by 1 to fetch the reg exp pattern argument.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            regexp = sys.argv[index]
-            index += 1
-        elif sys.argv[index].startswith('-R'):
-            # Increment by 1 to fetch the relocated directory argument.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            rdir = os.path.abspath(sys.argv[index])
-            if os.path.exists(rdir):
-                import shutil
-                print "Removing tree:", rdir
-                shutil.rmtree(rdir)
-            index += 1
-        elif sys.argv[index].startswith('-r'):
-            # Increment by 1 to fetch the relocated directory argument.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            rdir = os.path.abspath(sys.argv[index])
-            if os.path.exists(rdir):
-                print "Relocated directory:", rdir, "must not exist!"
-                usage()
-            index += 1
-        elif sys.argv[index].startswith('-S'):
-            skip_build_and_cleanup = True
-            index += 1
-        elif sys.argv[index].startswith('-s'):
-            # Increment by 1 to fetch the session dir name.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            sdir_name = sys.argv[index]
-            index += 1
-        elif sys.argv[index].startswith('-t'):
-            os.environ["LLDB_COMMAND_TRACE"] = "YES"
-            index += 1
-        elif sys.argv[index].startswith('-u'):
-            # Increment by 1 to fetch the environment variable to unset.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            unsets.append(sys.argv[index])
-            index += 1
-        elif sys.argv[index].startswith('-v'):
-            verbose = 2
-            index += 1
-        elif sys.argv[index].startswith('-w'):
-            os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
-            index += 1
-        elif sys.argv[index].startswith('-X'):
-            # Increment by 1 to fetch an excluded directory.
-            index += 1
-            if index >= len(sys.argv):
-                usage()
-            excluded.add(sys.argv[index])
-            index += 1
-        elif sys.argv[index].startswith('-x'):
-            # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
-            index += 1
-            if index >= len(sys.argv):
-                usage()
-            bmBreakpointSpec = sys.argv[index]
-            index += 1
-        elif sys.argv[index].startswith('-y'):
-            # Increment by 1 to fetch the the benchmark iteration count.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            bmIterationCount = int(sys.argv[index])
-            index += 1
-        elif sys.argv[index].startswith('-#'):
-            # Increment by 1 to fetch the repeat count argument.
-            index += 1
-            if index >= len(sys.argv) or sys.argv[index].startswith('-'):
-                usage()
-            count = int(sys.argv[index])
-            index += 1
+    if args.categoriesList:
+        finalCategoriesList = []
+        for category in args.categoriesList:
+            origCategory = category
+            if not(category in validCategories):
+                category = unique_string_match(category,validCategories)
+            if not(category in validCategories) or category == None:
+                print "fatal error: category '" + origCategory + "' is not a valid category"
+                print "if you have added a new category, please edit dotest.py, adding your new category to validCategories"
+                print "else, please specify one or more of the following: " + str(validCategories.keys())
+                sys.exit(1)
+            finalCategoriesList.append(category)
+        categoriesList = set(finalCategoriesList)
+        useCategories = True
+    else:
+        categoriesList = []
+
+    if args.compilers:
+        compilers = args.compilers
+    else:
+        compilers = ['clang']
+
+    if args.D:
+        dumpSysPath = True
+
+    if args.E:
+        cflags_extras = args.E
+        os.environ['CFLAGS_EXTRAS'] = cflags_extras
+
+    # argparse makes sure we have correct options
+    if args.N == 'dwarf':
+        dont_do_dwarf_test = True
+    elif args.N == 'dsym':
+        dont_do_dsym_test = True
+
+    if args.a:
+        dont_do_python_api_test = True
+
+    if args.plus_a:
+        if dont_do_python_api_test:
+            print "Warning: -a and +a can't both be specified! Using only -a"
         else:
-            print "Unknown option: ", sys.argv[index]
-            usage()
+            just_do_python_api_test = True
+
+    if args.plus_b:
+        just_do_benchmarks_test = True
+
+    if args.b:
+        if args.b.startswith('-'):
+            usage(parser)
+        blacklistFile = args.b
+        if not os.path.isfile(blacklistFile):
+            print 'Blacklist file:', blacklistFile, 'does not exist!'
+            usage(parser)
+        # Now read the blacklist contents and assign it to blacklist.
+        execfile(blacklistFile, globals(), blacklistConfig)
+        blacklist = blacklistConfig.get('blacklist')
+
+    if args.c:
+        if args.c.startswith('-'):
+            usage(parser)
+        configFile = args.c
+        if not os.path.isfile(configFile):
+            print 'Config file:', configFile, 'does not exist!'
+            usage(parser)
+
+    if args.d:
+        delay = True
+
+    if args.e:
+        if args.e.startswith('-'):
+            usage(parser)
+        bmExecutable = args.e
+        if not is_exe(bmExecutable):
+            usage(parser)
+
+    if args.F:
+        failfast = True
+
+    if args.f:
+        if any([x.startswith('-') for x in args.f]):
+            usage(parser)
+        filters.extend(args.f)
+
+    if args.g:
+        fs4all = False
+
+    if args.i:
+        ignore = True
+
+    if args.k:
+        runHooks.extend(args.k)
+
+    if args.l:
+        skip_long_running_test = False
+
+    if args.framework:
+        lldbFrameworkPath = args.framework
+
+    if args.executable:
+        lldbExecutablePath = args.executable
+
+    if args.n:
+        noHeaders = True
+
+    if args.p:
+        if args.p.startswith('-'):
+            usage(parser)
+        regexp = args.p
+
+    if args.q:
+        noHeaders = True
+        parsable = True
+
+    if args.P:
+        progress_bar = True
+        verbose = 0
+
+    if args.R:
+        if args.R.startswith('-'):
+            usage(parser)
+        rdir = os.path.abspath(args.R)
+        if os.path.exists(rdir):
+            import shutil
+            print 'Removing tree:', rdir
+            shutil.rmtree(rdir)
+
+    if args.r:
+        if args.r.startswith('-'):
+            usage(parser)
+        rdir = os.path.abspath(args.r)
+        if os.path.exists(rdir):
+            print 'Relocated directory:', rdir, 'must not exist!'
+            usage(parser)
+
+    if args.S:
+        skip_build_and_cleanup = True
+
+    if args.s:
+        if args.s.startswith('-'):
+            usage(parser)
+        sdir_name = args.s
+
+    if args.t:
+        os.environ['LLDB_COMMAND_TRACE'] = 'YES'
+
+    if args.T:
+        svn_silent = False
+
+    if args.v:
+        verbose = 2
+
+    if args.w:
+        os.environ['LLDB_WAIT_BETWEEN_TEST_CASES'] = 'YES'
+
+    if args.X:
+        if args.X.startswith('-'):
+            usage(parser)
+        excluded.add(args.X)
+
+    if args.x:
+        if args.x.startswith('-'):
+            usage(parser)
+        bmBreakpointSpec = args.x
+
+    # argparse makes sure we have a number
+    if args.y:
+        bmIterationCount = args.y
+
+    # argparse makes sure we have a number
+    if args.sharp:
+        count = args.sharp
 
     if do_help == True:
-        usage()
+        usage(parser)
 
     # Do not specify both '-a' and '+a' at the same time.
     if dont_do_python_api_test and just_do_python_api_test:
-        usage()
-
-    # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
-    if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"]!="YES") and verbose==0:
-        progress_bar = True
+        usage(parser)
 
     # Gather all the dirs passed on the command line.
-    if len(sys.argv) > index:
-        testdirs = map(os.path.abspath, sys.argv[index:])
+    if len(args.args) > 0:
+        testdirs = map(os.path.abspath, args.args)
 
     # If '-r dir' is specified, the tests should be run under the relocated
     # directory.  Let's copy the testdirs over.
@@ -639,8 +665,8 @@ def parseOptionsAndInitTestdirs():
             # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
             # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
             # Utilize the relative path to the 'test' directory to make our destination dir path.
-            if ("test"+os.sep) in srcdir:
-                to_split_on = "test"+os.sep
+            if ("test" + os.sep) in srcdir:
+                to_split_on = "test" + os.sep
             else:
                 to_split_on = "test"
             dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
@@ -681,7 +707,7 @@ def parseOptionsAndInitTestdirs():
     # which will reassign the two file objects to sys.stderr and sys.stdout,
     # respectively.
     #
-    # See also lldb-trunk/example/test/usage-config.
+    # See also lldb-trunk/examples/test/usage-config.
     global config, pre_flight, post_flight, lldbtest_remote_sandbox, lldbtest_remote_shell_template
     if configFile:
         # Pass config (a dictionary) as the locals namespace for side-effect.
@@ -716,6 +742,9 @@ def setupSysPath():
     global dumpSysPath
     global noHeaders
     global svn_info
+    global svn_silent
+    global lldbFrameworkPath
+    global lldbExecutablePath
 
     # Get the directory containing the current script.
     if ("DOTEST_PROFILE" in os.environ or "DOTEST_PDB" in os.environ) and "DOTEST_SCRIPT_DIR" in os.environ:
@@ -757,6 +786,7 @@ def setupSysPath():
     xcode3_build_dir = ['build']
     xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
     dbg = ['Debug']
+    dbc = ['DebugClang']
     rel = ['Release']
     bai = ['BuildAndIntegration']
     python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
@@ -764,98 +794,159 @@ def setupSysPath():
     # Some of the tests can invoke the 'lldb' command directly.
     # We'll try to locate the appropriate executable right here.
 
-    # First, you can define an environment variable LLDB_EXEC specifying the
-    # full pathname of the lldb executable.
-    if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
-        lldbExec = os.environ["LLDB_EXEC"]
+    lldbExec = None
+    if lldbExecutablePath:
+        if is_exe(lldbExecutablePath):
+            lldbExec = lldbExecutablePath
+            lldbHere = lldbExec
+        else:
+            print lldbExecutablePath + " is not an executable"
+            sys.exit(-1)
     else:
-        lldbExec = None
-
-    executable = ['lldb']
-    dbgExec  = os.path.join(base, *(xcode3_build_dir + dbg + executable))
-    dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
-    relExec  = os.path.join(base, *(xcode3_build_dir + rel + executable))
-    relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
-    baiExec  = os.path.join(base, *(xcode3_build_dir + bai + executable))
-    baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
-
-    # The 'lldb' executable built here in the source tree.
-    lldbHere = None
-    if is_exe(dbgExec):
-        lldbHere = dbgExec
-    elif is_exe(dbgExec2):
-        lldbHere = dbgExec2
-    elif is_exe(relExec):
-        lldbHere = relExec
-    elif is_exe(relExec2):
-        lldbHere = relExec2
-    elif is_exe(baiExec):
-        lldbHere = baiExec
-    elif is_exe(baiExec2):
-        lldbHere = baiExec2
-    elif lldbExec:
-        lldbHere = lldbExec
-
+        # First, you can define an environment variable LLDB_EXEC specifying the
+        # full pathname of the lldb executable.
+        if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
+            lldbExec = os.environ["LLDB_EXEC"]
+        else:
+            lldbExec = None
+    
+        executable = ['lldb']
+        dbgExec  = os.path.join(base, *(xcode3_build_dir + dbg + executable))
+        dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
+        dbcExec  = os.path.join(base, *(xcode3_build_dir + dbc + executable))
+        dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
+        relExec  = os.path.join(base, *(xcode3_build_dir + rel + executable))
+        relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
+        baiExec  = os.path.join(base, *(xcode3_build_dir + bai + executable))
+        baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
+    
+        # The 'lldb' executable built here in the source tree.
+        lldbHere = None
+        if is_exe(dbgExec):
+            lldbHere = dbgExec
+        elif is_exe(dbgExec2):
+            lldbHere = dbgExec2
+        elif is_exe(dbcExec):
+            lldbHere = dbcExec
+        elif is_exe(dbcExec2):
+            lldbHere = dbcExec2
+        elif is_exe(relExec):
+            lldbHere = relExec
+        elif is_exe(relExec2):
+            lldbHere = relExec2
+        elif is_exe(baiExec):
+            lldbHere = baiExec
+        elif is_exe(baiExec2):
+            lldbHere = baiExec2
+        elif lldbExec:
+            lldbHere = lldbExec
+
+        # One last chance to locate the 'lldb' executable.
+        if not lldbExec:
+            lldbExec = which('lldb')
+            if lldbHere and not lldbExec:
+                lldbExec = lldbHere
+            if lldbExec and not lldbHere:
+                lldbHere = lldbExec
+    
     if lldbHere:
         os.environ["LLDB_HERE"] = lldbHere
-        os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
+        os.environ["LLDB_LIB_DIR"] = os.path.split(lldbHere)[0]
         if not noHeaders:
-            print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
+            print "LLDB library dir:", os.environ["LLDB_LIB_DIR"]
             os.system('%s -v' % lldbHere)
 
-    # One last chance to locate the 'lldb' executable.
-    if not lldbExec:
-        lldbExec = which('lldb')
-        if lldbHere and not lldbExec:
-            lldbExec = lldbHere
-
-
     if not lldbExec:
         print "The 'lldb' executable cannot be located.  Some of the tests may not be run as a result."
     else:
         os.environ["LLDB_EXEC"] = lldbExec
         #print "The 'lldb' from PATH env variable", lldbExec
 
-    if os.path.isdir(os.path.join(base, '.svn')):
-        pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
-        svn_info = pipe.stdout.read()
-    elif os.path.isdir(os.path.join(base, '.git')):
-        pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
-        svn_info = pipe.stdout.read()
-    if not noHeaders:
-        print svn_info
+    # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
+    if not svn_silent and not parsable:
+        if os.path.isdir(os.path.join(base, '.svn')) and which("svn") is not None:
+            pipe = subprocess.Popen([which("svn"), "info", base], stdout = subprocess.PIPE)
+            svn_info = pipe.stdout.read()
+        elif os.path.isdir(os.path.join(base, '.git')) and which("git") is not None:
+            pipe = subprocess.Popen([which("git"), "svn", "info", base], stdout = subprocess.PIPE)
+            svn_info = pipe.stdout.read()
+        if not noHeaders:
+            print svn_info
 
     global ignore
 
-    # The '-i' option is used to skip looking for lldb.py in the build tree.
-    if ignore:
-        return
+    lldbPath = None
+    if lldbFrameworkPath:
+        candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
+        if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
+            lldbPath = candidatePath
+        if not lldbPath:
+            print 'Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath
+            sys.exit(-1)
+    else:
+        # The '-i' option is used to skip looking for lldb.py in the build tree.
+        if ignore:
+            return
+        
+        # If our lldb supports the -P option, use it to find the python path:
+        init_in_python_dir = 'lldb/__init__.py'
+        import pexpect
+        lldb_dash_p_result = None
+
+        if lldbHere:
+            lldb_dash_p_result = pexpect.run("%s -P"%(lldbHere))
+        elif lldbExec:
+            lldb_dash_p_result = pexpect.run("%s -P"%(lldbExec))
+
+        if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")):
+            lines = lldb_dash_p_result.splitlines()
+            if len(lines) == 1 and os.path.isfile(os.path.join(lines[0], init_in_python_dir)):
+                lldbPath = lines[0]
+                if "linux" in sys.platform:
+                    os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPath, '..', '..')
+        
+        if not lldbPath: 
+            dbgPath  = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
+            dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
+            dbcPath  = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
+            dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
+            relPath  = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
+            relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
+            baiPath  = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
+            baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
+    
+            if os.path.isfile(os.path.join(dbgPath, init_in_python_dir)):
+                lldbPath = dbgPath
+            elif os.path.isfile(os.path.join(dbgPath2, init_in_python_dir)):
+                lldbPath = dbgPath2
+            elif os.path.isfile(os.path.join(dbcPath, init_in_python_dir)):
+                lldbPath = dbcPath
+            elif os.path.isfile(os.path.join(dbcPath2, init_in_python_dir)):
+                lldbPath = dbcPath2
+            elif os.path.isfile(os.path.join(relPath, init_in_python_dir)):
+                lldbPath = relPath
+            elif os.path.isfile(os.path.join(relPath2, init_in_python_dir)):
+                lldbPath = relPath2
+            elif os.path.isfile(os.path.join(baiPath, init_in_python_dir)):
+                lldbPath = baiPath
+            elif os.path.isfile(os.path.join(baiPath2, init_in_python_dir)):
+                lldbPath = baiPath2
+
+        if not lldbPath:
+            print 'This script requires lldb.py to be in either ' + dbgPath + ',',
+            print relPath + ', or ' + baiPath
+            sys.exit(-1)
+
+    # Some of the code that uses this path assumes it hasn't resolved the Versions... link.  
+    # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
+    (before, frameWithVersion, after) = lldbPath.rpartition("LLDB.framework/Versions/A")
+    if frameWithVersion != "" :
+        lldbPath = before + "LLDB.framework" + after
 
-    dbgPath  = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
-    dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
-    relPath  = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
-    relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
-    baiPath  = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
-    baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
+    lldbPath = os.path.abspath(lldbPath)
 
-    lldbPath = None
-    if os.path.isfile(os.path.join(dbgPath, 'lldb/__init__.py')):
-        lldbPath = dbgPath
-    elif os.path.isfile(os.path.join(dbgPath2, 'lldb/__init__.py')):
-        lldbPath = dbgPath2
-    elif os.path.isfile(os.path.join(relPath, 'lldb/__init__.py')):
-        lldbPath = relPath
-    elif os.path.isfile(os.path.join(relPath2, 'lldb/__init__.py')):
-        lldbPath = relPath2
-    elif os.path.isfile(os.path.join(baiPath, 'lldb/__init__.py')):
-        lldbPath = baiPath
-    elif os.path.isfile(os.path.join(baiPath2, 'lldb/__init__.py')):
-        lldbPath = baiPath2
-
-    if not lldbPath:
-        print 'This script requires lldb.py to be in either ' + dbgPath + ',',
-        print relPath + ', or ' + baiPath
-        sys.exit(-1)
+    # If tests need to find LLDB_FRAMEWORK, now they can do it
+    os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
 
     # This is to locate the lldb.py module.  Insert it right after sys.path[0].
     sys.path[1:1] = [lldbPath]
@@ -987,7 +1078,7 @@ def lldbLoggings():
             raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
 
 def getMyCommandLine():
-    ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
+    ps = subprocess.Popen([which('ps'), '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
     lines = ps.split('\n')
     cmd_line = lines[1]
     return cmd_line
@@ -1071,8 +1162,9 @@ def getsource_if_available(obj):
     except:
         return repr(obj)
 
-print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
-print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
+if not noHeaders:
+    print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
+    print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
 
 # If either pre_flight or post_flight is defined, set lldb.test_remote to True.
 if lldb.pre_flight or lldb.post_flight:
@@ -1115,11 +1207,11 @@ unittest2.signals.installHandler()
 # later on.
 #
 # See also TestBase.dumpSessionInfo() in lldbtest.py.
+import datetime
+# The windows platforms don't like ':' in the pathname.
+timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
 if not sdir_name:
-    import datetime
-    # The windows platforms don't like ':' in the pathname.
-    timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
-    sdir_name = timestamp
+    sdir_name = timestamp_started
 os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
 
 if not noHeaders:
@@ -1129,22 +1221,13 @@ if not noHeaders:
 
 if not os.path.isdir(sdir_name):
     os.mkdir(sdir_name)
-fname = os.path.join(sdir_name, "svn-info")
+fname = os.path.join(sdir_name, "TestStarted")
 with open(fname, "w") as f:
+    print >> f, "Test started at: %s\n" % timestamp_started
     print >> f, svn_info
     print >> f, "Command invoked: %s\n" % getMyCommandLine()
 
 #
-# If we have environment variables to unset, do it here before we invoke the test runner.
-#
-for env_var in unsets :
-    if env_var in os.environ:
-        # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
-        # is automatically translated into a corresponding call to unsetenv().
-        del os.environ[env_var]
-        #os.unsetenv(env_var)
-
-#
 # Invoke the default TextTestRunner to run the test suite, possibly iterating
 # over different configurations.
 #
@@ -1180,7 +1263,8 @@ for i in range(len(compilers)):
                     compilers[i] = cmd_output.split('\n')[0]
                     print "'xcrun -find %s' returning %s" % (c, compilers[i])
 
-print "compilers=%s" % str(compilers)
+if not parsable:
+    print "compilers=%s" % str(compilers)
 
 if not compilers or len(compilers) == 0:
     print "No eligible compiler found, exiting."
@@ -1260,16 +1344,18 @@ for ia in range(len(archs) if iterArchs
                 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
 
             # Output the configuration.
-            sys.stderr.write("\nConfiguration: " + configString + "\n")
+            if not parsable:
+                sys.stderr.write("\nConfiguration: " + configString + "\n")
 
         #print "sys.stderr name is", sys.stderr.name
         #print "sys.stdout name is", sys.stdout.name
 
         # First, write out the number of collected test cases.
-        sys.stderr.write(separator + "\n")
-        sys.stderr.write("Collected %d test%s\n\n"
-                         % (suite.countTestCases(),
-                            suite.countTestCases() != 1 and "s" or ""))
+        if not parsable:
+            sys.stderr.write(separator + "\n")
+            sys.stderr.write("Collected %d test%s\n\n"
+                             % (suite.countTestCases(),
+                                suite.countTestCases() != 1 and "s" or ""))
 
         class LLDBTestResult(unittest2.TextTestResult):
             """
@@ -1283,6 +1369,30 @@ for ia in range(len(archs) if iterArchs
             __singleton__ = None
             __ignore_singleton__ = False
 
+            @staticmethod
+            def getTerminalSize():
+                import os
+                env = os.environ
+                def ioctl_GWINSZ(fd):
+                    try:
+                        import fcntl, termios, struct, os
+                        cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
+                    '1234'))
+                    except:
+                        return
+                    return cr
+                cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
+                if not cr:
+                    try:
+                        fd = os.open(os.ctermid(), os.O_RDONLY)
+                        cr = ioctl_GWINSZ(fd)
+                        os.close(fd)
+                    except:
+                        pass
+                if not cr:
+                    cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
+                return int(cr[1]), int(cr[0])
+
             def __init__(self, *args):
                 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
                     raise Exception("LLDBTestResult instantiated more than once")
@@ -1297,6 +1407,19 @@ for ia in range(len(archs) if iterArchs
                 self.indentation = ' ' * (counterWidth + 2)
                 # This counts from 1 .. suite.countTestCases().
                 self.counter = 0
+                (width, height) = LLDBTestResult.getTerminalSize()
+                self.progressbar = None
+                global progress_bar
+                if width > 10 and not parsable and progress_bar:
+                    try:
+                        self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
+                    except:
+                        self.progressbar = None
+
+            def _config_string(self, test):
+              compiler = getattr(test, "getCompiler", None)
+              arch = getattr(test, "getArchitecture", None)
+              return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
 
             def _exc_info_to_string(self, err, test):
                 """Overrides superclass TestResult's method in order to append
@@ -1313,56 +1436,126 @@ for ia in range(len(archs) if iterArchs
                 else:
                     return str(test)
 
+            def getCategoriesForTest(self,test):
+                if hasattr(test,"_testMethodName"):
+                    test_method = getattr(test,"_testMethodName")
+                    test_method = getattr(test,test_method)
+                else:
+                    test_method = None
+                if test_method != None and hasattr(test_method,"getCategories"):
+                    test_categories = test_method.getCategories(test)
+                elif hasattr(test,"getCategories"):
+                    test_categories = test.getCategories()
+                elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
+                    test_categories = test.__self__.getCategories()
+                else:
+                    test_categories = []
+                if test_categories == None:
+                    test_categories = []
+                return test_categories
+
+            def shouldSkipBecauseOfCategories(self,test):
+                global useCategories
+                import inspect
+                if useCategories:
+                    global categoriesList
+                    test_categories = self.getCategoriesForTest(test)
+                    if len(test_categories) == 0 or len(categoriesList & set(test_categories)) == 0:
+                        return True
+                return False
+
+            def hardMarkAsSkipped(self,test):
+                getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
+                getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
+
             def startTest(self, test):
+                if self.shouldSkipBecauseOfCategories(test):
+                    self.hardMarkAsSkipped(test)
                 self.counter += 1
                 if self.showAll:
                     self.stream.write(self.fmt % self.counter)
                 super(LLDBTestResult, self).startTest(test)
 
+            def addSuccess(self, test):
+                global parsable
+                super(LLDBTestResult, self).addSuccess(test)
+                if parsable:
+                    self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
+
             def addError(self, test, err):
                 global sdir_has_content
+                global parsable
                 sdir_has_content = True
                 super(LLDBTestResult, self).addError(test, err)
                 method = getattr(test, "markError", None)
                 if method:
                     method()
+                if parsable:
+                    self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
 
             def addFailure(self, test, err):
                 global sdir_has_content
+                global failuresPerCategory
+                global parsable
                 sdir_has_content = True
                 super(LLDBTestResult, self).addFailure(test, err)
                 method = getattr(test, "markFailure", None)
                 if method:
                     method()
+                if parsable:
+                    self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
+                if useCategories:
+                    test_categories = self.getCategoriesForTest(test)
+                    for category in test_categories:
+                        if category in failuresPerCategory:
+                            failuresPerCategory[category] = failuresPerCategory[category] + 1
+                        else:
+                            failuresPerCategory[category] = 1
 
-            def addExpectedFailure(self, test, err):
+            def addExpectedFailure(self, test, err, bugnumber):
                 global sdir_has_content
+                global parsable
                 sdir_has_content = True
-                super(LLDBTestResult, self).addExpectedFailure(test, err)
+                super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
                 method = getattr(test, "markExpectedFailure", None)
                 if method:
-                    method()
+                    method(err, bugnumber)
+                if parsable:
+                    self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
 
             def addSkip(self, test, reason):
                 global sdir_has_content
+                global parsable
                 sdir_has_content = True
                 super(LLDBTestResult, self).addSkip(test, reason)
                 method = getattr(test, "markSkippedTest", None)
                 if method:
                     method()
+                if parsable:
+                    self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
 
-            def addUnexpectedSuccess(self, test):
+            def addUnexpectedSuccess(self, test, bugnumber):
                 global sdir_has_content
+                global parsable
                 sdir_has_content = True
-                super(LLDBTestResult, self).addUnexpectedSuccess(test)
+                super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
                 method = getattr(test, "markUnexpectedSuccess", None)
                 if method:
-                    method()
+                    method(bugnumber)
+                if parsable:
+                    self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
+
+        if parsable:
+            v = 0
+        elif progress_bar:
+            v = 1
+        else:
+            v = verbose
 
         # Invoke the test runner.
         if count == 1:
             result = unittest2.TextTestRunner(stream=sys.stderr,
-                                              verbosity=(1 if progress_bar else verbose),
+                                              verbosity=v,
                                               failfast=failfast,
                                               resultclass=LLDBTestResult).run(suite)
         else:
@@ -1371,16 +1564,27 @@ for ia in range(len(archs) if iterArchs
             # not enforced.
             LLDBTestResult.__ignore_singleton__ = True
             for i in range(count):
+               
                 result = unittest2.TextTestRunner(stream=sys.stderr,
-                                                  verbosity=(1 if progress_bar else verbose),
+                                                  verbosity=v,
                                                   failfast=failfast,
                                                   resultclass=LLDBTestResult).run(suite)
 
+        failed = failed or not result.wasSuccessful()
 
-if sdir_has_content:
+if sdir_has_content and not parsable:
     sys.stderr.write("Session logs for test failures/errors/unexpected successes"
                      " can be found in directory '%s'\n" % sdir_name)
 
+if useCategories and len(failuresPerCategory) > 0:
+    sys.stderr.write("Failures per category:\n")
+    for category in failuresPerCategory:
+        sys.stderr.write("%s - %d\n" % (category,failuresPerCategory[category]))
+
+fname = os.path.join(sdir_name, "TestFinished")
+with open(fname, "w") as f:
+    print >> f, "Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
+
 # Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
 # This should not be necessary now.
 if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
@@ -1388,4 +1592,4 @@ if ("LLDB_TESTSUITE_FORCE_FINISH" in os.
     subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
 
 # Exiting.
-sys.exit(not result.wasSuccessful)
+sys.exit(failed)

Modified: lldb/branches/lldb-platform-work/test/example/TestSequenceFunctions.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/example/TestSequenceFunctions.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/example/TestSequenceFunctions.py (original)
+++ lldb/branches/lldb-platform-work/test/example/TestSequenceFunctions.py Thu Jun  6 19:06:43 2013
@@ -29,6 +29,8 @@ class SequenceFunctionsTestCase(unittest
         for element in random.sample(self.seq, 5):
             self.assertTrue(element in self.seq)
 
+    def getCategories(self):
+        return []
 
 if __name__ == '__main__':
     unittest.main()

Modified: lldb/branches/lldb-platform-work/test/expression_command/call-function/TestCallStdStringFunction.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/call-function/TestCallStdStringFunction.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/call-function/TestCallStdStringFunction.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/call-function/TestCallStdStringFunction.py Thu Jun  6 19:06:43 2013
@@ -26,19 +26,18 @@ class ExprCommandCallFunctionTestCase(Te
         self.call_function()
 
     @dwarf_test
+    @expectedFailureGcc # llvm.org/pr14437, fails with GCC 4.6.3 and 4.7.2
     def test_with_dwarf(self):
         """Test calling std::String member function."""
-        self.buildDsym()
+        self.buildDwarf()
         self.call_function()
 
     def call_function(self):
         """Test calling std::String member function."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        # Some versions of GCC encode two locations for the 'return' statement in main.cpp
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/expression_command/call-function/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/call-function/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/call-function/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/call-function/main.cpp Thu Jun  6 19:06:43 2013
@@ -6,10 +6,9 @@ int main (int argc, char const *argv[])
     std::string str = "Hello world";
     std::cout << str << std::endl;
     std::cout << str.c_str() << std::endl;
-    // Please test these expressions while stopped at this line:
 #if 0
     print str
     print str.c_str()
 #endif
-    return 0;
+    return 0; // Please test these expressions while stopped at this line:
 }

Modified: lldb/branches/lldb-platform-work/test/expression_command/formatters/TestFormatters.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/formatters/TestFormatters.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/formatters/TestFormatters.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/formatters/TestFormatters.py Thu Jun  6 19:06:43 2013
@@ -28,7 +28,7 @@ class ExprFormattersTestCase(TestBase):
     @dwarf_test
     def test_with_dwarf(self):
         """Test expr + formatters for good interoperability."""
-        self.buildDsym()
+        self.buildDwarf()
         self.do_my_test()
 
     def do_my_test(self):
@@ -45,20 +45,17 @@ class ExprFormattersTestCase(TestBase):
         """Test expr + formatters for good interoperability."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
         self.runCmd("script import formatters")
         self.runCmd("script import foosynth")
         
-        self.runCmd("frame variable foo1 -T")
-        self.runCmd("frame variable foo1.b -T")
-        self.runCmd("frame variable foo1.b.b_ref -T")
+        self.runCmd("frame variable foo1 --show-types")
+        self.runCmd("frame variable foo1.b --show-types")
+        self.runCmd("frame variable foo1.b.b_ref --show-types")
 
-        self.expect("expression *(new foo(47))",
+        self.expect("expression --show-types -- *(new foo(47))",
             substrs = ['(int) a = 47', '(bar) b = {', '(int) i = 94', '(baz) b = {', '(int) k = 99'])
 
         self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
@@ -96,7 +93,7 @@ class ExprFormattersTestCase(TestBase):
         self.runCmd("type summary delete foo")
         self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo")
 
-        self.expect("expression $" + object_name,
+        self.expect("expression --show-types -- $" + object_name,
             substrs = ['(foo) $', ' = {', '(int) *i_ptr = 243'])
 
         self.runCmd("n")
@@ -120,7 +117,7 @@ class ExprFormattersTestCase(TestBase):
         self.runCmd("type summary delete foo")
         self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo")
 
-        self.expect("expression $" + object_name,
+        self.expect("expression --show-types -- $" + object_name,
             substrs = ['(foo) $', ' = {', '(int) *i_ptr = 8888'])
 
         self.runCmd("n")

Modified: lldb/branches/lldb-platform-work/test/expression_command/issue_11588/Test11588.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/issue_11588/Test11588.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/issue_11588/Test11588.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/issue_11588/Test11588.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ expected in a SyntheticChildrenProvider
 import os, time
 import unittest2
 import lldb
+import lldbutil
 from lldbtest import *
 
 class Issue11581TestCase(TestBase):
@@ -19,28 +20,32 @@ class Issue11581TestCase(TestBase):
         def cleanup():
             self.runCmd('type synthetic clear', check=False)
 
+
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
         """valobj.AddressOf() should return correct values."""
         self.buildDefault()
-
-        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
-
-        self.runCmd("breakpoint set --name main")
-
-        self.runCmd("run", RUN_SUCCEEDED)
-
-        self.runCmd("next", RUN_SUCCEEDED)
-        self.runCmd("next", RUN_SUCCEEDED)
-        self.runCmd("next", RUN_SUCCEEDED)
-        self.runCmd("next", RUN_SUCCEEDED)
-        self.runCmd("next", RUN_SUCCEEDED)
+        
+        exe = os.path.join(os.getcwd(), "a.out")
+        
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        breakpoint = target.BreakpointCreateBySourceRegex('Set breakpoint here.',lldb.SBFileSpec ("main.cpp", False))
+        
+        process = target.LaunchSimple (None, None, os.getcwd())
+        self.assertTrue (process, "Created a process.")
+        self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped it too.")
+
+        thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
+        self.assertTrue (len(thread_list) == 1)
+        thread = thread_list[0]
 
         self.runCmd("command script import --allow-reload s11588.py")
         self.runCmd("type synthetic add --python-class s11588.Issue11581SyntheticProvider StgClosure")
 
-        self.expect("print *((StgClosure*)(r14-1))",
+        self.expect("expr --show-types -- *((StgClosure*)(r14-1))",
             substrs = ["(StgClosure) $",
             "(StgClosure *) &$","0x",
             "addr = ",
@@ -60,11 +65,11 @@ class Issue11581TestCase(TestBase):
                 self.runCmd("register write r14 %d" % addr)
                 self.expect("register read r14",
                     substrs = ["0x",hex(addr)[2:].rstrip("L")])  # Remove trailing 'L' if it exists
-                self.expect("print *(StgClosure*)$r14",
+                self.expect("expr --show-types -- *(StgClosure*)$r14",
                     substrs = ["(StgClosure) $",
                     "(StgClosure *) &$","0x",
-                    "(long) addr = ",
-                    "(long) load_address = ",
+                    "addr = ",
+                    "load_address = ",
                     hex(addr)[2:].rstrip("L"),
                     str(addr)])
 

Modified: lldb/branches/lldb-platform-work/test/expression_command/issue_11588/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/issue_11588/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/issue_11588/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/issue_11588/main.cpp Thu Jun  6 19:06:43 2013
@@ -50,5 +50,5 @@ int main()
 	ptr_type r14 = (ptr_type)r14_;
 	int x = 0;
 	x = 3;
-	return (x-1);
+	return (x-1); // Set breakpoint here.
 }

Modified: lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/TestPersistentVariables.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/TestPersistentVariables.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/TestPersistentVariables.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/TestPersistentVariables.py Thu Jun  6 19:06:43 2013
@@ -17,30 +17,38 @@ class PersistentVariablesTestCase(TestBa
 
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.runCmd("breakpoint set --name main")
+        self.runCmd("breakpoint set --source-pattern-regexp break")
 
         self.runCmd("run", RUN_SUCCEEDED)
 
-        self.expect("expression int $i = 5; $i + 1",
-            startstr = "(int) $0 = 6")
-        # (int) $0 = 6
+        self.runCmd("expression int $i = i")
+
+        self.expect("expression $i == i",
+            startstr = "(bool) $0 = true")
+
+        self.expect("expression $i + 1",
+            startstr = "(int) $1 = 6")
 
         self.expect("expression $i + 3",
-            startstr = "(int) $1 = 8")
-        # (int) $1 = 8
+            startstr = "(int) $2 = 8")
 
-        self.expect("expression $1 + $0",
-            startstr = "(int) $2 = 14")
-        # (int) $2 = 14
+        self.expect("expression $2 + $1",
+            startstr = "(int) $3 = 14")
+
+        self.expect("expression $3",
+            startstr = "(int) $3 = 14")
 
         self.expect("expression $2",
-            startstr = "(int) $2 = 14")
-        # (int) $2 =  14
+            startstr = "(int) $2 = 8")
+
+        self.expect("expression (int)-2",
+            startstr = "(int) $4 = -2")
 
-        self.expect("expression $1",
-            startstr = "(int) $1 = 8")
-        # (int) $1 = 8
+        self.expect("expression $4 > (int)31",
+            startstr = "(bool) $5 = false")
 
+        self.expect("expression (long)$4",
+            startstr = "(long) $6 = -2")
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/main.c?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/main.c (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/persistent_variables/main.c Thu Jun  6 19:06:43 2013
@@ -9,5 +9,6 @@
 
 int main (int argc, char const *argv[])
 {
-    return 0;
+    int i = 5;
+    return 0; // Set breakpoint here
 }

Modified: lldb/branches/lldb-platform-work/test/expression_command/radar_9531204/TestPrintfAfterUp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/radar_9531204/TestPrintfAfterUp.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/radar_9531204/TestPrintfAfterUp.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/radar_9531204/TestPrintfAfterUp.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar9531204TestCase(TestBase):
 
@@ -18,9 +19,7 @@ class Radar9531204TestCase(TestBase):
 
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -n foo",
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: name = 'foo', locations = 1")
+        lldbutil.run_break_set_by_symbol (self, 'foo', sym_exact=True, num_expected_locations=1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/expression_command/radar_9673664/TestExprHelpExamples.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/radar_9673664/TestExprHelpExamples.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/radar_9673664/TestExprHelpExamples.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/radar_9673664/TestExprHelpExamples.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar9673644TestCase(TestBase):
 
@@ -19,16 +20,14 @@ class Radar9673644TestCase(TestBase):
         self.line = line_number(self.main_source, '// Set breakpoint here.')
 
     # rdar://problem/9673664
+    @skipIfLinux # llvm.org/pr14805: expressions that require memory allocation evaluate incorrectly on Linux
     def test_expr_commands(self):
         """The following expression commands should just work."""
         self.buildDefault()
 
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f %s -l %d" % (self.main_source, self.line),
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
-                        (self.main_source, self.line))
+        lldbutil.run_break_set_by_file_and_line (self, self.main_source, self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs.py Thu Jun  6 19:06:43 2013
@@ -28,16 +28,18 @@ class BasicExprCommandsTestCase(TestBase
         self.line = line_number('main.cpp',
                                 '// Please test many expressions while stopped at this line:')
 
+        # Disable confirmation prompt to avoid infinite wait
+        self.runCmd("settings set auto-confirm true")
+        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+
     def test_many_expr_commands(self):
         """These basic expression commands should work as expected."""
         self.buildDefault()
 
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -74,12 +76,7 @@ class BasicExprCommandsTestCase(TestBase
         # (const char *) $7 = ...
 
         self.expect("expression argv[0]",
-            substrs = ["(const char *)",
-                       #
-                       # Relax this substring comparison a bit to take into acoount
-                       # the remote testsuite execution.
-                       #
-                       #os.path.join(self.mydir, "a.out")]                       
+            substrs = ["(const char *)", 
                        "a.out"])
         # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out"
 
@@ -165,6 +162,22 @@ class BasicExprCommandsTestCase(TestBase
             startstr = "'Z'")
         self.DebugSBValue(val)
 
+        callee_break = target.BreakpointCreateByName ("a_function_to_call", None)
+        self.assertTrue(callee_break.GetNumLocations() > 0)
+
+        # Make sure ignoring breakpoints works from the command line:
+        self.expect("expression -i true -- a_function_to_call()",
+                    substrs = ['(int) $', ' 1'])
+        self.assertTrue (callee_break.GetHitCount() == 1)
+
+        # Now try ignoring breakpoints using the SB API's:
+        options = lldb.SBExpressionOptions()
+        options.SetIgnoreBreakpoints(True)
+        value = frame.EvaluateExpression('a_function_to_call()', options)
+        self.assertTrue (value.IsValid())
+        self.assertTrue (value.GetValueAsSigned(0) == 2)
+        self.assertTrue (callee_break.GetHitCount() == 2)
+
     # rdar://problem/8686536
     # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands
     def test_expr_commands_can_handle_quotes(self):
@@ -173,10 +186,7 @@ class BasicExprCommandsTestCase(TestBase
 
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1,loc_exact=False)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -218,7 +228,6 @@ class BasicExprCommandsTestCase(TestBase
             substrs = ['(int) $',
                        '6'])
 
-
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()

Modified: lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs2.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs2.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs2.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/test/TestExprs2.py Thu Jun  6 19:06:43 2013
@@ -26,10 +26,7 @@ class ExprCommands2TestCase(TestBase):
 
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1,loc_exact=False)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/expression_command/test/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/test/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/test/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/test/main.cpp Thu Jun  6 19:06:43 2013
@@ -1,5 +1,14 @@
 #include <stdio.h>
 
+static int static_value = 0;
+
+int
+a_function_to_call()
+{
+    static_value++;
+    return static_value;
+}
+
 int main (int argc, char const *argv[])
 {
     printf ("Hello world!\n");
@@ -29,5 +38,7 @@ int main (int argc, char const *argv[])
     expression printf ("two: %llu, one: %i\n", 2ull, 1)
     expression random() % 255l
 #endif
+
+    a_function_to_call();
     return 0;
 }

Modified: lldb/branches/lldb-platform-work/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py (original)
+++ lldb/branches/lldb-platform-work/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ The expression parser's type search only
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class ObjCTypeQueryTestCase(TestBase):
 
@@ -26,6 +27,7 @@ class ObjCTypeQueryTestCase(TestBase):
         self.buildDsym()
         self.type_query_from_other_cu()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dwarf_test
     def test_with_dwarf(self):
         """The expression parser's type search should be wider than the current compilation unit."""
@@ -36,10 +38,7 @@ class ObjCTypeQueryTestCase(TestBase):
         """The expression parser's type search should be wider than the current compilation unit."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestAbbreviations.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestAbbreviations.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestAbbreviations.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestAbbreviations.py Thu Jun  6 19:06:43 2013
@@ -6,14 +6,15 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class AbbreviationsTestCase(TestBase):
-    
+
     mydir = os.path.join("functionalities", "abbreviation")
 
     def test_nonrunning_command_abbreviations (self):
         self.expect("ap script",
-                    startstr = "The following commands may relate to 'script':",
+                    startstr = "The following built-in commands may relate to 'script':",
                     substrs = ['breakpoint command add',
                                'breakpoint command list',
                                'breakpoint list',
@@ -34,7 +35,13 @@ class AbbreviationsTestCase(TestBase):
         self.expect("h",
                     startstr = "The following is a list of built-in, permanent debugger commands:")
 
+        # Execute cleanup function during test tear down
+        def cleanup():
+            self.runCmd("command alias t thread select")
+        self.addTearDownHook(cleanup)
+
         # Several matching commands: list them and error out.
+        self.runCmd("command unalias t")
         self.expect("t",
                     COMMAND_FAILED_AS_EXPECTED, error = True,
                     substrs = ["Ambiguous command 't'. Possible matches:",
@@ -47,7 +54,7 @@ class AbbreviationsTestCase(TestBase):
                     startstr = 'prompt (string) = "[with-three-trailing-spaces]   "')
 
 
-        self.runCmd("settings set -r prompt")
+        self.runCmd("settings clear prompt")
         self.expect("settings show prompt",
                     startstr = 'prompt (string) = "(lldb) "')
 
@@ -55,11 +62,11 @@ class AbbreviationsTestCase(TestBase):
         self.expect("lo li",
                     startstr = "Logging categories for ")
 
-        self.runCmd("se se prompt Sycamore> ")
+        self.runCmd("se se prompt 'Sycamore> '")
         self.expect("se sh prompt",
                     startstr = 'prompt (string) = "Sycamore> "')
 
-        self.runCmd("se se -r prompt")
+        self.runCmd("se cl prompt")
         self.expect("set sh prompt",
                     startstr = 'prompt (string) = "(lldb) "')
 
@@ -89,15 +96,15 @@ class AbbreviationsTestCase(TestBase):
         self.expect("file " + exe,
                     patterns = [ "Current executable set to .*a.out.*" ])
 
-        self.expect("_regexp-b product",
-                    substrs = [ "breakpoint set --name 'product'",
-                                "Breakpoint created: 1: name = 'product', locations = 1" ])
+        # By default, the setting interpreter.expand-regex-aliases is false.
+        self.expect("_regexp-br product", matching=False,
+                    substrs = [ "breakpoint set --name" ])
 
-        self.expect("br s -n sum",
-                    startstr = "Breakpoint created: 2: name = 'sum', locations = 1")
+        match_object = lldbutil.run_break_set_command (self, "br s -n sum")
+        lldbutil.check_breakpoint_result (self, match_object, symbol_name='sum', symbol_match_exact=False, num_locations=1)
 
-        self.expect("br s -f main.cpp -l 32",
-                    startstr = "Breakpoint created: 3: file ='main.cpp', line = 32, locations = 1")
+        match_object = lldbutil.run_break_set_command (self, "br s -f main.cpp -l 32")
+        lldbutil.check_breakpoint_result (self, match_object, file_name='main.cpp', line_number=32, num_locations=1)
 
         self.runCmd("br co a -s python 1 -o 'print frame'")
         self.expect("br co l 1",
@@ -137,18 +144,16 @@ class AbbreviationsTestCase(TestBase):
                                  "thread #1:",
                                  "a.out",
                                  "sum\(a=1238, b=78392\)",
-                                 "at main.cpp\:25", 
+                                 "at main.cpp\:25",
                                  "stop reason = breakpoint 2.1" ])
 
         # ARCH, if not specified, defaults to x86_64.
         if self.getArchitecture() in ["", 'x86_64', 'i386']:
             self.expect("dis -f",
                         startstr = "a.out`sum(int, int)",
-                        substrs = [' push',
-                                   ' mov',
+                        substrs = [' mov',
                                    ' addl ',
-                                   'ret'],
-                        patterns = ['(leave|popq|popl)'])                               
+                                   'ret'])
 
         self.expect("i d l main.cpp",
                     patterns = ["Line table for .*main.cpp in `a.out"])
@@ -166,7 +171,6 @@ class AbbreviationsTestCase(TestBase):
             self.expect("i li",
                         substrs = [ 'a.out',
                                     '/usr/lib/dyld',
-                                    '/usr/lib/libstdc++',
                                     '/usr/lib/libSystem.B.dylib'])
 
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestCommonShortSpellings.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestCommonShortSpellings.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestCommonShortSpellings.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/abbreviation/TestCommonShortSpellings.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class CommonShortSpellingsTestCase(TestBase):
     
@@ -29,9 +30,14 @@ class CommonShortSpellingsTestCase(TestB
                     patterns = [ "Current executable set to .*a.out.*" ])
 
         # br s -> breakpoint set
-        self.expect("br s -n sum",
-            startstr = "Breakpoint created: 1: name = 'sum', locations = 1")
-
+        
+        match_object = lldbutil.run_break_set_command (self, "br s -n sum")
+        lldbutil.check_breakpoint_result (self, match_object, symbol_name='sum', symbol_match_exact=False, num_locations=1)
+
+        self.runCmd("settings set interpreter.expand-regex-aliases true")
+        self.addTearDownHook(
+            lambda: self.runCmd("settings set interpreter.expand-regex-aliases false"))
+        
         # disp -> display
         self.expect("disp a",
             startstr = "target stop-hook add -o")

Modified: lldb/branches/lldb-platform-work/test/functionalities/abbreviation/change_prompt.lldb
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/abbreviation/change_prompt.lldb?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/abbreviation/change_prompt.lldb (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/abbreviation/change_prompt.lldb Thu Jun  6 19:06:43 2013
@@ -1,2 +1 @@
-settings set prompt [with-three-trailing-spaces]   
-
+settings set prompt "[with-three-trailing-spaces]   "
\ No newline at end of file

Modified: lldb/branches/lldb-platform-work/test/functionalities/alias/TestAliases.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/alias/TestAliases.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/alias/TestAliases.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/alias/TestAliases.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class AliasTestCase(TestBase):
 
@@ -80,15 +81,16 @@ class AliasTestCase(TestBase):
         self.runCmd ("alias bpa bp command add")
         self.runCmd ("alias bpi bp list")
 
-        self.expect ("bp set -n foo",
-                     startstr = "Breakpoint created: 1: name = 'foo', locations = 1")
+        break_results = lldbutil.run_break_set_command (self, "bp set -n foo")
+        lldbutil.check_breakpoint_result (self, break_results, num_locations=1, symbol_name='foo', symbol_match_exact=False)
 
-        self.expect ("bp set -n sum",
-                     startstr = "Breakpoint created: 2: name = 'sum', locations = 1")
+        break_results = lldbutil.run_break_set_command (self, "bp set -n sum")
+        lldbutil.check_breakpoint_result (self, break_results, num_locations=1, symbol_name='sum', symbol_match_exact=False)
 
         self.runCmd ("alias bfl bp set -f %1 -l %2")
-        self.expect ("bfl main.cpp 32",
-                     startstr = "Breakpoint created: 3: file ='main.cpp', line = 32, locations = 1")
+
+        break_results = lldbutil.run_break_set_command (self, "bfl main.cpp 32")
+        lldbutil.check_breakpoint_result (self, break_results, num_locations=1, file_name='main.cpp', line_number=32)
 
         self.expect ("bpi",
                      startstr = "Current breakpoints:",
@@ -134,22 +136,22 @@ class AliasTestCase(TestBase):
                                  "= 0x00000044" ])
 
         self.runCmd ("alias exprf expr -f %1")
-        self.runCmd ("alias exprf2 expr -f %1 --")
+        self.runCmd ("alias exprf2 expr --raw -f %1 --")
         self.expect ("exprf x -- 1234",
                      substrs = [ "(int) $",
                                  "= 0x000004d2" ])
 
         self.expect ('exprf2 c "Hi there!"',
-                     substrs = [ "(const char) [0] = 'H'",
-                                 "(const char) [1] = 'i'",
-                                 "(const char) [2] = ' '",
-                                 "(const char) [3] = 't'",
-                                 "(const char) [4] = 'h'",
-                                 "(const char) [5] = 'e'",
-                                 "(const char) [6] = 'r'",
-                                 "(const char) [7] = 'e'",
-                                 "(const char) [8] = '!'",
-                                 "(const char) [9] = '\\0'" ])
+                     substrs = [ "[0] = 'H'",
+                                 "[1] = 'i'",
+                                 "[2] = ' '",
+                                 "[3] = 't'",
+                                 "[4] = 'h'",
+                                 "[5] = 'e'",
+                                 "[6] = 'r'",
+                                 "[7] = 'e'",
+                                 "[8] = '!'",
+                                 "[9] = '\\0'" ])
         
 
         self.expect ("exprf x 1234",

Modified: lldb/branches/lldb-platform-work/test/functionalities/archives/TestBSDArchives.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/archives/TestBSDArchives.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/archives/TestBSDArchives.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/archives/TestBSDArchives.py Thu Jun  6 19:06:43 2013
@@ -4,6 +4,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class BSDArchivesTestCase(TestBase):
 
@@ -26,9 +27,8 @@ class BSDArchivesTestCase(TestBase):
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break inside a() by file and line first.
-        self.expect("breakpoint set -f a.c -l %d" % self.line, BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='a.c', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "a.c", self.line, num_expected_locations=1, loc_exact=True)
+
         self.runCmd("run", RUN_SUCCEEDED)
 
         # The stop reason of the thread should be breakpoint.
@@ -43,9 +43,7 @@ class BSDArchivesTestCase(TestBase):
             substrs = ['(int) __a_global = 1'])
 
         # Set breakpoint for b() next.
-        self.expect("breakpoint set -n b", BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 2: name = 'b'",
-            substrs = ['resolved = 1'])
+        lldbutil.run_break_set_by_symbol (self, "b", num_expected_locations=1, sym_exact=True)
 
         # Continue the program, we should break at b(int) next.
         self.runCmd("continue")

Modified: lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class BreakpointCommandTestCase(TestBase):
 
@@ -37,6 +38,9 @@ class BreakpointCommandTestCase(TestBase
         TestBase.setUp(self)
         # Find the line number to break inside main().
         self.line = line_number('main.c', '// Set break point at this line.')
+        # disable "There is a running process, kill it and restart?" prompt
+        self.runCmd("settings set auto-confirm true")
+        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
 
     def breakpoint_command_sequence(self):
         """Test a sequence of breakpoint command add, list, and delete."""
@@ -45,21 +49,12 @@ class BreakpointCommandTestCase(TestBase
 
         # Add three breakpoints on the same line.  The first time we don't specify the file,
         # since the default file is the one containing main:
-        self.expect("breakpoint set -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 1" %
-                        self.line)
-        self.expect("breakpoint set -f main.c -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 2: file ='main.c', line = %d, locations = 1" %
-                        self.line)
-        self.expect("breakpoint set -f main.c -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 3: file ='main.c', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
 
         # 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 --show-types --scope' 1")
         self.runCmd("breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); print >> here, \"lldb\"; here.close()' 2")
         self.runCmd("breakpoint command add --python-function bktptcmd.function 3")
 
@@ -78,7 +73,7 @@ class BreakpointCommandTestCase(TestBase
 
         self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
             substrs = ["Breakpoint commands:",
-                          "frame variable -T -s"])
+                          "frame variable --show-types --scope"])
         self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
             substrs = ["Breakpoint commands:",
                           "here = open",
@@ -93,21 +88,17 @@ class BreakpointCommandTestCase(TestBase
         # Next lets try some other breakpoint kinds.  First break with a regular expression
         # and then specify only one file.  The first time we should get two locations,
         # the second time only one:
-        self.expect ("break set -r ._MyFunction",
-                     patterns = ["Breakpoint created: [0-9]+: regex = '\._MyFunction', locations = 2"])
-      
-        self.expect ("break set -r ._MyFunction -f a.c",
-                     patterns = ["Breakpoint created: [0-9]+: regex = '\._MyFunction', locations = 1"])
+
+        lldbutil.run_break_set_by_regexp (self, r"._MyFunction", num_expected_locations=2)
+        
+        lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1)
       
-        self.expect ("break set -r ._MyFunction -f a.c -f b.c",
-                     patterns = ["Breakpoint created: [0-9]+: regex = '\._MyFunction', locations = 2"])
+        lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c -f b.c", num_expected_locations=2)
 
         # Now try a source regex breakpoint:
-        self.expect ("break set -p \"is about to return [12]0\" -f a.c -f b.c",
-                     patterns = ["Breakpoint created: [0-9]+: source regex = \"is about to return \[12\]0\", locations = 2"])
+        lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c -f b.c", num_expected_locations=2)
       
-        self.expect ("break set -p \"is about to return [12]0\" -f a.c",
-                     patterns = ["Breakpoint created: [0-9]+: source regex = \"is about to return \[12\]0\", locations = 1"])
+        lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c", num_expected_locations=1)
       
         # Run the program.  Remove 'output.txt' if it exists.
         self.RemoveTempFile("output.txt")
@@ -181,10 +172,7 @@ class BreakpointCommandTestCase(TestBase
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Add a breakpoint.
-        self.expect("breakpoint set -f main.c -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
 
         # Now add callbacks for the breakpoints just created.
         self.runCmd("breakpoint command add -s python -o 'here = open(\"output-2.txt\", \"w\"); print >> here, frame; print >> here, bp_loc; here.close()' 1")

Modified: lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py Thu Jun  6 19:06:43 2013
@@ -67,12 +67,10 @@ class BreakpointConditionsTestCase(TestB
 
         if inline:
             # Create a breakpoint by function name 'c' and set the condition.
-            self.expect("breakpoint set -n c -c 'val == 3'", BREAKPOINT_CREATED,
-                startstr = "Breakpoint created: 1: name = 'c', locations = 1")
+            lldbutil.run_break_set_by_symbol (self, "c", extra_options="-c 'val == 3'", num_expected_locations=1, sym_exact=True)
         else:
             # Create a breakpoint by function name 'c'.
-            self.expect("breakpoint set -n c", BREAKPOINT_CREATED,
-                startstr = "Breakpoint created: 1: name = 'c', locations = 1")
+            lldbutil.run_break_set_by_symbol (self, "c", num_expected_locations=1, sym_exact=True)
 
             # And set a condition on the breakpoint to stop on when 'val == 3'.
             self.runCmd("breakpoint modify -c 'val == 3' 1")
@@ -84,8 +82,8 @@ class BreakpointConditionsTestCase(TestB
         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 --show-types val' should return 3 due to breakpoint condition.
+        self.expect("frame variable --show-types val", VARIABLES_DISPLAYED_CORRECTLY,
             startstr = '(int) val = 3')
 
         # Also check the hit count, which should be 3, by design.
@@ -115,8 +113,8 @@ class BreakpointConditionsTestCase(TestB
         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 --show-types val' should return 1 since it is the first breakpoint hit.
+        self.expect("frame variable --show-types val", VARIABLES_DISPLAYED_CORRECTLY,
             startstr = '(int) val = 1')
 
 
@@ -167,7 +165,7 @@ class BreakpointConditionsTestCase(TestB
         # Frame #0 should be on self.line1 and the break condition should hold.
         from lldbutil import get_stopped_thread
         thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
-        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
+        self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
         frame0 = thread.GetFrameAtIndex(0)
         var = frame0.FindValue('val', lldb.eValueTypeVariableArgument)
         self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and

Modified: lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class BreakpointIDTestCase(TestBase):
 
@@ -27,15 +28,15 @@ class BreakpointIDTestCase(TestBase):
         self.expect("file " + exe,
                     patterns = [ "Current executable set to .*a.out" ])
 
-        self.expect ("breakpoint set -n product",
-                     startstr = "Breakpoint created: 1: name = 'product', locations =")
+        
+        bpno = lldbutil.run_break_set_by_symbol (self, 'product', num_expected_locations=-1, sym_exact=False)
+        self.assertTrue (bpno == 1, "First breakpoint number is 1.")
 
-        self.expect ("breakpoint set -n sum",
-                     startstr = "Breakpoint created: 2: name = 'sum', locations =")
+        bpno = lldbutil.run_break_set_by_symbol (self, 'sum', num_expected_locations=-1, sym_exact=False)
+        self.assertTrue (bpno == 2, "Second breakpoint number is 2.")
 
-        self.expect ("breakpoint set -n junk",
-                     startstr = "Breakpoint created: 3: name = 'junk', locations = 0 (pending)",
-                     substrs = [ "WARNING:  Unable to resolve breakpoint to any actual locations." ] )
+        bpno = lldbutil.run_break_set_by_symbol (self, 'junk', num_expected_locations=0, sym_exact=False)
+        self.assertTrue (bpno == 3, "Third breakpoint number is 3.")
 
         self.expect ("breakpoint disable 1.1 - 2.2 ",
                      COMMAND_FAILED_AS_EXPECTED, error = True,

Modified: lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py Thu Jun  6 19:06:43 2013
@@ -55,10 +55,8 @@ class BreakpointIgnoreCountTestCase(Test
         exe = os.path.join(os.getcwd(), "a.out")
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
-        # Create a breakpoint by function name 'c'.
-        self.expect("breakpoint set -i 1 -f main.c -l %d" % self.line1, BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 1" %
-                        self.line1)
+        # Create a breakpoint in main.c at line1.
+        lldbutil.run_break_set_by_file_and_line (self, 'main.c', self.line1, extra_options='-i 1', num_expected_locations=1, loc_exact=True)
 
         # Now run the program.
         self.runCmd("run", RUN_SUCCEEDED)
@@ -136,7 +134,7 @@ class BreakpointIgnoreCountTestCase(Test
         #lldbutil.print_stacktraces(process)
         from lldbutil import get_stopped_thread
         thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
-        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
+        self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
         frame0 = thread.GetFrameAtIndex(0)
         frame1 = thread.GetFrameAtIndex(1)
         frame2 = thread.GetFrameAtIndex(2)

Modified: lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class BreakpointLocationsTestCase(TestBase):
 
@@ -36,10 +37,7 @@ class BreakpointLocationsTestCase(TestBa
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # This should create a breakpoint with 3 locations.
-        self.expect("breakpoint set -f main.c -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 3" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=3)
 
         # The breakpoint list should show 3 locations.
         self.expect("breakpoint list -f", "Breakpoint locations shown correctly",

Modified: lldb/branches/lldb-platform-work/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class InlinedBreakpointsTestCase(TestBase):
     """Bug fixed: rdar://problem/8464339"""
@@ -37,10 +38,16 @@ class InlinedBreakpointsTestCase(TestBas
         exe = os.path.join(os.getcwd(), "a.out")
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f basic_type.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
-                        self.line)
+        # Set a breakpoint and fail because it is in an inlined source implemenation file
+        lldbutil.run_break_set_by_file_and_line (self, "basic_type.cpp", self.line, num_expected_locations=0)
+
+        # Now enable breakpoints in implementation files and see the breakpoint set succeed
+        self.runCmd('settings set target.inline-breakpoint-strategy always')
+        # And add hooks to restore the settings during tearDown().
+        self.addTearDownHook(
+            lambda: self.runCmd("settings set target.inline-breakpoint-strategy headers"))
+
+        lldbutil.run_break_set_by_file_and_line (self, "basic_type.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/TestCommandScript.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/TestCommandScript.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/TestCommandScript.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/TestCommandScript.py Thu Jun  6 19:06:43 2013
@@ -18,6 +18,7 @@ class CmdPythonTestCase(TestBase):
         self.pycmd_tests ()
 
     @dwarf_test
+    @skipIfLinux # causes buildbot failures, skip until we can investigate it
     def test_with_dwarf (self):
         self.buildDwarf ()
         self.pycmd_tests ()
@@ -44,6 +45,9 @@ class CmdPythonTestCase(TestBase):
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
+        # Interact with debugger in synchronous mode
+        self.setAsync(False)
+
         # We don't want to display the stdout if not in TraceOn() mode.
         if not self.TraceOn():
             self.HideStdout()
@@ -106,11 +110,22 @@ class CmdPythonTestCase(TestBase):
         self.expect("tell_async",
                     substrs = ['running async'])
         self.expect("tell_curr",
-                    substrs = ['I am running','sync'])
+                    substrs = ['I am running sync'])
 
+        # Test that a python command can redefine itself
+        self.expect('command script add -f foobar welcome')
 
         self.runCmd("command script clear")
 
+        # Test that re-defining an existing command works
+        self.runCmd('command script add my_command --function welcome.welcome_impl')
+        self.expect('my_command Blah', substrs = ['Hello Blah, welcome to LLDB'])
+
+        self.runCmd('command script add my_command --function welcome.target_name_impl')
+        self.expect('my_command', substrs = ['a.out'])
+
+        self.runCmd("command script clear")
+                
         self.expect('command script list', matching=False,
                     substrs = ['targetname',
                                'longwait'])

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/import/TestImport.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/import/TestImport.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/import/TestImport.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/import/TestImport.py Thu Jun  6 19:06:43 2013
@@ -10,6 +10,7 @@ class ImportTestCase(TestBase):
     mydir = os.path.join("functionalities", "command_script", "import")
 
     @python_api_test
+    @skipIfLinux # causes buildbot failures, skip until we can investigate it
     def test_import_command(self):
         """Import some Python scripts by path and test them"""
         self.run_test()
@@ -29,6 +30,8 @@ class ImportTestCase(TestBase):
             self.runCmd('command script delete foobarcmd', check=False)
             self.runCmd('command script delete barcmd', check=False)
             self.runCmd('command script delete barothercmd', check=False)
+            self.runCmd('command script delete TPcommandA', check=False)
+            self.runCmd('command script delete TPcommandB', check=False)
 
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
@@ -42,13 +45,15 @@ class ImportTestCase(TestBase):
                 error=True, startstr='error: module importing failed')
         self.expect("command script import ./nosuchfolder/",
                 error=True, startstr='error: module importing failed')
-        self.expect("command script import ./foo/foo.py",
-                error=True, startstr='error: module importing failed')
+        self.expect("command script import ./foo/foo.py", error=False)
+
+        self.runCmd("command script import --allow-reload ./thepackage")
+        self.expect("TPcommandA",substrs=["hello world A"])
+        self.expect("TPcommandB",substrs=["hello world B"])
 
         self.runCmd("script import dummymodule")
-        self.expect("command script import ./dummymodule.py",
-                error=True, startstr='error: module importing failed')
-        self.runCmd("command script import --allow-reload ./dummymodule.py")
+        self.expect("command script import ./dummymodule.py", error=False)
+        self.expect("command script import --allow-reload ./dummymodule.py", error=False)
 
         self.runCmd("command script add -f foo.foo_function foocmd")
         self.runCmd("command script add -f foobar.foo_function foobarcmd")

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/import/bar/bar.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/import/bar/bar.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/import/bar/bar.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/import/bar/bar.py Thu Jun  6 19:06:43 2013
@@ -1,6 +1,6 @@
 def bar_function(debugger, args, result, dict):
 	global UtilityModule
-	result.Printf(UtilityModule.barutil_function("bar told me " + args))
+	print >>result,  (UtilityModule.barutil_function("bar told me " + args))
 	return None
 
 def __lldb_init_module(debugger, session_dict):

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/bar/foobar.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/bar/foobar.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/bar/foobar.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/bar/foobar.py Thu Jun  6 19:06:43 2013
@@ -1,3 +1,3 @@
 def foo_function(debugger, args, result, dict):
-	result.Printf("foobar says " + args)
+	print >>result,  ("foobar says " + args)
 	return None

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo.py Thu Jun  6 19:06:43 2013
@@ -1,3 +1,3 @@
 def foo_function(debugger, args, result, dict):
-	result.Printf("foo says " + args)
+	print >>result,  ("foo says " + args)
 	return None

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo2.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo2.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo2.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/import/foo/foo2.py Thu Jun  6 19:06:43 2013
@@ -1,5 +1,5 @@
 def foo2_function(debugger, args, result, dict):
-	result.Printf("foo2 says " + args)
+	print >>result,  ("foo2 says " + args)
 	return None
 
 def __lldb_init_module(debugger, session_dict):

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/main.cpp Thu Jun  6 19:06:43 2013
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <cstdlib>
+#include <cstring>
 #include <string>
 #include <fstream>
 #include <iostream>

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/mysto.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/mysto.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/mysto.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/mysto.py Thu Jun  6 19:06:43 2013
@@ -11,7 +11,7 @@ def StepOver(debugger, args, result, dic
 	print type(arg_split)
 	count = int(arg_split[0])
 	for i in range(0,count):
-		lldb.thread.StepOver(lldb.eOnlyThisThread)
+		debugger.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver(lldb.eOnlyThisThread)
 		print "step<%d>"%i
 
 def __lldb_init_module(debugger, session_dict):

Modified: lldb/branches/lldb-platform-work/test/functionalities/command_script/welcome.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/command_script/welcome.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/command_script/welcome.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/command_script/welcome.py Thu Jun  6 19:06:43 2013
@@ -5,30 +5,31 @@ def welcome_impl(debugger, args, result,
         Just a docstring for welcome_impl
         A command that says hello to LLDB users
     """
-    result.Printf('Hello ' + args + ', welcome to LLDB');
+    print >>result,  ('Hello ' + args + ', welcome to LLDB');
     return None;
 
 def target_name_impl(debugger, args, result, dict):
     target = debugger.GetSelectedTarget()
     file = target.GetExecutable()
-    result.PutCString('Current target ' + file.GetFilename())
+    print >>result,  ('Current target ' + file.GetFilename())
     if args == 'fail':
         return 'a test for error in command'
     else:
         return None
 
 def print_wait_impl(debugger, args, result, dict):
-    print 'Trying to do long task..';
+    result.SetImmediateOutputFile(sys.stdout)
+    print >>result,  ('Trying to do long task..')
     import time
     time.sleep(1)
-    print 'Still doing long task..';
+    print >>result,  ('Still doing long task..')
     time.sleep(1)
-    result.PutCString('Done; if you saw the delays I am doing OK')
+    print >>result,  ('Done; if you saw the delays I am doing OK')
     return None
 
 def check_for_synchro(debugger, args, result, dict):
     if debugger.GetAsync() == True:
-        result.PutCString('I am running async')
+        print >>result,  ('I am running async')
     if debugger.GetAsync() == False:
-        result.PutCString('I am running sync')
+        print >>result,  ('I am running sync')
     return None

Modified: lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py Thu Jun  6 19:06:43 2013
@@ -15,14 +15,26 @@ class CommandLineCompletionTestCase(Test
     @classmethod
     def classCleanup(cls):
         """Cleanup the test byproducts."""
-        os.remove("child_send.txt")
-        os.remove("child_read.txt")
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+        except:
+            pass
+
+    def test_at(self):
+        """Test that 'at' completes to 'attach '."""
+        self.complete_from_to('at', 'attach ')
+
+    def test_de(self):
+        """Test that 'de' completes to 'detach '."""
+        self.complete_from_to('de', 'detach ')
 
     def test_process_attach_dash_dash_con(self):
         """Test that 'process attach --con' completes to 'process attach --continue '."""
         self.complete_from_to('process attach --con', 'process attach --continue ')
 
     # <rdar://problem/11052829>
+    @skipIfLinux # llvm.org/pr14637: this test case fails (with GCC 4.6 but not clang) because the input prompt "(lldb)" is missing
     def test_infinite_loop_while_completing(self):
         """Test that 'process print hello\' completes to itself and does not infinite loop."""
         self.complete_from_to('process print hello\\', 'process print hello\\',
@@ -85,12 +97,12 @@ class CommandLineCompletionTestCase(Test
         self.complete_from_to('settings set th', 'settings set thread-format')
 
     def test_settings_s_dash(self):
-        """Test that 'settings set -' completes to ['Available completions:', '-n', '-r']."""
-        self.complete_from_to('settings set -', ['Available completions:', '-n', '-r'])
+        """Test that 'settings set -' completes to 'settings set -g'."""
+        self.complete_from_to('settings set -', 'settings set -g')
 
-    def test_settings_set_dash_r_th(self):
-        """Test that 'settings set -r th' completes to 'settings set -r thread-format'."""
-        self.complete_from_to('settings set -r th', 'settings set -r thread-format')
+    def test_settings_clear_th(self):
+        """Test that 'settings clear th' completes to 'settings clear thread-format'."""
+        self.complete_from_to('settings clear th', 'settings clear thread-format')
 
     def test_settings_set_ta(self):
         """Test that 'settings set ta' completes to 'settings set target.'."""
@@ -98,7 +110,7 @@ class CommandLineCompletionTestCase(Test
 
     def test_settings_set_target_exec(self):
         """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""
-        self.complete_from_to('settings set target.exec', 'settings set target.exec-search-paths ')
+        self.complete_from_to('settings set target.exec', 'settings set target.exec-search-paths')
 
     def test_settings_set_target_pr(self):
         """Test that 'settings set target.pr' completes to ['Available completions:',
@@ -131,6 +143,10 @@ class CommandLineCompletionTestCase(Test
                               ['Available completions:', 'create', 'delete', 'list',
                                'modules', 'select', 'stop-hook', 'variable'])
 
+    def test_target_create_dash_co(self):
+        """Test that 'target create --co' completes to 'target variable --core '."""
+        self.complete_from_to('target create --co', 'target create --core ')
+
     def test_target_va(self):
         """Test that 'target va' completes to 'target variable '."""
         self.complete_from_to('target va', 'target variable ')

Modified: lldb/branches/lldb-platform-work/test/functionalities/conditional_break/.lldb
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/conditional_break/.lldb?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/conditional_break/.lldb (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/conditional_break/.lldb Thu Jun  6 19:06:43 2013
@@ -1,7 +1,7 @@
 #file a.out
 breakpoint set -n c
-script import sys, os
-script sys.path.append(os.path.join(os.getcwd(), os.pardir))
-script import conditional_break
-breakpoint command add -s python 1 -o "conditional_break.stop_if_called_from_a()"
+#script import sys, os
+#script sys.path.append(os.path.join(os.getcwd(), os.pardir))
+command script import -r conditional_break.py
+breakpoint command add 1 -F "conditional_break.stop_if_called_from_a"
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/conditional_break/TestConditionalBreak.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/conditional_break/TestConditionalBreak.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/conditional_break/TestConditionalBreak.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/conditional_break/TestConditionalBreak.py Thu Jun  6 19:06:43 2013
@@ -40,6 +40,7 @@ class ConditionalBreakTestCase(TestBase)
         self.simulate_conditional_break_by_user()
 
     @dwarf_test
+    @skipIfLinux # due to two assertion failures introduced by r174793: ProcessPOSIX.cpp:223 (assertion 'state == eStateStopped || state == eStateCrashed') and POSIXThread.cpp:254 (assertion 'bp_site')
     def test_with_dwarf_command(self):
         """Simulate a user using lldb commands to break on c() if called from a()."""
         self.buildDwarf()
@@ -119,9 +120,14 @@ class ConditionalBreakTestCase(TestBase)
         self.runCmd("file a.out")
         self.runCmd("command source .lldb")
 
+        self.runCmd ("break list")
+
         if self.TraceOn():
             print "About to run."
         self.runCmd("run", RUN_SUCCEEDED)
+
+        self.runCmd ("break list")
+
         if self.TraceOn():
             print "Done running"
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/conditional_break/conditional_break.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/conditional_break/conditional_break.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/conditional_break/conditional_break.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/conditional_break/conditional_break.py Thu Jun  6 19:06:43 2013
@@ -1,31 +1,25 @@
 import sys
 import lldb
-import lldbutil
 
-def stop_if_called_from_a():
-    # lldb.debugger_unique_id stores the id of the debugger associated with us.
-    dbg = lldb.SBDebugger.FindDebuggerWithID(lldb.debugger_unique_id)
+def stop_if_called_from_a(frame, bp_loc, dict):
+
+    thread = frame.GetThread()
+    process = thread.GetProcess()
+    target = process.GetTarget()
+    dbg = target.GetDebugger()
 
     # Perform synchronous interaction with the debugger.
     old_async = dbg.GetAsync()
     dbg.SetAsync(True)
 
-    # Retrieve the target, process, and the only thread.
-    target = dbg.GetSelectedTarget()
-    process = target.GetProcess()
-    thread = process.GetThreadAtIndex(0)
-
     # We check the call frames in order to stop only when the immediate caller
     # of the leaf function c() is a().  If it's not the right caller, we ask the
     # command interpreter to continue execution.
 
-    print >> sys.stdout, "Checking call frames..."
-    lldbutil.print_stacktrace(thread)
     should_stop = True
     if thread.GetNumFrames() >= 2:
-        funcs = lldbutil.get_function_names(thread)
-        print >> sys.stdout, funcs[0], "called from", funcs[1]
-        if (funcs[0] == 'c' and funcs[1] == 'a'):
+
+        if (thread.frames[0].function.name == 'c' and thread.frames[1].function.name == 'a'):
             should_stop = True
         else:
             process.Continue()

Modified: lldb/branches/lldb-platform-work/test/functionalities/connect_remote/TestConnectRemote.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/connect_remote/TestConnectRemote.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/connect_remote/TestConnectRemote.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/connect_remote/TestConnectRemote.py Thu Jun  6 19:06:43 2013
@@ -31,7 +31,10 @@ class ConnectRemoteTestCase(TestBase):
         fakeserver.expect_exact('Listening on localhost:12345')
 
         # Connect to the fake server....
-        self.runCmd("process connect connect://localhost:12345")
+        if sys.platform.startswith("linux"):
+            self.runCmd("process connect -p gdb-remote connect://localhost:12345")
+        else:
+            self.runCmd("process connect connect://localhost:12345")
 
 
 if __name__ == '__main__':

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class AdvDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class AdvDataFormatterTestCase(TestBase)
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -79,7 +77,8 @@ class AdvDataFormatterTestCase(TestBase)
         self.expect("frame variable int_array",
             substrs = ['1,2,3,4,5'])
 
-        self.runCmd("type summary add --summary-string \"${var[].integer}\" -x \"i_am_cool \\[[0-9]\\]")
+        # this will fail if we don't do [] as regex correctly
+        self.runCmd('type summary add --summary-string "${var[].integer}" "i_am_cool[]')
         
         self.expect("frame variable cool_array",
             substrs = ['1,1,1,1,6'])
@@ -124,7 +123,12 @@ class AdvDataFormatterTestCase(TestBase)
 
         self.runCmd("type summary clear")
             
-        self.runCmd("type summary add --summary-string \"${var[0-1]}\" -x \"int \[[0-9]\]\"")
+        self.runCmd('type summary add --summary-string \"${var[0-1]}\" -x \"int \[[0-9]\]\"')
+
+        self.expect("frame variable int_array",
+            substrs = ['1,2'])
+
+        self.runCmd('type summary add --summary-string \"${var[0-1]}\" "int []"')
 
         self.expect("frame variable int_array",
             substrs = ['1,2'])
@@ -286,7 +290,7 @@ class AdvDataFormatterTestCase(TestBase)
                                'i_2',
                                'k_2',
                                'o_2'])
-        self.expect('frame variable a_long_guy -A', matching=False,
+        self.expect('frame variable a_long_guy --show-all-children', matching=False,
                     substrs = ['...'])
 
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class CategoriesDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class CategoriesDataFormatterTestCase(Te
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class CppDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class CppDataFormatterTestCase(TestBase)
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class DataFormatterDisablingTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class DataFormatterDisablingTestCase(Tes
         """Check that we can properly disable all data formatter categories."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -83,7 +81,7 @@ class DataFormatterDisablingTestCase(Tes
         self.expect('type category list', substrs = ['system is not enabled', 'gnu-libstdc++ is not enabled', 'AppKit is not enabled'])
         
         # now enable and check that we are back to normal
-        cleanup()
+        self.runCmd("type category enable *")
 
         self.expect('type category list', substrs = ['system is enabled', 'gnu-libstdc++ is enabled', 'AppKit is enabled'])
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class GlobalsDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class GlobalsDataFormatterTestCase(TestB
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         # This is the function to remove the custom formats in order to have a
         # clean slate for the next test case.

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class NamedSummariesDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class NamedSummariesDataFormatterTestCas
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -96,9 +94,10 @@ class NamedSummariesDataFormatterTestCas
             substrs = ['Second: x=65',
                         'y=0x'])
                     
-        self.expect("frame variable second --summary NoSuchSummary",
-            substrs = ['Second: x=65',
-                        'y=0x'])
+        # <rdar://problem/11576143> decided that invalid summaries will raise an error
+        # instead of just defaulting to the base summary
+        self.expect("frame variable second --summary NoSuchSummary",error=True,
+            substrs = ['must specify a valid named summary'])
                     
         self.runCmd("thread step-over")
                     

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py Thu Jun  6 19:06:43 2013
@@ -8,6 +8,7 @@ import unittest2
 import lldb
 from lldbtest import *
 import datetime
+import lldbutil
 
 class ObjCDataFormatterTestCase(TestBase):
 
@@ -27,19 +28,140 @@ class ObjCDataFormatterTestCase(TestBase
         self.buildDwarf()
         self.plain_data_formatter_commands()
 
+    def appkit_tester_impl(self,builder,commands):
+        builder()
+        self.appkit_common_data_formatters_command()
+        commands()
+
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dsym_test
-    def test_appkit_with_dsym_and_run_command(self):
-        """Test formatters for AppKit classes."""
-        self.buildDsym()
-        self.appkit_data_formatter_commands()
+    def test_nsnumber_with_dsym_and_run_command(self):
+        """Test formatters for NSNumber."""
+        self.appkit_tester_impl(self.buildDsym,self.nsnumber_data_formatter_commands)
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dwarf_test
-    def test_appkit_with_dwarf_and_run_command(self):
-        """Test formatters for AppKit classes."""
-        self.buildDwarf()
-        self.appkit_data_formatter_commands()
+    def test_nsnumber_with_dwarf_and_run_command(self):
+        """Test formatters for NSNumber."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsnumber_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsstring_with_dsym_and_run_command(self):
+        """Test formatters for NSString."""
+        self.appkit_tester_impl(self.buildDsym,self.nsstring_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsstring_with_dwarf_and_run_command(self):
+        """Test formatters for NSString."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsstring_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nscontainers_with_dsym_and_run_command(self):
+        """Test formatters for NS container classes."""
+        self.appkit_tester_impl(self.buildDsym,self.nscontainers_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nscontainers_with_dwarf_and_run_command(self):
+        """Test formatters for  NS container classes."""
+        self.appkit_tester_impl(self.buildDwarf,self.nscontainers_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsdata_with_dsym_and_run_command(self):
+        """Test formatters for NSData."""
+        self.appkit_tester_impl(self.buildDsym,self.nsdata_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsdata_with_dwarf_and_run_command(self):
+        """Test formatters for  NSData."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsdata_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsurl_with_dsym_and_run_command(self):
+        """Test formatters for NSURL."""
+        self.appkit_tester_impl(self.buildDsym,self.nsurl_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsurl_with_dwarf_and_run_command(self):
+        """Test formatters for NSURL."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsurl_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nserror_with_dsym_and_run_command(self):
+        """Test formatters for NSError."""
+        self.appkit_tester_impl(self.buildDsym,self.nserror_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nserror_with_dwarf_and_run_command(self):
+        """Test formatters for NSError."""
+        self.appkit_tester_impl(self.buildDwarf,self.nserror_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsbundle_with_dsym_and_run_command(self):
+        """Test formatters for NSBundle."""
+        self.appkit_tester_impl(self.buildDsym,self.nsbundle_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsbundle_with_dwarf_and_run_command(self):
+        """Test formatters for NSBundle."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsbundle_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsexception_with_dsym_and_run_command(self):
+        """Test formatters for NSException."""
+        self.appkit_tester_impl(self.buildDsym,self.nsexception_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsexception_with_dwarf_and_run_command(self):
+        """Test formatters for NSException."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsexception_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsmisc_with_dsym_and_run_command(self):
+        """Test formatters for misc NS classes."""
+        self.appkit_tester_impl(self.buildDsym,self.nsmisc_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsmisc_with_dwarf_and_run_command(self):
+        """Test formatters for misc NS classes."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsmisc_data_formatter_commands)
+
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_nsdate_with_dsym_and_run_command(self):
+        """Test formatters for NSDate."""
+        self.appkit_tester_impl(self.buildDsym,self.nsdate_data_formatter_commands)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_nsdate_with_dwarf_and_run_command(self):
+        """Test formatters for NSDate."""
+        self.appkit_tester_impl(self.buildDwarf,self.nsdate_data_formatter_commands)
+
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dsym_test
@@ -84,7 +206,6 @@ class ObjCDataFormatterTestCase(TestBase
         self.rdar11106605_commands()
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
-    @expectedFailurei386
     @dsym_test
     def test_expr_with_dsym_and_run_command(self):
         """Test common cases of expression parser <--> formatters interaction."""
@@ -92,7 +213,6 @@ class ObjCDataFormatterTestCase(TestBase
         self.expr_objc_data_formatter_commands()
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
-    @expectedFailurei386
     @dwarf_test
     def test_expr_with_dwarf_and_run_command(self):
         """Test common cases of expression parser <--> formatters interaction."""
@@ -109,10 +229,7 @@ class ObjCDataFormatterTestCase(TestBase
         """Check that Unicode characters come out of CFString summary correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -143,10 +260,7 @@ class ObjCDataFormatterTestCase(TestBase
         """Test basic ObjC formatting behavior."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -196,14 +310,22 @@ class ObjCDataFormatterTestCase(TestBase
         self.expect("frame variable *object",
                     substrs = ['a test']);
 
-    def appkit_data_formatter_commands(self):
+        self.expect('frame variable myclass',
+                    substrs = ['(Class) myclass = NSValue'])
+        self.expect('frame variable myclass2',
+                    substrs = ['(Class) myclass2 = __NSCFConstantString'])
+        self.expect('frame variable myclass3',
+                    substrs = ['(Class) myclass3 = Molecule'])
+        self.expect('frame variable myclass4',
+                    substrs = ['(Class) myclass4 = NSMutableArray'])
+        self.expect('frame variable myclass5',
+                    substrs = ['(Class) myclass5 = nil'])
+
+    def appkit_common_data_formatters_command(self):
         """Test formatters for AppKit classes."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -221,7 +343,8 @@ class ObjCDataFormatterTestCase(TestBase
 
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
-
+    
+    def nsnumber_data_formatter_commands(self):
         # Now enable AppKit and check we are displaying Cocoa classes correctly
         self.expect('frame variable num1 num2 num3 num4 num5 num6 num7 num8_Y num8_N num9',
                     substrs = ['(NSNumber *) num1 = ',' (int)5',
@@ -235,13 +358,16 @@ class ObjCDataFormatterTestCase(TestBase
                     '(NSNumber *) num8_N = ',' @"0"',
                     '(NSNumber *) num9 = ',' (short)-31616'])
 
+        self.expect('frame variable decimal_one',
+                    substrs = ['(NSDecimalNumber *) decimal_one = 0x','1'])
+
         self.expect('frame variable num_at1 num_at2 num_at3 num_at4',
                     substrs = ['(NSNumber *) num_at1 = ',' (int)12',
                     '(NSNumber *) num_at2 = ',' (int)-12',
                     '(NSNumber *) num_at3 = ',' (double)12.5',
                     '(NSNumber *) num_at4 = ',' (double)-12.5'])
 
-        
+    def nsstring_data_formatter_commands(self):
         self.expect('frame variable str0 str1 str2 str3 str4 str5 str6 str8 str9 str10 str11 label1 label2 processName str12',
                     substrs = ['(NSString *) str1 = ',' @"A rather short ASCII NSString object is here"',
                     '(NSString *) str0 = ',' @"255"',
@@ -258,7 +384,16 @@ class ObjCDataFormatterTestCase(TestBase
                     '(NSString *) label1 = ',' @"Process Name: "',
                     '(NSString *) label2 = ',' @"Process Id: "',
                     '(NSString *) str12 = ',' @"Process Name:  a.out Process Id:'])
+        self.expect('frame variable attrString mutableAttrString mutableGetConst',
+                    substrs = ['(NSAttributedString *) attrString = ',' @"hello world from foo"',
+                    '(NSAttributedString *) mutableAttrString = ',' @"hello world from foo"',
+                    '(NSString *) mutableGetConst = ',' @"foo said this string needs to be very long so much longer than whatever other string has been seen ever before by anyone of the mankind that of course this is still not long enough given what foo our friend foo our lovely dearly friend foo desired of us so i am adding more stuff here for the sake of it and for the joy of our friend who is named guess what just foo. hence, dear friend foo, stay safe, your string is now  long enough to accommodate your testing need and I will make sure that if not we extend it with even more fuzzy random meaningless words pasted one after the other from a long tiresome friday evening spent working in my office. my office mate went home but I am still randomly typing just for the fun of seeing what happens of the length of a Mutable String in Cocoa if it goes beyond one byte.. so be it, dear foo"'])
+
+        self.expect('expr -d run-target -- path',substrs = ['usr/blah/stuff'])
+        self.expect('frame variable path',substrs = ['usr/blah/stuff'])
 
+
+    def nscontainers_data_formatter_commands(self):
         self.expect('frame variable newArray newDictionary newMutableDictionary cfdict_ref mutable_dict_ref cfarray_ref mutable_array_ref',
                     substrs = ['(NSArray *) newArray = ','@"50 objects"',
                     '(NSDictionary *) newDictionary = ',' 12 key/value pairs',
@@ -268,14 +403,18 @@ class ObjCDataFormatterTestCase(TestBase
                     '(CFArrayRef) cfarray_ref = ','@"3 objects"',
                     '(CFMutableArrayRef) mutable_array_ref = ','@"11 objects"'])
 
-        self.expect('frame variable attrString mutableAttrString mutableGetConst',
-                    substrs = ['(NSAttributedString *) attrString = ',' @"hello world from foo"',
-                    '(NSAttributedString *) mutableAttrString = ',' @"hello world from foo"',
-                    '(NSString *) mutableGetConst = ',' @"foo said this string needs to be very long so much longer than whatever other string has been seen ever before by anyone of the mankind that of course this is still not long enough given what foo our friend foo our lovely dearly friend foo desired of us so i am adding more stuff here for the sake of it and for the joy of our friend who is named guess what just foo. hence, dear friend foo, stay safe, your string is now  long enough to accommodate your testing need and I will make sure that if not we extend it with even more fuzzy random meaningless words pasted one after the other from a long tiresome friday evening spent working in my office. my office mate went home but I am still randomly typing just for the fun of seeing what happens of the length of a Mutable String in Cocoa if it goes beyond one byte.. so be it, dear foo"'])
+        self.expect('frame variable nscounted_set',
+                    substrs = ['(NSCountedSet *) nscounted_set = ','5 objects'])
 
-        self.expect('frame variable -d run-target path',substrs = ['usr/blah/stuff'])
-        self.expect('frame variable path',substrs = ['usr/blah/stuff'])
+        self.expect('frame variable iset1 iset2 imset',
+                    substrs = ['4 indexes','512 indexes','10 indexes'])
+
+        self.expect('frame variable mutable_bag_ref cfbag_ref binheap_ref',
+                    substrs = ['(CFMutableBagRef) mutable_bag_ref = ','@"17 values"',
+                    '(CFBagRef) cfbag_ref = ','@"15 values"',
+                    '(CFBinaryHeapRef) binheap_ref = ','@"21 items"'])
 
+    def nsdata_data_formatter_commands(self):
         self.expect('frame variable immutableData mutableData data_ref mutable_data_ref mutable_string_ref',
                     substrs = ['(NSData *) immutableData = ',' 4 bytes',
                     '(NSData *) mutableData = ',' 14 bytes',
@@ -283,11 +422,7 @@ class ObjCDataFormatterTestCase(TestBase
                     '(CFMutableDataRef) mutable_data_ref = ','@"5 bytes"',
                     '(CFMutableStringRef) mutable_string_ref = ',' @"Wish ya knew"'])
 
-        self.expect('frame variable mutable_bag_ref cfbag_ref binheap_ref',
-                    substrs = ['(CFMutableBagRef) mutable_bag_ref = ','@"17 values"',
-                    '(CFBagRef) cfbag_ref = ','@"15 values"',
-                    '(CFBinaryHeapRef) binheap_ref = ','@"21 items"'])
-
+    def nsurl_data_formatter_commands(self):
         self.expect('frame variable cfurl_ref cfchildurl_ref cfgchildurl_ref',
                     substrs = ['(CFURLRef) cfurl_ref = ','@"http://www.foo.bar',
                     'cfchildurl_ref = ','@"page.html -- http://www.foo.bar',
@@ -298,20 +433,43 @@ class ObjCDataFormatterTestCase(TestBase
                     '(NSURL *) nsurl2 =','@"page.html -- http://www.foo.bar',
                     '(NSURL *) nsurl3 = ','@"?whatever -- http://www.foo.bar/page.html"'])
 
+    def nserror_data_formatter_commands(self):
+        self.expect('frame variable nserror',
+                    substrs = ['domain: @"Foobar" - code: 12'])
+
+        self.expect('frame variable nserror->_userInfo',
+                    substrs = ['2 key/value pairs'])
+
+        self.expect('frame variable nserror->_userInfo --ptr-depth 1 -d run-target',
+                    substrs = ['@"a"','@"b"',"1","2"])
+
+    def nsbundle_data_formatter_commands(self):
         self.expect('frame variable bundle_string bundle_url main_bundle',
                     substrs = ['(NSBundle *) bundle_string = ',' @"/System/Library/Frameworks/Accelerate.framework"',
                     '(NSBundle *) bundle_url = ',' @"/System/Library/Frameworks/Cocoa.framework"',
                     '(NSBundle *) main_bundle = ','data-formatter-objc'])
 
+    def nsexception_data_formatter_commands(self):
         self.expect('frame variable except0 except1 except2 except3',
                     substrs = ['(NSException *) except0 = ','name:@"TheGuyWhoHasNoName" reason:@"cuz it\'s funny"',
                     '(NSException *) except1 = ','name:@"TheGuyWhoHasNoName~1" reason:@"cuz it\'s funny"',
                     '(NSException *) except2 = ','name:@"TheGuyWhoHasNoName`2" reason:@"cuz it\'s funny"',
                     '(NSException *) except3 = ','name:@"TheGuyWhoHasNoName/3" reason:@"cuz it\'s funny"'])
 
+    def nsmisc_data_formatter_commands(self):
+        self.expect('frame variable localhost',
+                    substrs = ['<NSHost ','> localhost ((','"127.0.0.1"'])
+
+        self.expect('frame variable my_task',
+                    substrs = ['<NS','Task: 0x'])
+
+        self.expect('frame variable range_value',
+                    substrs = ['NSRange: {4, 4}'])
+
         self.expect('frame variable port',
                     substrs = ['(NSMachPort *) port = ',' mach port: '])
 
+    def nsdate_data_formatter_commands(self):
         self.expect('frame variable date1 date2',
                     substrs = ['1985-04','2011-01'])
 
@@ -329,53 +487,25 @@ class ObjCDataFormatterTestCase(TestBase
         self.expect('frame variable date3_abs date4_abs',
                     substrs = [now_year,'1970'])
 
-        #self.runCmd('mem read `&date4_abs`')
-
-        #self.runCmd('mem read `nscounted_set`')
-
-        self.expect('frame variable nscounted_set',
-                    substrs = ['(NSCountedSet *) nscounted_set = ','5 objects'])
-
-        #self.runCmd('mem read `imset`')
-        #self.runCmd("p (int)[imset count]")
-
-        self.expect('frame variable iset1 iset2 imset',
-                    substrs = ['4 objects','512 objects','10 objects'])
-
         self.expect('frame variable cupertino home europe',
                     substrs = ['@"America/Los_Angeles"',
                     '@"Europe/Rome"',
                     '@"Europe/Paris"'])
 
-        self.expect('frame variable mut_bv',
-                    substrs = ['(CFMutableBitVectorRef) mut_bv = ', '1110 0110 1011 0000 1101 1010 1000 1111 0011 0101 1101 0001 00'])
-
         self.expect('frame variable cupertino_ns home_ns europe_ns',
                     substrs = ['@"America/Los_Angeles"',
                     '@"Europe/Rome"',
                     '@"Europe/Paris"'])
 
-        self.runCmd('type summary list')
-        self.expect('frame variable myclass',
-                    substrs = ['(Class) myclass = NSValue'])
-        self.expect('frame variable myclass2',
-                    substrs = ['(Class) myclass2 = __NSCFConstantString'])
-        self.expect('frame variable myclass3',
-                    substrs = ['(Class) myclass3 = Molecule'])
-        self.expect('frame variable myclass4',
-                    substrs = ['(Class) myclass4 = NSMutableArray'])
-        self.expect('frame variable myclass5',
-                    substrs = ['(Class) myclass5 = <error: unknown Class>'])
+        self.expect('frame variable mut_bv',
+                    substrs = ['(CFMutableBitVectorRef) mut_bv = ', '1110 0110 1011 0000 1101 1010 1000 1111 0011 0101 1101 0001 00'])
 
 
     def expr_objc_data_formatter_commands(self):
         """Test common cases of expression parser <--> formatters interaction."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -399,18 +529,18 @@ class ObjCDataFormatterTestCase(TestBase
         self.expect('expression ((id)@"Hello")', matching=False,
                     substrs = ['Hello'])
 
-        self.expect('expression -d true -- ((id)@"Hello")',
+        self.expect('expression -d run -- ((id)@"Hello")',
         substrs = ['Hello'])
 
-        self.expect('expr -d true -- label1',
+        self.expect('expr -d run -- label1',
             substrs = ['Process Name'])
 
-        self.expect('expr -d true -- @"Hello"',
+        self.expect('expr -d run -- @"Hello"',
             substrs = ['Hello'])
 
-        self.expect('expr -d true -o -- @"Hello"',
+        self.expect('expr -d run --object-description -- @"Hello"',
             substrs = ['Hello'])
-        self.expect('expr -d true -o -- @"Hello"', matching=False,
+        self.expect('expr -d run --object-description -- @"Hello"', matching=False,
             substrs = ['@"Hello" Hello'])
 
 
@@ -418,10 +548,7 @@ class ObjCDataFormatterTestCase(TestBase
         """Test formatters for Core OSX frameworks."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -475,10 +602,7 @@ class ObjCDataFormatterTestCase(TestBase
         """Test the behavior of formatters when KVO is in use."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -512,7 +636,8 @@ class ObjCDataFormatterTestCase(TestBase
         # check that NSMutableDictionary's formatter is not confused when dealing with a KVO'd dictionary
         self.expect('frame variable newMutableDictionary', substrs = ['(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs'])
 
-        self.runCmd("breakpoint set -r setAtoms")
+        lldbutil.run_break_set_by_regexp (self, 'setAtoms')
+
         self.runCmd("continue")
         self.expect("frame variable _cmd",substrs = ['setAtoms:'])
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/main.m?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/main.m (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-objc/main.m Thu Jun  6 19:06:43 2013
@@ -158,6 +158,8 @@ int main (int argc, const char * argv[])
 	    NSNumber* num_at3 = @12.5;
 	    NSNumber* num_at4 = @-12.5;
 
+		NSDecimalNumber* decimal_one = [NSDecimalNumber one];
+
 	    NSString *str0 = [num6 stringValue];
 
 	    NSString *str1 = [NSString stringWithCString:"A rather short ASCII NSString object is here" encoding:NSASCIIStringEncoding];
@@ -505,6 +507,9 @@ int main (int argc, const char * argv[])
 	    CFURLRef cfchildurl_ref = CFURLCreateWithString(NULL, CFSTR("page.html"), cfurl_ref);
 	    CFURLRef cfgchildurl_ref = CFURLCreateWithString(NULL, CFSTR("?whatever"), cfchildurl_ref);
 
+	    NSDictionary *error_userInfo = @{@"a": @1, @"b" : @2};
+	    NSError *nserror = [[NSError alloc] initWithDomain:@"Foobar" code:12 userInfo:error_userInfo];
+
 	    NSBundle* bundle_string = [[NSBundle alloc] initWithPath:@"/System/Library/Frameworks/Accelerate.framework"];
 	    NSBundle* bundle_url = [[NSBundle alloc] initWithURL:[[NSURL alloc] initWithString:@"file://localhost/System/Library/Frameworks/Cocoa.framework"]];
 
@@ -554,7 +559,7 @@ int main (int argc, const char * argv[])
 	    NSIndexSet *iset2 = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(1, 512)];
 
 	    NSMutableIndexSet *imset = [[NSMutableIndexSet alloc] init];
-	    [imset addIndex:4];
+	    [imset addIndex:1936];
 	    [imset addIndex:7];
 	    [imset addIndex:9];
 	    [imset addIndex:11];
@@ -582,12 +587,19 @@ int main (int argc, const char * argv[])
 		NSTimeZone *home_ns = [NSTimeZone timeZoneWithName:@"Europe/Rome"];
 		NSTimeZone *europe_ns = [NSTimeZone timeZoneWithAbbreviation:@"CET"];
 
+		NSHost *localhost = [NSHost hostWithAddress:@"127.0.0.1"];
+
+		NSTask *my_task = [[NSTask alloc] init];
+
 
 	CFGregorianUnits cf_greg_units = {1,3,5,12,5,7};
 	CFGregorianDate cf_greg_date = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(date1), NULL);
 	CFRange cf_range = {4,4};
 	NSPoint ns_point = {4,4};
 	NSRange ns_range = {4,4};
+	
+	NSValue *range_value = [NSValue valueWithRange:ns_range];
+	
 	NSRect ns_rect = {{1,1},{5,5}};
 	NSRect* ns_rect_ptr = &ns_rect;
 	NSRectArray ns_rect_arr = &ns_rect;
@@ -653,9 +665,7 @@ int main (int argc, const char * argv[])
 	NSArray *components = @[@"usr", @"blah", @"stuff"];
 	NSString *path = [NSString pathWithComponents: components];
 
-    // Set break point at this line.
-
-    [molecule addObserver:[My_KVO_Observer new] forKeyPath:@"atoms" options:0 context:NULL];
+    [molecule addObserver:[My_KVO_Observer new] forKeyPath:@"atoms" options:0 context:NULL];     // Set break point at this line.
     [newMutableDictionary addObserver:[My_KVO_Observer new] forKeyPath:@"weirdKeyToKVO" options:NSKeyValueObservingOptionNew context:NULL];
 
     [molecule setAtoms:nil];

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class PythonSynthDataFormatterTestCase(TestBase):
 
@@ -50,10 +51,7 @@ class PythonSynthDataFormatterTestCase(T
         """Test using Python synthetic children provider."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -128,7 +126,7 @@ class PythonSynthDataFormatterTestCase(T
                                'a = 280']);
 
         # check that expanding a pointer does the right thing
-        self.expect("frame variable -P 1 f00_ptr",
+        self.expect("frame variable --ptr-depth 1 f00_ptr",
             substrs = ['r = 45',
                        'fake_a = 218103808',
                        'a = 12'])
@@ -141,7 +139,7 @@ class PythonSynthDataFormatterTestCase(T
         self.expect('frame variable f00_1', matching=False,
             substrs = ['b = 1',
                        'j = 17'])
-        self.expect("frame variable -P 1 f00_ptr",
+        self.expect("frame variable --ptr-depth 1 f00_ptr",
                     substrs = ['r = 45',
                                'fake_a = 218103808',
                                'a = 12'])
@@ -153,7 +151,7 @@ class PythonSynthDataFormatterTestCase(T
         self.expect('frame variable f00_1',
                         substrs = ['b = 1',
                                    'j = 17'])
-        self.expect("frame variable -P 1 f00_ptr", matching=False,
+        self.expect("frame variable --ptr-depth 1 f00_ptr", matching=False,
                     substrs = ['r = 45',
                                'fake_a = 218103808',
                                'a = 12'])
@@ -178,7 +176,7 @@ class PythonSynthDataFormatterTestCase(T
         self.expect('frame variable f00_1', matching=False,
                     substrs = ['b = 1',
                                'j = 17'])
-        self.expect("frame variable -P 1 f00_ptr", 
+        self.expect("frame variable --ptr-depth 1 f00_ptr", 
                     substrs = ['r = 45',
                                'fake_a = 218103808',
                                'a = 12'])
@@ -207,14 +205,9 @@ class PythonSynthDataFormatterTestCase(T
         """Test that synthetic children persist stoppoints."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line2,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line2)
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line3,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 2: file ='main.cpp', line = %d, locations = 1" %
-                        self.line3)
+        # The second breakpoint is on a multi-line expression, so the comment can't be on the right line...
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=1, loc_exact=False)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line3, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp Thu Jun  6 19:06:43 2013
@@ -62,6 +62,5 @@ int main()
 	               256*'X' +
 	               256*256*'T'+
 	               256*256*256*'F';
-    // Set second cast break point at this line.
-    return 0;
-}
\ No newline at end of file
+    return 0;     // Set second cast break point at this line.
+}

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class ScriptDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class ScriptDataFormatterTestCase(TestBa
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile Thu Jun  6 19:06:43 2013
@@ -3,3 +3,10 @@ LEVEL = ../../../make
 CXX_SOURCES := main.cpp
 
 include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -O0
+
+ifeq (,$(findstring gcc,$(CC)))
+CXXFLAGS += -stdlib=libstdc++
+LDFLAGS += -stdlib=libstdc++
+endif

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class SkipSummaryDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,9 @@ class SkipSummaryDataFormatterTestCase(T
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        #import lldbutil
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -74,7 +74,7 @@ class SkipSummaryDataFormatterTestCase(T
                        '}'])
 
         # Skip the default (should be 1) levels of summaries
-        self.expect('frame variable -Y',
+        self.expect('frame variable --no-summary-depth',
             substrs = ['(DeepData_1) data1 = {',
                        'm_child1 = 0x',
                        '}',
@@ -86,7 +86,7 @@ class SkipSummaryDataFormatterTestCase(T
                        '}'])
 
         # Now skip 2 levels of summaries
-        self.expect('frame variable -Y2',
+        self.expect('frame variable --no-summary-depth=2',
             substrs = ['(DeepData_1) data1 = {',
                        'm_child1 = 0x',
                        '}',
@@ -99,15 +99,15 @@ class SkipSummaryDataFormatterTestCase(T
                        '}'])
 
         # Check that no "Level 3" comes out
-        self.expect('frame variable data1.m_child1 -Y2', matching=False,
+        self.expect('frame variable data1.m_child1 --no-summary-depth=2', matching=False,
             substrs = ['Level 3'])
 
         # Now expand a pointer with 2 level of skipped summaries
-        self.expect('frame variable data1.m_child1 -Y2',
+        self.expect('frame variable data1.m_child1 --no-summary-depth=2',
                     substrs = ['(DeepData_2 *) data1.m_child1 = 0x'])
 
         # Deref and expand said pointer
-        self.expect('frame variable *data1.m_child1 -Y2',
+        self.expect('frame variable *data1.m_child1 --no-summary-depth=2',
                     substrs = ['(DeepData_2) *data1.m_child1 = {',
                                'm_child2 = {',
                                'm_child1 = 0x',
@@ -115,7 +115,7 @@ class SkipSummaryDataFormatterTestCase(T
                                '}'])
 
         # Expand an expression, skipping 2 layers of summaries
-        self.expect('frame variable data1.m_child1->m_child2 -Y2',
+        self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=2',
                 substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
                            'm_child2 = {',
                            'm_child1 = Level 5',
@@ -124,7 +124,7 @@ class SkipSummaryDataFormatterTestCase(T
                            '}'])
 
         # Expand same expression, skipping only 1 layer of summaries
-        self.expect('frame variable data1.m_child1->m_child2 -Y1',
+        self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=1',
                     substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
                                'm_child1 = 0x',
                                'Level 4',
@@ -134,7 +134,7 @@ class SkipSummaryDataFormatterTestCase(T
         # Bad debugging info on SnowLeopard gcc (Apple Inc. build 5666).
         # Skip the following tests if the condition is met.
         if self.getCompiler().endswith('gcc') and not self.getCompiler().endswith('llvm-gcc'):
-           import re, lldbutil
+           import re
            gcc_version_output = system([lldbutil.which(self.getCompiler()), "-v"])[1]
            #print "my output:", gcc_version_output
            for line in gcc_version_output.split(os.linesep):
@@ -148,14 +148,14 @@ class SkipSummaryDataFormatterTestCase(T
                        self.skipTest("rdar://problem/9804600 wrong namespace for std::string in debug info")
 
         # Expand same expression, skipping 3 layers of summaries
-        self.expect('frame variable data1.m_child1->m_child2 -T -Y3',
+        self.expect('frame variable data1.m_child1->m_child2 --show-types --no-summary-depth=3',
                     substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
                                'm_some_text = "Just a test"',
                                'm_child2 = {',
                                'm_some_text = "Just a test"'])
 
         # Expand within a standard string (might depend on the implementation of the C++ stdlib you use)
-        self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 -Y2',
+        self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=2',
             substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
                        'm_some_text = {',
                        '_M_dataplus = {',
@@ -163,18 +163,18 @@ class SkipSummaryDataFormatterTestCase(T
                        '"Just a test"'])
 
         # Repeat the above, but only skip 1 level of summaries
-        self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 -Y1',
+        self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=1',
                     substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
                                'm_some_text = "Just a test"',
                                '}'])
 
-        # Change summary and expand, first without -Y then with -Y
+        # Change summary and expand, first without --no-summary-depth then with --no-summary-depth
         self.runCmd("type summary add --summary-string \"${var.m_some_text}\" DeepData_5")
         
         self.expect('fr var data2.m_child4.m_child2.m_child2',
             substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = "Just a test"'])
 
-        self.expect('fr var data2.m_child4.m_child2.m_child2 -Y',
+        self.expect('fr var data2.m_child4.m_child2.m_child2 --no-summary-depth',
                     substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = {',
                                'm_some_text = "Just a test"',
                                '}'])

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class SmartArrayDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class SmartArrayDataFormatterTestCase(Te
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -242,11 +240,11 @@ class SmartArrayDataFormatterTestCase(Te
 # using [] is required here
         self.runCmd("type summary add --summary-string \"arr = ${var%x}\" \"int [5]\"")
         
-        self.expect("frame variable intarr",
-                    substrs = ['<invalid usage of pointer value as object>'])
+        self.expect("frame variable intarr",matching=False,
+                    substrs = ['0x00000001,0x00000001,0x00000002,0x00000003,0x00000005'])
         
-        self.expect("frame variable other.intarr",
-                    substrs = ['<invalid usage of pointer value as object>'])
+        self.expect("frame variable other.intarr", matching=False,
+                    substrs = ['0x00000009,0x00000008,0x00000007,0x00000006,0x00000005'])
 
         self.runCmd("type summary add --summary-string \"arr = ${var[]%x}\" \"int [5]\"")
         

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class LibcxxListDataFormatterTestCase(TestBase):
 
@@ -18,6 +19,7 @@ class LibcxxListDataFormatterTestCase(Te
         self.buildDsym()
         self.data_formatter_commands()
 
+    @skipIfLinux # No standard locations for libc++ on Linux, so skip for now 
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
@@ -35,14 +37,8 @@ class LibcxxListDataFormatterTestCase(Te
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line2,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 2: file ='main.cpp', line = %d" %
-                        self.line2)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=-1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -63,7 +59,7 @@ class LibcxxListDataFormatterTestCase(Te
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
-        self.runCmd("frame variable numbers_list -T")
+        self.runCmd("frame variable numbers_list --show-types")
         self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e")
         self.runCmd("type format add -f hex int")
 
@@ -146,6 +142,9 @@ class LibcxxListDataFormatterTestCase(Te
                                '[2] = ', '3',
                                '[3] = ', '4'])            
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
+
         self.runCmd("type format delete int")
 
         self.runCmd("c")
@@ -156,6 +155,9 @@ class LibcxxListDataFormatterTestCase(Te
                                '[1]', 'is',
                                '[2]', 'smart'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
+
         self.expect("p text_list",
                     substrs = ['list has 3 items',
                                '\"goofy\"',

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class LibcxxMapDataFormatterTestCase(TestBase):
 
@@ -18,6 +19,7 @@ class LibcxxMapDataFormatterTestCase(Tes
         self.buildDsym()
         self.data_formatter_commands()
 
+    @skipIfLinux # No standard locations for libc++ on Linux, so skip for now 
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
@@ -27,17 +29,12 @@ class LibcxxMapDataFormatterTestCase(Tes
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)
-        # Find the line number to break at.
-        self.line = line_number('main.cpp', '// Set break point at this line.')
 
     def data_formatter_commands(self):
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -60,18 +57,16 @@ class LibcxxMapDataFormatterTestCase(Tes
 
         self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib'])
 
-        self.runCmd("frame variable ii -T")
-        
-        self.runCmd("type summary add -x \"std::__1::map<\" --summary-string \"map has ${svar%#} items\" -e") 
-        
+        self.runCmd("frame variable ii --show-types")
+                
         self.expect('frame variable ii',
-            substrs = ['map has 0 items',
+            substrs = ['size=0',
                        '{}'])
 
-        self.runCmd("n");self.runCmd("n");
+        self.runCmd("continue");
 
         self.expect('frame variable ii',
-                    substrs = ['map has 2 items',
+                    substrs = ['size=2',
                                '[0] = {',
                                'first = 0',
                                'second = 0',
@@ -79,10 +74,10 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'first = 1',
                                'second = 1'])
 
-        self.runCmd("n");self.runCmd("n");
+        self.runCmd("continue");
 
         self.expect('frame variable ii',
-                    substrs = ['map has 4 items',
+                    substrs = ['size=4',
                                '[2] = {',
                                'first = 2',
                                'second = 0',
@@ -90,12 +85,10 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'first = 3',
                                'second = 1'])
 
-        self.runCmd("n");self.runCmd("n");
-        self.runCmd("n");self.runCmd("n");
-        self.runCmd("frame select 0")
+        self.runCmd("continue");
 
         self.expect("frame variable ii",
-                    substrs = ['map has 8 items',
+                    substrs = ['size=8',
                                '[5] = {',
                                'first = 5',
                                'second = 0',
@@ -104,7 +97,7 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'second = 1'])
 
         self.expect("p ii",
-                    substrs = ['map has 8 items',
+                    substrs = ['size=8',
                                '[5] = {',
                                'first = 5',
                                'second = 0',
@@ -120,6 +113,9 @@ class LibcxxMapDataFormatterTestCase(Tes
                     substrs = ['first =',
                                'second =']);
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -128,32 +124,30 @@ class LibcxxMapDataFormatterTestCase(Tes
         #self.expect("expression ii[8]", matching=False, error=True,
         #            substrs = ['1234567'])
 
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
+        self.runCmd("continue");
         
         self.expect('frame variable ii',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
         
-        self.runCmd("frame variable si -T")
+        self.runCmd("frame variable si --show-types")
 
         self.expect('frame variable si',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
 
-        self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
+        self.runCmd("continue");
 
         self.expect('frame variable si',
-                    substrs = ['map has 1 items',
+                    substrs = ['size=1',
                                '[0] = ',
                                'first = \"zero\"',
                                'second = 0'])
 
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n")
-        self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
+        self.runCmd("continue");
 
         self.expect("frame variable si",
-                    substrs = ['map has 4 items',
+                    substrs = ['size=4',
                                '[0] = ',
                                'first = \"zero\"',
                                'second = 0',
@@ -168,7 +162,7 @@ class LibcxxMapDataFormatterTestCase(Tes
                                 'second = 3'])
 
         self.expect("p si",
-                    substrs = ['map has 4 items',
+                    substrs = ['size=4',
                                '[0] = ',
                                'first = \"zero\"',
                                'second = 0',
@@ -182,6 +176,9 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'first = \"three\"',
                                'second = 3'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
         # check access-by-index
         self.expect("frame variable si[0]",
                     substrs = ['first = ', 'one',
@@ -195,23 +192,23 @@ class LibcxxMapDataFormatterTestCase(Tes
         #self.expect("expression si[0]", matching=False, error=True,
         #            substrs = ['first = ', 'zero'])
 
-        self.runCmd("n");self.runCmd("n");
+        self.runCmd("continue");
         
         self.expect('frame variable si',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
 
-        self.runCmd("n")
-        self.runCmd("frame variable is -T")
+        self.runCmd("continue");
+        self.runCmd("frame variable is --show-types")
         
         self.expect('frame variable is',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
 
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+        self.runCmd("continue");
 
         self.expect("frame variable is",
-                    substrs = ['map has 4 items',
+                    substrs = ['size=4',
                                '[0] = ',
                                'second = \"goofy\"',
                                'first = 85',
@@ -226,7 +223,7 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'first = 3'])
         
         self.expect("p is",
-                    substrs = ['map has 4 items',
+                    substrs = ['size=4',
                                '[0] = ',
                                'second = \"goofy\"',
                                'first = 85',
@@ -240,6 +237,9 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'second = \"!!!\"',
                                'first = 3'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
         # check access-by-index
         self.expect("frame variable is[0]",
                     substrs = ['first = ',
@@ -253,24 +253,23 @@ class LibcxxMapDataFormatterTestCase(Tes
         #self.expect("expression is[0]", matching=False, error=True,
         #            substrs = ['first = ', 'goofy'])
 
-        self.runCmd("n")
+        self.runCmd("continue");
         
         self.expect('frame variable is',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
 
-        self.runCmd("n");self.runCmd("n");
-        self.runCmd("frame variable ss -T")
+        self.runCmd("continue");
+        self.runCmd("frame variable ss --show-types")
         
         self.expect('frame variable ss',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
 
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
+        self.runCmd("continue");
 
         self.expect("frame variable ss",
-                    substrs = ['map has 3 items',
+                    substrs = ['size=3',
                                '[0] = ',
                                'second = \"hello\"',
                                'first = \"ciao\"',
@@ -282,7 +281,7 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'first = \"gatto\"'])
         
         self.expect("p ss",
-                    substrs = ['map has 3 items',
+                    substrs = ['size=3',
                                '[0] = ',
                                'second = \"hello\"',
                                'first = \"ciao\"',
@@ -293,6 +292,9 @@ class LibcxxMapDataFormatterTestCase(Tes
                                'second = \"cat\"',
                                'first = \"gatto\"'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
+
         # check access-by-index
         self.expect("frame variable ss[2]",
                     substrs = ['gatto', 'cat']);
@@ -305,10 +307,10 @@ class LibcxxMapDataFormatterTestCase(Tes
         #self.expect("expression ss[3]", matching=False, error=True,
         #            substrs = ['gatto'])
 
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
+        self.runCmd("continue");
         
         self.expect('frame variable ss',
-                    substrs = ['map has 0 items',
+                    substrs = ['size=0',
                                '{}'])
 
 if __name__ == '__main__':

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp Thu Jun  6 19:06:43 2013
@@ -10,6 +10,17 @@
 #define intstr_map std::map<int, std::string> 
 #define strstr_map std::map<std::string, std::string> 
 
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+	if (arg < 0)
+		arg = 0;
+	if (!arg)
+		arg = 1;
+	g_the_foo += arg;
+	return g_the_foo;
+}
 
 int main()
 {
@@ -17,43 +28,54 @@ int main()
     
     ii[0] = 0; // Set break point at this line.
     ii[1] = 1;
+	thefoo_rw(1);  // Set break point at this line.
     ii[2] = 0;
     ii[3] = 1;
-    ii[4] = 0;
+	thefoo_rw(1);  // Set break point at this line.
+	ii[4] = 0;
     ii[5] = 1;
     ii[6] = 0;
     ii[7] = 1;
+    thefoo_rw(1);  // Set break point at this line.
     ii[85] = 1234567;
-    
+
     ii.clear();
     
     strint_map si;
-    
+    thefoo_rw(1);  // Set break point at this line.
+	
     si["zero"] = 0;
+	thefoo_rw(1);  // Set break point at this line.
     si["one"] = 1;
     si["two"] = 2;
     si["three"] = 3;
+	thefoo_rw(1);  // Set break point at this line.
     si["four"] = 4;
 
     si.clear();
-    
+    thefoo_rw(1);  // Set break point at this line.
+	
     intstr_map is;
-    
+    thefoo_rw(1);  // Set break point at this line.
     is[85] = "goofy";
     is[1] = "is";
     is[2] = "smart";
     is[3] = "!!!";
-    
+    thefoo_rw(1);  // Set break point at this line.
+	
     is.clear();
-    
+    thefoo_rw(1);  // Set break point at this line.
+	
     strstr_map ss;
-    
+    thefoo_rw(1);  // Set break point at this line.
+	
     ss["ciao"] = "hello";
     ss["casa"] = "house";
     ss["gatto"] = "cat";
+    thefoo_rw(1);  // Set break point at this line.
     ss["a Mac.."] = "..is always a Mac!";
     
     ss.clear();
-    
+    thefoo_rw(1);  // Set break point at this line.    
     return 0;
 }
\ No newline at end of file

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class LibcxxVectorDataFormatterTestCase(TestBase):
 
@@ -18,6 +19,7 @@ class LibcxxVectorDataFormatterTestCase(
         self.buildDsym()
         self.data_formatter_commands()
 
+    @skipIfLinux # No standard locations for libc++ on Linux, so skip for now 
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
@@ -35,14 +37,8 @@ class LibcxxVectorDataFormatterTestCase(
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line2,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 2: file ='main.cpp', line = %d" %
-                        self.line2)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=-1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Copied: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile (from r182522, lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile)
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile?p2=lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile&p1=lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile&r1=182522&r2=183468&rev=183468&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile Thu Jun  6 19:06:43 2013
@@ -2,7 +2,7 @@ LEVEL = ../../../../../make
 
 CXX_SOURCES := main.cpp
 
-include $(LEVEL)/Makefile.rules
+CFLAGS_EXTRAS := -O0
+USE_LIBSTDCPP := 1
 
-CXXFLAGS += -stdlib=libstdc++ -O0
-LDFLAGS += -stdlib=libstdc++
+include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile Thu Jun  6 19:06:43 2013
@@ -2,4 +2,7 @@ LEVEL = ../../../../../make
 
 CXX_SOURCES := main.cpp
 
+CFLAGS_EXTRAS := -O0
+USE_LIBSTDCPP := 1
+
 include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class StdListDataFormatterTestCase(TestBase):
 
@@ -19,25 +20,39 @@ class StdListDataFormatterTestCase(TestB
         self.data_formatter_commands()
 
     @dwarf_test
+    @expectedFailureLinux('llvm.org/pr15301', ['gcc', 'icc']) # LLDB prints incorrect sizes of STL containers
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
         self.buildDwarf()
         self.data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.data_formatter_commands_after_steps()
+
+    @dwarf_test
+    @expectedFailureLinux # llvm.org/pr15301 Multiple LLDB steps do not all complete synchronously. 
+    def test_with_dwarf_and_run_command_after_steps(self):
+        """Test data formatter commands with multiple steps."""
+        self.buildDwarf()
+        self.data_formatter_commands_after_steps()
+
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)
-        # Find the line number to break at.
+        # Find the line numbers to break at for the different tests.
         self.line = line_number('main.cpp', '// Set break point at this line.')
+        self.optional_line = line_number('main.cpp', '// Optional break point at this line.')
+        self.final_line = line_number('main.cpp', '// Set final break point at this line.')
 
     def data_formatter_commands(self):
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -58,7 +73,7 @@ class StdListDataFormatterTestCase(TestB
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
-        self.runCmd("frame variable numbers_list -T")
+        self.runCmd("frame variable numbers_list --show-types")
         #self.runCmd("type synth add std::int_list std::string_list int_list string_list -l StdListSynthProvider")
         self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e")
         self.runCmd("type format add -f hex int")
@@ -134,6 +149,9 @@ class StdListDataFormatterTestCase(TestB
         self.expect("expression numbers_list[0]", matching=False, error=True,
                     substrs = ['0x12345678'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
+
         self.runCmd("n")
             
         self.expect("frame variable numbers_list",
@@ -157,7 +175,14 @@ class StdListDataFormatterTestCase(TestB
             substrs = ['list has 0 items',
                        '{}'])
         
-        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.final_line, num_expected_locations=-1)
+
+        self.runCmd("c", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
 
         self.expect("frame variable text_list",
                     substrs = ['list has 4 items',
@@ -183,6 +208,49 @@ class StdListDataFormatterTestCase(TestB
         self.expect("expression text_list[0]", matching=False, error=True,
                     substrs = ['goofy'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
+
+    def data_formatter_commands_after_steps(self):
+        """Test that that file and class static variables display correctly after multiple step instructions."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.optional_line, num_expected_locations=-1)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        self.expect("frame variable text_list",
+            substrs = ['{}'])
+       
+        # Verify that steps in rapid succession are processed prior to inspecting text_list.
+        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+
+        self.expect("frame variable text_list",
+                    substrs = ['list has 4 items',
+                               '[0]', 'goofy',
+                               '[1]', 'is',
+                               '[2]', 'smart',
+                               '[3]', '!!!'])
+
+        self.expect("p text_list",
+                    substrs = ['list has 4 items',
+                               '\"goofy\"',
+                               '\"is\"',
+                               '\"smart\"',
+                               '\"!!!\"'])
+        
+        # check access-by-index
+        self.expect("frame variable text_list[0]",
+                    substrs = ['goofy']);
+        self.expect("frame variable text_list[3]",
+                    substrs = ['!!!']);
+        
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/main.cpp Thu Jun  6 19:06:43 2013
@@ -23,11 +23,12 @@ int main()
     numbers_list.push_back(4);
     
     string_list text_list;
-    text_list.push_back(std::string("goofy"));
+    text_list.push_back(std::string("goofy")); // Optional break point at this line.
     text_list.push_back(std::string("is"));
     text_list.push_back(std::string("smart"));
     
     text_list.push_back(std::string("!!!"));
         
-    return 0;
-}
\ No newline at end of file
+    return 0; // Set final break point at this line.
+}
+

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile Thu Jun  6 19:06:43 2013
@@ -2,4 +2,6 @@ LEVEL = ../../../../../make
 
 CXX_SOURCES := main.cpp
 
+USE_LIBSTDCPP := 1
+
 include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class StdMapDataFormatterTestCase(TestBase):
 
@@ -18,6 +19,10 @@ class StdMapDataFormatterTestCase(TestBa
         self.buildDsym()
         self.data_formatter_commands()
 
+    @expectedFailureClang # llvm.org/pr15301: LLDB prints incorrect size of
+                          # libstdc++ containers
+    @skipIfGcc # llvm.org/pr15036: When built with GCC, this test causes lldb to crash with
+               # assert DeclCXX.h:554 queried property of class with no definition
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
@@ -34,10 +39,7 @@ class StdMapDataFormatterTestCase(TestBa
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -58,7 +60,7 @@ class StdMapDataFormatterTestCase(TestBa
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
-        self.runCmd("frame variable ii -T")
+        self.runCmd("frame variable ii --show-types")
         
         self.runCmd("type summary add -x \"std::map<\" --summary-string \"map has ${svar%#} items\" -e") 
         
@@ -120,6 +122,9 @@ class StdMapDataFormatterTestCase(TestBa
         self.expect("frame variable ii[8]", matching=True,
                     substrs = ['1234567'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -135,7 +140,7 @@ class StdMapDataFormatterTestCase(TestBa
                                '{}'])
         
         self.runCmd("n")
-        self.runCmd("frame variable si -T")
+        self.runCmd("frame variable si --show-types")
 
         self.expect('frame variable si',
                     substrs = ['map has 0 items',
@@ -191,7 +196,10 @@ class StdMapDataFormatterTestCase(TestBa
         self.expect("frame variable si[0]",
                     substrs = ['first = ', 'four',
                                'second = 4']);
-        
+
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -207,7 +215,7 @@ class StdMapDataFormatterTestCase(TestBa
                                '{}'])
 
         self.runCmd("n")
-        self.runCmd("frame variable is -T")
+        self.runCmd("frame variable is --show-types")
         
         self.expect('frame variable is',
                     substrs = ['map has 0 items',
@@ -249,7 +257,10 @@ class StdMapDataFormatterTestCase(TestBa
         self.expect("frame variable is[0]",
                     substrs = ['first = ',
                                'second =']);
-        
+
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -265,7 +276,7 @@ class StdMapDataFormatterTestCase(TestBa
                                '{}'])
 
         self.runCmd("n")
-        self.runCmd("frame variable ss -T")
+        self.runCmd("frame variable ss --show-types")
         
         self.expect('frame variable ss',
                     substrs = ['map has 0 items',
@@ -306,6 +317,9 @@ class StdMapDataFormatterTestCase(TestBa
         # check access-by-index
         self.expect("frame variable ss[3]",
                     substrs = ['gatto', 'cat']);
+
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
         
         # check that the expression parser does not make use of
         # synthetic children instead of running code

Copied: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile (from r182522, lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile)
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile?p2=lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile&p1=lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile&r1=182522&r2=183468&rev=183468&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile Thu Jun  6 19:06:43 2013
@@ -2,7 +2,7 @@ LEVEL = ../../../../../make
 
 CXX_SOURCES := main.cpp
 
-include $(LEVEL)/Makefile.rules
+CFLAGS_EXTRAS := -O0
+USE_LIBSTDCPP := 1
 
-CXXFLAGS += -stdlib=libstdc++ -O0
-LDFLAGS += -stdlib=libstdc++
+include $(LEVEL)/Makefile.rules

Copied: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile (from r182522, lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile)
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile?p2=lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile&p1=lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile&r1=182522&r2=183468&rev=183468&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile Thu Jun  6 19:06:43 2013
@@ -2,10 +2,7 @@ LEVEL = ../../../../../make
 
 CXX_SOURCES := main.cpp
 
-include $(LEVEL)/Makefile.rules
+CFLAGS_EXTRAS := -O0
+USE_LIBSTDCPP := 1
 
-CXXFLAGS += -O0
-ifeq (,$(findstring gcc,$(CC)))
-CXXFLAGS += -stdlib=libstdc++
-LDFLAGS += -stdlib=libstdc++
-endif
+include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile Thu Jun  6 19:06:43 2013
@@ -2,4 +2,7 @@ LEVEL = ../../../../../make
 
 CXX_SOURCES := main.cpp
 
+CXXFLAGS := -O0
+USE_LIBSTDCPP := 1
+
 include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class StdVectorDataFormatterTestCase(TestBase):
 
@@ -19,6 +20,7 @@ class StdVectorDataFormatterTestCase(Tes
         self.data_formatter_commands()
 
     @dwarf_test
+    @expectedFailureLinux # llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
         self.buildDwarf()
@@ -34,10 +36,7 @@ class StdVectorDataFormatterTestCase(Tes
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -145,6 +144,9 @@ class StdVectorDataFormatterTestCase(Tes
         self.expect("expression numbers[6]", matching=False, error=True,
             substrs = ['1234567'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("numbers").MightHaveChildren(), "numbers.MightHaveChildren() says False for non empty!")
+
         # clear out the vector and see that we do the right thing once again
         self.runCmd("n")
 
@@ -206,6 +208,9 @@ class StdVectorDataFormatterTestCase(Tes
         self.expect("expression strings[0]", matching=False, error=True,
                     substrs = ['goofy'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("strings").MightHaveChildren(), "strings.MightHaveChildren() says False for non empty!")
+
         self.runCmd("n")
 
         self.expect("frame variable strings",

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class SynthDataFormatterTestCase(TestBase):
 
@@ -34,10 +35,7 @@ class SynthDataFormatterTestCase(TestBas
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -73,7 +71,7 @@ class SynthDataFormatterTestCase(TestBas
                                'z = 8'])
         
         # if we skip synth and summary show y
-        self.expect("frame variable int_bag -S false -Y1",
+        self.expect("frame variable int_bag --synthetic-type false --no-summary-depth=1",
                     substrs = ['x = 6',
                                'y = 7',
                                'z = 8'])
@@ -99,7 +97,7 @@ class SynthDataFormatterTestCase(TestBas
                                'z = 8'])
 
         # If I skip summaries, still give me the artificial children
-        self.expect("frame variable int_bag -Y1",
+        self.expect("frame variable int_bag --no-summary-depth=1",
                     substrs = ['x = 6',
                                'z = 8'])
 
@@ -137,14 +135,14 @@ class SynthDataFormatterTestCase(TestBas
 
         # ...even bitfields
         self.runCmd("type filter add BagOfBags --child x.y --child \"y->z[1-2]\"")
-        self.expect('frame variable bag_bag -T',
+        self.expect('frame variable bag_bag --show-types',
                     substrs = ['x.y = 70',
                                '(int:2) y->z[1-2] = 2'])
 
         # ...even if we format the bitfields
         self.runCmd("type filter add BagOfBags --child x.y --child \"y->y[0-0]\"")
         self.runCmd("type format add \"int:1\" -f bool")
-        self.expect('frame variable bag_bag -T',
+        self.expect('frame variable bag_bag --show-types',
                     substrs = ['x.y = 70',
                                '(int:1) y->y[0-0] = true'])
         
@@ -169,7 +167,7 @@ class SynthDataFormatterTestCase(TestBas
                                'array[2] = 3'])
         
         # skip synthetic children
-        self.expect('frame variable plenty_of_stuff -S no',
+        self.expect('frame variable plenty_of_stuff --synthetic-type no',
                     substrs = ['some_values = 0x0',
                                'array = 0x',
                                'array_size = 5'])
@@ -182,19 +180,19 @@ class SynthDataFormatterTestCase(TestBas
                        '*(plenty_of_stuff.array) = 3'])
         
         # check that we do not lose location information for our children
-        self.expect('frame variable plenty_of_stuff -L',
+        self.expect('frame variable plenty_of_stuff --location',
                     substrs = ['0x',
                                ':   bitfield = 17'])
 
         # check we work across pointer boundaries
-        self.expect('frame variable plenty_of_stuff.some_values -P1',
+        self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
                     substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
                                'x = 5',
                                'z = 7'])
 
         # but not if we don't want to
         self.runCmd("type filter add BagOfInts --child x --child z -p")
-        self.expect('frame variable plenty_of_stuff.some_values -P1',
+        self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
                     substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
                                'x = 5',
                                'y = 6',

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10449092/Test-rdar-10449092.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10449092/Test-rdar-10449092.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10449092/Test-rdar-10449092.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10449092/Test-rdar-10449092.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar10449092DataFormatterTestCase(TestBase):
 
@@ -35,10 +36,7 @@ class Radar10449092DataFormatterTestCase
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar10642615DataFormatterTestCase(TestBase):
 
@@ -19,6 +20,7 @@ class Radar10642615DataFormatterTestCase
         self.buildDsym()
         self.data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
@@ -35,10 +37,7 @@ class Radar10642615DataFormatterTestCase
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py Thu Jun  6 19:06:43 2013
@@ -6,13 +6,13 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Rdar10887661TestCase(TestBase):
 
     mydir = os.path.join("functionalities", "data-formatter", "rdar-10887661")
 
     # rdar://problem/10887661
-    @unittest2.expectedFailure
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dsym_test
     def test_with_dsym_and_run_command(self):
@@ -21,7 +21,6 @@ class Rdar10887661TestCase(TestBase):
         self.capping_test_commands()
 
     # rdar://problem/10887661
-    @unittest2.expectedFailure
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs."""
@@ -38,10 +37,7 @@ class Rdar10887661TestCase(TestBase):
         """Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11628688/TestFormattersBoolRefPtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11628688/TestFormattersBoolRefPtr.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11628688/TestFormattersBoolRefPtr.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11628688/TestFormattersBoolRefPtr.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import unittest2
 import lldb
 from lldbtest import *
 import datetime
+import lldbutil
 
 class DataFormatterOSTypeTestCase(TestBase):
 
@@ -36,10 +37,7 @@ class DataFormatterOSTypeTestCase(TestBa
         """Test the formatters we use for OSType."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.mm -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.mm', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11773899/TestFormattersBoolRefPtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11773899/TestFormattersBoolRefPtr.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11773899/TestFormattersBoolRefPtr.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-11773899/TestFormattersBoolRefPtr.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import unittest2
 import lldb
 from lldbtest import *
 import datetime
+import lldbutil
 
 class DataFormatterBoolRefPtr(TestBase):
 
@@ -36,10 +37,7 @@ class DataFormatterBoolRefPtr(TestBase):
         """Test the formatters we use for BOOL& and BOOL* in Objective-C."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.mm -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.mm', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-3534688/TestFormattersOneIsSingular.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-3534688/TestFormattersOneIsSingular.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-3534688/TestFormattersOneIsSingular.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-3534688/TestFormattersOneIsSingular.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import unittest2
 import lldb
 from lldbtest import *
 import datetime
+import lldbutil
 
 class DataFormatterOneIsSingularTestCase(TestBase):
 
@@ -36,10 +37,7 @@ class DataFormatterOneIsSingularTestCase
         """Test that 1 item is not as reported as 1 items."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.m -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -80,9 +78,9 @@ class DataFormatterOneIsSingularTestCase
         self.expect('frame variable nscounted_set', matching=False,
                     substrs = ['1 objects'])
         self.expect('frame variable imset',
-                    substrs = ['1 object'])
+                    substrs = ['1 index'])
         self.expect('frame variable imset', matching=False,
-                    substrs = ['1 objects'])
+                    substrs = ['1 indexes'])
         self.expect('frame variable binheap_ref',
                     substrs = ['@"1 item"'])
         self.expect('frame variable binheap_ref', matching=False,

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Makefile Thu Jun  6 19:06:43 2013
@@ -2,4 +2,10 @@ LEVEL = ../../../make
 
 CXX_SOURCES := main.cpp
 
+# Workaround for llvm.org/pr16214: clang doesn't emit structure definition DWARF
+# information without the flag below.
+ifneq (,$(findstring clang,$(CC)))
+  CFLAGS_EXTRAS := -fno-limit-debug-info
+endif
+
 include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar9973865DataFormatterTestCase(TestBase):
 
@@ -22,6 +23,7 @@ class Radar9973865DataFormatterTestCase(
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Test data formatter commands."""
+
         self.buildDwarf()
         self.data_formatter_commands()
 
@@ -35,10 +37,7 @@ class Radar9973865DataFormatterTestCase(
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar9973992DataFormatterTestCase(TestBase):
 
@@ -35,10 +36,7 @@ class Radar9973992DataFormatterTestCase(
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class Radar9974002DataFormatterTestCase(TestBase):
 
@@ -35,10 +36,7 @@ class Radar9974002DataFormatterTestCase(
         """Test that that file and class static variables display correctly."""
         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
 
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/dead-strip/TestDeadStrip.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/dead-strip/TestDeadStrip.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/dead-strip/TestDeadStrip.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/dead-strip/TestDeadStrip.py Thu Jun  6 19:06:43 2013
@@ -6,6 +6,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class DeadStripTestCase(TestBase):
 
@@ -18,6 +19,7 @@ class DeadStripTestCase(TestBase):
         self.buildDsym()
         self.dead_strip()
 
+    @skipIfLinux # The -dead_strip linker option isn't supported on Linux versions of ld.
     @dwarf_test
     def test_with_dwarf(self):
         """Test breakpoint works correctly with dead-code stripping."""
@@ -30,16 +32,13 @@ class DeadStripTestCase(TestBase):
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break by function name f1 (live code).
-        self.expect("breakpoint set -s a.out -n f1", BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: name = 'f1', module = a.out, locations = 1")
+        lldbutil.run_break_set_by_symbol (self, "f1", num_expected_locations=1, module_name="a.out")
 
         # Break by function name f2 (dead code).
-        self.expect("breakpoint set -s a.out -n f2", BREAKPOINT_PENDING_CREATED,
-            startstr = "Breakpoint created: 2: name = 'f2', module = a.out, locations = 0 (pending)")
+        lldbutil.run_break_set_by_symbol (self, "f2", num_expected_locations=0, module_name="a.out")
 
         # Break by function name f3 (live code).
-        self.expect("breakpoint set -s a.out -n f3", BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 3: name = 'f3', module = a.out, locations = 1")
+        lldbutil.run_break_set_by_symbol (self, "f3", num_expected_locations=1, module_name="a.out")
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/embedded_interpreter/TestConvenienceVariables.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/embedded_interpreter/TestConvenienceVariables.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/embedded_interpreter/TestConvenienceVariables.py Thu Jun  6 19:06:43 2013
@@ -18,6 +18,7 @@ class ConvenienceVariablesCase(TestBase)
         self.convenience_variables()
 
     @dwarf_test
+    @skipIfLinux # llvm.org/pr14637: this test case fails sometimes because the input prompt "(lldb)" is missing
     def test_with_dwarf_and_run_commands(self):
         """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame."""
         self.buildDwarf()

Modified: lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/Makefile Thu Jun  6 19:06:43 2013
@@ -1,5 +1,6 @@
 LEVEL = ../../make
 
+CFLAGS_EXTRAS := -lpthread
 C_SOURCES := locking.c
 
 include $(LEVEL)/Makefile.rules

Modified: lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py Thu Jun  6 19:06:43 2013
@@ -10,6 +10,9 @@ from lldbtest import *
 
 class ExprDoesntDeadlockTestCase(TestBase):
 
+    def getCategories(self):
+        return ['basic_process']
+
     mydir = os.path.join("functionalities", "expr-doesnt-deadlock")
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@@ -20,6 +23,7 @@ class ExprDoesntDeadlockTestCase(TestBas
         self.expr_doesnt_deadlock()
 
     @dwarf_test
+    @skipIfLinux # llvm.org/pr15258: disabled due to assertion failure in ProcessMonitor::GetCrashReasonForSIGSEGV:
     def test_with_dwarf_and_run_command(self):
         """Test that expr will time out and allow other threads to run if it blocks."""
         self.buildDwarf()
@@ -54,14 +58,14 @@ class ExprDoesntDeadlockTestCase(TestBas
         # Frame #0 should be on self.line1 and the break condition should hold.
         from lldbutil import get_stopped_thread
         thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
-        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
+        self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
 
         frame0 = thread.GetFrameAtIndex(0)
 
         var = frame0.EvaluateExpression ("call_me_to_get_lock()")
         self.assertTrue (var.IsValid())
         self.assertTrue (var.GetValueAsSigned (0) == 567)
-        
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()

Modified: lldb/branches/lldb-platform-work/test/functionalities/inferior-changed/TestInferiorChanged.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/inferior-changed/TestInferiorChanged.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/inferior-changed/TestInferiorChanged.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/inferior-changed/TestInferiorChanged.py Thu Jun  6 19:06:43 2013
@@ -4,6 +4,7 @@ import os, time
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class ChangedInferiorTestCase(TestBase):
 
@@ -25,6 +26,10 @@ class ChangedInferiorTestCase(TestBase):
         self.buildDwarf()
         self.inferior_crashing()
         self.cleanup()
+        # lldb needs to recognize the inferior has changed. If lldb needs to check the
+        # new module timestamp, make sure it is not the same as the old one, so add a
+        # 1 second delay.
+        time.sleep(1)
         d = {'C_SOURCES': 'main2.c'}
         self.buildDwarf(dictionary=d)
         self.setTearDownCleanup(dictionary=d)
@@ -44,14 +49,19 @@ class ChangedInferiorTestCase(TestBase):
 
         self.runCmd("run", RUN_SUCCEEDED)
 
+        if sys.platform.startswith("darwin"):
+            stop_reason = 'stop reason = EXC_BAD_ACCESS'
+        else:
+            stop_reason = 'stop reason = invalid address'
+
         # The stop reason of the thread should be a bad access exception.
         self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
             substrs = ['stopped',
-                       'stop reason = EXC_BAD_ACCESS'])
+                       stop_reason])
 
         # And it should report the correct line number.
         self.expect("thread backtrace all",
-            substrs = ['stop reason = EXC_BAD_ACCESS',
+            substrs = [stop_reason,
                        'main.c:%d' % self.line1])
 
     def inferior_not_crashing(self):
@@ -63,14 +73,16 @@ class ChangedInferiorTestCase(TestBase):
         self.runCmd("run", RUN_SUCCEEDED)
         self.runCmd("process status")
 
-        if 'EXC_BAD_ACCESS' in self.res.GetOutput():
+        if sys.platform.startswith("darwin"):
+            stop_reason = 'EXC_BAD_ACCESS'
+        else:
+            stop_reason = 'invalid address'
+
+        if stop_reason in self.res.GetOutput():
             self.fail("Inferior changed, but lldb did not perform a reload")
 
         # Break inside the main.
-        self.expect("breakpoint set -f main2.c -l %d" % self.line2,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main2.c', line = %d, locations = 1" %
-                        self.line2)
+        lldbutil.run_break_set_by_file_and_line (self, "main2.c", self.line2, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/TestInferiorCrashing.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/TestInferiorCrashing.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/TestInferiorCrashing.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/TestInferiorCrashing.py Thu Jun  6 19:06:43 2013
@@ -1,8 +1,8 @@
-"""Test that lldb reliably catches the inferior crashing."""
+"""Test that lldb functions correctly after the inferior has crashed."""
 
 import os, time
 import unittest2
-import lldb
+import lldb, lldbutil
 from lldbtest import *
 
 class CrashingInferiorTestCase(TestBase):
@@ -20,12 +20,85 @@ class CrashingInferiorTestCase(TestBase)
         self.buildDwarf()
         self.inferior_crashing()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_inferior_crashing_registers_dsym(self):
+        """Test that lldb reliably reads registers from the inferior after crashing (command)."""
+        self.buildDsym()
+        self.inferior_crashing_registers()
+
+    def test_inferior_crashing_register_dwarf(self):
+        """Test that lldb reliably reads registers from the inferior after crashing (command)."""
+        self.buildDwarf()
+        self.inferior_crashing_registers()
+
     @python_api_test
     def test_inferior_crashing_python(self):
         """Test that lldb reliably catches the inferior crashing (Python API)."""
         self.buildDefault()
         self.inferior_crashing_python()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_inferior_crashing_expr_dsym(self):
+        """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
+        self.buildDsym()
+        self.inferior_crashing_expr()
+
+    def test_inferior_crashing_expr_dwarf(self):
+        """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
+        self.buildDwarf()
+        self.inferior_crashing_expr()
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_inferior_crashing_step_dsym(self):
+        """Test that lldb functions correctly after stepping through a crash."""
+        self.buildDsym()
+        self.inferior_crashing_step()
+
+    def test_inferior_crashing_step_dwarf(self):
+        """Test that stepping after a crash behaves correctly."""
+        self.buildDwarf()
+        self.inferior_crashing_step()
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_inferior_crashing_step_after_break_dsym(self):
+        """Test that stepping after a crash behaves correctly."""
+        self.buildDsym()
+        self.inferior_crashing_step_after_break()
+
+    @expectedFailureLinux # due to llvm.org/pr15988 -- step over misbehaves after crash
+    def test_inferior_crashing_step_after_break_dwarf(self):
+        """Test that lldb functions correctly after stepping through a crash."""
+        self.buildDwarf()
+        self.inferior_crashing_step_after_break()
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_inferior_crashing_expr_step_and_expr_dsym(self):
+        """Test that lldb expressions work before and after stepping after a crash."""
+        self.buildDsym()
+        self.inferior_crashing_expr_step_expr()
+
+    @expectedFailureLinux # due to llvm.org/pr15989 -- expression fails after crash and step
+    def test_inferior_crashing_expr_step_and_expr_dwarf(self):
+        """Test that lldb expressions work before and after stepping after a crash."""
+        self.buildDwarf()
+        self.inferior_crashing_expr_step_expr()
+
+    def set_breakpoint(self, line):
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
+
+    def check_stop_reason(self):
+        if sys.platform.startswith("darwin"):
+            stop_reason = 'stop reason = EXC_BAD_ACCESS'
+        else:
+            stop_reason = 'stop reason = invalid address'
+
+        # The stop reason of the thread should be a bad access exception.
+        self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
+            substrs = ['stopped',
+                       stop_reason])
+
+        return stop_reason
+
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)
@@ -38,15 +111,11 @@ class CrashingInferiorTestCase(TestBase)
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         self.runCmd("run", RUN_SUCCEEDED)
-
-        # The stop reason of the thread should be a bad access exception.
-        self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
-            substrs = ['stopped',
-                       'stop reason = EXC_BAD_ACCESS'])
+        stop_reason = self.check_stop_reason()
 
         # And it should report the correct line number.
         self.expect("thread backtrace all",
-            substrs = ['stop reason = EXC_BAD_ACCESS',
+            substrs = [stop_reason,
                        'main.c:%d' % self.line])
 
     def inferior_crashing_python(self):
@@ -60,7 +129,6 @@ class CrashingInferiorTestCase(TestBase)
         # Both argv and envp are null.
         process = target.LaunchSimple(None, None, os.getcwd())
 
-        import lldbutil
         if process.GetState() != lldb.eStateStopped:
             self.fail("Process should be in the 'stopped' state, "
                       "instead the actual state is: '%s'" %
@@ -73,6 +141,94 @@ class CrashingInferiorTestCase(TestBase)
         if self.TraceOn():
             lldbutil.print_stacktrace(thread)
 
+    def inferior_crashing_registers(self):
+        """Test that lldb can read registers after crashing."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+        self.check_stop_reason()
+
+        # lldb should be able to read from registers from the inferior after crashing.
+        self.expect("register read eax",
+            substrs = ['eax = 0x'])
+
+    def inferior_crashing_expr(self):
+        """Test that the lldb expression interpreter can read symbols after crashing."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+        self.check_stop_reason()
+
+        # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+        self.expect("p argc",
+            startstr = '(int) $0 = 1')
+
+        self.expect("p hello_world",
+            substrs = ['Hello'])
+
+    def inferior_crashing_step(self):
+        """Test that lldb functions correctly after stepping through a crash."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        self.set_breakpoint(self.line)
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['main.c:%d' % self.line,
+                       'stop reason = breakpoint'])
+
+        self.runCmd("next")
+        stop_reason = self.check_stop_reason()
+
+        # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+        self.expect("p argv[0]",
+            substrs = ['a.out'])
+        self.expect("p null_ptr",
+            substrs = ['= 0x0'])
+
+        # lldb should be able to read from registers from the inferior after crashing.
+        self.expect("register read eax",
+            substrs = ['eax = 0x'])
+
+        # And it should report the correct line number.
+        self.expect("thread backtrace all",
+            substrs = [stop_reason,
+                       'main.c:%d' % self.line])
+
+    def inferior_crashing_step_after_break(self):
+        """Test that lldb behaves correctly when stepping after a crash."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+        self.check_stop_reason()
+
+        self.runCmd("next")
+        self.check_stop_reason()
+
+    def inferior_crashing_expr_step_expr(self):
+        """Test that lldb expressions work before and after stepping after a crash."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+        self.check_stop_reason()
+
+        # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+        self.expect("p argv[0]",
+            substrs = ['a.out'])
+
+        self.runCmd("next")
+        self.check_stop_reason()
+
+        # The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
+        self.expect("p argv[0]",
+            substrs = ['a.out'])
+
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()

Modified: lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/main.c?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/main.c (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/inferior-crashing/main.c Thu Jun  6 19:06:43 2013
@@ -8,9 +8,11 @@
 //===----------------------------------------------------------------------===//
 #include <stdio.h>
 
+const char *hello_world = "Hello, segfault!";
+
 int main(int argc, const char* argv[])
 {
     int *null_ptr = 0;
-    printf("Hello, segfault!\n");
+    printf("%s\n", hello_world);
     printf("Now crash %d\n", *null_ptr); // Crash here.
 }

Modified: lldb/branches/lldb-platform-work/test/functionalities/load_unload/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/load_unload/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/load_unload/Makefile (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/load_unload/Makefile Thu Jun  6 19:06:43 2013
@@ -4,7 +4,7 @@ CC ?= clang
 ifeq "$(ARCH)" ""
 	ARCH = x86_64
 endif
-CFLAGS ?=-arch $(ARCH) -gdwarf-2 -O0
+CFLAGS ?=-arch $(ARCH) -g -O0
 CWD := $(shell pwd)
 
 all: a.out hidden/libd.dylib

Modified: lldb/branches/lldb-platform-work/test/functionalities/load_unload/TestLoadUnload.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/load_unload/TestLoadUnload.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/load_unload/TestLoadUnload.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/load_unload/TestLoadUnload.py Thu Jun  6 19:06:43 2013
@@ -7,9 +7,13 @@ import re
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class LoadUnloadTestCase(TestBase):
 
+    def getCategories (self):
+        return ['basic_process']
+
     mydir = os.path.join("functionalities", "load_unload")
 
     def setUp(self):
@@ -22,6 +26,7 @@ class LoadUnloadTestCase(TestBase):
                                            '// Find this line number within d_dunction().')
 
     @not_remote_testsuite_ready
+    @skipIfLinux # llvm.org/pr14424 - missing linux Makefiles/testcase support
     def test_modules_search_paths(self):
         """Test target modules list after loading a different copy of the library libd.dylib, and verifies that it works with 'target modules search-paths add'."""
 
@@ -30,7 +35,6 @@ class LoadUnloadTestCase(TestBase):
 
         if sys.platform.startswith("darwin"):
             dylibName = 'libd.dylib'
-            dylibPath = 'DYLD_LIBRARY_PATH'
 
         # The directory with the dynamic library we did not link to.
         new_dir = os.path.join(os.getcwd(), "hidden")
@@ -61,13 +65,13 @@ class LoadUnloadTestCase(TestBase):
         # Obliterate traces of libd from the old location.
         os.remove(old_dylib)
         # Inform dyld of the new path, too.
-        env_cmd_string = "settings set target.env-vars " + dylibPath + "=" + new_dir
+        env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + new_dir
         if self.TraceOn():
             print "Set environment to: ", env_cmd_string
         self.runCmd(env_cmd_string)
         self.runCmd("settings show target.env-vars")
 
-        remove_dyld_path_cmd = "settings remove target.env-vars " + dylibPath
+        remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
         self.addTearDownHook(lambda: self.runCmd(remove_dyld_path_cmd))
 
         self.runCmd("run")
@@ -75,7 +79,7 @@ class LoadUnloadTestCase(TestBase):
         self.expect("target modules list", "LLDB successfully locates the relocated dynamic library",
             substrs = [new_dylib])
 
-        
+    @skipIfLinux # llvm.org/pr14424 - missing linux Makefiles/testcase support
     @not_remote_testsuite_ready
     def test_dyld_library_path(self):
         """Test DYLD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
@@ -89,7 +93,6 @@ class LoadUnloadTestCase(TestBase):
         if sys.platform.startswith("darwin"):
             dylibName = 'libd.dylib'
             dsymName = 'libd.dylib.dSYM'
-            dylibPath = 'DYLD_LIBRARY_PATH'
 
         # The directory to relocate the dynamic library and its debugging info.
         special_dir = "hidden"
@@ -105,19 +108,17 @@ class LoadUnloadTestCase(TestBase):
         # Try running with the DYLD_LIBRARY_PATH environment variable set, make sure
         # we pick up the hidden dylib.
 
-        env_cmd_string = "settings set target.env-vars " + dylibPath + "=" + new_dir
+        env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + new_dir
         if self.TraceOn():
             print "Set environment to: ", env_cmd_string
         self.runCmd(env_cmd_string)
         self.runCmd("settings show target.env-vars")
 
-        remove_dyld_path_cmd = "settings remove target.env-vars " + dylibPath
+        remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
         self.addTearDownHook(lambda: self.runCmd(remove_dyld_path_cmd))
 
-        self.expect("breakpoint set -f d.c -l %d" % self.line_d_function,
-                    BREAKPOINT_CREATED,
-                    startstr = "Breakpoint created: 1: file ='d.c', line = %d" %
-                        self.line_d_function)
+        lldbutil.run_break_set_by_file_and_line (self, "d.c", self.line_d_function, num_expected_locations=1, loc_exact=True)
+
         # For now we don't track DYLD_LIBRARY_PATH, so the old library will be in
         # the modules list.
         self.expect("target modules list",
@@ -134,6 +135,7 @@ class LoadUnloadTestCase(TestBase):
             substrs = [special_dir, os.path.basename(new_dylib)])
 
     @not_remote_testsuite_ready
+    @skipIfLinux # llvm.org/pr14424 - missing linux Makefiles/testcase support
     def test_lldb_process_load_and_unload_commands(self):
         """Test that lldb process load/unload command work correctly."""
 
@@ -146,10 +148,7 @@ class LoadUnloadTestCase(TestBase):
         # Break at main.c before the call to dlopen().
         # Use lldb's process load command to load the dylib, instead.
 
-        self.expect("breakpoint set -f main.c -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.c', line = %d" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -184,6 +183,7 @@ class LoadUnloadTestCase(TestBase):
         self.runCmd("process continue")
 
     @not_remote_testsuite_ready
+    @skipIfLinux # llvm.org/pr14424 - missing linux Makefiles/testcase support
     def test_load_unload(self):
         """Test breakpoint by name works correctly with dlopen'ing."""
 
@@ -194,8 +194,7 @@ class LoadUnloadTestCase(TestBase):
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break by function name a_function (not yet loaded).
-        self.expect("breakpoint set -n a_function", BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: name = 'a_function', locations = 0 (pending)")
+        lldbutil.run_break_set_by_symbol (self, "a_function", num_expected_locations=0)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -225,6 +224,7 @@ class LoadUnloadTestCase(TestBase):
             substrs = [' resolved, hit count = 2'])
 
     @not_remote_testsuite_ready
+    @skipIfLinux # llvm.org/pr14424 - missing linux Makefiles/testcase support
     def test_step_over_load (self):
         """Test stepping over code that loads a shared library works correctly."""
 
@@ -235,9 +235,7 @@ class LoadUnloadTestCase(TestBase):
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break by function name a_function (not yet loaded).
-        self.expect("breakpoint set -f main.c -l %d"%(self.line), BREAKPOINT_CREATED,
-            substrs = ['Breakpoint created:',
-                      "file ='main.c', line = %d, locations = 1"%(self.line)])
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/memory/read/TestMemoryRead.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/memory/read/TestMemoryRead.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/memory/read/TestMemoryRead.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/memory/read/TestMemoryRead.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import re
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class MemoryReadTestCase(TestBase):
 
@@ -37,10 +38,7 @@ class MemoryReadTestCase(TestBase):
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break in main() aftre the variables are assigned values.
-        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/non-overlapping-index-variable-i/TestIndexVariable.py Thu Jun  6 19:06:43 2013
@@ -4,6 +4,7 @@ from out of scope to in scope when stopp
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class NonOverlappingIndexVariableCase(TestBase):
 
@@ -26,10 +27,7 @@ class NonOverlappingIndexVariableCase(Te
         exe = os.path.join(os.getcwd(), exe_name)
         self.runCmd("file %s" % exe, CURRENT_EXECUTABLE_SET)
 
-        self.expect('breakpoint set -f %s -l %d' % (self.source, self.line_to_break),
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
-                        (self.source, self.line_to_break))
+        lldbutil.run_break_set_by_file_and_line (self, self.source, self.line_to_break, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/process_launch/TestProcessLaunch.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/process_launch/TestProcessLaunch.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/process_launch/TestProcessLaunch.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/process_launch/TestProcessLaunch.py Thu Jun  6 19:06:43 2013
@@ -11,6 +11,13 @@ class ProcessLaunchTestCase(TestBase):
 
     mydir = os.path.join("functionalities", "process_launch")
 
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # disable "There is a running process, kill it and restart?" prompt
+        self.runCmd("settings set auto-confirm true")
+        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dsym_test
     def test_io_with_dsym (self):
@@ -147,7 +154,7 @@ class ProcessLaunchTestCase(TestBase):
                                                                err_file_path)
 
         self.expect(launch_command, error=True,
-                startstr = "error: No such file or directory: %sz" % my_working_dir_path)
+                patterns = ["error:.* No such file or directory: %sz" % my_working_dir_path])
 
         # Really launch the process
         launch_command = "process launch -w %s -o %s -e %s" % (my_working_dir_path,

Modified: lldb/branches/lldb-platform-work/test/functionalities/register/TestRegisters.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/register/TestRegisters.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/register/TestRegisters.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/register/TestRegisters.py Thu Jun  6 19:06:43 2013
@@ -2,23 +2,42 @@
 Test the 'register' command.
 """
 
-import os, time
+import os, sys, time
 import re
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class RegisterCommandsTestCase(TestBase):
 
     mydir = os.path.join("functionalities", "register")
 
+    def setUp(self):
+        TestBase.setUp(self)
+        self.has_teardown = False
+
     def test_register_commands(self):
-        """Test commands related to registers, in particular xmm registers."""
+        """Test commands related to registers, in particular vector registers."""
         if not self.getArchitecture() in ['i386', 'x86_64']:
             self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior")
         self.buildDefault()
         self.register_commands()
 
+    def test_fp_register_write(self):
+        """Test commands that write to registers, in particular floating-point registers."""
+        if not self.getArchitecture() in ['i386', 'x86_64']:
+            self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior")
+        self.buildDefault()
+        self.fp_register_write()
+
+    def test_register_expressions(self):
+        """Test expression evaluation with commands related to registers."""
+        if not self.getArchitecture() in ['i386', 'x86_64']:
+            self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior")
+        self.buildDefault()
+        self.register_expressions()
+
     def test_convenience_registers(self):
         """Test convenience registers."""
         if not self.getArchitecture() in ['x86_64']:
@@ -26,6 +45,7 @@ class RegisterCommandsTestCase(TestBase)
         self.buildDefault()
         self.convenience_registers()
 
+    @skipIfLinux # Expression evaluation fails after attach by pid
     def test_convenience_registers_with_process_attach(self):
         """Test convenience registers after a 'process attach'."""
         if not self.getArchitecture() in ['x86_64']:
@@ -33,15 +53,13 @@ class RegisterCommandsTestCase(TestBase)
         self.buildDefault()
         self.convenience_registers_with_process_attach()
 
-    def register_commands(self):
-        """Test commands related to registers, in particular xmm registers."""
+    def common_setup(self):
         exe = os.path.join(os.getcwd(), "a.out")
+
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break in main().
-        self.expect("breakpoint set -n main",
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: name = 'main'")
+        lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1)
 
         self.runCmd("run", RUN_SUCCEEDED)
 
@@ -49,13 +67,132 @@ class RegisterCommandsTestCase(TestBase)
         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
             substrs = ['stopped', 'stop reason = breakpoint'])
 
-        # Test some register-related commands.
+    # platform specific logging of the specified category
+    def log_enable(self, category):
+        self.platform = ""
+        if sys.platform.startswith("darwin"):
+            self.platform = "" # TODO: add support for "log enable darwin registers"
+        if sys.platform.startswith("linux"):
+            self.platform = "linux"
+
+        if self.platform != "":
+            log_file = os.path.join(os.getcwd(), 'TestRegisters.log')
+            self.runCmd("log enable " + self.platform + " " + str(category) + " registers -v -f " + log_file, RUN_SUCCEEDED)
+            if not self.has_teardown:
+                self.has_teardown = True
+                self.addTearDownHook(lambda: os.remove(log_file))
+
+    def register_commands(self):
+        """Test commands related to registers, in particular vector registers."""
+        self.common_setup()
 
-        self.runCmd("register read -a")
+        # verify that logging does not assert
+        self.log_enable("registers")
+
+        self.expect("register read -a", MISSING_EXPECTED_REGISTERS,
+            substrs = ['registers were unavailable'], matching = False)
         self.runCmd("register read xmm0")
+        self.runCmd("register read ymm15") # may be available
+
+        self.expect("register read -s 3",
+            substrs = ['invalid register set index: 3'], error = True)
+
+    def write_and_restore(self, frame, register, must_exist = True):
+        value = frame.FindValue(register, lldb.eValueTypeRegister)
+        if must_exist:
+            self.assertTrue(value.IsValid(), "finding a value for register " + register)
+        elif not value.IsValid():
+            return # If register doesn't exist, skip this test
+
+        error = lldb.SBError()
+        register_value = value.GetValueAsUnsigned(error, 0)
+        self.assertTrue(error.Success(), "reading a value for " + register)
+
+        self.runCmd("register write " + register + " 0xff0e")
+        self.expect("register read " + register,
+            substrs = [register + ' = 0x', 'ff0e'])
+
+        self.runCmd("register write " + register + " " + str(register_value))
+        self.expect("register read " + register,
+            substrs = [register + ' = 0x'])
+
+    def vector_write_and_read(self, frame, register, new_value, must_exist = True):
+        value = frame.FindValue(register, lldb.eValueTypeRegister)
+        if must_exist:
+            self.assertTrue(value.IsValid(), "finding a value for register " + register)
+        elif not value.IsValid():
+            return # If register doesn't exist, skip this test
+
+        self.runCmd("register write " + register + " \'" + new_value + "\'")
+        self.expect("register read " + register,
+            substrs = [register + ' = ', new_value])
+
+    def fp_register_write(self):
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1)
+
+        # Launch the process, and do not stop at the entry point.
+        process = target.LaunchSimple(None, None, os.getcwd())
+
+        process = target.GetProcess()
+        self.assertTrue(process.GetState() == lldb.eStateStopped,
+                        PROCESS_STOPPED)
+
+        thread = process.GetThreadAtIndex(0)
+        self.assertTrue(thread.IsValid(), "current thread is valid")
+
+        currentFrame = thread.GetFrameAtIndex(0)
+        self.assertTrue(currentFrame.IsValid(), "current frame is valid")
+
+        self.write_and_restore(currentFrame, "fcw", False)
+        self.write_and_restore(currentFrame, "fsw", False)
+        self.write_and_restore(currentFrame, "ftw", False)
+        self.write_and_restore(currentFrame, "ip", False)
+        self.write_and_restore(currentFrame, "dp", False)
+        self.write_and_restore(currentFrame, "mxcsr", False)
+        self.write_and_restore(currentFrame, "mxcsrmask", False)
+
+        new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        self.vector_write_and_read(currentFrame, "stmm0", new_value)
+        new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a}"
+        self.vector_write_and_read(currentFrame, "stmm7", new_value)
+
+        new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x2f 0x2f}"
+        self.vector_write_and_read(currentFrame, "xmm0", new_value)
+        new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f}"
+        self.vector_write_and_read(currentFrame, "xmm15", new_value, False)
+
+        has_avx = False 
+        registerSets = currentFrame.GetRegisters() # Returns an SBValueList.
+        for registerSet in registerSets:
+            if 'advanced vector extensions' in registerSet.GetName().lower():
+                has_avx = True
+                break
+
+        if has_avx:
+            new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x0d 0x0e 0x0f}"
+            self.vector_write_and_read(currentFrame, "ymm0", new_value)
+            self.vector_write_and_read(currentFrame, "ymm15", new_value)
+            self.expect("expr $ymm0", substrs = ['vector_type'])
+        else:
+            self.runCmd("register read ymm0")
+
+    def register_expressions(self):
+        """Test expression evaluation with commands related to registers."""
+        self.common_setup()
+
+        self.expect("expr/x $eax",
+            substrs = ['unsigned int', ' = 0x'])
+
+        if self.getArchitecture() in ['x86_64']:
+            self.expect("expr -- ($rax & 0xffffffff) == $eax",
+                substrs = ['true'])
 
-        # rdar://problem/10611315
-        # expression command doesn't handle xmm or stmm registers...
         self.expect("expr $xmm0",
             substrs = ['vector_type'])
 
@@ -64,57 +201,47 @@ class RegisterCommandsTestCase(TestBase)
 
     def convenience_registers(self):
         """Test convenience registers."""
-        exe = os.path.join(os.getcwd(), "a.out")
-        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
-
-        # Break in main().
-        self.expect("breakpoint set -n main",
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: name = 'main'")
-
-        self.runCmd("run", RUN_SUCCEEDED)
+        self.common_setup()
 
-        # The stop reason of the thread should be breakpoint.
-        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
-            substrs = ['stopped', 'stop reason = breakpoint'])
+        # The command "register read -a" does output a derived register like eax...
+        self.expect("register read -a", matching=True,
+            substrs = ['eax'])
 
-        # The vanilla "register read" command does not output derived register like eax.
+        # ...however, the vanilla "register read" command should not output derived registers like eax.
         self.expect("register read", matching=False,
             substrs = ['eax'])
-        # While "register read -a" does output derived register like eax.
-        self.expect("register read -a", matching=True,
-            substrs = ['eax'])
         
         # Test reading of rax and eax.
-        self.runCmd("register read rax eax")
+        self.expect("register read rax eax",
+            substrs = ['rax = 0x', 'eax = 0x'])
 
         # Now write rax with a unique bit pattern and test that eax indeed represents the lower half of rax.
         self.runCmd("register write rax 0x1234567887654321")
-        self.expect("expr -- ($rax & 0xffffffff) == $eax",
-            substrs = ['true'])
-        self.expect("expr -- $ax == (($ah << 8) | $al)",
-            substrs = ['true'])
+        self.expect("register read rax 0x1234567887654321",
+            substrs = ['0x1234567887654321'])
 
     def convenience_registers_with_process_attach(self):
         """Test convenience registers after a 'process attach'."""
         exe = self.lldbHere
         
-        # Spawn a new process and don't display the stdout if not in TraceOn() mode.
-        import subprocess
-        popen = subprocess.Popen([exe, self.lldbOption],
-                                 stdout = open(os.devnull, 'w') if not self.TraceOn() else None)
-        if self.TraceOn():
-            print "pid of spawned process: %d" % popen.pid
+        # Spawn a new process
+        proc = self.spawnSubprocess(exe, [self.lldbOption])
+        self.addTearDownHook(self.cleanupSubprocesses)
 
-        self.runCmd("process attach -p %d" % popen.pid)
+        if self.TraceOn():
+            print "pid of spawned process: %d" % proc.pid
 
-        # Add a hook to kill the child process during teardown.
-        self.addTearDownHook(
-            lambda: popen.kill())
+        self.runCmd("process attach -p %d" % proc.pid)
 
         # Check that "register read eax" works.
         self.runCmd("register read eax")
 
+        if self.getArchitecture() in ['x86_64']:
+            self.expect("expr -- ($rax & 0xffffffff) == $eax",
+                substrs = ['true'])
+
+        self.expect("expr -- $ax == (($ah << 8) | $al)",
+            substrs = ['true'])
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/branches/lldb-platform-work/test/functionalities/return-value/TestReturnValue.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/return-value/TestReturnValue.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/return-value/TestReturnValue.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/return-value/TestReturnValue.py Thu Jun  6 19:06:43 2013
@@ -211,6 +211,9 @@ class ReturnValueTestCase(TestBase):
         #self.return_and_test_struct_value ("return_one_int_one_double_packed")
         self.return_and_test_struct_value ("return_one_int_one_long")
 
+        self.return_and_test_struct_value ("return_vector_size_float32")
+        self.return_and_test_struct_value ("return_ext_vector_size_float32")
+
         
 if __name__ == '__main__':
     import atexit

Modified: lldb/branches/lldb-platform-work/test/functionalities/return-value/call-func.c
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/return-value/call-func.c?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/return-value/call-func.c (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/return-value/call-func.c Thu Jun  6 19:06:43 2013
@@ -301,6 +301,21 @@ return_one_int_one_pointer (struct one_i
   return value;
 }
 
+typedef float vector_size_float32 __attribute__((__vector_size__(16)));
+typedef float ext_vector_size_float32 __attribute__((ext_vector_type(4)));
+
+vector_size_float32
+return_vector_size_float32 (vector_size_float32 value)
+{
+    return value;
+}
+
+ext_vector_size_float32
+return_ext_vector_size_float32 (ext_vector_size_float32 value)
+{
+    return value;
+}
+
 int 
 main ()
 {
@@ -351,6 +366,9 @@ main ()
   return_one_int_one_double_packed ((struct one_int_one_double_packed) {10, 20.0});
   return_one_int_one_long ((struct one_int_one_long) {10, 20});
 
+  return_vector_size_float32 (( vector_size_float32 ){1.5, 2.25, 4.125, 8.0625});
+  return_ext_vector_size_float32 ((ext_vector_size_float32){ 16.5, 32.25, 64.125, 128.0625});
+  
   return 0;
   
 }

Modified: lldb/branches/lldb-platform-work/test/functionalities/signal/TestSendSignal.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/signal/TestSendSignal.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/signal/TestSendSignal.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/signal/TestSendSignal.py Thu Jun  6 19:06:43 2013
@@ -4,6 +4,7 @@ import os, time, signal
 import unittest2
 import lldb
 from lldbtest import *
+import lldbutil
 
 class SendSignalTestCase(TestBase):
 
@@ -35,10 +36,7 @@ class SendSignalTestCase(TestBase):
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break inside the main() function and immediately send a signal to the inferior after resuming.
-        self.expect("breakpoint set -f main.c -l %d" % self.line,
-                    BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 1" %
-                        self.line)
+        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("run", RUN_SUCCEEDED)
         self.runCmd("thread backtrace")

Modified: lldb/branches/lldb-platform-work/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py Thu Jun  6 19:06:43 2013
@@ -16,10 +16,14 @@ class SingleQuoteInCommandLineTestCase(T
     @classmethod
     def classCleanup(cls):
         """Cleanup the test byproducts."""
-        os.remove("child_send.txt")
-        os.remove("child_read.txt")
-        os.remove(cls.myexe)
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+            os.remove(cls.myexe)
+        except:
+            pass
 
+    @skipIfLinux # llvm.org/pr14637: this test case fails sometimes because the input prompt "(lldb)" is missing
     def test_lldb_invocation_with_single_quote_in_filename(self):
         """Test that 'lldb my_file_name' works where my_file_name is a string with a single quote char in it."""
         self.buildDefault()

Modified: lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookCmd.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookCmd.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookCmd.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookCmd.py Thu Jun  6 19:06:43 2013
@@ -7,6 +7,7 @@ import unittest2
 import StringIO
 import lldb
 from lldbtest import *
+import lldbutil
 
 class StopHookCmdTestCase(TestBase):
 
@@ -43,14 +44,9 @@ class StopHookCmdTestCase(TestBase):
         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)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.begl, num_expected_locations=1, loc_exact=True)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
 
         self.runCmd("target stop-hook add -f main.cpp -l %d -e %d -o 'expr ptr'" % (self.begl, self.endl))
 
@@ -71,7 +67,7 @@ class StopHookCmdTestCase(TestBase):
                        'expr ptr'])
 
         self.runCmd("settings set auto-confirm true")
-        self.addTearDownHook(lambda: self.runCmd("settings set -r auto-confirm"))
+        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
 
         self.runCmd('target stop-hook delete')
 

Modified: lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookMechanism.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookMechanism.py?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookMechanism.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/stop-hook/TestStopHookMechanism.py Thu Jun  6 19:06:43 2013
@@ -19,6 +19,7 @@ class StopHookMechanismTestCase(TestBase
         self.buildDsym()
         self.stop_hook_firing()
 
+    @skipIfLinux # llvm.org/pr15037: stop-hooks sometimes fail to fire on Linux (disabled to avoid needless noise)
     @dwarf_test
     def test_with_dwarf(self):
         """Test the stop-hook mechanism."""

Modified: lldb/branches/lldb-platform-work/test/functionalities/stop-hook/multiple_threads/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/stop-hook/multiple_threads/Makefile?rev=183468&r1=183467&r2=183468&view=diff
===========================================