以下代碼在我的計算機上似乎可以正常工作,但會爲客戶提供訪問衝突。行之間的訪問衝突
procedure TSummaryThread.Execute;
var
When: String;
begin
try
FCarcassListCS := TCriticalSection.Create;
FCarcassLists := TObjectList.Create;
while (not Terminated) do
begin
try
When := 'GetMessage';
if (GetMessage(Msg, 0, 0, 0))
then begin
if (Msg.message = WM_SUMMARISE)
then begin
When := 'WM_SUMMARISE';
Update(True);
end
else if (Msg.message = WM_UPDATE)
then begin
When := 'WM_UPDATE';
Update(False);
end
else if (Msg.message = WM_RELOAD_SETUP)
then begin
When := 'WM_RELOAD_SETUP';
ReloadSetup(Pointer(Msg.wParam));
end
else if (Msg.message = WM_SEND_TO)
then begin
When := 'WM_SEND_TO';
SendToThread(Pointer(Msg.wParam));
end
else if (Msg.message = WM_UPDATE_ORDER_SUM)
then begin
When := 'WM_UPDATE_ORDER_SUM';
DoOrderSummary;
end
else if (Msg.message = WM_SUMMARISE_LOAD)
then begin
When := 'WM_SUMMARISE_LOAD';
LoadAndSummarise;
end
else begin
When := 'DispatchMessage';
DispatchMessage(Msg);
end;
end;
except
on E: Exception do
Log('Exception (' + E.ClassName + ') in summary thread at ' + When + ': ' + E.Message);
end;
end;
except
on E: Exception do
Log('Exception (' + E.ClassName + ') in summary thread (2) at ' + When + ': ' + E.Message);
end;
procedure TSummaryThread.Update(Full: Boolean);
var
CarcassList: TObjectList;
Where: String;
begin
try
Where := 'GetList';
FCarcassListCS.Enter;
try
if (FCarcassLists.Count = 0)
then raise Exception.Create('No carcass list found');
CarcassList := FCarcassLists[0] as TObjectList;
FCarcassLists.Extract(CarcassList);
finally
FCarcassListCS.Leave;
end;
FSummaryListCS.Enter;
try
Where := 'LoadFiles';
SetFiles;
try
Where := 'AddCcs';
CarcassList := GetShiftCarcassList(CarcassList);
AddCarcassesToSummaries(CarcassList, Full);
finally
CloseFiles;
end;
Where := 'Send';
SendSummaries;
Where := 'Done';
finally
FreeAndNil(CarcassList);
FSummaryListCS.Leave;
end;
except
on E: Exception do
begin
E.Message := 'Update(' + Where + '): ' + E.Message;
raise;
end;
end;
end;
從記錄我可以告訴When := 'WM_UPDATE';
被擊中Where := 'GetList';
不是。這導致我認爲在將Update()
過程中的本地Where
變量添加到堆棧時發生訪問衝突。
我可以添加哪些額外的診斷來幫助解決導致問題的原因?有什麼方法可以檢查堆棧是否損壞和/或將Where
變量添加到堆棧?
我意識到這是一個相當模糊的問題,但我想不出任何可以嘗試縮小範圍的問題。
確切錯誤是:
異常(EAccessViolation)在摘要線程WM_UPDATE:訪問衝突在模塊地址004B6759 'Application.exe'。讀取地址00000008
(1)確切的錯誤信息?(2)你確定線程對象是有效的並且沒有消失嗎? – JensG
您如何知道訪問衝突正在發生?什麼是實際症狀/日誌?未能在堆棧上放置變量不會生成AV,並且將一個值(特別是文字)賦值給'String'並不會將該數據放在堆棧上。在這段代碼中沒有任何東西可以導致你聲稱的AV,除非AV是從RTL的內存管理器本身來的,在這種情況下你的應用程序被搞砸了,你需要重新啓動它。 –
順便說一下,當涉及到跟蹤內存問題時,儘量減少內存分配,不要使用分配來跟蹤問題。使用['OutputDebugString()'](http://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx)進行日誌記錄,並使用類似[DebugView]的工具(http:// technet .microsoft.com/en-us/sysinternals/bb896647.aspx)在IDE調試器外部運行應用程序時查看這些消息。 –