Skip to content

Commit

Permalink
New RenderScript command to break on all kernels
Browse files Browse the repository at this point in the history
Patch adds a command to RenderScript plugin allowing users to automatically set breakpoints on every RS kernel.

Command syntax is 'language renderscript kernel breakpoint all <enable/disable>.'
Enable sets breakpoints on all currently loaded kernels, and any kernels which will be loaded in future.
Disable results in breakpoints no longer being set on loaded kernels, but doesn't affect existing breakpoints.

Current command 'language renderscript kernel breakpoint' is changed to 'language renderscript kernel breakpoint set'

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

llvm-svn: 247262
  • Loading branch information
EwanC committed Sep 10, 2015
1 parent 11d4d64 commit 7dc7771
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 10 deletions.
Expand Up @@ -538,7 +538,14 @@ RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
for (const auto &rs_module : m_rsmodules)
{
if (rs_module->m_module == module_sp)
{
// Check if the user has enabled automatically breaking on
// all RS kernels.
if (m_breakAllKernels)
BreakOnModuleKernels(rs_module);

return false;
}
}
bool module_loaded = false;
switch (GetModuleKind(module_sp))
Expand Down Expand Up @@ -809,6 +816,73 @@ RenderScriptRuntime::DumpKernels(Stream &strm) const
strm.IndentLess();
}

// Set breakpoints on every kernel found in RS module
void
RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
{
for (const auto &kernel : rsmodule_sp->m_kernels)
{
// Don't set breakpoint on 'root' kernel
if (strcmp(kernel.m_name.AsCString(), "root") == 0)
continue;

CreateKernelBreakpoint(kernel.m_name);
}
}

// Method is internally called by the 'kernel breakpoint all' command to
// enable or disable breaking on all kernels.
//
// When do_break is true we want to enable this functionality.
// When do_break is false we want to disable it.
void
RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
{
Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));

InitSearchFilter(target);

// Set breakpoints on all the kernels
if (do_break && !m_breakAllKernels)
{
m_breakAllKernels = true;

for (const auto &module : m_rsmodules)
BreakOnModuleKernels(module);

if (log)
log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
"- breakpoints set on all currently loaded kernels");
}
else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
{
m_breakAllKernels = false;

if (log)
log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
}
}

// Given the name of a kernel this function creates a breakpoint using our
// own breakpoint resolver, and returns the Breakpoint shared pointer.
BreakpointSP
RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
{
Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));

if (!m_filtersp)
{
if (log)
log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
return nullptr;
}

BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);

return bp;
}

void
RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
{
Expand All @@ -818,12 +892,10 @@ RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* nam
return;
}

SearchFilterSP filter_sp(new SearchFilterForUnconstrainedSearches(target));
InitSearchFilter(target);

ConstString kernel_name(name);
BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, kernel_name));

BreakpointSP bp = target->CreateBreakpoint(filter_sp, resolver_sp, false, false, false);
BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
if (bp)
bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);

Expand Down Expand Up @@ -1029,18 +1101,18 @@ class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
}
};

class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectParsed
class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
{
private:
public:
CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel breakpoint",
"Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint <kernel_name>",
CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
"Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
{
}

~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}

bool
DoExecute(Args &command, CommandReturnObject &result)
Expand Down Expand Up @@ -1072,6 +1144,77 @@ class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectPar
}
};

class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
{
private:
public:
CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
"Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
"Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
"but does not remove currently set breakpoints.",
"renderscript kernel breakpoint all <enable/disable>",
eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
{
}

~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}

bool
DoExecute(Args &command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
if (argc != 1)
{
result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}

RenderScriptRuntime *runtime =
static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));

bool do_break = false;
const char* argument = command.GetArgumentAtIndex(0);
if (strcmp(argument, "enable") == 0)
{
do_break = true;
result.AppendMessage("Breakpoints will be set on all kernels.");
}
else if (strcmp(argument, "disable") == 0)
{
do_break = false;
result.AppendMessage("Breakpoints will not be set on any new kernels.");
}
else
{
result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
result.SetStatus(eReturnStatusFailed);
return false;
}

runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());

result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
};

class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
{
private:
public:
CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
: CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
nullptr)
{
LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
}

~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
};

class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
{
private:
Expand Down Expand Up @@ -1172,7 +1315,8 @@ RenderScriptRuntime::Initiate()
}

RenderScriptRuntime::RenderScriptRuntime(Process *process)
: lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false)
: lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
m_breakAllKernels(false)
{
ModulesDidLoad(process->GetTarget().GetImages());
}
Expand Down
Expand Up @@ -200,6 +200,8 @@ class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime

void AttemptBreakpointAtKernelName(Stream &strm, const char *name, Error &error, lldb::TargetSP target);

void SetBreakAllKernels(bool do_break, lldb::TargetSP target);

void Status(Stream &strm) const;

virtual size_t GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates) {
Expand All @@ -213,10 +215,20 @@ class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime
void Initiate();

protected:

void InitSearchFilter(lldb::TargetSP target)
{
if (!m_filtersp)
m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
}

void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);

void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);

lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name);

void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);

struct RuntimeHook;
typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this!
Expand Down Expand Up @@ -257,8 +269,11 @@ class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime
std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;

lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API

bool m_initiated;
bool m_debuggerPresentFlagged;
bool m_breakAllKernels;
static const HookDefn s_runtimeHookDefns[];
static const size_t s_runtimeHookCount;

Expand Down

0 comments on commit 7dc7771

Please sign in to comment.