1
0
mirror of https://github.com/golang/go synced 2024-11-18 12:44:49 -07:00
go/misc/cgo/testsanitizers/testdata/msan6.go
Ian Lance Taylor 7b1e0bb79c misc/cgo: gofmt
Change-Id: I5d02279d0593a8368b2f249a6b53650b89aed7b7
Reviewed-on: https://go-review.googlesource.com/c/go/+/482275
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-04-10 22:32:33 +00:00

76 lines
1.4 KiB
Go

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// A C function returning a value on the Go stack could leave the Go
// stack marked as uninitialized, potentially causing a later error
// when the stack is used for something else. Issue 26209.
/*
#cgo LDFLAGS: -fsanitize=memory
#cgo CPPFLAGS: -fsanitize=memory
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
uintptr_t a[20];
} S;
S f() {
S *p;
p = (S *)(malloc(sizeof(S)));
p->a[0] = 0;
return *p;
}
*/
import "C"
// allocateStack extends the stack so that stack copying doesn't
// confuse the msan data structures.
//
//go:noinline
func allocateStack(i int) int {
if i == 0 {
return i
}
return allocateStack(i - 1)
}
// F1 marks a chunk of stack as uninitialized.
// C.f returns an uninitialized struct on the stack, so msan will mark
// the stack as uninitialized.
//
//go:noinline
func F1() uintptr {
s := C.f()
return uintptr(s.a[0])
}
// F2 allocates a struct on the stack and converts it to an empty interface,
// which will call msanread and see that the data appears uninitialized.
//
//go:noinline
func F2() interface{} {
return C.S{}
}
func poisonStack(i int) int {
if i == 0 {
return int(F1())
}
F1()
r := poisonStack(i - 1)
F2()
return r
}
func main() {
allocateStack(16384)
poisonStack(128)
}