17aa51b79SEd Maste //===-- ThreadPlan.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/lldb-python.h" 117aa51b79SEd Maste 127aa51b79SEd Maste #include "lldb/Target/ThreadPlan.h" 137aa51b79SEd Maste 147aa51b79SEd Maste // C Includes 157aa51b79SEd Maste // C++ Includes 167aa51b79SEd Maste // Other libraries and framework includes 177aa51b79SEd Maste // Project includes 187aa51b79SEd Maste #include "lldb/Core/Debugger.h" 197aa51b79SEd Maste #include "lldb/Core/Log.h" 207aa51b79SEd Maste #include "lldb/Core/State.h" 217aa51b79SEd Maste #include "lldb/Interpreter/CommandInterpreter.h" 227aa51b79SEd Maste #include "lldb/Interpreter/ScriptInterpreter.h" 237aa51b79SEd Maste #include "lldb/Interpreter/ScriptInterpreterPython.h" 247aa51b79SEd Maste #include "lldb/Target/RegisterContext.h" 257aa51b79SEd Maste #include "lldb/Target/Thread.h" 267aa51b79SEd Maste #include "lldb/Target/ThreadPlan.h" 277aa51b79SEd Maste #include "lldb/Target/ThreadPlanPython.h" 287aa51b79SEd Maste #include "lldb/Target/Process.h" 297aa51b79SEd Maste #include "lldb/Target/Target.h" 307aa51b79SEd Maste 317aa51b79SEd Maste using namespace lldb; 327aa51b79SEd Maste using namespace lldb_private; 337aa51b79SEd Maste 347aa51b79SEd Maste //---------------------------------------------------------------------- 357aa51b79SEd Maste // ThreadPlanPython 367aa51b79SEd Maste //---------------------------------------------------------------------- 377aa51b79SEd Maste 387aa51b79SEd Maste ThreadPlanPython::ThreadPlanPython (Thread &thread, const char *class_name) : 397aa51b79SEd Maste ThreadPlan (ThreadPlan::eKindPython, 407aa51b79SEd Maste "Python based Thread Plan", 417aa51b79SEd Maste thread, 427aa51b79SEd Maste eVoteNoOpinion, 437aa51b79SEd Maste eVoteNoOpinion), 447aa51b79SEd Maste m_class_name (class_name) 457aa51b79SEd Maste { 467aa51b79SEd Maste SetIsMasterPlan (true); 477aa51b79SEd Maste SetOkayToDiscard (true); 487aa51b79SEd Maste SetPrivate (false); 497aa51b79SEd Maste } 507aa51b79SEd Maste 517aa51b79SEd Maste ThreadPlanPython::~ThreadPlanPython () 527aa51b79SEd Maste { 537aa51b79SEd Maste // FIXME, do I need to decrement the ref count on this implementation object to make it go away? 547aa51b79SEd Maste } 557aa51b79SEd Maste 567aa51b79SEd Maste bool 577aa51b79SEd Maste ThreadPlanPython::ValidatePlan (Stream *error) 587aa51b79SEd Maste { 597aa51b79SEd Maste // I have to postpone setting up the implementation till after the constructor because I need to call 607aa51b79SEd Maste // shared_from_this, which you can't do in the constructor. So I'll do it here. 617aa51b79SEd Maste if (m_implementation_sp) 627aa51b79SEd Maste return true; 637aa51b79SEd Maste else 647aa51b79SEd Maste return false; 657aa51b79SEd Maste } 667aa51b79SEd Maste 677aa51b79SEd Maste void 687aa51b79SEd Maste ThreadPlanPython::DidPush() 697aa51b79SEd Maste { 707aa51b79SEd Maste // We set up the script side in DidPush, so that it can push other plans in the constructor, 717aa51b79SEd Maste // and doesn't have to care about the details of DidPush. 727aa51b79SEd Maste 737aa51b79SEd Maste if (!m_class_name.empty()) 747aa51b79SEd Maste { 757aa51b79SEd Maste ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 767aa51b79SEd Maste if (script_interp) 777aa51b79SEd Maste { 787aa51b79SEd Maste m_implementation_sp = script_interp->CreateScriptedThreadPlan (m_class_name.c_str(), this->shared_from_this()); 797aa51b79SEd Maste } 807aa51b79SEd Maste } 817aa51b79SEd Maste } 827aa51b79SEd Maste 837aa51b79SEd Maste bool 847aa51b79SEd Maste ThreadPlanPython::ShouldStop (Event *event_ptr) 857aa51b79SEd Maste { 867aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 877aa51b79SEd Maste if (log) 887aa51b79SEd Maste log->Printf ("%s called on Python Thread Plan: %s )", 897aa51b79SEd Maste __PRETTY_FUNCTION__, m_class_name.c_str()); 907aa51b79SEd Maste 917aa51b79SEd Maste bool should_stop = true; 927aa51b79SEd Maste if (m_implementation_sp) 937aa51b79SEd Maste { 947aa51b79SEd Maste ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 957aa51b79SEd Maste if (script_interp) 967aa51b79SEd Maste { 977aa51b79SEd Maste bool script_error; 987aa51b79SEd Maste should_stop = script_interp->ScriptedThreadPlanShouldStop (m_implementation_sp, event_ptr, script_error); 997aa51b79SEd Maste if (script_error) 1007aa51b79SEd Maste SetPlanComplete(false); 1017aa51b79SEd Maste } 1027aa51b79SEd Maste } 1037aa51b79SEd Maste return should_stop; 1047aa51b79SEd Maste } 1057aa51b79SEd Maste 1067aa51b79SEd Maste bool 1077aa51b79SEd Maste ThreadPlanPython::DoPlanExplainsStop (Event *event_ptr) 1087aa51b79SEd Maste { 1097aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 1107aa51b79SEd Maste if (log) 1117aa51b79SEd Maste log->Printf ("%s called on Python Thread Plan: %s )", 1127aa51b79SEd Maste __PRETTY_FUNCTION__, m_class_name.c_str()); 1137aa51b79SEd Maste 1147aa51b79SEd Maste bool explains_stop = true; 1157aa51b79SEd Maste if (m_implementation_sp) 1167aa51b79SEd Maste { 1177aa51b79SEd Maste ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1187aa51b79SEd Maste if (script_interp) 1197aa51b79SEd Maste { 1207aa51b79SEd Maste bool script_error; 1217aa51b79SEd Maste explains_stop = script_interp->ScriptedThreadPlanExplainsStop (m_implementation_sp, event_ptr, script_error); 1227aa51b79SEd Maste if (script_error) 1237aa51b79SEd Maste SetPlanComplete(false); 1247aa51b79SEd Maste } 1257aa51b79SEd Maste } 1267aa51b79SEd Maste return explains_stop; 1277aa51b79SEd Maste } 1287aa51b79SEd Maste 1297aa51b79SEd Maste bool 1307aa51b79SEd Maste ThreadPlanPython::MischiefManaged () 1317aa51b79SEd Maste { 1327aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 1337aa51b79SEd Maste if (log) 1347aa51b79SEd Maste log->Printf ("%s called on Python Thread Plan: %s )", 1357aa51b79SEd Maste __PRETTY_FUNCTION__, m_class_name.c_str()); 1367aa51b79SEd Maste bool mischief_managed = true; 1377aa51b79SEd Maste if (m_implementation_sp) 1387aa51b79SEd Maste { 1397aa51b79SEd Maste // I don't really need mischief_managed, since it's simpler to just call SetPlanComplete in should_stop. 1407aa51b79SEd Maste mischief_managed = IsPlanComplete(); 1417aa51b79SEd Maste if (mischief_managed) 1427aa51b79SEd Maste m_implementation_sp.reset(); 1437aa51b79SEd Maste } 1447aa51b79SEd Maste return mischief_managed; 1457aa51b79SEd Maste } 1467aa51b79SEd Maste 1477aa51b79SEd Maste lldb::StateType 1487aa51b79SEd Maste ThreadPlanPython::GetPlanRunState () 1497aa51b79SEd Maste { 1507aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 1517aa51b79SEd Maste if (log) 1527aa51b79SEd Maste log->Printf ("%s called on Python Thread Plan: %s )", 1537aa51b79SEd Maste __PRETTY_FUNCTION__, 1547aa51b79SEd Maste m_class_name.c_str()); 1557aa51b79SEd Maste lldb::StateType run_state = eStateRunning; 1567aa51b79SEd Maste if (m_implementation_sp) 1577aa51b79SEd Maste { 1587aa51b79SEd Maste ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1597aa51b79SEd Maste if (script_interp) 1607aa51b79SEd Maste { 1617aa51b79SEd Maste bool script_error; 1627aa51b79SEd Maste run_state = script_interp->ScriptedThreadPlanGetRunState (m_implementation_sp, script_error); 1637aa51b79SEd Maste } 1647aa51b79SEd Maste } 1657aa51b79SEd Maste return run_state; 1667aa51b79SEd Maste } 1677aa51b79SEd Maste 1687aa51b79SEd Maste // The ones below are not currently exported to Python. 1697aa51b79SEd Maste 1707aa51b79SEd Maste bool 1717aa51b79SEd Maste ThreadPlanPython::StopOthers () 1727aa51b79SEd Maste { 1737aa51b79SEd Maste // For now Python plans run all threads, but we should add some controls for this. 1747aa51b79SEd Maste return false; 1757aa51b79SEd Maste } 1767aa51b79SEd Maste 1777aa51b79SEd Maste void 1787aa51b79SEd Maste ThreadPlanPython::GetDescription (Stream *s, 1797aa51b79SEd Maste lldb::DescriptionLevel level) 1807aa51b79SEd Maste { 1817aa51b79SEd Maste s->Printf ("Python thread plan implemented by class %s.", m_class_name.c_str()); 1827aa51b79SEd Maste } 1837aa51b79SEd Maste 1847aa51b79SEd Maste bool 1857aa51b79SEd Maste ThreadPlanPython::WillStop () 1867aa51b79SEd Maste { 1877aa51b79SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 1887aa51b79SEd Maste if (log) 1897aa51b79SEd Maste log->Printf ("%s called on Python Thread Plan: %s )", 1907aa51b79SEd Maste __PRETTY_FUNCTION__, m_class_name.c_str()); 1917aa51b79SEd Maste return true; 1927aa51b79SEd Maste } 193