1""" 2Test thread creation after process attach. 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class CreateAfterAttachTestCase(TestBase): 14 15 mydir = TestBase.compute_mydir(__file__) 16 17 def setUp(self): 18 # Call super's setUp(). 19 TestBase.setUp(self) 20 # Find the line numbers for our breakpoints. 21 self.break_1 = line_number('main.cpp', '// Set first breakpoint here') 22 self.break_2 = line_number('main.cpp', '// Set second breakpoint here') 23 self.break_3 = line_number('main.cpp', '// Set third breakpoint here') 24 25 @skipIfFreeBSD # Hangs. May be the same as Linux issue llvm.org/pr16229 but 26 # not yet investigated. Revisit once required functionality 27 # is implemented for FreeBSD. 28 # Occasionally hangs on Windows, may be same as other issues. 29 @skipIfWindows 30 @skipIfiOSSimulator 31 @expectedFailureNetBSD 32 def test_create_after_attach(self): 33 """Test thread creation after process attach.""" 34 self.build(dictionary=self.getBuildFlags(use_cpp11=False)) 35 exe = self.getBuildArtifact("a.out") 36 37 # Spawn a new process 38 popen = self.spawnSubprocess(exe) 39 pid = popen.pid 40 41 # Attach to the spawned process 42 self.runCmd("process attach -p " + str(pid)) 43 44 target = self.dbg.GetSelectedTarget() 45 46 process = target.GetProcess() 47 self.assertTrue(process, PROCESS_IS_VALID) 48 49 # This should create a breakpoint in the main thread. 50 lldbutil.run_break_set_by_file_and_line( 51 self, "main.cpp", self.break_1, num_expected_locations=1) 52 53 # This should create a breakpoint in the second child thread. 54 lldbutil.run_break_set_by_file_and_line( 55 self, "main.cpp", self.break_2, num_expected_locations=1) 56 57 # This should create a breakpoint in the first child thread. 58 lldbutil.run_break_set_by_file_and_line( 59 self, "main.cpp", self.break_3, num_expected_locations=1) 60 61 # Note: With std::thread, we cannot rely on particular thread numbers. Using 62 # std::thread may cause the program to spin up a thread pool (and it does on 63 # Windows), so the thread numbers are non-deterministic. 64 65 # Run to the first breakpoint 66 self.runCmd("continue") 67 68 # The stop reason of the thread should be breakpoint. 69 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 70 substrs=['stopped', 71 '* thread #', 72 'main', 73 'stop reason = breakpoint']) 74 75 # Change a variable to escape the loop 76 self.runCmd("expression main_thread_continue = 1") 77 78 # Run to the second 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 #', 85 'thread_2_func', 86 'stop reason = breakpoint']) 87 88 # Change a variable to escape the loop 89 self.runCmd("expression child_thread_continue = 1") 90 91 # Run to the third breakpoint 92 self.runCmd("continue") 93 94 # The stop reason of the thread should be breakpoint. 95 # Thread 3 may or may not have already exited. 96 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 97 substrs=['stopped', 98 '* thread #', 99 'thread_1_func', 100 'stop reason = breakpoint']) 101 102 # Run to completion 103 self.runCmd("continue") 104 105 # At this point, the inferior process should have exited. 106 self.assertTrue( 107 process.GetState() == lldb.eStateExited, 108 PROCESS_EXITED) 109