Das Linux-spezifische backtrace()
und backtrace_symbols()
ermöglicht es Ihnen, eine Aufrufverfolgung des Programms zu erstellen. Es gibt jedoch nur Funktionsadressen aus, nicht ihre Namen für mein Programm. Wie kann ich sie dazu bringen, auch die Funktionsnamen zu drucken? Ich habe versucht, das Programm mit zu kompilieren -g
ebenso gut wie -ggdb
. Der folgende Testfall gibt nur Folgendes aus:
BACKTRACE ------------ ./a.out() [0x8048616] ./a.out() [0x8048623] /lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413] ./a.out() [0x8048421] ----------------------
Ich möchte, dass die ersten 2 Elemente auch die Funktionsnamen anzeigen, foo
und main
Code:
#include <execinfo.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
static void full_write(int fd, const char *buf, size_t len)
{
while (len > 0) {
ssize_t ret = write(fd, buf, len);
if ((ret == -1) && (errno != EINTR))
break;
buf += (size_t) ret;
len -= (size_t) ret;
}
}
void print_backtrace(void)
{
static const char start[] = "BACKTRACE ------------\n";
static const char end[] = "----------------------\n";
void *bt[1024];
int bt_size;
char **bt_syms;
int i;
bt_size = backtrace(bt, 1024);
bt_syms = backtrace_symbols(bt, bt_size);
full_write(STDERR_FILENO, start, strlen(start));
for (i = 1; i < bt_size; i++) {
size_t len = strlen(bt_syms[i]);
full_write(STDERR_FILENO, bt_syms[i], len);
full_write(STDERR_FILENO, "\n", 1);
}
full_write(STDERR_FILENO, end, strlen(end));
free(bt_syms);
}
void foo()
{
print_backtrace();
}
int main()
{
foo();
return 0;
}
mögliches Duplikat von So erhalten Sie einen detaillierteren Backtrace
– Nemo
4. August 2011 um 0:51 Uhr
btw, funktion
backtrace_symbols_fd
führt die gleiche Operation aus wiebacktrace_symbols()
aber die resultierenden Zeichenfolgen werden sofort in den Dateideskriptor geschriebenfd
.– nhngia
16. Juli 2018 um 10:01 Uhr
Ich habe mehrere Methoden ausführlich getestet unter: stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c/…
– Ciro Santilli OurBigBook.com
25. Januar 2019 um 12:20 Uhr
Da das zweite Argument von backtrace() die maximale Anzahl von Adressen angibt, die in dem vom ersten angegebenen Puffer (man 3 backtrace) gespeichert werden können, ist hier ein Wert von 1024 unnötig großzügig. Ein Wert von 20 sollte ausreichen, und das Drucken einer Warnung für eine mögliche Kürzung, wenn bt_size == 20 ist, ist eine gute Praxis.
– Robert
27. Juli 2021 um 13:13 Uhr