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
various: Fix gcc -fsanitize=undefined errors #7237
Conversation
ab63ea5
to
32f2e9f
Compare
I'll try to sort out the small ARM size difference and any other problems soon. |
Might make sense to always build the coverage variant using fsanitize to make sure these fixes don't regress. |
|
||
// Note: dest and slice regions may overlap | ||
#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_sz) \ | ||
memmove(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \ | ||
memmove(((char *)dest) + (beg + slice_len) * (item_sz), ((char *)dest) + (end) * (item_sz), (dest_len - end) * (item_sz)); | ||
(void)memmove0(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \ |
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.
Is the (void)
suppressing some warning here, or just to inicate the return value is unused?
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.
To mark it as intentionally unused. Without the cast, gcc encounters these diagnostics:
../../py/objlist.c: In function ‘list_subscr’:
../../py/misc.h:335:72: error: statement with no effect [-Werror=unused-value]
#define memmove0(dest, src, n) ((n) != 0 ? memmove((dest), (src), (n)) : (dest))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
../../py/obj.h:1009:5: note: in expansion of macro ‘memmove0’
memmove0(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \
^~~~~~~~
../../py/objlist.c:169:13: note: in expansion of macro ‘mp_seq_replace_slice_no_grow’
mp_seq_replace_slice_no_grow(self->items, self->len, slice.start, slice.stop, self->items /*NULL*/, 0, sizeof(*self->items));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
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.
Ah, right, because it's not a single function call anymore. Makes sense.
py/objdict.c
Outdated
@@ -247,7 +247,9 @@ mp_obj_t mp_obj_dict_copy(mp_obj_t self_in) { | |||
other->map.all_keys_are_qstrs = self->map.all_keys_are_qstrs; | |||
other->map.is_fixed = 0; | |||
other->map.is_ordered = self->map.is_ordered; | |||
memcpy(other->map.table, self->map.table, self->map.alloc * sizeof(mp_map_elem_t)); | |||
if (self->map.alloc) { |
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.
Why not memcpy0
?
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.
Thanks. I originally introduced these conditionals everywhere, before adopting the approach of providing wrapping functions I later adopted, and overlooked (at least) two of them in my own pre-push review. Will fix.
Can you fix the linenumbers in the message so they math with the last commit before yours? |
32f2e9f
to
29cd97e
Compare
[messages truncated to pass ci_commit_formatting_run] [the line numbers match 0e87459] ``` binary.c:210:13: runtime error: left shift of negative val... crypto-algorithms/sha256.c:49:19: runtime error: left shif... moduasyncio.c:106:35: runtime error: member access within ... mpz.c:711:5: runtime error: null pointer passed as argumen... mpz.c:744:16: runtime error: negation of -9223372036854775... objarray.c:130:9: runtime error: null pointer passed as ar... objarray.c:377:5: runtime error: null pointer passed as ar... objarray.c:457:21: runtime error: null pointer passed as a... objarray.c:457:21: runtime error: null pointer passed as a... objarray.c:461:21: runtime error: null pointer passed as a... objdict.c:250:5: runtime error: null pointer passed as arg... objdict.c:250:5: runtime error: null pointer passed as arg... objint.c:109:22: runtime error: left shift of # by 31 plac... objint_mpz.c:374:9: runtime error: left shift of # by 1 pl... objint_mpz.c:374:9: runtime error: left shift of negative ... objset.c:181:5: runtime error: null pointer passed as argu... objset.c:181:5: runtime error: null pointer passed as argu... parsenum.c:106:14: runtime error: left shift of # by 1 pla... qstr.c:181:78: runtime error: null pointer passed as argum... runtime.c:395:33: runtime error: left shift of negative va... runtime.c:534:17: runtime error: left shift of negative va... sequence.c:108:15: runtime error: null pointer passed as a... sequence.c:108:15: runtime error: null pointer passed as a... showbc.c:177:28: runtime error: left shift of negative val... vm.c:321:36: runtime error: left shift of negative value -... ``` With these cumulative changes, `make VARIANT=coverage test_full` with -fsanitize=undefined passes, except for some problems in axtls. My testing was done on an amd64 debian buster system using gcc-8.3 and these settings: ``` CFLAGS += -g3 -Og -fsanitize=undefined LDFLAGS += -fsanitize=undefined ``` The changes are intended/expected to produce no runtime overhead, as the behavior of the mem* functions is only actually modified for the unix coverage run (MICROPY_NONNULL_COMPLIANT). The introduced PAIRHEAP macro's conditional (x ? &x->i : NULL) assembles (under amd64 gcc 8.3 -Os) to the same as &x->i, since i is the initial field of the struct. However, for the purposes of undefined behavior analysis the conditional is needed. Signed-off-by: Jeff Epler <jepler@gmail.com>
29cd97e
to
cc74f22
Compare
Since there are remaining sanitizer problems in axtls, those would need to be resolved before turning on the sanitizer in the coverage build. I did file a PR upstream with axtls but I don't know whether this is likely to be acted on: pfalcon/axtls#6 (a possible alternative would be using a suppressions file to suppress these diagnostics) I've updated the locations both in the commit message and in the initial commit on this PR. |
The patch in this gist will unconditionally enable the "undefined behavior" sanitizer for coverage builds, while excluding axtls files from the sanitizer: https://gist.github.com/bc669a1f68d413afa2b9c1b14fd9956b Some reasons not to do this would include:
|
@@ -178,7 +178,9 @@ STATIC mp_obj_t set_copy(mp_obj_t self_in) { | |||
other->base.type = self->base.type; | |||
mp_set_init(&other->set, self->set.alloc); | |||
other->set.used = self->set.used; | |||
memcpy(other->set.table, self->set.table, self->set.alloc * sizeof(mp_obj_t)); | |||
if (self->set.alloc) { | |||
memcpy(other->set.table, self->set.table, self->set.alloc * sizeof(mp_obj_t)); |
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.
can this use memcpy0
?
It would be great to separate this PR into 2 commits:
|
Ok, yes, makes sense to have additional builds then, one for
We can fork axtls and/or berkeley repos to fix the issues with them (there are other things that would be good to fix in those libraries as well). |
Add Boardsource Blok
With these cumulative changes,
make VARIANT=coverage test_full
with -fsanitize=undefined passes, except for some problems in axtls.My testing was done on an amd64 debian buster system using gcc-8.3 and these settings:
The changes are intended/expected to produce no runtime overhead, as the behavior of the mem* functions is only actually modified for the unix coverage run (MICROPY_NONNULL_COMPLIANT).
The introduced PAIRHEAP macro's conditional
(x ? &x->i : NULL)
assembles (under amd64 gcc 8.3 -Os) to the same as&x->i
, since i is the initial field of the struct. However, for the purposes of undefined behavior analysis the conditional is needed.Signed-off-by: Jeff Epler jepler@gmail.com