ThreadPlanStepInRange.cpp revision 20594b1b003f63ed34ebafeec37634ee44552339
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadPlanStepInRange.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/ThreadPlanStepInRange.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h" 20809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham#include "lldb/Symbol/Symbol.h" 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h" 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h" 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h" 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanStepOut.h" 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanStepThrough.h" 26809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham#include "lldb/Core/RegularExpression.h" 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t ThreadPlanStepInRange::s_default_flag_values = ThreadPlanShouldStopHere::eAvoidNoDebug; 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ThreadPlanStepInRange: Step through a stack range, either stepping over or into 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// based on the value of \a type. 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::ThreadPlanStepInRange 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Thread &thread, 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const AddressRange &range, 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const SymbolContext &addr_context, 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb::RunMode stop_others 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) : 455a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others), 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL) 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetFlagsToDefault (); 49809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham // SetAvoidRegexp("^std\\:\\:.*"); 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::~ThreadPlanStepInRange () 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::GetDescription (Stream *s, lldb::DescriptionLevel level) 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (level == lldb::eDescriptionLevelBrief) 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->Printf("step in"); 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->Printf ("Stepping through range (stepping into functions): "); 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_address_range.Dump (s, &m_thread.GetProcess(), Address::DumpStyleLoadAddress); 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::ShouldStop (Event *event_ptr) 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_no_more_plans = false; 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StreamString s; 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s.Address (m_thread.GetRegisterContext()->GetPC(), m_thread.GetProcess().GetAddressByteSize()); 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf("ThreadPlanStepInRange reached %s.", s.GetData()); 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we're still in the range, keep going. 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (InRange()) 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we're in an older frame then we should stop. 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (FrameIsOlder()) 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // See if we are in a place we should step through (i.e. a trampoline of some sort): 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // One tricky bit here is that some stubs don't push a frame, so we have to check 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // both the case of a frame that is younger, or the same as this frame. 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // However, if the frame is the same, and we are still in the symbol we started 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // in, the we don't need to do this. This first check isn't strictly necessary, 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // but it is more efficient. 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!FrameIsYounger() && InSymbol()) 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetPlanComplete(); 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlan* new_plan = NULL; 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10481cfc99a02ee8c7f58c41236c7c034baaeb9fee8Jim Ingham // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and 10581cfc99a02ee8c7f58c41236c7c034baaeb9fee8Jim Ingham // continuing... 10681cfc99a02ee8c7f58c41236c7c034baaeb9fee8Jim Ingham 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool stop_others; 10881cfc99a02ee8c7f58c41236c7c034baaeb9fee8Jim Ingham if (m_stop_others != lldb::eAllThreads) 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner stop_others = true; 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner stop_others = false; 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others); 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If not, give the "should_stop" callback a chance to push a plan to get us out of here. 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // But only do that if we actually have stepped in. 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!new_plan && FrameIsYounger()) 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_plan = InvokeShouldStopHereCallback(); 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (new_plan == NULL) 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_no_more_plans = true; 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetPlanComplete(); 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_no_more_plans = false; 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::SetFlagsToDefault () 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values); 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 138809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Inghamvoid 139809ab9bcd5eb7aa87fb662a89a327384f892b923Jim InghamThreadPlanStepInRange::SetAvoidRegexp(const char *name) 140809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham{ 141809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham if (m_avoid_regexp_ap.get() == NULL) 142809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham m_avoid_regexp_ap.reset (new RegularExpression(name)); 143809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 144809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham m_avoid_regexp_ap->Compile (name); 145809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham} 146809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::SetDefaultFlagValue (uint32_t new_value) 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // TODO: Should we test this for sanity? 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlanStepInRange::s_default_flag_values = new_value; 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 154809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Inghambool 155809ab9bcd5eb7aa87fb662a89a327384f892b923Jim InghamThreadPlanStepInRange::FrameMatchesAvoidRegexp () 156809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham{ 157809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get(); 158809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 15920594b1b003f63ed34ebafeec37634ee44552339Jim Ingham RegularExpression *avoid_regexp_to_use; 16020594b1b003f63ed34ebafeec37634ee44552339Jim Ingham 16120594b1b003f63ed34ebafeec37634ee44552339Jim Ingham avoid_regexp_to_use = m_avoid_regexp_ap.get(); 16220594b1b003f63ed34ebafeec37634ee44552339Jim Ingham if (avoid_regexp_to_use == NULL) 16320594b1b003f63ed34ebafeec37634ee44552339Jim Ingham avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp(); 16420594b1b003f63ed34ebafeec37634ee44552339Jim Ingham 16520594b1b003f63ed34ebafeec37634ee44552339Jim Ingham if (avoid_regexp_to_use != NULL) 166809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham { 167809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham SymbolContext sc = frame->GetSymbolContext(eSymbolContextSymbol); 168809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham if (sc.symbol != NULL) 169809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham { 170809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham const char *unnamed_symbol = "<UNKNOWN>"; 171809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham const char *sym_name = sc.symbol->GetMangled().GetName().AsCString(unnamed_symbol); 172809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham if (strcmp (sym_name, unnamed_symbol) != 0) 17320594b1b003f63ed34ebafeec37634ee44552339Jim Ingham return avoid_regexp_to_use->Execute(sym_name); 174809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham } 175809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham } 176809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham return false; 177809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham} 178809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlan * 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton) 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 182809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham bool should_step_out = false; 183809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); 184809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (flags.IsSet(eAvoidNoDebug)) 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!frame->HasDebugInformation()) 188809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham should_step_out = true; 189809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham } 190809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 191809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham if (!should_step_out) 192809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham { 193809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham if (current_plan->GetKind() == eKindStepInRange) 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 195809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan); 196809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham should_step_out = step_in_range_plan->FrameMatchesAvoidRegexp (); 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 199809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham 200809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham if (should_step_out) 201809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham { 202809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions. 203809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham return current_plan->GetThread().QueueThreadPlanForStepOut (false, NULL, true, 204809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham current_plan->StopOthers(), 205809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham eVoteNo, eVoteNoOpinion); 206809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham } 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 210