Home | History | Annotate | Download | only in state
      1 """
      2 Test thread states.
      3 """
      4 
      5 import os, time
      6 import unittest2
      7 import lldb
      8 from lldbtest import *
      9 import lldbutil
     10 
     11 class ThreadStateTestCase(TestBase):
     12 
     13     mydir = os.path.join("functionalities", "thread", "state")
     14 
     15     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     16     @dsym_test
     17     def test_state_after_breakpoint_with_dsym(self):
     18         """Test thread state after breakpoint."""
     19         self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False))
     20         self.thread_state_after_breakpoint_test()
     21 
     22     @dwarf_test
     23     def test_state_after_breakpoint_with_dwarf(self):
     24         """Test thread state after breakpoint."""
     25         self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
     26         self.thread_state_after_breakpoint_test()
     27 
     28     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     29     @dsym_test
     30     def test_state_after_continue_with_dsym(self):
     31         """Test thread state after continue."""
     32         self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False))
     33         self.thread_state_after_continue_test()
     34 
     35     @dwarf_test
     36     def test_state_after_continue_with_dwarf(self):
     37         """Test thread state after continue."""
     38         self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
     39         self.thread_state_after_continue_test()
     40 
     41     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     42     @dsym_test
     43     def test_state_after_expression_with_dsym(self):
     44         """Test thread state after expression."""
     45         self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False))
     46         self.thread_state_after_continue_test()
     47 
     48     @dwarf_test
     49     def test_state_after_expression_with_dwarf(self):
     50         """Test thread state after expression."""
     51         self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
     52         self.thread_state_after_continue_test()
     53 
     54     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     55     @dsym_test
     56     @unittest2.expectedFailure("llvm.org/pr16172") # thread states not properly maintained
     57     def test_process_interrupt_with_dsym(self):
     58         """Test process interrupt."""
     59         self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False))
     60         self.process_interrupt_test()
     61 
     62     @dwarf_test
     63     @unittest2.expectedFailure("llvm.org/pr16712") # thread states not properly maintained
     64     def test_process_interrupt_with_dwarf(self):
     65         """Test process interrupt."""
     66         self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
     67         self.process_interrupt_test()
     68 
     69     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     70     @dsym_test
     71     @unittest2.expectedFailure("llvm.org/pr15824") # thread states not properly maintained
     72     def test_process_state_with_dsym(self):
     73         """Test thread states (comprehensive)."""
     74         self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False))
     75         self.thread_states_test()
     76 
     77     @dwarf_test
     78     @unittest2.expectedFailure("llvm.org/pr15824") # thread states not properly maintained
     79     def test_process_state_with_dwarf(self):
     80         """Test thread states (comprehensive)."""
     81         self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
     82         self.thread_states_test()
     83 
     84     def setUp(self):
     85         # Call super's setUp().
     86         TestBase.setUp(self)
     87         # Find the line numbers for our breakpoints.
     88         self.break_1 = line_number('main.c', '// Set first breakpoint here')
     89         self.break_2 = line_number('main.c', '// Set second breakpoint here')
     90 
     91     def thread_state_after_breakpoint_test(self):
     92         """Test thread state after breakpoint."""
     93         exe = os.path.join(os.getcwd(), "a.out")
     94         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     95 
     96         # This should create a breakpoint in the main thread.
     97         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1)
     98 
     99         # The breakpoint list should show 1 breakpoint with 1 location.
    100         self.expect("breakpoint list -f", "Breakpoint location shown correctly",
    101             substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1])
    102 
    103         # Run the program.
    104         self.runCmd("run", RUN_SUCCEEDED)
    105 
    106         # The stop reason of the thread should be breakpoint.
    107         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    108             substrs = ['stopped',
    109                        '* thread #1',
    110                        'stop reason = breakpoint'])
    111 
    112         # Get the target process
    113         target = self.dbg.GetSelectedTarget()
    114         process = target.GetProcess()
    115 
    116         # Get the number of threads
    117         num_threads = process.GetNumThreads()
    118 
    119         self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
    120 
    121         # Get the thread object
    122         thread = process.GetThreadAtIndex(0)
    123 
    124         # Make sure the thread is in the stopped state.
    125         self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.")
    126         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.")
    127 
    128         # Kill the process
    129         self.runCmd("process kill")
    130 
    131     def thread_state_after_continue_test(self):
    132         """Test thread state after continue."""
    133         exe = os.path.join(os.getcwd(), "a.out")
    134         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
    135 
    136         # This should create a breakpoint in the main thread.
    137         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1)
    138         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1)
    139 
    140         # The breakpoint list should show 1 breakpoints with 1 location.
    141         self.expect("breakpoint list -f", "Breakpoint location shown correctly",
    142             substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1])
    143 
    144         # Run the program.
    145         self.runCmd("run", RUN_SUCCEEDED)
    146 
    147         # The stop reason of the thread should be breakpoint.
    148         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    149             substrs = ['stopped',
    150                        '* thread #1',
    151                        'stop reason = breakpoint'])
    152 
    153         # Get the target process
    154         target = self.dbg.GetSelectedTarget()
    155         process = target.GetProcess()
    156 
    157         # Get the number of threads
    158         num_threads = process.GetNumThreads()
    159 
    160         self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
    161 
    162         # Get the thread object
    163         thread = process.GetThreadAtIndex(0)
    164 
    165         # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
    166         self.dbg.SetAsync(True)
    167         self.runCmd("continue")
    168         time.sleep(1)
    169 
    170         # Check the thread state. It should be running.
    171         self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.")
    172         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.")
    173 
    174         # Go back to synchronous interactions
    175         self.dbg.SetAsync(False)
    176 
    177         # Kill the process
    178         self.runCmd("process kill")
    179 
    180     def thread_state_after_expression_test(self):
    181         """Test thread state after expression."""
    182         exe = os.path.join(os.getcwd(), "a.out")
    183         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
    184 
    185         # This should create a breakpoint in the main thread.
    186         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1)
    187         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1)
    188 
    189         # The breakpoint list should show 1 breakpoints with 1 location.
    190         self.expect("breakpoint list -f", "Breakpoint location shown correctly",
    191             substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1])
    192 
    193         # Run the program.
    194         self.runCmd("run", RUN_SUCCEEDED)
    195 
    196         # The stop reason of the thread should be breakpoint.
    197         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    198             substrs = ['stopped',
    199                        '* thread #1',
    200                        'stop reason = breakpoint'])
    201 
    202         # Get the target process
    203         target = self.dbg.GetSelectedTarget()
    204         process = target.GetProcess()
    205 
    206         # Get the number of threads
    207         num_threads = process.GetNumThreads()
    208 
    209         self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
    210 
    211         # Get the thread object
    212         thread = process.GetThreadAtIndex(0)
    213 
    214         # Get the inferior out of its loop
    215         self.runCmd("expression g_test = 1")
    216 
    217         # Check the thread state
    218         self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.")
    219         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.")
    220 
    221         # Let the process run to completion
    222         self.runCmd("process continue")
    223 
    224 
    225     def process_interrupt_test(self):
    226         """Test process interrupt and continue."""
    227         exe = os.path.join(os.getcwd(), "a.out")
    228         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
    229 
    230         # This should create a breakpoint in the main thread.
    231         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1)
    232 
    233         # The breakpoint list should show 1 breakpoints with 1 location.
    234         self.expect("breakpoint list -f", "Breakpoint location shown correctly",
    235             substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1])
    236 
    237         # Run the program.
    238         self.runCmd("run", RUN_SUCCEEDED)
    239 
    240         # The stop reason of the thread should be breakpoint.
    241         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    242             substrs = ['stopped',
    243                        '* thread #1',
    244                        'stop reason = breakpoint'])
    245 
    246         # Get the target process
    247         target = self.dbg.GetSelectedTarget()
    248         process = target.GetProcess()
    249 
    250         # Get the number of threads
    251         num_threads = process.GetNumThreads()
    252 
    253         self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
    254 
    255         # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
    256         self.dbg.SetAsync(True)
    257         self.runCmd("continue")
    258         time.sleep(1)
    259 
    260         # Go back to synchronous interactions
    261         self.dbg.SetAsync(False)
    262 
    263         # Stop the process
    264         self.runCmd("process interrupt")
    265 
    266         # The stop reason of the thread should be signal.
    267         self.expect("process status", STOPPED_DUE_TO_SIGNAL,
    268             substrs = ['stopped',
    269                        '* thread #1',
    270                        'stop reason = signal'])
    271 
    272         # Get the inferior out of its loop
    273         self.runCmd("expression g_test = 1")
    274 
    275         # Run to completion
    276         self.runCmd("continue")
    277 
    278     def thread_states_test(self):
    279         """Test thread states (comprehensive)."""
    280         exe = os.path.join(os.getcwd(), "a.out")
    281         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
    282 
    283         # This should create a breakpoint in the main thread.
    284         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1)
    285         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1)
    286 
    287         # The breakpoint list should show 2 breakpoints with 1 location each.
    288         self.expect("breakpoint list -f", "Breakpoint location shown correctly",
    289             substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1,
    290                        "2: file = 'main.c', line = %d, locations = 1" % self.break_2])
    291 
    292         # Run the program.
    293         self.runCmd("run", RUN_SUCCEEDED)
    294 
    295         # The stop reason of the thread should be breakpoint.
    296         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    297             substrs = ['stopped',
    298                        '* thread #1',
    299                        'stop reason = breakpoint'])
    300 
    301         # Get the target process
    302         target = self.dbg.GetSelectedTarget()
    303         process = target.GetProcess()
    304 
    305         # Get the number of threads
    306         num_threads = process.GetNumThreads()
    307 
    308         self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
    309 
    310         # Get the thread object
    311         thread = process.GetThreadAtIndex(0)
    312 
    313         # Make sure the thread is in the stopped state.
    314         self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.")
    315         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.")
    316 
    317         # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
    318         self.dbg.SetAsync(True)
    319         self.runCmd("continue")
    320         time.sleep(1)
    321 
    322         # Check the thread state. It should be running.
    323         self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.")
    324         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.")
    325 
    326         # Go back to synchronous interactions
    327         self.dbg.SetAsync(False)
    328 
    329         # Stop the process
    330         self.runCmd("process interrupt")
    331 
    332         # The stop reason of the thread should be signal.
    333         self.expect("process status", STOPPED_DUE_TO_SIGNAL,
    334             substrs = ['stopped',
    335                        '* thread #1',
    336                        'stop reason = signal'])
    337 
    338         # Check the thread state
    339         self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after process stop.")
    340         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after process stop.")
    341 
    342         # Get the inferior out of its loop
    343         self.runCmd("expression g_test = 1")
    344 
    345         # Check the thread state
    346         self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.")
    347         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.")
    348 
    349         # The stop reason of the thread should be signal.
    350         self.expect("process status", STOPPED_DUE_TO_SIGNAL,
    351             substrs = ['stopped',
    352                        '* thread #1',
    353                        'stop reason = signal'])
    354 
    355         # Run to breakpoint 2
    356         self.runCmd("continue")
    357 
    358         # The stop reason of the thread should be breakpoint.
    359         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    360             substrs = ['stopped',
    361                        '* thread #1',
    362                        'stop reason = breakpoint'])
    363 
    364         # Make sure both threads are stopped
    365         self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 2.")
    366         self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 2.")
    367 
    368         # Run to completion
    369         self.runCmd("continue")
    370 
    371         # At this point, the inferior process should have exited.
    372         self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
    373 
    374 if __name__ == '__main__':
    375     import atexit
    376     lldb.SBDebugger.Initialize()
    377     atexit.register(lambda: lldb.SBDebugger.Terminate())
    378     unittest2.main()
    379