Skip to content
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

Accessing a nil *big.Float after v8 is initialized segfaults #38

Closed
konradreiche opened this issue Jan 22, 2019 · 2 comments · Fixed by #40
Closed

Accessing a nil *big.Float after v8 is initialized segfaults #38

konradreiche opened this issue Jan 22, 2019 · 2 comments · Fixed by #40

Comments

@konradreiche
Copy link
Contributor

konradreiche commented Jan 22, 2019

Accessing a nil *big.Float will cause a segfault after v8 has been initialized.

Minimum Example

// main.go
package main

import (
	"fmt"

	"github.com/augustoroman/v8"
	"github.com/konradreiche/v8/crash"
)

func main() {
        var f *big.Float
	fmt.Println(f)
	_ = v8.NewIsolate().NewContext()
        fmt.Println(f)
}

What did I expect?

<nil>
<nil>

What am I seeing instead?

<nil>
Received signal 11 SEGV_MAPERR 000000000000

==== C stack trace ===============================

 [0x000000d24234]
 [0x7fa5afb8ddd0]
 [0x0000004a32a7]
[end of stack trace]
signal: segmentation fault
@konradreiche konradreiche changed the title Accessing a nil *big.Float in internal package after v8 initialized segfaults Accessing a nil *big.Float from a subpackage after v8 is initialized segfaults Jan 22, 2019
@konradreiche konradreiche changed the title Accessing a nil *big.Float from a subpackage after v8 is initialized segfaults Accessing a nil *big.Float after v8 is initialized segfaults Jan 22, 2019
@konradreiche
Copy link
Contributor Author

konradreiche commented Jan 22, 2019

This seems to happen with any type from Go's big package. I traced the problem to the Go formatter code. Somehow, after initializing the v8, the formatter doesn't detect these fields nil types anymore but instead calls the String() method on that nil pointer.

@konradreiche
Copy link
Contributor Author

Before v8 is initialized this code from the Go stdlib is run: https://golang.org/src/fmt/print.go#L530
After, this code is not reached anymore and the segfault happens. Somehow the recover/panic mechanism doesn't work with V8 being initialized.

augustoroman pushed a commit that referenced this issue Jan 30, 2019
This fixes #38 which is more severe that it looks like in the issue. With v8's debug stack trace dumping turned on, the Go signal handling stops working. Go's panic mechanism relies on the SIGSEGV process signal. With v8's stack trace dumping the signal handler of the Go runtime is completely skipped.

This means that dereferencing any nil pointer in Go will result in a C stack trace with no information about the error happening in the Go code whatsoever.

What is worse, Go's formatter intentionally panics when printing nil pointers in order to recover from the panic and print it as <nil> eventually.

Without this change, once v8 is initialized, printing nil pointer will result in a crash. Running this v8 wrapper without this change in a product environment is highly risky.

You can read in more detail about this here http://konradreiche.com/posts/a-cautionary-tale-of-cgo-embedding.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant