-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cannon: Fix GC emulation of Go programs #11704
Conversation
Improves Linux/MIPS32 emulation for Go programs that utilize the garbage collector and goroutine scheduling. This adds support for the following syscalls: - getpid - used by the go scheduler - clock_gettime - used by the go scheduler and for GC assists and to properly emulate time related operations such as `time.Sleep`. Note on GC assists: The Go GC relies on `clock_gettime` for GC "assists", whereby a mutator can perform a little bit of GC without waiting for the scheduler to do so. A monotonic clock (runtime.nanotime) is used to compute the current goroutine's compute budget. By modeling a MIPS32 CPU that runs at some clock speed (ex: 10 MHz), we can provide a consistent emulation of monotonic time needed by the Go runtime. All other clock_gettime flags are handled as unimplemented syscalls.
a86832e
to
e83a22f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Just one question on the ClockGetTime error type.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #11704 +/- ##
===========================================
+ Coverage 78.49% 78.78% +0.29%
===========================================
Files 41 41
Lines 3208 3262 +54
===========================================
+ Hits 2518 2570 +52
Misses 529 529
- Partials 161 163 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Semgrep found 1 Please create a GitHub ticket for this TODO. Ignore this finding from todos_require_linear. |
@smartcontracts The heavy fuzz tests are timing out in CI due to slow MIPS test fuzzing. The MIPS tests utilize ffi which is terribly slow to execute for fuzzing. I've tweaked the heavy fuzzer to ignore the MIPS tests in order to unblock this PR. I'll follow up on this by completely moving all forge fuzz testing for the MIPS VM to Go (as done here) so that we can remove the tweaks. We probably need to adjust the number of runs the heavy fuzzer uses as this issue may crop up again for other contracts. |
Meta
Necro of #11292.
Fixes #11658 and #11648
Description
This patch improves Linux/MIPS32 emulation for Go programs that utilize the garbage collector and goroutine scheduling.
This adds support for the following syscalls:
getpid
- used by the go schedulerclock_gettime
- used by the go scheduler and for GC assists and to properly emulate time related operations such astime.Sleep
.Note on GC assists
The Go GC relies on
clock_gettime
for GC "assists", whereby a mutator can perform a little bit of GC without waiting for the scheduler to do so.A monotonic clock (runtime.nanotime) is used to compute the current goroutine's compute budget. By modeling a MIPS32 CPU that runs at some clock speed (ex: 10 MHz), we can provide a consistent emulation of monotonic time needed by the Go runtime. All other clock_gettime flags are handled as unimplemented syscalls.
Memory Proofs
Emulating
clock_gettime
a special as it's the only syscall that requires multi-word memory writes. There are two obvious ways to deal with this:This patch uses the latter approach in order to not complicate the VM state machine that handles futex and thread traversal. However, this means proofs need to be carefully verified between memory accesses. Thus,
MIPS2.sol
requires a second memory proof when stepping on aclock_gettime
syscall.This second memory proof is used to verify that the leaf node associated with the second write corresponds to a valid memory root (i.e. a merkle tree containing the first memory write).
Testing
TestInstrumentedState_Alloc
re-enabled and now asserts against a couple more allocation patterns.