diff options
| -rw-r--r-- | lldb/include/lldb/Target/ThreadPlanStepInRange.h | 6 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectThread.cpp | 14 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlanStepInRange.cpp | 54 |
3 files changed, 70 insertions, 4 deletions
diff --git a/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/lldb/include/lldb/Target/ThreadPlanStepInRange.h index 6d6405844cd..f7b7a45a94e 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -36,6 +36,8 @@ public: virtual bool ShouldStop (Event *event_ptr); + void SetAvoidRegexp(const char *name); + static ThreadPlan * DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton); @@ -51,6 +53,9 @@ protected: virtual void SetFlagsToDefault (); + + bool + FrameMatchesAvoidRegexp (); private: @@ -67,6 +72,7 @@ private: // from step in. static uint32_t s_default_flag_values; + std::auto_ptr<RegularExpression> m_avoid_regexp_ap; DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInRange); diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 85829124b41..0934045fd5b 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -383,6 +383,12 @@ public: error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option); } break; + case 'r': + { + m_avoid_regexp.clear(); + m_avoid_regexp.assign(option_arg); + } + break; default: error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); break; @@ -397,6 +403,7 @@ public: Options::ResetOptionValues(); m_avoid_no_debug = true; m_run_mode = eOnlyDuringStepping; + m_avoid_regexp.clear(); } const lldb::OptionDefinition* @@ -412,6 +419,7 @@ public: // Instance variables to hold the values for command options. bool m_avoid_no_debug; RunMode m_run_mode; + std::string m_avoid_regexp; }; CommandObjectThreadStepWithTypeAndScope (const char *name, @@ -514,6 +522,11 @@ public: frame->GetSymbolContext(eSymbolContextEverything), stop_other_threads, m_options.m_avoid_no_debug); + if (new_plan && !m_options.m_avoid_regexp.empty()) + { + ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan); + step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); + } } else new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); @@ -621,6 +634,7 @@ CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_1, false, "avoid_no_debug", 'a', required_argument, NULL, 0, "<avoid_no_debug>", "Should step-in step over functions with no debug information"}, { LLDB_OPT_SET_1, false, "run_mode", 'm', required_argument, g_tri_running_mode, 0, "<run_mode>", "Determine how to run other threads while stepping this one"}, +{ LLDB_OPT_SET_1, false, "regexp_to_avoid",'r', required_argument, NULL, 0, "<avoid_regexp>", "Should step-in step over functions matching this regexp"}, { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } }; diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index 6084b4e815f..58f61977ccd 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -17,11 +17,13 @@ #include "lldb/lldb-private-log.h" #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Core/RegularExpression.h" using namespace lldb; using namespace lldb_private; @@ -44,6 +46,7 @@ ThreadPlanStepInRange::ThreadPlanStepInRange ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL) { SetFlagsToDefault (); + // SetAvoidRegexp("^std\\:\\:.*"); } ThreadPlanStepInRange::~ThreadPlanStepInRange () @@ -129,6 +132,15 @@ ThreadPlanStepInRange::SetFlagsToDefault () GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values); } +void +ThreadPlanStepInRange::SetAvoidRegexp(const char *name) +{ + if (m_avoid_regexp_ap.get() == NULL) + m_avoid_regexp_ap.reset (new RegularExpression(name)); + + m_avoid_regexp_ap->Compile (name); +} + void ThreadPlanStepInRange::SetDefaultFlagValue (uint32_t new_value) { @@ -136,19 +148,53 @@ ThreadPlanStepInRange::SetDefaultFlagValue (uint32_t new_value) ThreadPlanStepInRange::s_default_flag_values = new_value; } +bool +ThreadPlanStepInRange::FrameMatchesAvoidRegexp () +{ + StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get(); + + if (m_avoid_regexp_ap.get() != NULL) + { + SymbolContext sc = frame->GetSymbolContext(eSymbolContextSymbol); + if (sc.symbol != NULL) + { + const char *unnamed_symbol = "<UNKNOWN>"; + const char *sym_name = sc.symbol->GetMangled().GetName().AsCString(unnamed_symbol); + if (strcmp (sym_name, unnamed_symbol) != 0) + return m_avoid_regexp_ap->Execute(sym_name); + } + } + return false; +} + ThreadPlan * ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton) { + bool should_step_out = false; + StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); + if (flags.IsSet(eAvoidNoDebug)) { - StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); - if (!frame->HasDebugInformation()) + should_step_out = true; + } + + if (!should_step_out) + { + if (current_plan->GetKind() == eKindStepInRange) { - // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions. - return current_plan->GetThread().QueueThreadPlanForStepOut (false, NULL, true, current_plan->StopOthers(), eVoteNo, eVoteNoOpinion); + ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan); + should_step_out = step_in_range_plan->FrameMatchesAvoidRegexp (); } } + + if (should_step_out) + { + // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions. + return current_plan->GetThread().QueueThreadPlanForStepOut (false, NULL, true, + current_plan->StopOthers(), + eVoteNo, eVoteNoOpinion); + } return NULL; } |

