2010-06-23 12 views
22

Moja aplikacja segfault czasami i głównie w malloc() i malloc_consolidate(), gdy patrzę na backtrace w gdb.Segfaults w malloc() i malloc_consolidate()

Sprawdziłem, czy maszyna ma wystarczającą ilość pamięci, że nawet nie zaczęła się zamiana. Sprawdziłem ulimity na segregację danych i maksymalny rozmiar pamięci i oba są ustawione na "bez ograniczeń". Ja również uruchomiłem aplikację pod valgrind i nie znalazłem żadnych błędów pamięci.

Teraz nie mam pomysłów, co jeszcze może powodować te uszkodzenia. Jakieś pomysły ?

Aktualizacja: Ponieważ nie jestem znalezienie czegokolwiek z valgrind (lub ptrcheck), to może być to, że inna aplikacja koszu strukturę pamięci LibC lub jest tam oddzielny struktura dla każdego procesu?

+2

Czy zdarzyło Ci się zderzyć pod wiatrem? –

+0

Nie, nie zawiesił się. Jest to aplikacja działająca w czasie rzeczywistym i pod obciążeniem mogącym obciążać ją tylko nieznacznie i zwykle tylko przy większym obciążeniu. –

+0

Jaki to system operacyjny? Sądząc po toolchainzie, brzmi to tak, jakby to był Linux. W tym przypadku nie, inne aplikacje nie mogą wyrzucić śmieci; to coś w twojej aplikacji. Jeśli dzieje się to tylko pod obciążeniem, to oczywiście jest to bardziej skomplikowane ... Co różni się pod obciążeniem? Jak to może spowodować, że wyrzucisz stertę? Spróbuj "torturować" swoją aplikację najlepiej jak potrafisz, gdy działa pod Valgrind ... jak najlepiej odtworzyć warunki, które mogłyby istnieć pod obciążeniem? Może za darmo przydzielić pamięć, coś w tym stylu? –

Odpowiedz

12

Najprawdopodobniej jesteś koszu sterty - to znaczy, piszesz poza granice kawałek pamięci, przydzielone, a to jest nadpisanie struktury danych, które malloc() używa do zarządzania sterty. To powoduje, że malloc() uzyskuje dostęp do nieprawidłowego adresu, a twoja aplikacja ulega awarii.

Kończy się pamięć, która nie spowodowałaby awarii programu malloc() - po prostu zwróciłaby NULL. To może spowodować awarię twojego kodu, jeśli nie sprawdzasz, czy jest NULL, ale strona z awarią nie byłaby w malloc().

To trochę dziwne, że Valgrind nie zgłasza żadnych błędów - ale są pewne błędy, które może przeoczyć domyślne narzędzie "Memcheck". Spróbuj uruchomić Valgrid przy pomocy "Ptrcheck" tool.

+0

Ale czy to nie powinno się pojawić pod valgrind? (Zakładając, że mój zasięg testu był wystarczająco dobry.) –

+1

Twój komentarz prawdopodobnie pokrył się z moją edycją - zgodnie z sugestią, spróbuj uruchomić Valgrind za pomocą narzędzia "Ptrcheck". Jeśli malloc() ulegnie awarii, jest prawie pewne, że w jakiś sposób zniszczysz stertę. –

+1

Od wersji Valgrind 3.7.0 (5 listopada 2011 r.), Narzędzie ** exp-ptrcheck ** zostało zmienione i zmniejszone w funkcji, aby kontrolować _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ check check check_proces_test_the_counter_. Nazywa się teraz ** exp-sgcheck ** ("Stack and Global Array Checking"). [link] (http://valgrind.org/docs/manual/dist.news.html) – Amar

21

Od http://www.gnu.org/s/libc/manual/html_node/Heap-Consistency-Checking.html#Heap-Consistency-Checking:

Inną możliwością, aby sprawdzić i ochronę przed błędami w stosowaniu malloc, realloc i wolna jest, aby ustawić zmienną środowiskową MALLOC_CHECK_. Po ustawieniu MALLOC_CHECK_ używana jest specjalna (mniej wydajna) implementacja , która jest zaprojektowana tak, aby była odporna na błędy proste, takie jak podwójne wywołania za darmo z tym samym argumentem, lub przekroczenia pojedynczego bajtu (off-by-one) błędy). Jednak nie wszystkie takie błędy mogą być chronione przed niepowodzeniem i mogą wystąpić przecieki pamięci. Jeśli MALLOC_CHECK_ jest ustawione na 0, wszelkie wykryte uszkodzenie sterty jest dyskretnie ignorowane; jeśli ustawione na 1, diagnostyka jest drukowana na stderr; jeśli ustawione na 2, przerwij nazywa się natychmiast. Może to być przydatne, ponieważ w innym wypadku awaria może nastąpić znacznie później, a prawdziwą przyczyną problemu jest bardzo trudne do wyśledzenia.