Link to home
Start Free TrialLog in
Avatar of steve-west
steve-west

asked on

AccessViolation when moving focus from the application

An application, as part of it's running process creates several threads. Whilst these threads are active the user can alt-tab away from the application or move focus by any means without any problem.

As soon as these threads terminate, any attempt to move focus away (click on taskbar etc) and an Access Violation is raised at address 000000000, read of address 000000000.

If you don't click away, the application is fine. You can start the process that creates the threads again, and all is well.

Can anyone suggest what could be causing this behaviour - remove focus and the applicatin crashes? (there's no special behaviour within the app to react to change of focus)

Thanks

Steve

Avatar of developmentguru
developmentguru
Flag of United States of America image

 I would guess that your threads are updating your display and the error is happening there.  I have seen issues in attempting to update the display when it does not have focus (usually with windows wrappered controls).  You can run a simple test.  Comment out any code that tries to update the display within your threads and see if you are able to reproduce the access violation.  If not then you would look into which thread's update was causing the issue.  I know that it is not uncommon for controls to create a component (or handle) when they have focus and destroy it when they do not have focus.  Trying to access this at the time it has been freed would cause the same error.  I would suspect updating of a grid as a possible culprit.

Let me know how it goes.
Avatar of steve-west
steve-west

ASKER

This is what I thought, but there is absolutely no link/reference to the user interface from the threads. The threads are purely non visual. There isn't even any requirement for a synchronize method.

Besides, at the time of the crash, no threads are running. The user only comes across the problem if they try to move to another application. I've narrowed the problem down to only happening when NO threads are running AFTER threads have been running.

Run Application - no threads, fine to move focus
Create threads, threads terminate, create threads - fine to move focus.
Create threads, threads terminate, notmore threads created - Crash when moving focus.

I just cannot debug it. The IDE stops on the application.run. The stack is next to useless, being full of "StdWndProc +$16". Before these is a reference to "USER32.GetDC + 0x6d". The act of swistching back to delphi to put breakpoints, results in crashes...

Don't know what else to try.

Steve
Avatar of ThievingSix
What exactly are the threads meant to do? What, if any, WinAPI are used?
So there's no onDeactive or no onHide (etc) event handlers for your forms? I think it would be good to rule out any suspicious event handlers.
 I had to debug an application years ago that had random "Runtim error 216" or "Access Violation" messages when closing.  I was able to determine that the problem was not in my code since I was able to debug down to the point where all Delphi code had been executed and it handed the execution back to Windows.  At that point I started doing Binary Deconstruction on the program.  Remove half of the forms, make the program compile doing what ever you have to, test it again.  If you can still cause the error then the cause is in the remaining forms.  I got it down to the point that only the main form was left.  I started removing half the components at a time and testing.  I got it down to the point where I found out that if I removed a TImageList component that the error would never happen.  I then restored the entire project and removed the TImageList and got the same results.  I then looked at the images.  One of them was over 64k.  I found out that it was a bug in Windows that was triggered by the way my application used the TImage List.

  I said all of that to point out that you do still have debugging options even if something like EurekaLog will not work for you.  The error may not be anywhere in your code, but that does not mean you can't find the cause.  

Good luck.
ThievingSix: :>> The threads are servicing database requests via a socket. One request (commnd per thread). They aren't doing a  great deal - opening a socket, writinga  command, reading from socket and closing.

rfwoolf: : I wish it were that obvious :).

It seems that if I don't dispose the socket when the thread terminates, the focus problem doesn't arise. Obviously, I must dispose the socket, but I don't understand how this can cause the problems it has.

The Socket is derived from Overbyte's ICS WSocket. If I call the inherited destroy from the derived class the application crashes? Following the code through, it's not doing anything abnormal that I can see.
I've had problems with TImageList as well when adding images of more than x X 300 pixels, maybe it's a delphi bug? the imagelist component in visualstudio doesn't have this problem

https://www.experts-exchange.com/questions/23222123/D2007-ImageList-crashes-the-IDE.html
steve-west, can you make a small app which demonstrates this problem?

