Jak namierzyć przyczynę pojawiania się błędu 0xC0000005?

0

Ponad rok temu napisałem program, który współpracuje z usługą udostępnioną przez SOAP. Program działa w wielu środowiskach u wielu klientów (ok 100 instalacji w całej polsce).

Program może działac w trybie automatycznym (poprzez uruchomienie go z odpowiednim parametrem w Harmonogramie Zadań systemu Windows), albo ręcznym (normalne uruchomienie execka.

W 99% przypadków program działa bezawaryjnie od zawsze. Mam jednak jednego klienta, który działa w środowisku terminalowym (Windows 2008 R2), do tego w mocno zwirtualizowanym otoczeniu (po prostu ma wykupiony dedykowany serwer, do którego ma dostęp przez usługi terminalowe). Na tym środowisku jest 12 baz PostgreSQL, z którymi program się łączy (właściwie dla każdej instancji bazy uruchamiana jest osobna instancja programu z odpowiednimi parametrami w innym okresie czasu - w odstępach ok 10 min).

Program wykonuje szereg czynności - m.in. połączenie do bazy, logowanie do usługi SOAP, pobranie zestawu danych z bazy, które mają być przesłane do SOAP, odebranie wyników przetwarzania usługi SOAP, zapis do bazy, wysłanie emaila z wynikami przetwarzania, itd, itd.

U tego jednego klienta raz na kilkadziesiąt uruchomień, któraś z instancji zawiśnie w trakcie wykonywania. Np. Zostanie przetworzone 30% pozycji i zima. Czasem zatrzymuje się zaraz po uruchomieniu.

Nie ma to związku z konkretną bazą, bo problem objawia się w różnych momentach, na różnych bazach - nie ma jakiejś specjalnej reguły czasowo-lokalizacyjnej.

Problem obserwuję od ok 3 miesięcy (codziennie ręcznie sprawdzam logi wykonania).

W związku z tym, że działa to w środowisku wysokodostępowym i wysokozabezpieczonym - administrator przekazał mi informację, że być może działanie mojego programu interferuje z zaplanowanymi zadaniami serwisowymi (backup, przepinki maszyn wirtualnych na Hyper-V, itd). Przestawiliśmy harmonogram pracy poza okres zaplanowanych prac serwisowych - częstotliwość pojawiania się błędów bez zmian.

Niedawno zadawałem tutaj pytanie o timeouty usługi SOAP - idąc tokiem myślenia, że być może usługa SOAP miewa jakieś czknięcia, a ja ich nie obsługuję. Timeout został wdrożony, ale nawet na bardzo krótkim okresie (rzędu kilkunastu milisekund) działa stabilnie, a błąd jak się pojawiał tak się pojawia.

Dzisiaj jednak czystym przypadkiem zwróciłem uwagę podczas restartu programu na zawiśniętej bazie (zwykle uruchamiałem program ręcznie) - w harmonogramie zadań status ostatniego wykonania dla tej programu dla tej bazy był: 0xc0000005

Trop jest dość nikły, ale pytanie w takim razie - czego szukać. Co może powodować ten błąd. Opisy, które znajduję na Googlach nie dają mi jasnego obrazu w która stronę patrzeć.

Mam jeden pomysł co może być powodem, ale nie jestem przekonany czy na pewno (wiem, że zrealizowałem go chamsko i dostanę teraz po głowie, ale robiłem na kolanie. Zadziałało, więc nie zmieniałem ;) ). Chodzi o to, że w trakcie pracy - program loguje sobie do TStringsa wszystkie komunikaty. Na początku życia programu zapis logów szedł na końcu programu. W trakcie rozwoju pojawiała się konieczność obsługiwania coraz to kolejnych wyjątków, które crashowały aplikację, ale żeby je wyłapać - potrzebowałem, żeby logi zapisywały się na bieżąco. Więc dodałem zapis TStrings.SaveToFile po każdej dodanej linijce (wiem, wiem - chamskie). Być może coś następuje w trakcie kolejnego zapisu zawartości pliku.

Trochę brakuje mi pomysłów gdzie szukać.

0

do logów masz np. darmowy Log4D (wzorowany na Log4J, chociaż nierozwijany to jednak do logowania stanów aplikacji/błędów się sprawdza). Jak nie chcesz tego to zamień TStringList na "głupie" TEXTFILE albo strumień i dopisuj tylko NOWE rzeczy a nie machaj plikiem z logiem w tę i nazad

0

Tak informacyjnie: ten błąd wskazuje na Access Violation. Czyli problem będzie gdzieś z tworzeniem/zwalnianiem czegoś. Może w pierwszej kolejności zbadaj aplikację pod kątem memory leaków.

0

Zainstaluj sobie EurekaLog triala powinien dać wskazanie w linijkę kodu która generuje błąd.
Do logowania użyj HotLog dostępny pod http://mapage.noos.fr/qnno/pages/hLog_ex.htm
Ps. jaką technologią łączysz się z bazą danych ? Czy pobierasz dane z bazy w osobnych wątkach ?

0

ZEOSem łączę się z Postgresem 9.0

Jawnie nie pobieram danych w osobnych wątkach - chyba, że ZEOS robi to gdzieś wewnątrz.

Jeżeli chodzi o TStrings to (ale mogę się mylić) - w XE2 SaveToFile pod spodem wykorzystuje TStream. Chyba, że chodzi o to, żeby nie otwierać strumienia do każdego zapisu, tylko otworzyć raz i trzymać go otwartego cały czas działania aplikacji.

0

No i jak sprawdziłeś w działaniu EurekaLog-a ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1