[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] An unreasonably effective defect mitigation
From: |
Greg Chicares |
Subject: |
[lmi] An unreasonably effective defect mitigation |
Date: |
Sat, 19 Dec 2020 22:57:34 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.0 |
There's a defect on branch valyuta/004 right now (SHA1 3742c5405d9):
,scale_fwd_ {detail::perform_pow(max_prec_real(10.0), decimals)}
,scale_fwd_c_ {detail::perform_pow(max_prec_real(10.0), decimals -
currency::cents_digits)}
The first quoted line has been in 'master' for decades. The second
quoted line is new on this branch, and it's defective: what if
'decimals' is so negative that subtracting two from it (which is what
decimals - currency::cents_digits
does) causes (signed) integer underflow? I understand that, and can
take whatever steps seem necessary to prevent anyone from rounding to
INT_MIN-2 digits. (As a practical matter, I'll probably just revise
the unit test that triggered this.)
But here's what I found surprising. Along my journey of discovery that
led to that insight, I used my favorite debugging technique (adding
statements to print internal state on stdout) and found that doing so
made the problem vanish--even when I reduced the added statements to
std::cout << std::flush;
. My analysis is that subtracting two from INT_MIN is UB, one possible
consequence of which is that a failing unit test stops failing. Another
is that demons don't fly out your nose when it seems they should. This
just feels so remarkable that I was moved to share it.
To reproduce:
/opt/lmi/src/lmi[0]$LMI_COMPILER=gcc ; LMI_TRIPLET=x86_64-pc-linux-gnu ; .
/opt/lmi/src/lmi/set_toolchain.sh
/opt/lmi/src/lmi[0]$git switch valyuta/004
Already on 'valyuta/004'
Your branch is up to date with 'origin/valyuta/004'.
running post-checkout hook...
...post-checkout hook finished.
/opt/lmi/src/lmi[0]$git status
On branch valyuta/004
Your branch is up to date with 'origin/valyuta/004'.
nothing to commit, working tree clean
/opt/lmi/src/lmi[0]$git rev-parse HEAD
3742c5405d96393163dc45e8ed9f743d673c2def
/opt/lmi/src/lmi[0]$make $coefficiency unit_tests
unit_test_targets=round_to_test
[...]
???? test failed: Caught exception of type
'St11logic_error'
when type
'St12domain_error'
was expected.
[file /opt/lmi/src/lmi/round_to_test.cpp, line 565]
[...]
???? 1 test errors detected; 8486 tests succeeded
Now the mystery: that error vanishes if we add a trivial
trace statement for debugging...and, in this minimal case,
even if that statement does pretty much nothing:
sed -i round_to.hpp -e'/<limits>/s/^/#include <iostream>\n/' -e '/return
max/s/^/ std::cout << std::flush;\n/'
/opt/lmi/src/lmi[0]$make $coefficiency unit_tests
unit_test_targets=round_to_test
[...]
.... 8487 tests succeeded
!!!! no errors detected
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi] An unreasonably effective defect mitigation,
Greg Chicares <=