1""" 2Test number of threads. 3""" 4 5import os, time 6import unittest2 7import lldb 8from lldbtest import * 9import lldbutil 10 11class ExitDuringStepTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "thread", "exit_during_step") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 17 @dsym_test 18 def test_with_dsym(self): 19 """Test thread exit during step handling.""" 20 self.buildDsym(dictionary=self.getBuildFlags()) 21 self.exit_during_step_inst_test() 22 23 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 24 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 25 @dsym_test 26 def test_step_over_with_dsym(self): 27 """Test thread exit during step-over handling.""" 28 self.buildDsym(dictionary=self.getBuildFlags()) 29 self.exit_during_step_over_test() 30 31 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 32 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 33 @dsym_test 34 def test_step_in_with_dsym(self): 35 """Test thread exit during step-in handling.""" 36 self.buildDsym(dictionary=self.getBuildFlags()) 37 self.exit_during_step_in_test() 38 39 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 40 @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD 41 @dwarf_test 42 def test_with_dwarf(self): 43 """Test thread exit during step handling.""" 44 self.buildDwarf(dictionary=self.getBuildFlags()) 45 self.exit_during_step_inst_test() 46 47 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 48 @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD 49 @dwarf_test 50 def test_step_over_with_dwarf(self): 51 """Test thread exit during step-over handling.""" 52 self.buildDwarf(dictionary=self.getBuildFlags()) 53 self.exit_during_step_over_test() 54 55 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 56 @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD 57 @dwarf_test 58 def test_step_in_with_dwarf(self): 59 """Test thread exit during step-in handling.""" 60 self.buildDwarf(dictionary=self.getBuildFlags()) 61 self.exit_during_step_in_test() 62 63 def setUp(self): 64 # Call super's setUp(). 65 TestBase.setUp(self) 66 # Find the line numbers to break and continue. 67 self.breakpoint = line_number('main.cpp', '// Set breakpoint here') 68 self.continuepoint = line_number('main.cpp', '// Continue from here') 69 70 def exit_during_step_inst_test(self): 71 """Test thread exit while using step-inst.""" 72 self.exit_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step') 73 74 def exit_during_step_over_test(self): 75 """Test thread exit while using step-over.""" 76 self.exit_during_step_base("thread step-over -m all-threads", 'stop reason = step over') 77 78 def exit_during_step_in_test(self): 79 """Test thread exit while using step-in.""" 80 self.exit_during_step_base("thread step-in -m all-threads", 'stop reason = step in') 81 82 def exit_during_step_base(self, step_cmd, step_stop_reason): 83 """Test thread exit during step handling.""" 84 exe = os.path.join(os.getcwd(), "a.out") 85 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 86 87 # This should create a breakpoint in the main thread. 88 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1) 89 90 # The breakpoint list should show 1 location. 91 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 92 substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint]) 93 94 # Run the program. 95 self.runCmd("run", RUN_SUCCEEDED) 96 97 # The stop reason of the thread should be breakpoint. 98 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 99 substrs = ['stopped', 100 'stop reason = breakpoint']) 101 102 # Get the target process 103 target = self.dbg.GetSelectedTarget() 104 process = target.GetProcess() 105 106 # Get the number of threads 107 num_threads = process.GetNumThreads() 108 109 # Make sure we see all three threads 110 self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match.') 111 112 # Get the thread objects 113 thread1 = process.GetThreadAtIndex(0) 114 thread2 = process.GetThreadAtIndex(1) 115 thread3 = process.GetThreadAtIndex(2) 116 117 # Make sure all threads are stopped 118 self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint") 119 self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint") 120 self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop during breakpoint") 121 122 # Keep stepping until we've reached our designated continue point 123 stepping_thread = process.GetSelectedThread() 124 current_line = self.breakpoint 125 stepping_frame = stepping_thread.GetFrameAtIndex(0) 126 self.assertTrue(current_line == stepping_frame.GetLineEntry().GetLine(), "Starting line for stepping doesn't match breakpoint line.") 127 while current_line != self.continuepoint: 128 self.runCmd(step_cmd) 129 130 if stepping_thread != process.GetSelectedThread(): 131 process.SetSelectedThread(stepping_thread) 132 133 frame = stepping_thread.GetFrameAtIndex(0) 134 135 current_line = frame.GetLineEntry().GetLine() 136 137 self.assertTrue(current_line >= self.breakpoint, "Stepped to unexpected line, " + str(current_line)) 138 self.assertTrue(current_line <= self.continuepoint, "Stepped to unexpected line, " + str(current_line)) 139 140 self.runCmd("thread list") 141 142 # Update the number of threads 143 num_threads = process.GetNumThreads() 144 145 # Check to see that we reduced the number of threads as expected 146 self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match after thread exit.') 147 148 self.expect("thread list", 'Process state is stopped due to step', 149 substrs = ['stopped', 150 step_stop_reason]) 151 152 # Run to completion 153 self.runCmd("continue") 154 155 # At this point, the inferior process should have exited. 156 self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) 157 158if __name__ == '__main__': 159 import atexit 160 lldb.SBDebugger.Initialize() 161 atexit.register(lambda: lldb.SBDebugger.Terminate()) 162 unittest2.main() 163