LLDB (Debugger) - LLDB (debugger)
Entwickler | LLVM-Entwicklergruppe |
---|---|
Repository | |
Geschrieben in | C++ |
Betriebssystem | macOS i386 und x86-64, Linux , FreeBSD , NetBSD , Windows |
Typ | Debugger |
Lizenz |
UIUC ( BSD-style ) Apache License 2.0 mit LLVM-Ausnahmen (v9.0.0 oder höher) |
Webseite | LLDB |
Der LLDB-Debugger ( LLDB ) ist die Debugger- Komponente des LLVM- Projekts. Es besteht aus einem Satz wiederverwendbarer Komponenten, die umfassend vorhandene Bibliotheken von LLVM verwenden, wie den Clang- Ausdrucksparser und den LLVM- Disassembler . LLDB ist kostenlos und Open-Source - Software unter der University of Illinois / NCSA Open Source Lizenz , eine BSD- permissiven Software - Lizenz . Seit v9.0.0 wurde es auf die Apache License 2.0 mit LLVM-Ausnahmen relizenziert .
Aktuellen Zustand
LLDB unterstützt das Debuggen von Programmen, die in C , Objective-C und C++ geschrieben wurden . Die Swift- Community unterhält eine Version, die die Sprache unterstützt. Es ist dafür bekannt, unter macOS , Linux , FreeBSD , NetBSD und Windows zu funktionieren und unterstützt i386- , x86-64- und ARM- Befehlssätze . LLDB ist der Standard-Debugger für Xcode 5 und höher. Android Studio verwendet auch LLDB zum Debuggen. LLDB kann von anderen IDEs verwendet werden, einschließlich Visual Studio Code , Eclipse und CLion .
Besonderheit | FreeBSD | Linux | Mac OS | NetBSD | Fenster |
---|---|---|---|---|---|
Rückverfolgung | |||||
Haltepunkte | |||||
C++11 | ? | ||||
Befehlszeilentool lldb | |||||
Kerndatei-Debugging | |||||
Debugserver (Remote-Debugging) | |||||
Demontage | |||||
Ausdrucksbewertung | ? | Funktioniert mit einigen Fehlern | Funktioniert mit einigen Fehlern | Funktioniert mit einigen Fehlern | |
JIT- Debugging | ? | Nur symbolisches Debuggen | Ungetestet | In Arbeit | |
Ziel-C 2.0: | ? | N / A | ? | N / A |
Beispiele für Befehle
lldb-Programm | Debug "Programm" (aus der Shell) |
---|---|
Lauf | Führen Sie das geladene Programm aus |
break set -n main | Setzen Sie einen Breakpoint am Anfang der Funktion "main" |
bt | Backtrace (falls das Programm abgestürzt ist) |
registrieren lesen | Alle Register löschen |
di -n main | Demontieren Sie die Funktion "main" |
Eine Beispielsitzung
Betrachten Sie das folgende falsche Programm, das in C geschrieben wurde :
#include <stdio.h>
int main(void)
{
char msg = "Hello, world!\n";
printf("%s", msg);
return 0;
}
Mit dem clang- Compiler unter macOS kann der obige Code mit dem -g
Flag kompiliert werden , um geeignete Debug-Informationen zu der generierten Binärdatei – einschließlich des Quellcodes – einzuschließen, was die Überprüfung mit LLDB erleichtert. Angenommen, die Datei, die den obigen Code enthält, heißt test.c
, der Befehl für die Kompilierung könnte wie folgt lauten:
$ clang -g test.c -o test
Und die Binärdatei kann jetzt ausgeführt werden:
$ ./test
Segmentation fault
Da der Beispielcode bei der Ausführung einen Segmentierungsfehler erzeugt , kann lldb verwendet werden, um das Problem zu untersuchen:
$ lldb test
(lldb) target create "test"
Current executable set to 'test' (x86_64).
(lldb) run
Process 70716 launched: '/Users/wikipedia/test' (x86_64)
Process 70716 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xffffff90)
frame #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>: and rcx, 0xf
0x7fff6c7c46fe <+30>: or rax, -0x1
Target 0: (test) stopped.
Das Problem tritt beim Aufrufen der Funktion auf strlen
, aber wir können einen Backtrace ausführen , um die genaue Codezeile zu identifizieren, die das Problem verursacht:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xffffff90)
* frame #0: 0x00007fff6c7c46f2 libsystem_platform.dylib`_platform_strlen + 18
frame #1: 0x00007fff6c66b16a libsystem_c.dylib`__vfprintf + 8812
frame #2: 0x00007fff6c6911c3 libsystem_c.dylib`__v2printf + 475
frame #3: 0x00007fff6c668e22 libsystem_c.dylib`vfprintf_l + 54
frame #4: 0x00007fff6c666f72 libsystem_c.dylib`printf + 174
frame #5: 0x0000000100000f6d test`main at test.c:5:2
frame #6: 0x00007fff6c5dc3d5 libdyld.dylib`start + 1
(lldb) source list
3 int main(void) {
4 char msg = "Hello, world!\n";
5 printf("%s", msg);
6 return 0;
7 }
Ab der Zeile, die mit beginnt frame #5
, zeigt LLDB an, dass der Fehler in Zeile 5 von auftritt test.c
. Laufen sehen source list
wir, dass sich dies auf den Aufruf bezieht printf
. EXC_BAD_ACCESS
Versucht gemäß dem Ausnahmecode aus dem Backtrace, strlen
aus einem Speicherbereich zu lesen, auf den er keinen Zugriff hat, indem er einen ungültigen Zeiger dereferenziert . Wenn wir zum Quellcode zurückkehren, sehen wir, dass die Variable msg
vom Typ ist, char
aber eine Zeichenfolge anstelle eines Zeichens enthält. Um das Problem zu beheben, ändern wir den Code, um anzugeben, dass msg
es sich um einen Zeiger auf eine Zeichenfolge handelt, chars
indem wir den *
Operator hinzufügen :
#include <stdio.h>
int main(void)
{
char* msg = "Hello, world!\n";
printf("%s", msg);
return 0;
}
Nach dem erneuten Kompilieren und erneuten Ausführen der ausführbaren Datei liefert LLDB nun das richtige Ergebnis:
(lldb) target create "test"
Current executable set to 'test' (x86_64).
(lldb) run
Process 93319 launched: '/Users/wikipedia/test' (x86_64)
Hello, world!
Process 93319 exited with status = 0 (0x00000000)
(lldb)
LLDB führt das Programm aus, das die Ausgabe printf
auf dem Bildschirm ausgibt . Nachdem das Programm normal beendet wurde, zeigt LLDB an, dass der Prozess, der das Programm ausführt, abgeschlossen ist, und gibt seinen Beendigungsstatus aus.