Skip to content

all: add internal/asan and internal/msan packages #64611

Open
@mauri870

Description

@mauri870

There are a couple issues where having asan/msan enabled throw off tests for memory allocations, see #64257 and #64256.

Most tests already skip these memory allocation assertions when they detect that race is enabled, but such functionality is not exposed for asan and msan.

Here is one example of such test:

if n := testing.AllocsPerRun(100, func() { Grow(s2, cap(s2)-len(s2)+1) }); n != 1 {
    errorf := t.Errorf
    if race.Enabled || testenv.OptimizationOff() {
        errorf = t.Logf // this allocates multiple times with race or msan enabled
    }
    errorf("Grow should allocate once when given insufficient capacity; allocated %v times", n)
}

One alternative is using the asan and msan build tags to skip certain tests, but that does not work in the middle of a test, only for entire files.

There is runtime.msanenabled, runtime.asanenabled, syscall.asanenabled we could use, but they are private to their respective packages.

It is worth noting that syscall and runtime duplicate some code related to asan:

  • syscall has asanenabled, asanRead, asanWrite that basically call into the runtime.
  • runtime has asanenabled as well

I propose we create internal/asan and internal/msan packages akin to internal/race. Then syscall and runtime would call internal/asan.Enabled and syscall could use ASanRead, ASanWrite as well, without having this logic duplicated.

The tests can also use internal/asan.Enabled to check if they should skip tests that allocate memory, which most tests already do currently by checking race.Enabled. We can also use these inside testenv.SkipIfOptimizationOff/testenv.OptimizationOff to make this process more seamless.

Here is the proposed apis for these new internal packages:

internal/asan

//go:build asan

package asan

import (
	"unsafe"
)

const Enabled = true

func Read(addr unsafe.Pointer, len int)
func Write(addr unsafe.Pointer, len int)

The !asan version would have stubs for these functions.

internal/msan

The only place that uses msan currently is the runtime, but having access to a msan.Enabled would be useful in tests as well and would make a good trio with internal/asan and internal/race. Other packages might be able to use the exported functions more easily as well.

The proposed api for internal/msan would then be:

//go:build msan

package msan

import (
	"unsafe"
)

const Enabled = true

func Read(addr unsafe.Pointer, sz uintptr)
func Write(addr unsafe.Pointer, sz uintptr)
func Malloc(addr unsafe.Pointer, sz uintptr)
func Free(addr unsafe.Pointer, sz uintptr)
func Move(dst, src unsafe.Pointer, sz uintptr)

The !msan version would have stubs for these functions.

Metadata

Metadata

Assignees

Labels

NeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status

In Progress

Relationships

None yet

Development

No branches or pull requests

Issue actions