1254721Semaste//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Target/ThreadPlanCallFunction.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste#include "llvm/Support/MachO.h" 16254721Semaste// Project includes 17254721Semaste#include "lldb/lldb-private-log.h" 18254721Semaste#include "lldb/Breakpoint/Breakpoint.h" 19254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h" 20254721Semaste#include "lldb/Core/Address.h" 21254721Semaste#include "lldb/Core/Log.h" 22254721Semaste#include "lldb/Core/Module.h" 23254721Semaste#include "lldb/Core/Stream.h" 24254721Semaste#include "lldb/Symbol/ObjectFile.h" 25254721Semaste#include "lldb/Target/LanguageRuntime.h" 26254721Semaste#include "lldb/Target/Process.h" 27254721Semaste#include "lldb/Target/RegisterContext.h" 28254721Semaste#include "lldb/Target/StopInfo.h" 29254721Semaste#include "lldb/Target/Target.h" 30254721Semaste#include "lldb/Target/Thread.h" 31254721Semaste#include "lldb/Target/ThreadPlanRunToAddress.h" 32254721Semaste 33254721Semasteusing namespace lldb; 34254721Semasteusing namespace lldb_private; 35254721Semaste 36254721Semaste//---------------------------------------------------------------------- 37254721Semaste// ThreadPlanCallFunction: Plan to call a single function 38254721Semaste//---------------------------------------------------------------------- 39254721Semastebool 40254721SemasteThreadPlanCallFunction::ConstructorSetup (Thread &thread, 41254721Semaste ABI *& abi, 42254721Semaste lldb::addr_t &start_load_addr, 43254721Semaste lldb::addr_t &function_load_addr) 44254721Semaste{ 45254721Semaste SetIsMasterPlan (true); 46254721Semaste SetOkayToDiscard (false); 47254721Semaste SetPrivate (true); 48254721Semaste 49254721Semaste ProcessSP process_sp (thread.GetProcess()); 50254721Semaste if (!process_sp) 51254721Semaste return false; 52254721Semaste 53254721Semaste abi = process_sp->GetABI().get(); 54254721Semaste 55254721Semaste if (!abi) 56254721Semaste return false; 57254721Semaste 58254721Semaste Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 59254721Semaste 60254721Semaste SetBreakpoints(); 61254721Semaste 62254721Semaste m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 63254721Semaste // If we can't read memory at the point of the process where we are planning to put our function, we're 64254721Semaste // not going to get any further... 65254721Semaste Error error; 66254721Semaste process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 67254721Semaste if (!error.Success()) 68254721Semaste { 69254721Semaste m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp); 70254721Semaste if (log) 71254721Semaste log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 72254721Semaste return false; 73254721Semaste } 74254721Semaste 75263367Semaste Module *exe_module = GetTarget().GetExecutableModulePointer(); 76254721Semaste 77254721Semaste if (exe_module == NULL) 78254721Semaste { 79254721Semaste m_constructor_errors.Printf ("Can't execute code without an executable module."); 80254721Semaste if (log) 81254721Semaste log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 82254721Semaste return false; 83254721Semaste } 84254721Semaste else 85254721Semaste { 86254721Semaste ObjectFile *objectFile = exe_module->GetObjectFile(); 87254721Semaste if (!objectFile) 88254721Semaste { 89254721Semaste m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 90254721Semaste exe_module->GetFileSpec().GetFilename().AsCString()); 91254721Semaste 92254721Semaste if (log) 93254721Semaste log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 94254721Semaste return false; 95254721Semaste } 96254721Semaste 97254721Semaste m_start_addr = objectFile->GetEntryPointAddress(); 98254721Semaste if (!m_start_addr.IsValid()) 99254721Semaste { 100254721Semaste m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 101254721Semaste exe_module->GetFileSpec().GetFilename().AsCString()); 102254721Semaste if (log) 103254721Semaste log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 104254721Semaste return false; 105254721Semaste } 106254721Semaste } 107254721Semaste 108263367Semaste start_load_addr = m_start_addr.GetLoadAddress (&GetTarget()); 109254721Semaste 110254721Semaste // Checkpoint the thread state so we can restore it later. 111254721Semaste if (log && log->GetVerbose()) 112254721Semaste ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 113254721Semaste 114254721Semaste if (!thread.CheckpointThreadState (m_stored_thread_state)) 115254721Semaste { 116254721Semaste m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 117254721Semaste if (log) 118254721Semaste log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 119254721Semaste return false; 120254721Semaste } 121263367Semaste function_load_addr = m_function_addr.GetLoadAddress (&GetTarget()); 122254721Semaste 123254721Semaste return true; 124254721Semaste} 125254721Semaste 126254721SemasteThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 127254721Semaste const Address &function, 128254721Semaste const ClangASTType &return_type, 129263367Semaste llvm::ArrayRef<addr_t> args, 130263367Semaste const EvaluateExpressionOptions &options) : 131254721Semaste ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 132254721Semaste m_valid (false), 133263367Semaste m_stop_other_threads (options.GetStopOthers()), 134263367Semaste m_unwind_on_error (options.DoesUnwindOnError()), 135263367Semaste m_ignore_breakpoints (options.DoesIgnoreBreakpoints()), 136263367Semaste m_debug_execution (options.GetDebug()), 137263367Semaste m_trap_exceptions (options.GetTrapExceptions()), 138254721Semaste m_function_addr (function), 139254721Semaste m_function_sp (0), 140254721Semaste m_return_type (return_type), 141254721Semaste m_takedown_done (false), 142263367Semaste m_should_clear_objc_exception_bp(false), 143263367Semaste m_should_clear_cxx_exception_bp (false), 144263367Semaste m_stop_address (LLDB_INVALID_ADDRESS) 145254721Semaste{ 146254721Semaste lldb::addr_t start_load_addr; 147254721Semaste ABI *abi; 148254721Semaste lldb::addr_t function_load_addr; 149254721Semaste if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) 150254721Semaste return; 151254721Semaste 152263367Semaste if (!abi->PrepareTrivialCall(thread, 153263367Semaste m_function_sp, 154263367Semaste function_load_addr, 155263367Semaste start_load_addr, 156263367Semaste args)) 157254721Semaste return; 158254721Semaste 159254721Semaste ReportRegisterState ("Function call was set up. Register state was:"); 160254721Semaste 161254721Semaste m_valid = true; 162254721Semaste} 163254721Semaste 164254721SemasteThreadPlanCallFunction::~ThreadPlanCallFunction () 165254721Semaste{ 166254721Semaste DoTakedown(PlanSucceeded()); 167254721Semaste} 168254721Semaste 169254721Semastevoid 170254721SemasteThreadPlanCallFunction::ReportRegisterState (const char *message) 171254721Semaste{ 172254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 173254721Semaste if (log) 174254721Semaste { 175254721Semaste StreamString strm; 176254721Semaste RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 177254721Semaste 178254721Semaste log->PutCString(message); 179254721Semaste 180254721Semaste RegisterValue reg_value; 181254721Semaste 182254721Semaste for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 183254721Semaste reg_idx < num_registers; 184254721Semaste ++reg_idx) 185254721Semaste { 186254721Semaste const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 187254721Semaste if (reg_ctx->ReadRegister(reg_info, reg_value)) 188254721Semaste { 189254721Semaste reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 190254721Semaste strm.EOL(); 191254721Semaste } 192254721Semaste } 193254721Semaste log->PutCString(strm.GetData()); 194254721Semaste } 195254721Semaste} 196254721Semaste 197254721Semastevoid 198254721SemasteThreadPlanCallFunction::DoTakedown (bool success) 199254721Semaste{ 200254721Semaste Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 201254721Semaste 202254721Semaste if (!m_valid) 203254721Semaste { 204254721Semaste //Don't call DoTakedown if we were never valid to begin with. 205254721Semaste if (log) 206254721Semaste log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this); 207254721Semaste return; 208254721Semaste } 209254721Semaste 210254721Semaste if (!m_takedown_done) 211254721Semaste { 212254721Semaste if (success) 213254721Semaste { 214254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 215254721Semaste const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 216254721Semaste if (abi && m_return_type.IsValid()) 217254721Semaste { 218254721Semaste const bool persistent = false; 219254721Semaste m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent); 220254721Semaste } 221254721Semaste } 222254721Semaste if (log) 223254721Semaste log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete()); 224254721Semaste m_takedown_done = true; 225254721Semaste m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 226254721Semaste m_real_stop_info_sp = GetPrivateStopInfo (); 227263365Semaste if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) 228263365Semaste { 229263365Semaste if (log) 230263365Semaste log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this); 231263365Semaste } 232254721Semaste SetPlanComplete(success); 233254721Semaste ClearBreakpoints(); 234254721Semaste if (log && log->GetVerbose()) 235254721Semaste ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 236254721Semaste 237254721Semaste } 238254721Semaste else 239254721Semaste { 240254721Semaste if (log) 241254721Semaste log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete()); 242254721Semaste } 243254721Semaste} 244254721Semaste 245254721Semastevoid 246254721SemasteThreadPlanCallFunction::WillPop () 247254721Semaste{ 248254721Semaste DoTakedown(PlanSucceeded()); 249254721Semaste} 250254721Semaste 251254721Semastevoid 252254721SemasteThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 253254721Semaste{ 254254721Semaste if (level == eDescriptionLevelBrief) 255254721Semaste { 256254721Semaste s->Printf("Function call thread plan"); 257254721Semaste } 258254721Semaste else 259254721Semaste { 260254721Semaste TargetSP target_sp (m_thread.CalculateTarget()); 261254721Semaste s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get())); 262254721Semaste } 263254721Semaste} 264254721Semaste 265254721Semastebool 266254721SemasteThreadPlanCallFunction::ValidatePlan (Stream *error) 267254721Semaste{ 268254721Semaste if (!m_valid) 269254721Semaste { 270254721Semaste if (error) 271254721Semaste { 272254721Semaste if (m_constructor_errors.GetSize() > 0) 273254721Semaste error->PutCString (m_constructor_errors.GetData()); 274254721Semaste else 275254721Semaste error->PutCString ("Unknown error"); 276254721Semaste } 277254721Semaste return false; 278254721Semaste } 279254721Semaste 280254721Semaste return true; 281254721Semaste} 282254721Semaste 283254721Semaste 284254721SemasteVote 285254721SemasteThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) 286254721Semaste{ 287254721Semaste if (m_takedown_done || IsPlanComplete()) 288254721Semaste return eVoteYes; 289254721Semaste else 290254721Semaste return ThreadPlan::ShouldReportStop(event_ptr); 291254721Semaste} 292254721Semaste 293254721Semastebool 294254721SemasteThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) 295254721Semaste{ 296254721Semaste Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS)); 297254721Semaste m_real_stop_info_sp = GetPrivateStopInfo (); 298254721Semaste 299254721Semaste // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 300254721Semaste // we answer yes. 301254721Semaste if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr)) 302254721Semaste { 303254721Semaste SetPlanComplete(); 304254721Semaste return true; 305254721Semaste } 306254721Semaste 307254721Semaste // Check if the breakpoint is one of ours. 308254721Semaste 309254721Semaste StopReason stop_reason; 310254721Semaste if (!m_real_stop_info_sp) 311254721Semaste stop_reason = eStopReasonNone; 312254721Semaste else 313254721Semaste stop_reason = m_real_stop_info_sp->GetStopReason(); 314254721Semaste if (log) 315254721Semaste log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason)); 316254721Semaste 317254721Semaste if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 318254721Semaste return true; 319254721Semaste 320254721Semaste // We control breakpoints separately from other "stop reasons." So first, 321254721Semaste // check the case where we stopped for an internal breakpoint, in that case, continue on. 322254721Semaste // If it is not an internal breakpoint, consult m_ignore_breakpoints. 323254721Semaste 324254721Semaste 325254721Semaste if (stop_reason == eStopReasonBreakpoint) 326254721Semaste { 327254721Semaste ProcessSP process_sp (m_thread.CalculateProcess()); 328254721Semaste uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 329254721Semaste BreakpointSiteSP bp_site_sp; 330254721Semaste if (process_sp) 331254721Semaste bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 332254721Semaste if (bp_site_sp) 333254721Semaste { 334254721Semaste uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 335254721Semaste bool is_internal = true; 336254721Semaste for (uint32_t i = 0; i < num_owners; i++) 337254721Semaste { 338254721Semaste Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 339254721Semaste if (log) 340254721Semaste log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID()); 341254721Semaste 342254721Semaste if (!bp.IsInternal()) 343254721Semaste { 344254721Semaste is_internal = false; 345254721Semaste break; 346254721Semaste } 347254721Semaste } 348254721Semaste if (is_internal) 349254721Semaste { 350254721Semaste if (log) 351254721Semaste log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping."); 352254721Semaste return false; 353254721Semaste } 354254721Semaste } 355254721Semaste 356254721Semaste if (m_ignore_breakpoints) 357254721Semaste { 358254721Semaste if (log) 359254721Semaste log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 360254721Semaste m_real_stop_info_sp->OverrideShouldStop(false); 361254721Semaste return true; 362254721Semaste } 363254721Semaste else 364254721Semaste { 365254721Semaste if (log) 366254721Semaste log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 367254721Semaste m_real_stop_info_sp->OverrideShouldStop(true); 368254721Semaste return false; 369254721Semaste } 370254721Semaste } 371254721Semaste else if (!m_unwind_on_error) 372254721Semaste { 373254721Semaste // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 374254721Semaste return false; 375254721Semaste } 376254721Semaste else 377254721Semaste { 378254721Semaste // If the subplan is running, any crashes are attributable to us. 379254721Semaste // If we want to discard the plan, then we say we explain the stop 380254721Semaste // but if we are going to be discarded, let whoever is above us 381254721Semaste // explain the stop. 382254721Semaste // But don't discard the plan if the stop would restart itself (for instance if it is a 383254721Semaste // signal that is set not to stop. Check that here first. We just say we explain the stop 384254721Semaste // but aren't done and everything will continue on from there. 385254721Semaste 386254721Semaste if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) 387254721Semaste { 388254721Semaste SetPlanComplete(false); 389254721Semaste if (m_subplan_sp) 390254721Semaste { 391254721Semaste if (m_unwind_on_error) 392254721Semaste return true; 393254721Semaste else 394254721Semaste return false; 395254721Semaste } 396254721Semaste else 397254721Semaste return false; 398254721Semaste } 399254721Semaste else 400254721Semaste return true; 401254721Semaste } 402254721Semaste} 403254721Semaste 404254721Semastebool 405254721SemasteThreadPlanCallFunction::ShouldStop (Event *event_ptr) 406254721Semaste{ 407254721Semaste // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete. 408254721Semaste // We need to do that here to make sure our state is correct. 409254721Semaste DoPlanExplainsStop(event_ptr); 410254721Semaste 411254721Semaste if (IsPlanComplete()) 412254721Semaste { 413254721Semaste ReportRegisterState ("Function completed. Register state was:"); 414254721Semaste return true; 415254721Semaste } 416254721Semaste else 417254721Semaste { 418254721Semaste return false; 419254721Semaste } 420254721Semaste} 421254721Semaste 422254721Semastebool 423254721SemasteThreadPlanCallFunction::StopOthers () 424254721Semaste{ 425254721Semaste return m_stop_other_threads; 426254721Semaste} 427254721Semaste 428254721Semastevoid 429254721SemasteThreadPlanCallFunction::SetStopOthers (bool new_value) 430254721Semaste{ 431254721Semaste if (m_subplan_sp) 432254721Semaste { 433254721Semaste ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 434254721Semaste address_plan->SetStopOthers(new_value); 435254721Semaste } 436254721Semaste m_stop_other_threads = new_value; 437254721Semaste} 438254721Semaste 439254721SemasteStateType 440254721SemasteThreadPlanCallFunction::GetPlanRunState () 441254721Semaste{ 442254721Semaste return eStateRunning; 443254721Semaste} 444254721Semaste 445254721Semastevoid 446254721SemasteThreadPlanCallFunction::DidPush () 447254721Semaste{ 448254721Semaste//#define SINGLE_STEP_EXPRESSIONS 449254721Semaste 450254721Semaste // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 451254721Semaste // Wait till the plan is pushed so we aren't changing the stop info till we're about to run. 452254721Semaste 453254721Semaste GetThread().SetStopInfoToNothing(); 454254721Semaste 455254721Semaste#ifndef SINGLE_STEP_EXPRESSIONS 456254721Semaste m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 457254721Semaste 458254721Semaste m_thread.QueueThreadPlan(m_subplan_sp, false); 459254721Semaste m_subplan_sp->SetPrivate (true); 460254721Semaste#endif 461254721Semaste} 462254721Semaste 463254721Semastebool 464254721SemasteThreadPlanCallFunction::WillStop () 465254721Semaste{ 466254721Semaste return true; 467254721Semaste} 468254721Semaste 469254721Semastebool 470254721SemasteThreadPlanCallFunction::MischiefManaged () 471254721Semaste{ 472254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 473254721Semaste 474254721Semaste if (IsPlanComplete()) 475254721Semaste { 476254721Semaste if (log) 477254721Semaste log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this); 478254721Semaste 479254721Semaste ThreadPlan::MischiefManaged (); 480254721Semaste return true; 481254721Semaste } 482254721Semaste else 483254721Semaste { 484254721Semaste return false; 485254721Semaste } 486254721Semaste} 487254721Semaste 488254721Semastevoid 489254721SemasteThreadPlanCallFunction::SetBreakpoints () 490254721Semaste{ 491254721Semaste ProcessSP process_sp (m_thread.CalculateProcess()); 492263367Semaste if (m_trap_exceptions && process_sp) 493254721Semaste { 494254721Semaste m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 495254721Semaste m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 496254721Semaste 497254721Semaste if (m_cxx_language_runtime) 498263367Semaste { 499263367Semaste m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); 500254721Semaste m_cxx_language_runtime->SetExceptionBreakpoints(); 501263367Semaste } 502254721Semaste if (m_objc_language_runtime) 503263367Semaste { 504263367Semaste m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet(); 505254721Semaste m_objc_language_runtime->SetExceptionBreakpoints(); 506263367Semaste } 507254721Semaste } 508254721Semaste} 509254721Semaste 510254721Semastevoid 511254721SemasteThreadPlanCallFunction::ClearBreakpoints () 512254721Semaste{ 513263367Semaste if (m_trap_exceptions) 514263367Semaste { 515263367Semaste if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) 516263367Semaste m_cxx_language_runtime->ClearExceptionBreakpoints(); 517263367Semaste if (m_objc_language_runtime && m_should_clear_objc_exception_bp) 518263367Semaste m_objc_language_runtime->ClearExceptionBreakpoints(); 519263367Semaste } 520254721Semaste} 521254721Semaste 522254721Semastebool 523254721SemasteThreadPlanCallFunction::BreakpointsExplainStop() 524254721Semaste{ 525254721Semaste StopInfoSP stop_info_sp = GetPrivateStopInfo (); 526254721Semaste 527263367Semaste if (m_trap_exceptions) 528254721Semaste { 529263367Semaste if ((m_cxx_language_runtime && 530263367Semaste m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 531263367Semaste ||(m_objc_language_runtime && 532263367Semaste m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) 533263367Semaste { 534263367Semaste Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 535263367Semaste if (log) 536263367Semaste log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); 537263367Semaste 538263367Semaste SetPlanComplete(false); 539263367Semaste 540263367Semaste // If the user has set the ObjC language breakpoint, it would normally get priority over our internal 541263367Semaste // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. 542263367Semaste stop_info_sp->OverrideShouldStop (true); 543263367Semaste return true; 544263367Semaste } 545254721Semaste } 546254721Semaste 547254721Semaste return false; 548254721Semaste} 549254721Semaste 550254721Semastebool 551254721SemasteThreadPlanCallFunction::RestoreThreadState() 552254721Semaste{ 553254721Semaste return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 554254721Semaste} 555254721Semaste 556