Source File
mem.go
Belonging Package
internal/fuzz
// Copyright 2020 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 fuzzimport ()// sharedMem manages access to a region of virtual memory mapped from a file,// shared between multiple processes. The region includes space for a header and// a value of variable length.//// When fuzzing, the coordinator creates a sharedMem from a temporary file for// each worker. This buffer is used to pass values to fuzz between processes.// Care must be taken to manage access to shared memory across processes;// sharedMem provides no synchronization on its own. See workerComm for an// explanation.type sharedMem struct {// f is the file mapped into memory.f *os.File// region is the mapped region of virtual memory for f. The content of f may// be read or written through this slice.region []byte// removeOnClose is true if the file should be deleted by Close.removeOnClose bool// sys contains OS-specific information.sys sharedMemSys}// sharedMemHeader stores metadata in shared memory.type sharedMemHeader struct {// count is the number of times the worker has called the fuzz function.// May be reset by coordinator.count int64// valueLen is the number of bytes in region which should be read.valueLen int// randState and randInc hold the state of a pseudo-random number generator.randState, randInc uint64// rawInMem is true if the region holds raw bytes, which occurs during// minimization. If true after the worker fails during minimization, this// indicates that an unrecoverable error occurred, and the region can be// used to retrieve the raw bytes that caused the error.rawInMem bool}// sharedMemSize returns the size needed for a shared memory buffer that can// contain values of the given size.func sharedMemSize( int) int {// TODO(jayconrod): set a reasonable maximum size per platform.return int(unsafe.Sizeof(sharedMemHeader{})) +}// sharedMemTempFile creates a new temporary file of the given size, then maps// it into memory. The file will be removed when the Close method is called.func sharedMemTempFile( int) ( *sharedMem, error) {// Create a temporary file., := os.CreateTemp("", "fuzz-*")if != nil {return nil,}defer func() {if != nil {.Close()os.Remove(.Name())}}()// Resize it to the correct size.:= sharedMemSize()if := .Truncate(int64()); != nil {return nil,}// Map the file into memory.:= truereturn sharedMemMapFile(, , )}// header returns a pointer to metadata within the shared memory region.func ( *sharedMem) () *sharedMemHeader {return (*sharedMemHeader)(unsafe.Pointer(&.region[0]))}// valueRef returns the value currently stored in shared memory. The returned// slice points to shared memory; it is not a copy.func ( *sharedMem) () []byte {:= .header().valueLen:= int(unsafe.Sizeof(sharedMemHeader{}))return .region[ : +]}// valueCopy returns a copy of the value stored in shared memory.func ( *sharedMem) () []byte {:= .valueRef()return bytes.Clone()}// setValue copies the data in b into the shared memory buffer and sets// the length. len(b) must be less than or equal to the capacity of the buffer// (as returned by cap(m.value())).func ( *sharedMem) ( []byte) {:= .valueRef()if len() > cap() {panic(fmt.Sprintf("value length %d larger than shared memory capacity %d", len(), cap()))}.header().valueLen = len()copy([:cap()], )}// setValueLen sets the length of the shared memory buffer returned by valueRef// to n, which may be at most the cap of that slice.//// Note that we can only store the length in the shared memory header. The full// slice header contains a pointer, which is likely only valid for one process,// since each process can map shared memory at a different virtual address.func ( *sharedMem) ( int) {:= .valueRef()if > cap() {panic(fmt.Sprintf("length %d larger than shared memory capacity %d", , cap()))}.header().valueLen =}// TODO(jayconrod): add method to resize the buffer. We'll need that when the// mutator can increase input length. Only the coordinator will be able to// do it, since we'll need to send a message to the worker telling it to// remap the file.
![]() |
The pages are generated with Golds v0.7.9-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |