获取我无法追踪的奇怪访问冲突。当用户使用该程序时,似乎几乎随机发生。
使用madexcept,它显示堆栈跟踪:
date/time : 2014-09-17, 18:04:30, 366ms
operating system : Windows 8 x64 build 9200
system language : English
system up time : 3 days 19 hours
program up time : 1 hour
processors : 4x Intel(R) Core(TM) i3-3110M CPU @ 2.40GHz
physical memory : 3113/6036 MB (free/total)
free disk space : (C:) 562.61 GB
display mode : 1366x768, 32 bit
process id : $24d0
allocated memory : 43.32 MB
largest free block : 1023.78 MB
executable : MyProgram.exe
exec. date/time : 2014-09-17 17:03
compiled with : Delphi XE5
madExcept version : 4.0.8.1
callstack crc : $1d6387db, $5509d601, $a3980266
exception number : 10
exception class : EAccessViolation
exception message : Access violation at address 005A8BE4 in module 'MyProgram.exe'. Read of address 001C7424.
main thread ($1310):
005a8be4 +070 MyProgram.exe Vcl.Controls 5595 +12 TControl.Notification
005ae5cf +00f MyProgram.exe Vcl.Controls 9169 +1 TWinControl.Notification
00667b1b +00f MyProgram.exe Vcl.Forms 3779 +1 TCustomForm.Notification
00537894 +040 MyProgram.exe System.Classes 15856 +8 TComponent.Notification
005376e9 +01d MyProgram.exe System.Classes 15778 +2 TComponent.RemoveComponent
00537445 +029 MyProgram.exe System.Classes 15653 +4 TComponent.Destroy
00538b7f +013 MyProgram.exe System.Classes 16460 +1 TBasicAction.Destroy
00561672 +03a MyProgram.exe System.Actions 485 +4 TContainedAction.Destroy
0058f0b3 +027 MyProgram.exe Vcl.ActnList 228 +3 TCustomAction.Destroy
00408ee0 +008 MyProgram.exe System 15513 +1 TObject.Free
006732fa +082 MyProgram.exe Vcl.Forms 10947 +14 TApplication.SetHint
0067307e +066 MyProgram.exe Vcl.Forms 10863 +4 TApplication.Idle
0067237f +017 MyProgram.exe Vcl.Forms 10318 +1 TApplication.HandleMessage
006726ad +0c9 MyProgram.exe Vcl.Forms 10456 +26 TApplication.Run
0086b12a +39a MyProgram.exe MyProgram 152 +88 initialization
7786919d +00c KERNEL32.DLL BaseThreadInitThunk
更新
cpu registers:
eax = 740053f8
ebx = 00000001
ecx = 00000001
edx = 00000000
esi = 0253aea0
edi = 025c29c0
eip = 005aca54
esp = 0018fdf0
ebp = 006120a0
stack dump:
0018fdf0 c0 29 5c 02 b0 c9 59 02 - d6 00 00 00 07 b7 53 00 .)\...Y.......S.
0018fe00 01 00 00 00 6c e8 7d 00 - c0 29 5c 02 b0 c9 59 02 ....l.}..)\...Y.
0018fe10 01 00 00 00 f8 c9 5a 00 - b0 c9 59 02 c0 29 5c 02 ......Z...Y..)\.
0018fe20 01 00 00 00 44 24 5b 00 - b0 c9 59 02 c0 29 5c 02 ....D$[...Y..)\.
0018fe30 01 00 00 00 90 b9 66 00 - c0 29 5c 02 20 8d 5c 02 ......f..)\. .\.
0018fe40 00 00 00 00 07 b7 53 00 - 01 fe 18 00 c0 fe 18 00 ......S.........
0018fe50 b0 63 66 00 20 8d 5c 02 - c0 29 5c 02 5c b5 53 00 .cf. .\..)\.\.S.
0018fe60 c0 29 5c 02 c0 29 5c 02 - 00 2a 5c 02 ba b2 53 00 .)\..)\..*\...S.
0018fe70 c0 29 5c 02 00 2a 5c 02 - f4 c9 53 00 00 00 00 00 .)\..*\...S.....
0018fe80 1c ff 18 00 c0 29 5c 02 - 00 fe 18 00 e7 54 56 00 .....)\......TV.
0018fe90 4c 2a 5c 02 c0 29 5c 02 - 01 fe 18 00 28 2f 59 00 L*\..)\.....(/Y.
0018fea0 54 2f 59 00 20 8d 5c 02 - 1f 8f 40 00 6f 71 67 00 T/Y. .\...@.oqg.
0018feb0 77 71 67 00 00 00 00 00 - b0 c9 59 02 c0 29 5c 02 wqg.......Y..)\.
0018fec0 f0 fe 18 00 f3 6e 67 00 - 1c ff 18 00 2c a2 40 00 .....ng.....,.@.
0018fed0 f0 fe 18 00 1c ff 18 00 - 00 00 00 00 20 8d 5c 02 ............ .\.
0018fee0 00 00 00 00 00 00 00 00 - 1c ff 18 00 20 8d 5c 02 ............ .\.
0018fef0 44 ff 18 00 f4 61 67 00 - d8 02 02 00 00 02 00 00 D....ag.........
0018ff00 00 00 00 00 bf 00 6e 02 - ff 6d 56 00 57 02 00 00 ......n..mV.W...
0018ff10 2e 03 00 00 31 65 67 00 - 22 65 67 00 28 ff 18 00 ....1eg."eg.(...
0018ff20 fc 9f 40 00 44 ff 18 00 - 4c ff 18 00 65 65 67 00 ..@.D...L...eeg.
disassembling:
[...]
005aca4a loc_5aca4a:
005aca4a 5595 mov eax, [esi+$bc]
005aca50 test eax, eax
005aca52 jz loc_5aca5e
005aca52
005aca54 > cmp edi, [eax+$c]
005aca57 jnz loc_5aca5e
005aca57
005aca59 5596 xor edx, edx
005aca5b mov [eax+$c], edx
005aca59
005aca5e loc_5aca5e:
005aca5e 5598 pop edi
[...]
堆栈跟踪甚至不包括我的程序中的代码(除了初始化),所以我不知道是什么原因导致它。完整的程序很长,我不知道哪个部分负责做一个简短的例子。
编辑:启用反汇编并获得另一个日志 - 已添加额外信息。
答案 0 :(得分:6)
我们从信息中可以看出,错误是在TControl.Notification
中引发的。看起来像这样:
procedure TControl.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then
begin
if AComponent = PopupMenu then
PopupMenu := nil
else if AComponent = Action then
Action := nil
else if AComponent = FHostDockSite then
FHostDockSite := nil
else if AComponent = FCustomHint then
FCustomHint := nil
else if (FTouchManager <> nil) and (AComponent = FTouchManager.GestureManager) then
FTouchManager.FGestureManager := nil;
end;
end;
您还被告知要查看5595行,这是从函数开始的12行。那条线是:
else if (FTouchManager <> nil) and (AComponent = FTouchManager.GestureManager) then
现在,对错误的明显解释是FTouchManager
的读取触发了访问冲突。如果Self
(即执行该方法的实例)已被销毁,则会发生这种情况。
因此,出于某种原因,此方法似乎已在已被销毁的实例上调用。我们无法为您解释,除非您获得幸运,否则网络搜索会显示出完全相同症状的问题。接下来你需要做的是找到一种可靠地重现故障的方法,然后找出它发生的原因。
一个明显的步骤是在完全调试模式下使用FastMM。这将使得释放对象上的内存访问更有可能确实导致访问冲突。这很可能使问题更容易预测,这有助于您追踪其根本原因。