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 # Occasionally hangs on Windows, may be same as other issues. 26 @skipIfWindows 27 @skipIfiOSSimulator 28 @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr48376") 29 @expectedFailureNetBSD 30 def test_create_after_attach(self): 31 """Test thread creation after process attach.""" 32 self.build(dictionary=self.getBuildFlags(use_cpp11=False)) 33 exe = self.getBuildArtifact("a.out") 34 35 # Spawn a new process 36 popen = self.spawnSubprocess(exe) 37 pid = popen.pid 38 39 # Attach to the spawned process 40 self.runCmd("process attach -p " + str(pid)) 41 42 target = self.dbg.GetSelectedTarget() 43 44 process = target.GetProcess() 45 self.assertTrue(process, PROCESS_IS_VALID) 46 47 # This should create a breakpoint in the main thread. 48 lldbutil.run_break_set_by_file_and_line( 49 self, "main.cpp", self.break_1, num_expected_locations=1) 50 51 # This should create a breakpoint in the second child thread. 52 lldbutil.run_break_set_by_file_and_line( 53 self, "main.cpp", self.break_2, num_expected_locations=1) 54 55 # This should create a breakpoint in the first child thread. 56 lldbutil.run_break_set_by_file_and_line( 57 self, "main.cpp", self.break_3, num_expected_locations=1) 58 59 # Note: With std::thread, we cannot rely on particular thread numbers. Using 60 # std::thread may cause the program to spin up a thread pool (and it does on 61 # Windows), so the thread numbers are non-deterministic. 62 63 # Run to the first breakpoint 64 self.runCmd("continue") 65 66 # The stop reason of the thread should be breakpoint. 67 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 68 substrs=['stopped', 69 '* thread #', 70 'main', 71 'stop reason = breakpoint']) 72 73 # Change a variable to escape the loop 74 self.runCmd("expression main_thread_continue = 1") 75 76 # Run to the second breakpoint 77 self.runCmd("continue") 78 79 # The stop reason of the thread should be breakpoint. 80 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 81 substrs=['stopped', 82 '* thread #', 83 'thread_2_func', 84 'stop reason = breakpoint']) 85 86 # Change a variable to escape the loop 87 self.runCmd("expression child_thread_continue = 1") 88 89 # Run to the third breakpoint 90 self.runCmd("continue") 91 92 # The stop reason of the thread should be breakpoint. 93 # Thread 3 may or may not have already exited. 94 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 95 substrs=['stopped', 96 '* thread #', 97 'thread_1_func', 98 'stop reason = breakpoint']) 99 100 # Run to completion 101 self.runCmd("continue") 102 103 # At this point, the inferior process should have exited. 104 self.assertTrue( 105 process.GetState() == lldb.eStateExited, 106 PROCESS_EXITED) 107