Mam nadzieję, że to pytanie nie jest zbyt otwarte. Wpadłem na problem z pamięcią z Rust, gdzie dostałem an "out of memory" from calling next
on an Iterator
trait object. Nie jestem pewien, jak to debugować. Wydruki doprowadziły mnie tylko do punktu, w którym nastąpiła awaria. Nie jestem zaznajomiony z innymi narzędziami, takimi jak ltrace, więc chociaż mogłem stworzyć ślad (231MiB, pff), tak naprawdę nie wiedziałem, co z tym zrobić. Czy taki ślad jest użyteczny? Czy powinienem lepiej pobrać gdb/lldb? Lub Valgrind?Jak mogę debugować problem z pamięcią w Rust?
Odpowiedz
Generalnie chciałbym spróbować wykonać następujące podejście:
boilerplate zniżki: Spróbuj zawęzić problem OOM, tak, że nie masz zbyt dużo dodatkowego kodu dookoła. Innymi słowy: im szybciej twój program się zawiesza, tym lepiej. Czasami możliwe jest wyrwanie określonego kodu i umieszczenie go w dodatkowym pliku binarnym, tylko na potrzeby dochodzenia. rozdrabnianie
Problem: Dolna problem z OOM do prostego „zbyt dużo pamięci”, tak, że rzeczywiście można powiedzieć coś niektóre odpady części, lecz że nie doprowadzi do OOM. Jeśli trudno jest stwierdzić, czy problem występuje, czy nie, można zmniejszyć limit pamięci. W systemie Linux, można to zrobić za pomocą
ulimit
: gromadzenieulimit -Sv 500000 # that's 500MB ./path/to/exe --foo
informacje: Jeśli problemem jest wystarczająco mały, jesteś gotowy do zbierania informacji, który ma niższy poziom hałasu. Istnieje wiele sposobów, które możesz wypróbować. Pamiętaj tylko, aby skompilować program za pomocą symboli debugowania. Również wyłączenie optymalizacji może być korzystne, ponieważ zazwyczaj prowadzi to do utraty informacji. Obie mogą być archiwizowane przez NIE przy użyciu flagi
--release
podczas kompilacji.Heap profilowanie: Jednym ze sposobów jest zbyt używać gperftools:
LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile ./path/to/exe --foo pprof --gv ./path/to/exe /tmp/profile/profile.0100.heap
To pokazuje wykres, która symbolizuje które części programu jeść która to ilość pamięci. Aby uzyskać więcej informacji, patrz official docs.
rr: Czasami bardzo trudno jest ustalić, co się naprawdę dzieje, szczególnie po utworzeniu profilu. Zakładając, że dobrą robotę w kroku 2, można użyć rr:
rr record ./path/to/exe --foo rr replay
To będzie tarło GDB z supermocarstw. Różnica w stosunku do zwykłej sesji debugowania polega na tym, że można nie tylko
continue
, ale takżereverse-continue
. Zasadniczo program jest wykonywany z nagrania, w którym można przeskakiwać w dowolne miejsce. This wiki page podaje dodatkowe przykłady. Należy zwrócić uwagę na to, że rr działa tylko z GDB.Dobre stare debugowanie: Czasami można uzyskać ślady i nagrania, które są zbyt duże. W takim przypadku można (w połączeniu z
ulimit
podstęp) wystarczy użyć GDB i czekać aż wywala program:gdb --args ./path/to/exe --foo
Teraz powinien dostać normalną debugowania sesji, gdzie można sprawdzić jaki jest aktualny stan programu było . GDB można również uruchomić za pomocą coredump. Ogólny problem z tym podejściem polega na tym, że nie można cofnąć się w czasie i nie można kontynuować wykonywania. Widzisz tylko bieżący stan, w tym wszystkie klatki stosu i zmienne. Tutaj możesz również użyć LLDB, jeśli chcesz.
(Potential) fix + powtórki: Po masz klej, co może pójść źle, możesz spróbować zmienić swój kod. Następnie spróbuj ponownie. Jeśli nadal nie działa, wróć do kroku 3 i spróbuj ponownie.
Ogólnie rzecz biorąc, do debugowania można użyć podejścia opartego na logowaniu (albo wstawiając dzienniki samodzielnie, albo mając narzędzie takie, jak ltrace
, ptrace
, ... aby wygenerować dzienniki dla ciebie) lub możesz użyj debuggera.
Należy pamiętać, że metody oparte na debuggerze wymagają, aby można było odtworzyć problem; Mam tendencję do faworyzowania ręcznych dzienników, ponieważ pracuję w branży, w której raporty o błędach są generalnie zbyt nieprecyzyjne, aby umożliwić natychmiastową reprodukcję (a zatem używamy dzienników do tworzenia scenariusza dla reproduktorów).
Rust obsługuje oba podejścia, a standardowy zestaw narzędzi, którego używa się w programach C lub C++, działa dobrze.
Moim osobistym podejściem jest rejestrowanie się w jednym miejscu, aby szybko zawęzić miejsce, w którym wystąpił problem, a jeśli logowanie nie wystarcza do uruchomienia debuggera w celu dokładniejszego sprawdzenia. W tym przypadku polecam od razu przejść do debuggera. Wygenerowano
Wygenerowano panic
, co oznacza, że poprzez przerwanie połączenia z hakiem paniki, zobaczysz zarówno stos wywołań, jak i stan pamięci w momencie, gdy coś pójdzie nie tak.
Uruchom program za pomocą debuggera, ustaw punkt przerwania na hak wywoływania paniki, uruchom program, zysk.
- 1. Problem z pamięcią UIAutomation
- 2. Problem z pamięcią w ARC
- 3. Problem z pamięcią PHPExcel
- 4. Jak mogę debugować makra?
- 5. Problem z pamięcią tablicową Numpy
- 6. Jak mogę debugować problem z dziedziczeniem stylu Android?
- 7. problem z pamięcią podręczną w actionscript URLLoader
- 8. UITextChecker: Problem z pamięcią z tysiącami słów
- 9. Jak rozwiązać problem z pamięcią z Mapą na iOS 6
- 10. Jak mogę debugować AppleScript?
- 11. Weird JavaCore Problem z pamięcią podręczną w języku Java
- 12. Jak mogę debugować reguły mod_rewrite?
- 13. Jak mogę przetestować prywatne metody w Rust?
- 14. Jak mogę przekazać parametry do gcc w Rust z ładunkiem?
- 15. Problem z pamięcią podczas pracy z dużą tablicą UIImage
- 16. Problem z pamięcią sieciową iOS w React Native
- 17. Wyjątek i problem z pamięcią w kopii zbiorczej SQL
- 18. Jak mogę debugować php gettext?
- 19. Jak mogę debugować skrypt Perla?
- 20. Jak mogę debugować PHP w IIS?
- 21. Problem z pamięcią z gniazdem asynchronicznym i rozpoczęcie wysyłania
- 22. Jak mogę pobrać dokumenty Rust API?
- 23. Jak mogę debugować zwisający wątek java?
- 24. Jak mogę debugować wyrażenie regularne w Pythonie?
- 25. Jak mogę debugować lub naprawiać problem nieskończonej pętli i sterty korupcji z udziałem boost :: interprocess managed_shared_memory?
- 26. Problem z brakującą pamięcią podczas instalowania pakietów na serwerze Ubuntu
- 27. ADFS 2.0 - Jak mogę debugować "401 - Nieautoryzowane"?
- 28. Jak mogę debugować przetwarzanie wartości hibernate.hbm2ddl.import_files w połączeniu z hsqldb?
- 29. Czy mogę debugować Exe
- 30. Jak rozwiązywać problemy z pamięcią w aplikacji wbudowanej?
Valgrind jest zawsze dobrym początkiem. Spróbuj również zoptymalizować swój kod. –
@EliSadoff Jak optymalizacja mojego kodu pomaga w debugowaniu problemów z pamięcią? – Apanatshka