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

runtime: detect infinite recursion during stack growth #2556

Closed
i3d opened this Issue Dec 12, 2011 · 8 comments

Comments

Projects
None yet
4 participants
@i3d
Copy link
Contributor

i3d commented Dec 12, 2011

What steps will reproduce the problem?
This simple code reveals an infinite print loop: 
package main 
import "fmt" 
import "log" 
import "runtime/debug" 
var count = 0 
type foo struct { 
  i int 
} 

func (f foo) String() string { 
  count++ 
  if count > 10 { 
    debug.PrintStack() 
    panic("call stack too large") 
  } 
  return fmt.Sprintf("foo@%p value: %d", f, f.i) 
} 

func main() { 
  f := foo{i: 3} 
  // ok 
  log.Println(fmt.Sprintf("foo@%p value: %d", &f, f.i)) 
  // inf loop 
  log.Printf("foo@%p, value: %d\n", f, f.i) 
} 

If you take out the loop protection in the code, you will end up crashing with no system
memory left.

What is the expected output?
There should be a callstack protection so that the program wouldn't chew up all the
system memories.

What do you see instead?
hang and eat up all the memories.

Which compiler are you using (5g, 6g, 8g, gccgo)?
6g, 8g

Which operating system are you using?
Linux 386/amd64

Which revision are you using?  (hg identify)
tip

Please provide any additional information below.

Ian's comment:

I think we should use the depth we are already passing down to catch 
this kind of loop before we eat all of memory.
@robpike

This comment has been minimized.

Copy link
Contributor

robpike commented Dec 12, 2011

Comment 1:

The actual bug in fmt is in issue #2555; once it's fixed (soon) the example will no
longer trigger the fault.
This bug is about general protection against infinite recursion and should have a
simpler example attached, perhaps something like
func main() {
  var a [1e6]int64
  _ = a
  main()
}

Status changed to Accepted.

@robpike

This comment has been minimized.

Copy link
Contributor

robpike commented Dec 20, 2011

Comment 2:

as advertised, the original program now works fine, but the related problem of detecting
infinite recursion is worth thinking about.
@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Sep 12, 2012

Comment 5:

Labels changed: added go1.1maybe.

@robpike

This comment has been minimized.

Copy link
Contributor

robpike commented Mar 7, 2013

Comment 6:

Labels changed: removed go1.1maybe.

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Mar 12, 2013

Comment 7:

[The time for maybe has passed.]
@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented May 29, 2013

Comment 8:

Issue #5587 has been merged into this issue.

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Jul 30, 2013

Comment 9:

Status changed to Duplicate.

Merged into issue #4692.

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Aug 16, 2013

Comment 10:

This issue was closed by revision 757e0de.

Status changed to Fixed.

@i3d i3d added fixed labels Aug 16, 2013

@golang golang locked and limited conversation to collaborators Jun 24, 2016

This issue was closed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.