|
|
DescriptionAdd SkMSAN.h
This lets us tag up pieces of code as requiring initialized inputs.
Almost all code requires initialized inputs, of course. This is for
code that works correctly with uninitialized data but triggers false
positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized
data in this max function:
static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; }
There's no bug in here... if there's uninitialized data being branched upon
here for the first time, it's sure not max's fault, it's its caller's fault.
So we might do this:
static uint8_t max(uint8_t x, uint8_t y) {
// This function uses branching, so if MSAN finds a problem here,
// we can assert x and y are initialized. This will remind us the
// problem somewhere in the caller or above, not here.
sk_msan_assert_initialized(&x, &x+1);
sk_masn_assert_initialized(&y, &y+1);
return x > y ? x : y;
}
By allowing code to assert its inputs must be initialized,
we can make the blame for use of uninitialized data more clear.
(Sometimes we have another option, to rewrite the code to avoid branching:
static uint8_t max(uint8_t x, uint8_t y) {
// This function is branchfree, so MSAN won't complain here.
// No real need to assert anything as requiring initialization.
int diff = x - y;
int negative = diff >> (sizeof(int)*8 - 1);
return (y & negative) | (x & ~negative);
}
These approaches to fixing MSAN false positives are orthogonal.)
BUG=chromium:574114
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1658913005
CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
Committed: https://skia.googlesource.com/skia/+/1059b1fc9f8711592a81836512850d123d75146d
Patch Set 1 #Patch Set 2 : year #Patch Set 3 : spelling #
Messages
Total messages: 23 (16 generated)
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Most code requires initialized inputs, of course. This is mostly for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g. static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN find a problem here, we might // want to assert x and y are initialized: sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } static uint8_t max_branchfree(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN is unlikely to complain in here. // No real need to tag anything as requiring initialization. } By starting with an assertion that the input must be initialized, it makes it clear that code's not the root problem. BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } Or possibly do this: static uint8_t max_branchfree(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to tag anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ==========
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } Or possibly do this: static uint8_t max_branchfree(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to tag anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } Or possibly do this: static uint8_t max_branchfree(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to tag anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ==========
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } Or possibly do this: static uint8_t max_branchfree(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to tag anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } (Or of course we might do something like this:) static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to tag anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ==========
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } (Or of course we might do something like this:) static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to tag anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } (Or of course we might do something like this:) static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ==========
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } (Or of course we might do something like this:) static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives. BUG=skia: ==========
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives. BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives.) BUG=skia: ==========
The CQ bit was checked by mtklein@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1658913005/1 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1658913005/1
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives.) BUG=skia: ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives.) BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot ==========
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives.) BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives.) BUG=chromium:574114 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot ==========
The CQ bit was checked by mtklein@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1658913005/40001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1658913005/40001
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } This is an orthogonal approach to fixing MSAN false positives.) BUG=chromium:574114 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } These approaches to fixing MSAN false positives are orthogonal.) BUG=chromium:574114 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot ==========
mtklein@chromium.org changed reviewers: + eugenis@google.com, reed@google.com
eugenis@chromium.org changed reviewers: + eugenis@chromium.org
LGTM
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by mtklein@google.com
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1658913005/40001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1658913005/40001
Message was sent while issue was closed.
Description was changed from ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } These approaches to fixing MSAN false positives are orthogonal.) BUG=chromium:574114 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot ========== to ========== Add SkMSAN.h This lets us tag up pieces of code as requiring initialized inputs. Almost all code requires initialized inputs, of course. This is for code that works correctly with uninitialized data but triggers false positive warnings in MSAN. E.g., imagine MSAN's found use of uninitialized data in this max function: static uint8_t max(uint8_t x, uint8_t y) { return x > y ? x : y; } There's no bug in here... if there's uninitialized data being branched upon here for the first time, it's sure not max's fault, it's its caller's fault. So we might do this: static uint8_t max(uint8_t x, uint8_t y) { // This function uses branching, so if MSAN finds a problem here, // we can assert x and y are initialized. This will remind us the // problem somewhere in the caller or above, not here. sk_msan_assert_initialized(&x, &x+1); sk_masn_assert_initialized(&y, &y+1); return x > y ? x : y; } By allowing code to assert its inputs must be initialized, we can make the blame for use of uninitialized data more clear. (Sometimes we have another option, to rewrite the code to avoid branching: static uint8_t max(uint8_t x, uint8_t y) { // This function is branchfree, so MSAN won't complain here. // No real need to assert anything as requiring initialization. int diff = x - y; int negative = diff >> (sizeof(int)*8 - 1); return (y & negative) | (x & ~negative); } These approaches to fixing MSAN false positives are orthogonal.) BUG=chromium:574114 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot Committed: https://skia.googlesource.com/skia/+/1059b1fc9f8711592a81836512850d123d75146d ==========
Message was sent while issue was closed.
Committed patchset #3 (id:40001) as https://skia.googlesource.com/skia/+/1059b1fc9f8711592a81836512850d123d75146d |