[Lldb-commits] [lldb] r285902 - [Renderscript] Add commands for scriptgroup interaction.

Aidan Dodds via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 3 06:20:38 PDT 2016


Author: aidandodds
Date: Thu Nov  3 08:20:37 2016
New Revision: 285902

URL: http://llvm.org/viewvc/llvm-project?rev=285902&view=rev
Log:
[Renderscript] Add commands for scriptgroup interaction.

This commit hooks the nofity function that signals script group
compilation.  By tracking scriptgroups compiled at runtine, users
are able to place breakpoints by script group name.  Breakpoints
will be placed on the kernels forming the group.


Added:
    lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
Modified:
    lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
    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/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt?rev=285902&r1=285901&r2=285902&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt Thu Nov  3 08:20:37 2016
@@ -2,6 +2,7 @@ add_lldb_library(lldbPluginRenderScriptR
   RenderScriptRuntime.cpp
   RenderScriptExpressionOpts.cpp
   RenderScriptx86ABIFixups.cpp
+  RenderScriptScriptGroup.cpp
   )
 
 if(NOT LLDB_BUILT_STANDALONE)

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=285902&r1=285901&r2=285902&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp Thu Nov  3 08:20:37 2016
@@ -14,6 +14,7 @@
 
 // Project includes
 #include "RenderScriptRuntime.h"
+#include "RenderScriptScriptGroup.h"
 
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
 #include "lldb/Core/ConstString.h"
@@ -31,11 +32,13 @@
 #include "lldb/Interpreter/CommandObjectMultiword.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/Options.h"
+#include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 
@@ -475,6 +478,26 @@ bool ParseCoordinate(llvm::StringRef coo
   return get_index(0, coord.x) && get_index(1, coord.y) &&
          get_index(2, coord.z);
 }
+
+bool SkipPrologue(lldb::ModuleSP &module, Address &addr) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+  SymbolContext sc;
+  uint32_t resolved_flags =
+      module->ResolveSymbolContextForAddress(addr, eSymbolContextFunction, sc);
+  if (resolved_flags & eSymbolContextFunction) {
+    if (sc.function) {
+      const uint32_t offset = sc.function->GetPrologueByteSize();
+      ConstString name = sc.GetFunctionName();
+      if (offset)
+        addr.Slide(offset);
+      if (log)
+        log->Printf("%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
+                    name.AsCString(), offset);
+    }
+    return true;
+  } else
+    return false;
+}
 } // anonymous namespace
 
 // The ScriptDetails class collects data associated with a single script
@@ -872,6 +895,80 @@ RSReduceBreakpointResolver::SearchCallba
   return eCallbackReturnContinue;
 }
 
+Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
+    SearchFilter &filter, SymbolContext &context, Address *addr,
+    bool containing) {
+
+  if (!m_breakpoint)
+    return eCallbackReturnContinue;
+
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  ModuleSP &module = context.module_sp;
+
+  if (!module || !IsRenderScriptScriptModule(module))
+    return Searcher::eCallbackReturnContinue;
+
+  std::vector<std::string> names;
+  m_breakpoint->GetNames(names);
+  if (names.empty())
+    return eCallbackReturnContinue;
+
+  for (auto &name : names) {
+    const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name));
+    if (!sg) {
+      if (log)
+        log->Printf("%s: could not find script group for %s", __FUNCTION__,
+                    name.c_str());
+      continue;
+    }
+
+    if (log)
+      log->Printf("%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
+
+    for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) {
+      if (log) {
+        log->Printf("%s: Adding breakpoint for %s", __FUNCTION__,
+                    k.m_name.AsCString());
+        log->Printf("%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
+      }
+
+      const lldb_private::Symbol *sym =
+          module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode);
+      if (!sym) {
+        if (log)
+          log->Printf("%s: Unable to find symbol for %s", __FUNCTION__,
+                      k.m_name.AsCString());
+        continue;
+      }
+
+      if (log) {
+        log->Printf("%s: Found symbol name is %s", __FUNCTION__,
+                    sym->GetName().AsCString());
+      }
+
+      auto address = sym->GetAddress();
+      if (!SkipPrologue(module, address)) {
+        if (log)
+          log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+      }
+
+      bool new_bp;
+      m_breakpoint->AddLocation(address, &new_bp);
+
+      if (log)
+        log->Printf("%s: Placed %sbreakpoint on %s", __FUNCTION__,
+                    new_bp ? "new " : "", k.m_name.AsCString());
+
+      // exit after placing the first breakpoint if we do not intend to stop
+      // on all kernels making up this script group
+      if (!m_stop_on_all)
+        break;
+    }
+  }
+
+  return eCallbackReturnContinue;
+}
+
 void RenderScriptRuntime::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 "RenderScript language support", CreateInstance,
