I use a lot of recursive closures in my experimental Go project.
And my program terminates with runtime error
SIGSEGV: segmentation violation
The error seems to be in Go runtime (or in Go compiler), because the
calling stacks in running goroutines are not printed.
I wrote a simple stack printer:
func stacktrace(name string) {
ok := true
var line int
fmt.Printf("%s: ", name)
for i := 1; ok; i++ {
if _, _, line, ok = runtime.Caller(i); ok {
fmt.Printf("%d ",line)
}
}
fmt.Printf("\n")
}
It walks through call stack and prints a line number for every
function frame.
I inserted calls to this stacktrace in some points in my code and I
found the place, where calling a closure breaks the stack. The code
looks like this:
...
next := func() {
stacktrace("next")
...
}
...
term = func() {
...
stacktrace("term")
next() // calling "next" breaks the stack
...
}
It outputs the following:
term: 716 677 736 677 736 677 736 677 736 677 736 677 736 677 736 677
736 677 630 616 602 563 538 490 391 349 324 812 140
next: 171
SIGSEGV: segmentation violation
Faulting address: 0x7d400014bb7
PC=0x40cade
(There is closure "term" somewhere deep in the stack, and it calls
closure "next". And suddenly stack becomes broken.)
My project is rather large (about 3500 lines of code), and I can't
reproduce the bug in a little sample :-(
Should I send all the sources to the developers of Go compiler?
Was the original crash also in runtime.Caller, or
were you trying to find a location in your own code
where a different crash happened?
Russ
...
next := func() {
stacktrace("next")
fmt.Printf("stacktrace succeded\n")
...
}
...
term = func() {
...
stacktrace("term")
next() // calling "next" breaks the stack
...
}
it outputs:
term: 717 678 737 678 737 678 737 678 737 678 737 678 737 678 737 678
737 678 631 617 603 564 539 491 392 350 325 813 140
next: 171
stacktrace succeded
SIGSEGV: segmentation violation
Faulting address: 0x7d400014bb7
PC=0x40cade
So it is not the fault of runtime.Caller.
I know the place where crash happens. Closure "next" attemps to use
channel "ts", that contains garbage due to broken stack.
next := func() {
stacktrace("next")
fmt.Printf("stacktrace succeded\n")
tok = <-ts // here we crash
var Ch chan string
and in main
func main (){
....
Ch := logger.Start()//returns a chan string
}
Because of using := to assign the channel, that assignment was only
valid inside of main, everywhere else, it was still uninitialized.
This caused a segfault.
If your channel is predeclared with var, make sure you do not use :=
to assign it
Moreover, as Go is safe language, I can't destroy memory by myself. If
it becomes destroyed, it means there is a bug in Go runtime (or in Go
compiler).
On Mar 3, 6:02 am, Michael Antonelli <michael.k.antone...@gmail.com>
wrote:
Russ