1""" 2Test number of threads. 3""" 4 5import os, time 6import unittest2 7import lldb 8from lldbtest import * 9import lldbutil 10 11class ThreadExitTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "thread", "thread_exit") 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 handling.""" 20 self.buildDsym(dictionary=self.getBuildFlags()) 21 self.thread_exit_test() 22 23 @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not implemented on FreeBSD yet 24 @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained 25 @dwarf_test 26 def test_with_dwarf(self): 27 """Test thread exit handling.""" 28 self.buildDwarf(dictionary=self.getBuildFlags()) 29 self.thread_exit_test() 30 31 def setUp(self): 32 # Call super's setUp(). 33 TestBase.setUp(self) 34 # Find the line numbers for our breakpoints. 35 self.break_1 = line_number('main.cpp', '// Set first breakpoint here') 36 self.break_2 = line_number('main.cpp', '// Set second breakpoint here') 37 self.break_3 = line_number('main.cpp', '// Set third breakpoint here') 38 self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here') 39 40 def thread_exit_test(self): 41 """Test thread exit handling.""" 42 exe = os.path.join(os.getcwd(), "a.out") 43 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 44 45 # This should create a breakpoint with 1 location. 46 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1) 47 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1) 48 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_3, num_expected_locations=1) 49 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_4, num_expected_locations=1) 50 51 # The breakpoint list should show 1 locations. 52 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 53 substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.break_1, 54 "2: file = 'main.cpp', line = %d, locations = 1" % self.break_2, 55 "3: file = 'main.cpp', line = %d, locations = 1" % self.break_3, 56 "4: file = 'main.cpp', line = %d, locations = 1" % self.break_4]) 57 58 # Run the program. 59 self.runCmd("run", RUN_SUCCEEDED) 60 61 # The stop reason of the thread should be breakpoint 1. 62 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 1", 63 substrs = ['stopped', 64 '* thread #1', 65 'stop reason = breakpoint 1', 66 'thread #2']) 67 68 # Get the target process 69 target = self.dbg.GetSelectedTarget() 70 process = target.GetProcess() 71 72 # Get the number of threads 73 num_threads = process.GetNumThreads() 74 75 self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match at breakpoint 1.') 76 77 # Run to the second breakpoint 78 self.runCmd("continue") 79 80 # The stop reason of the thread should be breakpoint 1. 81 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 2", 82 substrs = ['stopped', 83 'thread #1', 84 '* thread #2', 85 'stop reason = breakpoint 2', 86 'thread #3']) 87 88 # Update the number of threads 89 num_threads = process.GetNumThreads() 90 91 self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match at breakpoint 2.') 92 93 # Run to the third breakpoint 94 self.runCmd("continue") 95 96 # The stop reason of the thread should be breakpoint 3. 97 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 3", 98 substrs = ['stopped', 99 '* thread #1', 100 'stop reason = breakpoint 3', 101 'thread #3', 102 ]) 103 104 # Update the number of threads 105 num_threads = process.GetNumThreads() 106 107 self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match at breakpoint 3.') 108 109 # Run to the fourth breakpoint 110 self.runCmd("continue") 111 112 # The stop reason of the thread should be breakpoint 4. 113 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 4", 114 substrs = ['stopped', 115 '* thread #1', 116 'stop reason = breakpoint 4']) 117 118 # Update the number of threads 119 num_threads = process.GetNumThreads() 120 121 self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match at breakpoint 4.') 122 123 # Run to completion 124 self.runCmd("continue") 125 126 # At this point, the inferior process should have exited. 127 self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) 128 129if __name__ == '__main__': 130 import atexit 131 lldb.SBDebugger.Initialize() 132 atexit.register(lambda: lldb.SBDebugger.Terminate()) 133 unittest2.main() 134