124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanCallFunction.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1507f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan#include "llvm/Support/MachO.h" 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h" 18988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham#include "lldb/Breakpoint/Breakpoint.h" 19988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham#include "lldb/Breakpoint/BreakpointLocation.h" 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Address.h" 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 2249ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h" 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h" 2449ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/ObjectFile.h" 2529756d452be39535ded2cff50d9db4df46fe6400Sean Callanan#include "lldb/Target/LanguageRuntime.h" 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h" 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h" 28988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham#include "lldb/Target/StopInfo.h" 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Target.h" 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h" 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanRunToAddress.h" 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ThreadPlanCallFunction: Plan to call a single function 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 391e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Inghambool 401e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim InghamThreadPlanCallFunction::ConstructorSetup (Thread &thread, 411e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham ABI *& abi, 421e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham lldb::addr_t &start_load_addr, 431e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham lldb::addr_t &function_load_addr) 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 452bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham SetIsMasterPlan (true); 46110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham SetOkayToDiscard (false); 47ae0f59cf7c300089bb649fbb6159299d3ea0b143Andrew Kaylor SetPrivate (true); 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49f4124deeb9532044a38c0774ced872f2709347daGreg Clayton ProcessSP process_sp (thread.GetProcess()); 50f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (!process_sp) 511e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 52f4124deeb9532044a38c0774ced872f2709347daGreg Clayton 531e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham abi = process_sp->GetABI().get(); 5407f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!abi) 561e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 5707f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 58f4124deeb9532044a38c0774ced872f2709347daGreg Clayton TargetSP target_sp (thread.CalculateTarget()); 59f4124deeb9532044a38c0774ced872f2709347daGreg Clayton 60952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 6115dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham 6207f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan SetBreakpoints(); 6307f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 640ddf806dd9e71637846bf0ad46e1b2df7d02cbceSean Callanan m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 651e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham // If we can't read memory at the point of the process where we are planning to put our function, we're 661e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham // not going to get any further... 671e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham Error error; 681e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 691e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham if (!error.Success()) 701e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham { 71845970ec09b437160da1095006d74b82ef05195fJim Ingham m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp); 721e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham if (log) 73845970ec09b437160da1095006d74b82ef05195fJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 741e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 751e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham } 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 77f4124deeb9532044a38c0774ced872f2709347daGreg Clayton Module *exe_module = target_sp->GetExecutableModulePointer(); 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 795beb99d65c72cd4a4f7529c4ff8cc04a1a40769dGreg Clayton if (exe_module == NULL) 802877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham { 81845970ec09b437160da1095006d74b82ef05195fJim Ingham m_constructor_errors.Printf ("Can't execute code without an executable module."); 829d56ba96d520710c55874132d44a64de1257d2faJohnny Chen if (log) 83845970ec09b437160da1095006d74b82ef05195fJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 841e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 852877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham } 862877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham else 872877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham { 885beb99d65c72cd4a4f7529c4ff8cc04a1a40769dGreg Clayton ObjectFile *objectFile = exe_module->GetObjectFile(); 892877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham if (!objectFile) 902877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham { 91845970ec09b437160da1095006d74b82ef05195fJim Ingham m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 92845970ec09b437160da1095006d74b82ef05195fJim Ingham exe_module->GetFileSpec().GetFilename().AsCString()); 93845970ec09b437160da1095006d74b82ef05195fJim Ingham 949d56ba96d520710c55874132d44a64de1257d2faJohnny Chen if (log) 95845970ec09b437160da1095006d74b82ef05195fJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 961e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 972877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham } 98845970ec09b437160da1095006d74b82ef05195fJim Ingham 992877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham m_start_addr = objectFile->GetEntryPointAddress(); 1002877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham if (!m_start_addr.IsValid()) 1012877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham { 102845970ec09b437160da1095006d74b82ef05195fJim Ingham m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 103845970ec09b437160da1095006d74b82ef05195fJim Ingham exe_module->GetFileSpec().GetFilename().AsCString()); 1049d56ba96d520710c55874132d44a64de1257d2faJohnny Chen if (log) 105845970ec09b437160da1095006d74b82ef05195fJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 1061e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 1072877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham } 1082877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham } 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1101e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham start_load_addr = m_start_addr.GetLoadAddress (target_sp.get()); 1112877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham 11215dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham // Checkpoint the thread state so we can restore it later. 1132f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham if (log && log->GetVerbose()) 1142f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 1152f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham 11615dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham if (!thread.CheckpointThreadState (m_stored_thread_state)) 11715dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham { 118845970ec09b437160da1095006d74b82ef05195fJim Ingham m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 11915dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham if (log) 120845970ec09b437160da1095006d74b82ef05195fJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 1211e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return false; 12215dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham } 1231e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham function_load_addr = m_function_addr.GetLoadAddress (target_sp.get()); 1241e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham 1251e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return true; 1261e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham} 1271e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham 1281e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim InghamThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 1294f9103faba72fdfc4b4299d6d459bc820ee597b2Matt Kopec const Address &function, 1301e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham const ClangASTType &return_type, 1311e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham addr_t arg, 1321e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham bool stop_other_threads, 133b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham bool unwind_on_error, 134b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham bool ignore_breakpoints, 1351e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham addr_t *this_arg, 1361e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham addr_t *cmd_arg) : 1371e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 1381e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_valid (false), 1391e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_stop_other_threads (stop_other_threads), 1401e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_function_addr (function), 1415ebd51f464587ba848698fdf48429adc8bad9068Filipe Cabecinhas m_function_sp (0), 1421e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_return_type (return_type), 1431e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_takedown_done (false), 144110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham m_stop_address (LLDB_INVALID_ADDRESS), 145b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham m_unwind_on_error (unwind_on_error), 146b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham m_ignore_breakpoints (ignore_breakpoints) 1471e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham{ 1481e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham lldb::addr_t start_load_addr; 1491e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham ABI *abi; 1501e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham lldb::addr_t function_load_addr; 151110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) 1521e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham return; 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15461d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton if (this_arg && cmd_arg) 15561d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton { 15661d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton if (!abi->PrepareTrivialCall (thread, 15761d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton m_function_sp, 1581e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham function_load_addr, 159989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton start_load_addr, 16061d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton this_arg, 16161d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton cmd_arg, 162989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton &arg)) 16361d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton return; 16461d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton } 16561d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton else if (this_arg) 16661d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton { 16761d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton if (!abi->PrepareTrivialCall (thread, 16861d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton m_function_sp, 1691e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham function_load_addr, 170989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton start_load_addr, 17161d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton this_arg, 172989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton &arg)) 17361d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton return; 17461d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton } 17561d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton else 17661d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton { 17761d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton if (!abi->PrepareTrivialCall (thread, 17861d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton m_function_sp, 1791e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham function_load_addr, 180989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton start_load_addr, 181989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton &arg)) 182989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton return; 183989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton } 184989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton 185989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton ReportRegisterState ("Function call was set up. Register state was:"); 186989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton 187989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton m_valid = true; 188989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton} 189989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton 190989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton 191989816b9505219cd67ce044d655c54ac86ecf64bGreg ClaytonThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 1924f9103faba72fdfc4b4299d6d459bc820ee597b2Matt Kopec const Address &function, 193016ef8886cd429f8a53bff967e601f831e409eaaJim Ingham const ClangASTType &return_type, 194989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton bool stop_other_threads, 195b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham bool unwind_on_error, 196b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham bool ignore_breakpoints, 197989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton addr_t *arg1_ptr, 198989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton addr_t *arg2_ptr, 199989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton addr_t *arg3_ptr, 200989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton addr_t *arg4_ptr, 201989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton addr_t *arg5_ptr, 202989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton addr_t *arg6_ptr) : 203989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 204989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton m_valid (false), 205989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton m_stop_other_threads (stop_other_threads), 206574c3d63822cc7fd52bf6f6a94b6882fec4c8ce9Jim Ingham m_function_addr (function), 20776b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham m_function_sp (0), 208016ef8886cd429f8a53bff967e601f831e409eaaJim Ingham m_return_type (return_type), 2091e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_takedown_done (false), 21076b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham m_stop_address (LLDB_INVALID_ADDRESS), 211b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham m_unwind_on_error (unwind_on_error), 212b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham m_ignore_breakpoints (ignore_breakpoints) 213989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton{ 2141e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham lldb::addr_t start_load_addr; 2151e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham ABI *abi; 2161e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham lldb::addr_t function_load_addr; 217110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) 218f4124deeb9532044a38c0774ced872f2709347daGreg Clayton return; 219f4124deeb9532044a38c0774ced872f2709347daGreg Clayton 220989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton if (!abi->PrepareTrivialCall (thread, 2211e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham m_function_sp, 2221e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham function_load_addr, 223989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton start_load_addr, 224989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton arg1_ptr, 225989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton arg2_ptr, 226989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton arg3_ptr, 227989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton arg4_ptr, 228989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton arg5_ptr, 229989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton arg6_ptr)) 230989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton { 23161d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton return; 23261d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton } 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2342f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham ReportRegisterState ("Function call was set up. Register state was:"); 2352f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham 2362f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham m_valid = true; 2372f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham} 2382f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham 2392f6267ff7af90c14fe08fd88bac6a63a02069033Jim InghamThreadPlanCallFunction::~ThreadPlanCallFunction () 2402f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham{ 24189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham DoTakedown(PlanSucceeded()); 2422f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham} 2432f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham 2442f6267ff7af90c14fe08fd88bac6a63a02069033Jim Inghamvoid 2452f6267ff7af90c14fe08fd88bac6a63a02069033Jim InghamThreadPlanCallFunction::ReportRegisterState (const char *message) 2462f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham{ 247952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 2486dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan if (log) 2496dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan { 250628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton StreamString strm; 25108d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 2522f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham 2532f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham log->PutCString(message); 2542f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham 255628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton RegisterValue reg_value; 256628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton 257628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 258628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton reg_idx < num_registers; 259628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton ++reg_idx) 2606dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan { 261628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 262628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton if (reg_ctx->ReadRegister(reg_info, reg_value)) 263628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton { 264628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 265628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton strm.EOL(); 266628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton } 2676dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan } 268628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton log->PutCString(strm.GetData()); 2696dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan } 27014a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan} 27114a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan 27214a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callananvoid 273038fa8e30621e0e55faed3479387d811986f28b7Jim InghamThreadPlanCallFunction::DoTakedown (bool success) 27414a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan{ 275952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 276a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham 277a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham if (!m_valid) 278a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham { 279a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham //Don't call DoTakedown if we were never valid to begin with. 280a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham if (log) 281a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this); 282a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham return; 283a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham } 284a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham 2852f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham if (!m_takedown_done) 28615dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham { 287038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham if (success) 2882f085c6ca2895663687dca704589478ff040b849Greg Clayton { 289038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham ProcessSP process_sp (m_thread.GetProcess()); 290038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 291038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham if (abi && m_return_type.IsValid()) 292038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham { 293038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham const bool persistent = false; 294038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent); 295038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham } 2962f085c6ca2895663687dca704589478ff040b849Greg Clayton } 2972f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham if (log) 2985f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea 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()); 2992f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham m_takedown_done = true; 300ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 30104cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham m_real_stop_info_sp = GetPrivateStopInfo (); 30276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state); 303038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham SetPlanComplete(success); 30415dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham ClearBreakpoints(); 3052f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham if (log && log->GetVerbose()) 3062f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 30778108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham 3082f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham } 3092f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham else 3102f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham { 3112f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham if (log) 3125f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea 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()); 31315dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham } 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 3176c9662e0e5840b557fcd4bd990620e106e4a18e2Jim InghamThreadPlanCallFunction::WillPop () 3186c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Ingham{ 31989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham DoTakedown(PlanSucceeded()); 3206c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Ingham} 3216c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Ingham 3226c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Inghamvoid 323989816b9505219cd67ce044d655c54ac86ecf64bGreg ClaytonThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 325989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton if (level == eDescriptionLevelBrief) 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->Printf("Function call thread plan"); 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 331f4124deeb9532044a38c0774ced872f2709347daGreg Clayton TargetSP target_sp (m_thread.CalculateTarget()); 3325f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get())); 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::ValidatePlan (Stream *error) 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!m_valid) 340845970ec09b437160da1095006d74b82ef05195fJim Ingham { 341845970ec09b437160da1095006d74b82ef05195fJim Ingham if (error) 342845970ec09b437160da1095006d74b82ef05195fJim Ingham { 343845970ec09b437160da1095006d74b82ef05195fJim Ingham if (m_constructor_errors.GetSize() > 0) 344845970ec09b437160da1095006d74b82ef05195fJim Ingham error->PutCString (m_constructor_errors.GetData()); 345845970ec09b437160da1095006d74b82ef05195fJim Ingham else 346845970ec09b437160da1095006d74b82ef05195fJim Ingham error->PutCString ("Unknown error"); 347845970ec09b437160da1095006d74b82ef05195fJim Ingham } 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 349845970ec09b437160da1095006d74b82ef05195fJim Ingham } 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham 35589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim InghamVote 35689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim InghamThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) 35789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham{ 35889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (m_takedown_done || IsPlanComplete()) 35989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham return eVoteYes; 36089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham else 36189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham return ThreadPlan::ShouldReportStop(event_ptr); 36289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham} 36389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 3657c79a27b955432dfd3ad9439640f0af2eccf37b8Jim InghamThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) 36607f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan{ 367952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS)); 36804cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham m_real_stop_info_sp = GetPrivateStopInfo (); 3692370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham 370988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 371988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham // we answer yes. 37289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr)) 373b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham { 374b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham SetPlanComplete(); 375988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham return true; 376b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham } 377ba8547d98b305f7eec3fa24ddbe9a633ffe2f8f2Sean Callanan 37894fb5432f10882f8917acb7849abdba7c61277acSean Callanan // Check if the breakpoint is one of ours. 37994fb5432f10882f8917acb7849abdba7c61277acSean Callanan 380038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham StopReason stop_reason; 381038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham if (!m_real_stop_info_sp) 382038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham stop_reason = eStopReasonNone; 383038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham else 384038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham stop_reason = m_real_stop_info_sp->GetStopReason(); 38589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (log) 38689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason)); 387038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham 388038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 38994fb5432f10882f8917acb7849abdba7c61277acSean Callanan return true; 39094fb5432f10882f8917acb7849abdba7c61277acSean Callanan 39189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // We control breakpoints separately from other "stop reasons." So first, 39289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // check the case where we stopped for an internal breakpoint, in that case, continue on. 39389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // If it is not an internal breakpoint, consult m_ignore_breakpoints. 39407f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 395038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham 396038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham if (stop_reason == eStopReasonBreakpoint) 397988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham { 398f4124deeb9532044a38c0774ced872f2709347daGreg Clayton ProcessSP process_sp (m_thread.CalculateProcess()); 3992370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 400f4124deeb9532044a38c0774ced872f2709347daGreg Clayton BreakpointSiteSP bp_site_sp; 401f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (process_sp) 402f4124deeb9532044a38c0774ced872f2709347daGreg Clayton bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 403988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham if (bp_site_sp) 404988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham { 405988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 406988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham bool is_internal = true; 407988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham for (uint32_t i = 0; i < num_owners; i++) 408988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham { 40907f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 41089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (log) 41189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID()); 41207f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 41307f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan if (!bp.IsInternal()) 414988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham { 415988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham is_internal = false; 416988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham break; 417988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham } 418988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham } 419988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham if (is_internal) 42089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 42189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (log) 42289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping."); 423988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham return false; 42489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 425988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham } 42689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham 427b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham if (m_ignore_breakpoints) 428110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham { 42989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (log) 43089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 43189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham m_real_stop_info_sp->OverrideShouldStop(false); 432110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham return true; 433110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham } 434110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham else 43589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 43689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (log) 43789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 43889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham m_real_stop_info_sp->OverrideShouldStop(true); 439110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham return false; 44089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 44189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 44289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham else if (!m_unwind_on_error) 44389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 44489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 44589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham return false; 446988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham } 447988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham else 448988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham { 449988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham // If the subplan is running, any crashes are attributable to us. 45078108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham // If we want to discard the plan, then we say we explain the stop 45178108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham // but if we are going to be discarded, let whoever is above us 45278108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham // explain the stop. 45389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // But don't discard the plan if the stop would restart itself (for instance if it is a 45489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // signal that is set not to stop. Check that here first. We just say we explain the stop 45589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham // but aren't done and everything will continue on from there. 45689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham 45789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) 458038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham { 45989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham SetPlanComplete(false); 46089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (m_subplan_sp) 461038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham { 46289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (m_unwind_on_error) 46389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham return true; 46489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham else 46589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham return false; 466038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham } 467038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham else 468038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham return false; 469038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham } 470038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham else 47189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham return true; 472988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham } 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::ShouldStop (Event *event_ptr) 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4787c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete. 479b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham // We need to do that here to make sure our state is correct. 4807c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham DoPlanExplainsStop(event_ptr); 481b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham 482b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham if (IsPlanComplete()) 48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 4842f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham ReportRegisterState ("Function completed. Register state was:"); 48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::StopOthers () 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_stop_other_threads; 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::SetStopOthers (bool new_value) 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_subplan_sp) 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner address_plan->SetStopOthers(new_value); 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_stop_other_threads = new_value; 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStateType 511745ac7a5826fe7c392007941a4046bfb1a8dff81Jim InghamThreadPlanCallFunction::GetPlanRunState () 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return eStateRunning; 51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::DidPush () 51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 519c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan//#define SINGLE_STEP_EXPRESSIONS 520c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan 52176b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 52276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham // Wait till the plan is pushed so we aren't changing the stop info till we're about to run. 52376b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham 52476b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham GetThread().SetStopInfoToNothing(); 52576b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham 526c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan#ifndef SINGLE_STEP_EXPRESSIONS 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_thread.QueueThreadPlan(m_subplan_sp, false); 53015dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham m_subplan_sp->SetPrivate (true); 531c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan#endif 53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::WillStop () 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::MischiefManaged () 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 543952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 544b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham 54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (IsPlanComplete()) 54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 548a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this); 54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlan::MischiefManaged (); 55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 55807f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 55907f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callananvoid 56007f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean CallananThreadPlanCallFunction::SetBreakpoints () 56107f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan{ 562f4124deeb9532044a38c0774ced872f2709347daGreg Clayton ProcessSP process_sp (m_thread.CalculateProcess()); 563f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (process_sp) 564f4124deeb9532044a38c0774ced872f2709347daGreg Clayton { 565f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 566f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 56707f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 568f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (m_cxx_language_runtime) 569f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_cxx_language_runtime->SetExceptionBreakpoints(); 570f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (m_objc_language_runtime) 571f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_objc_language_runtime->SetExceptionBreakpoints(); 572f4124deeb9532044a38c0774ced872f2709347daGreg Clayton } 57307f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan} 57407f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan 57507f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callananvoid 57607f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean CallananThreadPlanCallFunction::ClearBreakpoints () 57707f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan{ 57829756d452be39535ded2cff50d9db4df46fe6400Sean Callanan if (m_cxx_language_runtime) 57929756d452be39535ded2cff50d9db4df46fe6400Sean Callanan m_cxx_language_runtime->ClearExceptionBreakpoints(); 58029756d452be39535ded2cff50d9db4df46fe6400Sean Callanan if (m_objc_language_runtime) 58129756d452be39535ded2cff50d9db4df46fe6400Sean Callanan m_objc_language_runtime->ClearExceptionBreakpoints(); 58207f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan} 58394fb5432f10882f8917acb7849abdba7c61277acSean Callanan 58494fb5432f10882f8917acb7849abdba7c61277acSean Callananbool 58594fb5432f10882f8917acb7849abdba7c61277acSean CallananThreadPlanCallFunction::BreakpointsExplainStop() 58694fb5432f10882f8917acb7849abdba7c61277acSean Callanan{ 58704cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham StopInfoSP stop_info_sp = GetPrivateStopInfo (); 58894fb5432f10882f8917acb7849abdba7c61277acSean Callanan 589b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham if ((m_cxx_language_runtime && 590b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 591b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham ||(m_objc_language_runtime && 592b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) 593b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham { 5940086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 5950086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham if (log) 5960086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); 5970086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham 598b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham SetPlanComplete(false); 5990086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham 6000086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham // If the user has set the ObjC language breakpoint, it would normally get priority over our internal 6010086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. 6020086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham stop_info_sp->OverrideShouldStop (true); 60329756d452be39535ded2cff50d9db4df46fe6400Sean Callanan return true; 604b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham } 605b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham 60694fb5432f10882f8917acb7849abdba7c61277acSean Callanan return false; 60794fb5432f10882f8917acb7849abdba7c61277acSean Callanan} 60876b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham 60976b258db0611dad2f5b5ae51721a4bc0abd580aeJim Inghambool 61076b258db0611dad2f5b5ae51721a4bc0abd580aeJim InghamThreadPlanCallFunction::RestoreThreadState() 61176b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham{ 61276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 61376b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham} 61476b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham 615