Files
clang-p2996/lldb/test/API/functionalities/thread_plan/TestThreadPlanCommands.py
Jim Ingham 2d658c56d5 Disable two new tests on Windows. They are failing but the logs are not helpful.
Also turn on the command trace unconditionally for TestThreadPlanCommands.py as the
tests for the Ubuntu bot don't seem to run with -t making it hard to see why this is
failing remotely.
2020-04-03 17:14:56 -07:00

166 lines
7.6 KiB
Python

"""
Test that thread plan listing, and deleting works.
"""
import lldb
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.lldbtest import *
class TestThreadPlanCommands(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@skipIfWindows
def test_thread_plan_actions(self):
self.build()
self.main_source_file = lldb.SBFileSpec("main.c")
self.thread_plan_test()
def check_list_output(self, command, active_plans = [], completed_plans = [], discarded_plans = []):
# Check the "thread plan list" output against a list of active & completed and discarded plans.
# If all three check arrays are empty, that means the command is expected to fail.
interp = self.dbg.GetCommandInterpreter()
result = lldb.SBCommandReturnObject()
num_active = len(active_plans)
num_completed = len(completed_plans)
num_discarded = len(discarded_plans)
interp.HandleCommand(command, result)
print("Command: %s"%(command))
print(result.GetOutput())
if num_active == 0 and num_completed == 0 and num_discarded == 0:
self.assertFalse(result.Succeeded(), "command: '%s' succeeded when it should have failed: '%s'"%
(command, result.GetError()))
return
self.assertTrue(result.Succeeded(), "command: '%s' failed: '%s'"%(command, result.GetError()))
result_arr = result.GetOutput().splitlines()
num_results = len(result_arr)
# Match the expected number of elements.
# Adjust the count for the number of header lines we aren't matching:
fudge = 0
if num_completed == 0 and num_discarded == 0:
# The fudge is 3: Thread header, Active Plan header and base plan
fudge = 3
elif num_completed == 0 or num_discarded == 0:
# The fudge is 4: The above plus either the Completed or Discarded Plan header:
fudge = 4
else:
# The fudge is 5 since we have both headers:
fudge = 5
self.assertEqual(num_results, num_active + num_completed + num_discarded + fudge,
"Too many elements in match arrays")
# Now iterate through the results array and pick out the results.
result_idx = 0
self.assertIn("thread #", result_arr[result_idx], "Found thread header") ; result_idx += 1
self.assertIn("Active plan stack", result_arr[result_idx], "Found active header") ; result_idx += 1
self.assertIn("Element 0: Base thread plan", result_arr[result_idx], "Found base plan") ; result_idx += 1
for text in active_plans:
self.assertFalse("Completed plan stack" in result_arr[result_idx], "Found Completed header too early.")
self.assertIn(text, result_arr[result_idx], "Didn't find active plan: %s"%(text)) ; result_idx += 1
if len(completed_plans) > 0:
self.assertIn("Completed plan stack:", result_arr[result_idx], "Found completed plan stack header") ; result_idx += 1
for text in completed_plans:
self.assertIn(text, result_arr[result_idx], "Didn't find completed plan: %s"%(text)) ; result_idx += 1
if len(discarded_plans) > 0:
self.assertIn("Discarded plan stack:", result_arr[result_idx], "Found discarded plan stack header") ; result_idx += 1
for text in discarded_plans:
self.assertIn(text, result_arr[result_idx], "Didn't find completed plan: %s"%(text)) ; result_idx += 1
def thread_plan_test(self):
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
"Set a breakpoint here", self.main_source_file)
# Now set a breakpoint in call_me and step over. We should have
# two public thread plans
call_me_bkpt = target.BreakpointCreateBySourceRegex("Set another here", self.main_source_file)
self.assertTrue(call_me_bkpt.GetNumLocations() > 0, "Set the breakpoint successfully")
thread.StepOver()
threads = lldbutil.get_threads_stopped_at_breakpoint(process, call_me_bkpt)
self.assertEqual(len(threads), 1, "Hit my breakpoint while stepping over")
current_id = threads[0].GetIndexID()
current_tid = threads[0].GetThreadID()
# Run thread plan list without the -i flag:
command = "thread plan list %d"%(current_id)
self.check_list_output (command, ["Stepping over line main.c"], [])
# Run thread plan list with the -i flag:
command = "thread plan list -i %d"%(current_id)
self.check_list_output(command, ["Stepping over line main.c", "Stepping out from"])
# Run thread plan list providing TID, output should be the same:
command = "thread plan list -t %d"%(current_tid)
self.check_list_output(command, ["Stepping over line main.c"])
# Provide both index & tid, and make sure we only print once:
command = "thread plan list -t %d %d"%(current_tid, current_id)
self.check_list_output(command, ["Stepping over line main.c"])
# Try a fake TID, and make sure that fails:
fake_tid = 0
for i in range(100, 10000, 100):
fake_tid = current_tid + i
thread = process.GetThreadByID(fake_tid)
if not thread:
break
command = "thread plan list -t %d"%(fake_tid)
self.check_list_output(command)
# Now continue, and make sure we printed the completed plan:
process.Continue()
threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)
self.assertEqual(len(threads), 1, "One thread completed a step")
# Run thread plan list - there aren't any private plans at this point:
command = "thread plan list %d"%(current_id)
self.check_list_output(command, [], ["Stepping over line main.c"])
# Set another breakpoint that we can run to, to try deleting thread plans.
second_step_bkpt = target.BreakpointCreateBySourceRegex("Run here to step over again",
self.main_source_file)
self.assertTrue(second_step_bkpt.GetNumLocations() > 0, "Set the breakpoint successfully")
final_bkpt = target.BreakpointCreateBySourceRegex("Make sure we get here on last continue",
self.main_source_file)
self.assertTrue(final_bkpt.GetNumLocations() > 0, "Set the breakpoint successfully")
threads = lldbutil.continue_to_breakpoint(process, second_step_bkpt)
self.assertEqual(len(threads), 1, "Hit the second step breakpoint")
threads[0].StepOver()
threads = lldbutil.get_threads_stopped_at_breakpoint(process, call_me_bkpt)
result = lldb.SBCommandReturnObject()
interp = self.dbg.GetCommandInterpreter()
interp.HandleCommand("thread plan discard 1", result)
self.assertTrue(result.Succeeded(), "Deleted the step over plan: %s"%(result.GetOutput()))
# Make sure the plan gets listed in the discarded plans:
command = "thread plan list %d"%(current_id)
self.check_list_output(command, [], [], ["Stepping over line main.c:"])
process.Continue()
threads = lldbutil.get_threads_stopped_at_breakpoint(process, final_bkpt)
self.assertEqual(len(threads), 1, "Ran to final breakpoint")
threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)
self.assertEqual(len(threads), 0, "Did NOT complete the step over plan")