diff --git a/src/runtime/asan.go b/src/runtime/asan.go index adef8fa7bf..32d5f45225 100644 --- a/src/runtime/asan.go +++ b/src/runtime/asan.go @@ -64,6 +64,9 @@ func asanregisterglobals(addr unsafe.Pointer, n uintptr) //go:noescape func lsanregisterrootregion(addr unsafe.Pointer, n uintptr) +//go:noescape +func lsanunregisterrootregion(addr unsafe.Pointer, n uintptr) + func lsandoleakcheck() // These are called from asan_GOARCH.s @@ -74,4 +77,5 @@ func lsandoleakcheck() //go:cgo_import_static __asan_poison_go //go:cgo_import_static __asan_register_globals_go //go:cgo_import_static __lsan_register_root_region_go +//go:cgo_import_static __lsan_unregister_root_region_go //go:cgo_import_static __lsan_do_leak_check_go diff --git a/src/runtime/asan/asan.go b/src/runtime/asan/asan.go index efdd911f2b..fefc82b278 100644 --- a/src/runtime/asan/asan.go +++ b/src/runtime/asan/asan.go @@ -39,6 +39,10 @@ void __lsan_register_root_region_go(void *addr, uintptr_t sz) { __lsan_register_root_region(addr, sz); } +void __lsan_unregister_root_region_go(void *addr, uintptr_t sz) { + __lsan_unregister_root_region(addr, sz); +} + void __lsan_do_leak_check_go(void) { __lsan_do_leak_check(); } diff --git a/src/runtime/asan0.go b/src/runtime/asan0.go index eb70367a29..8331653982 100644 --- a/src/runtime/asan0.go +++ b/src/runtime/asan0.go @@ -22,4 +22,5 @@ func asanunpoison(addr unsafe.Pointer, sz uintptr) { throw("asan") } func asanpoison(addr unsafe.Pointer, sz uintptr) { throw("asan") } func asanregisterglobals(addr unsafe.Pointer, sz uintptr) { throw("asan") } func lsanregisterrootregion(unsafe.Pointer, uintptr) { throw("asan") } +func lsanunregisterrootregion(unsafe.Pointer, uintptr) { throw("asan") } func lsandoleakcheck() { throw("asan") } diff --git a/src/runtime/asan_amd64.s b/src/runtime/asan_amd64.s index 3f9df4fec8..30dd477c07 100644 --- a/src/runtime/asan_amd64.s +++ b/src/runtime/asan_amd64.s @@ -77,6 +77,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16 MOVQ $__lsan_register_root_region_go(SB), AX JMP asancall<>(SB) +// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr) +TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16 + MOVQ addr+0(FP), RARG0 + MOVQ n+8(FP), RARG1 + // void __lsan_unregister_root_region_go(void *addr, uintptr_t sz) + MOVQ $__lsan_unregister_root_region_go(SB), AX + JMP asancall<>(SB) + // func runtime·lsandoleakcheck() TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0 // void __lsan_do_leak_check_go(void); diff --git a/src/runtime/asan_arm64.s b/src/runtime/asan_arm64.s index 5447d210e5..1f089d78d3 100644 --- a/src/runtime/asan_arm64.s +++ b/src/runtime/asan_arm64.s @@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16 MOVD $__lsan_register_root_region_go(SB), FARG JMP asancall<>(SB) +// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr) +TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16 + MOVD addr+0(FP), RARG0 + MOVD n+8(FP), RARG1 + // void __lsan_unregister_root_region_go(void *addr, uintptr_t n); + MOVD $__lsan_unregister_root_region_go(SB), FARG + JMP asancall<>(SB) + // func runtime·lsandoleakcheck() TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0 // void __lsan_do_leak_check_go(void); diff --git a/src/runtime/asan_loong64.s b/src/runtime/asan_loong64.s index 3abcf889b8..224d16ce2e 100644 --- a/src/runtime/asan_loong64.s +++ b/src/runtime/asan_loong64.s @@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16 MOVV $__lsan_register_root_region_go(SB), FARG JMP asancall<>(SB) +// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr) +TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16 + MOVV addr+0(FP), RARG0 + MOVV n+8(FP), RARG1 + // void __lsan_unregister_root_region_go(void *addr, uintptr_t n); + MOVV $__lsan_unregister_root_region_go(SB), FARG + JMP asancall<>(SB) + // func runtime·lsandoleakcheck() TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0 // void __lsan_do_leak_check_go(void); diff --git a/src/runtime/asan_ppc64le.s b/src/runtime/asan_ppc64le.s index 2fc5772a28..0c56a81991 100644 --- a/src/runtime/asan_ppc64le.s +++ b/src/runtime/asan_ppc64le.s @@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB),NOSPLIT|NOFRAME,$0-16 MOVD $__lsan_register_root_region_go(SB), FARG BR asancall<>(SB) +// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr) +TEXT runtime·lsanunregisterrootregion(SB),NOSPLIT|NOFRAME,$0-16 + MOVD addr+0(FP), RARG0 + MOVD n+8(FP), RARG1 + // void __lsan_unregister_root_region_go(void *addr, uintptr_t n); + MOVD $__lsan_unregister_root_region_go(SB), FARG + BR asancall<>(SB) + // func runtime·lsandoleakcheck() TEXT runtime·lsandoleakcheck(SB), NOSPLIT|NOFRAME, $0-0 // void __lsan_do_leak_check_go(void); diff --git a/src/runtime/asan_riscv64.s b/src/runtime/asan_riscv64.s index f5ddb21a25..6c77f66348 100644 --- a/src/runtime/asan_riscv64.s +++ b/src/runtime/asan_riscv64.s @@ -60,6 +60,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16 MOV $__lsan_register_root_region_go(SB), X14 JMP asancall<>(SB) +// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr) +TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16 + MOV addr+0(FP), X10 + MOV n+8(FP), X11 + // void __lsan_unregister_root_region_go(void *addr, uintptr_t n); + MOV $__lsan_unregister_root_region_go(SB), X14 + JMP asancall<>(SB) + // func runtime·lsandoleakcheck() TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0 // void __lsan_do_leak_check_go(void); diff --git a/src/runtime/mem.go b/src/runtime/mem.go index d45a0ccfb8..cd06ea323d 100644 --- a/src/runtime/mem.go +++ b/src/runtime/mem.go @@ -119,6 +119,13 @@ func sysHugePageCollapse(v unsafe.Pointer, n uintptr) { // //go:nosplit func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) { + // When using ASAN leak detection, the memory being freed is + // known by the sanitizer. We need to unregister it so it's + // not accessed by it. + if asanenabled { + lsanunregisterrootregion(v, n) + } + sysStat.add(-int64(n)) gcController.mappedReady.Add(-int64(n)) sysFreeOS(v, n)