Skip to content

Commit 7a36e78

Browse files
committed
proc: make PushPackageVarOrSelect check local variables first
Fixes #4179
1 parent d5d7576 commit 7a36e78

File tree

5 files changed

+45
-20
lines changed

5 files changed

+45
-20
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package issue4179helper
2+
3+
type Test struct {
4+
Name interface{}
5+
Age int
6+
}

_fixtures/testvariables2.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"runtime"
1010
"time"
1111
"unsafe"
12+
13+
"github.com/go-delve/delve/_fixtures/internal/issue4179helper"
1214
)
1315

1416
type (
@@ -175,6 +177,10 @@ type OnlyUsedInInterface struct {
175177

176178
type Message []byte
177179

180+
type Config struct {
181+
*issue4179helper.Test
182+
}
183+
178184
var _ I = (*W2)(nil)
179185

180186
type pptr *pptr
@@ -433,6 +439,8 @@ func main() {
433439

434440
var iface7 interface{} = OnlyUsedInInterface{"test"}
435441

442+
issue4179helper := &Config{Test: &issue4179helper.Test{}}
443+
436444
var amb1 = 1
437445
runtime.Breakpoint()
438446
for amb1 := 0; amb1 < 10; amb1++ {
@@ -443,5 +451,5 @@ func main() {
443451
longslice := make([]int, 100, 100)
444452

445453
runtime.Breakpoint()
446-
fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerReceiverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan, longbyteslice, enum1, enum2, enum3, enum4, enum5, enum6, zeropoint4, mlarge, messageVar, iface7)
454+
fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerReceiverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan, longbyteslice, enum1, enum2, enum3, enum4, enum5, enum6, zeropoint4, mlarge, messageVar, iface7, issue4179helper)
447455
}

pkg/proc/eval.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,9 @@ func (s *evalStack) fncallPeek() *functionCallState {
916916

917917
func (s *evalStack) pushErr(v *Variable, err error) {
918918
s.err = err
919-
s.stack = append(s.stack, v)
919+
if err == nil {
920+
s.stack = append(s.stack, v)
921+
}
920922
}
921923

922924
// eval evaluates ops. When it returns if callInjectionContinue is set the
@@ -1148,27 +1150,30 @@ func (stack *evalStack) executeOp() {
11481150
stack.push(nilVariable)
11491151

11501152
case *evalop.PushPackageVarOrSelect:
1151-
v, err := scope.findGlobal(op.Name, op.Sel)
1152-
if err != nil && !isSymbolNotFound(err) {
1153-
stack.err = err
1154-
return
1155-
}
1156-
if v != nil {
1157-
stack.push(v)
1158-
} else {
1159-
if op.NameIsString {
1160-
stack.err = fmt.Errorf("%q (type string) is not a struct", op.Name)
1161-
return
1162-
}
1163-
found := stack.pushIdent(scope, op.Name)
1153+
var savedErr error
1154+
found := false
1155+
if !op.NameIsString {
1156+
found = stack.pushIdent(scope, op.Name)
11641157
if stack.err != nil {
1165-
return
1158+
savedErr = stack.err
1159+
stack.err = nil
1160+
found = false
11661161
}
11671162
if found {
11681163
scope.evalStructSelector(&evalop.Select{Name: op.Sel}, stack)
1169-
} else {
1170-
stack.err = fmt.Errorf("could not find symbol value for %s", op.Name)
1164+
if stack.err != nil {
1165+
savedErr = stack.err
1166+
stack.err = nil
1167+
found = false
1168+
}
1169+
}
1170+
}
1171+
if !found {
1172+
v, err := scope.findGlobal(op.Name, op.Sel)
1173+
if err != nil && savedErr != nil {
1174+
err = savedErr
11711175
}
1176+
stack.pushErr(v, err)
11721177
}
11731178

11741179
case *evalop.PushIdent:

pkg/proc/variables_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ func getEvalExpressionTestCases() []varTest {
909909
{"(*afunc)(2)", false, "", "", "", errors.New("*")},
910910
{"unknownthing(2)", false, "", "", "", altErrors("function calls not allowed without using 'call'", "could not find symbol value for unknownthing")},
911911
{"(*unknownthing)(2)", false, "", "", "", altErrors("function calls not allowed without using 'call'", "could not find symbol value for unknownthing")},
912-
{"(*strings.Split)(2)", false, "", "", "", altErrors("function calls not allowed without using 'call'", "could not find symbol value for strings")},
912+
{"(*strings.Split)(2)", false, "", "", "", altErrors("function calls not allowed without using 'call'", "could not find symbol value for strings", "could not find symbol strings.Split")},
913913

914914
// pretty printing special types
915915
{"tim1", false, `time.Time(1977-05-25T18:00:00Z)…`, `time.Time(1977-05-25T18:00:00Z)…`, "time.Time", nil},
@@ -947,6 +947,9 @@ func getEvalExpressionTestCases() []varTest {
947947
{`*(*uint)(unsafe.Pointer(p1))`, false, `1`, `1`, "uint", nil},
948948
{`*(*uint)(unsafe.Pointer(&i1))`, false, `1`, `1`, "uint", nil},
949949

950+
// issue #4179 local variable shadows package
951+
{`issue4179helper.Test`, false, `*github.com/go-delve/delve/_fixtures/internal/issue4179helper.Test {Name: interface {} nil, Age: 0}`, `("*github.com/go-delve/delve/_fixtures/internal/issue4179helper.Test")(…`, "*github.com/go-delve/delve/_fixtures/internal/issue4179helper.Test", nil},
952+
950953
// Malformed values
951954
{`badslice`, false, `(unreadable non-zero length array with nil base)`, `(unreadable non-zero length array with nil base)`, "[]int", nil},
952955
}
@@ -1336,7 +1339,7 @@ func TestCallFunction(t *testing.T) {
13361339
{"x.CallMe()", nil, nil, 0},
13371340
{"x2.CallMe(5)", []string{":int:25"}, nil, 0},
13381341

1339-
{"\"delve\".CallMe()", nil, errors.New("\"delve\" (type string) is not a struct"), 0},
1342+
{"\"delve\".CallMe()", nil, altErrors("\"delve\" (type string) is not a struct", "could not find symbol delve.CallMe"), 0},
13401343

13411344
// Nested function calls tests
13421345

pkg/terminal/command_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,9 @@ func TestBreakPointFailWithCond(t *testing.T) {
15811581
if runtime.GOOS == "freebsd" || runtime.GOOS == "darwin" {
15821582
t.Skip("follow exec not implemented")
15831583
}
1584+
if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
1585+
t.Skip("flaky")
1586+
}
15841587

15851588
oldYesNo := yesno
15861589
defer func() { yesno = oldYesNo }()

0 commit comments

Comments
 (0)