@@ -1006,7 +1103,15 @@ const RenderScriptRuntime::HookDefn Rend
          "10AllocationE",
          0, RenderScriptRuntime::eModuleKindDriver,
          &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy},
-};
+
+        // renderscript script groups
+        {"rsdDebugHintScriptGroup2", "_ZN7android12renderscript21debugHintScrip"
+                                     "tGroup2EPKcjPKPFvPK24RsExpandKernelDriver"
+                                     "InfojjjEj",
+         "_ZN7android12renderscript21debugHintScriptGroup2EPKcjPKPFvPK24RsExpan"
+         "dKernelDriverInfojjjEj",
+         0, RenderScriptRuntime::eModuleKindImpl,
+         &lldb_private::RenderScriptRuntime::CaptureDebugHintScriptGroup2}};
 
 const size_t RenderScriptRuntime::s_runtimeHookCount =
     sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]);
@@ -1039,6 +1144,154 @@ void RenderScriptRuntime::HookCallback(R
   }
 }
 
+void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
+    RuntimeHook *hook_info, ExecutionContext &context) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+  enum {
+    eGroupName = 0,
+    eGroupNameSize,
+    eKernel,
+    eKernelCount,
+  };
+
+  std::array<ArgItem, 4> args{{
+      {ArgItem::ePointer, 0}, // const char         *groupName
+      {ArgItem::eInt32, 0},   // const uint32_t      groupNameSize
+      {ArgItem::ePointer, 0}, // const ExpandFuncTy *kernel
+      {ArgItem::eInt32, 0},   // const uint32_t      kernelCount
+  }};
+
+  if (!GetArgs(context, args.data(), args.size())) {
+    if (log)
+      log->Printf("%s - Error while reading the function parameters",
+                  __FUNCTION__);
+    return;
+  } else if (log) {
+    log->Printf("%s - groupName    : 0x%" PRIx64, __FUNCTION__,
+                addr_t(args[eGroupName]));
+    log->Printf("%s - groupNameSize: %" PRIu64, __FUNCTION__,
+                uint64_t(args[eGroupNameSize]));
+    log->Printf("%s - kernel       : 0x%" PRIx64, __FUNCTION__,
+                addr_t(args[eKernel]));
+    log->Printf("%s - kernelCount  : %" PRIu64, __FUNCTION__,
+                uint64_t(args[eKernelCount]));
+  }
+
+  // parse script group name
+  ConstString group_name;
+  {
+    Error err;
+    const uint64_t len = uint64_t(args[eGroupNameSize]);
+    std::unique_ptr<char[]> buffer(new char[uint32_t(len + 1)]);
+    m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err);
+    buffer.get()[len] = '\0';
+    if (!err.Success()) {
+      if (log)
+        log->Printf("Error reading scriptgroup name from target");
+      return;
+    } else {
+      if (log)
+        log->Printf("Extracted scriptgroup name %s", buffer.get());
+    }
+    // write back the script group name
+    group_name.SetCString(buffer.get());
+  }
+
+  // create or access existing script group
+  RSScriptGroupDescriptorSP group;
+  {
+    // search for existing script group
+    for (auto sg : m_scriptGroups) {
+      if (sg->m_name == group_name) {
+        group = sg;
+        break;
+      }
+    }
+    if (!group) {
+      group.reset(new RSScriptGroupDescriptor);
+      group->m_name = group_name;
+      m_scriptGroups.push_back(group);
+    } else {
+      // already have this script group
+      if (log)
+        log->Printf("Attempt to add duplicate script group %s",
+                    group_name.AsCString());
+      return;
+    }
+  }
+  assert(group);
+
+  const uint32_t target_ptr_size = m_process->GetAddressByteSize();
+  std::vector<addr_t> kernels;
+  // parse kernel addresses in script group
+  for (uint64_t i = 0; i < uint64_t(args[eKernelCount]); ++i) {
+    RSScriptGroupDescriptor::Kernel kernel;
+    // extract script group kernel addresses from the target
+    const addr_t ptr_addr = addr_t(args[eKernel]) + i * target_ptr_size;
+    uint64_t kernel_addr = 0;
+    Error err;
+    size_t read =
+        m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err);
+    if (!err.Success() || read != target_ptr_size) {
+      if (log)
+        log->Printf("Error parsing kernel address %" PRIu64 " in script group",
+                    i);
+      return;
+    }
+    if (log)
+      log->Printf("Extracted scriptgroup kernel address - 0x%" PRIx64,
+                  kernel_addr);
+    kernel.m_addr = kernel_addr;
+
+    // try to resolve the associated kernel name
+    if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) {
+      if (log)
+        log->Printf("Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
+                    kernel_addr);
+      return;
+    }
+
+    // try to find the non '.expand' function
+    {
+      const llvm::StringRef expand(".expand");
+      const llvm::StringRef name_ref = kernel.m_name.GetStringRef();
+      if (name_ref.endswith(expand)) {
+        const ConstString base_kernel(name_ref.drop_back(expand.size()));
+        // verify this function is a valid kernel
+        if (IsKnownKernel(base_kernel)) {
+          kernel.m_name = base_kernel;
+          if (log)
+            log->Printf("%s - found non expand version '%s'", __FUNCTION__,
+                        base_kernel.GetCString());
+        }
+      }
+    }
+    // add to a list of script group kernels we know about
+    group->m_kernels.push_back(kernel);
+  }
+
+  // Resolve any pending scriptgroup breakpoints
+  {
+    Target &target = m_process->GetTarget();
+    const BreakpointList &list = target.GetBreakpointList();
+    const size_t num_breakpoints = list.GetSize();
+    if (log)
+      log->Printf("Resolving %zu breakpoints", num_breakpoints);
+    for (size_t i = 0; i < num_breakpoints; ++i) {
+      const BreakpointSP bp = list.GetBreakpointAtIndex(i);
+      if (bp) {
+        if (bp->MatchesName(group_name.AsCString())) {
+          if (log)
+            log->Printf("Found breakpoint with name %s",
+                        group_name.AsCString());
+          bp->ResolveBreakpoint();
+        }
+      }
+    }
+  }
+}
+
 void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
     RuntimeHook *hook, ExecutionContext &exe_ctx) {
   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
@@ -1332,7 +1585,7 @@ void RenderScriptRuntime::LoadRuntimeHoo
   }
 
   Target &target = GetProcess()->GetTarget();
-  llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
+  const llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
 
   if (machine != llvm::Triple::ArchType::x86 &&
       machine != llvm::Triple::ArchType::arm &&
@@ -1345,7 +1598,11 @@ void RenderScriptRuntime::LoadRuntimeHoo
     return;
   }
 
-  uint32_t target_ptr_size = target.GetArchitecture().GetAddressByteSize();
+  const uint32_t target_ptr_size =
+      target.GetArchitecture().GetAddressByteSize();
+
+  std::array<bool, s_runtimeHookCount> hook_placed;
+  hook_placed.fill(false);
 
   for (size_t idx = 0; idx < s_runtimeHookCount; idx++) {
     const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
@@ -1393,6 +1650,20 @@ void RenderScriptRuntime::LoadRuntimeHoo
                   module->GetFileSpec().GetFilename().AsCString(),
                   (uint64_t)hook_defn->version, (uint64_t)addr);
     }
+    hook_placed[idx] = true;
+  }
+
+  // log any unhooked function
+  if (log) {
+    for (size_t i = 0; i < hook_placed.size(); ++i) {
+      if (hook_placed[i])
+        continue;
+      const HookDefn &hook_defn = s_runtimeHookDefns[i];
+      if (hook_defn.kind != kind)
+        continue;
+      log->Printf("%s - function %s was not hooked", __FUNCTION__,
+                  hook_defn.name);
+    }
   }
 }
 
