Exception results from bug in destructor TacCustomShellChangeNotifier.Destroy

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #32911
    HeDiBo
    Participant

    In destructor TacCustomShellChangeNotifier.Destroy in module acShellCtrls the thread is used after freeing:

    Code:
    destructor TacCustomShellChangeNotifier.Destroy;
    var
    Temp: TacShellChangeThread;
    begin
    if Assigned(FThread) then begin
    OnChange := nil;
    Temp := FThread;
    FThread := nil;
    Temp.Free; // .Terminate; <<--- Freed
    ReleaseMutex(Temp.FMutex); <<--- but used
    end;
    inherited;
    end;

    After changing it back to Temp.Terminate I get memory leaks. So I added Temp.Free after ReleaseMutex. That seemed to work. But later on I got exceptions again upon closing the program. I'm at loss here.

    Finally I changed the code to this:

    Code:
    destructor TacCustomShellChangeNotifier.Destroy;
    var
    Temp: TacShellChangeThread;
    begin
    if Assigned(FThread) then begin
    OnChange := nil;
    Temp := FThread;
    FThread := nil;
    ReleaseMutex(Temp.FMutex);
    Temp.Destroy; // I.s.o. Free!!
    end;
    inherited;
    end;

    That seemed to do the trick, it became better. But after a number of trial runs, I still got an access violation.

    #57336
    HeDiBo
    Participant

    My program needs to use the TsShellListView two times in a row. When using it once, many times it goes OK.

    But using it twice, results in a bug, so profound that it terminates the Delphi IDE itself ph34r.gif

    As soon as the second TsShellListView should appear (there is a user reaction before that, so you would expect threads to have terminated) Delphi throws this exception:

    [attachment=8541:system exception.jpg]

    Upon clicking Break, the debugger goes throws mayhem:

    [attachment=8542:system exception2.jpg]

    the exception occurs in this part of procedure TacShellChangeThread.Execute;

    Code:

    EnterCriticalSection(CS);
    if FWaitChanged then begin
    FindCloseChangeNotification(FWaitHandle); <<<=== point of exception
    FWaitHandle := ERROR_INVALID_HANDLE; <<<=== upon exception this is the point of execution
    FWaitHandle := FindFirstChangeNotification(PChar(FDirectory), LongBool(FWatchSubTree), FNotifyOptionFlags);
    FWaitChanged := false;
    end;
    LeaveCriticalSection(CS);

    Because the debugger got an exception, I don't know if this call stack is still valid:

    [attachment=8543:system exception3.jpg]

    The destructor TacCustomShellChangeNotifier.Destroy is still your version.

    I tried to change the order of Free and ReleaseMutex, and that seemed to do the trick. But it worked only once. On the second run I got the same problem.

    Please, help. I'm really stuck now. sad.gif

    #57337
    HeDiBo
    Participant

    I may have some indication where things go wrong.

    The first path that I select is a Google Drive directory.

    If I choose a normal directory, it seems to go OK.

    However this use of the Google Drive (or DropBox or MyDrive) is essential for my application to allow users to share the database.

    So this really must be solved umnik.gif.

    #57347
    Support
    Keymaster

    Can you replace the TsShellListView by the standard TShellListView component and check him for this issue?

    If issue will not occurs then I can compare the code of these two components, maybe I will have some ideas.

    #57348
    HeDiBo
    Participant
    'Support' wrote:

    Can you replace the TsShellListView by the standard TShellListView component and check him for this issue?

    If issue will not occurs then I can compare the code of these two components, maybe I will have some ideas.

    When I did that, I got an error in this procedure:

    Code:

    procedure TfrmSelPathAC.SetCurPath(const Value: String);
    begin
    FCurPath := Value;
    sShellTreeView1.Path := Value;
    if ( not (csDestroying in sShellTreeView1.ComponentState) ) and
    ( sShellTreeView1.SelectedFolder <> nil )
    then sShellListView1.SetPathFromID(sShellTreeView1.SelectedFolder.AbsoluteID); <<== SetPathFromID is unknown

    So I changed it to

    Code:
    then sShellListView1.Root := sShellTreeView1.SelectedFolder.PathName;

    which resolved the problems laugh.gif

    Maybe you should have a look at SetPathFromID in TsShellListView.

    #57349
    HeDiBo
    Participant

    It's still not OK.

    I'm trying to find further cause.

    #57350
    HeDiBo
    Participant
    'Support' wrote:

    Can you replace the TsShellListView by the standard TShellListView component and check him for this issue?

    If issue will not occurs then I can compare the code of these two components, maybe I will have some ideas.

    Replacing it with the standard components showed no problems anymore, except for a number of leaked memory areas, which were expected because in this case the thread is only terminated but not freed.

    #57352
    HeDiBo
    Participant

    I produced a test project, that will show you the exception.

    The main form allows for three ways to view the shelltreeview and shelllistview.

    If you use the standard controls (Select Path Std.) and press Select then terminate the program, you will find the Memory Leaks,

    If you use the DevEx version and press Select and then terminate the program, all goes well.

    If you use the AC version all kind of things may happen. It may break before showing anything in TacShellChangeThread.Execute as described above, it may break with an exception in the standard _Halt0 procedure or it may occasionally work.

    All three screens have an Exit button. This let's the main program terminate immediately (that will show a bug in the AC version also).

    At the moment I'm unable to run the AC version. It will always break with an exception in TacShellChangeThread.Execute. But sometimes I have it running!

    To get the AC bug when the path and list do show, choose a folder and press Select, choose another folder and press Select, etc. until it fails.

    I tried the program outside the Delphi environment and could not get it to break. So it is a timing problem that will occur on slower machines (the Delphi debugger takes a long time handling threads).

    [attachment=8546:acShellBug.zip]

    #57354
    HeDiBo
    Participant

    I have another important observation: if the TsShellTreeView has property Root set to rfMyComputer there's no problem.

    I still suspect the Google Drive at the top of the tree (Root set to rfDeskTop) to be the culprit.

    #57358
    Support
    Keymaster

    Hello and thank you for the good demo.

    I can repeat the issue, seems. I hope to fix it soon.

    #57359
    HeDiBo
    Participant
    'Support' wrote:

    Try the attached file, please.

    WOW a7.gif

    Must have been a heavy task, considering the number of changes w.r.t. the previous version. And for AC it does seem to work a3.gif.

    Unfortunately, now I get a problem with the standard TShellTreeView:

    Code:
    First chance exception at $73EACBB2.
    Exception class EThread with message 'Cannot terminate an externally created thread'.
    Process acShellBug.exe (13536)

    This problem occurs if you do a couple of different directory clicks in the standard shell tree view. The only thing that may tie this to AC is the fact that the shell controls are placed on sPanels (the stack list contains the message processor in TsPanel).

    However, I changed the TsPanels to standard TPanels and the same problem occurred.

    #57361
    HeDiBo
    Participant
    'Support' wrote:

    Here is a new changed file with delayed destruction of threads.

    Maybe something went wrong. This is the same file as before.

    Also, the problem did not occur in the AC version, it occurred in the standard version!

    Thanks!!

    #57360
    HeDiBo
    Participant

    Today I retried the standard TShellTreeView and the message 'Cannot terminate an externally created thread' did not occur anymore. I suspect all my testing yesterday left the shell in some mess. So for the time, consider this bug closed a7.gif

    #57412
    HeDiBo
    Participant
    'HeDiBo' wrote:
    So for the time, consider this bug closed a7.gif

    Problem is indeed solved in 12.22 a3.gif

Viewing 14 posts - 1 through 14 (of 14 total)
  • You must be logged in to reply to this topic.