Skip to content

Commit

Permalink
feat: Go+ project debug(vscode)
Browse files Browse the repository at this point in the history
  • Loading branch information
LiusCraft committed Jan 21, 2024
1 parent 73f5abf commit f910780
Show file tree
Hide file tree
Showing 10 changed files with 1,323 additions and 7 deletions.
2 changes: 1 addition & 1 deletion _fixtures/goptest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module testgop

go 1.21.5

require github.com/liuscraft/testgomod v0.0.0-20240114062333-3352239bb6d1
require github.com/liuscraft/testgomod v0.0.0-20240114062333-3352239bb6d1 // indirect
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/spf13/pflag v1.0.5
go.starlark.net v0.0.0-20231101134539-556fd59b42f6
golang.org/x/arch v0.6.0
golang.org/x/mod v0.14.0
golang.org/x/sys v0.13.0
golang.org/x/tools v0.14.0
gopkg.in/yaml.v2 v2.4.0
Expand All @@ -30,6 +31,5 @@ require (
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect
golang.org/x/mod v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
87 changes: 87 additions & 0 deletions pkg/goplus/mod/modcache/modcache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package modcache

import (
"bytes"
"errors"
"log"
"os/exec"
"path/filepath"
"strings"

"golang.org/x/mod/module"
)

// -----------------------------------------------------------------------------

var (
GOMODCACHE = getGOMODCACHE()
)

func getGOMODCACHE() string {
var buf bytes.Buffer
var stderr bytes.Buffer
cmd := exec.Command("go", "env", "GOMODCACHE")
cmd.Stdout = &buf
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
log.Panicln("GOMODCACHE not found:", err)
}
return strings.TrimRight(buf.String(), "\n")
}

// -----------------------------------------------------------------------------

var (
ErrNoNeedToDownload = errors.New("no need to download")
)

// DownloadCachePath returns download cache path of a versioned module.
func DownloadCachePath(mod module.Version) (string, error) {
if mod.Version == "" {
return mod.Path, ErrNoNeedToDownload
}
encPath, err := module.EscapePath(mod.Path)
if err != nil {
return "", err
}
return filepath.Join(GOMODCACHE, "cache/download", encPath, "@v", mod.Version+".zip"), nil
}

// Path returns cache dir of a versioned module.
func Path(mod module.Version) (string, error) {
if mod.Version == "" {
return mod.Path, nil
}
encPath, err := module.EscapePath(mod.Path)
if err != nil {
return "", err
}
return filepath.Join(GOMODCACHE, encPath+"@"+mod.Version), nil
}

// InPath returns if a path is in GOMODCACHE or not.
func InPath(path string) bool {
if strings.HasPrefix(path, GOMODCACHE) {
name := path[len(GOMODCACHE):]
return name == "" || name[0] == '/' || name[0] == '\\'
}
return false
}

// -----------------------------------------------------------------------------
44 changes: 40 additions & 4 deletions pkg/proc/bininfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package proc

