Home | History | Annotate | Download | only in thread_exit
      1 """
      2 Test number of threads.
      3 """
      4 
      5 import os, time
      6 import unittest2
      7 import lldb
      8 from lldbtest import *
      9 import lldbutil
     10 
     11 class 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 
    129 if __name__ == '__main__':
    130     import atexit
    131     lldb.SBDebugger.Initialize()
    132     atexit.register(lambda: lldb.SBDebugger.Terminate())
    133     unittest2.main()
    134