Уровень стека Ruby-профилировщика слишком глубокий

Кажется, что я всегда получаю эту ошибку на одном из моих сценариев:

/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)

Кто-нибудь сталкивался с этой ошибкой раньше? Что может быть причиной, и что я могу сделать, чтобы предотвратить это?

Я запускаю свои скрипты ruby-prof с помощью команды

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

Изменить Я на Mac OS X, если это имеет значение. дела ulimit -s 64000 кажется, не очень помогает, к сожалению. Вот что ulimit -a дает:

$ 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

Редактировать 2

Решение Эндрю Гримма отлично работало, чтобы предотвратить сбои ruby-prof, но у профилировщика, похоже, есть свои проблемы, потому что я вижу процент от 679.50% общего времени, затраченного на процесс...

3 ответа

Решение

Одним из обходных путей будет включение оптимизации хвостового вызова.

Ниже приведен пример того, что работает с включенной TCO, но не работает, когда TCO выключено.

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)

Уровень стека слишком глубокий обычно означает бесконечный цикл. Если вы посмотрите на код ruby-prof, где происходит ошибка, вы увидите, что это метод, который обнаруживает рекурсию в стеке вызовов.

Попробуйте заглянуть в код, где вы используете рекурсию (сколько мест в вашем коде вы можете использовать рекурсию?) И посмотрите, есть ли условие, из-за которого оно никогда не достигнет дна?

Это также может означать, что ваш системный стек просто недостаточно велик, чтобы справиться с тем, что вы пытаетесь сделать. Может быть, вы обрабатываете большой набор данных рекурсивно? Вы можете проверить размер вашего стека (Unixy системы):

$ ulimit -a

и увеличить размер стека:

$ ulimit -s 16384

Вы также можете рассмотреть возможность корректировки вашего алгоритма. Смотрите этот вопрос о переполнении стека

Я надеюсь, что я не просто перефразирую существующий вопрос...

Процентное превышение 100% в Ruby-prof было известной ошибкой, но должно быть исправлено сейчас.

Другие вопросы по тегам