1 """ 2 Test thread creation after process attach. 3 """ 4 5 import os, time 6 import unittest2 7 import lldb 8 from lldbtest import * 9 import lldbutil 10 11 class CreateAfterAttachTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "thread", "create_after_attach") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @dsym_test 17 def test_create_after_attach_with_dsym(self): 18 """Test thread creation after process attach.""" 19 self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False)) 20 self.create_after_attach(use_fork=False) 21 22 @skipIfFreeBSD # Hangs. May be the same as Linux issue llvm.org/pr16229 but 23 # not yet investigated. Revisit once required functionality 24 # is implemented for FreeBSD. 25 @skipIfLinux # Hangs, see llvm.org/pr16229 26 @dwarf_test 27 def test_create_after_attach_with_dwarf_and_popen(self): 28 """Test thread creation after process attach.""" 29 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 30 self.create_after_attach(use_fork=False) 31 32 @skipIfFreeBSD # Hangs. Revisit once required functionality is implemented 33 # for FreeBSD. 34 @dwarf_test 35 def test_create_after_attach_with_dwarf_and_fork(self): 36 """Test thread creation after process attach.""" 37 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 38 self.create_after_attach(use_fork=True) 39 40 def setUp(self): 41 # Call super's setUp(). 42 TestBase.setUp(self) 43 # Find the line numbers for our breakpoints. 44 self.break_1 = line_number('main.c', '// Set first breakpoint here') 45 self.break_2 = line_number('main.c', '// Set second breakpoint here') 46 self.break_3 = line_number('main.c', '// Set third breakpoint here') 47 48 def create_after_attach(self, use_fork): 49 """Test thread creation after process attach.""" 50 51 exe = os.path.join(os.getcwd(), "a.out") 52 53 # Spawn a new process 54 if use_fork: 55 pid = self.forkSubprocess(exe) 56 else: 57 popen = self.spawnSubprocess(exe) 58 pid = popen.pid 59 self.addTearDownHook(self.cleanupSubprocesses) 60 61 # Attach to the spawned process 62 self.runCmd("process attach -p " + str(pid)) 63 64 target = self.dbg.GetSelectedTarget() 65 66 process = target.GetProcess() 67 self.assertTrue(process, PROCESS_IS_VALID) 68 69 # This should create a breakpoint in the main thread. 70 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) 71 72 # This should create a breakpoint in the second child thread. 73 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1) 74 75 # This should create a breakpoint in the first child thread. 76 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_3, num_expected_locations=1) 77 78 # Run to the first breakpoint 79 self.runCmd("continue") 80 81 # The stop reason of the thread should be breakpoint. 82 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 83 substrs = ['stopped', 84 '* thread #1', 85 'stop reason = breakpoint', 86 'thread #2']) 87 88 # Change a variable to escape the loop 89 self.runCmd("expression main_thread_continue = 1") 90 91 # Run to the second breakpoint 92 self.runCmd("continue") 93 self.runCmd("thread select 3") 94 95 # The stop reason of the thread should be breakpoint. 96 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 97 substrs = ['stopped', 98 'thread #1', 99 'thread #2', 100 '* thread #3', 101 'stop reason = breakpoint']) 102 103 # Change a variable to escape the loop 104 self.runCmd("expression child_thread_continue = 1") 105 106 # Run to the third breakpoint 107 self.runCmd("continue") 108 self.runCmd("thread select 2") 109 110 # The stop reason of the thread should be breakpoint. 111 # Thread 3 may or may not have already exited. 112 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 113 substrs = ['stopped', 114 'thread #1', 115 '* thread #2', 116 'stop reason = breakpoint']) 117 118 # Run to completion 119 self.runCmd("continue") 120 121 # At this point, the inferior process should have exited. 122 self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) 123 124 125 if __name__ == '__main__': 126 import atexit 127 lldb.SBDebugger.Initialize() 128 atexit.register(lambda: lldb.SBDebugger.Terminate()) 129 unittest2.main() 130