LLDB (debuger)
Deweloperzy | Grupa programistów LLVM |
---|---|
Wersja stabilna | |
Magazyn | |
Napisane w | C++ |
System operacyjny | macOS i386 i x86-64, Linux , FreeBSD , NetBSD , Windows |
Typ | Debuger |
Licencja |
UIUC ( w stylu BSD ) Apache License 2.0 z wyjątkami LLVM (wersja 9.0.0 lub nowsza) |
Strona internetowa |
LLDB Debugger ( LLDB ) jest komponentem debugera projektu LLVM . Jest zbudowany jako zestaw komponentów wielokrotnego użytku, które intensywnie wykorzystują istniejące biblioteki LLVM, takie jak Clang i dezasembler LLVM . LLDB jest wolnym oprogramowaniem o otwartym kodzie źródłowym na licencji University of Illinois/NCSA Open Source License , zezwalającej licencji na oprogramowanie w stylu BSD . Od wersji 9.0.0 została zmieniona licencja na Apache License 2.0 z wyjątkami LLVM.
Stan aktulany
LLDB obsługuje debugowanie programów napisanych w C , Objective-C i C++ . Społeczność Swift utrzymuje wersję, która dodaje obsługę tego języka. Wiadomo, że działa na systemach macOS , Linux , FreeBSD , NetBSD i Windows oraz obsługuje zestawy instrukcji i386 , x86-64 i ARM . LLDB jest domyślnym debugerem dla Xcode 5 i nowszych. Studio Androida używa również LLDB do debugowania. LLDB może być używany z innych IDE, w tym Visual Studio Code , C++Builder , Eclipse i CLion .
Funkcja | FreeBSD | Linuks | System operacyjny Mac | NetBSD | Okna |
---|---|---|---|---|---|
Śledzenie | |||||
punktów przerwania | |||||
C++11 | ? | ||||
Narzędzie wiersza poleceń lldb | |||||
Debugowanie plików rdzenia | |||||
Serwer debugowania (zdalne debugowanie) | |||||
Dezasemblacja | |||||
Ocena ekspresji | Działa z kilkoma błędami | Działa z kilkoma błędami | Działa z kilkoma błędami | Działa z kilkoma błędami | |
Debugowanie JIT | ? | Tylko debugowanie symboliczne | Nietestowane | Praca w toku | |
Cel-C 2.0: | ? | — | ? | — |
Przykłady poleceń
program ldb
|
Debuguj „program” (z powłoki) |
---|---|
uruchomić
|
Uruchom załadowany program |
zestaw przerwań -n główny
|
Ustaw punkt przerwania na początku funkcji „main” |
bt
|
Backtrace (w przypadku awarii programu) |
rejestr przeczytany
|
Zrzuć wszystkie rejestry |
di -n główny
|
Zdemontuj funkcję „główna” |
Przykładowa sesja
Rozważ następujący niepoprawny program napisany w C :
0
#include <stdio.h> int main ( void ) { char msg = "Witaj, świecie! \n " ; printf ( "%s" , msg ); powrót ; }
Korzystając z kompilatora clang w systemie macOS , powyższy kod można skompilować przy użyciu flagi -g
w celu uwzględnienia odpowiednich informacji debugowania w wygenerowanym pliku binarnym — w tym w kodzie źródłowym — co ułatwia jego sprawdzenie za pomocą LLDB. Zakładając, że plik zawierający powyższy kod nosi nazwę test.c
, poleceniem kompilacji może być:
$ clang -g test.c -o test
A plik binarny można teraz uruchomić:
$ ./test Błąd segmentacji
Ponieważ przykładowy kod po wykonaniu generuje błąd segmentacji , można użyć lldb do sprawdzenia problemu:
$ lldb test (lldb) cel utwórz „test” Bieżący plik wykonywalny ustawiony na „test” (x86_64). (lldb) uruchom Uruchomiono proces 70716: „/Users/wikipedia/test” (x86_64) Proces 70716 zatrzymany * wątek nr 1, kolejka = „com.apple.main-thread”, powód zatrzymania = EXC_BAD_ACCESS (kod = 1, adres = 0xffffff90) ramka nr 0: 0x00007fff6c7c46f2 libsystem_platform.dylib`_platform_strlen + 18 libsystem_platform.dylib`_platform_strlen: -> 0x7fff6c7c46f2 <+18>: pcmpeqb xmm0, xmmword ptr [rdi]
0x7fff6c7c46f6 <+22>: pmovmskb esi, xmm0 0x7fff6c7c46fa <+26>: i rcx, 0xf 0x7fff6c7c46fe <+30>: lub rax, -0x1 Cel 0: (test) zatrzymany.
Problem występuje podczas wywoływania funkcji strlen
, ale możemy uruchomić śledzenie wsteczne , aby zidentyfikować dokładną linię kodu, która powoduje problem:
(lldb) bt * wątek nr 1, kolejka = 'com.apple.main-thread', powód zatrzymania = EXC_BAD_ACCESS (kod = 1, adres = 0xffffff90) * ramka nr 0: 0x00007fff6c7c46f2 libsystem_platform.dylib`_platform_strlen + 18 ramek nr 1 : 0x00007fff6c66b16a libsystem_c.dylib`__vfprintf + 8812 ramka #2: 0x00007fff6c6911c3 libsystem_c.dylib`__v2printf + 475 ramka #3: 0x00007fff6c668e22 libsystem_c.dylib`vfprintf_l + 54 ramka #4: 0x00007fff6c666f72 libsystem_c.dylib`printf + 174 ramka #5: 0x0000000100000f6d test`main at test.c:5:2 ramka nr 6: 0x00007fff6c5dc3d5 libdyld.dylib`start + 1
(lldb) source list 3 int main(void) { 4 char msg = "Witaj, świecie!\n"; 5 printf("%s", msg); 6 powrót 0; 7}
Od wiersza rozpoczynającego się od ramki nr 5
LLDB wskazuje, że błąd występuje w wierszu 5 pliku test.c.
Uruchamiając listę źródeł
, widzimy, że odnosi się to do wywołania printf
. Zgodnie z kodem wyjątku EXC_BAD_ACCESS
ze śladu wstecznego, strlen
próbuje odczytać z regionu pamięci, do którego nie ma dostępu, poprzez wyłuskanie nieprawidłowego wskaźnika. Wracając do kodu źródłowego, widzimy, że zmienna msg
jest typu char
ale zawiera ciąg znaków zamiast znaku. Aby rozwiązać ten problem, modyfikujemy kod, aby wskazać, że msg
jest wskaźnikiem do ciągu znaków
, dodając operator *
:
0
#include <stdio.h> int main ( void ) { char * msg = "Witaj świecie! \n " ; printf ( "%s" , msg ); powrót ; }
Po ponownej kompilacji i ponownym uruchomieniu pliku wykonywalnego, LLDB daje teraz poprawny wynik:
(lldb) cel utwórz „test” Bieżący plik wykonywalny ustawiony na „test” (x86_64). (lldb) uruchom Proces 93319 uruchomiony: „/Users/wikipedia/test” (x86_64) Witaj świecie! Proces 93319 zakończony ze statusem = 0 (0x00000000) (lldb)
LLDB uruchamia program, który wyświetla dane wyjściowe printf
na ekranie. Po normalnym zamknięciu programu LLDB wskazuje, że proces uruchamiający program zakończył się i drukuje jego status zakończenia.