Jak debugować usterki segmentacji w C?

Jak debugować usterki segmentacji w C?

Naruszenie dostępu ma miejsce, gdy procesor próbuje instrukcje ustawione poza obszarem pamięci lub odczytuje lub zapisuje do zastrzeżonej lokalizacji, która nie istnieje, co powoduje usterkę segmentacji. Niniejsza aplikacja jest zatrzymana w wyniku tego działania, a wynik wyznaczony jako usterka segmentacji jest wygenerowana. Ponieważ dane są często udostępniane w regionach pamięci w systemie, a przestrzeń do przechowywania programu jest udostępniana między aplikacjami, problem ten.

Niektóre maszyny mogą doświadczyć winy segmentacji, podczas gdy inne nie. Jeśli tak się stanie, zwykle oznacza to, że masz problem z kodem i udało nam się uciec od tego systemu przez szczęście. Wszystko polega na zorganizowaniu pamięci i tego, czy jest ona zerowa. Przeanalizujemy, jak zidentyfikować problem segmentacji programu w tym artykule.

Jaka jest wina segmentacji?

Wadość segmentacji, często znana jako SEGFAULT, jest rodzajem błędu komputera, który ma miejsce, gdy procesor próbuje uzyskać dostęp do adresu pamięci poza regionem magazynowym programu z powodu nieoczekiwanego stanu. Termin „segmentacja” odnosi się do metody ochrony pamięci wirtualnej pamięci. Podczas pracy z wskaźnikami w C ++/C często napotykamy ten problem.

Korzystanie z kompilatora GDB do błędu segmentacji

Aby dowiedzieć się, dlaczego programy C tworzą usterkę segmentacji, użyjemy GDB. GDB to debugger C (i C ++). Umożliwia programowi przebieganie do określonego punktu, a następnie zatrzymuje i zgłasza wartości określonych zmiennych w tym momencie lub przechodzi przez program jeden na raz, drukując wartości każdej zmiennej po wykonaniu każdej linii. Debugger GDB pomoże nam dowiedzieć się, które wiersze są odpowiedzialne za kwestię segmentacji.

Kluczowe punkty, aby zapobiec błędom segmentacji

Chociaż awarie dostępu do pamięci powodują większość błędów segmentacji, ważne jest, aby wskaźniki używane w programie zawsze odnoszą się do dopuszczalnych lokalizacji danych. Oto sposoby zapobiegania błędom segmentacji.

  • Ponieważ awarie dostępu do pamięci powodują większość błędów segmentacji, ważne jest, aby wskaźniki aplikacji zawsze wskazują na prawidłowe lokalizacje danych.
  • Przed odniesieniem odniesienia wrażliwego, takiego jak jedno wbudowane w strukturę przechowywaną na liście lub tablicy, powinniśmy wywołać Assert ().
  • Zawsze pamiętaj o prawidłowej inicjowaniu wskaźników.
  • Mutex lub semafor można wykorzystać do ochrony wspólnych zasobów przed równoczesnym dostępem do wielowy.
  • Powinniśmy użyć funkcji Free ()

Przykład 1: Program usterki segmentacji poprzez dereferencje wskaźnika z bloku pamięci w c

Mamy ilustrację usterki segmentacji, w której staramy się uzyskać dostęp do adresu wskaźnika, który uwolnił się. W poniższej funkcji głównej programu C mamy Deklaracja zmiennej wskaźnika „Int* a” i przydzielliśmy pamięć do zmiennej wskaźnika „A”. Ustanie segmentacji zostanie wygenerowane, gdy program będzie próbował odczytać z wskaźnika dereferencji *.

#włączać
int main (int argc, char ** argv)

int* a;
*a = 50;
powrót 0;

W kompilacji powyższego kodu widocznego na poniższym ekranie linia *a = 50 powoduje usterkę segmentacji.

Przykład 2: Program usterki segmentacji poprzez dostęp do tablicy z wiązania w C

Usunięcie segmentacji występuje w większości przypadków, gdy program próbuje odczytać lub zapisać pamięć poza jego granicami. W poniższym programie zadeklarowaliśmy szereg indeksu „10”, próbujemy pobrać wskaźnik tablicy, która jest poza związana i zainicjowa go wartością liczbową. To jest punkt, w którym otrzymamy usterki segmentacji po wykonaniu linii programu nieokreślonego.

#włączać
int main (int argc, char ** argv)

int myarr [10];
Myarr [1000] = 2;
powrót 0;

Jesteśmy w kompilatorze GDB, w którym użyliśmy polecenia listy GDB. Polecenie listy GDB wydrukowało wiersz kodu z programu zaworów. Z linii „Myarr [1000] = 2”, mamy usterkę segmentacji. Możesz to zobaczyć w następnej konsoli GDB.

Przykład 3: Program usterki segmentacji poprzez dereferencje zerowe wskaźnik w C

Odniesienia są wskaźnikami w językach programowania, które wskazują, gdzie element jest przechowywany w pamięci. Wskaźnik zerowy to wskaźnik, który nie wskazuje na żadną prawidłową lokalizację pamięci. W poniższym programie zadeklarowaliśmy zmienną wskaźnika „wskaźnik” i przypisaliśmy jej wartość zerową. Wyjątek wskaźnika zerowego jest rzucany lub usterka segmentacji występuje, gdy wskaźnik zerowy jest dereferencyjny w wierszu „*wskaźnik = 10”.

#włączać
int main (int argc, char ** argv)

int *pointerval = null;
*Pointerval = 10;
powrót 0;

Wynik powyższego programu rzucił usterkę segmentacji po wykonaniu w linii „*Pointerval = 10” pokazano poniżej.

Przykład 4: Program usterki segmentacji przez przepełnienie stosu w C

Nawet jeśli kod nie ma ani jednego wskaźnika, nie jest to problem wskaźnika. Przepełnienie stosu występuje następnie, gdy funkcja rekurencyjna jest powtarzana wielokrotnie, zużywając całą pamięć stosu. Pamięć może również nastąpić, gdy stos jest przestrzeni. Można go naprawić, powracając z funkcji rekurencyjnej ze stanem podstawowym.

Tutaj, w programie, mamy główną funkcję, a w treści głównej funkcji wywołaliśmy inną główną funkcję. Prowadzi to do usterki segmentacji z powodu przepełnienia stosu.

#włączać
int Main (void)

główny();
powrót 0;

Możesz zobaczyć, jak kompilator GDB podaje usterkę segmentacji na linii, w której powołaliśmy się do głównej funkcji programu głównego bloku funkcji.

Wniosek

Artykuł rzuci trochę światła na usterki segmentacji i jak możemy je debugować za pomocą kompilatora GDB. Kompilator GDB określa, które linie są odpowiedzialne za awarię segmentacji. Sesja debugowania błędów segmentacji jest bardzo łatwa w obsłudze za pomocą kompilatora GDB w programowaniu C. Następnie wzięliśmy różne scenariusze, w których mogą wystąpić usterki segmentacji. Mam nadzieję, że w tym artykule wyjaśniono problemy z błędami segmentacji.