這是一個Delphi應用程序,但我想這是一個通用的Windows編程問題。我不明白堆棧溢出錯誤在調用堆棧中重複DispatchMessageW
我離開我的應用程序運行(在Delphi IDE中)在週末,並剛剛回來找到堆棧溢出。
堆棧開始是這樣的...
: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
因此,一個計時器到期,我創建一個新的對象(AnyDac組件)和堆棧溢出。代碼完全釋放了對象。對於那些想要檢查的人,我在下面附加了它,但我不認爲這是我的問題。
堆棧然後繼續
: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
隨着該塊重複3條thoussand線(!)我不知道它是什麼,或者它在做什麼。它然後結束
StoreRoom.StoreRoom
:75c4339a kernel32.BaseThreadInitThunk + 0x12
:77eb9ef2 ntdll.RtlInitializeExceptionChain + 0x63
:77eb9ec5 ntdll.RtlInitializeExceptionChain + 0x36
我不明白所有重複堆棧 - 任何人都可以建議嗎?
(以及你們誰發現我的異常處理是顯示一個對話框的astutute,也就是當用戶點擊OK封閉一個TForm的)
我的代碼:
procedure TMainForm.ServerAliveTimerTimer(Sender: TObject);
begin
try
ADConnection := TADConnection.Create(Self); <======= stack overflow 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()
+1堆棧溢出問題。 – lkessler
爲什麼需要每次創建連接類而不是使用ADConnection.Connected True/False?數據庫連接設置在運行時是否更改? – pani
這個問題是Orignally題爲「我不懂stackoverflow」,但唉有人編輯它(+1對所有的相似者) – Mawg