Fixed a problem where expressions would attempt to

allocate memory in a process that did not support
expression execution.  Also improved detection of
whether or not a process can execute expressions.

llvm-svn: 140202
This commit is contained in:
Sean Callanan 2011-09-20 23:01:51 +00:00
parent 5227ea6028
commit 90539456a1
5 changed files with 67 additions and 29 deletions

View File

@ -2300,6 +2300,24 @@ public:
lldb::addr_t
AllocateMemory (size_t size, uint32_t permissions, Error &error);
//------------------------------------------------------------------
/// Determines whether executing JIT-compiled code in this process
/// is possible.
///
/// @return
/// True if execution of JIT code is possible; false otherwise.
//------------------------------------------------------------------
bool CanJIT ();
//------------------------------------------------------------------
/// Sets whether executing JIT-compiled code in this process
/// is possible.
///
/// @param[in] can_jit
/// True if execution of JIT code is possible; false otherwise.
//------------------------------------------------------------------
void SetCanJIT (bool can_jit);
//------------------------------------------------------------------
/// Actually deallocate memory in the process.
///
@ -2771,6 +2789,12 @@ protected:
LanguageRuntimeCollection m_language_runtimes;
std::auto_ptr<NextEventAction> m_next_event_action_ap;
enum {
eCanJITDontKnow= 0,
eCanJITYes,
eCanJITNo
} m_can_jit;
size_t
RemoveBreakpointOpcodesFromBuffer (lldb::addr_t addr, size_t size, uint8_t *buf) const;

View File

@ -496,8 +496,32 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr,
return err;
}
if (m_expr.NeedsValidation() && exe_ctx.process && exe_ctx.process->GetDynamicCheckers())
if (execution_policy != eExecutionPolicyNever &&
m_expr.NeedsValidation() &&
exe_ctx.process)
{
if (!exe_ctx.process->GetDynamicCheckers())
{
DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
StreamString install_errors;
if (!dynamic_checkers->Install(install_errors, exe_ctx))
{
if (install_errors.GetString().empty())
err.SetErrorString ("couldn't install checkers, unknown error");
else
err.SetErrorString (install_errors.GetString().c_str());
return err;
}
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
}
IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), function_name.c_str());
if (!ir_dynamic_checks.runOnModule(*module))

View File

@ -615,34 +615,8 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
}
}
if (exe_ctx.process == NULL)
if (exe_ctx.process == NULL || !exe_ctx.process->CanJIT())
execution_policy = eExecutionPolicyNever;
if (execution_policy != eExecutionPolicyNever && !exe_ctx.process->GetDynamicCheckers())
{
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Installing dynamic checkers ==");
DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
StreamString install_errors;
if (!dynamic_checkers->Install(install_errors, exe_ctx))
{
if (install_errors.GetString().empty())
error.SetErrorString ("couldn't install checkers, unknown error");
else
error.SetErrorString (install_errors.GetString().c_str());
result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
return eExecutionSetupError;
}
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
}
ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix));

View File

@ -78,7 +78,10 @@ DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
}
if (create)
{
process->SetCanJIT(false);
return new DynamicLoaderDarwinKernel (process);
}
return NULL;
}

View File

@ -601,7 +601,8 @@ Process::Process(Target &target, Listener &listener) :
m_memory_cache (*this),
m_allocated_memory_cache (*this),
m_attached_to_process (false),
m_next_event_action_ap()
m_next_event_action_ap(),
m_can_jit(eCanJITYes)
{
UpdateInstanceName();
@ -1956,6 +1957,18 @@ Process::AllocateMemory(size_t size, uint32_t permissions, Error &error)
#endif
}
bool
Process::CanJIT ()
{
return m_can_jit == eCanJITYes;
}
void
Process::SetCanJIT (bool can_jit)
{
m_can_jit = (can_jit ? eCanJITYes : eCanJITNo);
}
Error
Process::DeallocateMemory (addr_t ptr)
{