workflows: Run the address sanitizer (ASan) build during CI.
Summary
ASan, the address sanitizer can find interesting bugs using additional runtime checks. For instance, it detected the memory leak now fixed at https://github.com/micropython/berkeley-db-1.xx/pull/1 and possibly other interesting findings I've previously submitted.
This patch set enables ASan for the 64-bit unix coverage build.
Testing
Lots and lots of builds until it was green!
Trade-offs and Alternatives
I had to disable one entire class of check, "stack use after return". I wasn't able to find good information about how this mode works, but it clearly violates assumptions that micropython makes in nlr, gc, and stack space checking.
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 98.56%. Comparing base (
5ade8b7) to head (264ed6c). Report is 29 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #17503 +/- ##
=======================================
Coverage 98.56% 98.56%
=======================================
Files 169 169
Lines 21948 21948
=======================================
Hits 21632 21632
Misses 316 316
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
- :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
Code size report:
bare-arm: +0 +0.000%
minimal x86: +0 +0.000%
unix x64: +0 +0.000% standard
stm32: +0 +0.000% PYBV10
mimxrt: +0 +0.000% TEENSY40
rp2: +0 +0.000% RPI_PICO_W
samd: +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
qemu rv32: +0 +0.000% VIRT_RV32
aha https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn explains how it works. I'm not sure how you'd make this mode work with all micropython's stack trickery, there was a link to research on how to make it interoperate with some other kind of gc but it's dead and not archived that I could find.
ah, found it in their git history: llvm introduced two functions to allow gc to work with the stack use sanitizer. I don't know if gcc did likewise, and I'm not sure how exactly they'd be used in practice.
Here's a program that seems to know how to gather pointers in the fake stack for gc: https://github.com/karolba/serenity/blob/2a563b9de65886c0a5644b8ea41bef14e5587735/Userland/Libraries/LibJS/Heap/Heap.cpp#L163
(just to be clear: I don't think this PR should be held for want of being able to use that specific sanitizer.)
Rebased and merged in 9a5cf0e3dbb7dbc1b66ef67dd2fec0245d24e37e through 1eb27e11f3bf8e5e0ee13191ef1e9c30b00f9ead