Alternatively, you might want to install (the trial of) Eurekalog (www.eurekalog.com) or madexcept (http://www.madshi.net/madExceptDescription.htm). This might give you more details on where the access violation happens precisely.
Place a breakpoint in the destructor of the socket.  I think you will find that it is disposed of before you attempt to dispose of it.  This generates the access violation when you try to dispose of it the second time.  Once you find out where the it is first disposed of, you can decide how to properly handle it.
MerijnB: Thanks, I'll take a look at Eurekalog - I'll use anything which could give more to go on.
Regarding the sample application, I ddi try to create one but the application itself is so tied into our database, in particular, its technology (m21/MUMPS) that it's not possible.

developmentguru: The destructors only getting called once, definitely.This is one of the first things I checked - if I don't dispose the socket, the problems don't happen, but the destructor is only getting called the once - where I free it.
 But something even stranger is happening.
Our  socket compoent inherits from the ICS socket component. If I comment out the call to the inherited destructor, then the crashes never happen. If i reinstate the inherited destructor  - BUT - in the inherited destructor comment out all code (i.e. it now does absolutely nothing) the crashes resume.

How can this be????

Surely not calling the inherited destructor compared to calling the inherited destructor which contains no code amounts to the same thing? I even placed breakpoints on every method in my socket component and also the ICS componen to see if perhaps any methods were being called between calling the inherited destructor and actually entering the destructor itself. But none were called  - which was what I thought would happen.
@bryan7
I know the error I ran into is a windows error.  It is possible that the component used in Visual Studio is not using the windows API, but does it's own (leaving the bug for non-MS environments to find).

@steve-west
I have run into this kind of error in the past.  It normall involves a memory overwrite.  This kind of bug can be VERY hard to find.  Given the nature of what you have said thus far I would try the following:

Try a simple test where you create the socket component and destroy it normally.  I suspect that this will not cause any issues.

If it does cause the error then it is something about the component itself.

If it does not then you will need to watch for memory overwrites.  I would suspect an overwrite of a small portion of the VMT.  This would explain why calling the method causes the error even when there is no code in it.  The mehtod it is pointing to is invalid.

The only other possibility that I can think of is that the object has either been destroyed, or it's pointer has been overwritten with invalid data.  Stop the debugger on the line where the component is created (or OnCreate of the form) and make a note of the Pointer(MyComponent).  Then when you stop on the destructor see if the same Pointer(MyComponent) is different.  If it is then something has overwritten it.  You can set a data breakpoint to find out where it is overwritten.

Let me know how it goes.
eurekalog will probably shed light.

If you still can't find the problem, I really suggest you trim the app down until you have only the problem part. This works almost every time.
developmentguru: actually the bug is in the delphi ide itself, even saving the form causes the freeze. I've reported it to to QC
developmentguru:

Sorry, I've been away from the project and company for sometime. Now I've access to the project again, I'll try what you suggest regarding inspecting the pointer oncreate and onddestroy. The VMT overwrite does make sense.

Thanks

Steve.
This behaviour is definitely called by calling the bottom most i.e. TControl's destructor. If I call all destructors apart from this one, the application is fine.

I think it's to do with a hidden window  (which the ICS socket component creates and the peeking/dispatching of windows messages) but for the life of me I cannot pin it down

With an error this complicated I would likely need access to the full source to pin it down.  One other attack vector that has helped me in the past is to create a simple project that just strips out the same basic componnents and code that handle the subset of the program involved with the error.  If this project does not generate the same error then you know it has something to do with the main project.  Knowing this can be both encouraging and discouraging.  But, like I said, without the source I am not sure there is much more I can do.  Let me know if you have more specific questions.
developmentguru

Thanks for your help and offer to further assist, but the application is huge (1million+lines), so stripping out the relevant code would be daunting - I realise you're limited in what you can suggest without access to the full source code.

I've circumvented the problem by not calling the final inherited - I know this sucks, but I had to get the application out. ComponentCount was ZERO prior to calling the final inherited (well final before it went down into TComponent) and looking at the VCL source I couldn't see that it would do too much damage.

The application behaves ok now, processing roughly 1million RTF to HTML conversions daily

Thanks for you help.
ASKER CERTIFIED SOLUTION
Avatar of Computer101
Computer101
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial