Index: include/lldb/API/SBExpressionOptions.h =================================================================== --- include/lldb/API/SBExpressionOptions.h +++ include/lldb/API/SBExpressionOptions.h @@ -90,6 +90,12 @@ bool GetTopLevel(); void SetTopLevel(bool b = true); + + // Gets whether we will JIT an expression if it cannot be interpreted + bool GetAllowJIT(); + + // Sets whether we will JIT an expression if it cannot be interpreted + void SetAllowJIT(bool allow); protected: SBExpressionOptions( Index: packages/Python/lldbsuite/test/expression_command/dont_allow_jit/Makefile =================================================================== --- packages/Python/lldbsuite/test/expression_command/dont_allow_jit/Makefile +++ packages/Python/lldbsuite/test/expression_command/dont_allow_jit/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/expression_command/dont_allow_jit/TestSampleTest.py =================================================================== --- packages/Python/lldbsuite/test/expression_command/dont_allow_jit/TestSampleTest.py +++ packages/Python/lldbsuite/test/expression_command/dont_allow_jit/TestSampleTest.py @@ -0,0 +1,94 @@ +""" +Test that --allow-jit=false does disallow JITting: +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * + +class TestAllowJIT(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # If your test case doesn't stress debug info, the + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765") + def test_allow_jit_expr_command(self): + """Test the --allow-jit command line flag""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + self.expr_cmd_test() + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765") + def test_allow_jit_options(self): + """Test the SetAllowJIT SBExpressionOption setting""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + self.expr_options_test() + + + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def expr_cmd_test(self): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + + frame = thread.GetFrameAtIndex(0) + + # First make sure we can call the function with + interp = self.dbg.GetCommandInterpreter() + self.expect("expr --allow-jit 1 -- call_me(10)", + substrs = ["(int) $", "= 18"]) + # Now make sure it fails with the "can't IR interpret message" if allow-jit is false: + self.expect("expr --allow-jit 0 -- call_me(10)", + error=True, + substrs = ["Can't run the expression locally"]) + + def expr_options_test(self): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + + frame = thread.GetFrameAtIndex(0) + + # First make sure we can call the function with the default option set. + options = lldb.SBExpressionOptions() + # Check that the default is to allow JIT: + self.assertEqual(options.GetAllowJIT(), True, "Default is true") + + # Now use the options: + result = frame.EvaluateExpression("call_me(10)", options) + self.assertTrue(result.GetError().Success(), "expression succeeded") + self.assertEqual(result.GetValueAsSigned(), 18, "got the right value.") + + # Now disallow JIT and make sure it fails: + options.SetAllowJIT(False) + # Check that we got the right value: + self.assertEqual(options.GetAllowJIT(), False, "Got False after setting to False") + + # Again use it and ensure we fail: + result = frame.EvaluateExpression("call_me(10)", options) + self.assertTrue(result.GetError().Fail(), "expression failed with no JIT") + self.assertTrue("Can't run the expression locally" in result.GetError().GetCString(), "Got right error") + + # Finally set the allow JIT value back to true and make sure that works: + options.SetAllowJIT(True) + self.assertEqual(options.GetAllowJIT(), True, "Set back to True correctly") + + # And again, make sure this works: + result = frame.EvaluateExpression("call_me(10)", options) + self.assertTrue(result.GetError().Success(), "expression succeeded") + self.assertEqual(result.GetValueAsSigned(), 18, "got the right value.") + Index: packages/Python/lldbsuite/test/expression_command/dont_allow_jit/main.c =================================================================== --- packages/Python/lldbsuite/test/expression_command/dont_allow_jit/main.c +++ packages/Python/lldbsuite/test/expression_command/dont_allow_jit/main.c @@ -0,0 +1,15 @@ +#include + +int +call_me(int input) +{ + return printf("I was called: %d.\n", input); +} + +int +main() +{ + int test_var = 10; + printf ("Set a breakpoint here: %d.\n", test_var); + return call_me(100); +} Index: scripts/interface/SBExpressionOptions.i =================================================================== --- scripts/interface/SBExpressionOptions.i +++ scripts/interface/SBExpressionOptions.i @@ -132,6 +132,14 @@ void SetTopLevel(bool b = true); + + %feature("docstring", "Gets whether to JIT an expression if it cannot be interpreted.") GetAllowJIT; + bool + GetAllowJIT(); + + %feature("docstring", "Sets whether to JIT an expression if it cannot be interpreted.") SetAllowJIT; + void + SetAllowJIT(bool allow); protected: Index: source/API/SBExpressionOptions.cpp =================================================================== --- source/API/SBExpressionOptions.cpp +++ source/API/SBExpressionOptions.cpp @@ -159,6 +159,15 @@ : m_opaque_ap->default_execution_policy); } +bool SBExpressionOptions::GetAllowJIT() { + return m_opaque_ap->GetExecutionPolicy() != eExecutionPolicyNever; +} + +void SBExpressionOptions::SetAllowJIT(bool allow) { + m_opaque_ap->SetExecutionPolicy(allow ? m_opaque_ap->default_execution_policy + : eExecutionPolicyNever); +} + EvaluateExpressionOptions *SBExpressionOptions::get() const { return m_opaque_ap.get(); }