Detaillierte Erklärung der grundlegenden Verwendung des Linux-Debuggers GDB

Detaillierte Erklärung der grundlegenden Verwendung des Linux-Debuggers GDB

1. Übersicht

Drei Möglichkeiten zum GDB-Debuggen:

1. Die Zielplatine wird direkt mithilfe von GDB debuggt.

2. Die Zielplatine verwendet gdbserver und der Host verwendet xxx-linux-gdb als Client.

3. Die Zielplatine verwendet ulimit -c unlimited, um eine Core-Datei zu generieren; dann verwendet der Host xxx-linux-gdb ./test ./core.

2. GDB-Debugging

Bauen Sie die Testprogramme main.c und sum.c wie folgt auf:

main.c: #include <stdio.h>
#include <stdlib.h>
 
extern int Summe(int Wert);
 
Struktur inout {
    int-Wert;
    int Ergebnis;
};

int main(int argc, char * argv[])
{
    Struktur inout * io = (Struktur inout * ) malloc(sizeof(Struktur inout));
    wenn (NULL == io) {
        printf("Malloc ist fehlgeschlagen.\n");
        Rückgabe -1;
    }

    wenn (argc != 2) {
        printf("Falscher Absatz!\n");
        Rückgabe -1;
    }

    io->Wert = *argv[1] - '0';
    io->Ergebnis = Summe(io->Wert);
    printf("Ihre Eingabe: %d, Ergebnis: %d\n", io->Wert, io->Ergebnis);
    gebe 0 zurück;
}
Summe.c:
int Summe(int Wert) {
    int-Ergebnis = 0;
    }
    für (i = 0; i < Wert; i++)
        Ergebnis += (i + 1);
    Ergebnis zurückgeben;
}

Holen Sie sich dann mit gcc main.c sum.c -o main -g die ausführbare Hauptdatei.

Im Folgenden werden die meisten Funktionen von gdb vorgestellt. 1.1 Das Setzen von Haltepunkten und 1.3 Das Anzeigen von Stapelrahmen sind häufig verwendete Funktionen. Während des Debuggens können 1.6 Einzelschrittausführung, 1.4 Anzeigen von Variablen, 1.5 Anzeigen von Registern, 1.8 Überwachungspunkte und 1.9 Ändern von Variablenwerten erforderlich sein.

Wenn der Prozess bereits ausgeführt wird, müssen Sie in 1.11 eine Verbindung zum Prozess herstellen oder in 1.10 eine Dump-Datei zur Analyse generieren. Um die Effizienz zu verbessern, können Sie die Initialisierungsdatei 1.13 natürlich anpassen.

2.1. Haltepunkte setzen

Sie können Haltepunkte mit b oder break setzen. Haltepunkte können durch Funktionsnamen, Zeilennummer, Dateiname + Funktionsname, Dateiname + Zeilennummer, Offset, Adresse usw. gesetzt werden.

Das Format ist:

Name der Unterbrechungsfunktion

Zeilenumbruchnummer

break Dateiname: Funktionsname

Unterbrechungsdateiname:Zeilennummer

Unterbrechung + Verschiebung

brechen - verschieben

Pause *Adresse

Überprüfen Sie die Haltepunkte und zeigen Sie die Haltepunktliste über „Info-Break“ an.

Zum Löschen von Haltepunkten können folgende Befehle verwendet werden:

delete <breakpoint id>: Löscht den angegebenen Breakpoint.

delete: alle Haltepunkte löschen

klar

Funktionsnamen löschen

Zeilennummer löschen

Dateiname löschen:Zeilennummer

Dateinamen löschen: Funktionsname

Haltepunkte können auch bedingt unterbrochen werden

Haltepunkt unterbrechen, wenn Bedingung; z. B. „Break sum if value==9“, die Ausführung wird erst beendet, wenn der Eingabewert 9 ist.

Bedingungs-Haltepunktnummer: Löscht die Auslösebedingung für den angegebenen Haltepunkt

