Ответ 1
TL;DR
Используйте gdb
(например, Linux):
-
echo 'call (void)rb_backtrace()' | gdb -p $(pgrep -f ruby)
или используйте lldb
(например, OS X):
-
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -f ruby)
Вы можете отлаживать Ruby script с помощью библиотеки отладки.
Если script выполняется из оболочки, это может быть достигнуто путем изменения первой строки (shebang) script в:
#!/usr/bin/env ruby -rdebug
или запустив его как:
ruby -rdebug my_script.rb
Как только отладчик загружен, вы можете настроить некоторые точки останова или просто запустить приложение, набрав c
, чтобы продолжить выполнение.
Затем отладчик автоматически разбивается на любые Исключения (такие как Ctrl+C) или контрольные точки (например, строки, которые состоят из debugger
).
Затем каждый раз, когда отображается консоль отладчика, вы можете выбирать между:
-
c
для продолжения (к следующему исключению, точке останова или строке с помощью:debugger
), -
n
для следующей строки, -
w
/where
для отображения стека кадров/вызовов, -
l
Чтобы показать текущий код, -
cat
, чтобы показать контрольные точки. -
h
для получения дополнительной справки.
Смотрите также: Отладка с ruby-debug, Ключевые ярлыки для рубинового отладочного камня.
Недостатком этого метода является то, что нет волшебной кнопки для подбора отладчика по требованию, кроме создания исключения в script, а также для отображения другого блока кода, а не зависания.
Вот несколько других идей:
- Добавьте оператор
debugger
в свой код, поднимите отладчик и пошаговый шаг. -
Используйте Pry отладчик (см.: GitHub).
Установить через:
gem install pry
, выполнить как:pry
или добавить какrequire 'pry'
. -
Попробуйте
lldb
(который должен заменитьgdb
), который может подключаться к текущему запуску процесса.Пример (замените
PID
на ваш идентификатор процесса):$ lldb -p PID (lldb) bt all * thread #1: tid = 0x11d68a, 0x00007fff86c71716 libsystem_kernel.dylib`__psynch_cvwait + 10 * frame #0: 0x00007fff86c71716 libsystem_kernel.dylib`__psynch_cvwait + 10 frame #1: 0x00007fff838a9c3b libsystem_pthread.dylib`_pthread_cond_wait + 727 frame #2: 0x0000000100241aad libruby.2.0.0.dylib`native_cond_wait + 29
Другой пример, показывающий обратную трассировку текущего рубинового ruby script (на его tty):
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -f ruby)
-
В качестве альтернативы используйте
gdb
(вы можете расширить его:gdb.rb
, который может показать вам объекты ruby).- Установить через:
sudo apt-get install gdb python-dev ncurses-dev && gem install gdb.rb
- В Unix/OS X нажмите Ctrl+T, чтобы проверить PID и что делать (или проверить через
ps wuax | grep ruby
). - Присоедините к процессу через:
gdb -p PID
.
См. также: с помощью gdb для проверки зависающего рубинового процесса, Обертка GDB для Ruby и Проверка реального процесса Ruby.
- Установить через:
- Другие библиотеки/инструменты, которые могут помочь включить: debugger, crash-watch, memprof, rack-perftools_profiler.
Если ничего не помогает, вы можете просто попробовать: strace
(Linux)/dtruss
(OS X) со следующим синтаксисом:
sudo strace -fp <PID>
sudo dtruss -fp <PID>
Или ltrace
, который может отслеживать вызовы библиотеки, а не системные вызовы strace
.
Если вы считаете, что это проблема сети, используйте tcpdump
.
См. также:
- Как отлаживать скрипты Ruby?
- Как настроить ruby для ввода отладчика в Ctrl-C (SIGINT)?
- Как использовать клавиатуру для взлома ruby-debug с помощью приложения rails?
- Есть ли способ использовать нажатие клавиши для вызова жука-рубика?
- Отладка застрявших рубиновых процессов - что делать до того, как вы убьете -9
- Инструменты для отладки Running Ruby Processes и Отладка Ruby Tools
- Отладка приложений Rails
- Правильный способ борьбы с замороженными процессами в Unix
- Отладка Ruby-приложений в Unix от Sergii Boiko
- Отладка с использованием Ruby Debugger в JumpstartLab
- ruby-debug за 30 секунд (нам не нужен графический интерфейс stinkin!)
- Как отлаживать застрявшие процессы Ruby