void SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); StackFrameSP frame_sp (sb_frame.GetFrameSP()); if (log) { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); } if (exe_ctx.HasThreadScope()) { bool abort_other_plans = false; bool stop_other_threads = false; Thread *thread = exe_ctx.GetThreadPtr(); ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion, frame_sp->GetFrameIndex())); // This returns an error, we should use it! ResumeNewPlan (exe_ctx, new_plan_sp.get()); } }
// Internal function void LLDBServices::GetContextFromFrame( /* const */ lldb::SBFrame& frame, DT_CONTEXT *dtcontext) { #ifdef DBG_TARGET_AMD64 dtcontext->Rip = frame.GetPC(); dtcontext->Rsp = frame.GetSP(); dtcontext->Rbp = frame.GetFP(); dtcontext->EFlags = GetRegister(frame, "rflags"); dtcontext->Rax = GetRegister(frame, "rax"); dtcontext->Rbx = GetRegister(frame, "rbx"); dtcontext->Rcx = GetRegister(frame, "rcx"); dtcontext->Rdx = GetRegister(frame, "rdx"); dtcontext->Rsi = GetRegister(frame, "rsi"); dtcontext->Rdi = GetRegister(frame, "rdi"); dtcontext->R8 = GetRegister(frame, "r8"); dtcontext->R9 = GetRegister(frame, "r9"); dtcontext->R10 = GetRegister(frame, "r10"); dtcontext->R11 = GetRegister(frame, "r11"); dtcontext->R12 = GetRegister(frame, "r12"); dtcontext->R13 = GetRegister(frame, "r13"); dtcontext->R14 = GetRegister(frame, "r14"); dtcontext->R15 = GetRegister(frame, "r15"); dtcontext->SegCs = GetRegister(frame, "cs"); dtcontext->SegSs = GetRegister(frame, "ss"); dtcontext->SegDs = GetRegister(frame, "ds"); dtcontext->SegEs = GetRegister(frame, "es"); dtcontext->SegFs = GetRegister(frame, "fs"); dtcontext->SegGs = GetRegister(frame, "gs"); #elif DBG_TARGET_ARM dtcontext->Pc = frame.GetPC(); dtcontext->Sp = frame.GetSP(); dtcontext->Lr = GetRegister(frame, "lr"); dtcontext->Cpsr = GetRegister(frame, "cpsr"); dtcontext->R0 = GetRegister(frame, "r0"); dtcontext->R1 = GetRegister(frame, "r1"); dtcontext->R2 = GetRegister(frame, "r2"); dtcontext->R3 = GetRegister(frame, "r3"); dtcontext->R4 = GetRegister(frame, "r4"); dtcontext->R5 = GetRegister(frame, "r5"); dtcontext->R6 = GetRegister(frame, "r6"); dtcontext->R7 = GetRegister(frame, "r7"); dtcontext->R8 = GetRegister(frame, "r8"); dtcontext->R9 = GetRegister(frame, "r9"); dtcontext->R10 = GetRegister(frame, "r10"); dtcontext->R11 = GetRegister(frame, "r11"); dtcontext->R12 = GetRegister(frame, "r12"); #endif }
//++ ------------------------------------------------------------------------------------ // Details: Carry out work to complete the GDB show option 'language' to prepare // and send back the requested information. // Type: Method. // Args: vrWords - (R) List of additional parameters used by this option. // Return: MIstatus::success - Function succeeded. // MIstatus::failure - Function failed. // Throws: None. //-- bool CMICmdCmdGdbShow::OptionFnLanguage(const CMIUtilString::VecString_t &vrWords) { MIunused(vrWords); // Get current language CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread(); const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame(); lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit(); const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage(); m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType); return MIstatus::success; }
bool SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) { if (m_opaque_sp) { lldb::StackFrameSP frame_sp (frame.GetFrameSP()); if (frame_sp) { lldb_private::ExecutionContext exe_ctx; frame_sp->CalculateExecutionContext (exe_ctx); lldb_private::Target *target = exe_ctx.GetTargetPtr(); lldb_private::ArchSpec arch = target->GetArchitecture(); return m_opaque_sp->Emulate (arch, evaluate_options, (void *) frame_sp.get(), &lldb_private::EmulateInstruction::ReadMemoryFrame, &lldb_private::EmulateInstruction::WriteMemoryFrame, &lldb_private::EmulateInstruction::ReadRegisterFrame, &lldb_private::EmulateInstruction::WriteRegisterFrame); } } return false; }
lldb::SBValueList SBBlock::GetVariables (lldb::SBFrame& frame, bool arguments, bool locals, bool statics, lldb::DynamicValueType use_dynamic) { Block *block = GetPtr(); SBValueList value_list; if (block) { StackFrameSP frame_sp(frame.GetFrameSP()); VariableListSP variable_list_sp (block->GetBlockVariableList (true)); if (variable_list_sp) { const size_t num_variables = variable_list_sp->GetSize(); if (num_variables) { for (size_t i = 0; i < num_variables; ++i) { VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i)); if (variable_sp) { bool add_variable = false; switch (variable_sp->GetScope()) { case eValueTypeVariableGlobal: case eValueTypeVariableStatic: add_variable = statics; break; case eValueTypeVariableArgument: add_variable = arguments; break; case eValueTypeVariableLocal: add_variable = locals; break; default: break; } if (add_variable) { if (frame_sp) { lldb::ValueObjectSP valobj_sp(frame_sp->GetValueObjectForFrameVariable (variable_sp,eNoDynamicValues)); SBValue value_sb; value_sb.SetSP(valobj_sp, use_dynamic); value_list.Append (value_sb); } } } } } } } return value_list; }
void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); std::unique_lock<std::recursive_mutex> lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); if (!sb_frame.IsValid()) { if (log) log->Printf( "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", static_cast<void *>(exe_ctx.GetThreadPtr())); return; } StackFrameSP frame_sp(sb_frame.GetFrameSP()); if (log) { SBStream frame_desc_strm; sb_frame.GetDescription(frame_desc_strm); log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", static_cast<void *>(exe_ctx.GetThreadPtr()), static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); } if (exe_ctx.HasThreadScope()) { bool abort_other_plans = false; bool stop_other_threads = false; Thread *thread = exe_ctx.GetThreadPtr(); if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another " "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", static_cast<void *>(exe_ctx.GetThreadPtr()), sb_frame.GetThread().GetThreadID(), thread->GetID()); } ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion, frame_sp->GetFrameIndex())); // This returns an error, we should use it! ResumeNewPlan(exe_ctx, new_plan_sp.get()); } }
// Internal function DWORD_PTR LLDBServices::GetRegister( /* const */ lldb::SBFrame& frame, const char *name) { lldb::SBValue regValue = frame.FindRegister(name); lldb::SBError error; DWORD_PTR result = regValue.GetValueAsUnsigned(error); return result; }
void SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData()); } if (m_opaque_sp) { Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); bool abort_other_plans = true; bool stop_other_threads = true; m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion, sb_frame->GetFrameIndex()); Process &process = m_opaque_sp->GetProcess(); process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); Error error (process.Resume()); if (error.Success()) { // If we are doing synchronous mode, then wait for the // process to stop yet again! if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) process.WaitForProcessToStop (NULL); } } }
// Internal function DWORD_PTR LLDBServices::GetExpression( /* const */ lldb::SBFrame& frame, lldb::SBError& error, PCSTR exp) { DWORD_PTR result = 0; lldb::SBValue value = frame.EvaluateExpression(exp, lldb::eNoDynamicValues); if (value.IsValid()) { result = value.GetValueAsUnsigned(error); } return result; }
SBError SBThread::StepOverUntil (lldb::SBFrame &sb_frame, lldb::SBFileSpec &sb_file_spec, uint32_t line) { SBError sb_error; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); char path[PATH_MAX]; Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); StackFrameSP frame_sp (sb_frame.GetFrameSP()); if (log) { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); sb_file_spec->GetPath (path, sizeof(path)); log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData(), path, line); } if (exe_ctx.HasThreadScope()) { Target *target = exe_ctx.GetTargetPtr(); Thread *thread = exe_ctx.GetThreadPtr(); if (line == 0) { sb_error.SetErrorString("invalid line argument"); return sb_error; } if (!frame_sp) { frame_sp = thread->GetSelectedFrame (); if (!frame_sp) frame_sp = thread->GetStackFrameAtIndex (0); } SymbolContext frame_sc; if (!frame_sp) { sb_error.SetErrorString("no valid frames in thread to step"); return sb_error; } // If we have a frame, get its line frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextLineEntry | eSymbolContextSymbol ); if (frame_sc.comp_unit == NULL) { sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); return sb_error; } FileSpec step_file_spec; if (sb_file_spec.IsValid()) { // The file spec passed in was valid, so use it step_file_spec = sb_file_spec.ref(); } else { if (frame_sc.line_entry.IsValid()) step_file_spec = frame_sc.line_entry.file; else { sb_error.SetErrorString("invalid file argument or no file for frame"); return sb_error; } } // Grab the current function, then we will make sure the "until" address is // within the function. We discard addresses that are out of the current // function, and then if there are no addresses remaining, give an appropriate // error message. bool all_in_function = true; AddressRange fun_range = frame_sc.function->GetAddressRange(); std::vector<addr_t> step_over_until_addrs; const bool abort_other_plans = false; const bool stop_other_threads = false; const bool check_inlines = true; const bool exact = false; SymbolContextList sc_list; const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, sc_list); if (num_matches > 0) { SymbolContext sc; for (uint32_t i=0; i<num_matches; ++i) { if (sc_list.GetContextAtIndex(i, sc)) { addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); if (step_addr != LLDB_INVALID_ADDRESS) { if (fun_range.ContainsLoadAddress(step_addr, target)) step_over_until_addrs.push_back(step_addr); else all_in_function = false; } } } } if (step_over_until_addrs.empty()) { if (all_in_function) { step_file_spec.GetPath (path, sizeof(path)); sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); } else sb_error.SetErrorString ("step until target not in current function"); } else { ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, &step_over_until_addrs[0], step_over_until_addrs.size(), stop_other_threads, frame_sp->GetFrameIndex())); sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); } } else { sb_error.SetErrorString("this SBThread object is invalid"); } return sb_error; }
SBExecutionContext::SBExecutionContext (const lldb::SBFrame &frame) : m_exe_ctx_sp(new ExecutionContextRef()) { m_exe_ctx_sp->SetFrameSP(frame.GetFrameSP()); }