[Lldb-commits] [lldb] r260352 - This is an idea to make "thread step-in --target" work for the common

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Wed Feb 10 09:24:30 PST 2016


> On Feb 9, 2016, at 7:40 PM, Zachary Turner <zturner at google.com> wrote:
> 
> 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.
> 

Maybe obscure, but not that hard to type, so it isn't onerous.  

Doing it with a one shot breakpoint is two commands, with more typing, not one, and if I'm in code used on multiple threads, I would really have to make the one-shot breakpoint thread specific, so that means I also have to look up and write down the thread index.  That's kinda annoying.  Also...

> Also what happens if bar() calls foo()?

The "step-in targeting foo" operation's job is to step into the call to foo I see on the line in front of me.  That seems a useful operation as distinct from "stop anytime foo is called in course of stepping", which as you point out we already have breakpoints for.  The command will work as described even if bar calls foo because "step-in" always only steps one level deep and then either stops or immediately steps back out, so it would never notice the call foo->bar->foo.

Jim

> 
> On Tue, Feb 9, 2016 at 7:29 PM Jim Ingham via lldb-commits <lldb-commits at lists.llvm.org> wrote:
> Author: jingham
> Date: Tue Feb  9 21:25:24 2016
> New Revision: 260352
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=260352&view=rev
> Log:
> This is an idea to make "thread step-in --target" work for the common
> case where you have:
> 
> 1 ->    foo (bar(),
> 2            baz(),
> 3            lala());
> 4
> 
> You are sitting on line 1, and want to step into foo, but not bar, baz & lala.  Unfortunately
> there are line table entries for lines 1-3, and lldb doesn't know anything about the nesting
> of statement in these lines.  So we'll have to use the user's intelligence...  This patch adds:
> 
> (lldb) thread step-in -t foo --end-line 4
> 
> That tells lldb to keep stepping in till line 4, but stop if you step into foo.  I think I would
> remember to use this when faced with some of the long gnarly call sequences in lldb.  But there
> might be ways I haven't thought of to make it more convenient.  Jason suggests having "end" as a
> special token for --end-line which just means keep going to the end of the function, I really want
> to get into this thing...
> 
> There should be an SB API and tests, which will come if this seems useful.
> 
> Modified:
>     lldb/trunk/source/Commands/CommandObjectThread.cpp
> 
> Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=260352&r1=260351&r2=260352&view=diff
> ==============================================================================
> --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
> +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Tue Feb  9 21:25:24 2016
> @@ -386,7 +386,7 @@ public:
>                  {
>                      m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
>                      if (m_step_count == UINT32_MAX)
> -                       error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
> +                       error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg);
>                      break;
>                  }
>                  break;
> @@ -403,6 +403,16 @@ public:
>                  }
>                  break;
> 
> +            case 'e':
> +                {
> +                    uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
> +                    if (tmp_end_line == UINT32_MAX)
> +                       error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg);
> +                    else
> +                        m_end_line = tmp_end_line;
> +                    break;
> +                }
> +                break;
>              case 'r':
>                  {
>                      m_avoid_regexp.clear();
> @@ -441,6 +451,7 @@ public:
>              m_step_in_target.clear();
>              m_class_name.clear();
>              m_step_count = 1;
> +            m_end_line = LLDB_INVALID_LINE_NUMBER;
>          }
> 
>          const OptionDefinition*
> @@ -461,6 +472,7 @@ public:
>          std::string m_step_in_target;
>          std::string m_class_name;
>          uint32_t m_step_count;
> +        uint32_t m_end_line;
>      };
> 
>      CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
> @@ -559,6 +571,14 @@ protected:
>              }
>          }
> 
> +        if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER
> +            && m_step_type != eStepTypeInto)
> +        {
> +            result.AppendErrorWithFormat("end line option is only valid for step into");
> +            result.SetStatus(eReturnStatusFailed);
> +            return false;
> +        }
> +
>          const bool abort_other_plans = false;
>          const lldb::RunMode stop_other_threads = m_options.m_run_mode;
> 
> @@ -586,8 +606,70 @@ protected:
> 
>              if (frame->HasDebugInformation ())
>              {
> +                AddressRange range = frame->GetSymbolContext(eSymbolContextEverything).line_entry.range;
> +                if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)
> +                {
> +                    SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
> +                    if (sc.line_entry.line > m_options.m_end_line)
> +                    {
> +                        result.AppendErrorWithFormat("end line option %d must be after the current line: %d",
> +                                                     m_options.m_end_line,
> +                                                     sc.line_entry.line);
> +                        result.SetStatus(eReturnStatusFailed);
> +                        return false;
> +                    }
> +
> +                    CompileUnit *cu = sc.comp_unit;
> +                    uint32_t line_index = 0;
> +                    bool found = false;
> +                    while (1)
> +                    {
> +                        LineEntry this_line;
> +                        line_index = cu->FindLineEntry(line_index, sc.line_entry.line, nullptr, false, &this_line);
> +                        if (line_index == UINT32_MAX)
> +                            break;
> +                        if (LineEntry::Compare(this_line, sc.line_entry) == 0)
> +                        {
> +                            found = true;
> +                            break;
> +                        }
> +                    }
> +                    LineEntry end_entry;
> +                    if (!found)
> +                    {
> +                        // Can't find the index of the SymbolContext's line entry in the SymbolContext's CompUnit.
> +                        result.AppendErrorWithFormat("Can't find the current line entry in the CompUnit - can't process "
> +                                                     "the end-line option");
> +                        result.SetStatus(eReturnStatusFailed);
> +                        return false;
> +                    }
> +
> +                    line_index = cu->FindLineEntry(line_index, m_options.m_end_line, nullptr, false, &end_entry);
> +                    if (line_index == UINT32_MAX)
> +                    {
> +                        result.AppendErrorWithFormat("could not find a line table entry corresponding "
> +                                                     "to end line number %d",
> +                                                     m_options.m_end_line);
> +                        result.SetStatus(eReturnStatusFailed);
> +                        return false;
> +                    }
> +
> +                    Block *func_block = sc.GetFunctionBlock();
> +                    if (func_block && func_block->GetRangeIndexContainingAddress(end_entry.range.GetBaseAddress()) == UINT32_MAX)
> +                    {
> +                        result.AppendErrorWithFormat("end line number %d is not contained within the current function.",
> +                                                     m_options.m_end_line);
> +                        result.SetStatus(eReturnStatusFailed);
> +                        return false;
> +                    }
> +
> +                    lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress()
> +                                              - range.GetBaseAddress().GetFileAddress();
> +                    range.SetByteSize(range_size);
> +                }
> +
>                  new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
> -                                                                frame->GetSymbolContext(eSymbolContextEverything).line_entry,
> +                                                                range,
>                                                                  frame->GetSymbolContext(eSymbolContextEverything),
>                                                                  m_options.m_step_in_target.c_str(),
>                                                                  stop_other_threads,
> @@ -737,6 +819,7 @@ CommandObjectThreadStepWithTypeAndScope:
>  { 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."},
>  { 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."},
>  { 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."},
> +{ 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."},
>  { 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."},
>  { 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."},
>  { 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."},
> 
> 
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits



More information about the lldb-commits mailing list