lldb::ThreadPlanSP ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t args_addr, const EvaluateExpressionOptions &options, Stream &errors) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); if (log) log->Printf("-- [ClangFunction::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str()); // FIXME: Use the errors Stream for better error reporting. Thread *thread = exe_ctx.GetThreadPtr(); if (thread == NULL) { errors.Printf("Can't call a function without a valid thread."); return NULL; } // Okay, now run the function: Address wrapper_address (m_jit_start_addr); lldb::addr_t args = { args_addr }; lldb::ThreadPlanSP new_plan_sp (new ThreadPlanCallFunction (*thread, wrapper_address, CompilerType(), args, options)); new_plan_sp->SetIsMasterPlan(true); new_plan_sp->SetOkayToDiscard (false); return new_plan_sp; }
SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan) { SBError sb_error; Process *process = exe_ctx.GetProcessPtr(); if (!process) { sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); return sb_error; } Thread *thread = exe_ctx.GetThreadPtr(); if (!thread) { sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); return sb_error; } // User level plans should be Master Plans so they can be interrupted, other // plans executed, and // then a "continue" will resume the plan. if (new_plan != NULL) { new_plan->SetIsMasterPlan(true); new_plan->SetOkayToDiscard(false); } // Why do we need to set the current thread by ID here??? process->GetThreadList().SetSelectedThreadByID(thread->GetID()); if (process->GetTarget().GetDebugger().GetAsyncExecution()) sb_error.ref() = process->Resume(); else sb_error.ref() = process->ResumeSynchronous(NULL); return sb_error; }