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

Segfault in Weak.get_copy with Infix_tag #9485

Closed
stedolan opened this issue Apr 22, 2020 · 7 comments · Fixed by #9742
Closed

Segfault in Weak.get_copy with Infix_tag #9485

stedolan opened this issue Apr 22, 2020 · 7 comments · Fixed by #9742

Comments

@stedolan
Copy link
Contributor

The implementation of Weak.get_copy is missing the special case necessary to handle Infix_tag, so it can corrupt memory:

        OCaml version 4.10.0

# let w = Weak.create 1 in
  let rec f () = g () and g () = f () in
  Weak.set w 0 (Some g);
  match Weak.get_copy w 0 with Some h -> h () | _ -> ();;
Segmentation fault

I don't think this is particularly urgent to fix, because it's been there a long time without anyone noticing:

        Objective Caml version 3.10.2

# let w = Weak.create 1 in
  let rec f () = g () and g () = f () in
  Weak.set w 0 (Some g);
  match Weak.get_copy w 0 with Some h -> h () | _ -> ();;        
Segmentation fault
@bobot
Copy link
Contributor

bobot commented Apr 23, 2020

In the same vein than this issue #7810 reported by someone named @stedolan. Sorry to not have fixed those issues since 2 years ago.

@stedolan
Copy link
Contributor Author

I'd forgotten about that one!

This is a different Infix_tag bug, though - Weak.get_copy's reimplementation of Obj.dup is missing a case.

@bobot
Copy link
Contributor

bobot commented Apr 27, 2020

Do you think it is possible to directly call the code of Obj.dup?

@stedolan
Copy link
Contributor Author

Looking at it, I think there are enough differences that this would be awkward.

I think our best option might be to deprecate get_copy and make it be an alias for get - I don't think the optimisation it enables is really helpful any more.

@bobot
Copy link
Contributor

bobot commented May 14, 2020

I don't see what changed from when the optimisation was added. It is useful except in OCaml stdlib in weakhashset and weakhashtbl, in order to not make alive a value just to see it fail the equality test:

  • if the hash function is very bad
  • if it is a problem to keep the bindings that are colliding with an often accessed binding

Still I really don't like (hate?) get_copy, Obj.dup in disguise. So removing it in an MR and checking the behavior with e.g Frama-C and other opam packages can be very beneficial.

@stedolan
Copy link
Contributor Author

When the optimisation was added, an equality comparison was done whenever two keys ended up in the same bucket, which happens regularly. These days, and equality comparison is only done if two keys have exactly the same hash (not just bucket), which is very rare.

@bobot
Copy link
Contributor

bobot commented Jun 8, 2020

Indeed, I misremember the history. The weak hashtables were added in 0032c48, the use of the hash has been added many years later in db20929 (and described in Hashconsing in an Incrementally Garbage-Collected System by @damiendoligez and @pascal-cuoq).

So are you going to propose the removal of this function, at least from its use in weak hashtbl and deprecation?

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

Successfully merging a pull request may close this issue.

2 participants