Author: jingham Date: Thu Feb 25 19:37:30 2016 New Revision: 261953 URL: http://llvm.org/viewvc/llvm-project?rev=261953&view=rev Log: Add the "block" keyword to "thread step-in -e", and an alias that uses it: "sif <target function>" - i.e. step-into-function to allow you to step through a complex calling sequence into a particular function that may span multiple lines. Also some test cases for this and the --step-target feature.
Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/ lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/Makefile lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/main.c Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/Makefile?rev=261953&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/Makefile Thu Feb 25 19:37:30 2016 @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py?rev=261953&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py Thu Feb 25 19:37:30 2016 @@ -0,0 +1,113 @@ +"""Test the 'step target' feature.""" + +from __future__ import print_function + +import os, time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestStepTarget(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def getCategories(self): + return ['basic_process'] + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + self.end_line = line_number(self.main_source, "All done") + + @add_test_categories(['pyapi']) + + def get_to_start (self): + self.build() + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec (self.main_source) + + break_in_main = target.BreakpointCreateBySourceRegex ('Break here to try targetted stepping', self.main_source_spec) + self.assertTrue(break_in_main, VALID_BREAKPOINT) + self.assertTrue(break_in_main.GetNumLocations() > 0,"Has locations.") + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main) + + if len(threads) != 1: + self.fail ("Failed to stop at first breakpoint in main.") + + thread = threads[0] + return thread + + def test_with_end_line(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + error = lldb.SBError() + thread.StepInto("lotsOfArgs", self.end_line, error) + frame = thread.frames[0] + + self.assertTrue (frame.name == "lotsOfArgs", "Stepped to lotsOfArgs.") + + def test_with_end_line_bad_name(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + error = lldb.SBError() + thread.StepInto("lotsOfArgssss", self.end_line, error) + frame = thread.frames[0] + self.assertTrue (frame.line_entry.line == self.end_line, "Stepped to the block end.") + + def test_with_end_line_deeper(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + error = lldb.SBError() + thread.StepInto("modifyInt", self.end_line, error) + frame = thread.frames[0] + self.assertTrue (frame.name == "modifyInt", "Stepped to modifyInt.") + + def test_with_command_and_block(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + result = lldb.SBCommandReturnObject() + self.dbg.GetCommandInterpreter().HandleCommand('thread step-in -t "lotsOfArgs" -e block', result) + self.assertTrue(result.Succeeded(), "thread step-in command succeeded.") + + frame = thread.frames[0] + self.assertTrue (frame.name == "lotsOfArgs", "Stepped to lotsOfArgs.") + + def test_with_command_and_block_and_bad_name(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + result = lldb.SBCommandReturnObject() + self.dbg.GetCommandInterpreter().HandleCommand('thread step-in -t "lotsOfArgsssss" -e block', result) + self.assertTrue(result.Succeeded(), "thread step-in command succeeded.") + + frame = thread.frames[0] + + self.assertTrue (frame.name == "main", "Stepped back out to main.") + # end_line is set to the line after the containing block. Check that we got there: + self.assertTrue(frame.line_entry.line == self.end_line, "Got out of the block") + + + Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/main.c?rev=261953&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/main.c (added) +++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/step-target/main.c Thu Feb 25 19:37:30 2016 @@ -0,0 +1,40 @@ +#include <stdio.h> + +void +lotsOfArgs +( + int firstArg, + int secondArg, + int thirdArg, + int fourthArg +) +{ + printf ("First: %d Second: %d Third: %d Fourth: %d.\n", + firstArg, + secondArg, + thirdArg, + fourthArg); +} + +int +modifyInt(int incoming) +{ + return incoming % 2; +} + +int +main (int argc, char **argv) +{ + if (argc > 0) + { + int var_makes_block = argc + 1; + printf ("Break here to try targetted stepping.\n"); + lotsOfArgs(var_makes_block, + modifyInt(20), + 30, + modifyInt(40)); + printf ("Done calling lotsOfArgs."); + } + printf ("All done.\n"); + return 0; +} Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=261953&r1=261952&r2=261953&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Feb 25 19:37:30 2016 @@ -386,6 +386,11 @@ public: case 'e': { + if (strcmp(option_arg, "block") == 0) + { + m_end_line_is_block_end = 1; + break; + } 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); @@ -429,6 +434,7 @@ public: m_class_name.clear(); m_step_count = 1; m_end_line = LLDB_INVALID_LINE_NUMBER; + m_end_line_is_block_end = false; } const OptionDefinition* @@ -450,6 +456,7 @@ public: std::string m_class_name; uint32_t m_step_count; uint32_t m_end_line; + bool m_end_line_is_block_end; }; CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, @@ -588,6 +595,30 @@ protected: return false; } } + else if (m_options.m_end_line_is_block_end) + { + Error error; + Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; + if (!block) + { + result.AppendErrorWithFormat("Could not find the current block."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + AddressRange block_range; + Address pc_address = frame->GetFrameCodeAddress(); + block->GetRangeContainingAddress(pc_address, block_range); + if (!block_range.GetBaseAddress().IsValid()) + { + result.AppendErrorWithFormat("Could not find the current block address."); + result.SetStatus(eReturnStatusFailed); + return false; + } + lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress(); + lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block; + range = AddressRange(pc_address, range_length); + } else { range = sc.line_entry.range; @@ -741,7 +772,9 @@ CommandObjectThreadStepWithTypeAndScope: { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 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, nullptr, nullptr, 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, nullptr, nullptr, 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, nullptr, nullptr, 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, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over." + " You can also pass the string 'block' to step to the end of the current block." + " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."}, { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, 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, nullptr, nullptr, 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, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=261953&r1=261952&r2=261953&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Thu Feb 25 19:37:30 2016 @@ -185,6 +185,9 @@ CommandInterpreter::Initialize () LoadCommandDictionary (); + // An alias arguments vector to reuse - reset it before use... + OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector); + // Set up some initial aliases. CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false); if (cmd_obj_sp) @@ -239,6 +242,11 @@ CommandInterpreter::Initialize () { AddAlias ("s", cmd_obj_sp); AddAlias ("step", cmd_obj_sp); + + alias_arguments_vector_sp.reset (new OptionArgVector); + ProcessAliasOptionsArgs (cmd_obj_sp, "--end-linenumber block --step-in-target %1", alias_arguments_vector_sp); + AddAlias ("sif", cmd_obj_sp); + AddOrReplaceAliasOptions("sif", alias_arguments_vector_sp); } cmd_obj_sp = GetCommandSPExact ("thread step-over", false); @@ -329,8 +337,6 @@ CommandInterpreter::Initialize () AddAlias ("image", cmd_obj_sp); - OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector); - cmd_obj_sp = GetCommandSPExact ("expression", false); if (cmd_obj_sp) { _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits