Flag to set working directory (#650)
* proc: Add `wd` to Launch This change adds the `wd` arg which specify working directory of the program. Fixes #295 * service/debugger: Add `Wd` field to debugger.Config This change adds the `Wd` field which specify working directory of the program launched by debugger. Fixes #295 * service: Add `Wd` to service.Config This change adds the `Wd` field which specify working directory of the program debugger will launch. Fixes #295 * cmd/dlv: Add `Wd` flag This change adds `Wd` flag which specify working directory of the program which launched by debugger. Fixes #295 * only set the Linux working directory if it is set, stub out param in darwin and windows * set working directory for Windows https://godoc.org/golang.org/x/sys/windows#CreateProcess https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx * Windows workingDir must be an *uint16 * attempt to chdir on darwin via @yuntan * proc/exec_darwin.c: fix working directory for darwin * Add tests to check if working directory works. * Fix darwin implementation of fork/exec, which paniced if child fork returned. * cmd, service: rename Wd to WorkingDir
This commit is contained in:
parent
f62bf8d1e3
commit
4064d6acc0
15
_fixtures/workdir.go
Normal file
15
_fixtures/workdir.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println(pwd)
|
||||||
|
}
|
@ -39,6 +39,8 @@ var (
|
|||||||
InitFile string
|
InitFile string
|
||||||
// BuildFlags is the flags passed during compiler invocation.
|
// BuildFlags is the flags passed during compiler invocation.
|
||||||
BuildFlags string
|
BuildFlags string
|
||||||
|
// WorkingDir is the working directory for running the program.
|
||||||
|
WorkingDir string
|
||||||
|
|
||||||
// RootCommand is the root of the command tree.
|
// RootCommand is the root of the command tree.
|
||||||
RootCommand *cobra.Command
|
RootCommand *cobra.Command
|
||||||
@ -86,6 +88,7 @@ func New() *cobra.Command {
|
|||||||
RootCommand.PersistentFlags().IntVar(&APIVersion, "api-version", 1, "Selects API version when headless.")
|
RootCommand.PersistentFlags().IntVar(&APIVersion, "api-version", 1, "Selects API version when headless.")
|
||||||
RootCommand.PersistentFlags().StringVar(&InitFile, "init", "", "Init file, executed by the terminal client.")
|
RootCommand.PersistentFlags().StringVar(&InitFile, "init", "", "Init file, executed by the terminal client.")
|
||||||
RootCommand.PersistentFlags().StringVar(&BuildFlags, "build-flags", buildFlagsDefault, "Build flags, to be passed to the compiler.")
|
RootCommand.PersistentFlags().StringVar(&BuildFlags, "build-flags", buildFlagsDefault, "Build flags, to be passed to the compiler.")
|
||||||
|
RootCommand.PersistentFlags().StringVar(&WorkingDir, "wd", ".", "Working directory for running the program.")
|
||||||
|
|
||||||
// 'attach' subcommand.
|
// 'attach' subcommand.
|
||||||
attachCommand := &cobra.Command{
|
attachCommand := &cobra.Command{
|
||||||
@ -231,8 +234,12 @@ func debugCmd(cmd *cobra.Command, args []string) {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer os.Remove(fp)
|
defer os.Remove(fp)
|
||||||
|
abs, err := filepath.Abs(debugname)
|
||||||
processArgs := append([]string{"./" + debugname}, targetArgs...)
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
processArgs := append([]string{abs}, targetArgs...)
|
||||||
return execute(0, processArgs, conf, executingGeneratedFile)
|
return execute(0, processArgs, conf, executingGeneratedFile)
|
||||||
}()
|
}()
|
||||||
os.Exit(status)
|
os.Exit(status)
|
||||||
@ -275,6 +282,7 @@ func traceCmd(cmd *cobra.Command, args []string) {
|
|||||||
ProcessArgs: processArgs,
|
ProcessArgs: processArgs,
|
||||||
AttachPid: traceAttachPid,
|
AttachPid: traceAttachPid,
|
||||||
APIVersion: 2,
|
APIVersion: 2,
|
||||||
|
WorkingDir: WorkingDir,
|
||||||
}, Log)
|
}, Log)
|
||||||
if err := server.Run(); err != nil {
|
if err := server.Run(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
@ -398,6 +406,7 @@ func execute(attachPid int, processArgs []string, conf *config.Config, kind exec
|
|||||||
AttachPid: attachPid,
|
AttachPid: attachPid,
|
||||||
AcceptMulti: AcceptMulti,
|
AcceptMulti: AcceptMulti,
|
||||||
APIVersion: APIVersion,
|
APIVersion: APIVersion,
|
||||||
|
WorkingDir: WorkingDir,
|
||||||
}, Log)
|
}, Log)
|
||||||
default:
|
default:
|
||||||
fmt.Println("Unknown API version %d", APIVersion)
|
fmt.Println("Unknown API version %d", APIVersion)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "exec_darwin.h"
|
#include "exec_darwin.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
extern char** environ;
|
extern char** environ;
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ close_exec_pipe(int fd[2]) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
fork_exec(char *argv0, char **argv, int size,
|
fork_exec(char *argv0, char **argv, int size,
|
||||||
|
char *wd,
|
||||||
task_t *task,
|
task_t *task,
|
||||||
mach_port_t *port_set,
|
mach_port_t *port_set,
|
||||||
mach_port_t *exception_port,
|
mach_port_t *exception_port,
|
||||||
@ -53,7 +55,7 @@ fork_exec(char *argv0, char **argv, int size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fork succeeded, we are in the child.
|
// Fork succeeded, we are in the child.
|
||||||
int pret;
|
int pret, cret;
|
||||||
char sig;
|
char sig;
|
||||||
|
|
||||||
close(fd[1]);
|
close(fd[1]);
|
||||||
@ -62,7 +64,8 @@ fork_exec(char *argv0, char **argv, int size,
|
|||||||
|
|
||||||
// Create a new process group.
|
// Create a new process group.
|
||||||
if (setpgid(0, 0) < 0) {
|
if (setpgid(0, 0) < 0) {
|
||||||
return -1;
|
perror("setpgid");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set errno to zero before a call to ptrace.
|
// Set errno to zero before a call to ptrace.
|
||||||
@ -70,11 +73,29 @@ fork_exec(char *argv0, char **argv, int size,
|
|||||||
// for successful calls.
|
// for successful calls.
|
||||||
errno = 0;
|
errno = 0;
|
||||||
pret = ptrace(PT_TRACE_ME, 0, 0, 0);
|
pret = ptrace(PT_TRACE_ME, 0, 0, 0);
|
||||||
if (pret != 0 && errno != 0) return -errno;
|
if (pret != 0 && errno != 0) {
|
||||||
|
perror("ptrace");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change working directory if wd is not empty.
|
||||||
|
if (wd && wd[0]) {
|
||||||
|
errno = 0;
|
||||||
|
cret = chdir(wd);
|
||||||
|
if (cret != 0 && errno != 0) {
|
||||||
|
char *error_msg;
|
||||||
|
asprintf(&error_msg, "%s '%s'", "chdir", wd);
|
||||||
|
perror(error_msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
pret = ptrace(PT_SIGEXC, 0, 0, 0);
|
pret = ptrace(PT_SIGEXC, 0, 0, 0);
|
||||||
if (pret != 0 && errno != 0) return -errno;
|
if (pret != 0 && errno != 0) {
|
||||||
|
perror("ptrace");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the child process.
|
// Create the child process.
|
||||||
execve(argv0, argv, environ);
|
execve(argv0, argv, environ);
|
||||||
|
@ -7,4 +7,4 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
fork_exec(char *, char **, int, task_t*, mach_port_t*, mach_port_t*, mach_port_t*);
|
fork_exec(char *, char **, int, char *, task_t*, mach_port_t*, mach_port_t*, mach_port_t*);
|
||||||
|
@ -37,12 +37,11 @@ type OSProcessDetails struct {
|
|||||||
// custom fork/exec process in order to take advantage of
|
// custom fork/exec process in order to take advantage of
|
||||||
// PT_SIGEXC on Darwin which will turn Unix signals into
|
// PT_SIGEXC on Darwin which will turn Unix signals into
|
||||||
// Mach exceptions.
|
// Mach exceptions.
|
||||||
func Launch(cmd []string) (*Process, error) {
|
func Launch(cmd []string, wd string) (*Process, error) {
|
||||||
// check that the argument to Launch is an executable file
|
// check that the argument to Launch is an executable file
|
||||||
if fi, staterr := os.Stat(cmd[0]); staterr == nil && (fi.Mode()&0111) == 0 {
|
if fi, staterr := os.Stat(cmd[0]); staterr == nil && (fi.Mode()&0111) == 0 {
|
||||||
return nil, NotExecutableErr
|
return nil, NotExecutableErr
|
||||||
}
|
}
|
||||||
|
|
||||||
argv0Go, err := filepath.Abs(cmd[0])
|
argv0Go, err := filepath.Abs(cmd[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -69,6 +68,7 @@ func Launch(cmd []string) (*Process, error) {
|
|||||||
var pid int
|
var pid int
|
||||||
dbp.execPtraceFunc(func() {
|
dbp.execPtraceFunc(func() {
|
||||||
ret := C.fork_exec(argv0, &argvSlice[0], C.int(len(argvSlice)),
|
ret := C.fork_exec(argv0, &argvSlice[0], C.int(len(argvSlice)),
|
||||||
|
C.CString(wd),
|
||||||
&dbp.os.task, &dbp.os.portSet, &dbp.os.exceptionPort,
|
&dbp.os.task, &dbp.os.portSet, &dbp.os.exceptionPort,
|
||||||
&dbp.os.notificationPort)
|
&dbp.os.notificationPort)
|
||||||
pid = int(ret)
|
pid = int(ret)
|
||||||
|
@ -45,8 +45,8 @@ type OSProcessDetails struct {
|
|||||||
|
|
||||||
// Launch creates and begins debugging a new process. First entry in
|
// Launch creates and begins debugging a new process. First entry in
|
||||||
// `cmd` is the program to run, and then rest are the arguments
|
// `cmd` is the program to run, and then rest are the arguments
|
||||||
// to be supplied to that process.
|
// to be supplied to that process. `wd` is working directory of the program.
|
||||||
func Launch(cmd []string) (*Process, error) {
|
func Launch(cmd []string, wd string) (*Process, error) {
|
||||||
var (
|
var (
|
||||||
proc *exec.Cmd
|
proc *exec.Cmd
|
||||||
err error
|
err error
|
||||||
@ -62,6 +62,9 @@ func Launch(cmd []string) (*Process, error) {
|
|||||||
proc.Stdout = os.Stdout
|
proc.Stdout = os.Stdout
|
||||||
proc.Stderr = os.Stderr
|
proc.Stderr = os.Stderr
|
||||||
proc.SysProcAttr = &syscall.SysProcAttr{Ptrace: true, Setpgid: true}
|
proc.SysProcAttr = &syscall.SysProcAttr{Ptrace: true, Setpgid: true}
|
||||||
|
if wd != "" {
|
||||||
|
proc.Dir = wd
|
||||||
|
}
|
||||||
err = proc.Start()
|
err = proc.Start()
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -33,7 +33,7 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
func withTestProcess(name string, t testing.TB, fn func(p *Process, fixture protest.Fixture)) {
|
func withTestProcess(name string, t testing.TB, fn func(p *Process, fixture protest.Fixture)) {
|
||||||
fixture := protest.BuildFixture(name)
|
fixture := protest.BuildFixture(name)
|
||||||
p, err := Launch([]string{fixture.Path})
|
p, err := Launch([]string{fixture.Path}, ".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Launch():", err)
|
t.Fatal("Launch():", err)
|
||||||
}
|
}
|
||||||
@ -46,9 +46,9 @@ func withTestProcess(name string, t testing.TB, fn func(p *Process, fixture prot
|
|||||||
fn(p, fixture)
|
fn(p, fixture)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withTestProcessArgs(name string, t testing.TB, fn func(p *Process, fixture protest.Fixture), args []string) {
|
func withTestProcessArgs(name string, t testing.TB, wd string, fn func(p *Process, fixture protest.Fixture), args []string) {
|
||||||
fixture := protest.BuildFixture(name)
|
fixture := protest.BuildFixture(name)
|
||||||
p, err := Launch(append([]string{fixture.Path}, args...))
|
p, err := Launch(append([]string{fixture.Path}, args...), wd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Launch():", err)
|
t.Fatal("Launch():", err)
|
||||||
}
|
}
|
||||||
@ -1739,17 +1739,17 @@ func TestCmdLineArgs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make sure multiple arguments (including one with spaces) are passed to the binary correctly
|
// make sure multiple arguments (including one with spaces) are passed to the binary correctly
|
||||||
withTestProcessArgs("testargs", t, expectSuccess, []string{"test"})
|
withTestProcessArgs("testargs", t, ".", expectSuccess, []string{"test"})
|
||||||
withTestProcessArgs("testargs", t, expectSuccess, []string{"test", "pass flag"})
|
withTestProcessArgs("testargs", t, ".", expectSuccess, []string{"test", "pass flag"})
|
||||||
// check that arguments with spaces are *only* passed correctly when correctly called
|
// check that arguments with spaces are *only* passed correctly when correctly called
|
||||||
withTestProcessArgs("testargs", t, expectPanic, []string{"test pass", "flag"})
|
withTestProcessArgs("testargs", t, ".", expectPanic, []string{"test pass", "flag"})
|
||||||
withTestProcessArgs("testargs", t, expectPanic, []string{"test", "pass", "flag"})
|
withTestProcessArgs("testargs", t, ".", expectPanic, []string{"test", "pass", "flag"})
|
||||||
withTestProcessArgs("testargs", t, expectPanic, []string{"test pass flag"})
|
withTestProcessArgs("testargs", t, ".", expectPanic, []string{"test pass flag"})
|
||||||
// and that invalid cases (wrong arguments or no arguments) panic
|
// and that invalid cases (wrong arguments or no arguments) panic
|
||||||
withTestProcess("testargs", t, expectPanic)
|
withTestProcess("testargs", t, expectPanic)
|
||||||
withTestProcessArgs("testargs", t, expectPanic, []string{"invalid"})
|
withTestProcessArgs("testargs", t, ".", expectPanic, []string{"invalid"})
|
||||||
withTestProcessArgs("testargs", t, expectPanic, []string{"test", "invalid"})
|
withTestProcessArgs("testargs", t, ".", expectPanic, []string{"test", "invalid"})
|
||||||
withTestProcessArgs("testargs", t, expectPanic, []string{"invalid", "pass flag"})
|
withTestProcessArgs("testargs", t, ".", expectPanic, []string{"invalid", "pass flag"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue462(t *testing.T) {
|
func TestIssue462(t *testing.T) {
|
||||||
@ -1872,7 +1872,7 @@ func TestIssue509(t *testing.T) {
|
|||||||
cmd.Dir = nomaindir
|
cmd.Dir = nomaindir
|
||||||
assertNoError(cmd.Run(), t, "go build")
|
assertNoError(cmd.Run(), t, "go build")
|
||||||
exepath := filepath.Join(nomaindir, "debug")
|
exepath := filepath.Join(nomaindir, "debug")
|
||||||
_, err := Launch([]string{exepath})
|
_, err := Launch([]string{exepath}, ".")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected error but none was generated")
|
t.Fatalf("expected error but none was generated")
|
||||||
}
|
}
|
||||||
@ -1906,7 +1906,7 @@ func TestUnsupportedArch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.Remove(outfile)
|
defer os.Remove(outfile)
|
||||||
|
|
||||||
p, err := Launch([]string{outfile})
|
p, err := Launch([]string{outfile}, ".")
|
||||||
switch err {
|
switch err {
|
||||||
case UnsupportedArchErr:
|
case UnsupportedArchErr:
|
||||||
// all good
|
// all good
|
||||||
@ -2306,3 +2306,23 @@ func TestStepOutPanicAndDirectCall(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWorkDir(t *testing.T) {
|
||||||
|
wd := os.TempDir()
|
||||||
|
// For Darwin `os.TempDir()` returns `/tmp` which is symlink to `/private/tmp`.
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
wd = "/private/tmp"
|
||||||
|
}
|
||||||
|
withTestProcessArgs("workdir", t, wd, func(p *Process, fixture protest.Fixture) {
|
||||||
|
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 14)
|
||||||
|
assertNoError(err, t, "LineToPC")
|
||||||
|
p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||||
|
p.Continue()
|
||||||
|
v, err := evalVariable(p, "pwd")
|
||||||
|
assertNoError(err, t, "EvalVariable")
|
||||||
|
str := constant.StringVal(v.Value)
|
||||||
|
if wd != str {
|
||||||
|
t.Fatalf("Expected %s got %s\n", wd, str)
|
||||||
|
}
|
||||||
|
}, []string{})
|
||||||
|
}
|
||||||
|
@ -26,7 +26,7 @@ type OSProcessDetails struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Launch creates and begins debugging a new process.
|
// Launch creates and begins debugging a new process.
|
||||||
func Launch(cmd []string) (*Process, error) {
|
func Launch(cmd []string, wd string) (*Process, error) {
|
||||||
argv0Go, err := filepath.Abs(cmd[0])
|
argv0Go, err := filepath.Abs(cmd[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -82,6 +82,13 @@ func Launch(cmd []string) (*Process, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var workingDir *uint16
|
||||||
|
if wd != "" {
|
||||||
|
if workingDir, err = syscall.UTF16PtrFromString(wd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the startup info and create process
|
// Initialize the startup info and create process
|
||||||
si := new(sys.StartupInfo)
|
si := new(sys.StartupInfo)
|
||||||
@ -94,7 +101,11 @@ func Launch(cmd []string) (*Process, error) {
|
|||||||
|
|
||||||
dbp := New(0)
|
dbp := New(0)
|
||||||
dbp.execPtraceFunc(func() {
|
dbp.execPtraceFunc(func() {
|
||||||
err = sys.CreateProcess(argv0, cmdLine, nil, nil, true, _DEBUG_ONLY_THIS_PROCESS, nil, nil, si, pi)
|
if wd == "" {
|
||||||
|
err = sys.CreateProcess(argv0, cmdLine, nil, nil, true, _DEBUG_ONLY_THIS_PROCESS, nil, nil, si, pi)
|
||||||
|
} else {
|
||||||
|
err = sys.CreateProcess(argv0, cmdLine, nil, nil, true, _DEBUG_ONLY_THIS_PROCESS, nil, workingDir, si, pi)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -13,6 +13,10 @@ type Config struct {
|
|||||||
Listener net.Listener
|
Listener net.Listener
|
||||||
// ProcessArgs are the arguments to launch a new process.
|
// ProcessArgs are the arguments to launch a new process.
|
||||||
ProcessArgs []string
|
ProcessArgs []string
|
||||||
|
// WorkingDir is working directory of the new process. This field is used
|
||||||
|
// only when launching a new process.
|
||||||
|
WorkingDir string
|
||||||
|
|
||||||
// AttachPid is the PID of an existing process to which the debugger should
|
// AttachPid is the PID of an existing process to which the debugger should
|
||||||
// attach.
|
// attach.
|
||||||
AttachPid int
|
AttachPid int
|
||||||
|
@ -38,6 +38,10 @@ type Debugger struct {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
// ProcessArgs are the arguments to launch a new process.
|
// ProcessArgs are the arguments to launch a new process.
|
||||||
ProcessArgs []string
|
ProcessArgs []string
|
||||||
|
// WorkingDir is working directory of the new process. This field is used
|
||||||
|
// only when launching a new process.
|
||||||
|
WorkingDir string
|
||||||
|
|
||||||
// AttachPid is the PID of an existing process to which the debugger should
|
// AttachPid is the PID of an existing process to which the debugger should
|
||||||
// attach.
|
// attach.
|
||||||
AttachPid int
|
AttachPid int
|
||||||
@ -59,7 +63,7 @@ func New(config *Config) (*Debugger, error) {
|
|||||||
d.process = p
|
d.process = p
|
||||||
} else {
|
} else {
|
||||||
log.Printf("launching process with args: %v", d.config.ProcessArgs)
|
log.Printf("launching process with args: %v", d.config.ProcessArgs)
|
||||||
p, err := proc.Launch(d.config.ProcessArgs)
|
p, err := proc.Launch(d.config.ProcessArgs, d.config.WorkingDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != proc.NotExecutableErr && err != proc.UnsupportedArchErr {
|
if err != proc.NotExecutableErr && err != proc.UnsupportedArchErr {
|
||||||
err = fmt.Errorf("could not launch process: %s", err)
|
err = fmt.Errorf("could not launch process: %s", err)
|
||||||
@ -112,7 +116,7 @@ func (d *Debugger) Restart() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p, err := proc.Launch(d.config.ProcessArgs)
|
p, err := proc.Launch(d.config.ProcessArgs, d.config.WorkingDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not launch process: %s", err)
|
return fmt.Errorf("could not launch process: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,7 @@ func (s *ServerImpl) Run() error {
|
|||||||
if s.debugger, err = debugger.New(&debugger.Config{
|
if s.debugger, err = debugger.New(&debugger.Config{
|
||||||
ProcessArgs: s.config.ProcessArgs,
|
ProcessArgs: s.config.ProcessArgs,
|
||||||
AttachPid: s.config.AttachPid,
|
AttachPid: s.config.AttachPid,
|
||||||
|
WorkingDir: s.config.WorkingDir,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ 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)
|
||||||
p, err := proc.Launch([]string{fixture.Path})
|
p, err := proc.Launch([]string{fixture.Path}, ".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Launch():", err)
|
t.Fatal("Launch():", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user