zhangmeishan / sparsehash

Automatically exported from code.google.com/p/sparsehash
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

dense_hash_map resize() throws "resize overflow" exception in 1.8.1 and 1.9 #64

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. create a dense_hash_map object, call set_empty_key, set_deleted_key and then 
call resize(1234). an exception gets throws with the message "resize overflow"
2.
3.

What is the expected output? What do you see instead?
I expect the map to be resized to 1234 buckets.

What version of the product are you using? On what operating system?
I am using gcc 4.4, CentOS 5.5. I tried with sparsehash 1.8.1 and 1.9 and both 
had the problem. With 1.7 it worked as expected.

Please provide any additional information below.
I have a hunch it is because in densehashtable.h, HT_OCCUPANCY_PCT is defined 
as an int, and then it creates the settings class it passes in 
"HT_OCCUPANCY_PCT / 100.0f", which it expects to be a double of 50.0, but 
because HT_OCCUPANCY_PCT is an int, it actually evaulates to 0.0 instead. In 
hashtable-common.h, in the "min_buckets" function, it uses that value as "float 
enlarge = enlarge_factor()", and if that value is 0.0 it causes the "while" 
loop below always be true and that leads to "sz" doubling until it reaches an 
overflow, and then it throws a "std::length_error("resize overflow")" exception.

Original issue reported on code.google.com by chaimmi...@gmail.com on 19 Jan 2011 at 1:01

GoogleCodeExporter commented 9 years ago
Weird, I can actually test on a centos 5.5 box, and all the tests pass for me.  
The HT_OCCUPANCY_PCT / 100.0f code should be ok -- the compiler will conver the 
int to a float here -- though of course you could have some weird compiler 
problem.

What happens when you run 'make check' -- do all the package tests pass?

Original comment by csilv...@gmail.com on 20 Jan 2011 at 1:37

GoogleCodeExporter commented 9 years ago

What steps will reproduce the problem?
1. Define a dense_hash_map object as part of a larger class definition.
2.
3.

What is the expected output? What do you see instead?
I expect the dense hash map to successfully compile and execute.
Compilation fails, due to a thrown "resize overflow" exception.

What version of the product are you using? On what operating system?
sparsehash-1.10
CentOS release 5.4 (Final)
gcc version 4.1.2 (Wind River VxWorks G++ DWARF-EH 4.1-181) -- cross-compiling 
from x86 to PPC603

Please provide any additional information below.
Compilation and make check are fine when targeting the host system.
Compiling same code with cross-compiler causes issue.
Somewhat difficult to integrate the package tests into my build at the moment, 
sorry...
It's triggering a huge number of compilation errors, and they're not likely all 
to be legit issues.

Some things that appear to be in the resize exception area : 

hashtable_test.cxx: In member function 
'void<unnamed>::TEST_HashtableDeathTest_ResizeOverflow::Run()':
hashtable_test.cxx:1612: error: exception handling disabled, use -fexceptions 
to enable

google/sparsehash/hashtable-common.h: In member function 'SizeType 
sh_hashtable_settings<Key, HashFunc, SizeType, 
HT_MIN_BUCKETS>::min_buckets(SizeType, SizeType) [with Key = int, HashFunc = 
__gnu_cxx::hash<int>, SizeType = unsigned int, int HT_MIN_BUCKETS = 4]':
google/sparsehash/sparsehashtable.h:760:   instantiated from 
'google::sparse_hashtable<Value, Key, HashFcn, ExtractKey, SetKey, EqualKey, 
Alloc>::sparse_hashtable(typename Alloc::rebind<Value>::other::size_type, const 
HashFcn&, const EqualKey&, const ExtractKey&, const SetKey&, const Alloc&) 
[with Value = int, Key = int, HashFcn = __gnu_cxx::hash<int>, ExtractKey = 
google::sparse_hash_set<int, __gnu_cxx::hash<int>, std::equal_to<int>, 
google::libc_allocator_with_realloc<int> >::Identity, SetKey = 
google::sparse_hash_set<int, __gnu_cxx::hash<int>, std::equal_to<int>, 
google::libc_allocator_with_realloc<int> >::SetKey, EqualKey = 
std::equal_to<int>, Alloc = google::libc_allocator_with_realloc<int>]'
google/sparse_hash_set:168:   instantiated from 'google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::sparse_hash_set(typename 
google::sparse_hashtable<Value, Value, HashFcn, google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::Identity, google::sparse_hash_set<Value, HashFcn, 
EqualKey, Alloc>::SetKey, EqualKey, Alloc>::size_type, const typename 
google::sparse_hashtable<Value, Value, HashFcn, google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::Identity, google::sparse_hash_set<Value, HashFcn, 
EqualKey, Alloc>::SetKey, EqualKey, Alloc>::hasher&, const typename 
google::sparse_hashtable<Value, Value, HashFcn, google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::Identity, google::sparse_hash_set<Value, HashFcn, 
EqualKey, Alloc>::SetKey, EqualKey, Alloc>::key_equal&, const Alloc&) [with 
Value = int, HashFcn = __gnu_cxx::hash<int>, EqualKey = std::equal_to<int>, 
Alloc = google::libc_allocator_with_realloc<int>]'
simple_test.cxx:62:   instantiated from here
google/sparsehash/hashtable-common.h:158: error: exception handling disabled, 
use -fexceptions to enable

