Interesting stack overflow! compiler error?

I wonder if I found a compiler error? I removed some old code from my application and now I get stackoverflow in "begin" (see code and disassembly below).

procedure TfraNewRTMDisplay.ShowMeasurement; var iDummy, iDummy2, iDummy3:integer; begin // Qaru BEFORE MY CODE STARTS iDummy:=0; iDummy2:=0; case iDummy2 of 1: case iDummy of 1:m_SelectedRTMMenuData.ChannelMeasSet.MeasKV.ClearMeasurementData; 2:m_SelectedRTMMenuData.ChannelMeasSet.MeasKV.ClearMeasurementData; end; end; end; NewRTMDisplay.pas.1601: begin 00983BF8 55 push ebp 00983BF9 8BEC mov ebp,esp 00983BFB B9D4E40400 mov ecx,$0004e4d4 00983C00 6A00 push $00 // Qaru loop 00983C02 6A00 push $00 // Qaru loop 00983C04 49 dec ecx // Qaru loop 00983C05 75F9 jnz $00983c00 // Qaru loop 00983C07 56 push esi 00983C08 57 push edi 00983C09 8945FC mov [ebp-$04],eax 00983C0C 8D856005FFFF lea eax,[ebp-$0000faa0] 00983C12 8B153C789A00 mov edx,[$009a783c] 00983C18 E88B35A8FF call @InitializeRecord 00983C1D 8D85D00AFEFF lea eax,[ebp-$0001f530] 00983C23 8B153C789A00 mov edx,[$009a783c] 00983C29 E87A35A8FF call @InitializeRecord 00983C2E 33C0 xor eax,eax 00983C30 55 push ebp 00983C31 68F73C9800 push $00983cf7 00983C36 64FF30 push dword ptr fs:[eax] 00983C39 648920 mov fs:[eax],esp NewRTMDisplay.pas.1602: iDummy:=0; 00983C3C 33C0 xor eax,eax 00983C3E 8945F8 mov [ebp-$08],eax NewRTMDisplay.pas.1603: iDummy2:=0; 00983C41 33C0 xor eax,eax 00983C43 8945F4 mov [ebp-$0c],eax NewRTMDisplay.pas.1605: case iDummy2 of 00983C46 8B45F4 mov eax,[ebp-$0c] 00983C49 48 dec eax 00983C4A 7571 jnz $00983cbd NewRTMDisplay.pas.1607: case iDummy of 00983C4C 8B45F8 mov eax,[ebp-$08] 00983C4F 48 dec eax 00983C50 7405 jz $00983c57 00983C52 48 dec eax 00983C53 7436 jz $00983c8b 00983C55 EB66 jmp $00983cbd NewRTMDisplay.pas.1608: 1:m_SelectedRTMMenuData.ChannelMeasSet.MeasKV.ClearMeasurementData; 00983C57 8D951872EBFF lea edx,[ebp-$00148de8] 00983C5D 8B45FC mov eax,[ebp-$04] 00983C60 8B80F0020000 mov eax,[eax+$000002f0] 00983C66 E895DBE9FF call TRTMMenuData.ChannelMeasSet 00983C6B 8DB52072EBFF lea esi,[ebp-$00148de0] 00983C71 8DBD6005FFFF lea edi,[ebp-$0000faa0] 00983C77 B9A43E0000 mov ecx,$00003ea4 00983C7C F3A5 rep movsd 00983C7E 8D856005FFFF lea eax,[ebp-$0000faa0] 00983C84 E81B3F0200 call TDeviceMeas.ClearMeasurementData 00983C89 EB32 jmp $00983cbd NewRTMDisplay.pas.1609: 2:m_SelectedRTMMenuData.ChannelMeasSet.MeasKV.ClearMeasurementData; 00983C8B 8D9560D9D8FF lea edx,[ebp-$002726a0] 00983C91 8B45FC mov eax,[ebp-$04] 00983C94 8B80F0020000 mov eax,[eax+$000002f0] 00983C9A E861DBE9FF call TRTMMenuData.ChannelMeasSet 00983C9F 8DB568D9D8FF lea esi,[ebp-$00272698] 00983CA5 8DBDD00AFEFF lea edi,[ebp-$0001f530] 00983CAB B9A43E0000 mov ecx,$00003ea4 00983CB0 F3A5 rep movsd 00983CB2 8D85D00AFEFF lea eax,[ebp-$0001f530] 00983CB8 E8E73E0200 call TDeviceMeas.ClearMeasurementData NewRTMDisplay.pas.1612: end; 

any ideas?

Thank you! T. pl

+4
source share
5 answers

Julius is right: the 320K buffer is most likely an array [20] of what ChannelMeasSet returns, based on the size of the rep movsd loop.

It looks like you have code that returns a very large data structure by value, and not just a link to it. Besides the problem, this can be very inefficient.

+1
source

Something creating a 320 KB buffer. Do you have any of these objects in this call chain that have a statically distributed huge array inside them? Perhaps he is trying to push one of the returned objects onto the stack.

+2
source

This code is as follows:

 m_SelectedRTMMenuData.ChannelMeasSet.MeasKV.ClearMeasurementData; 

ChannelMeasSet seems to be a huge data structure that the compiler is trying to copy onto your stack for some reason. I'm not sure why the compiler will try to do this without seeing the rest of the object declaration. In addition, the compiler allocated two separate temporary storage areas on the stack, one for each line where you call it (although only one will be used at any given time).

You have at least two possible solutions:

  • Make the stack bigger. Perhaps there is a Delphi directive for this.
  • Correct your data structures so that the compiler does not want to copy huge temporary objects.
+2
source

Thank you for your suggestions! here is the call stack (from delphi 2009).

 NewRTMDisplay.TfraNewRTMDisplay.ShowMeasurement NewRTMDisplay.TfraNewRTMDisplay.DetectorSelectionChange($46552D0,drmOneAtATime) NewRTMDisplay.TfraNewRTMDisplay.pumOnDetectorSelectionChange($46129E0) Menus.TMenuItem.Click Menus.TMenu.DispatchCommand(???) Menus.TPopupList.WndProc((273, 386, 0, 0, 386, 0, 0, 0, 0, 0)) Menus.TPopupList.MainWndProc(???) Classes.StdWndProc(15403740,273,386,0) :7e418734 USER32.GetDC + 0x6d :7e418816 ; C:\WINDOWS\system32\USER32.dll :7e4189cd ; C:\WINDOWS\system32\USER32.dll :7e418a10 USER32.DispatchMessageW + 0xf Forms.TApplication.ProcessMessage(???) :0051e31c TApplication.ProcessMessage + $F8 

I am working on your comments here right now. come back in a few minutes.

Admittedly, there are several moderately large structures. I doubt that they are somewhere close to this big one, but I will be back to you soon.

0
source

stupid site; it automatically updates, destroying my answer. ChannelMeasSet is a record that surprised me at 1.2 MB!

 m_SelectedRTMMenuData a small object ChannelMeasSet a record MeasKV a record with method ClearMeasurementData( ); 

Oddly, the app just deleted a bunch of old code. I have never seen this one.

I will post this comment so that it is not destroyed before I can finish!

Thank you for your help!

0
source

All Articles