Bedingung Haltepunktnummer-Bedingung: Fügen Sie dem angegebenen Haltepunkt eine Auslösebedingung hinzu

Wie unten zu sehen ist, wird der Vorgang unterbrochen, wenn der Eingabeparameter 9 ist, und wenn der Eingabeparameter 8 ist, wird der Vorgang bis zum Ende ausgeführt.

Haltepunkte können mit „disable“/„enable“ auch vorübergehend deaktiviert oder aktiviert werden.

deaktivieren

Haltepunktnummer deaktivieren

Anzeige deaktivieren Nummer anzeigen

Mem-Speicherbereich deaktivieren

aktivieren

Haltepunktnummer aktivieren

Haltepunktnummer einmal aktivieren: Dieser Haltepunkt wird nur einmal aktiviert. Nachdem das Programm bis zu diesem Haltepunkt durchgelaufen ist und angehalten hat, wird der Haltepunkt deaktiviert.

Löschen der Haltepunktnummer aktivieren

Anzeige aktivieren Anzeigenummer

Mem-Speicherbereich aktivieren

2.1.1. Erweiterte Funktionen von Haltepunktbefehlen

Meistens müssen Sie an einem Haltepunkt eine Reihe von Aktionen ausführen. gdb bietet eine erweiterte Funktion namens „Commands“, um Befehle an Haltepunkten auszuführen.

#include <stdio.h>

int-gesamt = 0;

int Quadrat(int i)
{
    int Ergebnis=0;

    Ergebnis = i*i;

    Ergebnis zurückgeben;
}

int main(int argc, char **argv)
{
    int ich;

    für (i = 0; i < 10; i++)
    {
        Gesamtsumme += Quadrat(i);
    }
    gebe 0 zurück;
}

Beispielsweise müssen wir im obigen Programm einen Haltepunkt setzen, wenn der Quadratparameter i 5 ist, und zu diesem Zeitpunkt die Werte des Stapels, der lokalen Variablen und der Gesamtsumme ausdrucken.

Schreiben Sie gdb.init wie folgt:

Protokollierung für gdb.log festlegen


b Quadrat, wenn i == 5
Befehle
  bt voll
  ich Einheimische
  p gesamt
  drucken "Drücken Sie Break, wenn i == 5"
Ende

Rufen Sie in der GDB-Shell gdb.init auf und führen Sie anschließend den Befehl r aus. Die Ergebnisse sind wie folgt:

Es ist ersichtlich, dass der Haltepunkt unterbrochen wird, wenn i == 5 ist, und zu diesem Zeitpunkt wird der korrekte Wert gedruckt.

2.2. Betrieb

Nach „gdb-Befehl“ kann „run“ den Befehl unter gdb ausführen; wenn der Befehl Parameter erfordert, folgen diese „run“.

Wenn Sie einen Haltepunkt bei main() benötigen, führen Sie „start“ einfach direkt aus.

2.3. Stapelrahmen anzeigen

Wenn ein Haltepunkt erreicht wird, wird die Ausführung angehalten oder Coredump kann den Stack-Frame anzeigen.

bt kann den Stack-Frame anzeigen und bt full kann lokale Variablen anzeigen.

Das Befehlsformat ist wie folgt:

bt

bt full: zeigt nicht nur Backtrace, sondern auch lokale Variablen an

bt N: Zeigt die ersten N Stackframes an

bt voll SUBST

2.4. Anzeigevariablen

Mit „print variable“ kann der Inhalt der Variable angezeigt werden.

Wenn Sie mehrere Variablen in einer Zeile überwachen müssen, können Sie p {var1, var2, var3} verwenden.

Wenn Sie die automatische Anzeige verfolgen möchten, können Sie display {var1, var2, var3} verwenden.

2.5. Anzeigeregister

Über info reg kann der Registerinhalt angezeigt werden.

Fügen Sie vor dem Registernamen ein $ hinzu, um den Registerinhalt anzuzeigen.

p $register: Registerinhalt anzeigen

