Skip to content

longlong: Add sanitizer builds, fix revealed problems. #17709

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

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

jepler
Copy link
Contributor

@jepler jepler commented Jul 18, 2025

Summary

I decided to try the longlong build under the sanitizers. This exposed a pair of problems:

  • A line, already commented to explain undefined integer overflow behavior, did in fact produce a diagnostic
  • The address sanitizer produced spurious results on 32-bit x86 builds when raising exceptions.

Testing

I built the branch locally with the sanitizers until it passed.

Trade-offs and Alternatives

It's odd that the fixed version of left shift doesn't produce a diagnostic, because there is still an overflowing operation (now a multiplication, previously a shift). Is the sanitizer deliberately not checking this kind of overflow, or is recognizing a specific overflow check pattern in the following line? I was not able to find any documentation about this, and the documentation seemed to imply that -fsanitize=signed-integer-overflow was enabled by -fsanitize=undefined; explicitly enabling it made no difference.

It's unclear why adding the returns_twice qualification to nlr_push helps the sanitizer to function properly, but it's true that nlr_push should have this annotation. Hence, maybe it should be enabled whenever the compiler supports it? (any plausible gcc & clang versions, probably)

jepler added 5 commits July 18, 2025 13:39
This fixes the following two flavors of diagnostics:
```
../../py/objint_longlong.c:215:30: runtime error:
    left shift of negative value -10000000000000000
../../py/objint_longlong.c:215:30: runtime error:
    left shift of 72623859790382856 by 8 places cannot
    be represented in type 'long long int'
```

This formulation compiles to identical code (gcc 15 -m32 -O3).
In fact, the compiler is so sure the original and modified versions
are identical that building the following:
```
long long f1(long long lhs_val, long long rhs_val, bool *overflow) {
    long long result = lhs_val * (1ll << (int)rhs_val);
    *overflow = rhs_val > 0 && ((lhs_val >= 0 && result < lhs_val)
        || (lhs_val < 0 && result > lhs_val));
    return result;
}

long long f2(long long lhs_val, long long rhs_val, bool *overflow) {
    long long result = lhs_val << ((int)rhs_val);
    *overflow = rhs_val > 0 && ((lhs_val >= 0 && result < lhs_val)
        || (lhs_val < 0 && result > lhs_val));
    return result;
}
```
under `-Os` makes the body of f2 just say `jmp f1`!

Signed-off-by: Jeff Epler <jepler@gmail.com>
This diagnostic occurs when `nlr_push` is marked with the gcc/clang
attribute "returns_twice".

Signed-off-by: Jeff Epler <jepler@gmail.com>
This might affect codegen adversely in other cases,
so the attribute is only enabled in the case where the
address sanitizer is enabled.

Availabilty of the standard gcc/clang attribute syntax is assumed
when __SANITIZE_ADDRESS__ is defined.

Signed-off-by: Jeff Epler <jepler@gmail.com>
Signed-off-by: Jeff Epler <jepler@gmail.com>
Signed-off-by: Jeff Epler <jepler@gmail.com>
Copy link

codecov bot commented Jul 18, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.44%. Comparing base (17fbc5a) to head (ba3f9ca).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #17709   +/-   ##
=======================================
  Coverage   98.44%   98.44%           
=======================================
  Files         171      171           
  Lines       22208    22209    +1     
=======================================
+ Hits        21863    21864    +1     
  Misses        345      345           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jepler jepler marked this pull request as draft July 18, 2025 19:03
@jepler
Copy link
Contributor Author

jepler commented Jul 18, 2025

Interestingly, I don't see these stack errors locally.

under UBSan, this test and import/import_broken.py fail.

--- /home/runner/work/micropython/micropython/tests/results/extmod_vfs_rom.py.exp	2025-07-18 18:55:56.430739171 +0000
+++ /home/runner/work/micropython/micropython/tests/results/extmod_vfs_rom.py.out	2025-07-18 18:55:56.430739171 +0000
@@ -1 +1,13 @@
-SKIP
+Traceback (most recent call last):
+  File "/home/runner/work/micropython/micropython/tests/extmod/vfs_rom.py", line 489, in <module>
+  File "/home/runner/work/micropython/micropython/lib/micropython-lib/python-stdlib/unittest/unittest/__init__.py", line 464, in main
+  File "/home/runner/work/micropython/micropython/lib/micropython-lib/python-stdlib/unittest/unittest/__init__.py", line 269, in run
+  File "/home/runner/work/micropython/micropython/lib/micropython-lib/python-stdlib/unittest/unittest/__init__.py", line 254, in run
+  File "/home/runner/work/micropython/micropython/lib/micropython-lib/python-stdlib/unittest/unittest/__init__.py", line 420, in _run_suite
+  File "/home/runner/work/micropython/micropython/tests/extmod/vfs_rom.py", line 166, in setUpClass
+  File "/home/runner/work/micropython/micropython/tests/extmod/vfs_rom.py", line 145, in make_romfs
+  File "/home/runner/work/micropython/micropython/tests/extmod/vfs_rom.py", line 136, in _make_romfs
+  File "/home/runner/work/micropython/micropython/tests/extmod/vfs_rom.py", line 115, in mkfile
+  File "/home/runner/work/micropython/micropython/tests/extmod/vfs_rom.py", line 80, in _encode_uint
+RuntimeError: maximum recursion depth exceeded

Under asan, this failure comes up:

--- /home/runner/work/micropython/micropython/tests/results/thread_thread_lock3.py.exp	2025-07-18 18:56:16.661895914 +0000
+++ /home/runner/work/micropython/micropython/tests/results/thread_thread_lock3.py.out	2025-07-18 18:56:16.661895914 +0000
@@ -8,3 +8,7 @@
 my turn: 7
 my turn: 8
 my turn: 9
+=================================================================
+==11953==ERROR: AddressSanitizer: stack-buffer-overflow on address 0xef870270 at pc 0xf102e4eb bp 0xef870248 sp 0xef86fe18
+WRITE of size 12 at 0xef870270 thread T16777215
+TIMEOUT

If I can't resolve these, the "fixes" themselves are probably not worth taking either. Shifting to draft status.

Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy