summaryrefslogtreecommitdiffstats
path: root/lldb/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py
blob: 26cbf9e91e71c28f4c875e2f0218b6a892e08c02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
Test thread creation after process attach.
"""

import os, time
import unittest2
import lldb
from lldbtest import *
import lldbutil

class CreateAfterAttachTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    @skipUnlessDarwin
    @dsym_test
    def test_create_after_attach_with_dsym(self):
        """Test thread creation after process attach."""
        self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False))
        self.create_after_attach(use_fork=False)

    @skipIfFreeBSD # Hangs.  May be the same as Linux issue llvm.org/pr16229 but
                   # not yet investigated.  Revisit once required functionality
                   # is implemented for FreeBSD.
    @dwarf_test
    def test_create_after_attach_with_dwarf_and_popen(self):
        """Test thread creation after process attach."""
        self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
        self.create_after_attach(use_fork=False)

    @skipIfFreeBSD # Hangs. Revisit once required functionality is implemented
                   # for FreeBSD.
    @dwarf_test
    @expectedFailureLinux # this test fails 1/100 dosep runs
    def test_create_after_attach_with_dwarf_and_fork(self):
        """Test thread creation after process attach."""
        self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False))
        self.create_after_attach(use_fork=True)

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line numbers for our breakpoints.
        self.break_1 = line_number('main.c', '// Set first breakpoint here')
        self.break_2 = line_number('main.c', '// Set second breakpoint here')
        self.break_3 = line_number('main.c', '// Set third breakpoint here')

    def create_after_attach(self, use_fork):
        """Test thread creation after process attach."""

        exe = os.path.join(os.getcwd(), "a.out")

        # Spawn a new process
        if use_fork:
            pid = self.forkSubprocess(exe)
        else:
            popen = self.spawnSubprocess(exe)
            pid = popen.pid
        self.addTearDownHook(self.cleanupSubprocesses)

        # Attach to the spawned process
        self.runCmd("process attach -p " + str(pid))

        target = self.dbg.GetSelectedTarget()

        process = target.GetProcess()
        self.assertTrue(process, PROCESS_IS_VALID)

        # This should create a breakpoint in the main thread.
        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1)

        # This should create a breakpoint in the second child thread.
        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1)

        # This should create a breakpoint in the first child thread.
        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_3, num_expected_locations=1)

        # Run to the first breakpoint
        self.runCmd("continue")

        # The stop reason of the thread should be breakpoint.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
            substrs = ['stopped',
                       '* thread #1',
                       'stop reason = breakpoint',
                       'thread #2'])

        # Change a variable to escape the loop
        self.runCmd("expression main_thread_continue = 1")

        # Run to the second breakpoint
        self.runCmd("continue")
        self.runCmd("thread select 3")

        # The stop reason of the thread should be breakpoint.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
            substrs = ['stopped',
                       'thread #1',
                       'thread #2',
                       '* thread #3',
                       'stop reason = breakpoint'])

        # Change a variable to escape the loop
        self.runCmd("expression child_thread_continue = 1")

        # Run to the third breakpoint
        self.runCmd("continue")
        self.runCmd("thread select 2")

        # The stop reason of the thread should be breakpoint.
        # Thread 3 may or may not have already exited.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
            substrs = ['stopped',
                       'thread #1',
                       '* thread #2',
                       'stop reason = breakpoint'])

        # Run to completion
        self.runCmd("continue")

        # At this point, the inferior process should have exited.
        self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)


if __name__ == '__main__':
    import atexit
    lldb.SBDebugger.Initialize()
    atexit.register(lambda: lldb.SBDebugger.Terminate())
    unittest2.main()
OpenPOWER on IntegriCloud