Preventing double-free error with `stablePtr`
I was just reading Roman Cheplyaka’s very interesting blog-post here: https://ro-che.info/articles/2018-02-03-stableptr-undefined-behavior. As he points out, the docs for `freeStablePtr` say "if the stable pointer is passed to deRefStablePtr or freeStablePtr, the behaviour is undefined.” And indeed we can observe weird behavior as a result of sucn an error. A deRef of a stable pointer is arguably the sort of sharp-edge we know how to code to avoid. But a double free is a bit trickier. Would it be worth adding a bit more overhead to make such an operation idempotent? Additionally, would it be worthwhile to add `withStablePtr` to the `Foreign.StablePtr` module? I imagine there are cases that it won’t cover, but it would at least encourage good discipline in the cases that it does handle. The evident utility of such a function is witnessed by its existence in a few different codebases, not least the Win32 library ( https://hackage.haskell.org/package/Win32-2.6.2.0/docs/System-Win32-Types.ht... ) Cheers, Gershom
Catching double-frees does sound like a good idea to me. Also, is the wisdom in Roman’s post captured in the StablePtr docs? If not, can someone do that? Simon From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Gershom B Sent: 05 February 2018 01:38 To: Haskell Libraries <libraries@haskell.org> Subject: Preventing double-free error with `stablePtr` I was just reading Roman Cheplyaka’s very interesting blog-post here: https://ro-che.info/articles/2018-02-03-stableptr-undefined-behavior<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fro-che.info%2Farticles%2F2018-02-03-stableptr-undefined-behavior&data=02%7C01%7Csimonpj%40microsoft.com%7C10dc6ba9e74d4ec2bbbe08d56c39361a%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636533915338797696&sdata=Y3cT1XpzbPoD%2BTsf2qSkFhxPMkDeyRqV073fe2IRvaY%3D&reserved=0>. As he points out, the docs for `freeStablePtr` say "if the stable pointer is passed to deRefStablePtr or freeStablePtr, the behaviour is undefined.” And indeed we can observe weird behavior as a result of sucn an error. A deRef of a stable pointer is arguably the sort of sharp-edge we know how to code to avoid. But a double free is a bit trickier. Would it be worth adding a bit more overhead to make such an operation idempotent? Additionally, would it be worthwhile to add `withStablePtr` to the `Foreign.StablePtr` module? I imagine there are cases that it won’t cover, but it would at least encourage good discipline in the cases that it does handle. The evident utility of such a function is witnessed by its existence in a few different codebases, not least the Win32 library (https://hackage.haskell.org/package/Win32-2.6.2.0/docs/System-Win32-Types.html#v:withStablePtr<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fhackage.haskell.org%2Fpackage%2FWin32-2.6.2.0%2Fdocs%2FSystem-Win32-Types.html%23v%3AwithStablePtr&data=02%7C01%7Csimonpj%40microsoft.com%7C10dc6ba9e74d4ec2bbbe08d56c39361a%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636533915338797696&sdata=L45oTzaUhG8G7U%2Fp%2FIV85smqkxbub5UQqvGA%2B9cGuJI%3D&reserved=0>) Cheers, Gershom
would an alternative be to provide a helper that bundles a finalizer with the stable pointer and doens't allow explicit free on the associated stable pointer? On Tue, Feb 6, 2018 at 4:11 AM, Simon Peyton Jones via Libraries < libraries@haskell.org> wrote:
Catching double-frees does sound like a good idea to me.
Also, is the wisdom in Roman’s post captured in the StablePtr docs? If not, can someone do that?
Simon
*From:* Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Gershom B *Sent:* 05 February 2018 01:38 *To:* Haskell Libraries <libraries@haskell.org> *Subject:* Preventing double-free error with `stablePtr`
I was just reading Roman Cheplyaka’s very interesting blog-post here: https://ro-che.info/articles/2018-02-03-stableptr-undefined-behavior <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fro-che.info%2Farticles%2F2018-02-03-stableptr-undefined-behavior&data=02%7C01%7Csimonpj%40microsoft.com%7C10dc6ba9e74d4ec2bbbe08d56c39361a%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636533915338797696&sdata=Y3cT1XpzbPoD%2BTsf2qSkFhxPMkDeyRqV073fe2IRvaY%3D&reserved=0> .
As he points out, the docs for `freeStablePtr` say
"if the stable pointer is passed to deRefStablePtr or freeStablePtr, the behaviour is undefined.”
And indeed we can observe weird behavior as a result of sucn an error.
A deRef of a stable pointer is arguably the sort of sharp-edge we know how to code to avoid. But a double free is a bit trickier. Would it be worth adding a bit more overhead to make such an operation idempotent?
Additionally, would it be worthwhile to add `withStablePtr` to the `Foreign.StablePtr` module? I imagine there are cases that it won’t cover, but it would at least encourage good discipline in the cases that it does handle. The evident utility of such a function is witnessed by its existence in a few different codebases, not least the Win32 library ( https://hackage.haskell.org/package/Win32-2.6.2.0/docs/ System-Win32-Types.html#v:withStablePtr <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fhackage.haskell.org%2Fpackage%2FWin32-2.6.2.0%2Fdocs%2FSystem-Win32-Types.html%23v%3AwithStablePtr&data=02%7C01%7Csimonpj%40microsoft.com%7C10dc6ba9e74d4ec2bbbe08d56c39361a%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636533915338797696&sdata=L45oTzaUhG8G7U%2Fp%2FIV85smqkxbub5UQqvGA%2B9cGuJI%3D&reserved=0> )
Cheers,
Gershom
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Guaranteeing either idempotence or an error message seems to require that the stable pointer (but not what it points to) remain allocated until there are no more references to it. I don't know enough about these things to say how hard or expensive that might be. Another possibility might be to avoid reallocating a pointer too soon after it's freed; that would give a decent chance at an error and might be less expensive. On Feb 4, 2018 8:38 PM, "Gershom B" <gershomb@gmail.com> wrote:
I was just reading Roman Cheplyaka’s very interesting blog-post here: https://ro-che.info/articles/2018-02-03-stableptr-undefined-behavior.
As he points out, the docs for `freeStablePtr` say
"if the stable pointer is passed to deRefStablePtr or freeStablePtr, the behaviour is undefined.”
And indeed we can observe weird behavior as a result of sucn an error.
A deRef of a stable pointer is arguably the sort of sharp-edge we know how to code to avoid. But a double free is a bit trickier. Would it be worth adding a bit more overhead to make such an operation idempotent?
Additionally, would it be worthwhile to add `withStablePtr` to the `Foreign.StablePtr` module? I imagine there are cases that it won’t cover, but it would at least encourage good discipline in the cases that it does handle. The evident utility of such a function is witnessed by its existence in a few different codebases, not least the Win32 library ( https://hackage.haskell.org/package/Win32-2.6.2.0/docs/ System-Win32-Types.html#v:withStablePtr)
Cheers, Gershom
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (4)
-
Carter Schonwald -
David Feuer -
Gershom B -
Simon Peyton Jones