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; }
StackFrame* lldb_private::formatters::GetViableFrame (ExecutionContext exe_ctx) { StackFrame* frame = exe_ctx.GetFramePtr(); if (frame) return frame; Process* process = exe_ctx.GetProcessPtr(); if (!process) return nullptr; ThreadSP thread_sp(process->GetThreadList().GetSelectedThread()); if (thread_sp) return thread_sp->GetSelectedFrame().get(); return nullptr; }
size_t Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source) { ExecutionContext exe_ctx (shared_from_this()); Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); size_t num_frames_shown = 0; strm.Indent(); bool is_selected = false; if (process) { if (process->GetThreadList().GetSelectedThread().get() == this) is_selected = true; } strm.Printf("%c ", is_selected ? '*' : ' '); if (target && target->GetDebugger().GetUseExternalEditor()) { StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); if (frame_sp) { SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry)); if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); } } } DumpUsingSettingsFormat (strm, start_frame); if (num_frames > 0) { strm.IndentMore(); const bool show_frame_info = true; strm.IndentMore (); num_frames_shown = GetStackFrameList ()->GetStatus (strm, start_frame, num_frames, show_frame_info, num_frames_with_source); strm.IndentLess(); strm.IndentLess(); } return num_frames_shown; }
bool AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionContextScope *exe_scope) { if (!m_read_objc_library) return false; ExecutionContext exe_ctx; exe_scope->CalculateExecutionContext(exe_ctx); Process *process = exe_ctx.GetProcessPtr(); if (!process) return false; // We need other parts of the exe_ctx, but the processes have to match. assert (m_process == process); // Get the function address for the print function. const Address *function_address = GetPrintForDebuggerAddr(); if (!function_address) return false; Target *target = exe_ctx.GetTargetPtr(); ClangASTType clang_type = value.GetClangType(); if (clang_type) { if (!clang_type.IsObjCObjectPointerType()) { strm.Printf ("Value doesn't point to an ObjC object.\n"); return false; } } else { // If it is not a pointer, see if we can make it into a pointer. ClangASTContext *ast_context = target->GetScratchClangASTContext(); ClangASTType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID); if (!opaque_type) opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr); value.SetClangType (opaque_type); } ValueList arg_value_list; arg_value_list.PushValue(value); // This is the return value: ClangASTContext *ast_context = target->GetScratchClangASTContext(); ClangASTType return_clang_type = ast_context->GetCStringType(true); Value ret; // ret.SetContext(Value::eContextTypeClangType, return_clang_type); ret.SetClangType (return_clang_type); if (exe_ctx.GetFramePtr() == NULL) { Thread *thread = exe_ctx.GetThreadPtr(); if (thread == NULL) { exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread()); thread = exe_ctx.GetThreadPtr(); } if (thread) { exe_ctx.SetFrameSP(thread->GetSelectedFrame()); } } // Now we're ready to call the function: ClangFunction func (*exe_ctx.GetBestExecutionContextScope(), return_clang_type, *function_address, arg_value_list); StreamString error_stream; lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS; func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream); const bool unwind_on_error = true; const bool try_all_threads = true; const bool stop_others = true; const bool ignore_breakpoints = true; ExecutionResults results = func.ExecuteFunction (exe_ctx, &wrapper_struct_addr, error_stream, stop_others, PO_FUNCTION_TIMEOUT_USEC /* 15 secs timeout */, try_all_threads, unwind_on_error, ignore_breakpoints, ret); if (results != eExecutionCompleted) { strm.Printf("Error evaluating Print Object function: %d.\n", results); return false; } addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); char buf[512]; size_t cstr_len = 0; size_t full_buffer_len = sizeof (buf) - 1; size_t curr_len = full_buffer_len; while (curr_len == full_buffer_len) { Error error; curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf), error); strm.Write (buf, curr_len); cstr_len += curr_len; } return cstr_len > 0; }
bool AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionContextScope *exe_scope) { if (!m_read_objc_library) return false; ExecutionContext exe_ctx; exe_scope->CalculateExecutionContext(exe_ctx); Process *process = exe_ctx.GetProcessPtr(); if (!process) return false; // We need other parts of the exe_ctx, but the processes have to match. assert (m_process == process); // Get the function address for the print function. const Address *function_address = GetPrintForDebuggerAddr(); if (!function_address) return false; Target *target = exe_ctx.GetTargetPtr(); CompilerType compiler_type = value.GetCompilerType(); if (compiler_type) { if (!ClangASTContext::IsObjCObjectPointerType(compiler_type)) { strm.Printf ("Value doesn't point to an ObjC object.\n"); return false; } } else { // If it is not a pointer, see if we can make it into a pointer. ClangASTContext *ast_context = target->GetScratchClangASTContext(); CompilerType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID); if (!opaque_type) opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr); value.SetCompilerType (opaque_type); } ValueList arg_value_list; arg_value_list.PushValue(value); // This is the return value: ClangASTContext *ast_context = target->GetScratchClangASTContext(); CompilerType return_compiler_type = ast_context->GetCStringType(true); Value ret; // ret.SetContext(Value::eContextTypeClangType, return_compiler_type); ret.SetCompilerType (return_compiler_type); if (exe_ctx.GetFramePtr() == NULL) { Thread *thread = exe_ctx.GetThreadPtr(); if (thread == NULL) { exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread()); thread = exe_ctx.GetThreadPtr(); } if (thread) { exe_ctx.SetFrameSP(thread->GetSelectedFrame()); } } // Now we're ready to call the function: StreamString error_stream; lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS; if (!m_print_object_caller_up) { Error error; m_print_object_caller_up.reset(exe_scope->CalculateTarget()->GetFunctionCallerForLanguage (eLanguageTypeObjC, return_compiler_type, *function_address, arg_value_list, "objc-object-description", error)); if (error.Fail()) { m_print_object_caller_up.reset(); strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString()); return false; } m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, error_stream); } else { m_print_object_caller_up->WriteFunctionArguments(exe_ctx, wrapper_struct_addr, arg_value_list, error_stream); } EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetTryAllThreads(true); options.SetStopOthers(true); options.SetIgnoreBreakpoints(true); options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC); options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus); ExpressionResults results = m_print_object_caller_up->ExecuteFunction (exe_ctx, &wrapper_struct_addr, options, error_stream, ret); if (results != eExpressionCompleted) { strm.Printf("Error evaluating Print Object function: %d.\n", results); return false; } addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); char buf[512]; size_t cstr_len = 0; size_t full_buffer_len = sizeof (buf) - 1; size_t curr_len = full_buffer_len; while (curr_len == full_buffer_len) { Error error; curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf), error); strm.Write (buf, curr_len); cstr_len += curr_len; } return cstr_len > 0; }