Coder Social home page Coder Social logo

Comments (5)

randall77 avatar randall77 commented on May 30, 2024 1

It looks like of the 16 test objects, the 15th one is somehow still reachable even though it shouldn't be.

It is possible that this test is flaky because of conservative scanning of top stack frames. A value on a random stack frame somewhere (probably a dead pointer) that happens to point to the object in question would keep it alive longer than this test expects.

Not sure why it is the 15th object in both cases. Maybe the last mallocgc leaves that pointer somewhere deep on the stack and the subsequent call to gctestIsReachable "adopts" that slot uninitialized in its frame, which then gets scanned. I'm not sure how that failure mode wouldn't be deterministic, though.

In any case, I think this test is kind of fundamentally unsound when conservative scanning exists. Not sure what to do about it.

@aclements who wrote the test, @mknyszek who is deep in this kind of stuff.

from go.

gopherbot avatar gopherbot commented on May 30, 2024

Found new dashboard test flakes for:

#!watchflakes
default <- pkg == "runtime" && test == "TestGCTestIsReachable"
2024-05-06 11:46 android-amd64-emu go@ff0bc466 runtime.TestGCTestIsReachable (log)
--- FAIL: TestGCTestIsReachable (0.03s)
    gc_test.go:282: did not get expected reachable set; want 101010101010101, got 1101010101010101

watchflakes

from go.

randall77 avatar randall77 commented on May 30, 2024

Here's a test that demonstrates the "problem", that GCTestIsReachable can report false positives based on dead pointers in stacks of other conservatively scanned goroutines.

//go:noinline
func writeToStack(p unsafe.Pointer) unsafe.Pointer {
	var x [100]unsafe.Pointer
	for i := range x {
		x[i] = p
	}
	return x[7]
}

//go:noinline
func conservativelyScanned(c chan bool) int {
	// Tell parent that the vulnerable frame is running.
	c <- true

	// Run in a state where GC has to interrupt us to proceed, and thus
	// has to scan us conservatively.
	var s int
	for i := 0; i < 1<<30; i++ {
		s += i * i
	}

	// Tell parent we're done.
	c <- true

	// Allocate a stack frame region that is uninitialized until here.
	// This region overlaps writeToStack.x and thus contains dead copies
	// of the pointer in question during the loop above.
	var x [100]int
	return x[s%len(x)]
}

func TestBadReachable(t *testing.T) {
	s := make([]unsafe.Pointer, 1)
	s[0] = unsafe.Pointer(new(*int))
	c := make(chan bool, 1)
	go func(p unsafe.Pointer) {
		writeToStack(p)
		conservativelyScanned(c)
	}(s[0])

	// Make sure child goroutine is in a state where conservative scanning would find s[0].
	<-c

	got := runtime.GCTestIsReachable(s...)
	if got != 0 {
		t.Fatalf("s[0] is reachable, but shouldn't be")
	}

	// Wait for goroutine to finish
	<-c
}

(Add this to runtime/gc_test.go.)

from go.

mknyszek avatar mknyszek commented on May 30, 2024

Wow, nice reproducer. Maybe we run the test as a testprog (or have the test binary reinvoke itself) and explicitly disable asynchronous preemption via GODEBUG?

from go.

randall77 avatar randall77 commented on May 30, 2024

Yes, a reinvoke might work.
I do worry that if we enshrine GODEBUG=asyncpreemptoff=1 in order to make this test work, then we can never get rid of that debug option. Maybe that's not the end of the world.

from go.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.