Debuger
Część serii poświęconej |
tworzeniu oprogramowania |
---|
Debuger lub narzędzie do debugowania to program komputerowy używany do testowania i debugowania innych programów (program „docelowy”). Głównym zastosowaniem debuggera jest uruchamianie programu docelowego w kontrolowanych warunkach, które pozwalają programiście śledzić jego wykonanie i monitorować zmiany w zasobach komputera, które mogą wskazywać na wadliwy kod. Typowe funkcje debugowania obejmują możliwość uruchamiania lub zatrzymywania programu docelowego w określonych punktach, wyświetlania zawartości pamięci, rejestrów procesora lub urządzeń pamięci masowej (takich jak napędy dysków) oraz modyfikowania zawartości pamięci lub rejestrów w celu wprowadzenia wybranych danych testowych, które mogą być przyczyną błędnego wykonania programu.
Kod, który ma być zbadany, może alternatywnie działać na symulatorze zestawu instrukcji (ISS), technice, która zapewnia dużą moc w jego zdolności do zatrzymania, gdy napotkane zostaną określone warunki, ale która zazwyczaj będzie nieco wolniejsza niż wykonanie kodu bezpośrednio na odpowiednim (lub ten sam) procesor. Niektóre debuggery oferują dwa tryby działania, pełną lub częściową symulację, aby ograniczyć ten wpływ.
„ Pułapka ” pojawia się, gdy program nie może normalnie kontynuować działania z powodu błędu programistycznego lub nieprawidłowych danych. Na przykład program mógł próbować użyć instrukcji niedostępnej w aktualnej wersji procesora lub próbować uzyskać dostęp do niedostępnej lub chronionej pamięci . Kiedy program „zatrzymuje się” lub osiąga zadany warunek, debugger zwykle pokazuje lokalizację w oryginalnym kodzie, jeśli jest to debugger na poziomie źródłowym lub debugger symboliczny , często spotykany obecnie w zintegrowanych środowiskach programistycznych . Jeśli jest to debugger niskiego poziomu lub debugger języka maszynowego , pokazuje linię w dezasemblacji (chyba że ma również dostęp online do oryginalnego kodu źródłowego i może wyświetlić odpowiednią sekcję kodu z asemblera lub kompilacji).
Cechy
Zazwyczaj debugery oferują procesor zapytań, narzędzie do rozpoznawania symboli, interpreter wyrażeń i interfejs obsługi debugowania na najwyższym poziomie. Debugery oferują również bardziej wyrafinowane funkcje, takie jak uruchamianie programu krok po kroku ( pojedynczy krok lub animacja programu ), zatrzymanie ( przerwanie ) (wstrzymanie programu w celu sprawdzenia bieżącego stanu) przy jakimś zdarzeniu lub określonej instrukcji za pomocą punktu przerwania oraz śledzenie wartości zmiennych. Niektóre debuggery mają możliwość modyfikowania stanu programu podczas jego działania. Może być również możliwe kontynuowanie wykonywania w innym miejscu w programie, aby ominąć awarię lub błąd logiczny.
Ta sama funkcjonalność, która sprawia, że debugger jest przydatny do poprawiania błędów, pozwala na użycie go jako narzędzia do łamania oprogramowania w celu obejścia ochrony przed kopiowaniem , zarządzania prawami cyfrowymi i innych funkcji ochrony oprogramowania. Często czyni go również użytecznym jako ogólne narzędzie weryfikacyjne, wykrywanie błędów i analizator wydajności , zwłaszcza jeśli wyświetlane są długości ścieżek instrukcji . Wczesne mikrokomputery z pamięcią masową opartą na dyskach często korzystały z możliwości diagnozowania i odzyskiwania uszkodzonych rekordów danych katalogu lub rejestru, „cofnięcia” plików oznaczonych jako usunięte lub łamania ochrony plików hasłem.
Większość głównych silników debugowania, takich jak gdb i dbx , udostępnia interfejsy wiersza poleceń oparte na konsoli . Nakładki debugera to popularne rozszerzenia silników debugera, które zapewniają integrację IDE , animację programu i funkcje wizualizacji.
Nagrywaj i odtwarzaj debugowanie
Debugowanie w trybie nagrywania i odtwarzania , znane również jako „programowe nagrywanie lotu” lub „nagrywanie wykonania programu”, przechwytuje zmiany stanu aplikacji i zapisuje je na dysku podczas wykonywania każdej instrukcji w programie. Nagranie można następnie wielokrotnie odtwarzać i interaktywnie debugować w celu diagnozowania i usuwania usterek. Debugowanie w trybie nagrywania i odtwarzania jest bardzo przydatne do zdalnego debugowania i rozwiązywania sporadycznych, niedeterministycznych i innych trudnych do odtworzenia defektów.
Odwrotne debugowanie
Niektóre debugery zawierają funkcję o nazwie „ debugowanie wsteczne ”, znane również jako „debugowanie historyczne” lub „debugowanie wsteczne”. Debugery te umożliwiają cofnięcie wykonania programu w czasie. Różne debuggery zawierają tę funkcję. Program Microsoft Visual Studio (edycja 2010 Ultimate, 2012 Ultimate, 2013 Ultimate i 2015 Enterprise) oferuje odwrotne debugowanie IntelliTrace dla języków C#, Visual Basic .NET i niektórych innych języków, ale nie C++. Odwrotne debuggery istnieją również dla języków C, C++, Java, Python, Perl i innych. Niektóre są open source; niektóre są zastrzeżonym oprogramowaniem komercyjnym. Niektóre odwrotne debugery spowalniają cel o rzędy wielkości, ale najlepsze odwrotne debugery powodują spowolnienie 2× lub mniejsze. Debugowanie odwrotne jest bardzo przydatne w przypadku niektórych typów problemów, ale nadal nie jest jeszcze powszechnie stosowane.
Debugowanie podróży w czasie
Oprócz funkcji odwrotnych debuggerów, debugowanie w czasie pozwala również użytkownikom na interakcję z programem, zmianę historii w razie potrzeby i obserwowanie reakcji programu.
Zależność językowa
Niektóre debuggery działają w jednym określonym języku, podczas gdy inne mogą w przejrzysty sposób obsługiwać wiele języków. Na przykład, jeśli główny program docelowy jest napisany w języku COBOL , ale wywołuje podprogramy języka asemblera i podprogramy PL/1 , debugger może być zmuszony do dynamicznego przełączania trybów, aby uwzględnić zmiany w języku w miarę ich pojawiania się.
Ochrona pamięci
Niektóre debuggery zawierają również ochronę pamięci, aby uniknąć naruszeń pamięci, takich jak przepełnienie bufora . Może to być niezwykle ważne w przetwarzania transakcji , w których pamięć jest dynamicznie przydzielana z „pul” pamięci na podstawie zadania po zadaniu.
Wsparcie sprzętowe dla debugowania
Większość nowoczesnych mikroprocesorów ma co najmniej jedną z tych funkcji w projekcie procesora, aby ułatwić debugowanie:
- Wsparcie sprzętowe dla pojedynczego kroku programu, takie jak flaga pułapki .
- Zestaw instrukcji, który spełnia wymagania wirtualizacji Popka i Goldberga, ułatwia pisanie oprogramowania do debugowania, które działa na tym samym procesorze, co debugowane oprogramowanie; taki procesor może wykonywać wewnętrzne pętle testowanego programu z pełną prędkością i nadal pozostawać pod kontrolą debugera.
- Programowanie w systemie umożliwia zewnętrznemu debugerowi sprzętowemu przeprogramowanie testowanego systemu (na przykład dodanie lub usunięcie punktów przerwania instrukcji). Wiele systemów z taką obsługą ISP ma również inne wsparcie debugowania sprzętu.
- Wsparcie sprzętowe dla punktów przerwania kodu i danych , takich jak komparatory adresów i komparatory wartości danych lub, przy znacznie większym nakładzie pracy, sprzęt z błędami strony .
- JTAG do sprzętowych interfejsów debugowania, takich jak te w procesorach architektury ARM lub za pomocą zestawu poleceń Nexus . Procesory używane w systemach wbudowanych zazwyczaj mają rozbudowaną obsługę debugowania JTAG.
- Mikrokontrolery z zaledwie sześcioma pinami muszą używać substytutów JTAG o małej liczbie pinów, takich jak BDM , Spy-Bi-Wire lub debugWIRE w Atmel AVR . Na przykład DebugWIRE wykorzystuje dwukierunkową sygnalizację na pinie RESET.
Nakładki na debuger
Niektóre z najbardziej wydajnych i popularnych debuggerów implementują tylko prosty interfejs wiersza poleceń (CLI) — często w celu maksymalizacji przenośności i zminimalizowania zużycia zasobów. Deweloperzy zazwyczaj uważają, że debugowanie za pomocą graficznego interfejsu użytkownika (GUI) jest łatwiejsze i bardziej produktywne. [ Potrzebne źródło ] To jest powód wizualnych front-endów, które pozwalają użytkownikom monitorować i kontrolować podrzędne debuggery tylko z CLI za pośrednictwem graficznego interfejsu użytkownika . Niektóre interfejsy debugera GUI są zaprojektowane tak, aby były kompatybilne z różnymi debugerami obsługującymi tylko interfejs CLI, podczas gdy inne są ukierunkowane na jeden konkretny debuger.
Lista debuggerów
Niektóre powszechnie używane debuggery to:
- Ramię DTT , dawniej znane jako Allinea DDT
- Eclipse używany w różnych środowiskach IDE: Eclipse IDE (Java) Nodeclipse (JavaScript)
- Debuger JavaScript w Firefoksie
- GDB — debugger GNU
- LLDB
- Debuger Microsoft Visual Studio
- Radare2
- Valgrind
- WinDbg
Wcześniejsze debuggery minikomputerów obejmują:
mainframe obejmują:
Zobacz też
Cytaty
Źródła
- Sanjeev Kumar Aggarwal; M. Sarath Kumar (2003). „Debugery dla języków programowania” . W YN Srikant; Priti Shankar (red.). Podręcznik projektowania kompilatora: optymalizacje i generowanie kodu maszynowego . Boca Raton, Floryda: CRC Press . s. 295–327. ISBN 978-0-8493-1240-3 .
- Jonathan B. Rosenberg (1996). Jak działają debugery: algorytmy, struktury danych i architektura . John Wiley & Synowie . ISBN 0-471-14966-7 .
Linki zewnętrzne
- Narzędzia do debugowania dla systemu Windows
- OpenRCE: różne zasoby debugera i wtyczki
- IntelliTrace MSDN, Visual Studio 2015