Nieblokujący zrzut rdzenia w systemie Linux?

24

Szukam sposobu na wykonanie nieinwazyjnej operacji rdzeniowej w systemie Linux.

Znam gdb gcore, ale można go uruchomić tylko wtedy, gdy gdbjest dołączony do procesu i jest zatrzymany w celu debugowania. Dla dużego zrzutu rdzenia, który może oznaczać wiele sekund, a nawet kilka minut przerwanego wykonywania.

Czy jest jakaś nieblokująca alternatywa?

Linux obsługuje kopiowanie przy zapisie pamięci, który opiera się na wsparciu fork()bez exec(). Tak więc myślę o czymś na poziomie jądra, w którym jądro pobiera migawkę kopii przy zapisie tabel stron procesu zrzucanego procesu, a następnie wypisuje rdzeń, podczas gdy oryginalny proces nadal działa.

Jestem prawie pewien, że mógłbym użyć gdbsiły, a fork()następnie rzucić dziecko, podczas gdy rodzic kontynuuje radość, a następnie wait()w rodzic, aby zebrać dziecko po zakończeniu. Jest to jednak bałagan i nadal wymaga dwóch przerw w procesie macierzystym, aczkolwiek krótkich.

Z pewnością ktoś tego wcześniej potrzebował?

Craig Ringer
źródło
Przykro mi, że mogę wyrazić tylko jedną opinię na temat tego cudownego pytania.
Peter mówi, że przywróć Monikę
Doskonałe pytanie i ja z niecierpliwością czekam na odpowiedź. +1 ode mnie
thanasisk
1
Co powiesz na 1) dołączenie procesu do gdb 2) pozwól, aby rozwidliło go polecenie „wywołaj rozwidlenie” 3) zrzuć rdzeń procesu potomnego 4) pozwól martwemu dziecku poczekać na rodzica (kolejne „zadzwoń czekaj4”) 5 ) odłączyć od procesu 6) zautomatyzować 1-5? Gdb używa prostych wywołań systemowych sys_ptrace (), może to być niezbyt złożone narzędzie C całkowicie niezależne od gdb.
Peter mówi, że przywróć Monikę
1
Na maszynie wirtualnej możesz zrobić migawkę i przedstawić ją jako klon do analizy. Być może jedno z wymienionych tutaj narzędzi pomoże: cyberciti.biz/programming/linux-memory-forensics-analysis-tools
Giovanni Tirloni
1
Możesz uniknąć drugiej przerwy, mając proces potomny, który również rozwidla się, a następnie kończy działanie. Następnie proces nadrzędny może natychmiast poczekać na dziecko, a następnie kontynuować, podczas gdy dziadek zrzuca rdzeń.
kasperd

Odpowiedzi:

1

Google CoreDumper przychodzi mi na myśl. Tworzy kopię przestrzeni adresowej kopiowania przy zapisie, patrz WriteCoreDump () (patrz „Notatki”).

EricM
źródło
To wygląda niezwykle przydatne! Zastanawiam się, jaka jest podstawowa technika. Przypuszczalnie śledzi proces, ale utworzenie migawki CoW bez rozwidlania się w sposób, który nie wpływa na stosy, byłoby trudne. Będę musiał rzucić okiem na kod. Świetna wskazówka.
Craig Ringer
Niestety wygląda na to, że jest w trakcie przetwarzania i nie można go wywołać za pomocą programu gdb lub podobnego, ponieważ sam wymaga ptrace. To trochę przypomina debugującą bibliotekę DLL pod Windows, a nie nieblokujący gcore, ale nadal bardzo przydatny. Wydaje mi się, że byłoby możliwe użycie przez hak LD_PRELOAD i konfigurację modułu obsługi sygnałów z gdb, odłączanie i sygnalizowanie procesu, ale nie wygląda na to, że jest naprawdę zaprojektowany do zrzucania niezmodyfikowanych programów, i ma wspólny problem za pomocą dowolnego narzędzia zrzutu procesu, które jeśli proces zostanie wystarczająco pomieszany, zrzut nie będzie działał.
Craig Ringer
Przepraszam… Nie przeczytałem „nieinwazyjnego” bitu, kiedy po raz pierwszy przeczytałem pytanie.
EricM,