<rdar://problem/13372857>
authorGreg Clayton <gclayton@apple.com>
Mon, 11 Mar 2013 18:42:51 +0000 (18:42 +0000)
committerGreg Clayton <gclayton@apple.com>
Mon, 11 Mar 2013 18:42:51 +0000 (18:42 +0000)
Fixed the exception breakpoints to always use a file filter to make setting exception breakpoint efficient.

llvm-svn: 176821

lldb/include/lldb/Breakpoint/BreakpointResolver.h
lldb/include/lldb/Core/SearchFilter.h
lldb/include/lldb/Target/LanguageRuntime.h
lldb/source/Core/SearchFilter.cpp
lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
lldb/source/Target/LanguageRuntime.cpp

index 7cbbbe3..3db3795 100644 (file)
@@ -134,7 +134,6 @@ public:
     }
 
 protected:
-    Target *m_target;          // Every resolver has a target.
     Breakpoint *m_breakpoint;  // This is the breakpoint we add locations to.
 
 private:
index 70eee2e..57f1b9c 100644 (file)
@@ -135,23 +135,6 @@ public:
     ModulePasses (const lldb::ModuleSP &module_sp);
 
     //------------------------------------------------------------------
-    /// Call this method with a SymbolContext and a SymbolContextScope to see if
-    /// that SymbolContext passes the filter up to the level in \a scope.
-    ///
-    /// @param[in] context
-    ///    The SymbolContext to check against the filter.
-    ///
-    /// @param[in] scope
-    ///    The SymbolContextItem indicating what bits of the SymbolContextScope
-    ///    to check against the filter.
-    ///
-    ///  @return
-    ///    \b true if \a SymbolContext passes, and \b false otherwise.
-    //------------------------------------------------------------------
-    virtual bool
-    SymbolContextPasses (const SymbolContext &context,
-                         lldb::SymbolContextItem scope);
-    //------------------------------------------------------------------
     /// Call this method with a Address to see if \a address passes the filter.
     ///
     /// @param[in] addr
@@ -325,10 +308,6 @@ public:
     ModulePasses (const FileSpec &spec);
 
     virtual bool
-    SymbolContextPasses (const SymbolContext &context,
-                         lldb::SymbolContextItem scope);
-
-    virtual bool
     AddressPasses (Address &address);
 
     virtual bool
@@ -386,10 +365,6 @@ public:
     ModulePasses (const FileSpec &spec);
 
     virtual bool
-    SymbolContextPasses (const SymbolContext &context,
-                         lldb::SymbolContextItem scope);
-
-    virtual bool
     AddressPasses (Address &address);
 
     virtual bool
@@ -442,10 +417,6 @@ public:
     operator=(const SearchFilterByModuleListAndCU& rhs);
 
     virtual bool
-    SymbolContextPasses (const SymbolContext &context,
-                         lldb::SymbolContextItem scope);
-
-    virtual bool
     AddressPasses (Address &address);
 
     virtual bool
index cafbff0..1870231 100644 (file)
@@ -23,6 +23,9 @@
 #include "lldb/Core/Value.h"
 #include "lldb/Target/ExecutionContextScope.h"
 
