我已经为XE5 Update1更新了一些应用程序。从那时起,ShowMessage经常触发访问冲突。这在没有明显原因的几种应用中发生。如果我用简单的形式替换ShowMessage,则AV消失了。因此,很明显这是罪魁祸首ShowMessage。
AV出现在函数TaskDialogIndirect的WinApi.CommCtrl.pas中(请参见下面的标记行):
function TaskDialogIndirect(const pTaskConfig: TTaskDialogConfig;
pnButton: PInteger; pnRadioButton: PInteger; pfVerificationFlagChecked: PBOOL): HRESULT;
begin
if Assigned(_TaskDialogIndirect) then
Result := _TaskDialogIndirect(pTaskConfig, pnButton, pnRadioButton,
pfVerificationFlagChecked) // <====== HERE ==========
else
begin
InitComCtl;
Result := E_NOTIMPL;
if ComCtl32DLL <> 0 then
begin
@_TaskDialogIndirect := GetProcAddress(ComCtl32DLL, 'TaskDialogIndirect');
if Assigned(_TaskDialogIndirect) then
Result := _TaskDialogIndirect(pTaskConfig, pnButton, pnRadioButton,
pfVerificationFlagChecked)
end;
end;
end;
发生异常时的堆栈跟踪:
:671cab85 ; D:\Development\DelphiLibs\madCollection\madExcept\Dlls\madExcept32.dll
:671cabe2 ; D:\Development\DelphiLibs\madCollection\madExcept\Dlls\madExcept32.dll
:671ca755 madExcept32.ThisIsNoLeak + 0x29
:004aa9d7 ThisIsNoLeak + $F
:004a9412 HookedCreateThread + $82
:769613a2 msvcrt._beginthreadex + 0x74
:5f028473 ; C:\Windows\SysWOW64\DUser.dll
:5f028234 DUser.InitGadgets + 0xf5
:5f028177 DUser.InitGadgets + 0x38
:70e4da8d ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:70e5d492 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
Winapi.CommCtrl.TaskDialogIndirect(???,???,$18E974,$18E96C)
Vcl.Dialogs.TCustomTaskDialog.DoExecute(460578)
Vcl.Dialogs.TCustomTaskDialog.Execute(???)
Vcl.Dialogs.TTaskMessageDialog.Execute(???)
Vcl.Dialogs.TCustomTaskDialog.Execute
Vcl.Dialogs.DoTaskMessageDlgPosHelp('','Calibration failed Unknown error',mtCustom,[mbOK],0,-1,-1,'',mbOK)
Vcl.Dialogs.DoTaskMessageDlgPosHelp('',???,mtCustom,[mbOK],0,-1,-1,'')
Vcl.Dialogs.MessageDlgPosHelp('Calibration failed Unknown error',mtCustom,[mbOK],0,-1,-1,'')
Vcl.Dialogs.ShowMessagePos('',-1,-1)
Vcl.Dialogs.ShowMessage(???)
AutomationTechspCalibration.TCalibrationForm.StartCalibrationButtonClick($8C56D14)
Vcl.Controls.TControl.Click
Vcl.StdCtrls.TCustomButton.Click
Vcl.StdCtrls.TCustomButton.CNCommand(???)
Vcl.Controls.TControl.WndProc((48401, 1786, 526074, 0, 1786, 0, (), 1786, 8, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((48401, 1786, 526074, 0, 1786, 0, (), 1786, 8, (), 0, 0, ()))
Vcl.StdCtrls.TButtonControl.WndProc((48401, 1786, 526074, 0, 1786, 0, (), 1786, 8, (), 0, 0, ()))
Vcl.Controls.TControl.Perform(???,???,526074)
Vcl.Controls.DoControlMsg(???,(no value))
Vcl.Controls.TWinControl.WMCommand((273, (), 1786, 0, (), 526074, 0))
Vcl.Forms.TCustomForm.WMCommand((273, (), 1786, 0, (), 526074, 0))
Vcl.Controls.TControl.WndProc((273, 1786, 526074, 0, 1786, 0, (), 1786, 8, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((273, 1786, 526074, 0, 1786, 0, (), 1786, 8, (), 0, 0, ()))
Vcl.Forms.TCustomForm.WndProc((273, 1786, 526074, 0, 1786, 0, (), 1786, 8, (), 0, 0, ()))
Vcl.Controls.TWinControl.MainWndProc(???)
System.Classes.StdWndProc(460578,273,1786,526074)
:757462fa ; C:\Windows\syswow64\USER32.dll
:75746d3a USER32.GetThreadDesktop + 0xd7
:7574965e ; C:\Windows\syswow64\USER32.dll
:757496c5 USER32.SendMessageW + 0x4c
:70e84601 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:70e84663 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:70e844ed ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:757462fa ; C:\Windows\syswow64\USER32.dll
:75746d3a USER32.GetThreadDesktop + 0xd7
:75750d27 USER32.GetClientRect + 0xc5
:75750d4d USER32.CallWindowProcW + 0x1b
Vcl.Controls.TWinControl.DefaultHandler(???)
:005b92ef TWinControl.DefaultHandler + $EB
:005b91de TWinControl.WndProc + $5CA
:005d6599 TButtonControl.WndProc + $71
:0053ea12 StdWndProc + $16
:757462fa ; C:\Windows\syswow64\USER32.dll
:75746d3a USER32.GetThreadDesktop + 0xd7
:757477c4 ; C:\Windows\syswow64\USER32.dll
:7574788a USER32.DispatchMessageW + 0xf
任何帮助表示赞赏。
最佳答案
我禁用了madExcept并使用了FastMM4(不是XE5附带的,而是Sourceforge的最新版本)。 FastMM立即向我显示了madExcept尚未捕获的缓冲区溢出。
我解决了这个问题。我在FastMM上工作了几个小时,然后再次使用madExcept,一切正常。没有更多影音。
我的结论是,缓冲区溢出以导致ShowMessage AV的方式破坏了堆! madExcept不是问题,ShowMessage也不是。那是我自己的代码(缓冲区溢出),搞砸了所有内容。感谢FastMM几乎立即指向它(打开FastMM的FullDebugMode)。