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 os: Windows Server 2012 R2
clone_folder: c:\gopath\src\github.com\derekparker\delve clone_folder: c:\gopath\src\github.com\derekparker\delve
environment: environment:
GOPATH: c:\gopath GOPATH: C:\gopath
install: install:
- ps: | - ps: |
# Install MinGW. # Install MinGW.

@ -161,7 +161,7 @@ func (dbp *Process) LoadInformation(path string) error {
} }
// FindFileLocation returns the PC for a given file:line. // 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) { func (dbp *Process) FindFileLocation(fileName string, lineno int) (uint64, error) {
pc, _, err := dbp.goSymTable.LineToPC(fileName, lineno) pc, _, err := dbp.goSymTable.LineToPC(fileName, lineno)
if err != nil { if err != nil {

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

@ -5,7 +5,10 @@ import (
"errors" "errors"
"fmt" "fmt"
"log" "log"
"path/filepath"
"regexp" "regexp"
"runtime"
"strings"
"github.com/derekparker/delve/proc" "github.com/derekparker/delve/proc"
"github.com/derekparker/delve/service/api" "github.com/derekparker/delve/service/api"
@ -149,7 +152,18 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
) )
switch { switch {
case len(requestedBp.File) > 0: 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: case len(requestedBp.FunctionName) > 0:
if requestedBp.Line >= 0 { if requestedBp.Line >= 0 {
addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, false, requestedBp.Line) addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, false, requestedBp.Line)

@ -50,13 +50,6 @@ type FuncLocationSpec struct {
BaseName string 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) { func parseLocationSpec(locStr string) (LocationSpec, error) {
rest := locStr rest := locStr
@ -291,8 +284,11 @@ func (loc *NormalLocationSpec) FileMatch(path string) bool {
} }
func partialPathMatch(expr, path string) bool { func partialPathMatch(expr, path string) bool {
expr = normalizePath(expr) if runtime.GOOS == "windows" {
path = normalizePath(path) // 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 { if len(expr) < len(path)-1 {
return strings.HasSuffix(path, expr) && (path[len(path)-len(expr)-1] == '/') return strings.HasSuffix(path, expr) && (path[len(path)-len(expr)-1] == '/')
} else { } else {

@ -7,6 +7,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings"
"testing" "testing"
protest "github.com/derekparker/delve/proc/test" 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] stacktracemeAddr := findLocationHelper(t, c, "stacktraceprog.go:4", false, 1, 0)[0]
findLocationHelper(t, c, "main.stacktraceme", false, 1, stacktracemeAddr) 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) { func TestClientServer_FindLocationsAddr(t *testing.T) {