p/x $register: Registerinhalte hexadezimal anzeigen.

Verwenden Sie den Befehl x, um den Inhalt „x/Formatadresse“ anzuzeigen.

x $pc: Zeigt den Inhalt des Programmzeigers an

x/i $pc: Programmzeigerassemblierung anzeigen.

x/10i $pc: Zeigt 10 Anweisungen nach dem Programmzeiger an.

x/128wx 0xfc207000: Druckt 128 Wörter im Hexadezimalformat, beginnend bei 0xfc20700.

Sie können es auch mit dem Befehl „disassemble“ zerlegen.

zerlegen

Programmzähler zerlegen: Zerlegen Sie die gesamte Funktion, in der sich der PC befindet.

disassemblieren addr-0x40, addr+0x40: disassemblieren Sie Adresse mit 0x40 davor und danach.

2.6. Einzelschrittausführung

Es gibt zwei Befehle für die Einzelschrittausführung: „next“ und „step“. Der Unterschied zwischen den beiden besteht darin, dass „next“ die Funktion nicht aufruft, wenn eine Funktion auftritt, „step“ jedoch die Funktion ausführt.

Wenn Sie Assembly-Anweisungen einzeln ausführen müssen, können Sie jeweils nexti und stepi verwenden.

2.7. Ausführung fortsetzen

Verwenden Sie beim Debuggen den Befehl „Continue“, um die Programmausführung fortzusetzen. Nach einem Stromausfall wird das Programm erneut angehalten und, sofern kein Haltepunkt vorhanden ist, bis zum Ende weiter ausgeführt.

continue: Ausführung fortsetzen

Mal fortsetzen: Ausführung eine bestimmte Anzahl Mal fortsetzen.

2.8. Überwachungspunkte

Um herauszufinden, wo eine Variable geändert wird, können Sie mit dem Watch-Befehl einen Überwachungspunkt setzen.

watch <Ausdruck>: Pausiert, wenn sich der Ausdruck ändert

awatch<Ausdruck>: Ausdruck wird aufgerufen, Änderungen werden angehalten

rwatch<Ausdruck>: Ausführung anhalten, wenn auf den Ausdruck zugegriffen wird

Andere Varianten umfassen watch expr [Thread Thread-ID] [Maske Maskenwert], wobei die Maske Architekturunterstützung erfordert.

GDB kann eine Konstante nicht überwachen; beispielsweise würde die Überwachung 0x600850 einen Fehler melden.

Aber Sie können *(int *)0x600850 beobachten.

2.9. Den Wert einer Variablen ändern

Ändern Sie den Wert einer Variablen mit „set variable <variable>=<expression>“.

set $r0=xxx: Setzt den Wert des Registers r0 auf xxx.

2.10. Eine Kernel-Dump-Datei erzeugen

Generieren Sie über „generate-core-file“ eine core.xxxx-Dumpdatei.

Verwenden Sie dann gdb ./main ./core.xxxx, um die wiederhergestellte Szene anzuzeigen.

Ein anderer Befehl, gcore, kann eine Core-Dump-Datei direkt von der Befehlszeile aus generieren.

gcore „pidof-Befehl“: Dump-Datei abrufen, ohne das ausgeführte Programm zu stoppen.

2.11. An den Prozess anhängen

Wenn das Programm bereits ausgeführt wird oder das Debuggen in einer Endlosschleife festhängt und nicht zum Konsolenprozess zurückkehren kann, können Sie den Befehl „Attach“ verwenden.

PID anhängen

Sie können die PID des Prozesses über ps aux anzeigen und dann bt verwenden, um den Stapelrahmen anzuzeigen.

Am Beispiel von top lauten die Arbeitsschritte wie folgt:

1. ps -aux, um die Prozess-PID anzuzeigen, die 16974 ist.

2. sudo gdb attach 16974, verwenden Sie gdb zum Anhängen an den obersten Befehl.

3. Verwenden Sie bt full, um den aktuellen Stack-Frame anzuzeigen. Verwenden Sie jetzt die Druckfunktion usw., um die Informationen anzuzeigen.

4. Sie können Prozessinformationen auch über Info Proc anzeigen.

2.12. Wiederholte Ausführung

„continue“, „step“, „stepi“, „next“ und „nexti“ können alle die Anzahl der wiederholten Ausführungen angeben.

Haltepunktanzahl ignorieren: Sie können die angegebene Anzahl Haltepunkte ignorieren.

2.13. Initialisierungsdatei

Die Initialisierungsdatei in der Linux-Umgebung ist .gdbinit.

Wenn eine .gdbinit-Datei vorhanden ist, führt gdb sie vor dem Start als Befehlsdatei aus.

Die Ausführungsreihenfolge von Initialisierungsdateien und Befehlsdateien ist: HOME/.gdbinit > Befehlszeilenoptionen ausführen > ./.gdbinit > -x gibt die Befehlsdatei an.

2.14. Quellverzeichnis festlegen

Wenn Sie beim Debuggen auf den Quellcode zugreifen müssen, zeigen Sie ausführlichere Informationen an.

Das Quellverzeichnis kann über das Verzeichnis oder den festgelegten Ersatzpfad angegeben werden.

2.15 TUI-Debugging

TUI (TextUserInterface) ist die Text-Benutzeroberfläche für das GDB-Debugging, mit der Quellcode, Assembly und Registertextfenster bequem angezeigt werden können.

Das Quellcodefenster und das Assemblyfenster heben den Programmausführungsort hervor und kennzeichnen ihn mit dem Symbol „>“. Zur Identifizierung von Haltepunkten werden zwei spezielle Tags verwendet. Das erste Tag identifiziert den Haltepunkttyp:

  • B: Das Programm hat diesen Haltepunkt mindestens einmal erreicht.
  • b: Das Programm ist nicht bis zu diesem Haltepunkt gelaufen
  • H: Das Programm hat diesen Hardware-Haltepunkt mindestens einmal erreicht.
  • h: Das Programm ist nicht bis zu diesem Hardware-Haltepunkt gelaufen

Das zweite Flag wird verwendet, um anzuzeigen, ob der Haltepunkt aktiviert ist oder nicht:

+: Haltepunkt ist aktiviert. -: Haltepunkt ist deaktiviert.

Beim Debuggen eines Programms werden die Inhalte des Quellcodefensters, des Assemblyfensters und des Registerfensters automatisch aktualisiert.

2.16 Fangpunkt

Catch kann die Programmausführung basierend auf bestimmten Ereignistypen stoppen.

Sie können „catch syscall close“ verwenden, um die Programmausführung zu stoppen, wenn der Systemaufruf „close“ generiert wird.

Zu den anderen Catch-Ereignissen zählen Throw, Syscall, Assert, Exception usw.

2.17 Benutzerdefinierte Skripte

Die Eingabeparameter der Kommandozeile können über argc und *argv abgerufen werden.

2.17.0, Anmerkung, Zuweisung, Anzeige

# - Fügen Sie dem Skript Kommentare hinzu.

set – weist einer Variablen einen Wert zu, beginnend mit $, um zwischen GDB- und Debuggervariablen zu unterscheiden.

Beispiel: setze $x = 1

Die Anzeige von Variablen ist über echo und printf möglich.

2.17.1 Benutzerdefinierte Befehle

Mit dem Befehl „definieren“ können Sie Ihre eigenen Befehle definieren. Mit dem Befehl „dokumentieren“ können Sie Ihren benutzerdefinierten Befehlen Beschreibungen hinzufügen.

Addierer definieren
  wenn $argc == 2
    drucke $arg0 + $arg1
  Ende
  wenn $argc == 3
    drucke $arg0 + $arg1 + $arg2
  Ende
Ende

Dokument-Addierer
  Summieren Sie zwei oder drei Variablen.
Ende

Führen Sie den benutzerdefinierten Befehl bf aus. Die Ergebnisse sind wie folgt.

Es gibt keine Zeilenparameterdeklaration, aber es kann direkt mit $arg0, $arg1, $argc referenziert werden. Dies ist die Anzahl der formalen Parameter

2.17.2 Bedingte Anweisungen

Bedingte Befehle: if...else...end . Dies unterscheidet sich nicht vom if -Befehl in anderen Sprachen. Achten Sie lediglich auf das end .

2.17.3 Schleifenanweisung

Schleifenbefehl: while...end . gdb bietet auch die Befehle loop_break und loop_continue , die break bzw. continue in anderen Sprachen entsprechen. Achten Sie auch auf das end .

Protokollierung beim Überschreiben von gdb.log festlegen------------Speichern Sie das angezeigte Protokoll in gdb.log.
Paginierung ausschalten--------------------------Schalten Sie die Paginierungsanzeigefunktion aus.

tar jtag jtag://localhost:1025--------------Verbindung zu JTAG herstellen.

d----------------------------------------------Einen vorhandenen Haltepunkt löschen.

b func_a------------------------------------Fügen Sie einen Haltepunkt in func_a hinzu.
Befehle------------------------------------Führen Sie nach dem Haltepunkt die folgenden Befehle aus.
  b func_b----------------------------------Fügen Sie nach dem Haltepunkt in func_a einen Haltepunkt in func_b hinzu.
    Befehle bt voll-------------------------------Drucken Sie den Stapelrahmen bei func_b.
      c-------------------------------------Ausführung fortsetzen.
    Ende
  b file.c:555------------------------------------------Fügen Sie in Zeile 555 von file.c einen Haltepunktbefehl hinzu
      während 1----------------------------------------------Den nächsten Befehl unendlich ausführen.
        nächste
      Ende
    Ende
  c------------------------------------------Ausführung fortsetzen, um die Haltepunkte func_b und file.c:555 auszulösen.
Ende

c------------------------------------------- bedeutet, dass das Programm weiterhin ausgeführt wird.

Sie können das Skript auch in der Befehlszeile aktualisieren: gdb -x gdb.init bin; oder gdb bin und dann source gdb.init in der Befehlszeile.

2.18. Speicher in eine angegebene Datei sichern

Während des GDB-Debuggens müssen Sie möglicherweise einen Speicherabschnitt in eine Datei exportieren. Dies ist mithilfe des Befehls „Dump“ möglich.

Befehlsformat:

Binärspeicher auslesen DATEI START STOP

Beispielsweise exportiert „dump binary memory ./dump.bin 0x0 0x008000000“ den Speicherbereich von 0x0 bis 0x00800000 nach dump.bin.

3. Remote-Debugging von gdb+gdbserver

Die Remote-Debugging-Methode „GDBServer + Host-GDB“ der Zielplatine eignet sich besser für Zielplatinen mit eingeschränkter Leistung und kann nur GDBServer-Funktionen bereitstellen.

Führen Sie gdb zum Remote-Debuggen auf dem Hostcomputer aus. Der Testablauf ist wie folgt.

#include <stdio.h>

void C(int *p)
{
    *p = 0x12;
}

void B(int *p)
{
    C(p);
}
ungültig A(int *p)
{
    B(p);
}
ungültig A2(int *p)
{
    C(p);
}
int main(int argc, char **argv)
{
    int a;
    int *p = NULL;
    // A2 > C
    printf("a = 0x%x\n", a);
    // A > B > C
    gebe 0 zurück;
}

Die Zielplatine ist wie folgt eingerichtet: Öffnen Sie Port 2345 als Kupferport des GDBServers.

gdbserver: 2345 test_debug

Führen Sie gdb test_debug auf dem Host aus und taren Sie dann remote 192.168.2.84.2345, um eine Verbindung mit dem Remote-GDB-Server herzustellen.

Die Zielplatine erhält die Meldung „Remote-Debugging vom Host 192.168.33.77“, was darauf hinweist, dass die Verbindung zwischen den beiden erfolgreich ist.

Remote-Debugging kann auf dem Host durchgeführt werden. Nach dem Fortfahren sind die an beiden Enden erhaltenen Ergebnisse wie folgt:

Die Zielplatine stoppt den Betrieb nach der Ausgabe von „a=0x12“.

Der Host empfängt SIGSEGV und kann Backtrace-Informationen anzeigen. Es ist ersichtlich, dass das Problem darin liegt, dass der Zeiger p auf NULL zeigt und die Zuweisung des Zeigers 0 falsch ist.

4. Offline-Analyse durch Core + GDB

Führen Sie „ulimit -c unlimited“ auf der Zielplatine aus und führen Sie die Anwendung aus.

Wenn ein Programmfehler auftritt, wird im aktuellen Verzeichnis eine Core-Datei generiert.

Führen Sie nach dem Kopieren der Core-Datei xxx-linux-gdb ./test ./core zur Analyse auf dem PC aus.

4.1、Bibliotheksdateien laden

Nach dem Ausführen von xxx-linux-gdb ./test ./core sind die Bibliotheksdateien möglicherweise nicht zugeordnet.

Verwenden Sie info sharedlibrary, um den Ladestatus der Bibliothek anzuzeigen.

Von Nach Syms Lesen Gemeinsam genutzte Objektbibliothek
                        Nein xxx.so
                        Nein /lib/libdl.so.2
                        Nein /lib/libpthread.so.0
0x2ab6ec00 0x2ac09ba4 Ja xxx/lib/libstdc++.so.6
                        Nein /lib/libm.so.6
0x2acec460 0x2acf626c Ja xxx/lib/libgcc_s.so.1
                        Nein /lib/libc.so.6
                        Nein /lib/ld.so.1

Es kann durch „Set Solib-Search-Path“ und „Set Solib-Absolute-Prefix“ entsprechend dem Pfad festgelegt werden, in dem sich die Bibliothek befindet.

Von Nach Syms Lesen Gemeinsam genutzte Objektbibliothek
0x2aaca050 0x2aacc8d0 Ja xxx.so
0x2aad0ad0 0x2aad17ac Ja (*) xxx/lib/libdl.so.2
0x2aad8a50 0x2aae7434 Ja (*) xxx/lib/libpthread.so.0
0x2ab6ec00 0x2ac09ba4 Ja xxx/lib/libstdc++.so.6
0x2ac4b3d0 0x2acb1988 Ja xxx/lib/libm.so.6
0x2acec460 0x2acf626c Ja xxx/lib/libgcc_s.so.1
0x2ad17b80 0x2adf699e Ja xxx/lib/libc.so.6
0x2aaa89e0 0x2aabf66c Ja (*) xxx/lib/ld.so.1
(*): In der gemeinsam genutzten Bibliothek fehlen Debuginformationen.

Es ist ersichtlich, dass die relevanten Bibliotheksdateien geladen wurden, aber einige Bibliotheksdateien verfügen über keine Debuginformationen.

4.2. Backtrace anzeigen

Um den Backtrace des Coredumps anzuzeigen, verwenden Sie Bit t. Um umfassendere Informationen zu erhalten, verwenden Sie Bit t full.

Mehrere Funktionen, die einen Funktionsaufrufstapel erzeugen

bt: Zeigt Informationen zu allen Funktionsaufrufstapel-Frames an, eine Zeile pro Frame.

bt n: Zeigt Informationen zu n Frames im Stapel an.

bt -n: Zeigt n Informationsrahmen am unteren Ende des Stapels an.

bt full: Zeigt vollständige Informationen aller Frames im Stapel an, z. B. Funktionsparameter und lokale Variablen.

bt full n: Gleiche Verwendung wie oben.

bt voll -n

(gdb) bt
#0 0x2ad71f1e in memcpy () von xxx/lib/libc.so.6
#1 0x2ad71ac0 in memmove () von xxx/lib/libc.so.6
#2 0x0011f36c in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<unsigned char> (__first=0x34dfb008 "\377\330\377", <unvollständige Sequenz \340>, __last=0x34eeea2c "", 
    ...
#3 0x0011ee22 in std::__copy_move_a<false, unsigned char*, unsigned char*> (__first=0x34dfb008 "\377\330\377", <unvollständige Sequenz \340>, __last=0x34eeea2c "", __result=0x2b2013c0 "\377\330\377", <unvollständige Sequenz \340>)
    bei xxxinclude/c++/6.3.0/bits/stl_algobase.h:386
#4 0x0011e7e2 in std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >, unsigned char*> (__first=..., __last=..., __result=0x2b2013c0 "\377\330\377", <unvollständige Sequenz \340>)
    bei xxx/bits/stl_algobase.h:424
#5 0x0011dfd2 in std::copy<__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >, unsigned char*> (__first=..., __last=..., __result=0x2b2013c0 "\377\330\377", <unvollständige Sequenz \340>)
    bei xxx/6.3.0/bits/stl_algobase.h:456
#6 0x0011c948 in xxx
#7 0x00133e08 in xxx
#8 0x2aada31e in start_thread () von xxx/libc/lib/libpthread.so.0
#9 0x005a11b4 in ?? ()

4.3 Verzeichnis und Benennungsregeln für Core-Dump-Speicherdateien

Standardmäßig wird die Core-Datei im aktuellen Anwendungspfad gespeichert und kann zur Unterscheidung festgelegt werden.

Die Kerne werden hauptsächlich durch /proc/sys/kernel/core_uses_pid und /proc/sys/kernel/core_pattern unterschieden.

/proc/sys/kernel/core_uses_pid: Kann steuern, ob pid als Erweiterung im Dateinamen der generierten Core-Datei hinzugefügt wird. Wenn es hinzugefügt wird, ist der Dateiinhalt 1, andernfalls 0.

proc/sys/kernel/core_pattern: Sie können den Speicherort oder den Dateinamen der formatierten Kerndatei festlegen. Der ursprüngliche Dateiinhalt lautet beispielsweise core-%e.

echo "/tmp/core-%e-%p" > Kernmuster.

Die generierte Core-Datei wird im Verzeichnis /corefile gespeichert. Der generierte Dateiname lautet core-command name-pid-timestamp

Nachfolgend sehen Sie eine Liste der Parameter:

%p - PID in Dateinamen einfügen
%u - aktuelle UID in Dateinamen einfügen
%g - aktuelle GID in Dateinamen einfügen
%s - Signal, das den Coredump verursacht hat, in den Dateinamen einfügen
%t - fügt die UNIX-Zeit, zu der der Coredump auftrat, in den Dateinamen ein. Fügt die UNIX-Zeit hinzu, zu der die Core-Datei generiert wurde.
%h – fügt den Hostnamen, auf dem der Coredump aufgetreten ist, in den Dateinamen ein
%e - fügt den Namen der ausführbaren Coredumping-Datei in den Dateinamen ein. Befehlsnamen hinzufügen

Dies können Sie selbstverständlich auf folgende Arten tun:

sysctl -w kernel.core_pattern=/tmp/core-%e-%p

4.4 Verwendung von ulimit

Funktionsbeschreibung: Steuern Sie die Ressourcen des Shell-Programms.

Syntax: ulimit [-aHS][-c <Obergrenze der Kerndatei>][-d <Größe des Datenabschnitts>][-f <Dateigröße>][-m <Speichergröße>][-n <Anzahl der Dateien>][-p <Puffergröße>][-s <Stapelgröße>][-t <CPU-Zeit>][-u <Anzahl der Programme>][-v <Größe des virtuellen Speichers>]

Zusätzlicher Hinweis: ulimit ist ein integrierter Shell-Befehl, mit dem die Ressourcen des Shell-Ausführungsprogramms gesteuert werden können.

Parameter:

-a Zeigt die aktuellen Einstellungen für das Ressourcenlimit an.
-c <Obergrenze der Core-Datei> Legt den Maximalwert der Core-Datei in Blöcken fest.
-d <Datenabschnittsgröße> Der Maximalwert des Programmdatenabschnitts in KB.
-f <Dateigröße> Die größte Datei in Blöcken, die die Shell erstellen kann.
-H legt ein hartes Limit für die Ressource fest, d. h. das vom Administrator festgelegte Limit.
-m <Speichergröße> gibt die Obergrenze des verfügbaren Speichers in KB an.
-n <Anzahl der Dateien> gibt die maximale Anzahl der Dateien an, die gleichzeitig geöffnet werden können.
-p <Puffergröße> gibt die Größe des Pipe-Puffers in Einheiten von 512 Bytes an.
-s <Stapelgröße> Gibt die Obergrenze des Stapels in KB an.
-S Legt elastische Grenzen für Ressourcen fest.
-t <CPU-Zeit> gibt die Obergrenze der CPU-Auslastungszeit in Sekunden an.
-u <Anzahl der Programme> Die maximale Anzahl der Programme, die ein Benutzer öffnen kann.
-v <Größe des virtuellen Speichers> gibt die Obergrenze des verfügbaren virtuellen Speichers in KB an.

5. GDB-Tipps

5.1. Schließen

Geben Sie <return> ein, um fortzufahren, oder q <return>, um zu beenden---

Wenn der Anzeigeinhalt groß ist, erzwingt GDB eine Paginierung und die Anzeige wird angehalten. Dies ist jedoch möglicherweise nicht erforderlich und kann durch Ausschalten der Seitennummerierung deaktiviert werden.

5.2. An den laufenden Kernel anhängen

Wenn unter einem laufenden Linux ein Absturz oder ein anderes Problem auftritt, müssen Sie zur Lokalisierung des Problems die JTAG-Verbindung verwenden.

Die Verbindungsmethode ist:

gdb---------------------------------------------------Geben Sie die gdb-Shell ein.

Ziel-Remote-Localhost:1025-------------------Verbindung zum Ziel über IP:Port in der GDB-Shell herstellen.

Datei vmlinux----------------------------------------Laden Sie die Symboltabelle.

Anschließend können Sie den Laufstatus online einsehen.

Oben finden Sie detaillierte Informationen zur grundlegenden Verwendung des Linux-Debuggers GDB. Weitere Informationen zum Linux-Debugger GDB finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • So verwenden Sie gdb zum Debuggen von Kerndateien in Linux
  • Erste Schritte mit GDB unter Linux
  • Ein einfaches Tutorial zur Verwendung des Linux-Debugging-Tools GDB
  • Debuggen von Linux-Anwendungen mit den Befehlen gdb und gdbserver
  • Zusammenfassung gängiger Befehle basierend auf den Linux-Debugging-Tools strace und gdb

<<:  Welche Arten von MySQL-Verbindungsabfragen kennen Sie?

>>:  Einführung in die Verwendung der unbestimmten Eigenschaft des Kontrollkästchens

Artikel empfehlen

Methode und Einführung der Tabellenindexdefinition in MySQL

Überblick Ein Index ist eine vom DBMS basierend a...

Eine kurze Diskussion darüber, ob CSS das Rendern von Seiten blockiert

Vielleicht weiß jeder, dass die JS-Ausführung die...

Detaillierte Erklärung des Fischschwarm-Algorithmus im CocosCreator-Spiel

Vorwort Ich wollte vor kurzem CocosCreator lernen...

MySQL-Inspektionsskript (unbedingt lesen)

Wie unten dargestellt: #!/usr/bin/env python3.5 p...

Tutorial zur Installation von MySQL8 auf Centos7

Neue Funktionen in MySQL 8: Meine persönliche Mei...

So erstellen Sie SonarQube mit Docker

Inhaltsverzeichnis 1. Docker installieren 2. Sona...

Wissen Sie, wie viele Verbindungen ein Linux-Server verarbeiten kann?

Vorwort Sehen wir uns zunächst an, wie eine TCP-V...