Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack gobbler in Hashtbl implementation #8426

Closed
vicuna opened this issue Dec 22, 2003 · 1 comment
Closed

Stack gobbler in Hashtbl implementation #8426

vicuna opened this issue Dec 22, 2003 · 1 comment

Comments

@vicuna
Copy link

vicuna commented Dec 22, 2003

Original bug ID: 1994
Reporter: administrator
Status: closed (set by @xavierleroy on 2006-06-17T09:56:17Z)
Resolution: won't fix
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Full_Name: Nuutti Kotivuori
Version: 3.07+7 (2003-12-17)
OS: Debian GNU/Linux
Submission from: aka.pp.htv.fi (213.243.183.115)

I stumbled on a rather nasty condition in Hashtbl that will cause a
stack overflow with a bit bigger than normal data amounts.

A snippet that demonstrates this:
,----
| let tbl = Hashtbl.create 10 in
| for i = 0 to 100000 do
| Hashtbl.add tbl 1 "test"
| done;;
`----

The bug is as follows - hash table resizing has a recursive function
called to migrate a single bucket to the new table and it is not tail
recursive.

Here's the bit of code:
,----[ hashtbl.ml ]
| let resize hashfun tbl =
| let odata = tbl.data in
| let osize = Array.length odata in
| let nsize = min (2 * osize + 1) Sys.max_array_length in
| if nsize <> osize then begin
| let ndata = Array.create nsize Empty in
| let rec insert_bucket = function
| Empty -> ()
| | Cons(key, data, rest) ->
| insert_bucket rest; (* preserve original order of elements *)
| let nidx = (hashfun key) mod nsize in
| ndata.(nidx) <- Cons(key, data, ndata.(nidx)) in
| for i = 0 to osize - 1 do
| insert_bucket odata.(i)
| done;
| tbl.data <- ndata;
| end
`----

In here, insert_bucket obviously isn't tail recursive.

So what it means is that if even a rather meager amount of values
happens to get stuffed in the same hash bucket, it will cause a
stack overflow.

I ran into this while using some of the standard bits in OCaml that
internally used a Hashtbl - so this ended up as a real and actual
problem.

-- Naked

@vicuna
Copy link
Author

vicuna commented Jun 22, 2004

Comment author: administrator

Full_Name: Nuutti Kotivuori
Version: 3.07+7 (2003-12-17)

I stumbled on a rather nasty condition in Hashtbl that will cause a
stack overflow with a bit bigger than normal data amounts.
[...]
The bug is as follows - hash table resizing has a recursive function
called to migrate a single bucket to the new table and it is not tail
recursive.

Thank you for your bug report. After careful consideration, we have
decided that a program exhibiting this behaviour is broken.

Instead of hiding the bug and degrading the performance catastrophically,
we think it's better to expose the bug (for example by triggering a stack
overflow). Hence, we will not try to fix this "problem" in Hashtbl.

I ran into this while using some of the standard bits in OCaml that
internally used a Hashtbl - so this ended up as a real and actual
problem.

This is interesting. I know this reply is very late, but can you still
give us more details about which part of OCaml, and under what
circumstances you found this problem?

-- Damien

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant