Ostatnio było o debuggowaniu elixir z wykorzystaniem Visual Studio Code – co jest dalej uważam super opcją, mimo, że samo debugowanie ma swoje wady. Dziś zaś dla tycz wszystkich którzy nie lubią VS Code – wiem, że tacy są. Jak możemy nie tylko debuggować elixir, ale także erlang z wykorzystaniem narzędzi dostępnych w erlang OTP.
Dla celu krótkiego turoriala potrzebujemy jakiś prosty projekt który może robić nić albo może zawierać bencode.ex. Tą część przygotowawczą pozostawiam wam. Nie potrzebujemy niczego co będzie ładowane podczas startu. Więc naprawdę minimum jest wymagane.
Jak już wszystko mamy gotowe, to upewnijmy się, że przynajmniej mamy erlang w wersji 19 no i przypadłoby się zaktualizować elixir też. Ale jeżeli działało wam debugowanie w VS Code to tutaj nic nie musicie robić.
Zainicjalizowanie debuggera
Jeżeli mamy wszystko stworzone, wchodzimy za pomocą terminala do naszego katalogu projektu i odpalamy iex
:
iex -S mix
Następnie z miejsca uruchamiamy debuggera:
:debugger.start()
Ale byśmy mogli coś debuggować, to potrzebujemy załadować nasz moduł. W tym celu mamy dyspozycji moduł :int
i metodę ni/1
:
:int.ni(Bencode)
To spowoduje, że nasz moduł zostanie dodany do listy załadowanych modułów:
Oczywiście moglibyśmy dodać nasz moduł poprzez menu Modules | Interpret
Ale tutaj nie udało mi się załadować nigdy skompilowanego modułu (plik beam). Nie wiem czemu gdyż większość metod (jak nie wszystkie) z :int
są skrótem elementów z UI.
Mając nasz moduł załadowany, możemy go przeglądać Modules | Nasz Module | View
albo po prostu dwu klik na module z lewej strony okna Monitor.
Ustawienie breakpoint
Wydawałoby się takie proste………. A jednak. No dobra, jest to dość proste, możemy to zrobić z poziomu iex
:
:int.break(Bencode, 33)
Ale jest to o tyle trudne, że musimy znać linię kodu na której chcemy się zatrzymać. Na szczęście z widoku modułu (patrz poprzedni krok) możemy też dodawać breakpointy. Jeżeli otworzymy nasz moduł to mamy do dyspozycji trzy rodzaje breakpointów:
Line break
– jak sama nazwa wskazuje, zatrzymuje się na określonej linii;Conditional break
– zatrzymuje się wtedy kiedy jakiś warunek zostanie spełniony;Function break
– zatrzymuje się przy wywołaniu konkretnej funkcji (jak i wszystkich jej przeciążeń).
Za każdym razem możemy ustawić breakpointy dość prostu, jednak jeżeli nam przycisk OK nie działa to wystarczy zmodyfikować domyślne wartości w oknie, to znaczy nawet usunąć znak i go dodać, usunąć cyfrę z numeru linii i ją dodać. To spowoduje, że przycisk będzie śmigał.
Jeżeli zaś mamy dobrą pamięć to ogólnie moduł :int
daje nam bardzo dużo fajnych metod, warto przejrzeć je przynajmniej – możliwe, że ułatwią nam pracę, kto co lubi.
Proces debuggowania
Skoro mamy już wszystko przygotowane to w iex
możemy wyzwolić debuggera za pomocą wywołania funkcji, na której mamy ustawiony breakpoint:
Bencode.decode("i15e")
To zablokuje działanie iex
i w oknie Monitor zobaczymy taki o to widok:
Teraz jak klikniemy dwukrotnie na zaznaczonej linijce otworzy nam się nasze okno modułu z linijką, na której zatrzymał się debugger. Otwarcie tego za pomocą dwukliku na module, powoduje, że musimy kliknąć Step
by zobaczyć zatrzymanie debuggera. Dziwne, ale tak działa. Więc ku pamięci, klikamy na liście procesów nie na liście modułów :)
Teraz za pomocą przycisków możemy sterować co i jak:
Step
– wchodzenie w każdą możliwą linijkę, metodę;Next
– przechodzenie po kolejny linijkach danej metody;Continue
– przechodzi do następnego breakpoint albo końcy;Finish
– kończy;Up
iDown
– pozwala przechodzić pomiędzy funkcjami/stack trace; tak jakby skąd tutaj trafiłem, wróć tam gdzie jestem.
Podsumowanie
To tyle, nie udało mi się zmienić wartości zmiennych, ale to chyba zrozumiałem ;) tylko Elixir na to zezwala a erlang nie, choć opcja edycji jest możliwa – nie wiem zaś czy ona działa czy też nie.
Temat debuggowania rozwiązań elixirowych nie jest skończony, są dodatkowe opcje i metody które są dużo bardziej wydajniejsze. Choć ja i tak dalej lubię okienkowe debuggowanie :) O tych innych opcjach, może jeszcze kiedyś napiszę :)