2015-12-02 47 views
5

Tworzę bibliotekę, która ma zbyt dużo kodu, aby ją podać tutaj.Jak polować na "nieprawidłowy adres podany w następnej linii" błąd

Moim problemem jest usterka segmentacji, że Valgrind analizować jako:

Skocz do nieprawidłowy adres podany na następnej linii
na 0x72612F656D6F682F: ???
w [...] (call stack)

Dzięki this question, myślę, że to dlatego, że mam gdzieś stosu korupcji.

Moje pytanie brzmi: jak to znaleźć?
Próbowałem użyć GDB, ale błąd segmentacji wydaje się nie być w tym samym miejscu. GDB mówi mi, że jest w pierwszym wierszu funkcji, podczas gdy Valgrind mówi, że to wywołanie tej funkcji powoduje błąd segmentacji.

+1

Polowanie na problemy związane z UB nie jest zabawne, a sortowanie sterty/sterty może być naprawdę bolesne. Nie znam idealnego, metodycznego sposobu, aby to zrobić - tylko proces zawężania podejrzanych (np. Czasowo pomiń sekcje kodu do przetworzenia, wyeliminuj podejrzanych jak badacz). To, co odkryłem na przestrzeni lat, to to, że mam ich coraz mniej - łatwiej im zapobiegać niż później. Bardzo przydatne mogą być założenia o charakterze liberalnym, a zwłaszcza o niebezpiecznym kodzie. Robienie rygorystycznych testów zawsze, gdy angażujesz konstrukty niskopoziomowe, może uratować życie. –

+1

Rygor procedury testowej powinien zazwyczaj być skalowany z ilością kodu niskiego poziomu, który piszesz - na przykład, jeśli piszesz kontener niskiego poziomu lub alokator pamięci, który wymaga wielu testów jednostkowych. W każdym razie - obawiam się, że to nie jest tak pomocne dla bezpośredniego problemu - może ktoś ma naprawdę świetny sposób na ich debugowanie. –

+1

@ Tak, to był eksperymentalny kontener, który nadpisał dane na moim stosie ... Dzięki za radę. – Aracthor

Odpowiedz

4

Jeśli problem jest powtarzalny, można użyć techniki podobnej do this answer, aby ustawić punkt obserwacyjny na lokalizacji adresu zwrotnego, a GDB zatrzymać instrukcję bezpośrednio po tym, który ją psuje.

+0

@Aracthor Punktem wyjścia jest dokładne poinformowanie Cię, jak to znaleźć. * Wiesz * gdzie jest przechowywany adres zwrotny, a ty wiesz * że jest poprawny przy wejściu do funkcji. Ustaw więc punkt obserwacyjny, a GDB zatrzyma się, gdy ta lokalizacja zostanie nadpisana. –

+0

Ale jaka jest * lokalizacja adresu zwrotnego *, którą powinienem ustawić jako punkt kontrolny? – Aracthor

+0

Jeśli masz niezoptymalizowaną kompilację i jeśli korzystasz z 'x86_64', to kiedy' step' wprowadzisz do funkcji (poprzednia funkcja prolog), adres powrotu będzie przechowywany w '$ rbp [1]'. Jeśli zrobisz 'x/2a $ rbp', powinieneś zobaczyć poprzedni $ rbp i adres osoby dzwoniącej twojej funkcji. Jeśli masz zoptymalizowaną kompilację, będziesz musiał "zdemontować" funkcję, aby znaleźć miejsce, w którym zapisany jest adres zwrotny. –