Discussion:
Preventing double-free error with `stablePtr`
Gershom B
2018-02-05 01:38:16 UTC
Permalink
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
Carter Schonwald
2018-02-06 19:49:23 UTC
Permalink
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 <
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
B
*Sent:* 05 February 2018 01:38
*Subject:* Preventing double-free error with `stablePtr`
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
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
David Feuer
2018-02-06 19:58:04 UTC
Permalink
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.
Post by Gershom B
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
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Loading...