Skip to content

runtime: split stackoverflow on SIGINT + -QUIT + -INT #4836

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

Closed
bradfitz opened this issue Feb 17, 2013 · 6 comments
Closed

runtime: split stackoverflow on SIGINT + -QUIT + -INT #4836

bradfitz opened this issue Feb 17, 2013 · 6 comments

Comments

@bradfitz
Copy link
Contributor

What steps will reproduce the problem?
1. run a fuse daemon on OS X
2. try to catch SIGINT and SIGQUIT (this works on Linux)
3. send SIGINT (nothing)
4. send SIGQUIT (nothing)
5. send SIGINT again (runtime crash)

What is the expected output? What do you see instead?
Graceful shutdown.

2013/02/17 10:42:55 CAMLI StatFS
2013/02/17 10:42:55 Root lookup of "Backups.backupdb" = <nil-BlobRef>
2013/02/17 10:42:55 Root lookup of "mach_kernel" = <nil-BlobRef>
2013/02/17 10:42:55 Root lookup of "Backups.backupdb" = <nil-BlobRef>
2013/02/17 10:42:55 CAMLI StatFS
2013/02/17 10:42:55 Root lookup of "Backups.backupdb" = <nil-BlobRef>
2013/02/17 10:42:55 CAMLI StatFS
2013/02/17 10:42:55 Root lookup of "._." = <nil-BlobRef>
2013/02/17 10:42:55 Root lookup of "._." = <nil-BlobRef>
^C^\^C^\runtime: split stack overflow: 0xc20010cab0 < 0xc20010e000
fatal error: runtime: split stack overflow

goroutine 1 [syscall]:
runtime.entersyscall()
    /Users/bradfitz/go/src/pkg/runtime/proc.c:1052 +0x19a
syscall.Syscall()
    /Users/bradfitz/go/src/pkg/syscall/asm_darwin_amd64.s:14 +0x5
syscall.read(0x4, 0xc20011b000, 0x2000, 0x2000, 0xc20010e3c8, ...)
    /Users/bradfitz/go/src/pkg/syscall/zsyscall_darwin_amd64.go:905 +0x70
syscall.Read(0x4, 0xc20011b000, 0x2000, 0x2000, 0x2000, ...)
    /Users/bradfitz/go/src/pkg/syscall/syscall_unix.go:132 +0x5a
camlistore.org/third_party/code.google.com/p/rsc/fuse.(*Conn).ReadRequest(0xc20010d000,
0xc2000b3e40, 0xc2000bad70, 0xc200119340)
    /Users/bradfitz/src/camlistore.org/third_party/code.google.com/p/rsc/fuse/fuse.go:287 +0xe3
----- stack segment boundary -----
camlistore.org/third_party/code.google.com/p/rsc/fuse.(*Conn).Serve(0xc20010d000,
0xc2000b3e40, 0xc2000bad70, 0x0, 0x0, ...)
    /Users/bradfitz/src/camlistore.org/third_party/code.google.com/p/rsc/fuse/serve.go:242 +0x3ba
main.main()
    /Users/bradfitz/src/camlistore.org/cmd/cammount/cammount.go:91 +0x669
runtime.main()
    /Users/bradfitz/go/src/pkg/runtime/proc.c:255 +0x8f
runtime.goexit()
    /Users/bradfitz/go/src/pkg/runtime/proc.c:284

goroutine 3 [syscall]:
os/signal.loop()
    /Users/bradfitz/go/src/pkg/os/signal/signal_unix.go:20 +0x1c
created by os/signal.init·1
    /Users/bradfitz/go/src/pkg/os/signal/signal_unix.go:26 +0x2f

goroutine 4 [chan receive]:
main.func·002(0xc2000b6438, 0x0)
    /Users/bradfitz/src/camlistore.org/cmd/cammount/cammount.go:83 +0x31
created by main.main
    /Users/bradfitz/src/camlistore.org/cmd/cammount/cammount.go:84 +0x47e
ba12:~ bradfitz$ 
ba12:~ bradfitz$ 
ba12:~ bradfitz$ 
ba12:~ bradfitz$ 


$ go version
go version devel +bad13530d9b3 Fri Feb 08 09:20:05 2013 -0800 darwin/amd64


Whittling down Camlistore's cammount program, this should reproduce it:  (FUSE crashing
seems to have wedged this machine, so I can't test until I've rebooted...)

$ cat splitstack.go
package main

import (
    "io/ioutil"
    "log"
    "os"
    "os/signal"
    "syscall"

    "camlistore.org/third_party/code.google.com/p/rsc/fuse"
)

func main() {
    dir, err := ioutil.TempDir("", "")
    if err != nil {
        log.Fatal(err)
    }

    sigc := make(chan os.Signal, 1)
    go func() {
        log.Fatalf("Signal %s received, shutting down.", <-sigc)
    }()
    signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM)

    conn, err := fuse.Mount(dir)
    if err != nil {
        log.Fatalf("Mount: %v", err)
    }

    err = conn.Serve(fs{})
    if err != nil {
        log.Fatalf("Serve: %v", err)
    }
    log.Printf("fuse process ending.")
}

type fs struct{}

func (fs) Root() (fuse.Node, fuse.Error) {
    return fs{}, nil
}

func (fs) Attr() fuse.Attr {
    return fuse.Attr{
        Mode: os.ModeDir | 0700,
        Uid:  uint32(os.Getuid()),
        Gid:  uint32(os.Getgid()),
    }
}

func (fs) ReadDir(intr fuse.Intr) ([]fuse.Dirent, fuse.Error) {
    return []fuse.Dirent{{Name: "Hello FUSE"}}, nil
}
@rsc
Copy link
Contributor

rsc commented Feb 19, 2013

Comment 1:

Is it possible to reproduce without FUSE?

@bradfitz
Copy link
Contributor Author

Comment 2:

I haven't tried, and I don't have a Mac with me right now.
I wanted to file before I forgot.

@rsc
Copy link
Contributor

rsc commented Feb 19, 2013

Comment 3:

I tried the test program but it doesn't respond to any signals at all. I
had to kill -9 it.
I wonder if serving FUSE makes the kernel disable signals or something like
that.
But it still doesn't explain the split stack overflow you saw.

@bradfitz
Copy link
Contributor Author

Comment 4:

Maybe that example is too minimal. I could reproduce it 100% consistently the other day
with the full program.
Let me get back to you later when I'm at a Mac.

@rsc
Copy link
Contributor

rsc commented Mar 12, 2013

Comment 5:

[The time for maybe has passed.]

Labels changed: removed go1.1maybe.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 6:

If this happens again please file a new issue. We should have more information in the
crash now.

Status changed to Invalid.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants