114 lines · python
1"""2Test thread creation after process attach.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class CreateAfterAttachTestCase(TestBase):13 def setUp(self):14 # Call super's setUp().15 TestBase.setUp(self)16 # Find the line numbers for our breakpoints.17 self.break_1 = line_number("main.cpp", "// Set first breakpoint here")18 self.break_2 = line_number("main.cpp", "// Set second breakpoint here")19 self.break_3 = line_number("main.cpp", "// Set third breakpoint here")20 21 # Occasionally hangs on Windows, may be same as other issues.22 @skipIfWindows23 @skipIfiOSSimulator24 @expectedFailureNetBSD25 def test_create_after_attach(self):26 """Test thread creation after process attach."""27 self.build()28 exe = self.getBuildArtifact("a.out")29 30 # Spawn a new process31 # use realpath to workaround llvm.org/pr4837632 popen = self.spawnSubprocess(os.path.realpath(exe))33 pid = popen.pid34 35 # Attach to the spawned process36 self.runCmd("process attach -p " + str(pid))37 38 target = self.dbg.GetSelectedTarget()39 40 process = target.GetProcess()41 self.assertTrue(process, PROCESS_IS_VALID)42 43 # This should create a breakpoint in the main thread.44 lldbutil.run_break_set_by_file_and_line(45 self, "main.cpp", self.break_1, num_expected_locations=146 )47 48 # This should create a breakpoint in the second child thread.49 lldbutil.run_break_set_by_file_and_line(50 self, "main.cpp", self.break_2, num_expected_locations=151 )52 53 # This should create a breakpoint in the first child thread.54 lldbutil.run_break_set_by_file_and_line(55 self, "main.cpp", self.break_3, num_expected_locations=156 )57 58 # Note: With std::thread, we cannot rely on particular thread numbers. Using59 # std::thread may cause the program to spin up a thread pool (and it does on60 # Windows), so the thread numbers are non-deterministic.61 62 # Run to the first breakpoint63 self.runCmd("continue")64 65 # The stop reason of the thread should be breakpoint.66 self.expect(67 "thread list",68 STOPPED_DUE_TO_BREAKPOINT,69 substrs=["stopped", "* thread #", "main", "stop reason = breakpoint"],70 )71 72 # Change a variable to escape the loop73 self.runCmd("expression main_thread_continue = 1")74 75 # Run to the second breakpoint76 self.runCmd("continue")77 78 # The stop reason of the thread should be breakpoint.79 self.expect(80 "thread list",81 STOPPED_DUE_TO_BREAKPOINT,82 substrs=[83 "stopped",84 "* thread #",85 "thread_2_func",86 "stop reason = breakpoint",87 ],88 )89 90 # Change a variable to escape the loop91 self.runCmd("expression child_thread_continue = 1")92 93 # Run to the third breakpoint94 self.runCmd("continue")95 96 # The stop reason of the thread should be breakpoint.97 # Thread 3 may or may not have already exited.98 self.expect(99 "thread list",100 STOPPED_DUE_TO_BREAKPOINT,101 substrs=[102 "stopped",103 "* thread #",104 "thread_1_func",105 "stop reason = breakpoint",106 ],107 )108 109 # Run to completion110 self.runCmd("continue")111 112 # At this point, the inferior process should have exited.113 self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)114