Rusrails налагодження за допомогою гема - debugger

Коли ваш код поводиться несподіваним чином, можете друкувати в логи або консоль, щоб виявити проблему. На жаль, іноді буває, що такий спосіб відстеження помилки не ефективний в пошуку причини проблеми.

Коли ви фактично потребуєте подорожі вглиб виконуваного коду, відладчик - це ваш кращий напарник.

Отладчик також може допомогти, якщо хочете вивчити вихідний код Rails, але не знаєте з чого почати. Просто отладьте будь-який запит до свого додатком і використовуйте це керівництво для вивчення, як йде рух від написаного вами коду глибше в код Rails.

Rails використовує гем debugger для настройки точок зупинки і проходження через живий код. Щоб встановити його, просто запустіть:

У Rails є вбудована підтримка налагодження, починаючи з Rails 2.0. Усередині будь-якої програми на Rails можна викликати відладчик, викликавши метод debugger.

Якщо бачите повідомлення в консолі або балках:

Переконайтеся, що запустили свій веб сервер з опцією --debugger:

У режимі development можна динамічно викликати require \ 'debugger \' замість перезапуску сервера, якщо він був запущений без --debugger.

Як тільки додаток викликає метод debugger. відладчик буде запущений в середовищі отладчика у вікні терміналу, в якому запущений сервер додатки, і буде представлена ​​рядок debugger (rdb: n). n це число тредов. Рядок також показує наступну лінію коду, яка очікує виконання.

Якщо було отримано запит від браузера, закладка браузера, яка містить запит, буде висіти, поки відладчик закінчить, і трасування закінчить обробляти весь запит.

Настав час вивчити і покопатися в вашому додатку. Для початку добре б попросити допомогу у відладчика ... тому напишіть: help (Несподівано, правда?)

Наступна команда, яку ми вивчимо, одна з найкорисніших: list. Можна скорочувати будь-які налагоджувальні команди, надаючи тільки достатні літери для відрізнення їх від інших команд, тому можна використовувати l для команди list.

Ця команда показує, де ви зараз в коді, друкуючи 10 ліній з поточної лінією в центрі; поточна лінія в цьому випадку шоста і позначена =>.

Якщо повторіть команду list. Зараз вже використовуємо лише l. будуть виведені наступні 10 ліній файлу.

І так далі до кінця поточного файлу. Коли досягнуто кінець файлу, команда list запуститься знову з початку файлу і продовжиться знову до кінця, обробляючи файл як циклічний буфер.

З іншого боку, щоб побачити попередні десять ліній, слід написати list- або l-.

Таким чином можна переміщатися всередині файлу, переглядаючи код до і після рядка, в яку ви додали debugger. Нарешті, щоб знову побачити, де ви в коді зараз, можна написати list =.

Коли починаєте налагодження свого застосування, ви будете поміщені в різні контексти, так як проходите через різні частини стека.

debugger створює контекст, коли досягається точка зупинки або подія. У контексту є інформація про призупиненої програми, яка дозволяє отладчику переглядати кадр стека, значення змінних з точки зору налагоджують програму, і в ньому міститься інформація про місце, в якому налагоджують програму зупинилася.

У будь-який час можете викликати команду backtrace (або її псевдонім where), щоб надрукувати трасування програми. Це корисно для того, щоб знати, де ви є. Якщо ви коли-небудь замислювалися, як ви отримали щось в коді, то backtrace надасть відповідь.

Можете перейти, куди хочете в цій трасування (це змінить контекст) з використанням команди frame _n_. де n це певний номер кадру.

Доступні змінні ті ж самі, як якщо б ви запускали код рядок за рядком. Зрештою, це те, що регламентуватиме.

Переміщення по кадру стека: можете використовувати команди up [n] (скоращенно u) і down [n] для того, щоб змінити контекст на n кадрів вгору або вниз по стеку відповідно. n за замовчуванням дорівнює одному. Up в цьому випадку перейде до кадрів стека з великим номером, а down до кадрів з меншим номером.

Нитки (threads)

Отладчик може переглядати, зупиняти, поновлювати та перемикатися між запущеними нитками з використанням команди thread (або скорочено th). У цієї команди є кілька опцій:

  • thread показує поточну нитку
  • thread list використовується для відображення всіх ниток і їх статусів. Символ плюс + і число показують поточну нитку виконання.
  • thread stop _n_ зупиняє нитка n.
  • thread resume _n_ відновлює нитка n.
  • thread switch _n_ перемикає контекст поточної нитки на n.

Ця команда дуже корисна, зокрема коли ви налагоджувати паралельні нитки і потрібно переконатися, що в коді немає стану гонки.

Будь-яке вираження може бути обчислено в поточному контексті. Щоб обчислити вираз, просто надрукуйте його!

Цей приклад покаже, як можна надрукувати instance_variables, певні в поточному контексті:

Як ви вже зрозуміли, відображені всі змінні, до яких є доступ з контролера. Цей перелік динамічно оновлюється по мірі виконання коду. Наприклад, запустимо наступний рядок, використовуючи next (ми розглянемо цю команду трохи пізніше в цьому керівництві).

І потім знову запитаємо instance_variables:

Також можна зробити крок в режим irb з командою irb (звичайно!). Таким чином, сесія irb буде запущена в контексті, який її викликав. Але попереджаємо: це експериментальна особливість.

Метод var це більш зручний спосіб показати змінні і їх значення:

Команди p (print) і pp (pretty print) можуть використовуватися для обчислення виразів Ruby і відображення значення змінних в консолі.

Змінні в видимій частині переліку будуть друкуватися з їх значеннями після приміщення в стек. Щоб зупинити відображення змінної, використовуйте undisplay _n_. де n це номер змінної (1 в останньому прикладі).

Крок за кроком

Тепер ви знаєте, де перебуваєте в запущеній трасування, і здатні надрукувати доступні змінні. Давайте продовжимо і ознайомимося з виконанням програми.

Використовуйте step (скорочено s) для продовження запуску вашої програми до наступної логічної точки зупину і повернення контролю debugger.

Також можна використовувати step + n і step- n для руху вперед або назад на n кроків відповідно.

Також можете використовувати next. яка схожа на step, але виклики функції або методу, що виконуються в рядку коду, виконуються без зупинки. Як і з step, можна використовувати знак плюса для переміщення на n кроків.

Різниця між next і step в тому, що step зупиняється на наступній лінії виконуваного коду, роблячи лише один крок, в той час як next переміщує на наступний рядок без входу всередину методів.

Наприклад, розглянемо цей блок коду з включеним виразом debugger:

Можете використовувати debugger при використанні rails console. Просто не забудьте викликати require "debugger" перед викликом методу debugger.

З зупиненим кодом, давайте оглянемося:

Якщо хочете увійти глибше в трасування стека, можете переміститися на один крок step. через ваші викликають методи і в код Rails. Це кращий спосіб пошуку багів в вашому коді, а можливо і в Ruby or Rails.

точки зупинки

Точка зупину зупиняє ваше додаток, коли досягається певна точка в програмі. У цій лінії викликається оболонка відладчика.

Можете додавати точки зупину динамічно за допомогою команди break (або просто b). Є 3 можливих способу ручного додавання точок зупину:

  • break line. встановлює точку зупину в лінії line в поточному файлі исходника.
  • break file: line [if expression]. встановлює точку зупину в лінії номер line в файлі file. Якщо задана умова expression. воно повинно бути обчислено і дорівнювати true. щоб запустити відладчик.
  • break class (. | #) method [if expression]. встановлює точку зупину в методі method (. і # для методу класу і примірника відповідно), визначеного в класі class. expression працює так само, як і з file: line.

Використовуйте info breakpoints _n_ або info break _n_ для відображення переліку точок зупину. Якщо вкажете номер, відобразиться тільки ця точка зупинки. В іншому випадку відобразяться всі точки зупинки.

Щоб видалити точки зупину: використовуйте команду delete _n_ для усунення точки зупину номер n. Якщо номер не вказано, втечуть всі точки зупинки, які в даний момент активні ..

Також можна включити або відключити точки зупину:

  • enable breakpoints. дозволяє переліку breakpoints або всім їм, якщо перелік не визначений, зупиняти вашу програму. Цей стан за замовчуванням для створюваних точок зупину.
  • disable breakpoints. breakpoints не впливатимуть на вашу програму.

вилов винятків

Команда catch exception-name (або просто cat exception-name) може використовуватися для перехоплення виключення типу exception-name. коли в іншому випадку був би викликаний оброблювач для нього.

відновлення виконання

Є два способи відновлення виконання програми, з якою було зупинено отладчиком:

редагування

Щоб вийти з відладчика, використовуйте команду quit (скорочено q), або її псевдонім exit.

Простий вихід намагається припинити всі нитки в результаті. Тому ваш сервер буде зупинений і потрібно буде стартувати його знову.

  • set reload. презагрузіть вихідний код при зміні.
  • set autolist. Запускати команду list на кожній точці зупинки.
  • set listsize _n_. Встановити кількість ліній коду для відображення за замовчуванням n.
  • set forcestep. Переконуватися, що команди next і step завжди переходять на нову лінію

Ці установки можуть бути збережені в файлі .rdebugrc в домашній директорії. debugger зчитує ці глобальні настройки при запуску.

Ось хороший початок для .rdebugrc: