199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest lldb core component: SourceManager. 399451b44SJordan Rupprecht 499451b44SJordan RupprechtTest cases: 599451b44SJordan Rupprecht 699451b44SJordan Rupprechto test_display_source_python: 799451b44SJordan Rupprecht Test display of source using the SBSourceManager API. 899451b44SJordan Rupprechto test_modify_source_file_while_debugging: 999451b44SJordan Rupprecht Test the caching mechanism of the source manager. 1099451b44SJordan Rupprecht""" 1199451b44SJordan Rupprecht 1271b2ff79SJordan Rupprechtimport os 1351944e78SJonas Devlieghereimport io 1471b2ff79SJordan Rupprechtimport stat 1571b2ff79SJordan Rupprecht 1699451b44SJordan Rupprechtimport lldb 1799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1999451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 2099451b44SJordan Rupprecht 2199451b44SJordan Rupprecht 2299451b44SJordan Rupprechtdef ansi_underline_surround_regex(inner_regex_text): 2399451b44SJordan Rupprecht # return re.compile(r"\[4m%s\[0m" % inner_regex_text) 2499451b44SJordan Rupprecht return "4.+\033\\[4m%s\033\\[0m" % inner_regex_text 2599451b44SJordan Rupprecht 262238dcc3SJonas Devlieghere 2799451b44SJordan Rupprechtdef ansi_color_surround_regex(inner_regex_text): 2899451b44SJordan Rupprecht return "\033\\[3[0-7]m%s\033\\[0m" % inner_regex_text 2999451b44SJordan Rupprecht 3099451b44SJordan Rupprecht 312238dcc3SJonas Devlieghereclass SourceManagerTestCase(TestBase): 3299451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 3399451b44SJordan Rupprecht 3499451b44SJordan Rupprecht def setUp(self): 3599451b44SJordan Rupprecht # Call super's setUp(). 3699451b44SJordan Rupprecht TestBase.setUp(self) 3799451b44SJordan Rupprecht # Find the line number to break inside main(). 3899451b44SJordan Rupprecht self.file = self.getBuildArtifact("main-copy.c") 392238dcc3SJonas Devlieghere self.line = line_number("main.c", "// Set break point at this line.") 4099451b44SJordan Rupprecht 4151944e78SJonas Devlieghere def modify_content(self): 4251944e78SJonas Devlieghere # Read the main.c file content. 4351944e78SJonas Devlieghere with io.open(self.file, "r", newline="\n") as f: 4451944e78SJonas Devlieghere original_content = f.read() 4551944e78SJonas Devlieghere if self.TraceOn(): 4651944e78SJonas Devlieghere print("original content:", original_content) 4751944e78SJonas Devlieghere 4851944e78SJonas Devlieghere # Modify the in-memory copy of the original source code. 4951944e78SJonas Devlieghere new_content = original_content.replace("Hello world", "Hello lldb", 1) 5051944e78SJonas Devlieghere 5151944e78SJonas Devlieghere # Modify the source code file. 5251944e78SJonas Devlieghere # If the source was read only, the copy will also be read only. 5351944e78SJonas Devlieghere # Run "chmod u+w" on it first so we can modify it. 5451944e78SJonas Devlieghere statinfo = os.stat(self.file) 5551944e78SJonas Devlieghere os.chmod(self.file, statinfo.st_mode | stat.S_IWUSR) 5651944e78SJonas Devlieghere 5751944e78SJonas Devlieghere with io.open(self.file, "w", newline="\n") as f: 5851944e78SJonas Devlieghere time.sleep(1) 5951944e78SJonas Devlieghere f.write(new_content) 6051944e78SJonas Devlieghere if self.TraceOn(): 6151944e78SJonas Devlieghere print("new content:", new_content) 6251944e78SJonas Devlieghere print( 6351944e78SJonas Devlieghere "os.path.getmtime() after writing new content:", 6451944e78SJonas Devlieghere os.path.getmtime(self.file), 6551944e78SJonas Devlieghere ) 6651944e78SJonas Devlieghere 6799451b44SJordan Rupprecht def get_expected_stop_column_number(self): 6899451b44SJordan Rupprecht """Return the 1-based column number of the first non-whitespace 6999451b44SJordan Rupprecht character in the breakpoint source line.""" 7099451b44SJordan Rupprecht stop_line = get_line(self.file, self.line) 7199451b44SJordan Rupprecht # The number of spaces that must be skipped to get to the first non- 7299451b44SJordan Rupprecht # whitespace character --- where we expect the debugger breakpoint 7399451b44SJordan Rupprecht # column to be --- is equal to the number of characters that get 7499451b44SJordan Rupprecht # stripped off the front when we lstrip it, plus one to specify 7599451b44SJordan Rupprecht # the character column after the initial whitespace. 7699451b44SJordan Rupprecht return len(stop_line) - len(stop_line.lstrip()) + 1 7799451b44SJordan Rupprecht 782238dcc3SJonas Devlieghere def do_display_source_python_api( 792238dcc3SJonas Devlieghere self, use_color, needle_regex, highlight_source=False 802238dcc3SJonas Devlieghere ): 8199451b44SJordan Rupprecht self.build() 8299451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 8399451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 8499451b44SJordan Rupprecht 8599451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 8699451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 8799451b44SJordan Rupprecht 8899451b44SJordan Rupprecht # Launch the process, and do not stop at the entry point. 8999451b44SJordan Rupprecht args = None 9099451b44SJordan Rupprecht envp = None 912238dcc3SJonas Devlieghere process = target.LaunchSimple(args, envp, self.get_process_working_directory()) 9299451b44SJordan Rupprecht self.assertIsNotNone(process) 9399451b44SJordan Rupprecht 9499451b44SJordan Rupprecht # 9599451b44SJordan Rupprecht # Exercise Python APIs to display source lines. 9699451b44SJordan Rupprecht # 9799451b44SJordan Rupprecht 9899451b44SJordan Rupprecht # Setup whether we should use ansi escape sequences, including color 9999451b44SJordan Rupprecht # and styles such as underline. 10099451b44SJordan Rupprecht self.dbg.SetUseColor(use_color) 10199451b44SJordan Rupprecht # Disable syntax highlighting if needed. 10299451b44SJordan Rupprecht 10399451b44SJordan Rupprecht self.runCmd("settings set highlight-source " + str(highlight_source).lower()) 10499451b44SJordan Rupprecht 10599451b44SJordan Rupprecht filespec = lldb.SBFileSpec(self.file, False) 10699451b44SJordan Rupprecht source_mgr = self.dbg.GetSourceManager() 10799451b44SJordan Rupprecht # Use a string stream as the destination. 10899451b44SJordan Rupprecht stream = lldb.SBStream() 10999451b44SJordan Rupprecht column = self.get_expected_stop_column_number() 11099451b44SJordan Rupprecht context_before = 2 11199451b44SJordan Rupprecht context_after = 2 11299451b44SJordan Rupprecht current_line_prefix = "=>" 11399451b44SJordan Rupprecht source_mgr.DisplaySourceLinesWithLineNumbersAndColumn( 1142238dcc3SJonas Devlieghere filespec, 1152238dcc3SJonas Devlieghere self.line, 1162238dcc3SJonas Devlieghere column, 1172238dcc3SJonas Devlieghere context_before, 1182238dcc3SJonas Devlieghere context_after, 1192238dcc3SJonas Devlieghere current_line_prefix, 1202238dcc3SJonas Devlieghere stream, 1212238dcc3SJonas Devlieghere ) 12299451b44SJordan Rupprecht 12399451b44SJordan Rupprecht # 2 12499451b44SJordan Rupprecht # 3 int main(int argc, char const *argv[]) { 12599451b44SJordan Rupprecht # => 4 printf("Hello world.\n"); // Set break point at this line. 12699451b44SJordan Rupprecht # 5 return 0; 12799451b44SJordan Rupprecht # 6 } 1282238dcc3SJonas Devlieghere self.expect( 1292238dcc3SJonas Devlieghere stream.GetData(), 1302238dcc3SJonas Devlieghere "Source code displayed correctly:\n" + stream.GetData(), 13199451b44SJordan Rupprecht exe=False, 1322238dcc3SJonas Devlieghere patterns=["=>", "%d.*Hello world" % self.line, needle_regex], 1332238dcc3SJonas Devlieghere ) 13499451b44SJordan Rupprecht 13599451b44SJordan Rupprecht # Boundary condition testings for SBStream(). LLDB should not crash! 13699451b44SJordan Rupprecht stream.Print(None) 13799451b44SJordan Rupprecht stream.RedirectToFile(None, True) 13899451b44SJordan Rupprecht 1392238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 14099451b44SJordan Rupprecht def test_display_source_python_dumb_terminal(self): 14199451b44SJordan Rupprecht """Test display of source using the SBSourceManager API, using a 14299451b44SJordan Rupprecht dumb terminal and thus no color support (the default).""" 14399451b44SJordan Rupprecht use_color = False 14499451b44SJordan Rupprecht self.do_display_source_python_api(use_color, r"\s+\^") 14599451b44SJordan Rupprecht 1462238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 14799451b44SJordan Rupprecht def test_display_source_python_ansi_terminal(self): 14899451b44SJordan Rupprecht """Test display of source using the SBSourceManager API, using a 14999451b44SJordan Rupprecht dumb terminal and thus no color support (the default).""" 15099451b44SJordan Rupprecht use_color = True 15199451b44SJordan Rupprecht underline_regex = ansi_underline_surround_regex(r"printf") 15299451b44SJordan Rupprecht self.do_display_source_python_api(use_color, underline_regex) 15399451b44SJordan Rupprecht 1542238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 15599451b44SJordan Rupprecht def test_display_source_python_ansi_terminal_syntax_highlighting(self): 15699451b44SJordan Rupprecht """Test display of source using the SBSourceManager API and check for 15799451b44SJordan Rupprecht the syntax highlighted output""" 15899451b44SJordan Rupprecht use_color = True 1592238dcc3SJonas Devlieghere syntax_highlighting = True 16099451b44SJordan Rupprecht 16199451b44SJordan Rupprecht # Just pick 'int' as something that should be colored. 16299451b44SJordan Rupprecht color_regex = ansi_color_surround_regex("int") 16399451b44SJordan Rupprecht self.do_display_source_python_api(use_color, color_regex, syntax_highlighting) 16499451b44SJordan Rupprecht 16599451b44SJordan Rupprecht # Same for 'char'. 16699451b44SJordan Rupprecht color_regex = ansi_color_surround_regex("char") 16799451b44SJordan Rupprecht self.do_display_source_python_api(use_color, color_regex, syntax_highlighting) 16899451b44SJordan Rupprecht 16999451b44SJordan Rupprecht # Test that we didn't color unrelated identifiers. 17099451b44SJordan Rupprecht self.do_display_source_python_api(use_color, r" main\(", syntax_highlighting) 17199451b44SJordan Rupprecht self.do_display_source_python_api(use_color, r"\);", syntax_highlighting) 17299451b44SJordan Rupprecht 17399451b44SJordan Rupprecht def test_move_and_then_display_source(self): 17499451b44SJordan Rupprecht """Test that target.source-map settings work by moving main.c to hidden/main.c.""" 17599451b44SJordan Rupprecht self.build() 17699451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 17799451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 17899451b44SJordan Rupprecht 17999451b44SJordan Rupprecht # Move main.c to hidden/main.c. 18099451b44SJordan Rupprecht hidden = self.getBuildArtifact("hidden") 18199451b44SJordan Rupprecht lldbutil.mkdir_p(hidden) 18299451b44SJordan Rupprecht main_c_hidden = os.path.join(hidden, "main-copy.c") 18399451b44SJordan Rupprecht os.rename(self.file, main_c_hidden) 18499451b44SJordan Rupprecht 18599451b44SJordan Rupprecht # Set source remapping with invalid replace path and verify we get an 18699451b44SJordan Rupprecht # error 18799451b44SJordan Rupprecht self.expect( 18899451b44SJordan Rupprecht "settings set target.source-map /a/b/c/d/e /q/r/s/t/u", 18999451b44SJordan Rupprecht error=True, 1902238dcc3SJonas Devlieghere substrs=['''error: the replacement path doesn't exist: "/q/r/s/t/u"'''], 1912238dcc3SJonas Devlieghere ) 19299451b44SJordan Rupprecht 19399451b44SJordan Rupprecht # 'make -C' has resolved current directory to its realpath form. 19499451b44SJordan Rupprecht builddir_real = os.path.realpath(self.getBuildDir()) 19599451b44SJordan Rupprecht hidden_real = os.path.realpath(hidden) 19699451b44SJordan Rupprecht # Set target.source-map settings. 1972238dcc3SJonas Devlieghere self.runCmd( 1982238dcc3SJonas Devlieghere "settings set target.source-map %s %s" % (builddir_real, hidden_real) 1992238dcc3SJonas Devlieghere ) 20099451b44SJordan Rupprecht # And verify that the settings work. 2012238dcc3SJonas Devlieghere self.expect( 2022238dcc3SJonas Devlieghere "settings show target.source-map", substrs=[builddir_real, hidden_real] 2032238dcc3SJonas Devlieghere ) 20499451b44SJordan Rupprecht 20599451b44SJordan Rupprecht # Display main() and verify that the source mapping has been kicked in. 2062238dcc3SJonas Devlieghere self.expect( 2072238dcc3SJonas Devlieghere "source list -n main", SOURCE_DISPLAYED_CORRECTLY, substrs=["Hello world"] 2082238dcc3SJonas Devlieghere ) 20999451b44SJordan Rupprecht 21099451b44SJordan Rupprecht @skipIf(oslist=["windows"], bugnumber="llvm.org/pr44431") 21199451b44SJordan Rupprecht def test_modify_source_file_while_debugging(self): 21299451b44SJordan Rupprecht """Modify a source file while debugging the executable.""" 21399451b44SJordan Rupprecht self.build() 21499451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 21599451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 21699451b44SJordan Rupprecht 21799451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2182238dcc3SJonas Devlieghere self, "main-copy.c", self.line, num_expected_locations=1, loc_exact=True 2192238dcc3SJonas Devlieghere ) 22099451b44SJordan Rupprecht 22199451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 22299451b44SJordan Rupprecht 22399451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 2242238dcc3SJonas Devlieghere self.expect( 2252238dcc3SJonas Devlieghere "thread list", 2262238dcc3SJonas Devlieghere STOPPED_DUE_TO_BREAKPOINT, 2272238dcc3SJonas Devlieghere substrs=[ 2282238dcc3SJonas Devlieghere "stopped", 2292238dcc3SJonas Devlieghere "main-copy.c:%d" % self.line, 2302238dcc3SJonas Devlieghere "stop reason = breakpoint", 2312238dcc3SJonas Devlieghere ], 2322238dcc3SJonas Devlieghere ) 23399451b44SJordan Rupprecht 23499451b44SJordan Rupprecht # Display some source code. 23599451b44SJordan Rupprecht self.expect( 2362238dcc3SJonas Devlieghere "source list -f main-copy.c -l %d" % self.line, 23799451b44SJordan Rupprecht SOURCE_DISPLAYED_CORRECTLY, 2382238dcc3SJonas Devlieghere substrs=["Hello world"], 2392238dcc3SJonas Devlieghere ) 24099451b44SJordan Rupprecht 241bc0a9a17SJim Ingham # Do the same thing with a file & line spec: 242bc0a9a17SJim Ingham self.expect( 2432238dcc3SJonas Devlieghere "source list -y main-copy.c:%d" % self.line, 244bc0a9a17SJim Ingham SOURCE_DISPLAYED_CORRECTLY, 2452238dcc3SJonas Devlieghere substrs=["Hello world"], 2462238dcc3SJonas Devlieghere ) 247bc0a9a17SJim Ingham 24899451b44SJordan Rupprecht # The '-b' option shows the line table locations from the debug information 24999451b44SJordan Rupprecht # that indicates valid places to set source level breakpoints. 25099451b44SJordan Rupprecht 25199451b44SJordan Rupprecht # The file to display is implicit in this case. 25299451b44SJordan Rupprecht self.runCmd("source list -l %d -c 3 -b" % self.line) 25399451b44SJordan Rupprecht output = self.res.GetOutput().splitlines()[0] 25499451b44SJordan Rupprecht 25599451b44SJordan Rupprecht # If the breakpoint set command succeeded, we should expect a positive number 25699451b44SJordan Rupprecht # of breakpoints for the current line, i.e., self.line. 25799451b44SJordan Rupprecht import re 2582238dcc3SJonas Devlieghere 2592238dcc3SJonas Devlieghere m = re.search("^\[(\d+)\].*// Set break point at this line.", output) 26099451b44SJordan Rupprecht if not m: 26199451b44SJordan Rupprecht self.fail("Fail to display source level breakpoints") 2629c246882SJordan Rupprecht self.assertGreater(int(m.group(1)), 0) 26399451b44SJordan Rupprecht 26451944e78SJonas Devlieghere # Modify content 26551944e78SJonas Devlieghere self.modify_content() 26699451b44SJordan Rupprecht 26751944e78SJonas Devlieghere # Display the source code again. We should not see the updated line. 26851944e78SJonas Devlieghere self.expect( 26951944e78SJonas Devlieghere "source list -f main-copy.c -l %d" % self.line, 27051944e78SJonas Devlieghere SOURCE_DISPLAYED_CORRECTLY, 27151944e78SJonas Devlieghere substrs=["Hello world"], 2722238dcc3SJonas Devlieghere ) 27399451b44SJordan Rupprecht 27451944e78SJonas Devlieghere # clear the source cache. 27551944e78SJonas Devlieghere self.runCmd("source cache clear") 27651944e78SJonas Devlieghere 27751944e78SJonas Devlieghere # Display the source code again. Now we should see the updated line. 27899451b44SJordan Rupprecht self.expect( 2792238dcc3SJonas Devlieghere "source list -f main-copy.c -l %d" % self.line, 28099451b44SJordan Rupprecht SOURCE_DISPLAYED_CORRECTLY, 2812238dcc3SJonas Devlieghere substrs=["Hello lldb"], 2822238dcc3SJonas Devlieghere ) 28399451b44SJordan Rupprecht 28499451b44SJordan Rupprecht def test_set_breakpoint_with_absolute_path(self): 28599451b44SJordan Rupprecht self.build() 28699451b44SJordan Rupprecht hidden = self.getBuildArtifact("hidden") 28799451b44SJordan Rupprecht lldbutil.mkdir_p(hidden) 28899451b44SJordan Rupprecht # 'make -C' has resolved current directory to its realpath form. 28999451b44SJordan Rupprecht builddir_real = os.path.realpath(self.getBuildDir()) 29099451b44SJordan Rupprecht hidden_real = os.path.realpath(hidden) 2912238dcc3SJonas Devlieghere self.runCmd( 2922238dcc3SJonas Devlieghere "settings set target.source-map %s %s" % (builddir_real, hidden_real) 2932238dcc3SJonas Devlieghere ) 29499451b44SJordan Rupprecht 29599451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 29699451b44SJordan Rupprecht main = os.path.join(builddir_real, "hidden", "main-copy.c") 29799451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 29899451b44SJordan Rupprecht 29999451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 3002238dcc3SJonas Devlieghere self, main, self.line, num_expected_locations=1, loc_exact=False 3012238dcc3SJonas Devlieghere ) 30299451b44SJordan Rupprecht 30399451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 30499451b44SJordan Rupprecht 30599451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 3062238dcc3SJonas Devlieghere self.expect( 3072238dcc3SJonas Devlieghere "thread list", 3082238dcc3SJonas Devlieghere STOPPED_DUE_TO_BREAKPOINT, 3092238dcc3SJonas Devlieghere substrs=[ 3102238dcc3SJonas Devlieghere "stopped", 3112238dcc3SJonas Devlieghere "main-copy.c:%d" % self.line, 3122238dcc3SJonas Devlieghere "stop reason = breakpoint", 3132238dcc3SJonas Devlieghere ], 3142238dcc3SJonas Devlieghere ) 315edf410e4SMed Ismail Bennani 316edf410e4SMed Ismail Bennani def test_artificial_source_location(self): 31739b2979aSPavel Labath src_file = "artificial_location.cpp" 31839b2979aSPavel Labath d = {"C_SOURCES": "", "CXX_SOURCES": src_file} 319edf410e4SMed Ismail Bennani self.build(dictionary=d) 320edf410e4SMed Ismail Bennani 32139b2979aSPavel Labath target = lldbutil.run_to_breakpoint_make_target(self) 32239b2979aSPavel Labath 32339b2979aSPavel Labath # Find the instruction with line=0 and put a breakpoint there. 32439b2979aSPavel Labath sc_list = target.FindFunctions("A::foo") 32539b2979aSPavel Labath self.assertEqual(len(sc_list), 1) 32639b2979aSPavel Labath insns = sc_list[0].function.GetInstructions(target) 32739b2979aSPavel Labath insn0 = next(filter(lambda insn: insn.addr.line_entry.line == 0, insns)) 32839b2979aSPavel Labath bkpt = target.BreakpointCreateBySBAddress(insn0.addr) 32939b2979aSPavel Labath self.assertGreater(bkpt.GetNumLocations(), 0) 33039b2979aSPavel Labath 33139b2979aSPavel Labath lldbutil.run_to_breakpoint_do_run(self, target, bkpt) 332edf410e4SMed Ismail Bennani 3332238dcc3SJonas Devlieghere self.expect( 33466a2ed50SAlex Langford "process status", 3352238dcc3SJonas Devlieghere substrs=[ 3362238dcc3SJonas Devlieghere "stop reason = breakpoint", 33766a2ed50SAlex Langford f"{src_file}:0", 33839b2979aSPavel Labath "static int foo();", 339*0394e08bSPavel Labath "note: This address is not associated with a specific line " 340*0394e08bSPavel Labath "of code. This may be due to compiler optimizations.", 3412238dcc3SJonas Devlieghere ], 3422238dcc3SJonas Devlieghere ) 343d49caf4aSJonas Devlieghere 344d49caf4aSJonas Devlieghere def test_source_cache_dump_and_clear(self): 345d49caf4aSJonas Devlieghere self.build() 346d49caf4aSJonas Devlieghere exe = self.getBuildArtifact("a.out") 347d49caf4aSJonas Devlieghere self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 348d49caf4aSJonas Devlieghere lldbutil.run_break_set_by_file_and_line( 349d49caf4aSJonas Devlieghere self, self.file, self.line, num_expected_locations=1, loc_exact=True 350d49caf4aSJonas Devlieghere ) 351d49caf4aSJonas Devlieghere self.runCmd("run", RUN_SUCCEEDED) 352d49caf4aSJonas Devlieghere 353d49caf4aSJonas Devlieghere # Make sure the main source file is in the source cache. 354d49caf4aSJonas Devlieghere self.expect( 355d49caf4aSJonas Devlieghere "source cache dump", 356d49caf4aSJonas Devlieghere substrs=["Modification time", "Lines", "Path", " 7", self.file], 357d49caf4aSJonas Devlieghere ) 358d49caf4aSJonas Devlieghere 359d49caf4aSJonas Devlieghere # Clear the cache. 360d49caf4aSJonas Devlieghere self.expect("source cache clear") 361d49caf4aSJonas Devlieghere 362d49caf4aSJonas Devlieghere # Make sure the main source file is no longer in the source cache. 363d49caf4aSJonas Devlieghere self.expect("source cache dump", matching=False, substrs=[self.file]) 36451944e78SJonas Devlieghere 36551944e78SJonas Devlieghere def test_source_cache_interactions(self): 36651944e78SJonas Devlieghere self.build() 36751944e78SJonas Devlieghere exe = self.getBuildArtifact("a.out") 36851944e78SJonas Devlieghere 36951944e78SJonas Devlieghere # Create a first target. 37051944e78SJonas Devlieghere self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 371ecbe78c1SJonas Devlieghere lldbutil.run_break_set_by_symbol(self, "main", num_expected_locations=1) 37251944e78SJonas Devlieghere self.expect("run", RUN_SUCCEEDED, substrs=["Hello world"]) 37351944e78SJonas Devlieghere 37451944e78SJonas Devlieghere # Create a second target. 37551944e78SJonas Devlieghere self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 376ecbe78c1SJonas Devlieghere lldbutil.run_break_set_by_symbol(self, "main", num_expected_locations=1) 37751944e78SJonas Devlieghere self.expect("run", RUN_SUCCEEDED, substrs=["Hello world"]) 37851944e78SJonas Devlieghere 37951944e78SJonas Devlieghere # Modify the source file content. 38051944e78SJonas Devlieghere self.modify_content() 38151944e78SJonas Devlieghere 38251944e78SJonas Devlieghere # Clear the source cache. This will wipe the debugger and the process 38351944e78SJonas Devlieghere # cache for the second process. 38451944e78SJonas Devlieghere self.runCmd("source cache clear") 38551944e78SJonas Devlieghere 38651944e78SJonas Devlieghere # Make sure we're seeing the new content from the clean process cache. 387ecbe78c1SJonas Devlieghere self.expect( 388ecbe78c1SJonas Devlieghere "next", 38951944e78SJonas Devlieghere SOURCE_DISPLAYED_CORRECTLY, 39051944e78SJonas Devlieghere substrs=["Hello lldb"], 39151944e78SJonas Devlieghere ) 39251944e78SJonas Devlieghere 39351944e78SJonas Devlieghere # Switch back to the first target. 39451944e78SJonas Devlieghere self.runCmd("target select 0") 39551944e78SJonas Devlieghere 39651944e78SJonas Devlieghere # Make sure we're seeing the old content from the first target's 39751944e78SJonas Devlieghere # process cache. 398ecbe78c1SJonas Devlieghere self.expect( 399ecbe78c1SJonas Devlieghere "next", 40051944e78SJonas Devlieghere SOURCE_DISPLAYED_CORRECTLY, 40151944e78SJonas Devlieghere substrs=["Hello world"], 40251944e78SJonas Devlieghere ) 403