[Linux] [C / C ++] So ermitteln Sie den Wert der Rücksprungadresse einer Funktion und den Funktionsnamen des Aufrufers

TL;DR

Ich möchte eine von verschiedenen Orten aufgerufene Funktion debuggen, um den Funktionsnamen des Aufrufers abzurufen.

Es wäre schön, __builtin_return_address (0) und dladdr zu verwenden.

Implementierungsbeispiel

test.c(Rufen Sie den Funktionsnamen und die Absenderadresse des Anrufers ab)


#include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>

void hoge() {
    Dl_info info;
    dladdr(__builtin_return_address(0), &info);
    printf("[%s] parent func name => %p [%s]\n",
           __func__,
           __builtin_return_address(0),
           info.dli_sname);
}

void foo() {
    hoge();

    Dl_info info;
    dladdr(__builtin_return_address(0), &info);
    printf("[%s] parent func name => %p [%s]\n",
           __func__,
           __builtin_return_address(0),
           info.dli_sname);
}

int main(int argc, char const* argv[])
{
    hoge();

    foo();

    return 0;
}

Das Ergebnis der Ausführung ist wie folgt. Sie können den Symbolnamen von dladdr erhalten.

$ gcc test.c -ldl -rdynamic
$ ./a.out
[hoge] parent func name => 0x4008ee [main]
[hoge] parent func name => 0x40089e [foo]
[foo] parent func name => 0x4008f8 [main]

Diese Methode ist jedoch begrenzt und Sie müssen mit -rdynamic erstellen. (-rdynamic => Alle Symbole zur dynamischen Symboltabelle hinzufügen)

Wenn das Symbol in der dynamischen Symboltabelle nicht vorhanden ist, kann der Name nicht von dladdr erhalten werden.

Ausführungsergebnis


$ gcc test.c -ldl
$ ./a.out
[hoge] parent func name => 0x4006de [(null)]
[hoge] parent func name => 0x40068e [(null)]
[foo] parent func name => 0x4006e8 [(null)]

Da die Rücksprungadresse unter "__builtin_return_address (0)" bekannt ist, kann sie beispielsweise mit "objdump" ermittelt werden.

$ objdump -d ./a.out | view -
000000000040067c <foo>: #Anrufer
  40067c:	55                   	push   %rbp
  40067d:	48 89 e5             	mov    %rsp,%rbp
  400680:	48 83 ec 20          	sub    $0x20,%rsp
  400684:	b8 00 00 00 00       	mov    $0x0,%eax
  400689:	e8 af ff ff ff       	callq  40063d <hoge>
  40068e:	48 8b 45 08          	mov    0x8(%rbp),%rax   #Kehre hierher zurück, wenn du Hoge verlässt
  400692:	48 8d 55 e0          	lea    -0x20(%rbp),%rdx
  400696:	48 89 d6             	mov    %rdx,%rsi
  400699:	48 89 c7             	mov    %rax,%rdi
  40069c:	e8 7f fe ff ff       	callq  400520 <dladdr@plt>
  4006a1:	48 8b 55 f0          	mov    -0x10(%rbp),%rdx
  4006a5:	48 8b 45 08          	mov    0x8(%rbp),%rax
  4006a9:	48 89 d1             	mov    %rdx,%rcx
  4006ac:	48 89 c2             	mov    %rax,%rdx
  4006af:	be 9f 07 40 00       	mov    $0x40079f,%esi
  4006b4:	bf 78 07 40 00       	mov    $0x400778,%edi
  4006b9:	b8 00 00 00 00       	mov    $0x0,%eax
  4006be:	e8 4d fe ff ff       	callq  400510 <printf@plt>
  4006c3:	c9                   	leaveq 
  4006c4:	c3                   	retq   
~Unterlassung~
00000000004006c5 <main>: #Anrufer
  4006c5:	55                   	push   %rbp
  4006c6:	48 89 e5             	mov    %rsp,%rbp
  4006c9:	48 83 ec 10          	sub    $0x10,%rsp
  4006cd:	89 7d fc             	mov    %edi,-0x4(%rbp)
  4006d0:	48 89 75 f0          	mov    %rsi,-0x10(%rbp)
  4006d4:	b8 00 00 00 00       	mov    $0x0,%eax
  4006d9:	e8 5f ff ff ff       	callq  40063d <hoge>
  4006de:	b8 00 00 00 00       	mov    $0x0,%eax     #Kehre hierher zurück, wenn du Hoge verlässt
  4006e3:	e8 94 ff ff ff       	callq  40067c <foo>
  4006e8:	b8 00 00 00 00       	mov    $0x0,%eax     #Kehre hierher zurück, wenn du foo verlässt
  4006ed:	c9                   	leaveq 
  4006ee:	c3                   	retq   
  4006ef:	90                   	nop

Beziehung

Wenn Sie es mit dem zuvor untersuchten Hook in LD_PRELOAD kombinieren, scheint sich das Debuggen zu verbessern.

Ersetzen Sie printf später durch LD_PRELOAD --Qiita

Referenz

So erhalten Sie die Zeichenfolge des Funktionsnamens in C-Sprache - Taisho (miettal) -Tagebuch Function caller in linux kernel - Stack Overflow How to get function's name from function's pointer in C? - Stack Overflow Return Address - Using the GNU Compiler Collection (GCC) Funktions-Tracer mit GCC-Kompilierungsoptionstagebuch von torutk Über __builtin_return_address --syohex 'Tagebuch

Recommended Posts

[Linux] [C / C ++] So ermitteln Sie den Wert der Rücksprungadresse einer Funktion und den Funktionsnamen des Aufrufers
So ermitteln Sie die Speicheradresse des Pandas-Datenrahmenwerts
Holen Sie sich den Aufrufer einer Funktion in Python
[C-Sprache] [Linux] Ruft den Wert der Umgebungsvariablen ab
So erhalten Sie den "Namen" eines Feldes, dessen Wert durch das Auswahlattribut im Django-Modell begrenzt ist
[Linux] [C / C ++] Zusammenfassung, wie man pid, ppid, tid bekommt
So erhalten Sie den letzten (letzten) Wert in einer Liste in Python
Der Rückgabewert (Generator) einer Funktion, die endlich und Ausbeute kombiniert, darf nicht direkt an next übergeben werden
[C / C ++] Übergeben Sie den in C / C ++ berechneten Wert an eine Python-Funktion, um den Prozess auszuführen, und verwenden Sie diesen Wert in C / C ++.
Eine Geschichte über die Portierung des Codes "Versuchen Sie zu verstehen, wie Linux funktioniert" nach Rust
Ich möchte den Namen der ausgeführten Funktion / Methode erhalten
So erhalten Sie den NTP-Servernamen per DHCP und legen ihn fest
[Python] So erhalten Sie den ersten und den letzten Tag des Monats
So geben Sie das Ausgabeergebnis des Linux-Befehls man in eine Datei aus
So ermitteln Sie die Scheitelpunktkoordinaten eines Features in ArcPy
Erstellen Sie eine Funktion, um den Inhalt der Datenbank in Go abzurufen
So erhalten Sie den Pixelwert des Punkts aus dem Satellitenbild, indem Sie den Breiten- und Längengrad angeben
Teilen und Verarbeiten eines Datenrahmens mithilfe der Groupby-Funktion
So erhalten Sie mit pandas DataFrame einen bestimmten Spaltennamen und Indexnamen
[Linux] Ein Befehl zum Abrufen einer Liste der in der Vergangenheit ausgeführten Befehle
So erstellen Sie einen Wrapper, der die Signatur der zu umschließenden Funktion beibehält
[C-Sprache] Verwendung der Krypta-Funktion unter Linux [Passwort-Hashing]
So berechnen Sie die Volatilität einer Marke
[Circuit x Python] So ermitteln Sie die Übertragungsfunktion eines Schaltkreises mit Lcapy
[NNabla] So erhalten Sie die Ausgabe (Variable) der mittleren Schicht des erstellten Netzwerks
So zählen Sie die Anzahl der Elemente in Django und geben sie in die Vorlage aus
[Python] Ich habe versucht, den Typnamen als Zeichenfolge aus der Typfunktion abzurufen
Ich möchte den Dateinamen, die Zeilennummer und den Funktionsnamen in Python 3.4 erhalten
Stellen Sie unter Linux (Ubuntu) das Trackpad ein und stellen Sie die Funktion auf Drei-Finger-Wischen ein
Tool zum Einfügen des Ländernamens und des Ländercodes in einen Teil der IP-Adresse
So erhalten Sie mit Python eine Liste der Dateien im selben Verzeichnis
[Einführung in Python] So erhalten Sie den Datenindex mit der for-Anweisung
So erhalten Sie den Variablennamen selbst in Python
Ruft den Variablennamen der Variablen als Zeichenfolge ab.
So ermitteln Sie die Anzahl der Stellen in Python
[Python of Hikari-] Kapitel 06-02 Funktion (Argument und Rückgabewert 1)
Wie man das Dokument der magischen Funktion (Linienmagie) trifft
[Django 2.2] Sortieren und erhalten Sie den Wert des Beziehungsziels
[Python] So rufen Sie eine Funktion von c aus Python auf (ctypes edition)
So zeigen Sie das Änderungsdatum einer Datei in C-Sprache bis zu Nanosekunden an
[Blender] So ermitteln Sie die Auswahlreihenfolge von Scheitelpunkten, Seiten und Flächen eines Objekts
So speichern Sie eine Python-Funktion im Wert eines Wörterbuchs (dict) und rufen die Funktion gemäß dem Schlüssel auf
So beschränken Sie die API, die in der gemeinsam genutzten Linux-Bibliothek in C-Sprache veröffentlicht werden soll
linux / c> link> Ruft das Ausführungsergebnis des Shell-Befehls im C-Programm ab.> Mir wurde beigebracht, wie man popen () verwendet.
[Ubuntu] So löschen Sie den gesamten Inhalt des Verzeichnisses
Versuchen Sie, die Funktionsliste des Python> os-Pakets abzurufen
Der Wert von meta beim Angeben einer Funktion ohne Rückgabewert mit Dask dataframe gilt
So rufen Sie eine Funktion auf
Ruft den Wert eines bestimmten Schlüssels bis zum angegebenen Index der Wörterbuchliste in Python ab
[OCI] Python-Skript zum Abrufen der IP-Adresse einer Recheninstanz in Cloud Shell
Ich habe eine Funktion erstellt, um das Modell von DCGAN zu überprüfen
So führen Sie die Exportfunktion des GCP-Datenspeichers automatisch aus
So erhalten Sie alle Schlüssel und Werte im Wörterbuch
So erhalten Sie eine Liste der integrierten Ausnahmen für Python
Eine grobe Zusammenfassung der Unterschiede zwischen Windows und Linux
So ermitteln Sie den Skalierungskoeffizienten eines bipolaren Wavelets
Weisen Sie Linux eine lokale Linkadresse zu und verwenden Sie DNS-SD / SSDP
So erhalten Sie eine Liste mit Links von einer Seite aus Wikipedia