Fix various issues detected by megacheck (#880)
* Fix various issues detected by megacheck I've ran honnef.co/go/tools/cmd/megacheck and fixed a few of the things that came up there. * Cleanup using Gogland
This commit is contained in:
parent
a19bca2298
commit
32a005de2b
@ -404,7 +404,7 @@ func coreCmd(cmd *cobra.Command, args []string) {
|
|||||||
func connectCmd(cmd *cobra.Command, args []string) {
|
func connectCmd(cmd *cobra.Command, args []string) {
|
||||||
addr := args[0]
|
addr := args[0]
|
||||||
if addr == "" {
|
if addr == "" {
|
||||||
fmt.Fprintf(os.Stderr, "An empty address was provided. You must provide an address as the first argument.\n")
|
fmt.Fprint(os.Stderr, "An empty address was provided. You must provide an address as the first argument.\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(connect(addr, conf))
|
os.Exit(connect(addr, conf))
|
||||||
@ -419,8 +419,7 @@ func splitArgs(cmd *cobra.Command, args []string) ([]string, []string) {
|
|||||||
|
|
||||||
func connect(addr string, conf *config.Config) int {
|
func connect(addr string, conf *config.Config) int {
|
||||||
// Create and start a terminal - attach to running instance
|
// Create and start a terminal - attach to running instance
|
||||||
var client service.Client
|
client := rpc2.NewClient(addr)
|
||||||
client = rpc2.NewClient(addr)
|
|
||||||
term := terminal.New(client, conf)
|
term := terminal.New(client, conf)
|
||||||
status, err := term.Run()
|
status, err := term.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -447,7 +446,7 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile
|
|||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
if Headless && (InitFile != "") {
|
if Headless && (InitFile != "") {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: init file ignored\n")
|
fmt.Fprint(os.Stderr, "Warning: init file ignored\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
var server interface {
|
var server interface {
|
||||||
@ -498,7 +497,7 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile
|
|||||||
if Headless {
|
if Headless {
|
||||||
// Print listener address
|
// Print listener address
|
||||||
fmt.Printf("API server listening at: %s\n", listener.Addr())
|
fmt.Printf("API server listening at: %s\n", listener.Addr())
|
||||||
ch := make(chan os.Signal)
|
ch := make(chan os.Signal, 1)
|
||||||
signal.Notify(ch, syscall.SIGINT)
|
signal.Notify(ch, syscall.SIGINT)
|
||||||
select {
|
select {
|
||||||
case <-ch:
|
case <-ch:
|
||||||
@ -507,8 +506,7 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile
|
|||||||
err = server.Stop(true)
|
err = server.Stop(true)
|
||||||
} else {
|
} else {
|
||||||
// Create and start a terminal
|
// Create and start a terminal
|
||||||
var client service.Client
|
client := rpc2.NewClient(listener.Addr().String())
|
||||||
client = rpc2.NewClient(listener.Addr().String())
|
|
||||||
term := terminal.New(client, conf)
|
term := terminal.New(client, conf)
|
||||||
term.InitFile = InitFile
|
term.InitFile = InitFile
|
||||||
status, err = term.Run()
|
status, err = term.Run()
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@ -32,10 +32,7 @@ type FrameDescriptionEntry struct {
|
|||||||
// Returns whether or not the given address is within the
|
// Returns whether or not the given address is within the
|
||||||
// bounds of this frame.
|
// bounds of this frame.
|
||||||
func (fde *FrameDescriptionEntry) Cover(addr uint64) bool {
|
func (fde *FrameDescriptionEntry) Cover(addr uint64) bool {
|
||||||
if (addr - fde.begin) < fde.end {
|
return (addr - fde.begin) < fde.end
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address of first location for this frame.
|
// Address of first location for this frame.
|
||||||
|
|||||||
@ -33,7 +33,6 @@ func patchPCRel(pc uint64, inst *x86asm.Inst) {
|
|||||||
inst.Args[i] = x86asm.Imm(int64(pc) + int64(rel) + int64(inst.Len))
|
inst.Args[i] = x86asm.Imm(int64(pc) + int64(rel) + int64(inst.Len))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inst *AsmInstruction) Text(flavour AssemblyFlavour) string {
|
func (inst *AsmInstruction) Text(flavour AssemblyFlavour) string {
|
||||||
|
|||||||
@ -739,11 +739,7 @@ func (p *Process) Restart(pos string) error {
|
|||||||
p.conn.setBreakpoint(addr)
|
p.conn.setBreakpoint(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.setCurrentBreakpoints(); err != nil {
|
return p.setCurrentBreakpoints()
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) When() (string, error) {
|
func (p *Process) When() (string, error) {
|
||||||
@ -1274,7 +1270,7 @@ func (t *Thread) reloadGAtPC() error {
|
|||||||
// around by clearing and re-setting the breakpoint in a specific sequence
|
// around by clearing and re-setting the breakpoint in a specific sequence
|
||||||
// with the memory writes.
|
// with the memory writes.
|
||||||
// Additionally all breakpoints in [pc, pc+len(movinstr)] need to be removed
|
// Additionally all breakpoints in [pc, pc+len(movinstr)] need to be removed
|
||||||
for addr, _ := range t.p.breakpoints {
|
for addr := range t.p.breakpoints {
|
||||||
if addr >= pc && addr <= pc+uint64(len(movinstr)) {
|
if addr >= pc && addr <= pc+uint64(len(movinstr)) {
|
||||||
err := t.p.conn.clearBreakpoint(addr)
|
err := t.p.conn.clearBreakpoint(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -50,7 +50,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var ErrTooManyAttempts = errors.New("too many transmit attempts")
|
var ErrTooManyAttempts = errors.New("too many transmit attempts")
|
||||||
var ErrNoTargetDescrption = errors.New("target description not supported")
|
|
||||||
|
|
||||||
// GdbProtocolError is an error response (Exx) of Gdb Remote Serial Protocol
|
// GdbProtocolError is an error response (Exx) of Gdb Remote Serial Protocol
|
||||||
// or an "unsupported command" response (empty packet).
|
// or an "unsupported command" response (empty packet).
|
||||||
@ -526,7 +525,7 @@ func (conn *gdbConn) resume(sig uint8, tu *threadUpdater) (string, uint8, error)
|
|||||||
if conn.direction == proc.Forward {
|
if conn.direction == proc.Forward {
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
if sig == 0 {
|
if sig == 0 {
|
||||||
fmt.Fprintf(&conn.outbuf, "$vCont;c")
|
fmt.Fprint(&conn.outbuf, "$vCont;c")
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(&conn.outbuf, "$vCont;C%02x", sig)
|
fmt.Fprintf(&conn.outbuf, "$vCont;C%02x", sig)
|
||||||
}
|
}
|
||||||
@ -535,7 +534,7 @@ func (conn *gdbConn) resume(sig uint8, tu *threadUpdater) (string, uint8, error)
|
|||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$bc")
|
fmt.Fprint(&conn.outbuf, "$bc")
|
||||||
}
|
}
|
||||||
if err := conn.send(conn.outbuf.Bytes()); err != nil {
|
if err := conn.send(conn.outbuf.Bytes()); err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
@ -561,7 +560,7 @@ func (conn *gdbConn) step(threadID string, tu *threadUpdater) (string, uint8, er
|
|||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$bs")
|
fmt.Fprint(&conn.outbuf, "$bs")
|
||||||
}
|
}
|
||||||
if err := conn.send(conn.outbuf.Bytes()); err != nil {
|
if err := conn.send(conn.outbuf.Bytes()); err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
@ -698,7 +697,7 @@ func (conn *gdbConn) queryProcessInfo(pid int) (map[string]string, error) {
|
|||||||
if pid != 0 {
|
if pid != 0 {
|
||||||
fmt.Fprintf(&conn.outbuf, "$qProcessInfoPID:%d", pid)
|
fmt.Fprintf(&conn.outbuf, "$qProcessInfoPID:%d", pid)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(&conn.outbuf, "$qProcessInfo")
|
fmt.Fprint(&conn.outbuf, "$qProcessInfo")
|
||||||
}
|
}
|
||||||
resp, err := conn.exec(conn.outbuf.Bytes(), "process info for pid")
|
resp, err := conn.exec(conn.outbuf.Bytes(), "process info for pid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -886,9 +885,9 @@ func (conn *gdbConn) threadStopInfo(threadID string) (sig uint8, reason string,
|
|||||||
// restart executes a 'vRun' command.
|
// restart executes a 'vRun' command.
|
||||||
func (conn *gdbConn) restart(pos string) error {
|
func (conn *gdbConn) restart(pos string) error {
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$vRun;")
|
fmt.Fprint(&conn.outbuf, "$vRun;")
|
||||||
if pos != "" {
|
if pos != "" {
|
||||||
fmt.Fprintf(&conn.outbuf, ";")
|
fmt.Fprint(&conn.outbuf, ";")
|
||||||
writeAsciiBytes(&conn.outbuf, []byte(pos))
|
writeAsciiBytes(&conn.outbuf, []byte(pos))
|
||||||
}
|
}
|
||||||
_, err := conn.exec(conn.outbuf.Bytes(), "restart")
|
_, err := conn.exec(conn.outbuf.Bytes(), "restart")
|
||||||
@ -901,9 +900,9 @@ func (conn *gdbConn) qRRCmd(args ...string) (string, error) {
|
|||||||
panic("must specify at least one argument for qRRCmd")
|
panic("must specify at least one argument for qRRCmd")
|
||||||
}
|
}
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$qRRCmd")
|
fmt.Fprint(&conn.outbuf, "$qRRCmd")
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
fmt.Fprintf(&conn.outbuf, ":")
|
fmt.Fprint(&conn.outbuf, ":")
|
||||||
writeAsciiBytes(&conn.outbuf, []byte(arg))
|
writeAsciiBytes(&conn.outbuf, []byte(arg))
|
||||||
}
|
}
|
||||||
resp, err := conn.exec(conn.outbuf.Bytes(), "qRRCmd")
|
resp, err := conn.exec(conn.outbuf.Bytes(), "qRRCmd")
|
||||||
|
|||||||
@ -78,7 +78,7 @@ func ParseVersionString(ver string) (GoVersion, bool) {
|
|||||||
r.Major, err1 = strconv.Atoi(v[0])
|
r.Major, err1 = strconv.Atoi(v[0])
|
||||||
r.Minor, err2 = strconv.Atoi(v[1])
|
r.Minor, err2 = strconv.Atoi(v[1])
|
||||||
r.Rev, err3 = strconv.Atoi(v[2])
|
r.Rev, err3 = strconv.Atoi(v[2])
|
||||||
r.Proposal = v[3];
|
r.Proposal = v[3]
|
||||||
if err1 != nil || err2 != nil || err3 != nil || r.Proposal == "" {
|
if err1 != nil || err2 != nil || err3 != nil || r.Proposal == "" {
|
||||||
return GoVersion{}, false
|
return GoVersion{}, false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,7 +169,7 @@ func (thread *Thread) clearBreakpointState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (th *Thread) Breakpoint() (*proc.Breakpoint, bool, error) {
|
func (th *Thread) Breakpoint() (*proc.Breakpoint, bool, error) {
|
||||||
return th.CurrentBreakpoint, (th.CurrentBreakpoint != nil && th.BreakpointConditionMet), th.BreakpointConditionError
|
return th.CurrentBreakpoint, th.CurrentBreakpoint != nil && th.BreakpointConditionMet, th.BreakpointConditionError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (th *Thread) ThreadID() int {
|
func (th *Thread) ThreadID() int {
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/constant"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -397,6 +396,9 @@ func GoroutinesInfo(dbp Process) ([]*G, error) {
|
|||||||
}
|
}
|
||||||
faddr := make([]byte, dbp.BinInfo().Arch.PtrSize())
|
faddr := make([]byte, dbp.BinInfo().Arch.PtrSize())
|
||||||
_, err = dbp.CurrentThread().ReadMemory(faddr, uintptr(allgentryaddr))
|
_, err = dbp.CurrentThread().ReadMemory(faddr, uintptr(allgentryaddr))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
allgptr := binary.LittleEndian.Uint64(faddr)
|
allgptr := binary.LittleEndian.Uint64(faddr)
|
||||||
|
|
||||||
for i := uint64(0); i < allglen; i++ {
|
for i := uint64(0); i < allglen; i++ {
|
||||||
@ -429,24 +431,6 @@ func GoroutinesInfo(dbp Process) ([]*G, error) {
|
|||||||
return allg, nil
|
return allg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGoVersion(p Process) (GoVersion, error) {
|
|
||||||
scope := &EvalScope{0, 0, p.CurrentThread(), nil, p.BinInfo(), 0}
|
|
||||||
vv, err := scope.packageVarAddr("runtime.buildVersion")
|
|
||||||
if err != nil {
|
|
||||||
return GoVersion{}, fmt.Errorf("could not determine version number: %v", err)
|
|
||||||
}
|
|
||||||
vv.loadValue(LoadConfig{true, 0, 64, 0, 0})
|
|
||||||
if vv.Unreadable != nil {
|
|
||||||
return GoVersion{}, fmt.Errorf("unreadable version number: %v\n", vv.Unreadable)
|
|
||||||
}
|
|
||||||
|
|
||||||
ver, ok := ParseVersionString(constant.StringVal(vv.Value))
|
|
||||||
if !ok {
|
|
||||||
return GoVersion{}, fmt.Errorf("could not parse version number: %v\n", vv.Value)
|
|
||||||
}
|
|
||||||
return ver, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindGoroutine returns a G struct representing the goroutine
|
// FindGoroutine returns a G struct representing the goroutine
|
||||||
// specified by `gid`.
|
// specified by `gid`.
|
||||||
func FindGoroutine(dbp Process, gid int) (*G, error) {
|
func FindGoroutine(dbp Process, gid int) (*G, error) {
|
||||||
|
|||||||
@ -208,7 +208,7 @@ func setFileBreakpoint(p proc.Process, t *testing.T, fixture protest.Fixture, li
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestHalt(t *testing.T) {
|
func TestHalt(t *testing.T) {
|
||||||
stopChan := make(chan interface{})
|
stopChan := make(chan interface{}, 1)
|
||||||
withTestProcess("loopprog", t, func(p proc.Process, fixture protest.Fixture) {
|
withTestProcess("loopprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.loop")
|
_, err := setFunctionBreakpoint(p, "main.loop")
|
||||||
assertNoError(err, t, "SetBreakpoint")
|
assertNoError(err, t, "SetBreakpoint")
|
||||||
@ -219,18 +219,20 @@ func TestHalt(t *testing.T) {
|
|||||||
assertNoError(err, t, "Registers")
|
assertNoError(err, t, "Registers")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resumeChan := make(chan struct{})
|
resumeChan := make(chan struct{}, 1)
|
||||||
go func() {
|
go func() {
|
||||||
<-resumeChan
|
<-resumeChan
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
if err := p.RequestManualStop(); err != nil {
|
stopChan <- p.RequestManualStop()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
stopChan <- nil
|
|
||||||
}()
|
}()
|
||||||
p.ResumeNotify(resumeChan)
|
p.ResumeNotify(resumeChan)
|
||||||
assertNoError(proc.Continue(p), t, "Continue")
|
assertNoError(proc.Continue(p), t, "Continue")
|
||||||
<-stopChan
|
retVal := <-stopChan
|
||||||
|
|
||||||
|
if err, ok := retVal.(error); ok && err != nil {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
|
||||||
// Loop through threads and make sure they are all
|
// Loop through threads and make sure they are all
|
||||||
// actually stopped, err will not be nil if the process
|
// actually stopped, err will not be nil if the process
|
||||||
// is still running.
|
// is still running.
|
||||||
@ -870,7 +872,11 @@ func stackMatch(stack []loc, locations []proc.Stackframe, skipRuntime bool) bool
|
|||||||
|
|
||||||
func TestStacktraceGoroutine(t *testing.T) {
|
func TestStacktraceGoroutine(t *testing.T) {
|
||||||
mainStack := []loc{{13, "main.stacktraceme"}, {26, "main.main"}}
|
mainStack := []loc{{13, "main.stacktraceme"}, {26, "main.main"}}
|
||||||
agoroutineStacks := [][]loc{[]loc{{8, "main.agoroutine"}}, []loc{{9, "main.agoroutine"}}, []loc{{10, "main.agoroutine"}}}
|
agoroutineStacks := [][]loc{
|
||||||
|
{{8, "main.agoroutine"}},
|
||||||
|
{{9, "main.agoroutine"}},
|
||||||
|
{{10, "main.agoroutine"}},
|
||||||
|
}
|
||||||
|
|
||||||
protest.AllowRecording(t)
|
protest.AllowRecording(t)
|
||||||
withTestProcess("goroutinestackprog", t, func(p proc.Process, fixture protest.Fixture) {
|
withTestProcess("goroutinestackprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
@ -940,7 +946,7 @@ func TestKill(t *testing.T) {
|
|||||||
if err := p.Kill(); err != nil {
|
if err := p.Kill(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if p.Exited() != true {
|
if !p.Exited() {
|
||||||
t.Fatal("expected process to have exited")
|
t.Fatal("expected process to have exited")
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
@ -954,7 +960,7 @@ func TestKill(t *testing.T) {
|
|||||||
if err := p.Detach(true); err != nil {
|
if err := p.Detach(true); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if p.Exited() != true {
|
if !p.Exited() {
|
||||||
t.Fatal("expected process to have exited")
|
t.Fatal("expected process to have exited")
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
@ -1789,6 +1795,9 @@ func TestIssue332_Part2(t *testing.T) {
|
|||||||
pcAfterPrologue, err := proc.FindFunctionLocation(p, "main.changeMe", true, -1)
|
pcAfterPrologue, err := proc.FindFunctionLocation(p, "main.changeMe", true, -1)
|
||||||
assertNoError(err, t, "FindFunctionLocation()")
|
assertNoError(err, t, "FindFunctionLocation()")
|
||||||
pcEntry, err := proc.FindFunctionLocation(p, "main.changeMe", false, 0)
|
pcEntry, err := proc.FindFunctionLocation(p, "main.changeMe", false, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("got error while finding function location: %v", err)
|
||||||
|
}
|
||||||
if pcAfterPrologue == pcEntry {
|
if pcAfterPrologue == pcEntry {
|
||||||
t.Fatalf("main.changeMe and main.changeMe:0 are the same (%x)", pcAfterPrologue)
|
t.Fatalf("main.changeMe and main.changeMe:0 are the same (%x)", pcAfterPrologue)
|
||||||
}
|
}
|
||||||
@ -1891,7 +1900,7 @@ func TestCmdLineArgs(t *testing.T) {
|
|||||||
t.Fatalf("Process did not exit: %v", err)
|
t.Fatalf("Process did not exit: %v", err)
|
||||||
} else {
|
} else {
|
||||||
if exit.Status != 0 {
|
if exit.Status != 0 {
|
||||||
t.Fatalf("process exited with invalid status", exit.Status)
|
t.Fatalf("process exited with invalid status %d", exit.Status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2364,7 +2373,7 @@ func TestStepConcurrentPtr(t *testing.T) {
|
|||||||
|
|
||||||
if oldk, ok := kvals[gid]; ok {
|
if oldk, ok := kvals[gid]; ok {
|
||||||
if oldk >= k {
|
if oldk >= k {
|
||||||
t.Fatalf("Goroutine %d did not make progress?")
|
t.Fatalf("Goroutine %d did not make progress?", gid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kvals[gid] = k
|
kvals[gid] = k
|
||||||
@ -2752,7 +2761,7 @@ func TestStacktraceWithBarriers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
t.Log("Truncated stacktrace for %d\n", goid)
|
t.Logf("Truncated stacktrace for %d\n", goid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -2824,7 +2833,7 @@ func TestAttachDetach(t *testing.T) {
|
|||||||
assertNoError(err, t, "Page request after detach")
|
assertNoError(err, t, "Page request after detach")
|
||||||
bs, err := ioutil.ReadAll(resp.Body)
|
bs, err := ioutil.ReadAll(resp.Body)
|
||||||
assertNoError(err, t, "Reading /nobp page")
|
assertNoError(err, t, "Reading /nobp page")
|
||||||
if out := string(bs); strings.Index(out, "hello, world!") < 0 {
|
if out := string(bs); !strings.Contains(out, "hello, world!") {
|
||||||
t.Fatalf("/nobp page does not contain \"hello, world!\": %q", out)
|
t.Fatalf("/nobp page does not contain \"hello, world!\": %q", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
package proc_test
|
package proc_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
@ -12,6 +13,15 @@ import (
|
|||||||
protest "github.com/derekparker/delve/pkg/proc/test"
|
protest "github.com/derekparker/delve/pkg/proc/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type errIssue419 struct {
|
||||||
|
pid int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (npe errIssue419) Error() string {
|
||||||
|
return fmt.Sprintf("Pid is zero or negative: %d", npe.pid)
|
||||||
|
}
|
||||||
|
|
||||||
func TestIssue419(t *testing.T) {
|
func TestIssue419(t *testing.T) {
|
||||||
if testBackend == "lldb" && runtime.GOOS == "darwin" {
|
if testBackend == "lldb" && runtime.GOOS == "darwin" {
|
||||||
// debugserver bug?
|
// debugserver bug?
|
||||||
@ -20,29 +30,43 @@ func TestIssue419(t *testing.T) {
|
|||||||
if testBackend == "rr" {
|
if testBackend == "rr" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errChan := make(chan error, 2)
|
||||||
|
|
||||||
// SIGINT directed at the inferior should be passed along not swallowed by delve
|
// SIGINT directed at the inferior should be passed along not swallowed by delve
|
||||||
withTestProcess("issue419", t, func(p proc.Process, fixture protest.Fixture) {
|
withTestProcess("issue419", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
|
defer close(errChan)
|
||||||
_, err := setFunctionBreakpoint(p, "main.main")
|
_, err := setFunctionBreakpoint(p, "main.main")
|
||||||
assertNoError(err, t, "SetBreakpoint()")
|
assertNoError(err, t, "SetBreakpoint()")
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
resumeChan := make(chan struct{})
|
resumeChan := make(chan struct{}, 1)
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
<-resumeChan
|
<-resumeChan
|
||||||
if p.Pid() <= 0 {
|
if p.Pid() <= 0 {
|
||||||
// if we don't stop the inferior the test will never finish
|
// if we don't stop the inferior the test will never finish
|
||||||
p.RequestManualStop()
|
p.RequestManualStop()
|
||||||
p.Kill()
|
err := p.Kill()
|
||||||
t.Fatalf("Pid is zero or negative: %d", p.Pid())
|
errChan <- errIssue419{pid: p.Pid(), err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := syscall.Kill(p.Pid(), syscall.SIGINT)
|
err := syscall.Kill(p.Pid(), syscall.SIGINT)
|
||||||
assertNoError(err, t, "syscall.Kill")
|
errChan <- errIssue419{pid: p.Pid(), err: err}
|
||||||
}()
|
}()
|
||||||
p.ResumeNotify(resumeChan)
|
p.ResumeNotify(resumeChan)
|
||||||
err = proc.Continue(p)
|
errChan <- proc.Continue(p)
|
||||||
|
})
|
||||||
|
|
||||||
|
for i :=0; i<2; i++ {
|
||||||
|
err := <-errChan
|
||||||
|
|
||||||
|
if v, ok := err.(errIssue419); ok {
|
||||||
|
assertNoError(v.err, t, "syscall.Kill")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if _, exited := err.(proc.ProcessExitedError); !exited {
|
if _, exited := err.(proc.ProcessExitedError); !exited {
|
||||||
t.Fatalf("Unexpected error after Continue(): %v\n", err)
|
t.Fatalf("Unexpected error after Continue(): %v\n", err)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -481,7 +481,7 @@ func (g *G) UserCurrent() Location {
|
|||||||
frame := it.Frame()
|
frame := it.Frame()
|
||||||
if frame.Call.Fn != nil {
|
if frame.Call.Fn != nil {
|
||||||
name := frame.Call.Fn.Name
|
name := frame.Call.Fn.Name
|
||||||
if (strings.Index(name, ".") >= 0) && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
|
if strings.Contains(name, ".") && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
|
||||||
return frame.Call
|
return frame.Call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -712,7 +712,7 @@ func (v *Variable) structMember(memberName string) (*Variable, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
embeddedVar.Name = structVar.Name
|
embeddedVar.Name = structVar.Name
|
||||||
embeddedField, err := embeddedVar.structMember(memberName)
|
embeddedField, _ := embeddedVar.structMember(memberName)
|
||||||
if embeddedField != nil {
|
if embeddedField != nil {
|
||||||
return embeddedField, nil
|
return embeddedField, nil
|
||||||
}
|
}
|
||||||
@ -1016,8 +1016,6 @@ func (v *Variable) loadSliceInfo(t *dwarf.SliceType) {
|
|||||||
if t, ok := v.fieldType.(*dwarf.PtrType); ok {
|
if t, ok := v.fieldType.(*dwarf.PtrType); ok {
|
||||||
v.stride = t.ByteSize
|
v.stride = t.ByteSize
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
|
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
|
||||||
@ -1652,7 +1650,6 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig
|
|||||||
} else {
|
} else {
|
||||||
v.Children[0].OnlyAddr = true
|
v.Children[0].OnlyAddr = true
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches all variables of a specific type in the current function scope
|
// Fetches all variables of a specific type in the current function scope
|
||||||
|
|||||||
@ -369,7 +369,7 @@ func TestOnPrefix(t *testing.T) {
|
|||||||
for {
|
for {
|
||||||
outstr, err := term.Exec("continue")
|
outstr, err := term.Exec("continue")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Index(err.Error(), "exited") < 0 {
|
if !strings.Contains(err.Error(), "exited") {
|
||||||
t.Fatalf("Unexpected error executing 'continue': %v", err)
|
t.Fatalf("Unexpected error executing 'continue': %v", err)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -422,7 +422,7 @@ func TestOnPrefixLocals(t *testing.T) {
|
|||||||
for {
|
for {
|
||||||
outstr, err := term.Exec("continue")
|
outstr, err := term.Exec("continue")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Index(err.Error(), "exited") < 0 {
|
if !strings.Contains(err.Error(), "exited") {
|
||||||
t.Fatalf("Unexpected error executing 'continue': %v", err)
|
t.Fatalf("Unexpected error executing 'continue': %v", err)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -476,7 +476,7 @@ func TestIssue387(t *testing.T) {
|
|||||||
breakpointHitCount += countOccourences(outstr, "issue387.go:8")
|
breakpointHitCount += countOccourences(outstr, "issue387.go:8")
|
||||||
t.Log(outstr)
|
t.Log(outstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Index(err.Error(), "exited") < 0 {
|
if !strings.Contains(err.Error(), "exited") {
|
||||||
t.Fatalf("Unexpected error executing 'continue': %v", err)
|
t.Fatalf("Unexpected error executing 'continue': %v", err)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -509,7 +509,7 @@ func listIsAt(t *testing.T, term *FakeTerminal, listcmd string, cur, start, end
|
|||||||
|
|
||||||
t.Logf("%q: %q", listcmd, outstr)
|
t.Logf("%q: %q", listcmd, outstr)
|
||||||
|
|
||||||
if strings.Index(lines[0], fmt.Sprintf(":%d", cur)) < 0 {
|
if !strings.Contains(lines[0], fmt.Sprintf(":%d", cur)) {
|
||||||
t.Fatalf("Could not find current line number in first output line: %q", lines[0])
|
t.Fatalf("Could not find current line number in first output line: %q", lines[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,11 @@ package terminal
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/derekparker/delve/service/api"
|
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/derekparker/delve/service/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DisasmPrint(dv api.AsmInstructions, out io.Writer) {
|
func DisasmPrint(dv api.AsmInstructions, out io.Writer) {
|
||||||
|
|||||||
@ -27,10 +27,10 @@ func replaceDocPath(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (commands *Commands) WriteMarkdown(w io.Writer) {
|
func (commands *Commands) WriteMarkdown(w io.Writer) {
|
||||||
fmt.Fprintf(w, "# Commands\n\n")
|
fmt.Fprint(w, "# Commands\n\n")
|
||||||
|
|
||||||
fmt.Fprintf(w, "Command | Description\n")
|
fmt.Fprint(w, "Command | Description\n")
|
||||||
fmt.Fprintf(w, "--------|------------\n")
|
fmt.Fprint(w, "--------|------------\n")
|
||||||
for _, cmd := range commands.cmds {
|
for _, cmd := range commands.cmds {
|
||||||
h := cmd.helpMsg
|
h := cmd.helpMsg
|
||||||
if idx := strings.Index(h, "\n"); idx >= 0 {
|
if idx := strings.Index(h, "\n"); idx >= 0 {
|
||||||
@ -38,17 +38,17 @@ func (commands *Commands) WriteMarkdown(w io.Writer) {
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(w, "[%s](#%s) | %s\n", cmd.aliases[0], cmd.aliases[0], h)
|
fmt.Fprintf(w, "[%s](#%s) | %s\n", cmd.aliases[0], cmd.aliases[0], h)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Fprint(w, "\n")
|
||||||
|
|
||||||
for _, cmd := range commands.cmds {
|
for _, cmd := range commands.cmds {
|
||||||
fmt.Fprintf(w, "## %s\n%s\n\n", cmd.aliases[0], replaceDocPath(cmd.helpMsg))
|
fmt.Fprintf(w, "## %s\n%s\n\n", cmd.aliases[0], replaceDocPath(cmd.helpMsg))
|
||||||
if len(cmd.aliases) > 1 {
|
if len(cmd.aliases) > 1 {
|
||||||
fmt.Fprintf(w, "Aliases:")
|
fmt.Fprint(w, "Aliases:")
|
||||||
for _, alias := range cmd.aliases[1:] {
|
for _, alias := range cmd.aliases[1:] {
|
||||||
fmt.Fprintf(w, " %s", alias)
|
fmt.Fprintf(w, " %s", alias)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Fprint(w, "\n")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Fprint(w, "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -276,5 +276,5 @@ func ConvertRegisters(in []proc.Register) (out []Register) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCheckpoint(in proc.Checkpoint) (out Checkpoint) {
|
func ConvertCheckpoint(in proc.Checkpoint) (out Checkpoint) {
|
||||||
return Checkpoint{ID: in.ID, When: in.When, Where: in.Where}
|
return Checkpoint(in)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
|
|||||||
if includeType && v.Type != "void" {
|
if includeType && v.Type != "void" {
|
||||||
fmt.Fprintf(buf, "%s nil", v.Type)
|
fmt.Fprintf(buf, "%s nil", v.Type)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, "nil")
|
fmt.Fprint(buf, "nil")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -50,11 +50,11 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
|
|||||||
v.writeArrayTo(buf, newlines, includeType, indent)
|
v.writeArrayTo(buf, newlines, includeType, indent)
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if v.Type == "" {
|
if v.Type == "" {
|
||||||
fmt.Fprintf(buf, "nil")
|
fmt.Fprint(buf, "nil")
|
||||||
} else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 {
|
} else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 {
|
||||||
fmt.Fprintf(buf, "(%s)(0x%x)", v.Type, v.Children[0].Addr)
|
fmt.Fprintf(buf, "(%s)(0x%x)", v.Type, v.Children[0].Addr)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, "*")
|
fmt.Fprint(buf, "*")
|
||||||
v.Children[0].writeTo(buf, false, newlines, includeType, indent)
|
v.Children[0].writeTo(buf, false, newlines, includeType, indent)
|
||||||
}
|
}
|
||||||
case reflect.UnsafePointer:
|
case reflect.UnsafePointer:
|
||||||
@ -78,7 +78,7 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
|
|||||||
if v.Children[0].Kind == reflect.Invalid {
|
if v.Children[0].Kind == reflect.Invalid {
|
||||||
fmt.Fprintf(buf, "%s ", v.Type)
|
fmt.Fprintf(buf, "%s ", v.Type)
|
||||||
if v.Children[0].Addr == 0 {
|
if v.Children[0].Addr == 0 {
|
||||||
fmt.Fprintf(buf, "nil")
|
fmt.Fprint(buf, "nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -88,9 +88,9 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
|
|||||||
data := v.Children[0]
|
data := v.Children[0]
|
||||||
if data.Kind == reflect.Ptr {
|
if data.Kind == reflect.Ptr {
|
||||||
if len(data.Children) == 0 {
|
if len(data.Children) == 0 {
|
||||||
fmt.Fprintf(buf, "...")
|
fmt.Fprint(buf, "...")
|
||||||
} else if data.Children[0].Addr == 0 {
|
} else if data.Children[0].Addr == 0 {
|
||||||
fmt.Fprintf(buf, "nil")
|
fmt.Fprint(buf, "nil")
|
||||||
} else if data.Children[0].OnlyAddr {
|
} else if data.Children[0].OnlyAddr {
|
||||||
fmt.Fprintf(buf, "0x%x", v.Children[0].Addr)
|
fmt.Fprintf(buf, "0x%x", v.Children[0].Addr)
|
||||||
} else {
|
} else {
|
||||||
@ -103,7 +103,7 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
|
|||||||
v.writeMapTo(buf, newlines, includeType, indent)
|
v.writeMapTo(buf, newlines, includeType, indent)
|
||||||
case reflect.Func:
|
case reflect.Func:
|
||||||
if v.Value == "" {
|
if v.Value == "" {
|
||||||
fmt.Fprintf(buf, "nil")
|
fmt.Fprint(buf, "nil")
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, "%s", v.Value)
|
fmt.Fprintf(buf, "%s", v.Value)
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ func (v *Variable) writeStructTo(buf io.Writer, newlines, includeType bool, inde
|
|||||||
|
|
||||||
nl := v.shouldNewlineStruct(newlines)
|
nl := v.shouldNewlineStruct(newlines)
|
||||||
|
|
||||||
fmt.Fprintf(buf, "{")
|
fmt.Fprint(buf, "{")
|
||||||
|
|
||||||
for i := range v.Children {
|
for i := range v.Children {
|
||||||
if nl {
|
if nl {
|
||||||
@ -161,9 +161,9 @@ func (v *Variable) writeStructTo(buf io.Writer, newlines, includeType bool, inde
|
|||||||
fmt.Fprintf(buf, "%s: ", v.Children[i].Name)
|
fmt.Fprintf(buf, "%s: ", v.Children[i].Name)
|
||||||
v.Children[i].writeTo(buf, false, nl, true, indent+indentString)
|
v.Children[i].writeTo(buf, false, nl, true, indent+indentString)
|
||||||
if i != len(v.Children)-1 || nl {
|
if i != len(v.Children)-1 || nl {
|
||||||
fmt.Fprintf(buf, ",")
|
fmt.Fprint(buf, ",")
|
||||||
if !nl {
|
if !nl {
|
||||||
fmt.Fprintf(buf, " ")
|
fmt.Fprint(buf, " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,12 +172,12 @@ func (v *Variable) writeStructTo(buf io.Writer, newlines, includeType bool, inde
|
|||||||
if nl {
|
if nl {
|
||||||
fmt.Fprintf(buf, "\n%s%s", indent, indentString)
|
fmt.Fprintf(buf, "\n%s%s", indent, indentString)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, ",")
|
fmt.Fprint(buf, ",")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(buf, "...+%d more", int(v.Len)-len(v.Children))
|
fmt.Fprintf(buf, "...+%d more", int(v.Len)-len(v.Children))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(buf, "}")
|
fmt.Fprint(buf, "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Variable) writeMapTo(buf io.Writer, newlines, includeType bool, indent string) {
|
func (v *Variable) writeMapTo(buf io.Writer, newlines, includeType bool, indent string) {
|
||||||
@ -187,7 +187,7 @@ func (v *Variable) writeMapTo(buf io.Writer, newlines, includeType bool, indent
|
|||||||
|
|
||||||
nl := newlines && (len(v.Children) > 0)
|
nl := newlines && (len(v.Children) > 0)
|
||||||
|
|
||||||
fmt.Fprintf(buf, "[")
|
fmt.Fprint(buf, "[")
|
||||||
|
|
||||||
for i := 0; i < len(v.Children); i += 2 {
|
for i := 0; i < len(v.Children); i += 2 {
|
||||||
key := &v.Children[i]
|
key := &v.Children[i]
|
||||||
@ -198,10 +198,10 @@ func (v *Variable) writeMapTo(buf io.Writer, newlines, includeType bool, indent
|
|||||||
}
|
}
|
||||||
|
|
||||||
key.writeTo(buf, false, false, false, indent+indentString)
|
key.writeTo(buf, false, false, false, indent+indentString)
|
||||||
fmt.Fprintf(buf, ": ")
|
fmt.Fprint(buf, ": ")
|
||||||
value.writeTo(buf, false, nl, false, indent+indentString)
|
value.writeTo(buf, false, nl, false, indent+indentString)
|
||||||
if i != len(v.Children)-1 || nl {
|
if i != len(v.Children)-1 || nl {
|
||||||
fmt.Fprintf(buf, ", ")
|
fmt.Fprint(buf, ", ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,18 +210,18 @@ func (v *Variable) writeMapTo(buf io.Writer, newlines, includeType bool, indent
|
|||||||
if nl {
|
if nl {
|
||||||
fmt.Fprintf(buf, "\n%s%s", indent, indentString)
|
fmt.Fprintf(buf, "\n%s%s", indent, indentString)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, ",")
|
fmt.Fprint(buf, ",")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(buf, "...+%d more", int(v.Len)-(len(v.Children)/2))
|
fmt.Fprintf(buf, "...+%d more", int(v.Len)-(len(v.Children)/2))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, "...")
|
fmt.Fprint(buf, "...")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if nl {
|
if nl {
|
||||||
fmt.Fprintf(buf, "\n%s", indent)
|
fmt.Fprintf(buf, "\n%s", indent)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(buf, "]")
|
fmt.Fprint(buf, "]")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Variable) shouldNewlineArray(newlines bool) bool {
|
func (v *Variable) shouldNewlineArray(newlines bool) bool {
|
||||||
@ -290,7 +290,7 @@ func (v *Variable) shouldNewlineStruct(newlines bool) bool {
|
|||||||
|
|
||||||
func (v *Variable) writeSliceOrArrayTo(buf io.Writer, newlines bool, indent string) {
|
func (v *Variable) writeSliceOrArrayTo(buf io.Writer, newlines bool, indent string) {
|
||||||
nl := v.shouldNewlineArray(newlines)
|
nl := v.shouldNewlineArray(newlines)
|
||||||
fmt.Fprintf(buf, "[")
|
fmt.Fprint(buf, "[")
|
||||||
|
|
||||||
for i := range v.Children {
|
for i := range v.Children {
|
||||||
if nl {
|
if nl {
|
||||||
@ -298,7 +298,7 @@ func (v *Variable) writeSliceOrArrayTo(buf io.Writer, newlines bool, indent stri
|
|||||||
}
|
}
|
||||||
v.Children[i].writeTo(buf, false, nl, false, indent+indentString)
|
v.Children[i].writeTo(buf, false, nl, false, indent+indentString)
|
||||||
if i != len(v.Children)-1 || nl {
|
if i != len(v.Children)-1 || nl {
|
||||||
fmt.Fprintf(buf, ",")
|
fmt.Fprint(buf, ",")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,11 +307,11 @@ func (v *Variable) writeSliceOrArrayTo(buf io.Writer, newlines bool, indent stri
|
|||||||
if nl {
|
if nl {
|
||||||
fmt.Fprintf(buf, "\n%s%s", indent, indentString)
|
fmt.Fprintf(buf, "\n%s%s", indent, indentString)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, ",")
|
fmt.Fprint(buf, ",")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(buf, "...+%d more", int(v.Len)-len(v.Children))
|
fmt.Fprintf(buf, "...+%d more", int(v.Len)-len(v.Children))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(buf, "...")
|
fmt.Fprint(buf, "...")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,5 +319,5 @@ func (v *Variable) writeSliceOrArrayTo(buf io.Writer, newlines bool, indent stri
|
|||||||
fmt.Fprintf(buf, "\n%s", indent)
|
fmt.Fprintf(buf, "\n%s", indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(buf, "]")
|
fmt.Fprint(buf, "]")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package debugger
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
sys "golang.org/x/sys/unix"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
sys "golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func attachErrorMessage(pid int, err error) error {
|
func attachErrorMessage(pid int, err error) error {
|
||||||
|
|||||||
@ -178,7 +178,7 @@ func parseFuncLocationSpec(in string) *FuncLocationSpec {
|
|||||||
r := stripReceiverDecoration(v[0])
|
r := stripReceiverDecoration(v[0])
|
||||||
if r != v[0] {
|
if r != v[0] {
|
||||||
spec.ReceiverName = r
|
spec.ReceiverName = r
|
||||||
} else if strings.Index(r, "/") >= 0 {
|
} else if strings.Contains(r, "/") {
|
||||||
spec.PackageName = r
|
spec.PackageName = r
|
||||||
} else {
|
} else {
|
||||||
spec.PackageOrReceiverName = r
|
spec.PackageOrReceiverName = r
|
||||||
@ -198,7 +198,7 @@ func parseFuncLocationSpec(in string) *FuncLocationSpec {
|
|||||||
spec.AbsolutePackage = true
|
spec.AbsolutePackage = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Index(spec.BaseName, "/") >= 0 || strings.Index(spec.ReceiverName, "/") >= 0 {
|
if strings.Contains(spec.BaseName, "/") || strings.Contains(spec.ReceiverName, "/") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import (
|
|||||||
// Client is a RPC service.Client.
|
// Client is a RPC service.Client.
|
||||||
type RPCClient struct {
|
type RPCClient struct {
|
||||||
addr string
|
addr string
|
||||||
processPid int
|
|
||||||
client *rpc.Client
|
client *rpc.Client
|
||||||
haltMu sync.Mutex
|
haltMu sync.Mutex
|
||||||
haltReq bool
|
haltReq bool
|
||||||
@ -303,10 +302,6 @@ func (c *RPCClient) DisassemblePC(scope api.EvalScope, pc uint64, flavour api.As
|
|||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RPCClient) url(path string) string {
|
|
||||||
return fmt.Sprintf("http://%s%s", c.addr, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) call(method string, args, reply interface{}) error {
|
func (c *RPCClient) call(method string, args, reply interface{}) error {
|
||||||
return c.client.Call("RPCServer."+method, args, reply)
|
return c.client.Call("RPCServer."+method, args, reply)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import (
|
|||||||
// Client is a RPC service.Client.
|
// Client is a RPC service.Client.
|
||||||
type RPCClient struct {
|
type RPCClient struct {
|
||||||
addr string
|
addr string
|
||||||
processPid int
|
|
||||||
client *rpc.Client
|
client *rpc.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,10 +348,6 @@ func (c *RPCClient) ClearCheckpoint(id int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RPCClient) url(path string) string {
|
|
||||||
return fmt.Sprintf("http://%s%s", c.addr, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) call(method string, args, reply interface{}) error {
|
func (c *RPCClient) call(method string, args, reply interface{}) error {
|
||||||
return c.client.Call("RPCServer."+method, args, reply)
|
return c.client.Call("RPCServer."+method, args, reply)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,7 +109,6 @@ func (s *RPCServer) Command(command api.DebuggerCommand, cb service.RPCCallback)
|
|||||||
var out CommandOut
|
var out CommandOut
|
||||||
out.State = *st
|
out.State = *st
|
||||||
cb.Return(out, nil)
|
cb.Return(out, nil)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBreakpointIn struct {
|
type GetBreakpointIn struct {
|
||||||
|
|||||||
@ -244,7 +244,6 @@ func suitableMethods(rcvr interface{}, methods map[string]*methodType) {
|
|||||||
}
|
}
|
||||||
methods[sname+"."+mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType, Synchronous: synchronous, Rcvr: rcvrv}
|
methods[sname+"."+mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType, Synchronous: synchronous, Rcvr: rcvrv}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerImpl) serveJSONCodec(conn io.ReadWriteCloser) {
|
func (s *ServerImpl) serveJSONCodec(conn io.ReadWriteCloser) {
|
||||||
|
|||||||
@ -26,7 +26,7 @@ func assertError(err error, t *testing.T, s string) {
|
|||||||
t.Fatalf("failed assertion at %s:%d: %s (no error)\n", fname, line, s)
|
t.Fatalf("failed assertion at %s:%d: %s (no error)\n", fname, line, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Index(err.Error(), "Internal debugger error") >= 0 {
|
if strings.Contains(err.Error(), "Internal debugger error") {
|
||||||
_, file, line, _ := runtime.Caller(1)
|
_, file, line, _ := runtime.Caller(1)
|
||||||
fname := filepath.Base(file)
|
fname := filepath.Base(file)
|
||||||
t.Fatalf("failed assertion at %s:%d: %s internal debugger error: %v\n", fname, line, s, err)
|
t.Fatalf("failed assertion at %s:%d: %s internal debugger error: %v\n", fname, line, s, err)
|
||||||
|
|||||||
@ -172,7 +172,7 @@ func Test1ClientServer_exit(t *testing.T) {
|
|||||||
if !state.Exited {
|
if !state.Exited {
|
||||||
t.Fatalf("Expected exit after continue: %v", state)
|
t.Fatalf("Expected exit after continue: %v", state)
|
||||||
}
|
}
|
||||||
state, err = c.GetState()
|
_, err = c.GetState()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected error on querying state from exited process")
|
t.Fatal("Expected error on querying state from exited process")
|
||||||
}
|
}
|
||||||
@ -699,6 +699,9 @@ func Test1ClientServer_SetVariable(t *testing.T) {
|
|||||||
assertNoError(c.SetVariable(api.EvalScope{-1, 0}, "a2", "8"), t, "SetVariable()")
|
assertNoError(c.SetVariable(api.EvalScope{-1, 0}, "a2", "8"), t, "SetVariable()")
|
||||||
|
|
||||||
a2, err := c.EvalVariable(api.EvalScope{-1, 0}, "a2")
|
a2, err := c.EvalVariable(api.EvalScope{-1, 0}, "a2")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not evaluate variable: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
t.Logf("a2: %v", a2)
|
t.Logf("a2: %v", a2)
|
||||||
|
|
||||||
@ -737,7 +740,7 @@ func Test1ClientServer_FullStacktrace(t *testing.T) {
|
|||||||
if arg.Name != "i" {
|
if arg.Name != "i" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.Logf("frame %d, variable i is %v\n", arg)
|
t.Logf("frame %d, variable i is %v\n", i, arg)
|
||||||
argn, err := strconv.Atoi(arg.Value)
|
argn, err := strconv.Atoi(arg.Value)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
found[argn] = true
|
found[argn] = true
|
||||||
|
|||||||
@ -196,7 +196,7 @@ func TestClientServer_exit(t *testing.T) {
|
|||||||
if !state.Exited {
|
if !state.Exited {
|
||||||
t.Fatalf("Expected exit after continue: %v", state)
|
t.Fatalf("Expected exit after continue: %v", state)
|
||||||
}
|
}
|
||||||
state, err = c.GetState()
|
_, err = c.GetState()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected error on querying state from exited process")
|
t.Fatal("Expected error on querying state from exited process")
|
||||||
}
|
}
|
||||||
@ -762,6 +762,9 @@ func TestClientServer_SetVariable(t *testing.T) {
|
|||||||
assertNoError(c.SetVariable(api.EvalScope{-1, 0}, "a2", "8"), t, "SetVariable()")
|
assertNoError(c.SetVariable(api.EvalScope{-1, 0}, "a2", "8"), t, "SetVariable()")
|
||||||
|
|
||||||
a2, err := c.EvalVariable(api.EvalScope{-1, 0}, "a2", normalLoadConfig)
|
a2, err := c.EvalVariable(api.EvalScope{-1, 0}, "a2", normalLoadConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not evaluate variable: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
t.Logf("a2: %v", a2)
|
t.Logf("a2: %v", a2)
|
||||||
|
|
||||||
|
|||||||
@ -83,6 +83,10 @@ func evalVariable(p proc.Process, symbol string, cfg proc.LoadConfig) (*proc.Var
|
|||||||
scope, err = proc.GoroutineScope(p.CurrentThread())
|
scope, err = proc.GoroutineScope(p.CurrentThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return scope.EvalVariable(symbol, cfg)
|
return scope.EvalVariable(symbol, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,8 +104,6 @@ func setVariable(p proc.Process, symbol, value string) error {
|
|||||||
return scope.SetVariable(symbol, value)
|
return scope.SetVariable(symbol, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const varTestBreakpointLineNumber = 59
|
|
||||||
|
|
||||||
func withTestProcess(name string, t *testing.T, fn func(p proc.Process, fixture protest.Fixture)) {
|
func withTestProcess(name string, t *testing.T, fn func(p proc.Process, fixture protest.Fixture)) {
|
||||||
fixture := protest.BuildFixture(name)
|
fixture := protest.BuildFixture(name)
|
||||||
var p proc.Process
|
var p proc.Process
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user