<div dir="ltr">Seems like kind of an obscure command. Why not just set a one-shot breakpoint on foo by name, then continue, so that the first time the breakpoint hits it gets removed.<div><br></div><div>Also what happens if bar() calls foo()?</div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Feb 9, 2016 at 7:29 PM Jim Ingham via lldb-commits <<a href="mailto:lldb-commits@lists.llvm.org">lldb-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jingham<br>
Date: Tue Feb 9 21:25:24 2016<br>
New Revision: 260352<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=260352&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=260352&view=rev</a><br>
Log:<br>
This is an idea to make "thread step-in --target" work for the common<br>
case where you have:<br>
<br>
1 -> foo (bar(),<br>
2 baz(),<br>
3 lala());<br>
4<br>
<br>
You are sitting on line 1, and want to step into foo, but not bar, baz & lala. Unfortunately<br>
there are line table entries for lines 1-3, and lldb doesn't know anything about the nesting<br>
of statement in these lines. So we'll have to use the user's intelligence... This patch adds:<br>
<br>
(lldb) thread step-in -t foo --end-line 4<br>
<br>
That tells lldb to keep stepping in till line 4, but stop if you step into foo. I think I would<br>
remember to use this when faced with some of the long gnarly call sequences in lldb. But there<br>
might be ways I haven't thought of to make it more convenient. Jason suggests having "end" as a<br>
special token for --end-line which just means keep going to the end of the function, I really want<br>
to get into this thing...<br>
<br>
There should be an SB API and tests, which will come if this seems useful.<br>
<br>
Modified:<br>
lldb/trunk/source/Commands/CommandObjectThread.cpp<br>
<br>
Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=260352&r1=260351&r2=260352&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=260352&r1=260351&r2=260352&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)<br>
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Tue Feb 9 21:25:24 2016<br>
@@ -386,7 +386,7 @@ public:<br>
{<br>
m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);<br>
if (m_step_count == UINT32_MAX)<br>
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);<br>
+ error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg);<br>
break;<br>
}<br>
break;<br>
@@ -403,6 +403,16 @@ public:<br>
}<br>
break;<br>
<br>
+ case 'e':<br>
+ {<br>
+ uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);<br>
+ if (tmp_end_line == UINT32_MAX)<br>
+ error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg);<br>
+ else<br>
+ m_end_line = tmp_end_line;<br>
+ break;<br>
+ }<br>
+ break;<br>
case 'r':<br>
{<br>
m_avoid_regexp.clear();<br>
@@ -441,6 +451,7 @@ public:<br>
m_step_in_target.clear();<br>
m_class_name.clear();<br>
m_step_count = 1;<br>
+ m_end_line = LLDB_INVALID_LINE_NUMBER;<br>
}<br>
<br>
const OptionDefinition*<br>
@@ -461,6 +472,7 @@ public:<br>
std::string m_step_in_target;<br>
std::string m_class_name;<br>
uint32_t m_step_count;<br>
+ uint32_t m_end_line;<br>
};<br>
<br>
CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,<br>
@@ -559,6 +571,14 @@ protected:<br>
}<br>
}<br>
<br>
+ if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER<br>
+ && m_step_type != eStepTypeInto)<br>
+ {<br>
+ result.AppendErrorWithFormat("end line option is only valid for step into");<br>
+ result.SetStatus(eReturnStatusFailed);<br>
+ return false;<br>
+ }<br>
+<br>
const bool abort_other_plans = false;<br>
const lldb::RunMode stop_other_threads = m_options.m_run_mode;<br>
<br>
@@ -586,8 +606,70 @@ protected:<br>
<br>
if (frame->HasDebugInformation ())<br>
{<br>
+ AddressRange range = frame->GetSymbolContext(eSymbolContextEverything).line_entry.range;<br>
+ if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)<br>
+ {<br>
+ SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);<br>
+ if (sc.line_entry.line > m_options.m_end_line)<br>
+ {<br>
+ result.AppendErrorWithFormat("end line option %d must be after the current line: %d",<br>
+ m_options.m_end_line,<br>
+ sc.line_entry.line);<br>
+ result.SetStatus(eReturnStatusFailed);<br>
+ return false;<br>
+ }<br>
+<br>
+ CompileUnit *cu = sc.comp_unit;<br>
+ uint32_t line_index = 0;<br>
+ bool found = false;<br>
+ while (1)<br>
+ {<br>
+ LineEntry this_line;<br>
+ line_index = cu->FindLineEntry(line_index, sc.line_entry.line, nullptr, false, &this_line);<br>
+ if (line_index == UINT32_MAX)<br>
+ break;<br>
+ if (LineEntry::Compare(this_line, sc.line_entry) == 0)<br>
+ {<br>
+ found = true;<br>
+ break;<br>
+ }<br>
+ }<br>
+ LineEntry end_entry;<br>
+ if (!found)<br>
+ {<br>
+ // Can't find the index of the SymbolContext's line entry in the SymbolContext's CompUnit.<br>
+ result.AppendErrorWithFormat("Can't find the current line entry in the CompUnit - can't process "<br>
+ "the end-line option");<br>
+ result.SetStatus(eReturnStatusFailed);<br>
+ return false;<br>
+ }<br>
+<br>
+ line_index = cu->FindLineEntry(line_index, m_options.m_end_line, nullptr, false, &end_entry);<br>
+ if (line_index == UINT32_MAX)<br>
+ {<br>
+ result.AppendErrorWithFormat("could not find a line table entry corresponding "<br>
+ "to end line number %d",<br>
+ m_options.m_end_line);<br>
+ result.SetStatus(eReturnStatusFailed);<br>
+ return false;<br>
+ }<br>
+<br>
+ Block *func_block = sc.GetFunctionBlock();<br>
+ if (func_block && func_block->GetRangeIndexContainingAddress(end_entry.range.GetBaseAddress()) == UINT32_MAX)<br>
+ {<br>
+ result.AppendErrorWithFormat("end line number %d is not contained within the current function.",<br>
+ m_options.m_end_line);<br>
+ result.SetStatus(eReturnStatusFailed);<br>
+ return false;<br>
+ }<br>
+<br>
+ lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress()<br>
+ - range.GetBaseAddress().GetFileAddress();<br>
+ range.SetByteSize(range_size);<br>
+ }<br>
+<br>
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,<br>
- frame->GetSymbolContext(eSymbolContextEverything).line_entry,<br>
+ range,<br>
frame->GetSymbolContext(eSymbolContextEverything),<br>
m_options.m_step_in_target.c_str(),<br>
stop_other_threads,<br>
@@ -737,6 +819,7 @@ CommandObjectThreadStepWithTypeAndScope:<br>
{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},<br>
{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},<br>
{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},<br>
+{ LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over."},<br>
{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},<br>
{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},<br>
{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},<br>
<br>
<br>
_______________________________________________<br>
lldb-commits mailing list<br>
<a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits</a><br>
</blockquote></div>