Author: abidh Date: Sun Feb 8 14:21:08 2015 New Revision: 228538 URL: http://llvm.org/viewvc/llvm-project?rev=228538&view=rev Log: Fix a handling of full path in break-insert. For some time, eclipse (CDT) uses full path of the file in break-insert command when putting breakpoint on a source line. On windows, a typical command looks like the following. 56-break-insert -f F:\\work\\ws\\test\\main.c:49
Current implementation in lldb-mi have problem in 2 ways. 1. It was assuming that there will be only one : in the path which is wrong if full path is supplied. 2. CDT sends out path with double backslashes in windows which gives error on resolution. Fixed the : issue in lldb-mi. Changed FileSpec::Normalize to make sure that it handles the path with \\ correctly. Added test cases to check for full path in both lldb-mi and lldb. Also added a test case to check SBFileSpec with double slashes. Modified: lldb/trunk/source/Host/common/FileSpec.cpp lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py lldb/trunk/test/functionalities/paths/TestPaths.py lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py lldb/trunk/test/tools/lldb-mi/main.c lldb/trunk/tools/lldb-mi/MICmdCmdBreak.cpp Modified: lldb/trunk/source/Host/common/FileSpec.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=228538&r1=228537&r2=228538&view=diff ============================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp (original) +++ lldb/trunk/source/Host/common/FileSpec.cpp Sun Feb 8 14:21:08 2015 @@ -240,6 +240,12 @@ void FileSpec::Normalize(llvm::SmallVect return; std::replace(path.begin(), path.end(), '\\', '/'); + // Windows path can have \\ slashes which can be changed by replace + // call above to //. Here we remove the duplicate. + auto iter = std::unique ( path.begin(), path.end(), + []( char &c1, char &c2 ){ + return (c1 == '/' && c2 == '/');}); + path.erase(iter, path.end()); } void FileSpec::DeNormalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax) Modified: lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py?rev=228538&r1=228537&r2=228538&view=diff ============================================================================== --- lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py (original) +++ lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py Sun Feb 8 14:21:08 2015 @@ -43,6 +43,11 @@ class RegexpBreakCommandTestCase(TestBas break_results = lldbutil.run_break_set_command (self, "b %s:%d" % (self.source, self.line)) lldbutil.check_breakpoint_result (self, break_results, file_name='main.c', line_number=self.line, num_locations=1) + # Check breakpoint with full file path. + full_path = os.path.join(os.getcwd(), self.source) + break_results = lldbutil.run_break_set_command (self, "b %s:%d" % (full_path, self.line)) + lldbutil.check_breakpoint_result (self, break_results, file_name='main.c', line_number=self.line, num_locations=1) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. Modified: lldb/trunk/test/functionalities/paths/TestPaths.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/paths/TestPaths.py?rev=228538&r1=228537&r2=228538&view=diff ============================================================================== --- lldb/trunk/test/functionalities/paths/TestPaths.py (original) +++ lldb/trunk/test/functionalities/paths/TestPaths.py Sun Feb 8 14:21:08 2015 @@ -27,7 +27,14 @@ class TestPaths(TestBase): f = lldb.SBHostOS.GetLLDBPath(path_type); # No directory path types should have the filename set self.assertTrue (f.GetFilename() == None); - + + @unittest2.skipUnless(sys.platform.startswith("win32"), "Test for windows only") + def test_windows_double_slash (self): + '''Test to check the path with double slash is handled correctly ''' + # Create a path and see if lldb gets the directory and file right + fspec = lldb.SBFileSpec("C:\\dummy1\\dummy2//unknown_file", True); + self.assertTrue (fspec.GetDirectory() == "C:/dummy1/dummy2"); + self.assertTrue (fspec.GetFilename() == "unknown_file"); if __name__ == '__main__': import atexit Modified: lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py?rev=228538&r1=228537&r2=228538&view=diff ============================================================================== --- lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py (original) +++ lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py Sun Feb 8 14:21:08 2015 @@ -83,6 +83,17 @@ class MiBreakpointTestCase(lldbmi_testca self.runCmd("-break-insert main.c:%d" % line) self.expect("\^done,bkpt={number=\"3\"") + # Check with full path. TODO, figure out why this commands fails + # if -f is not given + line = line_number('main.c', '// BP_doloop') + full_path = os.path.join(os.getcwd(), "main.c") + self.runCmd("-break-insert -f %s:%d" % (full_path, line)) + self.expect("\^done,bkpt={number=\"4\"") + + self.runCmd("-exec-continue") + self.expect("\^running") + self.expect("\*stopped,reason=\"breakpoint-hit\"") + self.runCmd("-exec-continue") self.expect("\^running") self.expect("\*stopped,reason=\"breakpoint-hit\"") Modified: lldb/trunk/test/tools/lldb-mi/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/main.c?rev=228538&r1=228537&r2=228538&view=diff ============================================================================== --- lldb/trunk/test/tools/lldb-mi/main.c (original) +++ lldb/trunk/test/tools/lldb-mi/main.c Sun Feb 8 14:21:08 2015 @@ -22,7 +22,7 @@ int main (int argc, char const *argv[]) a = a_MyFunction(); //BP_a_MyFunction_call b = b_MyFunction(); //BP_b_MyFunction_call //BP_localstest -- it must be at line #24 (or fix it in main*.micmds) - if (doloop) + if (doloop) // BP_doloop infloop(); if (argc > 1 && *argv[1] == 'l') { a++; Modified: lldb/trunk/tools/lldb-mi/MICmdCmdBreak.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdCmdBreak.cpp?rev=228538&r1=228537&r2=228538&view=diff ============================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdBreak.cpp (original) +++ lldb/trunk/tools/lldb-mi/MICmdCmdBreak.cpp Sun Feb 8 14:21:08 2015 @@ -180,19 +180,16 @@ CMICmdCmdBreakInsert::Execute(void) CMIUtilString fileName; MIuint nFileLine = 0; CMIUtilString strFileFn; - const MIint nPosColon = m_brkName.find(cColon); - if (nPosColon != (MIint)std::string::npos) + CMIUtilString rStrLineOrFn; + // Full path in windows can have : after drive letter. So look for the + // last colon + const size_t nPosColon = m_brkName.find_last_of(cColon); + if (nPosColon != std::string::npos) { - CMIUtilString::VecString_t vecFileAndLocation; - const MIuint nSplits = m_brkName.Split(cColon, vecFileAndLocation); - MIunused(nSplits); - if (vecFileAndLocation.size() != 2) - { - SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_FORMAT), m_cmdData.strMiCmd.c_str(), m_brkName.c_str())); - return MIstatus::failure; - } - fileName = vecFileAndLocation.at(0); - const CMIUtilString &rStrLineOrFn(vecFileAndLocation.at(1)); + // extract file name and line number from it + fileName = m_brkName.substr(0, nPosColon); + rStrLineOrFn = m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1); + if (rStrLineOrFn.empty()) eBrkPtType = eBreakPoint_ByName; else _______________________________________________ lldb-commits mailing list lldb-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits