Bug 41448 - std::sort on std::vector<float> with certain values leads to segfault in the vector destructor
Summary: std::sort on std::vector<float> with certain values leads to segfault in the ...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.3.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-09-23 15:44 UTC by Alexey Chernov
Modified: 2023-10-03 19:35 UTC (History)
2 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
The preprocessed file of the program (132.64 KB, application/octet-stream)
2009-09-23 15:45 UTC, Alexey Chernov
Details
Source code that triggers the bug (460 bytes, text/plain)
2009-09-23 15:48 UTC, Alexey Chernov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Chernov 2009-09-23 15:44:09 UTC
I suffer strange segfault in program using std::sort on std::vector<float>. The segfault occures in destructor of sorted std::vector after several sort/clear cycles. The values to reproduce the crash is actually decoded audio. I'm so sorry, I can't evaluate the proper sequence of bad values so I've uploaded the whole chunk here: http://downmusic.ru/test1 (110 mb sorry but i found no better way...) I know it's not the ideal way but maybe it helps.

As far as I found out it is because of NaNs in float vector. Also, std::stable_sort never leads to crash as I've tested.
Comment 1 Alexey Chernov 2009-09-23 15:45:30 UTC
Created attachment 18638 [details]
The preprocessed file of the program
Comment 2 Alexey Chernov 2009-09-23 15:47:52 UTC
Console output of g++ -v -save-temps -o gcc_sort -Wall -lQtCore -DQT_SHARED -I/usr/include/QtCore gcc_sort.cpp:

Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.3.2/configure --prefix=/usr --libexecdir=/usr/lib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++,fortran,objc,treelang --disable-multilib --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.3.2 (GCC)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'gcc_sort' '-Wall' '-DQT_SHARED' '-I/usr/include/QtCore' '-shared-libgcc' '-mtune=generic'
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/cc1plus -E -quiet -v -I/usr/include/QtCore -D_GNU_SOURCE -DQT_SHARED gcc_sort.cpp -mtune=generic -Wall -fpch-preprocess -o gcc_sort.ii
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../x86_64-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/QtCore
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/x86_64-unknown-linux-gnu
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/backward
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/include
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'gcc_sort' '-Wall' '-DQT_SHARED' '-I/usr/include/QtCore' '-shared-libgcc' '-mtune=generic'
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/cc1plus -fpreprocessed gcc_sort.ii -quiet -dumpbase gcc_sort.cpp -mtune=generic -auxbase gcc_sort -Wall -version -o gcc_sort.s
GNU C++ (GCC) version 4.3.2 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.3.2, GMP version 4.2.4, MPFR version 2.3.2.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 181aa37d41253b88eaf3c45c4486e83b
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'gcc_sort' '-Wall' '-DQT_SHARED' '-I/usr/include/QtCore' '-shared-libgcc' '-mtune=generic'
 as -V -Qy -o gcc_sort.o gcc_sort.s
GNU assembler version 2.18 (x86_64-unknown-linux-gnu) using BFD version (GNU Binutils) 2.18
COMPILER_PATH=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'gcc_sort' '-Wall' '-DQT_SHARED' '-I/usr/include/QtCore' '-shared-libgcc' '-mtune=generic'
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib/ld-linux-x86-64.so.2 -o gcc_sort /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../lib/crt1.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../lib/crti.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/crtbegin.o -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2 -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2 -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../.. -lQtCore gcc_sort.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/crtend.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../lib/crtn.o
Comment 3 Alexey Chernov 2009-09-23 15:48:42 UTC
Created attachment 18639 [details]
Source code that triggers the bug
Comment 4 Andrew Pinski 2009-09-23 15:57:19 UTC
I don't think this is a bug as the comparison function causes an unstable sort as NaNs are special and are unordered :).
Comment 5 Alexey Chernov 2009-09-23 16:04:24 UTC
Oh, I've tried to find info how the implementation manages NaNs but didn't find any clear info. So is it the expected behavior? And is it safe to use std::stable_sort for vectors with NaNs or I was just lucky?

Actually, NaNs in the flow is an error in my program which I fixed, but I decided to save the faulty state to file the report.
Comment 6 Andrew Pinski 2009-09-23 16:13:27 UTC
so in floating point world, NaNs are considered unordered that is X == NaN is always false for all values of  X including NaNs itself, likewise for >, <, <=,  and >=.  X != NaN is always true for all values of X including NaNs itself.

So NaNs will cause weird stuff to happen because it is always unordered.

Complex numbers are also considered unordered too :)
Comment 7 Alexey Chernov 2009-09-24 18:39:24 UTC
Is there anything in C++ Standard concerning this case?
Maybe it's more preferrable to throw exception or something like this.. Now it seems to make memory leak in the operated vector.

The output is like this:
*** glibc detected *** /usr/local/share/workspace/playground/gcc_sort: munmap_chunk(): invalid pointer: 0x0000000001d2c550 ***
*** glibc detected *** /usr/local/share/workspace/playground/gcc_sort: malloc(): memory corruption: 0x0000000001d2bca0 ***
Comment 8 Chris Jefferson 2009-09-29 11:04:12 UTC
Just to clarify, it is not a memory leak which is occurring, it is memory corruption. Basically when std::sort is given a type which is not totally ordered as required, it tends to corrupt the memory immediately before and after the given array. There are a few ways in which this could be detected, but if it was detected it's not obvious what the behaviour should then be, and obviously it would (slightly) slow down std::sort when given 'correct' types.
Comment 9 Paolo Carlini 2009-09-29 11:55:56 UTC
In C++03 this is not a bug. However, I seem to vaguely remember a recent discussion in the committee (basing on either a paper or a DR) about comparisons of floats, if somebody can find a reference I would appreciate it...
Comment 10 Alexey Chernov 2009-10-02 08:41:06 UTC
Yeah, I see..
But anyway, thank you for discussing it.