I do not understand error with repeated DispatchMessageW in call stack

This is a Delphi application, but I suppose this is a general Windows programming issue.

I left my application (in the Delphi IDE) on the weekend and just returned to find a stack overflow.

The stack starts like this:

:75c4417e kernel32.GetDriveTypeW + 0x23 :75c452ae kernel32.IsProcessorFeaturePresent + 0xa9 :75c45272 kernel32.IsProcessorFeaturePresent + 0x6d :75c45248 kernel32.IsProcessorFeaturePresent + 0x43 :7678410b KERNELBASE.LoadStringBaseExW + 0xc7 :76678ed2 USER32.LoadStringW + 0x19 :0040c4ae LoadResString + $4A uADStanDef.TADDefinition.Create(nil) uADStanDef.TADDefinition.CreateTemporary uADStanDef.TADConnectionDefTemporaryFactory.CreateObject uADStanFactory.TADManager.CreateInterface((1050358107, 62550, 16757, (168, 100, 178, 87, 60, 74, 32, 21)),(no value),True) uADStanFactory.ADCreateInterface((1050358107, 62550, 16757, (168, 100, 178, 87, 60, 74, 32, 21)),(no value),True) uADCompClient.TADCustomConnection.Create($2DB7EB0) fMainForm.TMainForm.ServerAliveTimerTimer($2E8DE38) <========== my code :004f1546 Winapi + $4F1546 :00461316 Winapi + $461316 :766762fa ; C:\Windows\syswow64\USER32.dll :76676d3a USER32.GetThreadDesktop + 0xd7 :766777c4 ; C:\Windows\syswow64\USER32.dll :7667788a USER32.DispatchMessageW + 0xf 

So, the timer expires, I create a new object (AnyDac component) and stack overflow. Code definitely frees an object. I have added it below for those who want to check, but I do not think this is my question.

Then the stack continues

 :7669cdfd ; C:\Windows\syswow64\USER32.dll :7669cf5c ; C:\Windows\syswow64\USER32.dll :766cf73c ; C:\Windows\syswow64\USER32.dll :766cfa18 ; C:\Windows\syswow64\USER32.dll :766cfb1f USER32.MessageBoxTimeoutW + 0x52 :766cfd15 USER32.MessageBoxExW + 0x1b :766cfd57 USER32.MessageBoxW + 0x18 :00549986 Vcl + $549986 :00549aa2 Vcl + $549AA2 :00549873 Vcl + $549873 :00461316 Winapi + $461316 :766762fa ; C:\Windows\syswow64\USER32.dll :76676d3a USER32.GetThreadDesktop + 0xd7 :766777c4 ; C:\Windows\syswow64\USER32.dll :7667788a USER32.DispatchMessageW + 0xf 

Three thousand lines are repeated with this block (!) And I have no idea what it is or what it does. Then it ends

 StoreRoom.StoreRoom :75c4339a kernel32.BaseThreadInitThunk + 0x12 :77eb9ef2 ntdll.RtlInitializeExceptionChain + 0x63 :77eb9ec5 ntdll.RtlInitializeExceptionChain + 0x36 

I do not create all these repeating stacks - can anyone advise?

(And for you who notice that my exception handling shows a dialog, this is TForm, which closes when the user clicks OK)

My code is:

 procedure TMainForm.ServerAliveTimerTimer(Sender: TObject); begin try ADConnection := TADConnection.Create(Self); <======= Qaru here ADConnection.DriverName := 'mysql'; ADConnection.Params.Add('Server=' + MAIN_STOREROOM_IP_ADDRESS); // other params, such as password, removed for posting ADConnection.Connected := True; except on E : Exception do begin ADConnection.Free(); theDialogForm := TDialogFormForm.Create(Nil); theDialogForm.ShowTheForm('Database problem'+#13+#10+''+#13+#10+ E.ClassName+#13+#10+E.Message); StopTheApplication(); <===== just calls ExitProcess(0); Exit; as I had problems with Halt elsewhere in the code end; end; if isMainStoreRoom then begin CheckIfStoreRoomIsAlive(SECONDARY_STOREROOM_IP_ADDRESS); end else begin CheckIfStoreRoomIsAlive(MAIN_STOREROOM_IP_ADDRESS); end; try // Now, update our own timestamp timestamp := GetCurrentUnixTimeStamp(); ADConnection.ExecSQL('UPDATE server_status SET alive_timestamp="' + IntToStr(timestamp) + '" WHERE ip_address="' + ipAddress + '"'); except on E : Exception do begin ADConnection.Free(); Exit; end; end; ADConnection.Free(); end; // ServerAliveTimerTimer() 
+6
source share
1 answer

Stack overflow due to MessageBox() called again and again in response to a message with a repeating window. Inside MessageBox() , its own message loop starts, which obviously processes and sends the same message again and again. This may mean a timer that has gone astray. I highly recommend disabling your timer when you first enter the OnTimer event OnTimer , and then re-enable the timer before exiting.

In a separate note, StopTheApplication() should NOT be called ExitProcess() (or even Halt() ) directly. Use Application.Terminate() instead.

+15
source

Source: https://habr.com/ru/post/926076/


All Articles