@@ -2594,7 +2865,10 @@ bool RenderScriptRuntime::LoadModule(con
       break;
     }
     case eModuleKindImpl: {
-      m_libRSCpuRef = module_sp;
+      if (!m_libRSCpuRef) {
+        m_libRSCpuRef = module_sp;
+        LoadRuntimeHooks(m_libRSCpuRef, RenderScriptRuntime::eModuleKindImpl);
+      }
       break;
     }
     case eModuleKindLibRS: {
@@ -3535,6 +3809,45 @@ bool RenderScriptRuntime::PlaceBreakpoin
   return true;
 }
 
+BreakpointSP
+RenderScriptRuntime::CreateScriptGroupBreakpoint(const ConstString &name,
+                                                 bool stop_on_all) {
+  Log *log(
+      GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+
+  if (!m_filtersp) {
+    if (log)
+      log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+    return nullptr;
+  }
+
+  BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
+      nullptr, name, m_scriptGroups, stop_on_all));
+  BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+      m_filtersp, resolver_sp, false, false, false);
+  // Give RS breakpoints a specific name, so the user can manipulate them as a
+  // group.
+  Error err;
+  if (!bp->AddName(name.AsCString(), err))
+    if (log)
+      log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+                  err.AsCString());
+  // ask the breakpoint to resolve itself
+  bp->ResolveBreakpoint();
+  return bp;
+}
+
+bool RenderScriptRuntime::PlaceBreakpointOnScriptGroup(TargetSP target,
+                                                       Stream &strm,
+                                                       const ConstString &name,
+                                                       bool multi) {
+  InitSearchFilter(target);
+  BreakpointSP bp = CreateScriptGroupBreakpoint(name, multi);
+  if (bp)
+    bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
+  return bool(bp);
+}
+
 bool RenderScriptRuntime::PlaceBreakpointOnReduction(TargetSP target,
                                                      Stream &messages,
                                                      const char *reduce_name,
@@ -3617,6 +3930,32 @@ RenderScriptRuntime::CreateAllocation(ad
   return m_allocations.back().get();
 }
 
+bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
+                                            ConstString &name) {
+  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+
+  Target &target = GetProcess()->GetTarget();
+  Address resolved;
+  // RenderScript module
+  if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) {
+    if (log)
+      log->Printf("%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
+                  __FUNCTION__, kernel_addr);
+    return false;
+  }
+
+  Symbol *sym = resolved.CalculateSymbolContextSymbol();
+  if (!sym)
+    return false;
+
+  name = sym->GetName();
+  assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule()));
+  if (log)
+    log->Printf("%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
+                kernel_addr, name.GetCString());
+  return true;
+}
+
 void RSModuleDescriptor::Dump(Stream &strm) const {
   int indent = strm.GetIndentLevel();
 
@@ -4636,6 +4975,8 @@ public:
         "allocation",
         CommandObjectSP(
             new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
+    LoadSubCommand("scriptgroup",
+                   NewCommandObjectRenderScriptScriptGroup(interpreter));
     LoadSubCommand(
         "reduction",
         CommandObjectSP(

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=285902&r1=285901&r2=285902&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h Thu Nov  3 08:20:37 2016
@@ -36,10 +36,13 @@ class RSModuleDescriptor;
 struct RSGlobalDescriptor;
 struct RSKernelDescriptor;
 struct RSReductionDescriptor;
+struct RSScriptGroupDescriptor;
 
 typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
 typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
 typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
+typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP;
+
 struct RSCoordinate {
   uint32_t x, y, z;
 
@@ -227,6 +230,61 @@ public:
   std::string m_resname;
 };
 
+struct RSScriptGroupDescriptor {
+  struct Kernel {
+    ConstString m_name;
+    lldb::addr_t m_addr;
+  };
+  ConstString m_name;
+  std::vector<Kernel> m_kernels;
+};
+
+typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList;
+
+class RSScriptGroupBreakpointResolver : public BreakpointResolver {
+public:
+  RSScriptGroupBreakpointResolver(Breakpoint *bp, const ConstString &name,
+                                  const RSScriptGroupList &groups,
+                                  bool stop_on_all)
+      : BreakpointResolver(bp, BreakpointResolver::NameResolver),
+        m_group_name(name), m_script_groups(groups),
+        m_stop_on_all(stop_on_all) {}
+
+  void GetDescription(Stream *strm) override {
+    if (strm)
+      strm->Printf("RenderScript ScriptGroup breakpoint for '%s'",
+                   m_group_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 RSScriptGroupBreakpointResolver(
+        &breakpoint, m_group_name, m_script_groups, m_stop_on_all));
+    return ret_sp;
+  }
+
+protected:
+  const RSScriptGroupDescriptorSP
+  FindScriptGroup(const ConstString &name) const {
+    for (auto sg : m_script_groups) {
+      if (ConstString::Compare(sg->m_name, name) == 0)
+        return sg;
+    }
+    return RSScriptGroupDescriptorSP();
+  }
+
+  ConstString m_group_name;
+  const RSScriptGroupList &m_script_groups;
+  bool m_stop_on_all;
+};
 } // namespace lldb_renderscript
 
 class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime {
@@ -304,6 +362,9 @@ public:
       const lldb_renderscript::RSCoordinate *coords = nullptr,
       int kernel_types = ~(0));
 
+  bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm,
+                                    const ConstString &name, bool stop_on_all);
+
   void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
 
   void Status(Stream &strm) const;
@@ -320,6 +381,18 @@ public:
 
   void Initiate();
 
+  const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const {
+    return m_scriptGroups;
+  };
+
+  bool IsKnownKernel(const ConstString &name) {
+    for (const auto &module : m_rsmodules)
+      for (const auto &kernel : module->m_kernels)
+        if (kernel.m_name == name)
+          return true;
+    return false;
+  }
+
   //------------------------------------------------------------------
   // PluginInterface protocol
   //------------------------------------------------------------------
@@ -330,11 +403,15 @@ public:
   static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord,
                                   Thread *thread_ptr);
 
+  bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name);
+
 protected:
   struct ScriptDetails;
   struct AllocationDetails;
   struct Element;
 
