Fix path lookup logic on Windows.

Fixes #370.
This commit is contained in:
Luke Hoban 2016-01-30 13:27:08 -08:00 committed by Derek Parker
parent 3ca1dd35ca
commit cf3a07b584
7 changed files with 68 additions and 16 deletions

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("test")
}

@ -2,7 +2,7 @@ version: '{build}'
os: Windows Server 2012 R2
clone_folder: c:\gopath\src\github.com\derekparker\delve
environment:
GOPATH: c:\gopath
GOPATH: C:\gopath
install:
- ps: |
# Install MinGW.

@ -161,7 +161,7 @@ func (dbp *Process) LoadInformation(path string) error {
}
// FindFileLocation returns the PC for a given file:line.
// Assumes that `file` is normailzed to lower case and '/' on Windows.
// Assumes that `file` is normailzed to lower case and '/' on Windows.
func (dbp *Process) FindFileLocation(fileName string, lineno int) (uint64, error) {
pc, _, err := dbp.goSymTable.LineToPC(fileName, lineno)
if err != nil {

@ -8,7 +8,6 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
@ -65,9 +64,6 @@ func BuildFixture(name string) Fixture {
source, _ := filepath.Abs(path)
source = filepath.ToSlash(source)
if runtime.GOOS == "windows" {
source = strings.ToLower(source)
}
Fixtures[name] = Fixture{Name: name, Path: tmpfile, Source: source}
return Fixtures[name]

@ -5,7 +5,10 @@ import (
"errors"
"fmt"
"log"
"path/filepath"
"regexp"
"runtime"
"strings"
"github.com/derekparker/delve/proc"
"github.com/derekparker/delve/service/api"
@ -149,7 +152,18 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
)
switch {
case len(requestedBp.File) > 0:
addr, err = d.process.FindFileLocation(normalizePath(requestedBp.File), requestedBp.Line)
fileName := requestedBp.File
if runtime.GOOS == "windows" {
// Accept fileName which is case-insensitive and slash-insensitive match
fileNameNormalized := strings.ToLower(filepath.ToSlash(fileName))
for symFile := range d.process.Sources() {
if fileNameNormalized == strings.ToLower(filepath.ToSlash(symFile)) {
fileName = symFile
break
}
}
}
addr, err = d.process.FindFileLocation(fileName, requestedBp.Line)
case len(requestedBp.FunctionName) > 0:
if requestedBp.Line >= 0 {
addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, false, requestedBp.Line)

@ -50,13 +50,6 @@ type FuncLocationSpec struct {
BaseName string
}
func normalizePath(path string) string {
if runtime.GOOS != "windows" {
return path
}
return strings.ToLower(filepath.ToSlash(path))
}
func parseLocationSpec(locStr string) (LocationSpec, error) {
rest := locStr
@ -291,8 +284,11 @@ func (loc *NormalLocationSpec) FileMatch(path string) bool {
}
func partialPathMatch(expr, path string) bool {
expr = normalizePath(expr)
path = normalizePath(path)
if runtime.GOOS == "windows" {
// Accept `expr` which is case-insensitive and slash-insensitive match to `path`
expr = strings.ToLower(filepath.ToSlash(expr))
path = strings.ToLower(filepath.ToSlash(path))
}
if len(expr) < len(path)-1 {
return strings.HasSuffix(path, expr) && (path[len(path)-len(expr)-1] == '/')
} else {

@ -7,6 +7,7 @@ import (
"path/filepath"
"runtime"
"strconv"
"strings"
"testing"
protest "github.com/derekparker/delve/proc/test"
@ -616,6 +617,44 @@ func TestClientServer_FindLocations(t *testing.T) {
stacktracemeAddr := findLocationHelper(t, c, "stacktraceprog.go:4", false, 1, 0)[0]
findLocationHelper(t, c, "main.stacktraceme", false, 1, stacktracemeAddr)
})
withTestClient("locationsUpperCase", t, func(c service.Client) {
// Upper case
findLocationHelper(t, c, "locationsUpperCase.go:6", false, 1, 0)
// Fully qualified path
path := protest.Fixtures["locationsUpperCase"].Source
findLocationHelper(t, c, path+":6", false, 1, 0)
bp, err := c.CreateBreakpoint(&api.Breakpoint{File: path, Line: 6})
if err != nil {
t.Fatalf("Could not set breakpoint in %s: %v\n", path, err)
}
c.ClearBreakpoint(bp.ID)
// Allow `/` or `\` on Windows
if runtime.GOOS == "windows" {
findLocationHelper(t, c, filepath.FromSlash(path)+":6", false, 1, 0)
bp, err = c.CreateBreakpoint(&api.Breakpoint{File: filepath.FromSlash(path), Line: 6})
if err != nil {
t.Fatalf("Could not set breakpoint in %s: %v\n", filepath.FromSlash(path), err)
}
c.ClearBreakpoint(bp.ID)
}
// Case-insensitive on Windows, case-sensitive otherwise
shouldWrongCaseBeError := true
numExpectedMatches := 0
if runtime.GOOS == "windows" {
shouldWrongCaseBeError = false
numExpectedMatches = 1
}
findLocationHelper(t, c, strings.ToLower(path)+":6", shouldWrongCaseBeError, numExpectedMatches, 0)
bp, err = c.CreateBreakpoint(&api.Breakpoint{File: strings.ToLower(path), Line: 6})
if (err == nil) == shouldWrongCaseBeError {
t.Fatalf("Could not set breakpoint in %s: %v\n", strings.ToLower(path), err)
}
c.ClearBreakpoint(bp.ID)
})
}
func TestClientServer_FindLocationsAddr(t *testing.T) {