+class ExceptionBreakpointResolver;
+class ExceptionSearchFilter;
+
 namespace lldb_private {
 
 class LanguageRuntime :
@@ -95,52 +98,15 @@ protected:
     //------------------------------------------------------------------
     // Classes that inherit from LanguageRuntime can see and modify these
     //------------------------------------------------------------------
-    
-    // The Target is the one that knows how to create breakpoints, so this function is meant to be used either
-    // by the target or internally in Set/ClearExceptionBreakpoints.
-    class ExceptionBreakpointResolver : public BreakpointResolver
-    {
-    public:
-        ExceptionBreakpointResolver (Breakpoint *bkpt,
-                                lldb::LanguageType language,
-                                bool catch_bp,
-                                bool throw_bp);
-
-        virtual ~ExceptionBreakpointResolver() {}
-
-        virtual Searcher::CallbackReturn
-        SearchCallback (SearchFilter &filter,
-                        SymbolContext &context,
-                        Address *addr,
-                        bool containing);
-
-        virtual Searcher::Depth
-        GetDepth ();
-
-        virtual void
-        GetDescription (Stream *s);
-        
-        virtual void
-        Dump (Stream *s) const {}
-
-        /// Methods for support type inquiry through isa, cast, and dyn_cast:
-        static inline bool classof(const BreakpointResolverName *) { return true; }
-        static inline bool classof(const BreakpointResolver *V) {
-            return V->getResolverID() == BreakpointResolver::ExceptionResolver;
-        }
-    protected:
-        bool SetActualResolver();
-        
-        lldb::BreakpointResolverSP m_actual_resolver_sp;
-        lldb::ProcessWP m_process_wp;
-        lldb::LanguageType m_language;
-        bool m_catch_bp;
-        bool m_throw_bp;
-    };
+    friend class ExceptionBreakpointResolver;
+    friend class ExceptionSearchFilter;
     
     virtual lldb::BreakpointResolverSP
     CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0;
     
+    virtual lldb::SearchFilterSP
+    CreateExceptionSearchFilter ();
+
     LanguageRuntime(Process *process);
     Process *m_process;
 private:
index edc5656..523d3f6 100644 (file)
@@ -85,16 +85,6 @@ SearchFilter::ModulePasses (const ModuleSP &module_sp)
 }
 
 bool
-SearchFilter::SymbolContextPasses
-(
-    const SymbolContext &context,
-    lldb::SymbolContextItem scope
-)
-{
-    return true;
-}
-
-bool
 SearchFilter::AddressPasses (Address &address)
 {
     return true;
@@ -376,22 +366,6 @@ SearchFilterByModule::ModulePasses (const FileSpec &spec)
 }
 
 bool
-SearchFilterByModule::SymbolContextPasses (const SymbolContext &sc,
-                                           lldb::SymbolContextItem scope)
-{
-    if (scope & eSymbolContextModule)
-    {
-        if (sc.module_sp)
-        {
-            // Match the full path only if "m_module_spec" has a directory
-            const bool full_match = m_module_spec.GetDirectory();
-            return FileSpec::Equal (sc.module_sp->GetFileSpec(), m_module_spec, full_match);
-        }
-    }
-    return false;
-}
-
-bool
 SearchFilterByModule::AddressPasses (Address &address)
 {
     // FIXME: Not yet implemented
@@ -543,22 +517,6 @@ SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
 }
 
 bool
-SearchFilterByModuleList::SymbolContextPasses
-(
- const SymbolContext &context,
- lldb::SymbolContextItem scope
- )
-{
-    if (!(scope & eSymbolContextModule))
-        return false;
-
-    if (context.module_sp && m_module_spec_list.FindFileIndex(0, context.module_sp->GetFileSpec(), true) != UINT32_MAX)
-        return true;
-    else
-        return false;
-}
-
-bool
 SearchFilterByModuleList::AddressPasses (Address &address)
 {
     // FIXME: Not yet implemented
@@ -715,25 +673,8 @@ SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU()
 }
 
 bool
-SearchFilterByModuleListAndCU::SymbolContextPasses
-(
- const SymbolContext &context,
- lldb::SymbolContextItem scope
- )
-{
-    if (!SearchFilterByModuleList::SymbolContextPasses(context, scope))
-        return false;
-    if (!(scope & eSymbolContextCompUnit))
-        return false;
-    if (context.comp_unit && m_cu_spec_list.FindFileIndex(0, context.comp_unit, false) == UINT32_MAX)
-        return false;
-    return true;
-}
-
-bool
 SearchFilterByModuleListAndCU::AddressPasses (Address &address)
 {
-    // FIXME: Not yet implemented
     return true;
 }
 
index 8eff78e..410e6be 100644 (file)
@@ -338,19 +338,6 @@ ItaniumABILanguageRuntime::GetPluginVersion()
     return 1;
 }
 
-// This is an array of symbol names to use in setting exception breakpoints.  The names are laid out:
-//
-//  catch_names, general_throw_names, throw_names_for_use_in_expressions
-//
-// Then you can use the following constants to pick out the part of the array you want to pass to the breakpoint
-// resolver.
-
-static const char *exception_names[] = { "__cxa_begin_catch", "__cxa_throw", "__cxa_rethrow", "__cxa_allocate_exception"};
-static const int num_exception_names = sizeof (exception_names)/sizeof (char *);
-static const int num_catch_names = 1;
-static const int num_throw_names = num_exception_names - num_catch_names;
-static const int num_expression_throw_names = 1;
-
 BreakpointResolverSP
 ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
 {
@@ -360,48 +347,70 @@ ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch
 BreakpointResolverSP
 ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions)
 {
-    BreakpointResolverSP resolver_sp;
-    
     // One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do
     // anything better with predicting unwinding the expression parser does.  So we have two forms of the exception
     // breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it.
     // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former.
+    static const char *g_catch_name = "__cxa_begin_catch";
+    static const char *g_throw_name1 = "__cxa_throw";
+    static const char *g_throw_name2 = "__cxa_rethrow";
+    static const char *g_exception_throw_name = "__cxa_allocate_exception";
+    std::vector<const char *> exception_names;
+    exception_names.reserve(4);
+    if (catch_bp)
+        exception_names.push_back(g_catch_name);
+
+    if (throw_bp)
+    {
+        exception_names.push_back(g_throw_name1);
+        exception_names.push_back(g_throw_name2);
+    }
+
+    if (for_expressions)
+        exception_names.push_back(g_exception_throw_name);
     
-    uint32_t num_expressions;
-    if (catch_bp && throw_bp)
+    BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt,
+                                                                  exception_names.data(),
+                                                                  exception_names.size(),
+                                                                  eFunctionNameTypeBase,
+                                                                  eLazyBoolNo));
+
+    return resolver_sp;
+}
+
+
+
+lldb::SearchFilterSP
+ItaniumABILanguageRuntime::CreateExceptionSearchFilter ()
+{
+    Target &target = m_process->GetTarget();
+
+    if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
     {
-        if (for_expressions)
-            num_expressions = num_exception_names;
-        else
-            num_expressions = num_exception_names - num_expression_throw_names;
-            
-        resolver_sp.reset (new BreakpointResolverName (bkpt,
-                                                       exception_names,
-                                                       num_expressions,
-                                                       eFunctionNameTypeBase,
-                                                       eLazyBoolNo));
+        // Limit the number of modules that are searched for these breakpoints for
+        // Apple binaries.
+        FileSpecList filter_modules;
+        filter_modules.Append(FileSpec("libc++abi.dylib", false));
+        filter_modules.Append(FileSpec("libSystem.B.dylib", false));
+        return target.GetSearchFilterForModuleList(&filter_modules);
     }
-    else if (throw_bp)
+    else
     {
-        if (for_expressions)
-            num_expressions = num_throw_names;
-        else
-            num_expressions = num_throw_names - num_expression_throw_names;
-        
-        resolver_sp.reset (new BreakpointResolverName (bkpt,
-                                                       exception_names + num_catch_names,
-                                                       num_expressions,
-                                                       eFunctionNameTypeBase,
-                                                       eLazyBoolNo));
+        return LanguageRuntime::CreateExceptionSearchFilter();
     }
-    else if (catch_bp)
-        resolver_sp.reset (new BreakpointResolverName (bkpt,
-                                                       exception_names,
-                                                       num_catch_names,
-                                                       eFunctionNameTypeBase,
-                                                       eLazyBoolNo));
+}
 
-    return resolver_sp;
+lldb::BreakpointSP
+ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp,
+                                                      bool throw_bp,
+                                                      bool for_expressions,
+                                                      bool is_internal)
+{
+    Target &target = m_process->GetTarget();
+    FileSpecList filter_modules;
+    BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
+    SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
+    return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
 }
 
 void
@@ -418,31 +427,16 @@ ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
     // For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and
     // stop at exception allocation as well.
     
-    if (!m_cxx_exception_bp_sp)
+    if (m_cxx_exception_bp_sp)
     {
-        Target &target = m_process->GetTarget();
-        FileSpecList filter_modules;
-        // Limit the number of modules that are searched for these breakpoints for
-        // Apple binaries.
-        if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
-        {
-            filter_modules.Append(FileSpec("libc++abi.dylib", false));
-            filter_modules.Append(FileSpec("libSystem.B.dylib", false));
-        }
-        BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
-        SearchFilterSP filter_sp;
-        
-        if (filter_modules.IsEmpty())
-            filter_sp = target.GetSearchFilterForModule(NULL);
-        else
-            filter_sp = target.GetSearchFilterForModuleList(&filter_modules);
-        
-        m_cxx_exception_bp_sp = target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
+        m_cxx_exception_bp_sp->SetEnabled (true);
+    }
+    else
+    {
+        m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal);
         if (m_cxx_exception_bp_sp)
             m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
     }
-    else
-        m_cxx_exception_bp_sp->SetEnabled (true);
     
 }
 
@@ -452,7 +446,7 @@ ItaniumABILanguageRuntime::ClearExceptionBreakpoints ()
     if (!m_process)
         return;
     
-    if (m_cxx_exception_bp_sp.get())
+    if (m_cxx_exception_bp_sp)
     {
         m_cxx_exception_bp_sp->SetEnabled (false);
     }    
index 85c93d2..d5cf6b3 100644 (file)
@@ -77,9 +77,18 @@ namespace lldb_private {
         virtual lldb::BreakpointResolverSP
         CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
 
-        virtual lldb::BreakpointResolverSP
+        virtual lldb::SearchFilterSP
+        CreateExceptionSearchFilter ();
+
+        lldb::BreakpointResolverSP
         CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions);
 
+        lldb::BreakpointSP
+        CreateExceptionBreakpoint(bool catch_bp,
+                                  bool throw_bp,
+                                  bool for_expressions,
+                                  bool is_internal);
+        
     private:
         ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
         
index 1f20f44..951654b 100644 (file)
@@ -393,3 +393,21 @@ AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing()
     else
         return false;
 }
+
+lldb::SearchFilterSP
+AppleObjCRuntime::CreateExceptionSearchFilter ()
+{
+    Target &target = m_process->GetTarget();
+    
+    if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
+    {
+        FileSpecList filter_modules;
+        filter_modules.Append(FileSpec("libobjc.A.dylib", false));
+        return target.GetSearchFilterForModuleList(&filter_modules);
+    }
+    else
+    {
+        return LanguageRuntime::CreateExceptionSearchFilter();
+    }
+}
+
index e5d2c0f..4ae527a 100644 (file)
@@ -106,6 +106,9 @@ protected:
     lldb::BreakpointSP m_objc_exception_bp_sp;
     lldb::ModuleWP m_objc_module_wp;
 
+    virtual lldb::SearchFilterSP
+    CreateExceptionSearchFilter ();
+    
     AppleObjCRuntime(Process *process) :
         lldb_private::ObjCLanguageRuntime(process),
         m_read_objc_library (false),
index ecd69a3..7a6bfbe 100644 (file)
 using namespace lldb;
 using namespace lldb_private;
 
+
+class ExceptionSearchFilter : public SearchFilter
+{
+public:
+    ExceptionSearchFilter (const lldb::TargetSP &target_sp,
+                           lldb::LanguageType language) :
+        SearchFilter (target_sp),
+        m_language (language),
+        m_language_runtime (NULL),
+        m_filter_sp ()
+    {
+        UpdateModuleListIfNeeded ();
+    }
+    
+    virtual bool
+    ModulePasses (const lldb::ModuleSP &module_sp)
+    {
+        UpdateModuleListIfNeeded ();
+        if (m_filter_sp)
+            return m_filter_sp->ModulePasses (module_sp);
+        return false;
+    }
+    
+    virtual bool
+    ModulePasses (const FileSpec &spec)
+    {
+        UpdateModuleListIfNeeded ();
+        if (m_filter_sp)
+            return m_filter_sp->ModulePasses (spec);
+        return false;
+        
+    }
+    
+    virtual void
+    Search (Searcher &searcher)
+    {
+        UpdateModuleListIfNeeded ();
+        if (m_filter_sp)
+            m_filter_sp->Search (searcher);
+    }
+
+    virtual void
+    GetDescription (Stream *s)
+    {
+        UpdateModuleListIfNeeded ();
+        if (m_filter_sp)
+            m_filter_sp->GetDescription (s);
+    }
+    
+protected:
+    LanguageType m_language;
+    LanguageRuntime *m_language_runtime;
+    SearchFilterSP m_filter_sp;
+
+    void
+    UpdateModuleListIfNeeded ()
+    {
+        ProcessSP process_sp (m_target_sp->GetProcessSP());
+        if (process_sp)
+        {
+            bool refreash_filter = !m_filter_sp;
+            if (m_language_runtime == NULL)
+            {
+                m_language_runtime = process_sp->GetLanguageRuntime(m_language);
+                refreash_filter = true;
+            }
+            else
+            {
+                LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
+                if (m_language_runtime != language_runtime)
+                {
+                    m_language_runtime = language_runtime;
+                    refreash_filter = true;
+                }
+            }
+            
+            if (refreash_filter && m_language_runtime)
+            {
+                m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
+            }
+        }
+        else
+        {
+            m_filter_sp.reset();
+            m_language_runtime = NULL;
+        }
+    }
+};
+
+// The Target is the one that knows how to create breakpoints, so this function
+// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
+class ExceptionBreakpointResolver : public BreakpointResolver
+{
+public:
+    ExceptionBreakpointResolver (lldb::LanguageType language,
+                                 bool catch_bp,
+                                 bool throw_bp) :
+        BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
+        m_language (language),
+        m_language_runtime (NULL),
+        m_catch_bp (catch_bp),
+        m_throw_bp (throw_bp)
+    {
+    }
+
+    virtual
+    ~ExceptionBreakpointResolver()
+    {
+    }
+    
+    virtual Searcher::CallbackReturn
+    SearchCallback (SearchFilter &filter,
+                    SymbolContext &context,
+                    Address *addr,
+                    bool containing)
+    {
+        
+        if (SetActualResolver())
+            return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
+        else
+            return eCallbackReturnStop;
+    }
+    
+    virtual Searcher::Depth
+    GetDepth ()
+    {
+        if (SetActualResolver())
+            return m_actual_resolver_sp->GetDepth();
+        else
+            return eDepthTarget;
+    }
+    
+    virtual void
+    GetDescription (Stream *s)
+    {
+        s->Printf ("Exception breakpoint (catch: %s throw: %s)",
+                   m_catch_bp ? "on" : "off",
+                   m_throw_bp ? "on" : "off");
+        
+        SetActualResolver();
+        if (m_actual_resolver_sp)
+        {
+            s->Printf (" using: ");
+            m_actual_resolver_sp->GetDescription (s);
+        }
+        else
+            s->Printf (" the correct runtime exception handler will be determined when you run");
+    }
+
+    virtual void
+    Dump (Stream *s) const
+    {
+    }
+    
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const BreakpointResolverName *) { return true; }
+    static inline bool classof(const BreakpointResolver *V) {
+        return V->getResolverID() == BreakpointResolver::ExceptionResolver;
+    }
+protected:
+    bool
+    SetActualResolver()
+    {
+        ProcessSP process_sp;
+        if (m_breakpoint)
+        {
+            process_sp = m_breakpoint->GetTarget().GetProcessSP();
+            if (process_sp)
+            {
+                bool refreash_resolver = !m_actual_resolver_sp;
+                if (m_language_runtime == NULL)
+                {
+                    m_language_runtime = process_sp->GetLanguageRuntime(m_language);
+                    refreash_resolver = true;
+                }
+                else
+                {
+                    LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
+                    if (m_language_runtime != language_runtime)
+                    {
+                        m_language_runtime = language_runtime;
+                        refreash_resolver = true;
+                    }
+                }
+                
+                if (refreash_resolver && m_language_runtime)
+                {
+                    m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
+                }
+            }
+            else
+            {
+                m_actual_resolver_sp.reset();
+                m_language_runtime = NULL;
+            }
+        }
+        else
+        {
+            m_actual_resolver_sp.reset();
+            m_language_runtime = NULL;
+        }
+        return (bool)m_actual_resolver_sp;
+    }
+    lldb::BreakpointResolverSP m_actual_resolver_sp;
+    lldb::LanguageType m_language;
+    LanguageRuntime *m_language_runtime;
+    bool m_catch_bp;
+    bool m_throw_bp;
+};
+
+
 LanguageRuntime*
 LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
 {
@@ -49,148 +260,22 @@ LanguageRuntime::~LanguageRuntime()
 }
 
 BreakpointSP
-LanguageRuntime::CreateExceptionBreakpoint(
-    Target &target, 
-    lldb::LanguageType language, 
-    bool catch_bp, 
-    bool throw_bp, 
-    bool is_internal)
+LanguageRuntime::CreateExceptionBreakpoint (Target &target,
+                                            lldb::LanguageType language,
+                                            bool catch_bp,
+                                            bool throw_bp,
+                                            bool is_internal)
 {
-    BreakpointSP exc_breakpt_sp;
-    BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(NULL, language, catch_bp, throw_bp));
-    SearchFilterSP filter_sp(target.GetSearchFilterForModule(NULL));
+    BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
+    SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
     
-    exc_breakpt_sp = target.CreateBreakpoint (filter_sp, resolver_sp, is_internal);
+    BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal));
     if (is_internal)
         exc_breakpt_sp->SetBreakpointKind("exception");
     
     return exc_breakpt_sp;
 }
 
-LanguageRuntime::ExceptionBreakpointResolver::ExceptionBreakpointResolver (Breakpoint *bkpt,
-                        LanguageType language,
-                        bool catch_bp,
-                        bool throw_bp) :
-    BreakpointResolver (bkpt, BreakpointResolver::ExceptionResolver),
-    m_language (language),
-    m_catch_bp (catch_bp),
-    m_throw_bp (throw_bp)
-
-{
-}
-                        
-void
-LanguageRuntime::ExceptionBreakpointResolver::GetDescription (Stream *s)
-{
-    s->Printf ("Exception breakpoint (catch: %s throw: %s)", 
-           m_catch_bp ? "on" : "off",
-           m_throw_bp ? "on" : "off");
-       
-    SetActualResolver();
-    if (m_actual_resolver_sp)
-    {
-        s->Printf (" using: ");
-        m_actual_resolver_sp->GetDescription (s);
-    }
-    else
-        s->Printf (" the correct runtime exception handler will be determined when you run");
-}
-
-bool
-LanguageRuntime::ExceptionBreakpointResolver::SetActualResolver()
-{
-    ProcessSP process_sp = m_process_wp.lock();
-    
-    // See if our process weak pointer is still good:
-    if (!process_sp)
-    {
-        // If not, our resolver is no good, so chuck that.  Then see if we can get the 
-        // target's new process.
-        m_actual_resolver_sp.reset();
-        if (m_breakpoint)
-        {
-            Target &target = m_breakpoint->GetTarget();
-            process_sp = target.GetProcessSP();
-            if (process_sp)
-            {
-                m_process_wp = process_sp;
-                process_sp = m_process_wp.lock();
-            }
-        }
-    }
-    
-    if (process_sp)
-    {
-        if (m_actual_resolver_sp)
-            return true;
-        else
-        {
-            // If we have a process but not a resolver, set one now.
-            LanguageRuntime *runtime = process_sp->GetLanguageRuntime(m_language);
-            if (runtime)
-            {
-                m_actual_resolver_sp = runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
-                return (bool) m_actual_resolver_sp;
-            }
-            else
-                return false;
-        }
-    }
-    else
-        return false;
-}
-
-Searcher::CallbackReturn
-LanguageRuntime::ExceptionBreakpointResolver::SearchCallback (SearchFilter &filter,
-                SymbolContext &context,
-                Address *addr,
-                bool containing)
-{
-    
-    if (!SetActualResolver())
-    {
-        return eCallbackReturnStop;
-    }
-    else
-        return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
-}
-
-Searcher::Depth
-LanguageRuntime::ExceptionBreakpointResolver::GetDepth ()
-{
-    if (!SetActualResolver())
-        return eDepthTarget;
-    else
-        return m_actual_resolver_sp->GetDepth();
-}
-
-/*
-typedef enum LanguageType
-{
-    eLanguageTypeUnknown         = 0x0000,   ///< Unknown or invalid language value.
-    eLanguageTypeC89             = 0x0001,   ///< ISO C:1989.
-    eLanguageTypeC               = 0x0002,   ///< Non-standardized C, such as K&R.
-    eLanguageTypeAda83           = 0x0003,   ///< ISO Ada:1983.
-    eLanguageTypeC_plus_plus     = 0x0004,   ///< ISO C++:1998.
-    eLanguageTypeCobol74         = 0x0005,   ///< ISO Cobol:1974.
-    eLanguageTypeCobol85         = 0x0006,   ///< ISO Cobol:1985.
-    eLanguageTypeFortran77       = 0x0007,   ///< ISO Fortran 77.
-    eLanguageTypeFortran90       = 0x0008,   ///< ISO Fortran 90.
-    eLanguageTypePascal83        = 0x0009,   ///< ISO Pascal:1983.
-    eLanguageTypeModula2         = 0x000a,   ///< ISO Modula-2:1996.
-    eLanguageTypeJava            = 0x000b,   ///< Java.
-    eLanguageTypeC99             = 0x000c,   ///< ISO C:1999.
-    eLanguageTypeAda95           = 0x000d,   ///< ISO Ada:1995.
-    eLanguageTypeFortran95       = 0x000e,   ///< ISO Fortran 95.
-    eLanguageTypePLI             = 0x000f,   ///< ANSI PL/I:1976.
-    eLanguageTypeObjC            = 0x0010,   ///< Objective-C.
-    eLanguageTypeObjC_plus_plus  = 0x0011,   ///< Objective-C++.
-    eLanguageTypeUPC             = 0x0012,   ///< Unified Parallel C.
-    eLanguageTypeD               = 0x0013,   ///< D.
-    eLanguageTypePython          = 0x0014    ///< Python.
-} LanguageType;
- */
-
 struct language_name_pair {
     const char *name;
     LanguageType type;
@@ -247,4 +332,12 @@ LanguageRuntime::GetNameForLanguageType (LanguageType language)
     else
         return language_names[eLanguageTypeUnknown].name;
 }
-        
+
+lldb::SearchFilterSP
+LanguageRuntime::CreateExceptionSearchFilter ()
+{
+    return m_process->GetTarget().GetSearchFilterForModule(NULL);
+}
+
+
+