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.
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
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
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