2012-05-08 25 views
6

Mam problemy podczas próby wykrycia naruszenia zasad dostępu w moim programie. Występuje, gdy destruktor jest wywoływany po raz trzeci, dokładnie wtedy, gdy destruktor wydaje się kończyć.C++ Wszelkie porady dotyczące śledzenia naruszeń dostępu?

Spędziłem wiele godzin próbując to sprawdzić, więc szukam dalszych porad na temat tego, co mogę zrobić. Tworzę instancję klasy z operatorami new i delete. Okno wyjściowe Visual Studio pokazuje:

First-chance exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab. Unhandled exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab.

Czy mogę coś zrobić, aby spróbować dowiedzieć się, co było w tych miejscach pamięci?

Okno stosu wywołań pokazuje następujący (w odwrotnej kolejności jak już wklejony go do porządku chronologicznym, najwcześniej do najnowszego):

Program.exe!Network::`scalar deleting destructor'() + 0x2b bytes C++ 

Program.exe!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::~basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >() Line 754 + 0xf bytes C++ 

Program.exe!std::_String_val<wchar_t,std::allocator<wchar_t> >::~_String_val<wchar_t,std::allocator<wchar_t> >() Line 478 + 0xb bytes C++ 

msvcp100d.dll std :: _ Container_base12 :: _Orphan_all() Linia 214 + 0x5 bajtów C++

Według mojej najlepszej opinii na temat tej informacji istnieje jakiś rodzaj zmiennej łańcuchowej powodującej problem? Czy ktoś ma jakieś porady dotyczące interpretacji tych informacji?

Wszelkie inne porady również byłyby przydatne, z góry dziękuję.

Kodowanie pod Windows 7 i przy użyciu Visual Studio 2010 Professional.

+2

[valgrind] (http://valgrind.org/) – dasblinkenlight

+1

0xABABABAB jest używany przez HeapAlloc jako bajt strażnika. Być może gdzieś masz gdzieś uszkodzić pamięć. http://asawicki.info/news_1292_magic_numbers_in_visual_c.html –

+0

@dasblinkenlight Podobnie jak Valgrind, nie obsługuje systemu Windows. – cgmb

Odpowiedz

3

Miałem sukces śledzenia błędów pamięci przed użyciem BoundsChecker (now part of Borland DevPartner). Istnieje wiele podobnych produktów, które mogą również pomóc: HeapAgent i Rational Purify. Te wydają się być bardzo podobne do ValGrind, ale działają w systemie Windows.

Oto 3 open source alternatyw, które mogą pomóc:

  1. DUMA (przez wygląda to, trzeba będzie budować dla Windows siebie, ale README zawiera kilka wskazówek na to robić)

  2. XMEM

  3. elephant

Nie mam pojęcia, jak te występy, ale brzmią bardzo obiecująco i wyglądają tak, jakby wszystkie działały w systemie Windows w taki czy inny sposób.

Ta pomoc może również pomóc w uzyskaniu pomocy pod adresem Microsoft page on managing memory errors, a także zawiera łącza do ustawiania punktów zatrzymania pamięci, które mogą pomóc w ustaleniu, kiedy dane zostaną najpierw usunięte lub zmienione. Powodzenia!

+0

Podczas gdy te linki wydają się interesujące, wolałbym nie kupować nowego oprogramowania, aby rozwiązać ten problem. – Interminable

+0

Mój projekt jest gotowy za niecały tydzień, chcę mieć ten kod zawinięty w kilka dni, nie mogę sobie pozwolić na instalację systemu operacyjnego, którego nie znam i próbuję kodować pod tym w IDE Jestem nieznany w celu korzystania z oprogramowania do debugowania, które nie jest gwarantem rozwiązania problemu, którego doświadczam, przepraszam. EDYCJA: komentarz, na który ten komentarz odpowiadał, zniknął. – Interminable

+0

Link do BoundsChecker nie działa – TankorSmash

2

Użyj narzędzi do debugowania Microsoft Heap i miej nadzieję, że to jeden z przypadków, dla których został zaprojektowany. Oczyszczenie będzie następnym krokiem.

Jest wbudowane w Visual Studio i jest pomocne w niektórych przypadkach. Jeśli to zadziała, z pewnością bije dając IBM dwie lub trzy kieszenie pełne gotówki na Purify.

można znaleźć informacje here

TL; DR W głównym, zrób to

 
int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 
// Turn On (OR) - Keep freed memory blocks in the 
// heap's linked list and mark them as freed 
tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF; 

// Turn on memory checking at each heap operation 
tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF; 

// Set the new state for the flag 
_CrtSetDbgFlag(tmpFlag); 

Można przełączać flagę _CRTDBG_CHECK_ALWAYS_DF w różnych miejscach, jeśli przebiega zbyt wolno. Jednak uruchomiłbym to kilka razy z każdą opcją op sprawdzoną, aby zorientować się, gdzie występuje problem.

1

Napisałem ten blog z niektórych wskazówek

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

Główną rzeczą, którą musisz zrobić, to aby uzyskać awarii lub wyjątku wydarzy natomiast kod z błędu jest wciąż na stosie. Wiele razy otrzymujesz naruszenie dostępu po wykryciu kodu z błędem i może to potrwać długo (w czasie komputera). W takim przypadku jest prawie niemożliwe, aby to rozgryźć.

W twoim przypadku, z problemem oznaczonym jako "usuń", jest to silny wskaźnik, że sterty są uszkodzone, a dwiema typowymi przyczynami w C++ są podwójne usuwanie i mieszanie usuwania macierzy (użycie polecenia delete przy użyciu polecenia delete [] Albo na odwrót).

Jeśli możesz odtworzyć go z prostym kodem, chciałbym poszukać dwóch powyższych problemów. W przeciwnym razie pobierz narzędzia do debugowania Microsoft i użyj gflags +hpa -i program.exe, aby uczynić kupę dużo bardziej wrażliwą na korupcję (znacznie szybciej zgłosi błąd).