[Lldb-commits] [lldb] r258303 - [RenderScript] New command for viewing coordinate of current kernel invocation

Ewan Crawford via lldb-commits lldb-commits at lists.llvm.org
Wed Jan 20 04:03:30 PST 2016


Author: ewancrawford
Date: Wed Jan 20 06:03:29 2016
New Revision: 258303

URL: http://llvm.org/viewvc/llvm-project?rev=258303&view=rev
Log:
[RenderScript] New command for viewing coordinate of current kernel invocation

Patch adds command 'language renderscript kernel coordinate' for printing the kernel index in (x,y,z) format.
This is done by walking the call stack and looking for a function with suffix '.expand', as well as the frame variables containing the coordinate data. 

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=258303&r1=258302&r2=258303&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp Wed Jan 20 06:03:29 2016
@@ -390,6 +390,8 @@ const unsigned int RenderScriptRuntime::
     {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
 };
 
+const std::string RenderScriptRuntime::s_runtimeExpandSuffix(".expand");
+const std::array<const char *, 3> RenderScriptRuntime::s_runtimeCoordVars{"rsIndex", "p->current.y", "p->current.z"};
 //------------------------------------------------------------------
 // Static Functions
 //------------------------------------------------------------------
@@ -3071,6 +3073,79 @@ RenderScriptRuntime::GetFrameVarAsUnsign
     return true;
 }
 
+// Function attempts to find the current coordinate of a kernel invocation by investigating the
+// values of frame variables in the .expand function. These coordinates are returned via the coord
+// array reference parameter. Returns true if the coordinates could be found, and false otherwise.
+bool
+RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, Thread *thread_ptr)
+{
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+    if (!thread_ptr)
+    {
+        if (log)
+            log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+
+        return false;
+    }
+
+    // Walk the call stack looking for a function whose name has the suffix '.expand'
+    // and contains the variables we're looking for.
+    for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i)
+    {
+        if (!thread_ptr->SetSelectedFrameByIndex(i))
+            continue;
+
+        StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
+        if (!frame_sp)
+            continue;
+
+        // Find the function name
+        const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
+        const char *func_name_cstr = sym_ctx.GetFunctionName().AsCString();
+        if (!func_name_cstr)
+            continue;
+
+        if (log)
+            log->Printf("%s - Inspecting function '%s'", __FUNCTION__, func_name_cstr);
+
+        // Check if function name has .expand suffix
+        std::string func_name(func_name_cstr);
+        const int length_difference = func_name.length() - RenderScriptRuntime::s_runtimeExpandSuffix.length();
+        if (length_difference <= 0)
+            continue;
+
+        const int32_t has_expand_suffix = func_name.compare(length_difference,
+                                                            RenderScriptRuntime::s_runtimeExpandSuffix.length(),
+                                                            RenderScriptRuntime::s_runtimeExpandSuffix);
+
+        if (has_expand_suffix != 0)
+            continue;
+
+        if (log)
+            log->Printf("%s - Found .expand function '%s'", __FUNCTION__, func_name_cstr);
+
+        // Get values for variables in .expand frame that tell us the current kernel invocation
+        bool found_coord_variables = true;
+        assert(RenderScriptRuntime::s_runtimeCoordVars.size() == coord.size());
+
+        for (uint32_t i = 0; i < coord.size(); ++i)
+        {
+            uint64_t value = 0;
+            if (!GetFrameVarAsUnsigned(frame_sp, RenderScriptRuntime::s_runtimeCoordVars[i], value))
+            {
+                found_coord_variables = false;
+                break;
+            }
+            coord[i] = value;
+        }
+
+        if (found_coord_variables)
+            return true;
+    }
+    return false;
+}
+
 // Callback when a kernel breakpoint hits and we're looking for a specific coordinate.
 // Baton parameter contains a pointer to the target coordinate we want to break on.
 // Function then checks the .expand frame for the current coordinate and breaks to user if it matches.
@@ -3086,53 +3161,38 @@ RenderScriptRuntime::KernelBreakpointHit
     assert(baton && "Error: null baton in conditional kernel breakpoint callback");
 
     // Coordinate we want to stop on
-    const int* target_coord = static_cast<const int*>(baton);
+    const uint32_t *target_coord = static_cast<const uint32_t *>(baton);
 
     if (log)
-        log->Printf("RenderScriptRuntime::KernelBreakpointHit - Break ID %" PRIu64 ", target coord (%d, %d, %d)",
-                    break_id, target_coord[0], target_coord[1], target_coord[2]);
+        log->Printf("%s - Break ID %" PRIu64 ", (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", __FUNCTION__, break_id,
+                    target_coord[0], target_coord[1], target_coord[2]);
 
-    // Go up one stack frame to .expand kernel
+    // Select current thread
     ExecutionContext context(ctx->exe_ctx_ref);
-    ThreadSP thread_sp = context.GetThreadSP();
-    if (!thread_sp->SetSelectedFrameByIndex(1))
-    {
-        if (log)
-            log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't go up stack frame");
+    Thread *thread_ptr = context.GetThreadPtr();
+    assert(thread_ptr && "Null thread pointer");
 
-       return false;
-    }
-
-    StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
-    if (!frame_sp)
+    // Find current kernel invocation from .expand frame variables
+    RSCoordinate current_coord{}; // Zero initialise array
+    if (!GetKernelCoordinate(current_coord, thread_ptr))
     {
         if (log)
-            log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't select .expand stack frame");
+            log->Printf("%s - Error, couldn't select .expand stack frame", __FUNCTION__);
 
         return false;
     }
 
