You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I ran the sanitizers again, and found a few more instances of undefined behaviour, mostly around bit-shifting of signed integers and arithmetic with NULL pointers.
export CC="clang"export ASAN_OPTIONS=detect_leaks=0
configure --with-assertions --with-address-sanitizer --with-trace-refs --with-undefined-behavior-sanitizer --with-pydebug
nice make -j8
make test
As a practical test, we can take the asserts I added in the PRs mentioned in the text of the issue, convert them into something that triggers in release mode (eg a normal if and a printf or abort) and run them under the same conditions as release mode.
I don't know why the sanitizer doesn't pick any of this up. At least it doesn't pick any of this up when the build bot runs it, neither in release mode nor in the debug mode.
I ran my sanitizer locally with different flags. See above.
(I'm only on my phone right now, so can't run these experiments until later today.)
I don't know why the sanitizer doesn't pick any of this up. At least it doesn't pick any of this up when the build bot runs it, neither in release mode nor in the debug mode.
Answering that question is very important, as it may reveal very interesting things such as problems in the running builder or what is the difference in behaviour between your builds and the builder and if the differences matte or not.
neither in release mode nor in the debug mode.
The sanitizer only runs in release mode in the build bots
The sanitizer only runs in release mode in the build bots
Oh, thanks. I must have misunderstood something.
Of course, our general point about not actually picking up many instances of UB still stands.
Btw, the config that you linked to that had the sanitizer enabled didn't enable optimisations as far as I can tell, hence I didn't see it as release mode.
Good news! I found the rootcause of why my debug build with all sanitisers turned up showed undefined behaviour, but they didn't show up in the build bot.
Most invocations of configure add -fwrapv to the compiler options. But --with-pydebug removes that.
From clang's documentation about -fwrapv
Treat signed integer overflow as two’s complement
GCC is a bit more verbose, but still rather vague:
This option instructs the compiler to assume that signed arithmetic overflow of addition, subtraction and multiplication wraps around using twos-complement representation. This flag enables some optimizations and disables others.
It turns out that arithmetic on the null-pointer also becomes defined with -fwrapv. At least my experiments point in that direction. The only thing I could find is some discussion on the netbsd kernel mailing list that seems to confirm this.
If the above is true, then all the instances of UB that I found are not actually UB in the effective C-dialect we are using for release builds.
Now we have (at least) two options:
fix --with-pydebug to also add -fwrapv for consistency.
remove -fwrapv from the release builds.
The former is the minimal change and safe. The latter enables a lot of C compiler optimizations, and my experiments running the sanitisers suggests that we are already nearly -fno-wrapv-ready. In general, we might want to look into -fstrict-overflow, too.
I say we should do the former straight away, and in the longer term consider implementing the latter (after running benchmarks and weighing the pros and cons etc).
I am closing this issue for now, because thanks to -fwrapv we don't actually have any UB in the release builds. Only when building --with-pydebug or with an explicit optimization option on the command line.
Activity
[-]Undefined behaviours in main and 3.11[/-][+]Undefined behaviours in `main` and 3.11[/+][-]Undefined behaviours in `main` and 3.11[/-][+]Undefined behaviour in `main` and 3.11[/+]kumaraditya303 commentedon Sep 8, 2022
Can you post a summary of "arithmetic with NULL pointers" here? Thanks
matthiasgoergens commentedon Sep 8, 2022
@kumaraditya303 In
ceval.c, theassertis my addition.There's also an example in
Modules/_testcapimodule.cbut that's only a test, I guess.matthiasgoergens commentedon Sep 8, 2022
#96672 is also vaguely related.
kumaraditya303 commentedon Sep 8, 2022
cc @pablogsal This seems to be introduced in #89419
pablogsal commentedon Sep 8, 2022
I am a bit surprised by this because we have a USAN buildbot that has not detected anything:
https://buildbot.python.org/all/#/builders/964
pablogsal commentedon Sep 8, 2022
These are the parameters, just in case we want to compare:
https://github.com/python/buildmaster-config/blob/8484356e8a0854084e186d9c9eb47b3b0c6eb628/master/custom/factories.py#L311-L315
matthiasgoergens commentedon Sep 8, 2022
@pablogsal I added some more info about what compiler I am using.
pablogsal commentedon Sep 8, 2022
Can you see if you reproduce these warnings using the exact flags the buildbot is using?
matthiasgoergens commentedon Sep 8, 2022
I'll try that later today.
33 remaining items
matthiasgoergens commentedon Sep 11, 2022
As a practical test, we can take the asserts I added in the PRs mentioned in the text of the issue, convert them into something that triggers in release mode (eg a normal
ifand a printf or abort) and run them under the same conditions as release mode.I don't know why the sanitizer doesn't pick any of this up. At least it doesn't pick any of this up when the build bot runs it, neither in release mode nor in the debug mode.
I ran my sanitizer locally with different flags. See above.
(I'm only on my phone right now, so can't run these experiments until later today.)
pablogsal commentedon Sep 11, 2022
Answering that question is very important, as it may reveal very interesting things such as problems in the running builder or what is the difference in behaviour between your builds and the builder and if the differences matte or not.
The sanitizer only runs in release mode in the build bots
matthiasgoergens commentedon Sep 11, 2022
Oh, thanks. I must have misunderstood something.
Of course, our general point about not actually picking up many instances of UB still stands.
Btw, the config that you linked to that had the sanitizer enabled didn't enable optimisations as far as I can tell, hence I didn't see it as release mode.
matthiasgoergens commentedon Sep 12, 2022
@pablogsal @markshannon @kumaraditya303
Good news! I found the rootcause of why my debug build with all sanitisers turned up showed undefined behaviour, but they didn't show up in the build bot.
Most invocations of
configureadd-fwrapvto the compiler options. But--with-pydebugremoves that.From clang's documentation about
-fwrapvGCC is a bit more verbose, but still rather vague:
It turns out that arithmetic on the null-pointer also becomes defined with
-fwrapv. At least my experiments point in that direction. The only thing I could find is some discussion on the netbsd kernel mailing list that seems to confirm this.If the above is true, then all the instances of UB that I found are not actually UB in the effective C-dialect we are using for release builds.
Now we have (at least) two options:
--with-pydebugto also add-fwrapvfor consistency.-fwrapvfrom the release builds.The former is the minimal change and safe. The latter enables a lot of C compiler optimizations, and my experiments running the sanitisers suggests that we are already nearly
-fno-wrapv-ready. In general, we might want to look into-fstrict-overflow, too.I say we should do the former straight away, and in the longer term consider implementing the latter (after running benchmarks and weighing the pros and cons etc).
gh-96678: Avoid undefined behaviour in test (#96672)
pythongh-96678: Avoid undefined behaviour in test (pythonGH-96672)
pythongh-96678: Fix UB of null pointer arithmetic (pythonGH-96782)
gh-96678: Fix UB of null pointer arithmetic (GH-96782)
pythongh-96678: Fix UB of null pointer arithmetic (pythonGH-96782)
gh-96678: Avoid undefined behaviour in test (GH-96672) (#96795)
gh-96678: Fix UB of null pointer arithmetic (GH-96782)
gh-96678: Fix UB of null pointer arithmetic (GH-96782)
matthiasgoergens commentedon Sep 14, 2022
I am closing this issue for now, because thanks to
-fwrapvwe don't actually have any UB in the release builds. Only when building--with-pydebugor with an explicit optimization option on the command line.