Bug 471634

Summary: strtod() gives inaccurate values on Alpine Linux (musl-libc) under valgrind
Product: [Developer tools] valgrind Reporter: Nick Little <nicklaus.little>
Component: generalAssignee: Julian Seward <jseward>
Status: RESOLVED DUPLICATE    
Severity: normal CC: pjfloyd
Priority: NOR    
Version: 3.21.0   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Test File

Description Nick Little 2023-06-29 15:40:30 UTC
Created attachment 159980 [details]
Test File

SUMMARY
When running under valgrind on Alpine Linux, strtod() gives inaccurate values. Test was performed on x86_64 architecture. (The same test on Ubuntu valgrind v3.19 yielded the correct values.)

Each test prints out the original value passed in followed by a comma and then the result of converting the value to a string (using sprintf(..., "%.17g", ...)) and parsing it using strtod(). Examining the bits of the resulting values indicates that the last 10-11 bits of the mantissa are zero'd out compared to the expected values. My best guess is that this has something to do with how valgrind's dynamic recompiler and musl's implementation of strtod().

STEPS TO REPRODUCE
1. Compile Test File: `g++ -Wall -o ValgrindStrtodTest ValgrindStrtodTest.cxx`
2. Run without valgrind to observe correct results: `./ValgrindStrtodTest`
3. Run with valgrind to observe incorrect results: `valgrind ./ValgrindStrtodTest`

OBSERVED RESULT
~ $ g++ -Wall -o ValgrindTest cal-ro/ValgrindTest.cxx
~ $ ./ValgrindTest
71596396.900554374, 71596396.900554374: GOOD
37033884.342276432, 37033884.342276432: GOOD
71596396.900543213, 71596396.900543213: GOOD
37033884.342269897, 37033884.342269897: GOOD
7.2506449597179708e+307, 7.2506449597179708e+307: GOOD
1.7428478780436407e+308, 1.7428478780436407e+308: GOOD
~ $ valgrind ./ValgrindTest
==108== Memcheck, a memory error detector
==108== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==108== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==108== Command: ./ValgrindTest
==108==
71596396.900554373, 71596396.900543212: BAD
37033884.342276431, 37033884.342269897: BAD
71596396.900543212, 71596396.900543212: GOOD
37033884.342269897, 37033884.342269897: GOOD
7.2506449597179707e+307, 7.2506449597178859e+307: BAD
1.7428478780436407e+308, 1.7428478780438379e+308: BAD
==108==
==108== HEAP SUMMARY:
==108==     in use at exit: 0 bytes in 0 blocks
==108==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==108==
==108== All heap blocks were freed -- no leaks are possible
==108==
==108== For lists of detected and suppressed errors, rerun with: -s
==108== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
~ $ uname -a
Linux cf8449d6eb32 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 Linux
~ $ cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.18.2
PRETTY_NAME="Alpine Linux v3.18"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

EXPECTED RESULT
The output when running with valgrind should match the output when running without valgrind:
71596396.900554374, 71596396.900554374: GOOD
37033884.342276432, 37033884.342276432: GOOD
71596396.900543213, 71596396.900543213: GOOD
37033884.342269897, 37033884.342269897: GOOD
7.2506449597179708e+307, 7.2506449597179708e+307: GOOD
1.7428478780436407e+308, 1.7428478780436407e+308: GOOD

SOFTWARE/OS VERSIONS
Linux: Alpine 3.18 image running on WSL

ADDITIONAL INFORMATION
Also performed the same test on WSL Ubuntu image. The expected results were observed.
Comment 1 Paul Floyd 2023-06-30 03:12:35 UTC
Does Musl use long doubles? Valgrind only handles 64 bit doubles.
Comment 2 Nick Little 2023-06-30 16:41:59 UTC
After looking through musl's strtod implementation, yes, long double is used. That is probably the issue.
Comment 3 Paul Floyd 2023-07-02 08:31:44 UTC
Marking this as a duplicate.

*** This bug has been marked as a duplicate of bug 421262 ***