12451cbf0SJonas Devlieghere"""
22451cbf0SJonas DevlieghereTest reproducer attach.
32451cbf0SJonas Devlieghere"""
42451cbf0SJonas Devlieghere
52451cbf0SJonas Devlieghereimport lldb
62451cbf0SJonas Devlieghereimport tempfile
72451cbf0SJonas Devliegherefrom lldbsuite.test import lldbtest_config
82451cbf0SJonas Devliegherefrom lldbsuite.test.decorators import *
92451cbf0SJonas Devliegherefrom lldbsuite.test.lldbtest import *
102451cbf0SJonas Devliegherefrom lldbsuite.test import lldbutil
112451cbf0SJonas Devlieghere
122451cbf0SJonas Devlieghere
1301387c44SJonas Devlieghereclass ReproducerAttachTestCase(TestBase):
142451cbf0SJonas Devlieghere    NO_DEBUG_INFO_TESTCASE = True
152451cbf0SJonas Devlieghere
162451cbf0SJonas Devlieghere    @skipIfNetBSD
172451cbf0SJonas Devlieghere    @skipIfWindows
182451cbf0SJonas Devlieghere    @skipIfRemote
192451cbf0SJonas Devlieghere    @skipIfiOSSimulator
2001387c44SJonas Devlieghere    def test_reproducer_attach(self):
212451cbf0SJonas Devlieghere        """Test thread creation after process attach."""
222451cbf0SJonas Devlieghere        exe = '%s_%d' % (self.testMethodName, os.getpid())
232451cbf0SJonas Devlieghere
242451cbf0SJonas Devlieghere        token = self.getBuildArtifact(exe + '.token')
252451cbf0SJonas Devlieghere        if os.path.exists(token):
262451cbf0SJonas Devlieghere            os.remove(token)
272451cbf0SJonas Devlieghere
282451cbf0SJonas Devlieghere        reproducer = self.getBuildArtifact(exe + '.reproducer')
292451cbf0SJonas Devlieghere        if os.path.exists(reproducer):
302451cbf0SJonas Devlieghere            try:
312451cbf0SJonas Devlieghere                shutil.rmtree(reproducer)
322451cbf0SJonas Devlieghere            except OSError:
332451cbf0SJonas Devlieghere                pass
342451cbf0SJonas Devlieghere
352451cbf0SJonas Devlieghere        self.build(dictionary={'EXE': exe})
362451cbf0SJonas Devlieghere
372451cbf0SJonas Devlieghere        inferior = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
382451cbf0SJonas Devlieghere        pid = inferior.pid
392451cbf0SJonas Devlieghere
402451cbf0SJonas Devlieghere        lldbutil.wait_for_file_on_target(self, token)
412451cbf0SJonas Devlieghere
422451cbf0SJonas Devlieghere        # Use Popen because pexpect is overkill and spawnSubprocess is
432451cbf0SJonas Devlieghere        # asynchronous.
442451cbf0SJonas Devlieghere        capture = subprocess.Popen([
45*68a9356bSJan Kratochvil            lldbtest_config.lldbExec, '-b', '--no-lldbinit', '--no-use-colors']
46*68a9356bSJan Kratochvil            + sum(map(lambda x: ['-O', x], self.setUpCommands()), [])
47*68a9356bSJan Kratochvil            + ['--capture', '--capture-path', reproducer,
48*68a9356bSJan Kratochvil            '-o', 'proc att -n {}'.format(exe), '-o', 'reproducer generate'
492451cbf0SJonas Devlieghere        ],
502451cbf0SJonas Devlieghere                                   stdin=subprocess.PIPE,
512451cbf0SJonas Devlieghere                                   stdout=subprocess.PIPE,
522451cbf0SJonas Devlieghere                                   stderr=subprocess.PIPE)
5317bdb7a1SJonas Devlieghere        outs, _ = capture.communicate()
5417bdb7a1SJonas Devlieghere        outs = outs.decode('utf-8')
552451cbf0SJonas Devlieghere        self.assertIn('Process {} stopped'.format(pid), outs)
562451cbf0SJonas Devlieghere        self.assertIn('Reproducer written', outs)
572451cbf0SJonas Devlieghere
582451cbf0SJonas Devlieghere        # We can dump the reproducer in the current context.
592451cbf0SJonas Devlieghere        self.expect('reproducer dump -f {} -p process'.format(reproducer),
602451cbf0SJonas Devlieghere                    substrs=['pid = {}'.format(pid), 'name = {}'.format(exe)])
61