Trying to hunt down a weird access violation, and wondering if anyone has seen anything similar.

Trying to hunt down a weird access violation, and wondering if anyone has seen anything similar.

I have a MDI child form which uses DevExpress components, including the layout stuff. In the OnCreate of the form the first line creates a datamodule which contains some ClientDataSets and dbx query components and nothing else.

This works fine on my machine (win8.1), on my laptop (win7) and on our internal terminal server (win2008r2)... However it consistently crashes with an AV on the target terminal server, which is also running win2008r2. According to the debugger the AV happens deep inside the DX layout code, and it occurs while the datamodule is being streamed (thus before the datamodule's OnCreate).

I haven't had time to chase further down the rabbit hole yet (deadline looming) but I did find a workaround: call Application.ProcessMessages inthe form's OnCreate, before the datamodule ia created...

I wonder if anyone experienced anything similar? What puzzles me is why the layout stuff is being called as the datamodule doesn't have anything to do with that, and why just on this machine.

Using XE6 with all updates.

Comments

  1. Pretty often the reason for such an behaviour is a component event that references something before it was created.
    One possible workaround is to bind your events after everything is created.
    Codesite is nice to instrument your methods and see which one was called before the crash happened.

    ReplyDelete
  2. Roland Kossow​ Thanks, the call stack doesn't show any of my event handlers but then I don't trust it fully. I'll try hooking things up manually.

    edit: apart from the form's OnCreate that is.

    ReplyDelete
  3. Thought 1: Have you checked whether midas.dll is fully installed/registered/up to date on the target server?  Thought 2: As Roland implies, this smells of some sort of reference that isn't quite valid at the time it's being called on.  If you use or have global datamodule references (ones referenced by components somewhere else in particular), you could try replacing/wrapping these global references with functions that returns these globals but that additionally check that the reference itself is assigned before returning them, and then raise an exception otherwise.  This should give you a clearer indication of what's trying to read what when it's not ready yet.

    ReplyDelete
  4. Walter Prins I'll verify tomorrow but I shouldn't have any global references to the datamodule nor any direct references from the form. The datasources are on the form and linked in the form's OnCreate, after the datamodule is created of course.

    As far as I know we're using the midaslib unit, so no dll, but just to be sure I'll check that too.

    Cheers for the input.

    ReplyDelete
  5. Walter Prins​ Asbjørn Heid​ My first thought was also midas.dll but I ruled that out because of your mentioning of a workaround.

    ReplyDelete
  6. Do you enable "Use Debug DCUs"?
    Just a question.. 
    Stack trace then will show you much more (especially in such cases).

    ReplyDelete
  7. Zigmund Bulinsh Yeah have 'em enabled, unfortunately remote debugging only seems to show the last 3-4 calls.

    I'm also using Jcl's stack trace thingy, and it shows a lot more. But still couldn't seem to figure out what triggers the layout components to do their layout-changing-procedure. I'll have to take another look at them tomorrow.

    ReplyDelete
  8. the clue will be that application.processmessges helps
    i.e so it sounds like something has not initiated before it needs to be yet...maybe there are some force update ore refresh functions you can call before that item is used or similar ? (i.e I like Roland's idea of what is wrong too)

    ReplyDelete
  9. Brian Hamilton Sounds like it, I just can't imagine what. I'll also try to re-use the datamodule on a different form, just to see if it's this or that.

    ReplyDelete
  10. Remark the data module creation and inject for loop for a certain long time there. Would it be crashed?

    Any DX components as the members of that form? It's about class members/fields initializing.


    ReplyDelete
  11. Sam Shaw You mean inherit the Create?

    Not sure what you mean w.r.t. DX components. They're part of the form, the datamodule has database components only, no DX stuff there.

    ReplyDelete
  12. Asbjørn Heid Any dataaware components in the MDI form? Those could cause the problem because their internal functions might reference something also before it was created. Try to hook them up by code after the creation of your datamodel.

    ReplyDelete
  13. well, so can you remove/remark the 1st line in form oncreate , ie, creating data module. Then write a for loop, for example, 0 to 1000000, there.

    I'd like to know is it really related data module
    or just a timing issue.



    ReplyDelete
  14. Sam Shaw It's related somehow, though I don't know if it's just "a" datamodule or that specific one. I removed all references to the datamodule and then it worked.

     Roland Kossow The datasources are on the form and are hooked up to the datasets on the datamodule after I create the datamodule. And the crash happens before the datamodule is properly created so...

    I did this anyway because I'm bloody tired of all those property editors always wanting a live connection to the db server while I'm designing, which doesn't work in our project (needs extra setup).

    ReplyDelete
  15. Do something like ...

    "while not Assigned(Datamodule) do nothing special;"

    in front of the code that hooks up the datasets, perhabs that solves the problem.

    I am starting to have no clue anymore.

    ReplyDelete
  16. It crashes before the datamodule constructor even returns... but I can try something like that before I create the datamodule.

    Thanks guys, I'll try your suggestions tomorrow and see.

    ReplyDelete
  17. but if you try something like "while not Assigned(datamodule)" before you create the datamodule you are in deep shit ;-)
    however ... good luck tomorrow.

    ReplyDelete
  18. IMHO, I don't think it's related to datamoudle, because you said "call Application.ProcessMessages in the form's OnCreate, before the datamodule is created" problem solved.

    What does it imply ?  If something were done before you creating datamodule, no crashed happened. What is the effect of calling Application.ProcessMessage?

    1. it delays some time and let some functions finished (perphaps on the other thread)
    2. it processes some messages.
    3. involved 1 and 2.

    Until now, it doesn't matter with the datamodule creation.  Just something need to be done, then later procedures will run well. 

    Now think about why your app runs well in many PCs without ProcessMessage?  It means datamodule and its cross references and are all correct. And drivers in terminal target which run fail are correct ones, since you just need to add Application.ProcessMessage.  I think ProcessMessage is nothing to do with drivers.

    So the key point is something have to be done and something aren't related to datamodule, because when Application.ProcessMessage called, the datamodule hasn't created yet!  That is, if the something are related to datamodule, it should crash immediately in ProcessMessage.

    Well, let's come back to the effect of ProcessMessage.  I said there might be 3 affects.  However, again, why the app runs on many PCs well and not rely on it?  So I guess it's the reason #1.

    What should be done before Application.ProcessMessage or before entering oncreate procedure?  It's the Fields(you may called that instance variables, data members in c++) in the form should be created/initialization.  Since you said some DX components are part of the form, so they will create before oncreate.  When those components are initializing, what are they doing?.... I don't know.

    All in all, think about 1. runs well in many PCs without ProcessMessage. 2. ProcessMessage is before datamodule creation. 3. What's the effect of ProccessMessage cause issue solved.   If my deduction is correct.  It should not the datamodule, any instance inside datamodule and any cross references problem.

    ReplyDelete
  19. After I think it more,  I think I have to amend my deduction.  There's a possibility. Let's say, 

    If DX components or some components related to it refer to datamodule reference and when they are initializing, and the datamoule is nil, no AV occurred.  If components initialization is too slow and datamoudule is under init, then it may crash, since reference is not nil but its instance variables are not created completely.  

    So If we give components some time to finish initialization while datamodule is nil, AV may not occurred.  But this is still the timing issue.

    ReplyDelete
  20. maybe put the code that is in the formcreate into a ttimer instead (that fires only once)

    ReplyDelete

Post a Comment