1""" 2Test reproducer attach. 3""" 4 5import lldb 6import tempfile 7from lldbsuite.test import lldbtest_config 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class ReproducerAttachTestCase(TestBase): 14 15 mydir = TestBase.compute_mydir(__file__) 16 NO_DEBUG_INFO_TESTCASE = True 17 18 @skipIfFreeBSD 19 @skipIfNetBSD 20 @skipIfWindows 21 @skipIfRemote 22 @skipIfiOSSimulator 23 @skipIfReproducer 24 def test_reproducer_attach(self): 25 """Test thread creation after process attach.""" 26 exe = '%s_%d' % (self.testMethodName, os.getpid()) 27 28 token = self.getBuildArtifact(exe + '.token') 29 if os.path.exists(token): 30 os.remove(token) 31 32 reproducer = self.getBuildArtifact(exe + '.reproducer') 33 if os.path.exists(reproducer): 34 try: 35 shutil.rmtree(reproducer) 36 except OSError: 37 pass 38 39 self.build(dictionary={'EXE': exe}) 40 self.addTearDownHook(self.cleanupSubprocesses) 41 42 inferior = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) 43 pid = inferior.pid 44 45 lldbutil.wait_for_file_on_target(self, token) 46 47 # Use Popen because pexpect is overkill and spawnSubprocess is 48 # asynchronous. 49 capture = subprocess.Popen([ 50 lldbtest_config.lldbExec, '-b', '--no-lldbinit', '--no-use-colors'] 51 + sum(map(lambda x: ['-O', x], self.setUpCommands()), []) 52 + ['--capture', '--capture-path', reproducer, 53 '-o', 'proc att -n {}'.format(exe), '-o', 'reproducer generate' 54 ], 55 stdin=subprocess.PIPE, 56 stdout=subprocess.PIPE, 57 stderr=subprocess.PIPE) 58 outs, _ = capture.communicate() 59 outs = outs.decode('utf-8') 60 self.assertIn('Process {} stopped'.format(pid), outs) 61 self.assertIn('Reproducer written', outs) 62 63 # Check that replay works. 64 replay = subprocess.Popen( 65 [lldbtest_config.lldbExec, '-replay', reproducer], 66 stdin=subprocess.PIPE, 67 stdout=subprocess.PIPE, 68 stderr=subprocess.PIPE) 69 outs, _ = replay.communicate() 70 outs = outs.decode('utf-8') 71 self.assertIn('Process {} stopped'.format(pid), outs) 72 73 # We can dump the reproducer in the current context. 74 self.expect('reproducer dump -f {} -p process'.format(reproducer), 75 substrs=['pid = {}'.format(pid), 'name = {}'.format(exe)]) 76