New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix process hangs when daemon starts #373

Merged
merged 1 commit into from Jul 4, 2017

Conversation

Projects
None yet
2 participants
@xofyarg
Contributor

xofyarg commented Jun 30, 2017

The parent hangs on syscall When creating daemon from client. Instead,
use highlevel interface to bring daemon up.

return errors.New("cannot find elvish: " + err.Error())
}
binPath = result
if !filepath.IsAbs(binPath) {

This comment has been minimized.

@xiaq

xiaq Jul 2, 2017

Member

I feel that it is better to use the homegrown searching utility (util.Search) in place of exec.LookPath in consistency with the rest of Elvish.

binPath = result
if !filepath.IsAbs(binPath) {
var err error
binPath, err = exec.LookPath(os.Args[0])

This comment has been minimized.

@xiaq

xiaq Jul 2, 2017

Member

The original code has the upside of not crashing when size of os.Args is 0 :).

Also, when Elvish is used as a login shell, os.Args[0] contains -elvish, and this code will search -elvish instead of elvish.

I think the original code is fine here...

"-sock", d.SockPath,
"-logprefix", d.LogPathPrefix,
)
return cmd.Run()

This comment has been minimized.

@xiaq

xiaq Jul 2, 2017

Member

I think it's better to understand what is happening under the scene than using a different interface to do the job :) According to the doc cmd.Run waits for the subprocess to terminate, that is probably some step we should add.

This comment has been minimized.

@xofyarg

xofyarg Jul 2, 2017

Contributor

I think it's better to understand what is happening under the scene than using a different interface to do the job :)

Agreed. The point here is, trying not to re-invent the wheel by using high level API when possible since it is not recommended to use "syscall" package directly according to its doc.

A quick gdb showed the daemon was stuck during the syscall, which remind me to check the flags done internally by exec.Command.

(gdb) bt
#0  syscall.Syscall () at /usr/lib/go-1.8/src/syscall/asm_linux_amd64.s:27
#1  0x000000000047e516 in syscall.readlen (fd=1, p=0xc420125ae0 "", np=8, n=13, err=...) at /usr/lib/go-1.8/src/syscall/zsyscall_linux_amd64.go:1085
#2  0x0000000000478313 in syscall.forkExec (argv0=..., argv=..., attr=0xc420125da0, pid=10, err=...) at /usr/lib/go-1.8/src/syscall/exec_unix.go:202
#3  0x0000000000478754 in syscall.ForkExec (argv0=..., argv=..., attr=0xc420125da0, pid=140729429880769, err=...)
    at /usr/lib/go-1.8/src/syscall/exec_unix.go:235
#4  0x0000000000541bfa in github.com/elves/elvish/daemon.forkExec (attr=0xc420125da0, forkLevel=1, binPath=..., dbPath=..., sockPath=..., logPathPrefix=...,
    ~r6=...) at /home/go/src/github.com/elves/elvish/daemon/daemon.go:120
#5  0x0000000000541a78 in github.com/elves/elvish/daemon.(*Daemon).pseudoFork (d=0xc4201145f0, attr=0xc420125da0, ~r1=842351593000)
    at /home/go/src/github.com/elves/elvish/.build/src/github.com/elves/elvish/daemon/daemon.go:104
#6  0x000000000054173a in github.com/elves/elvish/daemon.(*Daemon).Main (d=0xc4201145f0, serve={void (struct string, struct string)} 0xc420125e48,
    ~r1=14689824) at /home/go/src/github.com/elves/elvish/daemon/daemon.go:67
#7  0x0000000000816869 in main.main () at /home/go/src/github.com/elves/elvish/main.go:121

This comment has been minimized.

@xiaq

xiaq Jul 2, 2017

Member

It's probably best to use the os/exec interface to implement forkExec.

This comment has been minimized.

@xofyarg

xofyarg Jul 3, 2017

Contributor

Deal. Using os.StartProcess instead to fully close stdin/stdout/stderr.

@xofyarg xofyarg force-pushed the xofyarg:daemon-hang branch 2 times, most recently from dd325b7 to 7f5365b Jul 2, 2017

// pseudoFork forks a daemon. It is supposed to be called from the daemon.
func (d *Daemon) pseudoFork(attr *syscall.ProcAttr) int {
err := forkExec(attr, d.Forked+1, d.BinPath, d.DbPath, d.SockPath, d.LogPathPrefix)
p, err := os.StartProcess(binPath, []string{

This comment has been minimized.

@xiaq

xiaq Jul 3, 2017

Member

This is repeated below; please make it a function.

Fix process hangs when daemon starts
The parent hangs on syscall When creating daemon from client. Instead,
use highlevel interface to bring daemon up.

@xofyarg xofyarg force-pushed the xofyarg:daemon-hang branch from 7f5365b to 1ae564a Jul 3, 2017

@xiaq xiaq merged commit 1b7dc43 into elves:master Jul 4, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment