summaryrefslogtreecommitdiff
path: root/lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/TestBreakpoint.py
blob: b95a97d9dae7b1e75fb96782a9441bf7916f70df (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
Test lldb breakpoint with symlinks/realpath and source-map.
"""

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil, lldbplatformutil


class BreakpointTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break inside main().
        self.line_in_main = line_number("main.c", "// Set break point at this line.")
        self.line_in_foo = line_number("real/foo.h", "// Set break point at this line.")
        self.line_in_bar = line_number("real/bar.h", "// Set break point at this line.")
        self.line_in_qux = line_number("real/qux.h", "// Set break point at this line.")
        # disable "There is a running process, kill it and restart?" prompt
        self.runCmd("settings set auto-confirm true")
        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))

    def buildAndCreateTarget(self):
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

    @skipIf(oslist=["windows"])
    @skipIf(hostoslist=["windows"])
    def test_file_line_breakpoint_realpath_and_source_map(self):
        """Test file/line breakpoint with realpathing and source-mapping."""
        self.buildAndCreateTarget()
        cwd = os.getcwd()

        ######################################################################
        # Baseline
        # --------------------------------------------------------------------
        # Breakpoints should be resolved with paths which are in the line-table.
        lldbutil.run_break_set_by_file_and_line(
            self, "main.c", self.line_in_main, num_expected_locations=1, loc_exact=True
        )
        lldbutil.run_break_set_by_file_and_line(
            self,
            "symlink1/foo.h",
            self.line_in_foo,
            num_expected_locations=1,
            loc_exact=True,
        )
        lldbutil.run_break_set_by_file_and_line(
            self,
            "symlink2/bar.h",
            self.line_in_bar,
            num_expected_locations=1,
            loc_exact=True,
        )
        lldbutil.run_break_set_by_file_and_line(
            self,
            "symlink2/qux.h",
            self.line_in_qux,
            num_expected_locations=1,
            loc_exact=True,
        )

        ######################################################################
        # Symlinked file
        # --------------------------------------------------------------------
        # - `symlink1/foo.h` is a symlink file, pointing at `real/foo.h`
        # - main.c includes `symlink1/foo.h`.
        # - As a result, the line-table contains a support file `(test_base_dir)/symlink1/foo.h`
        # - Setting a breakpoint for `real/foo.h` won't be resolved, because it doesn't match the above path.
        # - Setting a realpath prefix to the current working directory will cause the above support file to be realpath'ed to `(test_base_dir)/real/foo.h`
        # - Now setting a breakpoint for `real/foo.h` will be resolved.
        lldbutil.run_break_set_by_file_and_line(
            self,
            "real/foo.h",
            self.line_in_foo,
            num_expected_locations=0,
            loc_exact=True,
        )
        self.runCmd(f'settings set target.source-realpath-prefixes "{cwd}"')
        lldbutil.run_break_set_by_file_and_line(
            self,
            "real/foo.h",
            self.line_in_foo,
            num_expected_locations=1,
            loc_exact=True,
        )
        # Clear settings so that the test below won't be affected.
        self.runCmd("settings clear target.source-realpath-prefixes")

        ######################################################################
        # Symlinked directory
        # --------------------------------------------------------------------
        # - `symlink2` is a symlink directory, pointing at `real`.
        # - So, `symlink2/bar.h` will be realpath'ed to `real/bar.h`.
        # - main.c includes `symlink2/bar.h`.
        # - As a result, the line-table contains a support file `(test_base_dir)/symlink2/bar.h`
        # - Setting a breakpoint for `real/bar.h` won't be resolved, because it doesn't match the above path.
        # - Setting a realpath prefix to the current working directory will cause the above support file to be realpath'ed to `(test_base_dir)/real/bar.h`
        # - Now setting a breakpoint for `real/bar.h` will be resolved.
        lldbutil.run_break_set_by_file_and_line(
            self,
            "real/bar.h",
            self.line_in_foo,
            num_expected_locations=0,
            loc_exact=True,
        )
        self.runCmd(f'settings set target.source-realpath-prefixes "{cwd}"')
        lldbutil.run_break_set_by_file_and_line(
            self,
            "real/bar.h",
            self.line_in_foo,
            num_expected_locations=1,
            loc_exact=True,
        )
        # Clear settings so that the test below won't be affected.
        self.runCmd("settings clear target.source-realpath-prefixes")

        ######################################################################
        # Symlink + source-map
        # --------------------------------------------------------------------
        # - `symlink2` is a symlink directory, pointing at `real`.
        # - So, `symlink2/qux.h` will be realpath'ed to `real/qux.h`.
        # - main.c includes `symlink2/qux.h`.
        # - As a result, the line-table contains a support file `(test_base_dir)/symlink2/qux.h`
        # - Setting a realpath prefix to the current working directory will cause the above support file to be realpath'ed to `(test_base_dir)/real/qux.h`
        # - Setting a breakpoint for `to-be-mapped/qux.h` won't be resolved, because it doesn't match the above path.
        # - After setting a source-map, setting the same breakpoint will be resolved, because the input path `to-be-mapped/qux.h` is reverse-mapped to `real/qux.h`, which matches the realpath'ed support file.
        lldbutil.run_break_set_by_file_and_line(
            self,
            "real/qux.h",
            self.line_in_foo,
            num_expected_locations=0,
            loc_exact=True,
        )
        self.runCmd(f'settings set target.source-realpath-prefixes "{cwd}"')
        lldbutil.run_break_set_by_file_and_line(
            self,
            "to-be-mapped/qux.h",
            self.line_in_foo,
            num_expected_locations=0,
            loc_exact=True,
        )
        self.runCmd('settings set target.source-map "real" "to-be-mapped"')
        lldbutil.run_break_set_by_file_and_line(
            self,
            "to-be-mapped/qux.h",
            self.line_in_foo,
            num_expected_locations=1,
            loc_exact=True,
        )
        # Clear settings so that the test below won't be affected.
        self.runCmd("settings clear target.source-realpath-prefixes")