diff --git a/Documentation/cli/expr.md b/Documentation/cli/expr.md index db18a676f50a1d091e890fd5f2cb76783a86c6ea..8233d756e931afb6006f07618d81ba7c4e0b4410 100644 --- a/Documentation/cli/expr.md +++ b/Documentation/cli/expr.md @@ -81,3 +81,12 @@ To use a field of a struct contained inside an interface variable use a type ass (dlv) p iface1.(*main.astruct).B 2 ``` + +# Specifying package paths + +Packages with the same name can be disambiguated by using the full package path. For example, if the application imports two packages, `some/package` and `some/other/package`, both defining a variable `A`, the two variables can be accessed using this syntax: + +``` +(dlv) p "some/package".A +(dlv) p "some/other/package".A +``` diff --git a/_fixtures/pkgrenames.go b/_fixtures/pkgrenames.go index 2ee420fdd754d94f580634a13451632e99c77720..d315e6b766284a2df980b3edea052caeb32b7922 100644 --- a/_fixtures/pkgrenames.go +++ b/_fixtures/pkgrenames.go @@ -51,5 +51,5 @@ func main() { m := t.Method(0) fmt.Println(m.Type.In(0)) fmt.Println(m.Type.String()) - fmt.Println(badexpr, req, amap, amap2, dir0someType, dir1someType, amap3, anarray, achan, aslice, afunc, astruct, astruct2, iface2iface, iface3, pkg.SomeVar) + fmt.Println(badexpr, req, amap, amap2, dir0someType, dir1someType, amap3, anarray, achan, aslice, afunc, astruct, astruct2, iface2iface, iface3, pkg.SomeVar, pkg.A, dir1pkg.A) } diff --git a/_fixtures/vendor/dir0/pkg/main.go b/_fixtures/vendor/dir0/pkg/main.go index bb0d895bda066129698b550cbab9db29d40b5f47..c3435b260c81876b706f8663961c1b567b672e66 100644 --- a/_fixtures/vendor/dir0/pkg/main.go +++ b/_fixtures/vendor/dir0/pkg/main.go @@ -1,5 +1,7 @@ package pkg +var A = 0 + type SomeType struct { X float64 } diff --git a/_fixtures/vendor/dir1/pkg/main.go b/_fixtures/vendor/dir1/pkg/main.go index 99ad14352723d372b8ceae3f301dd1d25519db8e..9201e224b057715f1fd9bab1756ec6750c5eb81c 100644 --- a/_fixtures/vendor/dir1/pkg/main.go +++ b/_fixtures/vendor/dir1/pkg/main.go @@ -1,5 +1,7 @@ package pkg +var A = 1 + type SomeType struct { X int Y int diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 0417c29a5c76428f91de0cc276c837ced5b2e30d..ec1cb320b9b92ef2c9b2947276ed14160ce8cda2 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -11,6 +11,7 @@ import ( "go/printer" "go/token" "reflect" + "strconv" "github.com/derekparker/delve/pkg/dwarf/godwarf" "github.com/derekparker/delve/pkg/dwarf/reader" @@ -187,6 +188,15 @@ func (scope *EvalScope) evalAST(t ast.Expr) (*Variable, error) { return v, nil } } + // try to accept "package/path".varname syntax for package variables + if maybePkg, ok := node.X.(*ast.BasicLit); ok && maybePkg.Kind == token.STRING { + pkgpath, err := strconv.Unquote(maybePkg.Value) + if err == nil { + if v, err := scope.findGlobal(pkgpath + "." + node.Sel.Name); err == nil { + return v, nil + } + } + } // if it's not a package variable then it must be a struct member access return scope.evalStructSelector(node) diff --git a/service/test/variables_test.go b/service/test/variables_test.go index bf52f9f8cb8cb0e998e6fde06136c4f859d9f014..5533a14be6f1bb5b21fa8b2a38a70d8f90533711 100644 --- a/service/test/variables_test.go +++ b/service/test/variables_test.go @@ -920,6 +920,9 @@ func TestPackageRenames(t *testing.T) { {"astruct", true, `interface {}(*struct { A github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType; B github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType }) *{A: github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType {X: 1, Y: 2}, B: github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType {X: 3}}`, "", "interface {}", nil}, {"astruct2", true, `interface {}(*struct { github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType; X int }) *{SomeType: github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType {X: 1, Y: 2}, X: 10}`, "", "interface {}", nil}, {"iface2iface", true, `interface {}(*interface { AMethod(int) int; AnotherMethod(int) int }) **github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType {X: 4}`, "", "interface {}", nil}, + + {`"dir0/pkg".A`, false, "0", "", "int", nil}, + {`"dir1/pkg".A`, false, "1", "", "int", nil}, } ver, _ := goversion.Parse(runtime.Version())