Compiling simple_test.o
google/sparsehash/hashtable-common.h: In member function 'SizeType 
sh_hashtable_settings<Key, HashFunc, SizeType, 
HT_MIN_BUCKETS>::min_buckets(SizeType, SizeType) [with Key = int, HashFunc = 
__gnu_cxx::hash<int>, SizeType = unsigned int, int HT_MIN_BUCKETS = 4]':
google/sparsehash/sparsehashtable.h:760:   instantiated from 
'google::sparse_hashtable<Value, Key, HashFcn, ExtractKey, SetKey, EqualKey, 
Alloc>::sparse_hashtable(typename Alloc::rebind<Value>::other::size_type, const 
HashFcn&, const EqualKey&, const ExtractKey&, const SetKey&, const Alloc&) 
[with Value = int, Key = int, HashFcn = __gnu_cxx::hash<int>, ExtractKey = 
google::sparse_hash_set<int, __gnu_cxx::hash<int>, std::equal_to<int>, 
google::libc_allocator_with_realloc<int> >::Identity, SetKey = 
google::sparse_hash_set<int, __gnu_cxx::hash<int>, std::equal_to<int>, 
google::libc_allocator_with_realloc<int> >::SetKey, EqualKey = 
std::equal_to<int>, Alloc = google::libc_allocator_with_realloc<int>]'
google/sparse_hash_set:168:   instantiated from 'google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::sparse_hash_set(typename 
google::sparse_hashtable<Value, Value, HashFcn, google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::Identity, google::sparse_hash_set<Value, HashFcn, 
EqualKey, Alloc>::SetKey, EqualKey, Alloc>::size_type, const typename 
google::sparse_hashtable<Value, Value, HashFcn, google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::Identity, google::sparse_hash_set<Value, HashFcn, 
EqualKey, Alloc>::SetKey, EqualKey, Alloc>::hasher&, const typename 
google::sparse_hashtable<Value, Value, HashFcn, google::sparse_hash_set<Value, 
HashFcn, EqualKey, Alloc>::Identity, google::sparse_hash_set<Value, HashFcn, 
EqualKey, Alloc>::SetKey, EqualKey, Alloc>::key_equal&, const Alloc&) [with 
Value = int, HashFcn = __gnu_cxx::hash<int>, EqualKey = std::equal_to<int>, 
Alloc = google::libc_allocator_with_realloc<int>]'
simple_test.cxx:62:   instantiated from here
google/sparsehash/hashtable-common.h:158: error: exception handling disabled, 
use -fexceptions to enable

Original comment by PASimon...@gmail.com on 3 Jun 2011 at 8:39

GoogleCodeExporter commented 9 years ago
It looks like this (comment #2) is a separate problem.  The fix is likely to do 
what gcc tells you to do:
google/sparsehash/hashtable-common.h:158: error: exception handling disabled, 
use -fexceptions to enable

Original comment by csilv...@gmail.com on 4 Jun 2011 at 1:12

GoogleCodeExporter commented 9 years ago
Any more word on this (the original bug)?  I'm closing it CannotReproduce, but 
feel free to reopen it if you have more information.

Original comment by csilv...@gmail.com on 26 Aug 2011 at 1:09