199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest the IR interpreter 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport lldb 799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 999451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprechtclass IRInterpreterTestCase(TestBase): 1399451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1499451b44SJordan Rupprecht 1559237bb5SJonas Devlieghere def time_expression(self, expr, options): 1659237bb5SJonas Devlieghere start = time.time() 1759237bb5SJonas Devlieghere res = self.target.EvaluateExpression(expr, options) 1859237bb5SJonas Devlieghere return res, time.time() - start 1959237bb5SJonas Devlieghere 2059237bb5SJonas Devlieghere def test_interpreter_timeout(self): 2159237bb5SJonas Devlieghere """Test the timeout logic in the IRInterpreter.""" 2259237bb5SJonas Devlieghere self.build() 2359237bb5SJonas Devlieghere self.target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 2459237bb5SJonas Devlieghere self.assertTrue(self.target, VALID_TARGET) 2559237bb5SJonas Devlieghere 2659237bb5SJonas Devlieghere # A non-trivial infinite loop. 2759237bb5SJonas Devlieghere inf_loop = "for (unsigned i = 0; i < 100; ++i) --i; 1" 2859237bb5SJonas Devlieghere timeout_error = "Reached timeout while interpreting expression" 2959237bb5SJonas Devlieghere options = lldb.SBExpressionOptions() 3059237bb5SJonas Devlieghere 3159237bb5SJonas Devlieghere # This is an IRInterpreter specific test, so disable the JIT. 3259237bb5SJonas Devlieghere options.SetAllowJIT(False) 3359237bb5SJonas Devlieghere 34*7822e5dbSwalter erquinigo # We use a 500ms timeout. 35*7822e5dbSwalter erquinigo options.SetTimeoutInMicroSeconds(500000) 3659237bb5SJonas Devlieghere res, duration_sec = self.time_expression(inf_loop, options) 3759237bb5SJonas Devlieghere self.assertIn(timeout_error, str(res.GetError())) 3859237bb5SJonas Devlieghere 3959237bb5SJonas Devlieghere # Depending on the machine load the expression might take quite some 4059237bb5SJonas Devlieghere # time, so give the time a generous upper bound. 4159237bb5SJonas Devlieghere self.assertLess(duration_sec, 15) 4259237bb5SJonas Devlieghere 4359237bb5SJonas Devlieghere # Try a simple one second timeout. 4459237bb5SJonas Devlieghere options.SetTimeoutInMicroSeconds(1000000) 4559237bb5SJonas Devlieghere res, duration_sec = self.time_expression(inf_loop, options) 4659237bb5SJonas Devlieghere self.assertIn(timeout_error, str(res.GetError())) 4791a0e832SDavid Spickett # Anything within 5% of 1s is fine, to account for machine differences. 4891a0e832SDavid Spickett self.assertGreaterEqual(duration_sec, 0.95) 4959237bb5SJonas Devlieghere self.assertLess(duration_sec, 30) 5059237bb5SJonas Devlieghere 5161af957aSJonas Devlieghere def test_interpreter_interrupt(self): 5261af957aSJonas Devlieghere """Test interrupting the IRInterpreter.""" 5361af957aSJonas Devlieghere self.build() 5461af957aSJonas Devlieghere self.target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 5561af957aSJonas Devlieghere self.assertTrue(self.target, VALID_TARGET) 5661af957aSJonas Devlieghere 5761af957aSJonas Devlieghere # A non-trivial infinite loop. 5861af957aSJonas Devlieghere inf_loop = "for (unsigned i = 0; i < 100; ++i) --i; 1" 5961af957aSJonas Devlieghere 6061af957aSJonas Devlieghere options = lldb.SBExpressionOptions() 6161af957aSJonas Devlieghere 6261af957aSJonas Devlieghere # This is an IRInterpreter specific test, so disable the JIT. 6361af957aSJonas Devlieghere options.SetAllowJIT(False) 6461af957aSJonas Devlieghere 6561af957aSJonas Devlieghere # Make sure we have a pretty long (10s) timeout so we have a chance to 6661af957aSJonas Devlieghere # interrupt the interpreted expression. 6761af957aSJonas Devlieghere options.SetTimeoutInMicroSeconds(10000000) 6861af957aSJonas Devlieghere 6961af957aSJonas Devlieghere self.dbg.RequestInterrupt() 7061af957aSJonas Devlieghere 7161af957aSJonas Devlieghere self.dbg.SetAsync(True) 7261af957aSJonas Devlieghere res = self.target.EvaluateExpression(inf_loop, options) 7361af957aSJonas Devlieghere self.dbg.SetAsync(False) 7461af957aSJonas Devlieghere 7561af957aSJonas Devlieghere # Be sure to turn this off again: 7661af957aSJonas Devlieghere def cleanup(): 7761af957aSJonas Devlieghere if self.dbg.InterruptRequested(): 7861af957aSJonas Devlieghere self.dbg.CancelInterruptRequest() 7961af957aSJonas Devlieghere 8061af957aSJonas Devlieghere self.addTearDownHook(cleanup) 8161af957aSJonas Devlieghere 8261af957aSJonas Devlieghere interrupt_error = "Interrupted while interpreting expression" 8361af957aSJonas Devlieghere self.assertIn(interrupt_error, str(res.GetError())) 8461af957aSJonas Devlieghere 8599451b44SJordan Rupprecht def setUp(self): 8699451b44SJordan Rupprecht # Call super's setUp(). 8799451b44SJordan Rupprecht TestBase.setUp(self) 8899451b44SJordan Rupprecht # Find the line number to break for main.c. 892238dcc3SJonas Devlieghere self.line = line_number("main.c", "// Set breakpoint here") 9099451b44SJordan Rupprecht 9199451b44SJordan Rupprecht # Disable confirmation prompt to avoid infinite wait 9299451b44SJordan Rupprecht self.runCmd("settings set auto-confirm true") 932238dcc3SJonas Devlieghere self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm")) 9499451b44SJordan Rupprecht 9599451b44SJordan Rupprecht def build_and_run(self): 9699451b44SJordan Rupprecht """Test the IR interpreter""" 9799451b44SJordan Rupprecht self.build() 9899451b44SJordan Rupprecht 9999451b44SJordan Rupprecht self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 1022238dcc3SJonas Devlieghere self, "main.c", self.line, num_expected_locations=1, loc_exact=False 1032238dcc3SJonas Devlieghere ) 10499451b44SJordan Rupprecht 10599451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 10699451b44SJordan Rupprecht 1072238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 10899451b44SJordan Rupprecht # getpid() is POSIX, among other problems, see bug 1092238dcc3SJonas Devlieghere @expectedFailureAll(oslist=["windows"], bugnumber="http://llvm.org/pr21765") 11099451b44SJordan Rupprecht def test_ir_interpreter(self): 11199451b44SJordan Rupprecht self.build_and_run() 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht options = lldb.SBExpressionOptions() 11499451b44SJordan Rupprecht options.SetLanguage(lldb.eLanguageTypeC_plus_plus) 11599451b44SJordan Rupprecht 1162238dcc3SJonas Devlieghere set_up_expressions = [ 1172238dcc3SJonas Devlieghere "int $i = 9", 1182238dcc3SJonas Devlieghere "int $j = 3", 1192238dcc3SJonas Devlieghere "int $k = 5", 1202238dcc3SJonas Devlieghere "unsigned long long $ull = -1", 1212238dcc3SJonas Devlieghere "unsigned $u = -1", 1222238dcc3SJonas Devlieghere ] 12399451b44SJordan Rupprecht 1242238dcc3SJonas Devlieghere expressions = [ 1252238dcc3SJonas Devlieghere "$i + $j", 12699451b44SJordan Rupprecht "$i - $j", 12799451b44SJordan Rupprecht "$i * $j", 12899451b44SJordan Rupprecht "$i / $j", 12999451b44SJordan Rupprecht "$i % $k", 13099451b44SJordan Rupprecht "$i << $j", 13199451b44SJordan Rupprecht "$i & $j", 13299451b44SJordan Rupprecht "$i | $j", 133b725142cSPavel Labath "$i ^ $j", 1342238dcc3SJonas Devlieghere "($ull & -1) == $u", 1352238dcc3SJonas Devlieghere ] 13699451b44SJordan Rupprecht 13799451b44SJordan Rupprecht for expression in set_up_expressions: 13899451b44SJordan Rupprecht self.frame().EvaluateExpression(expression, options) 13999451b44SJordan Rupprecht 14099451b44SJordan Rupprecht for expression in expressions: 14199451b44SJordan Rupprecht interp_expression = expression 14299451b44SJordan Rupprecht jit_expression = "(int)getpid(); " + expression 14399451b44SJordan Rupprecht 1442238dcc3SJonas Devlieghere interp_result = ( 1452238dcc3SJonas Devlieghere self.frame() 1462238dcc3SJonas Devlieghere .EvaluateExpression(interp_expression, options) 1472238dcc3SJonas Devlieghere .GetValueAsSigned() 1482238dcc3SJonas Devlieghere ) 1492238dcc3SJonas Devlieghere jit_result = ( 1502238dcc3SJonas Devlieghere self.frame() 1512238dcc3SJonas Devlieghere .EvaluateExpression(jit_expression, options) 1522238dcc3SJonas Devlieghere .GetValueAsSigned() 1532238dcc3SJonas Devlieghere ) 15499451b44SJordan Rupprecht 15599451b44SJordan Rupprecht self.assertEqual( 1562238dcc3SJonas Devlieghere interp_result, jit_result, "While evaluating " + expression 1572238dcc3SJonas Devlieghere ) 15899451b44SJordan Rupprecht 15999451b44SJordan Rupprecht def test_type_conversions(self): 16099451b44SJordan Rupprecht target = self.dbg.GetDummyTarget() 16199451b44SJordan Rupprecht short_val = target.EvaluateExpression("(short)-1") 16299451b44SJordan Rupprecht self.assertEqual(short_val.GetValueAsSigned(), -1) 16399451b44SJordan Rupprecht long_val = target.EvaluateExpression("(long) " + short_val.GetName()) 16499451b44SJordan Rupprecht self.assertEqual(long_val.GetValueAsSigned(), -1) 165