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

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
*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"
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