1
0
mirror of https://github.com/golang/go synced 2024-11-16 17:04:41 -07:00

runtime: wait for Go runtime to initialize in Windows signal test

The test harness waits for "ready" as a sign that the Go runtime has
installed its signal handler and is ready to be tested. But actually,
while LoadLibrary starts the loading of the Go runtime, it does so
asynchronously, so the "ready" sign is potentially premature and
certainly racy. However, all exported cgo entry points make a call to
_cgo_wait_runtime_init_done which waits for that asynchronous
initialization to complete. Therefore, this commit fixes the test to
call into the exported "Dummy" cgo function before emitting the "ready"
sign, so that we're sure the Go runtime is actually loaded.

Updates #45638.

Change-Id: I9b12b172d45bdcc09d54dd301de3a3e499544834
Reviewed-on: https://go-review.googlesource.com/c/go/+/321769
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Jason A. Donenfeld 2021-05-21 12:01:39 +02:00
parent 831573cd21
commit 7e63c8b765

View File

@ -19,13 +19,13 @@ int main(void)
{ {
waitForCtrlBreakEvent = CreateEvent(NULL, TRUE, FALSE, NULL); waitForCtrlBreakEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!waitForCtrlBreakEvent) { if (!waitForCtrlBreakEvent) {
fprintf(stderr, "ERROR: Could not create event"); fprintf(stderr, "ERROR: Could not create event\n");
return 1; return 1;
} }
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
{ {
fprintf(stderr, "ERROR: Could not set control handler"); fprintf(stderr, "ERROR: Could not set control handler\n");
return 1; return 1;
} }
@ -34,7 +34,14 @@ int main(void)
// This way the library handler gets called first. // This way the library handler gets called first.
HMODULE dummyDll = LoadLibrary("dummy.dll"); HMODULE dummyDll = LoadLibrary("dummy.dll");
if (!dummyDll) { if (!dummyDll) {
fprintf(stderr, "ERROR: Could not load dummy.dll"); fprintf(stderr, "ERROR: Could not load dummy.dll\n");
return 1;
}
// Call the Dummy function so that Go initialization completes, since
// all cgo entry points call out to _cgo_wait_runtime_init_done.
if (((int(*)(void))GetProcAddress(dummyDll, "Dummy"))() != 42) {
fprintf(stderr, "ERROR: Dummy function did not return 42\n");
return 1; return 1;
} }
@ -42,7 +49,7 @@ int main(void)
fflush(stdout); fflush(stdout);
if (WaitForSingleObject(waitForCtrlBreakEvent, 5000) != WAIT_OBJECT_0) { if (WaitForSingleObject(waitForCtrlBreakEvent, 5000) != WAIT_OBJECT_0) {
fprintf(stderr, "FAILURE: No signal received"); fprintf(stderr, "FAILURE: No signal received\n");
return 1; return 1;
} }