![]() |
EAccessViolation führt zu unerwartetem APPCRASH (gelöst)
Hi,
für eine Konsolenanwendung die sich mit einem ActiveMQ Server verbindet und Nachrichten sendet habe ich versucht, bei einem temporären Ausfall des Servers (oder des Netzwerks) die Verbindung neu herzustellen und verwende dazu eine Schleife, die bei einer Exception verlassen und dann nach dem erneuten Verbindungsaufbau wieder gestartet wird. Anstatt die Schleife zu verlassen kommt es aber immer zu einem APPCRASH sobald der Server gestoppt wird. Hier erst einmal der Code für die Schleife mit der Exceptionbehandlung und der Code, der die Nachricht sendet:
Delphi-Quellcode:
Mit madExcept habe ich den Absturz untersucht und die Ursache ist anscheinend eine Access Violation. Im Stacktrace erscheint die Zeile 109 aus der ProducerLoop unit, dies ist die Zeile in der das "Break" steht mit dem die innere Schleife verlassen wird.
procedure TProducerLoop.Run;
begin while True do begin Connect; while True do begin try ProduceOneMessage; except on E: Exception do begin Break; // ---------------- Die innere Schleife soll bei einer Exception verlassen (stattdessen APPCRASH) end; end; end; Disconnect; end; end; procedure TProducerLoop.ProduceOneMessage; var Payload: string; begin Payload := Format('id [%d]', [Sequence.Value]); try Logger.Info('Produce ...'); Producer.Send(Queue, Payload); Logger.Info('Produced message: ' + Payload); Sequence.Increment; Sleep(100); except on E: Exception do begin Logger.Error('ProduceOneMessage', E); raise; end; end; end;
Code:
exception class : EAccessViolation
exception message : Access violation at address 00404A74 in module 'Producer.exe'. Read of address 00000000. main thread ($e3c): 00404a74 +170 Producer.exe System 44 +0 @HandleOnException 00404b5e +02a Producer.exe System 44 +0 @HandleFinallyInternal 777e3835 +0f4 ntdll.dll RtlUnwind 777aed27 +063 ntdll.dll bsearch 7779015e +00a ntdll.dll KiUserExceptionDispatcher 0045b0cf +033 Producer.exe SysUtils AppendChars 0040461a +002 Producer.exe System 44 +0 @ClassDestroy 0045d528 +03c Producer.exe SysUtils Exception.Destroy 00404198 +008 Producer.exe System 44 +0 TObject.Free 004531c9 +009 Producer.exe madExcept InterceptFreeExceptObject 00404d0a +016 Producer.exe System 44 +0 @DoneExcept 00482ebd +045 Producer.exe ProducerLoop 109 +12 TProducerLoop.Run 7779015e +00a ntdll.dll KiUserExceptionDispatcher 777aed27 +063 ntdll.dll bsearch 7779015e +00a ntdll.dll KiUserExceptionDispatcher 00499cc9 +025 Producer.exe IdTCPConnection 814 +3 TIdTCPConnection.CheckForGracefulDisconnect 0049ed83 +05b Producer.exe BTCommAdapterBaseIndy 424 +9 TBTCommAdapterBaseIndy.ConsumeHeartBeats 0049ef09 +055 Producer.exe BTCommAdapterBaseIndy 516 +6 TBTCommAdapterBaseIndy.ReadStompHeader 0049f626 +02a Producer.exe BTCommAdapterIndy 66 +1 TBTCommAdapterIndy.ReadFrame 0049f189 +055 Producer.exe BTCommAdapterBaseIndy 574 +5 TBTCommAdapterBaseIndy.ReadOneMessage 00477dce +066 Producer.exe BTStompClient 1232 +6 TBTStompClient.WaitForReceiptFrame 00475ca0 +140 Producer.exe BTStompClient 681 +22 TBTStompClient.Send 0047a426 +09e Producer.exe BTAbstractTransport 191 +12 TBTAbstractTransport.InternalSend 0047a6b1 +029 Producer.exe BTAbstractTransport 242 +3 TBTAbstractTransport.Send 00481d0e +126 Producer.exe BTConnection 1460 +40 TBTSession.Send 0047bda4 +0bc Producer.exe BTMessageProducer 251 +27 TBTMessageProducer.Send 0047bc73 +027 Producer.exe BTMessageProducer 209 +1 TBTMessageProducer.Send 0047d35e +022 Producer.exe BTMQProducer 160 +2 TBTMQProducer.InternalSend 0047d202 +03e Producer.exe BTMQProducer 125 +3 TBTMQProducer.Send 00482f62 +086 Producer.exe ProducerLoop 126 +5 TProducerLoop.ProduceOneMessage 00482e9b +023 Producer.exe ProducerLoop 105 +8 TProducerLoop.Run 004831e7 +033 Producer.exe ProducerUnit 38 +5 RunDemo 004a0754 +020 Producer.exe Producer 15 +3 initialization 75a7343b +010 kernel32.dll BaseThreadInitThunk Aus dem weiteren Stacktrace kann ich nicht erkennen warum die Schleife nicht verlassen wird. Ich teste als nächstes ob das Break in einem try ... except den Absturz verursacht. Die Entwicklungsumgebung ist Delphi 2009 auf Windows 7 (32 Bit). |
AW: EAccessViolation führt zu unerwartetem APPCRASH
Wäre da nicht ein Exit besser? Ich kann es mit den paar Source Krümeln leider nicht testen.
|
AW: EAccessViolation führt zu unerwartetem APPCRASH
Update:
Am Break liegt es nicht, mit diesem Code ergibt sich beim Stoppen des Servers ebenfalls ein APPCRASH:
Delphi-Quellcode:
Im Stacktrace erscheint die Zeile 111 aus der ProducerLoop unit, dies ist die Zeile in der das IsConnected := False steht mit dem die innere Schleife verlassen wird.
procedure TProducerLoop.Run;
begin while True do begin Connect; while IsConnected do begin try ProduceOneMessage; except on E: Exception do begin IsConnected := False; // ---------------- Die innere Schleife soll bei einer Exception verlassen (stattdessen APPCRASH) end; end; end; Disconnect; end; end;
Code:
exception class : EAccessViolation
exception message : Access violation at address 00404A74 in module 'Producer.exe'. Read of address 00000000. main thread ($b50): 00404a74 +170 Producer.exe System 72 +0 @HandleOnException 00404b5e +02a Producer.exe System 72 +0 @HandleFinallyInternal 77e83835 +0f4 ntdll.dll RtlUnwind 77e4ed27 +063 ntdll.dll bsearch 77e3015e +00a ntdll.dll KiUserExceptionDispatcher 0045b0cf +033 Producer.exe SysUtils AppendChars 7584c538 +041 KERNELBASE.dll RaiseException 0040461a +002 Producer.exe System 72 +0 @ClassDestroy 0045d528 +03c Producer.exe SysUtils Exception.Destroy 00404198 +008 Producer.exe System 72 +0 TObject.Free 004531c9 +009 Producer.exe madExcept InterceptFreeExceptObject 00404d0a +016 Producer.exe System 72 +0 @DoneExcept 00482ece +04e Producer.exe ProducerLoop 111 +12 TProducerLoop.Run 77e3015e +00a ntdll.dll KiUserExceptionDispatcher 77e4ed27 +063 ntdll.dll bsearch 7584c538 +041 KERNELBASE.dll RaiseException 77e3015e +00a ntdll.dll KiUserExceptionDispatcher 7584c538 +041 KERNELBASE.dll RaiseException 00491dee +016 Producer.exe IdStack 894 +1 TIdStack.RaiseLastSocketError 00491d59 +015 Producer.exe IdStack 868 +2 TIdStack.CheckForSocketError 0048df39 +025 Producer.exe IdStackBSDBase 444 +1 TIdStackBSDBase.Receive 0049320e +012 Producer.exe IdSocketHandle 321 +1 TIdSocketHandle.Receive 0049d843 +02b Producer.exe IdIOHandlerStack 431 +2 TIdIOHandlerStack.ReadDataFromSource 00497142 +0e2 Producer.exe IdIOHandler 1698 +28 TIdIOHandler.ReadFromSource 0049d367 +00b Producer.exe IdIOHandlerStack 243 +1 TIdIOHandlerStack.Connected 0049736b +017 Producer.exe IdIOHandler 1775 +8 TIdIOHandler.CheckForDataOnSource 0049ed86 +04e Producer.exe BTCommAdapterBaseIndy 421 +6 TBTCommAdapterBaseIndy.ConsumeHeartBeats 0049ef19 +055 Producer.exe BTCommAdapterBaseIndy 516 +6 TBTCommAdapterBaseIndy.ReadStompHeader 0049f636 +02a Producer.exe BTCommAdapterIndy 66 +1 TBTCommAdapterIndy.ReadFrame 0049f199 +055 Producer.exe BTCommAdapterBaseIndy 574 +5 TBTCommAdapterBaseIndy.ReadOneMessage 00477dce +066 Producer.exe BTStompClient 1232 +6 TBTStompClient.WaitForReceiptFrame 00475ca0 +140 Producer.exe BTStompClient 681 +22 TBTStompClient.Send 0047a426 +09e Producer.exe BTAbstractTransport 191 +12 TBTAbstractTransport.InternalSend 0047a6b1 +029 Producer.exe BTAbstractTransport 242 +3 TBTAbstractTransport.Send 004813fa +126 Producer.exe BTConnection 1460 +40 TBTSession.Send 0047f4bc +0bc Producer.exe BTMessageProducer 251 +27 TBTMessageProducer.Send 0047f38b +027 Producer.exe BTMessageProducer 209 +1 TBTMessageProducer.Send 0047ba1a +022 Producer.exe BTMQProducer 160 +2 TBTMQProducer.InternalSend 0047b8be +03e Producer.exe BTMQProducer 125 +3 TBTMQProducer.Send 00482f72 +086 Producer.exe ProducerLoop 128 +5 TProducerLoop.ProduceOneMessage 00482ea5 +025 Producer.exe ProducerLoop 107 +8 TProducerLoop.Run 004831f7 +033 Producer.exe ProducerUnit 38 +5 RunDemo 004a0754 +020 Producer.exe Producer 15 +3 initialization 7574343b +010 kernel32.dll BaseThreadInitThunk |
AW: EAccessViolation führt zu unerwartetem APPCRASH
Das Break verlässt nur die innere Schleife.
Danach kommt ein Disconnect, welches vermutlich einen Fehler verursachen wird. Prüfe vor dem Disconnect, ob IsConnected True ist. |
AW: EAccessViolation führt zu unerwartetem APPCRASH
Zitat:
|
AW: EAccessViolation führt zu unerwartetem APPCRASH
Ich seh es so wie Jasocul, das nicht das Break der Fehler ist sondern das was danach passiert.
|
AW: EAccessViolation führt zu unerwartetem APPCRASH
Zitat:
|
AW: EAccessViolation führt zu unerwartetem APPCRASH
ot
Ich habe da mal eine Frage, Du beginnst mit " while True do", worauf bezieht sich "True" ? /ot |
AW: EAccessViolation führt zu unerwartetem APPCRASH
Zitat:
als Breakpoint habe ich die Zeile mit IsConnected := False gesetzt. Dort stoppt das Programm dann wie erwartet, aber von dort geht es mit F8 sofort aus der Prozedur heraus in das finally der aufrufenden Methode.
Delphi-Quellcode:
ProducerLoop := TProducerLoop.Create(BROKER_URL, QUEUE_NAME);
try ProducerLoop.Run; // die Run-Prozedur wird bei einer Exception verlassen ... finally ProducerLoop.Free; // ... und daher das Programm hier fortgesetzt end; |
AW: EAccessViolation führt zu unerwartetem APPCRASH
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz