[Lldb-commits] [lldb] r246842 - RenderScript pending kernel breakpoints.

Ewan Crawford via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 4 01:56:52 PDT 2015


Author: ewancrawford
Date: Fri Sep  4 03:56:52 2015
New Revision: 246842

URL: http://llvm.org/viewvc/llvm-project?rev=246842&view=rev
Log:
RenderScript pending kernel breakpoints.

Currently the RS breakpoint command can only find a kernel if it's in an already loaded RS module.
This patch allows users to set pending breakpoints on RenderScript kernels which will be loaded in the future.
Implemented by creating a RS breakpoint resolver, to limit search scope to only RS modules.

Reviewed by: clayborg, jingham
Subscribers: lldb-commits, ADodds, domipheus
Differential Revision: http://reviews.llvm.org/D12360

Modified:
    lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h

Modified: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp?rev=246842&r1=246841&r2=246842&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp Fri Sep  4 03:56:52 2015
@@ -30,6 +30,7 @@
 
 using namespace lldb;
 using namespace lldb_private;
+using namespace lldb_renderscript;
 
 //------------------------------------------------------------------
 // Static Functions
@@ -44,6 +45,47 @@ RenderScriptRuntime::CreateInstance(Proc
         return NULL;
 }
 
+// Callback with a module to search for matching symbols.
+// We first check that the module contains RS kernels.
+// Then look for a symbol which matches our kernel name.
+// The breakpoint address is finally set using the address of this symbol.
+Searcher::CallbackReturn
+RSBreakpointResolver::SearchCallback(SearchFilter &filter,
+                                     SymbolContext &context,
+                                     Address*,
+                                     bool)
+{
+    ModuleSP module = context.module_sp;
+
+    if (!module)
+        return Searcher::eCallbackReturnContinue;
+
+    // Is this a module containing renderscript kernels?
+    if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
+        return Searcher::eCallbackReturnContinue;
+
+    // Attempt to set a breakpoint on the kernel name symbol within the module library.
+    // If it's not found, it's likely debug info is unavailable - try to set a
+    // breakpoint on <name>.expand.
+
+    const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
+    if (!kernel_sym)
+    {
+        std::string kernel_name_expanded(m_kernel_name.AsCString());
+        kernel_name_expanded.append(".expand");
+        kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
+    }
+
+    if (kernel_sym)
+    {
+        Address bp_addr = kernel_sym->GetAddress();
+        if (filter.AddressPasses(bp_addr))
+            m_breakpoint->AddLocation(bp_addr);
+    }
+
+    return Searcher::eCallbackReturnContinue;
+}
+
 void
 RenderScriptRuntime::Initialize()
 {
@@ -767,68 +809,24 @@ RenderScriptRuntime::DumpKernels(Stream
     strm.IndentLess();
 }
 
-void 
-RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error)
+void
+RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
 {
-    if (!name) 
+    if (!name)
     {
         error.SetErrorString("invalid kernel name");
         return;
     }
 
-    bool kernels_found = false;
-    ConstString kernel_name(name);
-    for (const auto &module : m_rsmodules)
-    {
-        for (const auto &kernel : module->m_kernels)
-        {
-            if (kernel.m_name == kernel_name)
-            {
-                //Attempt to set a breakpoint on this symbol, within the module library
-                //If it's not found, it's likely debug info is unavailable - set a
-                //breakpoint on <name>.expand and emit a warning.
-
-                const Symbol* kernel_sym = module->m_module->FindFirstSymbolWithNameAndType(kernel_name, eSymbolTypeCode);
-
-                if (!kernel_sym)
-                {
-                    std::string kernel_name_expanded(name);
-                    kernel_name_expanded.append(".expand");
-                    kernel_sym = module->m_module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
-
-                    if (kernel_sym)
-                    {
-                        strm.Printf("Kernel '%s' could not be found, but expansion exists. ", name); 
-                        strm.Printf("Breakpoint placed on expanded kernel. Have you compiled in debug mode?");
-                        strm.EOL();
-                    }
-                    else
-                    {
-                        error.SetErrorStringWithFormat("Could not locate symbols for loaded kernel '%s'.", name);
-                        return;
-                    }
-                }
-
-                addr_t bp_addr = kernel_sym->GetLoadAddress(&GetProcess()->GetTarget());
-                if (bp_addr == LLDB_INVALID_ADDRESS)
-                {
-                    error.SetErrorStringWithFormat("Could not locate load address for symbols of kernel '%s'.", name);
-                    return;
-                }
+    SearchFilterSP filter_sp(new SearchFilterForUnconstrainedSearches(target));
 
-                BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(bp_addr, false, false);
-                strm.Printf("Breakpoint %" PRIu64 ": kernel '%s' within script '%s'", (uint64_t)bp->GetID(), name, module->m_resname.c_str());
-                strm.EOL();
+    ConstString kernel_name(name);
+    BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, kernel_name));
 
-                kernels_found = true;
-            }
-        }
-    }
+    BreakpointSP bp = target->CreateBreakpoint(filter_sp, resolver_sp, false, false, false);
+    if (bp)
+        bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
 
-    if (!kernels_found)
-    {
-        error.SetErrorString("kernel name not found");
-    }
     return;
 }
 
@@ -1037,7 +1035,7 @@ class CommandObjectRenderScriptRuntimeKe
   public:
     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint",
-                              "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint",
+                              "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint <kernel_name>",
                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
     {
     }
@@ -1054,7 +1052,8 @@ class CommandObjectRenderScriptRuntimeKe
                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
 
             Error error;
-            runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0), error);
+            runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
+                                                   error, m_exe_ctx.GetTargetSP());
 
             if (error.Success())
             {

Modified: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h?rev=246842&r1=246841&r2=246842&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h Fri Sep  4 03:56:52 2015
@@ -22,6 +22,9 @@
 namespace lldb_private
 {
 
+namespace lldb_renderscript
+{
+
 typedef uint32_t RSSlot;
 class RSModuleDescriptor;
 struct RSGlobalDescriptor;
@@ -31,7 +34,53 @@ typedef std::shared_ptr<RSModuleDescript
 typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
 typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
 
+// Breakpoint Resolvers decide where a breakpoint is placed,
+// so having our own allows us to limit the search scope to RS kernel modules.
+// As well as check for .expand kernels as a fallback.
+class RSBreakpointResolver : public BreakpointResolver
+{
+  public:
+
+    RSBreakpointResolver(Breakpoint *bkpt, ConstString name):
+                         BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+                         m_kernel_name(name)
+    {
+    }
+
+    void
+    GetDescription(Stream *strm) override
+    {
+        if (strm)
+            strm->Printf("RenderScript kernel breakpoint for '%s'", m_kernel_name.AsCString());
+    }
 
+    void
+    Dump(Stream *s) const override
+    {
+    }
+
+    Searcher::CallbackReturn
+    SearchCallback(SearchFilter &filter,
+                   SymbolContext &context,
+                   Address *addr,
+                   bool containing) override;
+
+    Searcher::Depth
+    GetDepth() override
+    {
+        return Searcher::eDepthModule;
+    }
+
+    lldb::BreakpointResolverSP
+    CopyForBreakpoint(Breakpoint &breakpoint) override
+    {
+        lldb::BreakpointResolverSP ret_sp(new RSBreakpointResolver(&breakpoint, m_kernel_name));
+        return ret_sp;
+    }
+
+  protected:
+    ConstString m_kernel_name;
+};
 
 struct RSKernelDescriptor
 {
@@ -86,6 +135,8 @@ class RSModuleDescriptor
     std::string m_resname;
 };
 
+} // end lldb_renderscript namespace
+
 class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime
 {
   public:
@@ -147,7 +198,7 @@ class RenderScriptRuntime : public lldb_
 
     void DumpKernels(Stream &strm) const;
 
-    void AttemptBreakpointAtKernelName(Stream &strm, const char *name, Error &error);
+    void AttemptBreakpointAtKernelName(Stream &strm, const char *name, Error &error, lldb::TargetSP target);
 
     void Status(Stream &strm) const;
 
@@ -163,7 +214,7 @@ class RenderScriptRuntime : public lldb_
     
   protected:
     
-    void FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp);
+    void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
 
     void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
     
@@ -200,10 +251,10 @@ class RenderScriptRuntime : public lldb_
     lldb::ModuleSP m_libRS;
     lldb::ModuleSP m_libRSDriver;
     lldb::ModuleSP m_libRSCpuRef;
-    std::vector<RSModuleDescriptorSP> m_rsmodules;
+    std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules;
     std::vector<ScriptDetails> m_scripts;
 
-    std::map<lldb::addr_t, RSModuleDescriptorSP> m_scriptMappings;
+    std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
     std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
 
     bool m_initiated;




More information about the lldb-commits mailing list