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

spec: some way to analyze or enforce data lifetimes #9743

Closed
tv42 opened this issue Jan 30, 2015 · 10 comments
Closed

spec: some way to analyze or enforce data lifetimes #9743

tv42 opened this issue Jan 30, 2015 · 10 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@tv42
Copy link

tv42 commented Jan 30, 2015

I wish -race or oracle or a new tool in the spirit of errcheck could help prevent these kinds of mistakes:

  1. io.Writer Write is not allowed to hold on to the buffer past its return. Yet that's an easy bug to cause; e.g. send the buffer on a channel.
  2. Anything that uses sync.Pool (or its own pool) for e.g. incoming network requests, and calls handler functions, has this issue if the handler holds on the value returned to the pool. This might include net/http.Handler Request, ResponseWriter, etc.
  3. As a more complex case, https://github.com/boltdb/bolt has func (db *DB) View(fn func(*Tx) error) error where the function passed in can do val := txn.Bucket(b).Get(key) and the val []byte is only valid inside that View transaction. It's quite easy to accidentally write
var result []byte
get := func(txn *bolt.Tx) error {
    result = txn.Bucket("widgets").Get("frobnizer")
    return nil
}
if err := db.View(get); err != nil { ... }

but the database is free to reuse the memory pointed to by result immediately after get returns.

@minux
Copy link
Member

minux commented Jan 31, 2015

I think reliably checking this is equivalent to solving the halting problem.
(because in general, data lifetime is undecidable, otherwise why do
we need GC at all? Just make the compiler intelligently insert malloc
and free and we're done.)

And unreliable checking will probably annoy the user. (Trivial cases
are easily checked, but what the user really wants is to be able to
check for those non-trivial cases.)

@extemporalgenome
Copy link
Contributor

Indeed, such analysis isn't tractable in the general case. Even in specific cases, it can be difficult in practice: for example, lifetime requirements can be maintained even when sending a []byte down a channel as long as the slice is no longer used by the time the return from, i.e., Write, occurs.

Because of the practical need for such a tool to strike some balance between accuracy and usefulness, it'd likely have to be a 3rd party tool with some kind of annotations or hinting (preferably outside of the Go code, perhaps similar to the API checking tool).

@minux
Copy link
Member

minux commented Feb 1, 2015

A dynamic checking tool for this is possible, but I'm not sure if it could
be done without runtime changes.

@dvyukov
Copy link
Member

dvyukov commented Feb 1, 2015

A rough idea:
Provide a function:
foo.AssertThisIsTheOnlyReferenceTo(ptr interface{})
Calls to this function are either inserted by user manually, or using code transformation technique similar to 'go test cover'.
The function dumps heap, analyzes it and ensures that the pointer is indeed the only reference to the object.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@bradfitz
Copy link
Contributor

bradfitz commented Feb 1, 2017

@alandonovan, are there existing checkers using your guru fanciness?

@bradfitz
Copy link
Contributor

bradfitz commented Feb 1, 2017

/cc @josharian

@alandonovan
Copy link
Contributor

@bradfitz nope. A static analysis for this problem would need to understand both control flow and aliasing, which makes it basically intractible. You could do it if the user supplied lots of information about ownership, but then you'd be programming in Rust, not Go.

@rsc rsc changed the title ponies: Ways to analyze or even enforce data lifetimes proposal: spec: some way to analyze or enforce data lifetimes Jun 20, 2017
@rsc rsc added the v2 A language change or incompatible library change label Jun 20, 2017
@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 9, 2018
@ianlancetaylor
Copy link
Contributor

This is not a Go 2 issue. It is a request for a different sort of tool. It might require some way to annotate the program, but if so that could be discussed separately as a general issue, not specific to this idea.

@ianlancetaylor ianlancetaylor removed v2 A language change or incompatible library change Proposal labels May 8, 2018
@rsc rsc changed the title proposal: spec: some way to analyze or enforce data lifetimes spec: some way to analyze or enforce data lifetimes Jun 11, 2018
@rsc rsc removed the Proposal label Jun 11, 2018
@rsc
Copy link
Contributor

rsc commented Jun 11, 2018

This is a wish, not a proposal. Nothing concrete is being proposed. I would love to have this too, but I don't know how to do it. Removing the proposal label again, and the prefix too, so gopherbot doesn't put the label back.

@rsc
Copy link
Contributor

rsc commented Jun 11, 2018

On second thought I don't think this is appropriate as an open issue. There's no concrete next action.

@rsc rsc closed this as completed Jun 11, 2018
@golang golang locked and limited conversation to collaborators Jun 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

9 participants