1435933ddSDimitry Andric //===-- ThreadPlanPython.cpp ------------------------------------*- C++ -*-===// 27aa51b79SEd Maste // 37aa51b79SEd Maste // The LLVM Compiler Infrastructure 47aa51b79SEd Maste // 57aa51b79SEd Maste // This file is distributed under the University of Illinois Open Source 67aa51b79SEd Maste // License. See LICENSE.TXT for details. 77aa51b79SEd Maste // 87aa51b79SEd Maste //===----------------------------------------------------------------------===// 97aa51b79SEd Maste 107aa51b79SEd Maste #include "lldb/Target/ThreadPlan.h" 117aa51b79SEd Maste 127aa51b79SEd Maste // C Includes 137aa51b79SEd Maste // C++ Includes 147aa51b79SEd Maste // Other libraries and framework includes 157aa51b79SEd Maste // Project includes 167aa51b79SEd Maste #include "lldb/Core/Debugger.h" 177aa51b79SEd Maste #include "lldb/Core/State.h" 187aa51b79SEd Maste #include "lldb/Interpreter/CommandInterpreter.h" 197aa51b79SEd Maste #include "lldb/Interpreter/ScriptInterpreter.h" 20435933ddSDimitry Andric #include "lldb/Target/Process.h" 217aa51b79SEd Maste #include "lldb/Target/RegisterContext.h" 22435933ddSDimitry Andric #include "lldb/Target/Target.h" 237aa51b79SEd Maste #include "lldb/Target/Thread.h" 247aa51b79SEd Maste #include "lldb/Target/ThreadPlan.h" 257aa51b79SEd Maste #include "lldb/Target/ThreadPlanPython.h" 26f678e45dSDimitry Andric #include "lldb/Utility/Log.h" 277aa51b79SEd Maste 287aa51b79SEd Maste using namespace lldb; 297aa51b79SEd Maste using namespace lldb_private; 307aa51b79SEd Maste 317aa51b79SEd Maste //---------------------------------------------------------------------- 327aa51b79SEd Maste // ThreadPlanPython 337aa51b79SEd Maste //---------------------------------------------------------------------- 347aa51b79SEd Maste 35435933ddSDimitry Andric ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name) 36435933ddSDimitry Andric : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread, 37435933ddSDimitry Andric eVoteNoOpinion, eVoteNoOpinion), 38435933ddSDimitry Andric m_class_name(class_name) { 397aa51b79SEd Maste SetIsMasterPlan(true); 407aa51b79SEd Maste SetOkayToDiscard(true); 417aa51b79SEd Maste SetPrivate(false); 427aa51b79SEd Maste } 437aa51b79SEd Maste 44435933ddSDimitry Andric ThreadPlanPython::~ThreadPlanPython() { 45435933ddSDimitry Andric // FIXME, do I need to decrement the ref count on this implementation object 46435933ddSDimitry Andric // to make it go away? 477aa51b79SEd Maste } 487aa51b79SEd Maste 49435933ddSDimitry Andric bool ThreadPlanPython::ValidatePlan(Stream *error) { 50435933ddSDimitry Andric // I have to postpone setting up the implementation till after the constructor 51435933ddSDimitry Andric // because I need to call 52435933ddSDimitry Andric // shared_from_this, which you can't do in the constructor. So I'll do it 53435933ddSDimitry Andric // here. 547aa51b79SEd Maste if (m_implementation_sp) 557aa51b79SEd Maste return true; 567aa51b79SEd Maste else 577aa51b79SEd Maste return false; 587aa51b79SEd Maste } 597aa51b79SEd Maste 60435933ddSDimitry Andric void ThreadPlanPython::DidPush() { 61435933ddSDimitry Andric // We set up the script side in DidPush, so that it can push other plans in 62435933ddSDimitry Andric // the constructor, 637aa51b79SEd Maste // and doesn't have to care about the details of DidPush. 647aa51b79SEd Maste 65435933ddSDimitry Andric if (!m_class_name.empty()) { 66435933ddSDimitry Andric ScriptInterpreter *script_interp = m_thread.GetProcess() 67435933ddSDimitry Andric ->GetTarget() 68435933ddSDimitry Andric .GetDebugger() 69435933ddSDimitry Andric .GetCommandInterpreter() 70435933ddSDimitry Andric .GetScriptInterpreter(); 71435933ddSDimitry Andric if (script_interp) { 72435933ddSDimitry Andric m_implementation_sp = script_interp->CreateScriptedThreadPlan( 73435933ddSDimitry Andric m_class_name.c_str(), this->shared_from_this()); 747aa51b79SEd Maste } 757aa51b79SEd Maste } 767aa51b79SEd Maste } 777aa51b79SEd Maste 78435933ddSDimitry Andric bool ThreadPlanPython::ShouldStop(Event *event_ptr) { 797aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 807aa51b79SEd Maste if (log) 81435933ddSDimitry Andric log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, 82435933ddSDimitry Andric m_class_name.c_str()); 837aa51b79SEd Maste 847aa51b79SEd Maste bool should_stop = true; 85435933ddSDimitry Andric if (m_implementation_sp) { 86435933ddSDimitry Andric ScriptInterpreter *script_interp = m_thread.GetProcess() 87435933ddSDimitry Andric ->GetTarget() 88435933ddSDimitry Andric .GetDebugger() 89435933ddSDimitry Andric .GetCommandInterpreter() 90435933ddSDimitry Andric .GetScriptInterpreter(); 91435933ddSDimitry Andric if (script_interp) { 927aa51b79SEd Maste bool script_error; 93435933ddSDimitry Andric should_stop = script_interp->ScriptedThreadPlanShouldStop( 94435933ddSDimitry Andric m_implementation_sp, event_ptr, script_error); 957aa51b79SEd Maste if (script_error) 967aa51b79SEd Maste SetPlanComplete(false); 977aa51b79SEd Maste } 987aa51b79SEd Maste } 997aa51b79SEd Maste return should_stop; 1007aa51b79SEd Maste } 1017aa51b79SEd Maste 102435933ddSDimitry Andric bool ThreadPlanPython::IsPlanStale() { 1037aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 1047aa51b79SEd Maste if (log) 105435933ddSDimitry Andric log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, 106435933ddSDimitry Andric m_class_name.c_str()); 107435933ddSDimitry Andric 108435933ddSDimitry Andric bool is_stale = true; 109435933ddSDimitry Andric if (m_implementation_sp) { 110435933ddSDimitry Andric ScriptInterpreter *script_interp = m_thread.GetProcess() 111435933ddSDimitry Andric ->GetTarget() 112435933ddSDimitry Andric .GetDebugger() 113435933ddSDimitry Andric .GetCommandInterpreter() 114435933ddSDimitry Andric .GetScriptInterpreter(); 115435933ddSDimitry Andric if (script_interp) { 116435933ddSDimitry Andric bool script_error; 117435933ddSDimitry Andric is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp, 118435933ddSDimitry Andric script_error); 119435933ddSDimitry Andric if (script_error) 120435933ddSDimitry Andric SetPlanComplete(false); 121435933ddSDimitry Andric } 122435933ddSDimitry Andric } 123435933ddSDimitry Andric return is_stale; 124435933ddSDimitry Andric } 125435933ddSDimitry Andric 126435933ddSDimitry Andric bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) { 127435933ddSDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 128435933ddSDimitry Andric if (log) 129435933ddSDimitry Andric log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, 130435933ddSDimitry Andric m_class_name.c_str()); 1317aa51b79SEd Maste 1327aa51b79SEd Maste bool explains_stop = true; 133435933ddSDimitry Andric if (m_implementation_sp) { 134435933ddSDimitry Andric ScriptInterpreter *script_interp = m_thread.GetProcess() 135435933ddSDimitry Andric ->GetTarget() 136435933ddSDimitry Andric .GetDebugger() 137435933ddSDimitry Andric .GetCommandInterpreter() 138435933ddSDimitry Andric .GetScriptInterpreter(); 139435933ddSDimitry Andric if (script_interp) { 1407aa51b79SEd Maste bool script_error; 141435933ddSDimitry Andric explains_stop = script_interp->ScriptedThreadPlanExplainsStop( 142435933ddSDimitry Andric m_implementation_sp, event_ptr, script_error); 1437aa51b79SEd Maste if (script_error) 1447aa51b79SEd Maste SetPlanComplete(false); 1457aa51b79SEd Maste } 1467aa51b79SEd Maste } 1477aa51b79SEd Maste return explains_stop; 1487aa51b79SEd Maste } 1497aa51b79SEd Maste 150435933ddSDimitry Andric bool ThreadPlanPython::MischiefManaged() { 1517aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 1527aa51b79SEd Maste if (log) 153435933ddSDimitry Andric log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, 154435933ddSDimitry Andric m_class_name.c_str()); 1557aa51b79SEd Maste bool mischief_managed = true; 156435933ddSDimitry Andric if (m_implementation_sp) { 157435933ddSDimitry Andric // I don't really need mischief_managed, since it's simpler to just call 158435933ddSDimitry Andric // SetPlanComplete in should_stop. 1597aa51b79SEd Maste mischief_managed = IsPlanComplete(); 1607aa51b79SEd Maste if (mischief_managed) 1617aa51b79SEd Maste m_implementation_sp.reset(); 1627aa51b79SEd Maste } 1637aa51b79SEd Maste return mischief_managed; 1647aa51b79SEd Maste } 1657aa51b79SEd Maste 166435933ddSDimitry Andric lldb::StateType ThreadPlanPython::GetPlanRunState() { 1677aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 1687aa51b79SEd Maste if (log) 169435933ddSDimitry Andric log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, 1707aa51b79SEd Maste m_class_name.c_str()); 1717aa51b79SEd Maste lldb::StateType run_state = eStateRunning; 172435933ddSDimitry Andric if (m_implementation_sp) { 173435933ddSDimitry Andric ScriptInterpreter *script_interp = m_thread.GetProcess() 174435933ddSDimitry Andric ->GetTarget() 175435933ddSDimitry Andric .GetDebugger() 176435933ddSDimitry Andric .GetCommandInterpreter() 177435933ddSDimitry Andric .GetScriptInterpreter(); 178435933ddSDimitry Andric if (script_interp) { 1797aa51b79SEd Maste bool script_error; 180435933ddSDimitry Andric run_state = script_interp->ScriptedThreadPlanGetRunState( 181435933ddSDimitry Andric m_implementation_sp, script_error); 1827aa51b79SEd Maste } 1837aa51b79SEd Maste } 1847aa51b79SEd Maste return run_state; 1857aa51b79SEd Maste } 1867aa51b79SEd Maste 1877aa51b79SEd Maste // The ones below are not currently exported to Python. 1887aa51b79SEd Maste 189435933ddSDimitry Andric bool ThreadPlanPython::StopOthers() { 190435933ddSDimitry Andric // For now Python plans run all threads, but we should add some controls for 191435933ddSDimitry Andric // this. 1927aa51b79SEd Maste return false; 1937aa51b79SEd Maste } 1947aa51b79SEd Maste 195435933ddSDimitry Andric void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) { 196435933ddSDimitry Andric s->Printf("Python thread plan implemented by class %s.", 197435933ddSDimitry Andric m_class_name.c_str()); 1987aa51b79SEd Maste } 1997aa51b79SEd Maste 200435933ddSDimitry Andric bool ThreadPlanPython::WillStop() { 2017aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 2027aa51b79SEd Maste if (log) 203435933ddSDimitry Andric log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, 204435933ddSDimitry Andric m_class_name.c_str()); 2057aa51b79SEd Maste return true; 2067aa51b79SEd Maste } 207