我在我的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