internal/fakecgo: remove clang mmap bug workaround (#432)
The workaround for clang's mmap is not necessary because fakecgo is not built with clang. Anyway, I just removed that code from runtine/cgo, clang 3.8 was shipped ten years ago. See https://go-review.googlesource.com/c/go/+/745662.
- commit
- 5110604b3385278be6887d0feead513a1bfe7a82
- author
- Quim Muntal · · 2026-03-05 13:19 UTC
- committer
- GitHub · · 2026-03-05 13:19 UTC
- parent
- 6e7b934
- signature
- GPG Unverified
B5690EEEBB952194The key is unknown
3 files · +12 -75
M internal/fakecgo/go_freebsd.go +4 -25
| @@ -67,34 +67,13 @@ var setg_func uintptr | |||
| 67 | 67 | //go:nosplit | |
| 68 | 68 | func x_cgo_init(g *G, setg uintptr) { | |
| 69 | 69 | var size size_t | |
| 70 | - | var attr *pthread_attr_t | |
| 71 | - | ||
| 72 | - | /* The memory sanitizer distributed with versions of clang | |
| 73 | - | before 3.8 has a bug: if you call mmap before malloc, mmap | |
| 74 | - | may return an address that is later overwritten by the msan | |
| 75 | - | library. Avoid this problem by forcing a call to malloc | |
| 76 | - | here, before we ever call malloc. | |
| 77 | - | ||
| 78 | - | This is only required for the memory sanitizer, so it's | |
| 79 | - | unfortunate that we always run it. It should be possible | |
| 80 | - | to remove this when we no longer care about versions of | |
| 81 | - | clang before 3.8. The test for this is | |
| 82 | - | misc/cgo/testsanitizers. | |
| 83 | - | ||
| 84 | - | GCC works hard to eliminate a seemingly unnecessary call to | |
| 85 | - | malloc, so we actually use the memory we allocate. */ | |
| 70 | + | var attr pthread_attr_t | |
| 86 | 71 | ||
| 87 | 72 | setg_func = setg | |
| 88 | - | attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) | |
| 89 | - | if attr == nil { | |
| 90 | - | println("fakecgo: malloc failed") | |
| 91 | - | abort() | |
| 92 | - | } | |
| 93 | - | pthread_attr_init(attr) | |
| 94 | - | pthread_attr_getstacksize(attr, &size) | |
| 73 | + | pthread_attr_init(&attr) | |
| 74 | + | pthread_attr_getstacksize(&attr, &size) | |
| 95 | 75 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | |
| 96 | 76 | // but this should be OK since we are taking the address of the first variable in this function. | |
| 97 | 77 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | |
| 98 | - | pthread_attr_destroy(attr) | |
| 99 | - | free(unsafe.Pointer(attr)) | |
| 78 | + | pthread_attr_destroy(&attr) | |
| 100 | 79 | } | |
| @@ -67,34 +67,13 @@ var setg_func uintptr | |||||
| 67 | //go:nosplit | 67 | //go:nosplit | ||
| 68 | func x_cgo_init(g *G, setg uintptr) { | 68 | func x_cgo_init(g *G, setg uintptr) { | ||
| 69 | var size size_t | 69 | var size size_t | ||
| 70 | - | var attr *pthread_attr_t | 70 | + | var attr pthread_attr_t |
| 71 | - | ||||
| 72 | - | /* The memory sanitizer distributed with versions of clang | |||
| 73 | - | before 3.8 has a bug: if you call mmap before malloc, mmap | |||
| 74 | - | may return an address that is later overwritten by the msan | |||
| 75 | - | library. Avoid this problem by forcing a call to malloc | |||
| 76 | - | here, before we ever call malloc. | |||
| 77 | - | ||||
| 78 | - | This is only required for the memory sanitizer, so it's | |||
| 79 | - | unfortunate that we always run it. It should be possible | |||
| 80 | - | to remove this when we no longer care about versions of | |||
| 81 | - | clang before 3.8. The test for this is | |||
| 82 | - | misc/cgo/testsanitizers. | |||
| 83 | - | ||||
| 84 | - | GCC works hard to eliminate a seemingly unnecessary call to | |||
| 85 | - | malloc, so we actually use the memory we allocate. */ | |||
| 86 | 71 | ||||
| 87 | setg_func = setg | 72 | setg_func = setg | ||
| 88 | - | attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) | 73 | + | pthread_attr_init(&attr) |
| 89 | - | if attr == nil { | 74 | + | pthread_attr_getstacksize(&attr, &size) |
| 90 | - | println("fakecgo: malloc failed") | |||
| 91 | - | abort() | |||
| 92 | - | } | |||
| 93 | - | pthread_attr_init(attr) | |||
| 94 | - | pthread_attr_getstacksize(attr, &size) | |||
| 95 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | 75 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | ||
| 96 | // but this should be OK since we are taking the address of the first variable in this function. | 76 | // but this should be OK since we are taking the address of the first variable in this function. | ||
| 97 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | 77 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | ||
| 98 | - | pthread_attr_destroy(attr) | 78 | + | pthread_attr_destroy(&attr) |
| 99 | - | free(unsafe.Pointer(attr)) | |||
| 100 | } | 79 | } | ||
M internal/fakecgo/go_linux.go +4 -25
| @@ -67,34 +67,13 @@ var setg_func uintptr | |||
| 67 | 67 | //go:nosplit | |
| 68 | 68 | func x_cgo_init(g *G, setg uintptr) { | |
| 69 | 69 | var size size_t | |
| 70 | - | var attr *pthread_attr_t | |
| 71 | - | ||
| 72 | - | /* The memory sanitizer distributed with versions of clang | |
| 73 | - | before 3.8 has a bug: if you call mmap before malloc, mmap | |
| 74 | - | may return an address that is later overwritten by the msan | |
| 75 | - | library. Avoid this problem by forcing a call to malloc | |
| 76 | - | here, before we ever call malloc. | |
| 77 | - | ||
| 78 | - | This is only required for the memory sanitizer, so it's | |
| 79 | - | unfortunate that we always run it. It should be possible | |
| 80 | - | to remove this when we no longer care about versions of | |
| 81 | - | clang before 3.8. The test for this is | |
| 82 | - | misc/cgo/testsanitizers. | |
| 83 | - | ||
| 84 | - | GCC works hard to eliminate a seemingly unnecessary call to | |
| 85 | - | malloc, so we actually use the memory we allocate. */ | |
| 70 | + | var attr pthread_attr_t | |
| 86 | 71 | ||
| 87 | 72 | setg_func = setg | |
| 88 | - | attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) | |
| 89 | - | if attr == nil { | |
| 90 | - | println("fakecgo: malloc failed") | |
| 91 | - | abort() | |
| 92 | - | } | |
| 93 | - | pthread_attr_init(attr) | |
| 94 | - | pthread_attr_getstacksize(attr, &size) | |
| 73 | + | pthread_attr_init(&attr) | |
| 74 | + | pthread_attr_getstacksize(&attr, &size) | |
| 95 | 75 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | |
| 96 | 76 | // but this should be OK since we are taking the address of the first variable in this function. | |
| 97 | 77 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | |
| 98 | - | pthread_attr_destroy(attr) | |
| 99 | - | free(unsafe.Pointer(attr)) | |
| 78 | + | pthread_attr_destroy(&attr) | |
| 100 | 79 | } | |
| @@ -67,34 +67,13 @@ var setg_func uintptr | |||||
| 67 | //go:nosplit | 67 | //go:nosplit | ||
| 68 | func x_cgo_init(g *G, setg uintptr) { | 68 | func x_cgo_init(g *G, setg uintptr) { | ||
| 69 | var size size_t | 69 | var size size_t | ||
| 70 | - | var attr *pthread_attr_t | 70 | + | var attr pthread_attr_t |
| 71 | - | ||||
| 72 | - | /* The memory sanitizer distributed with versions of clang | |||
| 73 | - | before 3.8 has a bug: if you call mmap before malloc, mmap | |||
| 74 | - | may return an address that is later overwritten by the msan | |||
| 75 | - | library. Avoid this problem by forcing a call to malloc | |||
| 76 | - | here, before we ever call malloc. | |||
| 77 | - | ||||
| 78 | - | This is only required for the memory sanitizer, so it's | |||
| 79 | - | unfortunate that we always run it. It should be possible | |||
| 80 | - | to remove this when we no longer care about versions of | |||
| 81 | - | clang before 3.8. The test for this is | |||
| 82 | - | misc/cgo/testsanitizers. | |||
| 83 | - | ||||
| 84 | - | GCC works hard to eliminate a seemingly unnecessary call to | |||
| 85 | - | malloc, so we actually use the memory we allocate. */ | |||
| 86 | 71 | ||||
| 87 | setg_func = setg | 72 | setg_func = setg | ||
| 88 | - | attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) | 73 | + | pthread_attr_init(&attr) |
| 89 | - | if attr == nil { | 74 | + | pthread_attr_getstacksize(&attr, &size) |
| 90 | - | println("fakecgo: malloc failed") | |||
| 91 | - | abort() | |||
| 92 | - | } | |||
| 93 | - | pthread_attr_init(attr) | |||
| 94 | - | pthread_attr_getstacksize(attr, &size) | |||
| 95 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | 75 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | ||
| 96 | // but this should be OK since we are taking the address of the first variable in this function. | 76 | // but this should be OK since we are taking the address of the first variable in this function. | ||
| 97 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | 77 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | ||
| 98 | - | pthread_attr_destroy(attr) | 78 | + | pthread_attr_destroy(&attr) |
| 99 | - | free(unsafe.Pointer(attr)) | |||
| 100 | } | 79 | } | ||
M internal/fakecgo/go_netbsd.go +4 -25
| @@ -73,34 +73,13 @@ var setg_func uintptr | |||
| 73 | 73 | //go:nosplit | |
| 74 | 74 | func x_cgo_init(g *G, setg uintptr) { | |
| 75 | 75 | var size size_t | |
| 76 | - | var attr *pthread_attr_t | |
| 77 | - | ||
| 78 | - | /* The memory sanitizer distributed with versions of clang | |
| 79 | - | before 3.8 has a bug: if you call mmap before malloc, mmap | |
| 80 | - | may return an address that is later overwritten by the msan | |
| 81 | - | library. Avoid this problem by forcing a call to malloc | |
| 82 | - | here, before we ever call malloc. | |
| 83 | - | ||
| 84 | - | This is only required for the memory sanitizer, so it's | |
| 85 | - | unfortunate that we always run it. It should be possible | |
| 86 | - | to remove this when we no longer care about versions of | |
| 87 | - | clang before 3.8. The test for this is | |
| 88 | - | misc/cgo/testsanitizers. | |
| 89 | - | ||
| 90 | - | GCC works hard to eliminate a seemingly unnecessary call to | |
| 91 | - | malloc, so we actually use the memory we allocate. */ | |
| 76 | + | var attr pthread_attr_t | |
| 92 | 77 | ||
| 93 | 78 | setg_func = setg | |
| 94 | - | attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) | |
| 95 | - | if attr == nil { | |
| 96 | - | println("fakecgo: malloc failed") | |
| 97 | - | abort() | |
| 98 | - | } | |
| 99 | - | pthread_attr_init(attr) | |
| 100 | - | pthread_attr_getstacksize(attr, &size) | |
| 79 | + | pthread_attr_init(&attr) | |
| 80 | + | pthread_attr_getstacksize(&attr, &size) | |
| 101 | 81 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | |
| 102 | 82 | // but this should be OK since we are taking the address of the first variable in this function. | |
| 103 | 83 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | |
| 104 | - | pthread_attr_destroy(attr) | |
| 105 | - | free(unsafe.Pointer(attr)) | |
| 84 | + | pthread_attr_destroy(&attr) | |
| 106 | 85 | } | |
| @@ -73,34 +73,13 @@ var setg_func uintptr | |||||
| 73 | //go:nosplit | 73 | //go:nosplit | ||
| 74 | func x_cgo_init(g *G, setg uintptr) { | 74 | func x_cgo_init(g *G, setg uintptr) { | ||
| 75 | var size size_t | 75 | var size size_t | ||
| 76 | - | var attr *pthread_attr_t | 76 | + | var attr pthread_attr_t |
| 77 | - | ||||
| 78 | - | /* The memory sanitizer distributed with versions of clang | |||
| 79 | - | before 3.8 has a bug: if you call mmap before malloc, mmap | |||
| 80 | - | may return an address that is later overwritten by the msan | |||
| 81 | - | library. Avoid this problem by forcing a call to malloc | |||
| 82 | - | here, before we ever call malloc. | |||
| 83 | - | ||||
| 84 | - | This is only required for the memory sanitizer, so it's | |||
| 85 | - | unfortunate that we always run it. It should be possible | |||
| 86 | - | to remove this when we no longer care about versions of | |||
| 87 | - | clang before 3.8. The test for this is | |||
| 88 | - | misc/cgo/testsanitizers. | |||
| 89 | - | ||||
| 90 | - | GCC works hard to eliminate a seemingly unnecessary call to | |||
| 91 | - | malloc, so we actually use the memory we allocate. */ | |||
| 92 | 77 | ||||
| 93 | setg_func = setg | 78 | setg_func = setg | ||
| 94 | - | attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) | 79 | + | pthread_attr_init(&attr) |
| 95 | - | if attr == nil { | 80 | + | pthread_attr_getstacksize(&attr, &size) |
| 96 | - | println("fakecgo: malloc failed") | |||
| 97 | - | abort() | |||
| 98 | - | } | |||
| 99 | - | pthread_attr_init(attr) | |||
| 100 | - | pthread_attr_getstacksize(attr, &size) | |||
| 101 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | 81 | // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` | ||
| 102 | // but this should be OK since we are taking the address of the first variable in this function. | 82 | // but this should be OK since we are taking the address of the first variable in this function. | ||
| 103 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | 83 | g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 | ||
| 104 | - | pthread_attr_destroy(attr) | 84 | + | pthread_attr_destroy(&attr) |
| 105 | - | free(unsafe.Pointer(attr)) | |||
| 106 | } | 85 | } | ||