Naprawianie błędów segmentacji W C++

Piszę wieloplatformowy program C++ Dla Windows i Unix. Po stronie okna kod będzie kompilowany i wykonywany bez problemu. Po stronie Uniksa będzie się kompilował, jednak gdy próbuję go uruchomić, dostaję błąd segmentacji. Moje wstępne przeczucie jest takie, że jest problem ze wskaźnikami.

Jakie są dobre metody wyszukiwania i naprawiania błędów segmentacji?

Author: Veedrac, 2010-09-15

6 answers

  1. Skompiluj swoją aplikację za pomocą -g, a następnie będziesz miał symbole debugowania w pliku binarnym.

  2. Użyj gdb, aby otworzyć konsolę gdb.

  3. Użyj file i podaj plik binarny aplikacji w konsoli.

  4. Użyj run i podaj wszelkie argumenty, które Twoja aplikacja musi uruchomić.

  5. Zrób coś, aby spowodować błąd segmentacji .

  6. Wpisz bt w konsoli gdb, Aby uzyskać ślad stosu błąd segmentacji .

 80
Author: Svisstack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 10:45:31

Czasami sama awaria nie jest prawdziwą przyczyną problemu. być może pamięć została rozbita wcześniej, ale trochę trwało zanim korupcja się ujawniła. Sprawdź valgrind , który ma wiele sprawdzeń problemów ze wskaźnikami(w tym sprawdzanie granic tablic). Powie Ci, gdzie zaczyna się problem , a nie tylko linia, w której dochodzi do awarii.

 24
Author: paleozogt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-15 15:16:44

Zanim pojawi się problem, staraj się go unikać jak najbardziej:

  • Kompiluj i uruchamiaj kod tak często, jak możesz. Łatwiej będzie zlokalizować wadliwą część.
  • staraj się hermetyzować procedury niskiego poziomu / podatne na błędy, tak aby rzadko trzeba było pracować bezpośrednio z pamięcią (zwróć uwagę na modelowanie programu)
  • / Align = "left" / Mając przegląd tego, co obecnie działa, co już nie działa itp., pomoże Ci dowiedzieć się, gdzie problem polega na tym, że (Boost test jest możliwym rozwiązaniem, sam go nie używam, ale dokumentacja może pomóc zrozumieć, jakie informacje muszą być wyświetlane).

Użyj odpowiednich narzędzi do debugowania. Na Unix:

  • GDB może Ci powiedzieć, gdzie program się zawiesza i pozwoli Ci zobaczyć w jakim kontekście.
  • Valgrind pomoże Ci wykryć wiele błędów związanych z pamięcią.
  • z GCC możesz również użyć mudflap Z GCC i Clang możesz użyć address/Memory Sanitizer . Może wykryć pewne błędy, których nie ma Valgrind, a utrata wydajności jest lżejsza.

W końcu polecam zwykłe rzeczy. Im bardziej twój program jest czytelny, łatwy do utrzymania, przejrzysty i schludny, tym łatwiej będzie go debugować.

 15
Author: log0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-27 12:00:08

Na Unixie możesz użyć valgrind, aby znaleźć problemy. Jest darmowy i potężny. Jeśli wolisz zrobić to sam, możesz przeciążyć operatory new i delete, aby skonfigurować konfigurację, w której masz 1 bajt z 0xDEADBEEF przed i po każdym nowym obiekcie. Następnie śledź, co dzieje się podczas każdej iteracji. To może nie złapać wszystkiego (nie masz gwarancji, aby nawet dotknąć tych bajtów), ale to działało dla mnie w przeszłości na platformie Windows.

 2
Author: wheaties,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-15 15:12:45

Tak, jest problem ze wskaźnikami. Bardzo prawdopodobne, że używasz takiego, który nie jest prawidłowo zainicjowany, ale jest również możliwe, że psujesz zarządzanie pamięcią za pomocą podwójnych zwolnień lub czegoś takiego.

Aby uniknąć niezinicjalizowanych wskaźników jako zmiennych lokalnych, spróbuj zadeklarować je tak późno, jak to możliwe, najlepiej (i nie zawsze jest to możliwe), gdy mogą być zainicjowane znaczącą wartością. Przekonaj się, że będą miały wartość przed ich użyciem, badając kod. Jeśli masz z tym problemy, zainicjuj je na stałą wskaźnika null (Zwykle zapisywaną jako NULL lub 0) i sprawdź je.

Aby uniknąć niezainicjowanych wskaźników jako wartości składowych, upewnij się, że są one prawidłowo zainicjowane w konstruktorze i prawidłowo obsługiwane w konstruktorach kopiujących i operatorach przypisania. Nie polegaj na funkcji init do zarządzania pamięcią, chociaż możesz w przypadku innych inicjalizacji.

Jeśli twoja klasa nie potrzebuje konstruktorów kopiujących lub przypisania operatory, możesz zadeklarować je jako prywatne funkcje Członkowskie i nigdy ich nie definiować. Spowoduje to błąd kompilatora, jeśli są używane jawnie lub niejawnie.

Użyj inteligentnych wskaźników, gdy ma to zastosowanie. Dużą zaletą jest to, że jeśli będziesz się ich trzymać i konsekwentnie z nich korzystać, możesz całkowicie uniknąć pisania delete i nic nie zostanie podwójnie usunięte.

Używaj łańcuchów C++ i klas kontenerów, gdy tylko jest to możliwe, zamiast łańcuchów i tablic w stylu C. Rozważ użycie .at(i) raczej niż [i], ponieważ wymusi to sprawdzenie granic. Sprawdź, czy twój kompilator lub biblioteka mogą być ustawione na sprawdzanie granic w [i], przynajmniej w trybie debugowania. Błędy segmentacji mogą być spowodowane przekroczeniami buforów, które zapisują śmieci na bardzo dobrych wskaźnikach.

Robienie tych rzeczy znacznie zmniejszy prawdopodobieństwo błędów segmentacji i innych problemów z pamięcią. Bez wątpienia nie naprawią wszystkiego i dlatego powinieneś używać valgrind od czasu do czasu, gdy nie masz problemów, i valgrind i gdb, kiedy to zrobisz.

 2
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-15 17:28:27

Nie znam żadnej metodologii, której można by użyć do naprawiania takich rzeczy. Nie sądzę, że byłoby możliwe wymyślić jeden albo dla samego problemu pod ręką jest to, że zachowanie programu jest niezdefiniowany(Nie wiem o żadnym przypadku, gdy SEGFAULT nie został spowodowany przez jakiś UB).

Istnieją wszelkiego rodzaju "metodologie", aby uniknąć problemu, zanim się pojawi. Jednym z ważniejszych jest RAII.

Poza tym, musisz po prostu rzucić w to swoją najlepszą psychiczną energię.

 0
Author: Crazy Eddie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-15 16:43:04