我在我的delphi 2009應用程序中有一個有趣的問題。當在調試器中運行時,我在子例程的Begin關鍵字和第一個語句之間得到一個AV。我相信那是在設置局部變量的時候。這裏是調試器中顯示的信息:有趣的堆棧問題?
uDeviceModule.pas.940: begin // _GetMeasurementsForChannel
00AF24C8 55 push ebp
00AF24C9 8BEC mov ebp,esp
00AF24CB 51 push ecx
00AF24CC B9E9A90100 mov ecx,$0001a9e9 // isn't this a lot for the stack?
// error happens in here
00AF24D1 6A00 push $00
00AF24D3 6A00 push $00
00AF24D5 49 dec ecx
00AF24D6 75F9 jnz $00af24d1
00AF24D8 874DFC xchg [ebp-$04],ecx
00AF24DB 53 push ebx
00AF24DC 894DF4 mov [ebp-$0c],ecx
00AF24DF 8955FC mov [ebp-$04],edx
00AF24E2 8945F8 mov [ebp-$08],eax
00AF24E5 33C0 xor eax,eax
00AF24E7 55 push ebp
00AF24E8 687D2FAF00 push $00af2f7d
00AF24ED 64FF30 push dword ptr fs:[eax]
00AF24F0 648920 mov fs:[eax],esp
uDeviceModule.pas.941: SelectChannel(eChannelNum); // first statement
這是這個嵌套子例程的簡化版本(見下文)。
procedure TDeviceModule.GetMeasurements(ExpInfo:TExpInfo;
_DisplayList:TMeasDisplayListAncestor; eExposureStatus:TExposureStatus;
bActiveErrorEnabled:boolean);
procedure _GetMeasurementsForChannel(_DisplayList:TObjectList;
eChannelNum:TDeviceChannelNum; eExposureStatus:TMyEnum;
bActiveErrorEnabled:boolean);
var
// these are all objects (not records)
selChannel:TDeviceChannel;
det:TDeviceDetector;
shoKVMeas:TStoMeasurement;
begin // ********************* error happens on this line
SelectChannel(eChannelNum);
_GetMeasurement(ExpInfo, _DisplayList, eChannelNum, eExposureStatus, ctdVal1);
_GetMeasurement(ExpInfo, _DisplayList, eChannelNum, eExposureStatus, ctdVal2);
_GetMeasurement(ExpInfo, _DisplayList, eChannelNum, eExposureStatus, ctdVal3);
end; // _GetMeasurementsForChannel
begin
// blah blah blah
_GetMeasurementsForChannel(_DisplayList,
eChannelNum,
eExposureStatus,
bActiveErrorEnabled);
// blah blah blah
end;
它是一個單線程的應用程序。
你會如何建議我去找出這個問題的原因?我的第一個想法是:
1)增加最大堆棧大小 - 我做了但沒有改變任何東西。現在它是$ 160000(1441792),但在此之前我認爲它是$ 150000。 2)這個對象仍然有效嗎?似乎是......它正確響應ClassName方法& FastMM不會警告我任何問題。
有趣的是,堆棧跟蹤沒有提到導致問題的例程。
:7e42b35c USER32.MoveWindow + 0xbe
:7e4565b7 USER32.GetRawInputDeviceInfoW + 0x5f
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
ActnMenus.CallWindowHook(???,0,$31104)
:7e42b372 USER32.MoveWindow + 0xd4
:7e4565b7 USER32.GetRawInputDeviceInfoW + 0x5f
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:007b882d aqDockingWndProcHook + $1D
:7e42b372 USER32.MoveWindow + 0xd4
:7e4565b7 USER32.GetRawInputDeviceInfoW + 0x5f
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:7e428dd9 USER32.DefWindowProcW + 0xb9
:7e428d77 USER32.DefWindowProcW + 0x57
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e42a013 USER32.IsWindowUnicode + 0xa1
:7e42a039 USER32.CallWindowProcW + 0x1b
Controls.TWinControl.DefaultHandler(???)
:0050fac8 TWinControl.DefaultHandler + $DC
:0050b4b9 TControl.WndProc + $2D5
:0050f9cc TWinControl.WndProc + $518
:0050f0e3 TWinControl.MainWndProc + $2F
:0048874e StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e428ea0 ; C:\WINDOWS\system32\USER32.dll
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:7e428dd9 USER32.DefWindowProcW + 0xb9
:7e428d77 USER32.DefWindowProcW + 0x57
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e42a013 USER32.IsWindowUnicode + 0xa1
:7e42a039 USER32.CallWindowProcW + 0x1b
:0050fac8 TWinControl.DefaultHandler + $DC
:0050f9cc TWinControl.WndProc + $518
:0050f0e3 TWinControl.MainWndProc + $2F
:0048874e StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e428ea0 ; C:\WINDOWS\system32\USER32.dll
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:7e428dd9 USER32.DefWindowProcW + 0xb9
:7e428d77 USER32.DefWindowProcW + 0x57
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e42a013 USER32.IsWindowUnicode + 0xa1
:7e42a039 USER32.CallWindowProcW + 0x1b
:0050fac8 TWinControl.DefaultHandler + $DC
:0050f9cc TWinControl.WndProc + $518
:0050f0e3 TWinControl.MainWndProc + $2F
:0048874e StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e428ea0 ; C:\WINDOWS\system32\USER32.dll
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:7e428dd9 USER32.DefWindowProcW + 0xb9
:7e428d77 USER32.DefWindowProcW + 0x57
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e42a013 USER32.IsWindowUnicode + 0xa1
:7e42a039 USER32.CallWindowProcW + 0x1b
:0050fac8 TWinControl.DefaultHandler + $DC
:0050f9cc TWinControl.WndProc + $518
:0065279d TcxControl.WndProc + $121
:0070b38d TcxCustomGrid.WndProc + $5
:0048874e StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e428ea0 ; C:\WINDOWS\system32\USER32.dll
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:7e428dd9 USER32.DefWindowProcW + 0xb9
:7e428d77 USER32.DefWindowProcW + 0x57
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e42a013 USER32.IsWindowUnicode + 0xa1
:7e42a039 USER32.CallWindowProcW + 0x1b
:0050fac8 TWinControl.DefaultHandler + $DC
:0050f9cc TWinControl.WndProc + $518
:0065279d TcxControl.WndProc + $121
:0075bbc4 TcxGridSite.WndProc + $20
:0048874e StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e428ea0 ; C:\WINDOWS\system32\USER32.dll
:7e428eec ; C:\WINDOWS\system32\USER32.dll
:7c90e473 ntdll.KiUserCallbackDispatcher + 0x13
:0044c91e HandleException + $22A
:004539af InterceptAHandleExcept + $3F
:0048874e StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e4189cd ; C:\WINDOWS\system32\USER32.dll
:7e418a10 USER32.DispatchMessageW + 0xf
這表明問題是堆棧溢出的某種 - 消息處理使用的東西。
建議???謝謝!
是否有任何類的構造函數的任何對象? – code4life 2010-06-21 03:15:14
什麼是TDeviceChannel,TDeviceDetector,TStoMeasurement,TDeviceChannelNum,TMyEnum?即:他們是什麼SizeOf? – Alex 2010-06-21 07:35:34
>是否有任何類的構造函數的任何對象? 這個對象是在調用這個例程之前在別處構造的,我們(未示出)檢索這些對象。 @Alexander:所有這些的大小是4(TDeviceChannel,TDeviceDetector和TStoMeasurement都是對象,因此它們的SizeOf將是指針(4)的SizeOf)。 – 2010-06-21 17:26:19