Startup error during main form creation

1

Delphi XE5/32, on Windows10/64, generating Win32 VCL executable.

I am getting intermittent Access Violation errors that are associated with form creation. This error has also been seen, rarely, by some end-users (I'm currently in small-scale trials, with a test group of about 20 users).

This has been going on for months and until recently my attempts to find the problem were frustrated by the fact that it was so hard to reproduce. However, I have now finally been able to establish an environment that reproduces the error quite reliably. Bizzarely, I have discovered it is triggered by certain emails being displayed in my GMail account, in Chrome browser. The emails that cause the problem are completely consistent - see the video in https://www.devexpress.com/Support/Center/Question/Details/T395896. (I initially posted this query to the DevExpress support forum because I suspected one of their components was the cause, however now I doubt this).

I have now disabled my splash screen temporarily, and changed my previous auto-create datamodules to be created in the main form's OnCreate. The DPR is now, very simply:

begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := 'Topshare V3';
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.

That is, nothing happens prior to the CreateForm for the program's main form.

When the error is happening, the program either hangs silently during Application.CreateForm(TMainForm, MainForm), and before the main form's OnCreate is invoked; or it terminates before OnCreate, and invokes the form's OnDestroy. So the problem is occurring during the parsing of the DFM.

If I step the program in debug mode within the IDE when the error is active, there are several AVs raised during Application.CreateForm(TMainForm, MainForm). These are only apparent from the IDE so are, presumably, within try..except blocks. If I click Break on the first of these, the Call Stack is usually something like:

System.SysGetMem(???)
:00405423 SysGetMem + $43
System.Classes.TReader.ReadComponent(nil)
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($7BCCD90)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
:00aa0bcd TcxCustomGrid.ReadState + $29
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($7BF4230)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
System.Classes.TReader.ReadComponent(nil)
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($7BF3F50)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
System.Classes.TReader.ReadComponent(nil)
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($9B9C7A0)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
Vcl.Forms.TCustomForm.ReadState($9C6F098)
System.Classes.TReader.ReadRootComponent($9B9C7A0)
System.Classes.TStream.ReadComponent($9B9C7A0)
System.Classes.InternalReadComponentRes(???,???,$9B9C7A0)
System.Classes.InitComponent(TMainForm)
System.Classes.InitInheritedComponent($9B9C7A0,TForm)
Vcl.Forms.TCustomForm.Create(???)
Vcl.Forms.TApplication.CreateForm(???,(no value))
TopshareV3.TopshareV3

The apparent involvement of SysGetMem lead me to this Question: Delphi XE5 Acces Violation on app start

Accordingly I have enabled both Range Checking and Overflow Checking, but this does not help.

There must be something wrong with the DFM.

One aspect is that the main form inherits from an ancestor form type. The ancestor form has no components, just some methods. The ancestor form's source code does not include the default global variable declaration. So, the main form's form declaration is: TMainForm = class(TABase)

and the DFM contains: inherited MainForm: TMainForm

The form contains several nested frames, and also uses several ActionManagers, ActionToolbars, an ActionMainMenubar, a PopupActionbar, and a dxSkinController.

Can anyone shed any further light on what to look for, or how to proceed further??

EDIT: The call stack shown above is After the first AV. But I have already done the tracing you suggest. I put a breakpoint in System.Classes at line #10169, in TReader.ReadComponent. I then add watches on "Parent.name" and "CompName". Then, starting again in the IDE, I see the various main form components being created.

Previously, when the datamodules were being created first, I would see a number of components created, but the AV would always happen after hitting the breakpoint with watches showing the first View of the first cxGrid (DevExpress). If I added an extra grid to the form (and on the first panel to be created), without any properties being set, then the new grid would appear to trigger the AV. In other words, it seemed like the cxGrid was the problem - hence my contact with DevExpress support.

But postponing the creation of the datamodules, and eliminating my splash screen, has changed things (although the AV is still occurring). Now, it progresses well beyond the first grid; and, although a cxGrid still seems to be involved, I'm not sure that's relevant now (I have a lot of grids on the main form).

EDIT: Running in the IDE, there are 3 AVs (if I click Continue after each) - then the program hangs before my code in OnCreate executes: the first is $C0000005 with message 'access violation at 0x0040541d: read of address 0x002d001c'; and, twice, $C0000005 with message 'access violation at 0x00a8107a: read of address 0x00000068'.

EDIT: My initial breakpoint at Classes # 10169 now executes a few dozen times as the form components from the DFM are processed. On the now-critical component (still a cxGrid view), execution steps from Classes #10169 (in Treader.ReadComponent), to CreateComponent #10114, to Result.create #10129. From here there is a loop (or recursion) that includes an assembler block beginning at System #16752, and empty Tobject.Create at #15511. A breakpoint at System #15511 executes 29 times. Then, the 30th time through, the AV occurs at System #16757, CALL DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance

EDIT: When stepping through execution when there's no error condition, things seem essentially the same as when there is: that is, the same sequence of calls. The same sequence described in the para above seems to be followed - except for no AV on the 30th pass or subsequently.

delphi
startup
delphi-xe5
asked on Stack Overflow Jun 25, 2016 by Chris J • edited May 23, 2017 by Community

1 Answer

1

I have narrowed the problem down to DevExpress's dxSpreadSheetCore unit. If I include that in any Uses clause, the error is displayed; if I omit it, no error. I have submitted the problem to DevExpress, although I was not able to simplify my application enough to also give them a useful demonstration of the error.

My assumption, based on comments here, is that something in the initialization section of dxSpreadSheetCore (or in its dependant units) is causing heap corruption.

answered on Stack Overflow Jun 29, 2016 by Chris J

User contributions licensed under CC BY-SA 3.0