From 6e882c50fa85aba34e4204e1016bc36ab09a617f Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Sat, 22 Oct 2016 07:04:03 +0200 Subject: [PATCH] debugger/locations: prioritize exact matches of function names (#651) If the location specification matches the name of a function exactly return that function as a match event if the expression matches other functions as well. Without this some functions, like math/rand.Intn are unmatchable. --- _fixtures/locationsprog3.go | 12 ++++++++++++ service/debugger/locations.go | 8 ++++++-- service/test/integration2_test.go | 12 ++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 _fixtures/locationsprog3.go diff --git a/_fixtures/locationsprog3.go b/_fixtures/locationsprog3.go new file mode 100644 index 00000000..430c9fde --- /dev/null +++ b/_fixtures/locationsprog3.go @@ -0,0 +1,12 @@ +package main + +import ( + "fmt" + "math/rand" + "runtime" +) + +func main() { + runtime.Breakpoint() + fmt.Println(rand.Intn(10)) +} diff --git a/service/debugger/locations.go b/service/debugger/locations.go index c6eba685..0c85ae51 100644 --- a/service/debugger/locations.go +++ b/service/debugger/locations.go @@ -346,10 +346,14 @@ func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s continue } if loc.FuncBase.Match(f.Sym) { - candidates = append(candidates, f.Name) - if len(candidates) >= maxFindLocationCandidates { + if loc.Base == f.Name { + // if an exact match for the function name is found use it + candidates = []string{f.Name} break } + if len(candidates) < maxFindLocationCandidates { + candidates = append(candidates, f.Name) + } } } } diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 52dd0f0f..2f2c68c6 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -666,6 +666,18 @@ func TestClientServer_FindLocationsAddr(t *testing.T) { }) } +func TestClientServer_FindLocationsExactMatch(t *testing.T) { + // if an expression matches multiple functions but one of them is an exact + // match it should be used anyway. + // In this example "math/rand.Intn" would normally match "math/rand.Intn" + // and "math/rand.(*Rand).Intn" but since the first match is exact it + // should be prioritized. + withTestClient2("locationsprog3", t, func(c service.Client) { + <-c.Continue() + findLocationHelper(t, c, "math/rand.Intn", false, 1, 0) + }) +} + func TestClientServer_EvalVariable(t *testing.T) { withTestClient2("testvariables", t, func(c service.Client) { state := <-c.Continue()