import (
"bytes"
"debug/buildinfo"
"debug/dwarf"
"debug/elf"
"debug/macho"
Expand All @@ -16,6 +17,7 @@ import (
"io"
"os"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
Expand All @@ -29,12 +31,14 @@ import (
"github.com/go-delve/delve/pkg/dwarf/loclist"
"github.com/go-delve/delve/pkg/dwarf/op"
"github.com/go-delve/delve/pkg/dwarf/reader"
"github.com/go-delve/delve/pkg/goplus/mod/modcache"
"github.com/go-delve/delve/pkg/goversion"
"github.com/go-delve/delve/pkg/internal/gosym"
"github.com/go-delve/delve/pkg/logflags"
"github.com/go-delve/delve/pkg/proc/debuginfod"
"github.com/go-delve/gore"
"github.com/hashicorp/golang-lru/simplelru"
"golang.org/x/mod/module"
)

const (
Expand Down Expand Up @@ -112,6 +116,8 @@ type BinaryInfo struct {
regabi bool

logger logflags.Logger

buildModInfoMap map[string]string
}

var (
Expand Down Expand Up @@ -702,15 +708,32 @@ func (bi *BinaryInfo) LoadBinaryInfo(path string, entryPoint uint64, debugInfoDi
}

bi.DebugInfoDirectories = debugInfoDirs
bi.PackagePathMap(path)

return bi.AddImage(path, entryPoint)
}

func PackagePathMap(path string) map[string]string {
func (bi *BinaryInfo) PackagePathMap(path string) map[string]string {
// TODO: getBinary Build Info: mod info
//
// buildinfo.ReadFile()
return nil
if len(bi.buildModInfoMap) == 0 {
bi.buildModInfoMap = make(map[string]string)
binfo, _ := buildinfo.ReadFile(path)
bi.buildModInfoMap["main"] = filepath.ToSlash(filepath.Dir(path)) + "/"
for _, m := range binfo.Deps {
aa := module.Version{
Path: m.Path,
Version: m.Version,
}
cupath, _ := modcache.Path(aa)
if runtime.GOOS == "windows" {
cupath = filepath.ToSlash(cupath)
}
bi.buildModInfoMap[m.Path+"/"] = cupath + "/"
}
}
return bi.buildModInfoMap
}

func loadBinaryInfo(bi *BinaryInfo, image *Image, path string, entryPoint uint64) error {
Expand Down Expand Up @@ -797,6 +820,7 @@ type ErrCouldNotFindLine struct {

func (err *ErrCouldNotFindLine) Error() string {
if err.fileFound {
panic("aaaa")
return fmt.Sprintf("could not find statement at %s:%d, please use a line with a statement", err.filename, err.lineno)
}
return fmt.Sprintf("could not find file %s", err.filename)
Expand Down Expand Up @@ -2295,17 +2319,29 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB

bi.lookupFunc = nil
bi.lookupGenericFunc = nil

for _, cu := range image.compileUnits {
if cu.lineInfo != nil {
cuName := cu.name
if runtime.GOOS == "windows" {
cuName = filepath.ToSlash(cuName)
}
for _, fileEntry := range cu.lineInfo.FileNames {
if filepath.Ext(fileEntry.Path) != ".go" && !filepath.IsAbs(fileEntry.Path) {
filePakage := strings.TrimSuffix(cuName, cu.lineInfo.IncludeDirs[fileEntry.DirIdx])
absPath := bi.buildModInfoMap[filePakage] + fileEntry.Path
cu.lineInfo.Lookup[absPath] = fileEntry
delete(cu.lineInfo.Lookup, fileEntry.Path)
fileEntry.Path = absPath
}
bi.Sources = append(bi.Sources, fileEntry.Path)
}
}
}
sort.Strings(bi.Sources)
bi.Sources = uniq(bi.Sources)

for i, v := range bi.Sources {
fmt.Println(i, v)
}
if cont != nil {
cont()
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/proc/proc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,14 @@ func TestStep(t *testing.T) {
}
})
}

func TestSources(t *testing.T) {
protest.AllowRecording(t)
withTestProcess("goptest/", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
for i, v := range p.BinInfo().Sources {
t.Log(i, v)
}
})
}
func TestBreakpoint(t *testing.T) {
protest.AllowRecording(t)
withTestProcess("testprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
Expand Down
15 changes: 15 additions & 0 deletions pkg/proc/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"go/constant"
"path/filepath"
"reflect"
"strings"

Expand Down Expand Up @@ -323,7 +324,21 @@ func (it *stackIterator) newStackframe(ret, retaddr uint64) Stackframe {
l = -1
} else {
it.regs.FrameBase = it.frameBase(fn)
if filepath.Ext(f) != ".go" && !filepath.IsAbs(f) {

absFile := f
for _, fe2 := range fn.cu.lineInfo.FileNames {
absFile = filepath.ToSlash(fn.cu.name + strings.TrimPrefix(fe2.Path, fn.cu.lineInfo.IncludeDirs[fe2.DirIdx]))
for _, v := range it.bi.Sources {
if strings.HasSuffix(v, absFile) {
f = v
}
}
}

}
}

r := Stackframe{Current: Location{PC: it.pc, File: f, Line: l, Fn: fn}, Regs: it.regs, Ret: ret, stackHi: it.stackhi, SystemStack: it.systemstack, lastpc: it.pc}
if r.Regs.Reg(it.regs.PCRegNum) == nil {
r.Regs.AddReg(it.regs.PCRegNum, op.DwarfRegisterFromUint64(it.pc))
Expand Down
78 changes: 78 additions & 0 deletions vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f910780

Please sign in to comment.