-    // Get values for variables in .expand frame that tell us the current kernel invocation
-    const char* coord_expressions[] = {"rsIndex", "p->current.y", "p->current.z"};
-    uint64_t current_coord[3] = {0, 0, 0};
-
-    for(int i = 0; i < 3; ++i)
-    {
-        if (!GetFrameVarAsUnsigned(frame_sp, coord_expressions[i], current_coord[i]))
-            return false;
-
-        if (log)
-            log->Printf("RenderScriptRuntime::KernelBreakpointHit, %s = %" PRIu64, coord_expressions[i], current_coord[i]);
-    }
+    if (log)
+        log->Printf("%s - (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0], current_coord[1],
+                    current_coord[2]);
 
     // Check if the current kernel invocation coordinate matches our target coordinate
-    if (current_coord[0] == static_cast<uint64_t>(target_coord[0]) &&
-        current_coord[1] == static_cast<uint64_t>(target_coord[1]) &&
-        current_coord[2] == static_cast<uint64_t>(target_coord[2]))
+    if (current_coord[0] == target_coord[0] && current_coord[1] == target_coord[1] &&
+        current_coord[2] == target_coord[2])
     {
         if (log)
-             log->Printf("RenderScriptRuntime::KernelBreakpointHit, BREAKING %" PRIu64 ", %" PRIu64 ", %" PRIu64,
-                         current_coord[0], current_coord[1], current_coord[2]);
+            log->Printf("%s, BREAKING (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0],
+                        current_coord[1], current_coord[2]);
 
         BreakpointSP breakpoint_sp = context.GetTargetPtr()->GetBreakpointByID(break_id);
         assert(breakpoint_sp != nullptr && "Error: Couldn't find breakpoint matching break id for callback");
@@ -3169,7 +3229,7 @@ RenderScriptRuntime::PlaceBreakpointOnKe
         strm.EOL();
 
         // Allocate memory for the baton, and copy over coordinate
-        int* baton = new int[3];
+        uint32_t *baton = new uint32_t[coords.size()];
         baton[0] = coords[0]; baton[1] = coords[1]; baton[2] = coords[2];
 
         // Create a callback that will be invoked everytime the breakpoint is hit.
@@ -3177,7 +3237,7 @@ RenderScriptRuntime::PlaceBreakpointOnKe
         bp->SetCallback(KernelBreakpointHit, baton, true);
 
         // Store a shared pointer to the baton, so the memory will eventually be cleaned up after destruction
-        m_conditional_breaks[bp->GetID()] = std::shared_ptr<int>(baton);
+        m_conditional_breaks[bp->GetID()] = std::shared_ptr<uint32_t>(baton);
     }
 
     if (bp)
@@ -3606,6 +3666,42 @@ public:
     }
 };
 
+class CommandObjectRenderScriptRuntimeKernelCoordinate : public CommandObjectParsed
+{
+public:
+    CommandObjectRenderScriptRuntimeKernelCoordinate(CommandInterpreter &interpreter)
+        : CommandObjectParsed(interpreter, "renderscript kernel coordinate",
+                              "Shows the (x,y,z) coordinate of the current kernel invocation.",
+                              "renderscript kernel coordinate",
+                              eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
+    {
+    }
+
+    ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default;
+
+    bool
+    DoExecute(Args &command, CommandReturnObject &result) override
+    {
+        RSCoordinate coord{}; // Zero initialize array
+        bool success = RenderScriptRuntime::GetKernelCoordinate(coord, m_exe_ctx.GetThreadPtr());
+        Stream &stream = result.GetOutputStream();
+
+        if (success)
+        {
+            stream.Printf("Coordinate: (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", coord[0], coord[1], coord[2]);
+            stream.EOL();
+            result.SetStatus(eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            stream.Printf("Error: Coordinate could not be found.");
+            stream.EOL();
+            result.SetStatus(eReturnStatusFailed);
+        }
+        return true;
+    }
+};
+
 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
 {
 public:
@@ -3629,6 +3725,7 @@ public:
     {
         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
+        LoadSubCommand("coordinate", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter)));
     }
 
     ~CommandObjectRenderScriptRuntimeKernel() override = default;

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=258303&r1=258302&r2=258303&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h Wed Jan 20 06:03:29 2016
@@ -36,6 +36,7 @@ struct RSKernelDescriptor;
 typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
 typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
 typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
+typedef std::array<uint32_t, 3> RSCoordinate;
 
 // Breakpoint Resolvers decide where a breakpoint is placed,
 // so having our own allows us to limit the search scope to RS kernel modules.
@@ -224,6 +225,9 @@ public:
 
     uint32_t GetPluginVersion() override;
 
+    static bool
+    GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, Thread *thread_ptr);
+
 protected:
     struct ScriptDetails;
     struct AllocationDetails;
@@ -279,7 +283,7 @@ protected:
 
     std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
     std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
-    std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks;
+    std::map<lldb::user_id_t, std::shared_ptr<uint32_t>> m_conditional_breaks;
 
     lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API
 
@@ -288,6 +292,8 @@ protected:
     bool m_breakAllKernels;
     static const HookDefn s_runtimeHookDefns[];
     static const size_t s_runtimeHookCount;
+    static const std::string s_runtimeExpandSuffix;
+    static const std::array<const char *, 3> s_runtimeCoordVars;
 
 private:
     RenderScriptRuntime(Process *process); // Call CreateInstance instead.




More information about the lldb-commits mailing list