18871Srgrimes//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 24Srgrimes// 34Srgrimes// The LLVM Compiler Infrastructure 44Srgrimes// 58871Srgrimes// This file is distributed under the University of Illinois Open Source 64Srgrimes// License. See LICENSE.TXT for details. 74Srgrimes// 84Srgrimes//===----------------------------------------------------------------------===// 94Srgrimes 104Srgrimes#include "lldb/Target/ThreadPlanCallFunction.h" 118871Srgrimes 124Srgrimes// C Includes 134Srgrimes// C++ Includes 144Srgrimes// Other libraries and framework includes 158871Srgrimes#include "llvm/Support/MachO.h" 164Srgrimes// Project includes 178871Srgrimes#include "lldb/lldb-private-log.h" 184Srgrimes#include "lldb/Breakpoint/Breakpoint.h" 194Srgrimes#include "lldb/Breakpoint/BreakpointLocation.h" 204Srgrimes#include "lldb/Core/Address.h" 214Srgrimes#include "lldb/Core/Log.h" 228871Srgrimes#include "lldb/Core/Module.h" 234Srgrimes#include "lldb/Core/Stream.h" 244Srgrimes#include "lldb/Symbol/ObjectFile.h" 254Srgrimes#include "lldb/Target/LanguageRuntime.h" 264Srgrimes#include "lldb/Target/Process.h" 27114589Sobrien#include "lldb/Target/RegisterContext.h" 28114589Sobrien#include "lldb/Target/StopInfo.h" 2937415Scharnier#include "lldb/Target/Target.h" 30103348Sphk#include "lldb/Target/Thread.h" 314Srgrimes#include "lldb/Target/ThreadPlanRunToAddress.h" 32104272Sphk 33113454Sphkusing namespace lldb; 3479681Sjoergusing namespace lldb_private; 3537415Scharnier 3679681Sjoerg//---------------------------------------------------------------------- 3737415Scharnier// ThreadPlanCallFunction: Plan to call a single function 3837415Scharnier//---------------------------------------------------------------------- 3937415Scharnierbool 4037415ScharnierThreadPlanCallFunction::ConstructorSetup (Thread &thread, 41148035Sphk ABI *& abi, 4279681Sjoerg lldb::addr_t &start_load_addr, 4379681Sjoerg lldb::addr_t &function_load_addr) 44100202Sbde{ 454Srgrimes SetIsMasterPlan (true); 4637415Scharnier SetOkayToDiscard (false); 4716561Salex SetPrivate (true); 4816561Salex 494Srgrimes ProcessSP process_sp (thread.GetProcess()); 50227081Sed if (!process_sp) 514Srgrimes return false; 52217808Ssobomax 53217808Ssobomax abi = process_sp->GetABI().get(); 54217808Ssobomax 55217808Ssobomax if (!abi) 564Srgrimes return false; 574Srgrimes 584Srgrimes Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 594Srgrimes 604Srgrimes SetBreakpoints(); 614Srgrimes 624Srgrimes m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 634Srgrimes // If we can't read memory at the point of the process where we are planning to put our function, we're 644Srgrimes // not going to get any further... 654Srgrimes Error error; 664Srgrimes process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 674Srgrimes if (!error.Success()) 68217808Ssobomax { 694Srgrimes m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp); 704Srgrimes if (log) 714Srgrimes log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 7220061Ssos return false; 7320061Ssos } 7493394Sphk 754Srgrimes Module *exe_module = GetTarget().GetExecutableModulePointer(); 7693394Sphk 7710514Sjoerg if (exe_module == NULL) 7893394Sphk { 794Srgrimes m_constructor_errors.Printf ("Can't execute code without an executable module."); 8093394Sphk if (log) 81145763Snyan log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 82145763Snyan return false; 83113454Sphk } 844Srgrimes else 854Srgrimes { 8693394Sphk ObjectFile *objectFile = exe_module->GetObjectFile(); 87148035Sphk if (!objectFile) 8893394Sphk { 894Srgrimes m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 904Srgrimes exe_module->GetFileSpec().GetFilename().AsCString()); 9193394Sphk 9293394Sphk if (log) 9393394Sphk log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 9493394Sphk return false; 954Srgrimes } 964Srgrimes 974Srgrimes m_start_addr = objectFile->GetEntryPointAddress(); 984Srgrimes if (!m_start_addr.IsValid()) 9919459Sjkh { 10019459Sjkh m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 10119459Sjkh exe_module->GetFileSpec().GetFilename().AsCString()); 10219459Sjkh if (log) 10319459Sjkh log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 10419459Sjkh return false; 10519459Sjkh } 10619459Sjkh } 10719459Sjkh 10819459Sjkh start_load_addr = m_start_addr.GetLoadAddress (&GetTarget()); 10919459Sjkh 11019459Sjkh // Checkpoint the thread state so we can restore it later. 111224150Srstone if (log && log->GetVerbose()) 112224150Srstone ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 113224150Srstone 11419459Sjkh if (!thread.CheckpointThreadState (m_stored_thread_state)) 11519459Sjkh { 11619459Sjkh m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 11748282Srnordier if (log) 11857896Simp log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 1194Srgrimes return false; 12048282Srnordier } 1214Srgrimes function_load_addr = m_function_addr.GetLoadAddress (&GetTarget()); 122181036Sobrien 1234Srgrimes return true; 12457896Simp} 12595002Strhodes 12619459SjkhThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 12719459Sjkh const Address &function, 128169143Smaxim const ClangASTType &return_type, 1294Srgrimes llvm::ArrayRef<addr_t> args, 130187246Sluigi const EvaluateExpressionOptions &options) : 131187246Sluigi ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 132187246Sluigi m_valid (false), 133187246Sluigi m_stop_other_threads (options.GetStopOthers()), 134187246Sluigi m_unwind_on_error (options.DoesUnwindOnError()), 135187246Sluigi m_ignore_breakpoints (options.DoesIgnoreBreakpoints()), 136187246Sluigi m_debug_execution (options.GetDebug()), 137187246Sluigi m_trap_exceptions (options.GetTrapExceptions()), 138187246Sluigi m_function_addr (function), 139187246Sluigi m_function_sp (0), 140187248Sluigi m_return_type (return_type), 141187248Sluigi m_takedown_done (false), 142187246Sluigi m_should_clear_objc_exception_bp(false), 143187246Sluigi m_should_clear_cxx_exception_bp (false), 144187246Sluigi m_stop_address (LLDB_INVALID_ADDRESS) 145187246Sluigi{ 146187246Sluigi lldb::addr_t start_load_addr; 147187246Sluigi ABI *abi; 148187246Sluigi lldb::addr_t function_load_addr; 149187246Sluigi if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) 150187246Sluigi return; 151187246Sluigi 152187246Sluigi if (!abi->PrepareTrivialCall(thread, 153187246Sluigi m_function_sp, 154187246Sluigi function_load_addr, 155187246Sluigi start_load_addr, 156187248Sluigi args)) 157187246Sluigi return; 158187246Sluigi 159187246Sluigi ReportRegisterState ("Function call was set up. Register state was:"); 160187246Sluigi 161187246Sluigi m_valid = true; 162187246Sluigi} 163187246Sluigi 164187246SluigiThreadPlanCallFunction::~ThreadPlanCallFunction () 165187246Sluigi{ 166187246Sluigi DoTakedown(PlanSucceeded()); 167187246Sluigi} 168187246Sluigi 169187246Sluigivoid 170187246SluigiThreadPlanCallFunction::ReportRegisterState (const char *message) 171187246Sluigi{ 172187246Sluigi Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 173187246Sluigi if (log) 174187246Sluigi { 175187246Sluigi StreamString strm; 176187246Sluigi RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 177187246Sluigi 178187246Sluigi log->PutCString(message); 179187246Sluigi 180187246Sluigi RegisterValue reg_value; 181187246Sluigi 182187246Sluigi for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 183187246Sluigi reg_idx < num_registers; 184187246Sluigi ++reg_idx) 185187246Sluigi { 186187246Sluigi const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 187187246Sluigi if (reg_ctx->ReadRegister(reg_info, reg_value)) 188187246Sluigi { 189187246Sluigi reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 190187246Sluigi strm.EOL(); 191187246Sluigi } 192187246Sluigi } 193187246Sluigi log->PutCString(strm.GetData()); 194187246Sluigi } 195187246Sluigi} 196187246Sluigi 197187246Sluigivoid 198187246SluigiThreadPlanCallFunction::DoTakedown (bool success) 199187246Sluigi{ 200187246Sluigi Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 201187246Sluigi 202187246Sluigi if (!m_valid) 203187246Sluigi { 204187246Sluigi //Don't call DoTakedown if we were never valid to begin with. 205187246Sluigi if (log) 206187246Sluigi log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this); 207187246Sluigi return; 208187246Sluigi } 209187246Sluigi 210187246Sluigi if (!m_takedown_done) 211187248Sluigi { 212187246Sluigi if (success) 213187246Sluigi { 214187246Sluigi ProcessSP process_sp (m_thread.GetProcess()); 215187246Sluigi const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 216187246Sluigi if (abi && m_return_type.IsValid()) 217187246Sluigi { 218187246Sluigi const bool persistent = false; 219187246Sluigi m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent); 220187246Sluigi } 221234345Smarck } 222187246Sluigi if (log) 223187246Sluigi 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()); 2244Srgrimes m_takedown_done = true; 2254Srgrimes m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 226187246Sluigi m_real_stop_info_sp = GetPrivateStopInfo (); 227187246Sluigi if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) 228187246Sluigi { 229187246Sluigi if (log) 230187246Sluigi log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this); 231187246Sluigi } 232187246Sluigi SetPlanComplete(success); 233187246Sluigi ClearBreakpoints(); 234187246Sluigi if (log && log->GetVerbose()) 235187246Sluigi ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 236227292Sae 237187239Sluigi } 238187241Sluigi else 23916561Salex { 24019459Sjkh if (log) 24116561Salex 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()); 24293394Sphk } 24316561Salex} 24493394Sphk 24593394Sphkvoid 24679681SjoergThreadPlanCallFunction::WillPop () 24781164Siedowse{ 24893394Sphk DoTakedown(PlanSucceeded()); 24916561Salex} 250148035Sphk 25193394Sphkvoid 25293394SphkThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 25393394Sphk{ 25493394Sphk if (level == eDescriptionLevelBrief) 255217808Ssobomax { 25619459Sjkh s->Printf("Function call thread plan"); 25719459Sjkh } 25865054Sjhb else 25937415Scharnier { 2604Srgrimes TargetSP target_sp (m_thread.CalculateTarget()); 26116561Salex s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get())); 26216561Salex } 2634Srgrimes} 26448282Srnordier 26593394Sphkbool 26693394SphkThreadPlanCallFunction::ValidatePlan (Stream *error) 2674Srgrimes{ 268181036Sobrien if (!m_valid) 26948282Srnordier { 27048282Srnordier if (error) 27148282Srnordier { 2724Srgrimes if (m_constructor_errors.GetSize() > 0) 27357896Simp error->PutCString (m_constructor_errors.GetData()); 27457896Simp else 27557896Simp error->PutCString ("Unknown error"); 27648282Srnordier } 27748282Srnordier return false; 27848282Srnordier } 27948282Srnordier 28048282Srnordier return true; 28148282Srnordier} 28248282Srnordier 28348282Srnordier 28448282SrnordierVote 28548282SrnordierThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) 28648282Srnordier{ 28748282Srnordier if (m_takedown_done || IsPlanComplete()) 288169143Smaxim return eVoteYes; 289169143Smaxim else 290169143Smaxim return ThreadPlan::ShouldReportStop(event_ptr); 291181036Sobrien} 292181036Sobrien 293181036Sobrienbool 29457896SimpThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) 29557896Simp{ 29657896Simp Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS)); 29748282Srnordier m_real_stop_info_sp = GetPrivateStopInfo (); 29848282Srnordier 29948282Srnordier // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 30048282Srnordier // we answer yes. 30148282Srnordier if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr)) 30248282Srnordier { 30348282Srnordier SetPlanComplete(); 30448282Srnordier return true; 30548282Srnordier } 30648282Srnordier 30748282Srnordier // Check if the breakpoint is one of ours. 30848282Srnordier 30948282Srnordier StopReason stop_reason; 31048282Srnordier if (!m_real_stop_info_sp) 31148282Srnordier stop_reason = eStopReasonNone; 31248282Srnordier else 31348282Srnordier stop_reason = m_real_stop_info_sp->GetStopReason(); 3144Srgrimes if (log) 31548282Srnordier log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason)); 31648282Srnordier 31748282Srnordier if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 31848282Srnordier return true; 31948282Srnordier 32048282Srnordier // We control breakpoints separately from other "stop reasons." So first, 3214Srgrimes // check the case where we stopped for an internal breakpoint, in that case, continue on. 32279681Sjoerg // If it is not an internal breakpoint, consult m_ignore_breakpoints. 32379681Sjoerg 32479681Sjoerg 325182844Slulf if (stop_reason == eStopReasonBreakpoint) 326182844Slulf { 327187203Sluigi ProcessSP process_sp (m_thread.CalculateProcess()); 32810514Sjoerg uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 32979681Sjoerg BreakpointSiteSP bp_site_sp; 33079681Sjoerg if (process_sp) 3314Srgrimes bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 33263027Sjhb if (bp_site_sp) 33363027Sjhb { 33463027Sjhb uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 335159757Ssimon bool is_internal = true; 336159757Ssimon for (uint32_t i = 0; i < num_owners; i++) 33763329Sjhb { 33863329Sjhb Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 33963027Sjhb if (log) 340169143Smaxim log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID()); 341169143Smaxim 342169143Smaxim if (!bp.IsInternal()) 343169143Smaxim { 344169143Smaxim is_internal = false; 345169143Smaxim break; 346169143Smaxim } 347169143Smaxim } 348187203Sluigi if (is_internal) 349169143Smaxim { 350169143Smaxim if (log) 351169143Smaxim log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping."); 352169143Smaxim return false; 353169143Smaxim } 354169143Smaxim } 355169143Smaxim 356169143Smaxim if (m_ignore_breakpoints) 357169143Smaxim { 358169143Smaxim if (log) 359169143Smaxim log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 360169143Smaxim m_real_stop_info_sp->OverrideShouldStop(false); 361169143Smaxim return true; 36293394Sphk } 36357896Simp else 36457896Simp { 36557896Simp if (log) 36657896Simp log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 36757896Simp m_real_stop_info_sp->OverrideShouldStop(true); 36857896Simp return false; 369187203Sluigi } 37057896Simp } 37157896Simp else if (!m_unwind_on_error) 37257896Simp { 37357896Simp // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 37457896Simp return false; 37557896Simp } 37657896Simp else 37757896Simp { 37857896Simp // If the subplan is running, any crashes are attributable to us. 37957896Simp // If we want to discard the plan, then we say we explain the stop 3804Srgrimes // but if we are going to be discarded, let whoever is above us 38119459Sjkh // explain the stop. 38293394Sphk // But don't discard the plan if the stop would restart itself (for instance if it is a 38350215Sphk // signal that is set not to stop. Check that here first. We just say we explain the stop 38450215Sphk // but aren't done and everything will continue on from there. 385187203Sluigi 38650215Sphk if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) 38750215Sphk { 38850215Sphk SetPlanComplete(false); 38965054Sjhb if (m_subplan_sp) 39065054Sjhb { 39181164Siedowse if (m_unwind_on_error) 39250215Sphk return true; 393187239Sluigi else 39495002Strhodes return false; 39595002Strhodes } 39650215Sphk else 39750215Sphk return false; 39893394Sphk } 39919459Sjkh else 40019459Sjkh return true; 40119459Sjkh } 40219459Sjkh} 40319459Sjkh 404187239Sluigibool 40519459SjkhThreadPlanCallFunction::ShouldStop (Event *event_ptr) 40619459Sjkh{ 40793394Sphk // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete. 40819459Sjkh // We need to do that here to make sure our state is correct. 40919459Sjkh DoPlanExplainsStop(event_ptr); 41019459Sjkh 4114Srgrimes if (IsPlanComplete()) 4124Srgrimes { 41319459Sjkh ReportRegisterState ("Function completed. Register state was:"); 41465054Sjhb return true; 4154Srgrimes } 41620061Ssos else 41719459Sjkh { 41819459Sjkh return false; 41919459Sjkh } 42026421Sbrian} 42119459Sjkh 42219459Sjkhbool 4234SrgrimesThreadPlanCallFunction::StopOthers () 4244Srgrimes{ 42519459Sjkh return m_stop_other_threads; 4264Srgrimes} 4274Srgrimes 42848282Srnordiervoid 42943054SrnordierThreadPlanCallFunction::SetStopOthers (bool new_value) 43043054Srnordier{ 43148282Srnordier if (m_subplan_sp) 43295002Strhodes { 43319459Sjkh ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 43419459Sjkh address_plan->SetStopOthers(new_value); 43519459Sjkh } 436187239Sluigi m_stop_other_threads = new_value; 43795002Strhodes} 43819459Sjkh 4394SrgrimesStateType 440145763SnyanThreadPlanCallFunction::GetPlanRunState () 44119459Sjkh{ 44219459Sjkh return eStateRunning; 44319459Sjkh} 4444Srgrimes 4454Srgrimesvoid 4464SrgrimesThreadPlanCallFunction::DidPush () 44737415Scharnier{ 4484Srgrimes//#define SINGLE_STEP_EXPRESSIONS 44937415Scharnier 45037415Scharnier // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 45137415Scharnier // Wait till the plan is pushed so we aren't changing the stop info till we're about to run. 45248282Srnordier 453181036Sobrien GetThread().SetStopInfoToNothing(); 45448282Srnordier 45537415Scharnier#ifndef SINGLE_STEP_EXPRESSIONS 4564Srgrimes m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 4574Srgrimes 45816561Salex m_thread.QueueThreadPlan(m_subplan_sp, false); 459187239Sluigi m_subplan_sp->SetPrivate (true); 4604Srgrimes#endif 46193394Sphk} 4624Srgrimes 4634Srgrimesbool 4644SrgrimesThreadPlanCallFunction::WillStop () 465187241Sluigi{ 466187241Sluigi return true; 467187241Sluigi} 468187241Sluigi 4694Srgrimesbool 4704SrgrimesThreadPlanCallFunction::MischiefManaged () 47193394Sphk{ 4724Srgrimes Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 47316561Salex 474187241Sluigi if (IsPlanComplete()) 4754Srgrimes { 47626389Sgibbs if (log) 4774Srgrimes log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this); 4784Srgrimes 4794Srgrimes ThreadPlan::MischiefManaged (); 4804Srgrimes return true; 4814Srgrimes } 48226389Sgibbs else 48326389Sgibbs { 48426389Sgibbs return false; 48526389Sgibbs } 48626389Sgibbs} 48726389Sgibbs 48890866Sjoevoid 48990866SjoeThreadPlanCallFunction::SetBreakpoints () 490100202Sbde{ 49137244Sbde ProcessSP process_sp (m_thread.CalculateProcess()); 492226908Sjmg if (m_trap_exceptions && process_sp) 493100202Sbde { 49434952Sobrien m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 49534952Sobrien m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 49669371Sobrien 4974Srgrimes if (m_cxx_language_runtime) 49869371Sobrien { 4994Srgrimes m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); 5004Srgrimes m_cxx_language_runtime->SetExceptionBreakpoints(); 50169371Sobrien } 50269371Sobrien if (m_objc_language_runtime) 5034Srgrimes { 5044Srgrimes m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet(); 50519459Sjkh m_objc_language_runtime->SetExceptionBreakpoints(); 50616561Salex } 50719459Sjkh } 50819459Sjkh} 50995860Speter 51048282Srnordiervoid 51193394SphkThreadPlanCallFunction::ClearBreakpoints () 51263027Sjhb{ 51348282Srnordier if (m_trap_exceptions) 51448282Srnordier { 51593394Sphk if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) 51693394Sphk m_cxx_language_runtime->ClearExceptionBreakpoints(); 51763027Sjhb if (m_objc_language_runtime && m_should_clear_objc_exception_bp) 518226907Sjmg m_objc_language_runtime->ClearExceptionBreakpoints(); 519226907Sjmg } 52063027Sjhb} 52163027Sjhb 52263218Sachebool 52363218SacheThreadPlanCallFunction::BreakpointsExplainStop() 52463027Sjhb{ 52563027Sjhb StopInfoSP stop_info_sp = GetPrivateStopInfo (); 52693394Sphk 52793394Sphk if (m_trap_exceptions) 52848282Srnordier { 52963027Sjhb if ((m_cxx_language_runtime && 53063027Sjhb m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 53195860Speter ||(m_objc_language_runtime && 53295860Speter m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) 53395860Speter { 53495860Speter Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 53595860Speter if (log) 53695860Speter log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); 53795860Speter 538113454Sphk SetPlanComplete(false); 53995860Speter 54019459Sjkh // If the user has set the ObjC language breakpoint, it would normally get priority over our internal 54119459Sjkh // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. 54219459Sjkh stop_info_sp->OverrideShouldStop (true); 54319459Sjkh return true; 54416561Salex } 5454Srgrimes } 546187203Sluigi 5474Srgrimes return false; 54819459Sjkh} 5494Srgrimes 5504Srgrimesbool 5514SrgrimesThreadPlanCallFunction::RestoreThreadState() 55265054Sjhb{ 55363027Sjhb return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 55463027Sjhb} 5554Srgrimes 55665054Sjhb