Created
July 16, 2019 16:29
-
-
Save ramielrowe/cf41891d38fa9bf636b7f45eb81a0cd0 to your computer and use it in GitHub Desktop.
azure_mmap_segfault
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"errors" | |
"fmt" | |
"os" | |
"syscall" | |
"time" | |
"golang.org/x/sync/errgroup" | |
) | |
func fatal(msg string) { | |
fmt.Println(msg) | |
os.Exit(1) | |
} | |
type mmf []byte | |
func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) { | |
prot, flags := syscall.PROT_READ, syscall.MAP_SHARED // Assume read-only | |
if writable { | |
prot, flags = syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED | |
} | |
addr, err := syscall.Mmap(int(file.Fd()), offset, length, prot, flags) | |
return mmf(addr), err | |
} | |
func (m *mmf) unmap() { | |
err := syscall.Munmap(*m) | |
*m = nil | |
if err != nil { | |
fatal("if we are unable to unmap the memory-mapped file, there is serious concern for memory corruption") | |
} | |
} | |
func read(ctx context.Context, m []byte, i int) error { | |
time.Sleep(time.Second) | |
select { | |
case <-ctx.Done(): | |
return ctx.Err() | |
default: | |
b := m[i] | |
if b == byte('e') { | |
return errors.New("Some Error") | |
} | |
} | |
return nil | |
} | |
func run() error { | |
ctx := context.Background() | |
group, gCtx := errgroup.WithContext(ctx) | |
f, err := os.Open("test.txt") | |
if err != nil { | |
fatal(err.Error()) | |
} | |
s, err := f.Stat() | |
if err != nil { | |
fatal(err.Error()) | |
} | |
m, err := newMMF(f, false, 0, int(s.Size())) | |
if err != nil { | |
fatal(err.Error()) | |
} | |
defer m.unmap() | |
work := make(chan int, 5) | |
for c := 0; c < 5; c++ { | |
group.Go(func() error { | |
for w := range work { | |
err := read(gCtx, m, w) | |
if err != nil { | |
return err | |
} | |
} | |
return nil | |
}) | |
} | |
for i := 0; i < len(m); i++ { | |
work <- i | |
} | |
close(work) | |
return group.Wait() | |
} | |
func main() { | |
run() | |
time.Sleep(10 * time.Second) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"errors" | |
"fmt" | |
"os" | |
"syscall" | |
"time" | |
) | |
func fatal(msg string) { | |
fmt.Println(msg) | |
os.Exit(1) | |
} | |
type mmf []byte | |
func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) { | |
prot, flags := syscall.PROT_READ, syscall.MAP_SHARED // Assume read-only | |
if writable { | |
prot, flags = syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED | |
} | |
addr, err := syscall.Mmap(int(file.Fd()), offset, length, prot, flags) | |
return mmf(addr), err | |
} | |
func (m *mmf) unmap() { | |
err := syscall.Munmap(*m) | |
*m = nil | |
if err != nil { | |
fatal("if we are unable to unmap the memory-mapped file, there is serious concern for memory corruption") | |
} | |
} | |
func read(m []byte, i int) error { | |
time.Sleep(time.Second) | |
b := m[i] | |
if b == byte('e') { | |
return errors.New("Some Erroor") | |
} | |
return nil | |
} | |
func run() error { | |
ctxOutter := context.Background() | |
_, cancel := context.WithCancel(ctxOutter) | |
defer cancel() | |
f, err := os.Open("test.txt") | |
if err != nil { | |
fatal(err.Error()) | |
} | |
s, err := f.Stat() | |
if err != nil { | |
fatal(err.Error()) | |
} | |
m, err := newMMF(f, false, 0, int(s.Size())) | |
if err != nil { | |
fatal(err.Error()) | |
} | |
defer m.unmap() | |
work := make(chan int, 5) | |
resultChan := make(chan error, len(m)) | |
for g := 0; g < 5; g++ { | |
go func() { | |
for w := range work { | |
resultChan <- read(m, w) | |
} | |
}() | |
} | |
for i := 0; i < len(m); i++ { | |
work <- i | |
} | |
close(work) | |
for result := range resultChan { | |
if result != nil { | |
return result | |
} | |
} | |
return nil | |
} | |
func main() { | |
run() | |
time.Sleep(10 * time.Second) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abcdefg |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment