Potrzebuję wydrukować stos śledzenia z obsługi sygnału 64-bitowej aplikacji M ++ z uruchomionym systemem Linux. Chociaż znalazłem kilka przykładów kodu, żaden z nich się nie kompiluje. Mój punkt blokowania polega na uzyskaniu adresu osoby dzwoniącej (punktu, w którym wygenerowano sygnał) ze struktury ucontext_t. Wszystkie informacje, które mogłem znaleźć, wskazują na rejestr EIP jako ucontext.gregs [REG_EIP] lub ucontext.eip. Wygląda na to, że oba są specyficzne dla x86. Potrzebuję 64-bitowego kodu zgodnego z procesorami Intel i AMD. Czy ktokolwiek może pomóc?Drukowanie ścieżki stosu z nośnika sygnału
Odpowiedz
Zwykłym sposobem uzyskiwania ślad stosu jest podjęcie adres zmiennej lokalnej , następnie dodać trochę magiczną liczbę do niej, w zależności od sposobu kompilator generuje kod (który może zależeć od opcji optymalizacji wykorzystywanych do skompilować kod) i od tego miejsca wrócić. Wszystko zależy od systemu, ale jest to wykonalne, jeśli wiesz, co robisz.
czy to działa z obsługi sygnału jest inna kwestia. Nie wiedzieć o platformie opisujesz, ale wiele systemów zainstalować osobny stos do obsługi sygnałów, bez linkiem do przerwany w stosie użytkownika dostępnej pamięci.
Czy masz na myśli żadnego związku z powrotem do przerwanego stosie? –
@wood_brian Brak dostępnej pamięci dla użytkownika. (System operacyjny oczywiście przechowuje informacje w pewien sposób.) –
Napisałeś przerwane statyczne. Myślałem, że masz na myśli przerwany stos. –
istnieje funkcja glibc backtrace. Strona podręcznika wymienia przykładowe się wezwanie:
#define SIZE 100
void myfunc3(void) {
int j, nptrs;
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
zobaczyć stronę man, aby uzyskać więcej kontekstu.
trudno powiedzieć, czy to naprawdę jest gwarantowane do pracy z obsługi sygnału, ponieważ tylko kilka list POSIX reentrant funkcje, które są gwarantowane do pracy. Pamiętaj: program obsługi sygnału może zostać wywołany, podczas gdy reszta procesu jest w samym środku połączenia malloc.
Domyślam się, że to zwykle działa, ale może się nie udać od czasu do czasu. Do debugowania może to być wystarczająco dobre.
Nie zdziwiłbym się, gdyby nie było to możliwe. Czy próbowałeś robić to na 32-bitach? A także, która dystrybucja? –
W 64-bitowym rejestrze jest RIP. Jestem pewien, że gdzieś tam będzie. –
To jest Red Hat 4.1.2-50. Nie może być aplikacją 32-bitową, ponieważ pracujemy z dużymi obszarami pamięci do 60 GB GB – GMichael