Go is a production-level statically typed programming language whose design features explicit message-passing primitives and lightweight threads, enabling (and encouraging) programmers to develop concurrent systems where components interact through communication more so than by lock-based shared memory concurrency. Go can only detect global deadlocks at runtime, but provides no compile-time protection against all too common communication mismatches or partial deadlocks. This work develops a static verification framework for liveness and safety in Go programs, able to detect communication errors and partial deadlocks in a general class of realistic concurrent programs, including those with dynamic channel creation, unbounded thread creation and recursion. Our approach infers from a Go program a faithful representation of its communication patterns as a behavioural type. By checking a syntactic restriction on channel usage, dubbed fencing, we ensure that programs are made up of finitely many different communication patterns that may be repeated infinitely many times. This restriction allows us to implement procedures to check for liveness and safety in types which in turn approximates liveness and safety in Go programs. We have implemented a type inference and liveness and safety checks in a tool-chain and tested it against publicly available Go programs. Note: This is a revised extended version of a paper that appeared in POPL 2017, see page 13 for details.
翻译:Go 是一种生产层面的静态编程语言,其设计特征是明确传递信息、原始和轻量级线索,使(和鼓励)程序程序员能够开发同时的系统,使各组成部分通过通信进行互动的系统比基于锁定的共享记忆货币更能通过通信进行互动。 Go 只能探测在运行时出现的全球僵局,但不能提供针对所有常见的通信不匹配或部分僵局的编程时间保护。 这项工作为Go 方案中的生活和安全开发了一个静态的核查框架, 能够发现通信错误和部分僵局, 包括具有动态频道创建、 不受约束的线创建和循环程序。 我们的方法从一个 Go 方案中推断出其通信模式作为一种行为类型的忠实表现。 通过检查对频道使用的同步限制, 隐蔽的栅栏, 我们确保程序由有限的许多不同的通信模式组成, 这些模式可能会被无限地反复重复。 这一限制使我们能够执行程序来检查生活和安全的种类, 反过来可以比较Go 程序中的生活和安全性和安全性。 我们从Go 方案中应用了一种类型的推价和安全性和安全性、活性和安全性和安全性和安全性检查方式。