+  lldb_renderscript::RSScriptGroupList m_scriptGroups;
+
   void InitSearchFilter(lldb::TargetSP target) {
     if (!m_filtersp)
       m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
@@ -349,6 +426,9 @@ protected:
   bool EvalRSExpression(const char *expression, StackFrame *frame_ptr,
                         uint64_t *result);
 
+  lldb::BreakpointSP CreateScriptGroupBreakpoint(const ConstString &name,
+                                                 bool multi);
+
   lldb::BreakpointSP CreateKernelBreakpoint(const ConstString &name);
 
   lldb::BreakpointSP CreateReductionBreakpoint(const ConstString &name,
@@ -416,6 +496,10 @@ private:
 
   void HookCallback(RuntimeHook *hook_info, ExecutionContext &context);
 
+  // Callback function when 'debugHintScriptGroup2' executes on the target.
+  void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info,
+                                    ExecutionContext &context);
+
   void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);
 
   void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);

Added: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp?rev=285902&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp (added)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp Thu Nov  3 08:20:37 2016
@@ -0,0 +1,162 @@
+//===-- RenderScriptScriptGroup.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "RenderScriptRuntime.h"
+#include "RenderScriptScriptGroup.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_renderscript;
+
+class CommandObjectRenderScriptScriptGroupBreakpointSet
+    : public CommandObjectParsed {
+public:
+  CommandObjectRenderScriptScriptGroupBreakpointSet(
+      CommandInterpreter &interpreter)
+      : CommandObjectParsed(
+            interpreter, "renderscript scriptgroup breakpoint set",
+            "Place a breakpoint on all kernels forming a script group.",
+            "renderscript scriptgroup breakpoint set <group_name>",
+            eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
+
+  ~CommandObjectRenderScriptScriptGroupBreakpointSet() override = default;
+
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    Stream &stream = result.GetOutputStream();
+    RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+        m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+            eLanguageTypeExtRenderScript));
+    assert(runtime);
+    auto &target = m_exe_ctx.GetTargetSP();
+    bool stop_on_all = false;
+    const llvm::StringRef long_stop_all("--stop-on-all"), short_stop_all("-a");
+    std::vector<ConstString> sites;
+    sites.reserve(command.GetArgumentCount());
+    for (size_t i = 0; i < command.GetArgumentCount(); ++i) {
+      const auto arg = command.GetArgumentAtIndex(i);
+      if (long_stop_all == arg || short_stop_all == arg)
+        stop_on_all = true;
+      else
+        sites.push_back(ConstString(arg));
+    }
+    for (const auto &name : sites) {
+      runtime->PlaceBreakpointOnScriptGroup(target, stream, name, stop_on_all);
+    }
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    return true;
+  }
+};
+
+class CommandObjectRenderScriptScriptGroupBreakpoint
+    : public CommandObjectMultiword {
+public:
+  CommandObjectRenderScriptScriptGroupBreakpoint(
+      CommandInterpreter &interpreter)
+      : CommandObjectMultiword(
+            interpreter, "renderscript scriptgroup breakpoint",
+            "Renderscript scriptgroup breakpoint interaction.",
+            "renderscript scriptgroup breakpoint set [--stop-on-all/-a]"
+            "<scriptgroup name> ...",
+            eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
+    LoadSubCommand(
+        "set",
+        CommandObjectSP(new CommandObjectRenderScriptScriptGroupBreakpointSet(
+            interpreter)));
+  }
+
+  ~CommandObjectRenderScriptScriptGroupBreakpoint() override = default;
+};
+
+class CommandObjectRenderScriptScriptGroupList : public CommandObjectParsed {
+public:
+  CommandObjectRenderScriptScriptGroupList(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "renderscript scriptgroup list",
+                            "List all currently discovered script groups.",
+                            "renderscript scriptgroup list",
+                            eCommandRequiresProcess |
+                                eCommandProcessMustBeLaunched) {}
+
+  ~CommandObjectRenderScriptScriptGroupList() override = default;
+
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    Stream &stream = result.GetOutputStream();
+    RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+        m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+            eLanguageTypeExtRenderScript));
+    assert(runtime);
+    const RSScriptGroupList &groups = runtime->GetScriptGroups();
+    // print script group count
+    stream.Printf("%" PRIu64 " script %s", uint64_t(groups.size()),
+                  (groups.size() == 1) ? "group" : "groups");
+    stream.EOL();
+    // print script group details
+    stream.IndentMore();
+    for (const RSScriptGroupDescriptorSP &g : groups) {
+      if (g) {
+        stream.Indent();
+        // script group name
+        stream.Printf("%s", g->m_name.AsCString());
+        stream.EOL();
+        // print out the kernels
+        stream.IndentMore();
+        for (const auto &k : g->m_kernels) {
+          stream.Indent();
+          stream.Printf(". %s", k.m_name.AsCString());
+          stream.EOL();
+        }
+        stream.IndentLess();
+      }
+    }
+    stream.IndentLess();
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    return true;
+  }
+};
+
+class CommandObjectRenderScriptScriptGroup : public CommandObjectMultiword {
+public:
+  CommandObjectRenderScriptScriptGroup(CommandInterpreter &interpreter)
+      : CommandObjectMultiword(interpreter, "renderscript scriptgroup",
+                               "Command set for interacting with scriptgroups.",
+                               nullptr, eCommandRequiresProcess |
+                                            eCommandProcessMustBeLaunched) {
+    LoadSubCommand(
+        "breakpoint",
+        CommandObjectSP(
+            new CommandObjectRenderScriptScriptGroupBreakpoint(interpreter)));
+    LoadSubCommand(
+        "list", CommandObjectSP(
+                    new CommandObjectRenderScriptScriptGroupList(interpreter)));
+  }
+
+  ~CommandObjectRenderScriptScriptGroup() override = default;
+};
+
+lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup(
+    lldb_private::CommandInterpreter &interpreter) {
+  return CommandObjectSP(new CommandObjectRenderScriptScriptGroup(interpreter));
+}

Added: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h?rev=285902&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h (added)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h Thu Nov  3 08:20:37 2016
@@ -0,0 +1,18 @@
+//===-- RenderScriptScriptGroup.h -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RenderScriptScriptGroup_h_
+#define liblldb_RenderScriptScriptGroup_h_
+
+#include "lldb/Interpreter/CommandInterpreter.h"
+
+lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup(
+    lldb_private::CommandInterpreter &interpreter);
+
+#endif // liblldb_RenderScriptScriptGroup_h_




More information about the lldb-commits mailing list