4

It seems like I always get this error on one of my scripts:

/Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/ruby-prof-0.11.2/lib/ruby-prof/profile.rb:25: stack level too deep (SystemStackError)

Has anyone encountered this error before? What could be causing it, and what can I be doing to prevent it from happening?

I run my ruby-prof scripts using the command

ruby-prof --printer=graph --file=profile.txt scraper.rb -- "fall 2012"

Edit I'm on Mac OS X, if that matters. Doing ulimit -s 64000 doesn't seem to help much, unfortunately. Here is what ulimit -a gives:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 64000
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

Edit 2

Andrew Grimm's solution worked just fine to prevent ruby-prof from crashing, but the profiler seems to have problems of its own, because I see percentages like 679.50% of total time taken for a process...

wrongusername
  • 18,564
  • 40
  • 130
  • 214
  • Have you tried [turning tail call optimization on](http://stackoverflow.com/a/8735003/38765)? – Andrew Grimm Jul 31 '12 at 03:25
  • @AndrewGrimm Yes, that worked! Thanks!! I'll accept it if you enter it in as an answer – wrongusername Jul 31 '12 at 18:05
  • 1
    Solving the more than 100% percentages problem probably merits its own question. You're not the first person to have such an issue. I'm not sure what the culprit is though. – Andrew Grimm Aug 01 '12 at 02:24

3 Answers3

6

One workaround would be to turn tail call optimization on.

The following is an example of something that works with TCO on, but doesn't work when TCO is off.

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

def countUpTo(current, final)
  puts current
  return nil if current == final
  countUpTo(current+1, final)
end

countUpTo(1, 10_000)
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
3

Stack level too deep usually means an infinite loop. If you look at the ruby-prof code where the error happens you will see that it's a method that detects recursion in the call stack.

Try looking into the code where you are using recursion (how many places in your code can you be using recursion?) and see if there is a condition that would cause it to never bottom-out?

It could also mean that your system stack just isn't big enough to handle what you are trying to do. Maybe you are processing a large data set recursively? You can check your stack size (unixy systems):

$ ulimit -a

and increase the stack size:

$ ulimit -s 16384

You can also consider adjusting your algorithm. See this stack overflow quesion

I hope I'm not just re-hashing an existing question...

Community
  • 1
  • 1
radixhound
  • 2,190
  • 2
  • 18
  • 23
  • Well, my code works totally fine without the profiler, so I'm pretty sure it doesn't have any infinite loops. I did see the ulimit suggestion when Googling earlier, but when I execute `ulimit`, I get "unlimited" -- is this misleading? – wrongusername Jul 27 '12 at 20:09
  • Also, I don't see a stack trace when the program crashes -- just that one message. And it crashes when my programs ends -- I suspect that the program runs fine, but the profiler crashes after the program ends. – wrongusername Jul 27 '12 at 20:11
  • really? unlimited stack size? or are you looking at something else? `stack size (kbytes, -s) 8192` – radixhound Jul 27 '12 at 20:29
  • What's happening is you script ends and then the profiler is processing the call stack. So it's probably just hitting the stack limit. Upping your stack size is probably the ticket. – radixhound Jul 27 '12 at 20:30
  • I'm on a Mac, if that makes a difference. Probably does. Typing `ulimit 1000000` gives me `-bash: ulimit: stack size: cannot modify limit: Operation not permitted` – wrongusername Jul 27 '12 at 21:10
  • somehow you're missing the parameters e.g. `-a` and `-s` refer to my answer again. Also, why not set your stack size to something sane? – radixhound Jul 27 '12 at 21:42
  • I mean, I thought `ulimit` by itself gives the current stack limit. I'll try setting the stack size to something a bit smaller, haha. – wrongusername Jul 27 '12 at 22:01
  • I did `ulimit -s 64000` but it still gives the same error. Any ideas? – wrongusername Jul 28 '12 at 02:56
2

Having percentages go over 100% in Ruby-prof has been a known bug, but should be fixed now.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338