Index: cross-project-tests/debuginfo-tests/dexter/Commands.md =================================================================== --- cross-project-tests/debuginfo-tests/dexter/Commands.md +++ cross-project-tests/debuginfo-tests/dexter/Commands.md @@ -170,10 +170,12 @@ --- ## DexUnreachable - DexUnreachable() + DexUnreachable([, **from_line=1][,**to_line=Max][,**on_line]) ### Description -Expect the source line this is found on will never be stepped on to. +Expect the source line this is found on will never be stepped on to. If either +'on_line' or both 'from_line' and 'to_line' are specified, checks that the +specified line(s) are not stepped on. ### Heuristic [TODO] Index: cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexUnreachable.py =================================================================== --- cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexUnreachable.py +++ cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexUnreachable.py @@ -18,7 +18,21 @@ See Commands.md for more info. """ - def __init(self): + def __init__(self, *args, **kwargs): + if len(args) != 0: + raise TypeError("DexUnreachable takes no positional arguments") + if 'on_line' in kwargs: + on_line = kwargs.pop('on_line') + self._from_line = on_line + self._to_line = on_line + elif 'from_line' in kwargs and 'to_line' in kwargs: + self._from_line = kwargs.pop('from_line') + self._to_line = kwargs.pop('to_line') + elif 'from_line' in kwargs or 'to_line' in kwargs: + raise TypeError("Must provide both from_line and to_line to DexUnreachable") + + if len(kwargs) > 0: + raise TypeError("Unexpected kwargs {}".format(kwargs.keys())) super(DexUnreachable, self).__init__() pass Index: cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py =================================================================== --- cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py +++ cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py @@ -18,6 +18,15 @@ return any(os.path.samefile(step_info.current_location.path, f) \ for f in source_files) +def have_hit_line(watch, loc): + if hasattr(watch, '_on_line'): + return watch._on_line == loc.lineno + elif hasattr(watch, '_from_line'): + return watch._from_line <= loc.lineno and watch._to_line >= loc.lineno + elif watch.lineno == loc.lineno: + return True + return False + def update_step_watches(step_info, watches, commands): watch_cmds = ['DexUnreachable', 'DexExpectStepOrder'] towatch = chain.from_iterable(commands[x] @@ -30,7 +39,7 @@ if (loc.path != None and os.path.exists(loc.path) and os.path.samefile(watch.path, loc.path) - and watch.lineno == loc.lineno): + and have_hit_line(watch, loc)): result = watch.eval(step_info) step_info.watches.update(result) break Index: cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable_line_range.cpp =================================================================== --- /dev/null +++ cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable_line_range.cpp @@ -0,0 +1,17 @@ +// Purpose: +// Check that \DexUnreachable correctly applies a penalty if the command +// line is stepped on. +// +// UNSUPPORTED: system-darwin +// +// +// RUN: not %dexter_regression_test -- %s | FileCheck %s +// CHECK: unreachable_line_range.cpp: + +int +main() +{ // DexLabel('begin') + return 1; +} // DexLabel('end') + +// DexUnreachable(from_line=ref('begin'), to_line=ref('end')) Index: cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable_on_line.cpp =================================================================== --- /dev/null +++ cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable_on_line.cpp @@ -0,0 +1,17 @@ +// Purpose: +// Check that \DexUnreachable correctly applies a penalty if the command +// line is stepped on. +// +// UNSUPPORTED: system-darwin +// +// +// RUN: not %dexter_regression_test -- %s | FileCheck %s +// CHECK: unreachable_on_line.cpp: + +int +main() +{ + return 1; // DexLabel('this_one') +} + +// DexUnreachable(on_line=ref('this_one')) Index: cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable_not_cmd_lineno.cpp =================================================================== --- /dev/null +++ cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable_not_cmd_lineno.cpp @@ -0,0 +1,17 @@ +// Purpose: +// Check that \DexUnreachable doesn't trigger on the line it's specified +// on, if it has a specifier indicating which lines should be unreachable. +// +// UNSUPPORTED: system-darwin +// +// RUN: %dexter_regression_test -- %s | FileCheck %s +// CHECK: unreachable_not_cmd_lineno.cpp: + +int main(int argc, char **argv) +{ + if (argc != 1) + return 1; // DexLabel('this_one') + else + return 0; // DexUnreachable(on_line=ref('this_one')) DexUnreachable(from_line=ref('this_one'), to_line=ref('this_one')) +} + Index: cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable_on_line.cpp =================================================================== --- /dev/null +++ cross-project-tests/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable_on_line.cpp @@ -0,0 +1,18 @@ +// Purpose: +// Check that \DexUnreachable has no effect if the command line is never +// stepped on. +// +// UNSUPPORTED: system-darwin +// +// RUN: %dexter_regression_test -- %s | FileCheck %s +// CHECK: unreachable_on_line.cpp: + +int main() +{ + return 0; + return 1; // DexLabel('this_one') +} + + +// DexUnreachable(on_line=ref('this_one')) +// DexUnreachable(from_line=ref('this_one'), to_line=ref('this_one'))