AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Delphi-PRAXiS - Lounge Delphi-News aus aller Welt EurekaLog helps not only you, but also developers of libraries that you are using
Thema durchsuchen
Ansicht
Themen-Optionen

EurekaLog helps not only you, but also developers of libraries that you are using

Ein Thema von DP News-Robot · begonnen am 5. Okt 2022
Antwort Antwort
Benutzerbild von DP News-Robot
DP News-Robot

Registriert seit: 4. Jun 2010
15.404 Beiträge
 
#1

EurekaLog helps not only you, but also developers of libraries that you are using

  Alt 5. Okt 2022, 14:00
We were contacted by a customer that claimed that his application worked fine until he added EurekaLog to it. Specifically, his application starts to raise an EAccessViolation exception in his event handler's code.

A quick look indicated that the EAccessViolation exception was thrown with the following message: "Access violation at 0x0108164d: read of address 0xdeadc30f" and the following call stack: ContosoInplaceContainer.TContosoCustomViewInfoItem .Destroy ContosoInplaceContainer.TContosoEditCellViewInfo.D estroy System.TObject.Free ContosoClasses.TContosoObjectList.FreeItem ContosoClasses.TContosoObjectList.Clear ContosoGrid.TContosoCustomRowViewInfo.ClearValuesI nfo ContosoGrid.TContosoCustomMultiEditorRow.EditorsCh anged ContosoGrid.TContosoEditorPropertiesCollection.Upd ate System.Classes.TCollection.Changed System.Classes.TCollection.RemoveItem System.Classes.TCollectionItem.SetCollection System.Classes.TCollectionItem.Release System.Classes.TCollectionItem.Destroy ContosoGrid.TContosoCustomEditorRowProperties.Dest roy System.TObject.Free System.Classes.TCollection.Delete Unit2.TForm2.DeleteEditor Unit2.TForm2.PropertiesEditValueChanged ContosoEdit.TContosoCustomEditingController.EditVa lueChanged ContosoInplaceContainer.TContosoEditingController. EditValueChanged ... The code in question is: destructor TContosoCustomViewInfoItem.Destroy; begin // Crashes below: if (Control nil) and (Control.Controller.HotTrackController.HintElement = Self) then Control.Controller.HotTrackController.CancelHint; inherited Destroy; end; The "Contoso" refers to Contoso Ltd. - which is a fictional company used by Microsoft as an example company. Here it masks the real vendor of a certain well-known 3rd party library, as the point of this story is to show how EurekaLog can help you find bugs, not to ridicule any particular developer/vendor.

Unlike most other stories this one was extremely easy to resolve. Mostly because we had a reliable reproducible example.

First of all, take a closer look at the exception message: "...read of address 0xdeadc30f". Notice that the code is trying to access the DEADC30F address, which is close to the DEADBEEF address. The DEADBEEF is a special debugging marker (see the "When memory is released" option), indicating already released memory. In other words, this code is trying to access already deleted object.

The above means that our customer (or 3rd pary code, e.g. Contoso) have "use after free" bug somewhere. This is 100% reliable information, which can NOT be false-positive. In other words, if customer is sure that his code is correct - then he has found a bug in the Contoso library (congratulations!). And visa versa: if Contoso library code is correct, then there is a bug in customer's code on how he uses the Contoso library.

Armed with this information all there is left to do is to simply walk through customer's code, paying attention to all delete/free operations. Here is how it goes:
  1. The TContosoCustomEditingController.EditValueChanged fires an event handler, which is set to customer's code (PropertiesEditValueChanged), which calls: Row1.Properties.Editors.Delete(1);.
  2. The Delete is a method of RTL's TCollection, which removes item from the collection and then deletes the item:
    procedure TCollection.Delete(Index: Integer); begin Notify(TCollectionItem(FItems[Index]), cnDeleting); TCollectionItem(FItems[Index]).DisposeOf; // here end; destructor TContosoCustomEditorRowProperties.Destroy; begin FreeAndNil(FEditContainer); // IMPORTANT inherited Destroy; // here end; Notice that the TContosoCustomEditorRowProperties.Destroy is deleting the FEditContainer field. However, there is a reference to that object in other place - as we will see below.
  3. Now TCollectionItem's destructor will release itself from the owner (collection):
    destructor TCollectionItem.Destroy; begin if FCollection nil then Release; // here inherited Destroy; end; procedure TCollectionItem.Release; begin SetCollection(nil); // here end; procedure TCollectionItem.SetCollection(Value: TCollection); begin if FCollection Value then begin if FCollection nil then FCollection.RemoveItem(Self); // here if Value nil then Value.InsertItem(Self); end; end; procedure TCollection.RemoveItem(Item: TCollectionItem); begin Notify(Item, cnExtracting); if Item = FItems.Last then FItems.Delete(FItems.Count - 1) else FItems.Remove(Item); Item.FCollection := nil; NotifyDesigner(Self, Item, opRemove); Changed; // here end;
  4. Removing item from the collection will run notifiers - including TContosoEditorPropertiesCollection.Update:
    procedure TCollection.Changed; begin if FUpdateCount = 0 then Update(nil); // here end; procedure TContosoEditorPropertiesCollection.Update(Item: TCollectionItem); var I: Integer; begin for I := 0 to Count - 1 do GetItem(I).EditContainer.FCellIndex := I; Row.EditorsChanged; // here end;
  5. The Contoso library is trying to update editors:
    procedure TContosoCustomMultiEditorRow.EditorsChanged; begin if Properties.Locked or VerticalGrid.IsLoading then Exit; ViewInfo.ClearValuesInfo; // here Changed; end; procedure TContosoCustomRowViewInfo.ClearValuesInfo; begin FIsRightToLeftConverted := False; FInitialized := False; ValuesInfo.Clear; // here ValuesLinesInfo.Clear; end; procedure TContosoObjectList.Clear; var I: Integer; begin if OwnObjects then begin for I := 0 to Count - 1 do // = 2 FreeItem(I); // here end; inherited Clear; end;
  6. There are 2 items in the ValuesInfo list. First one (index 0) is OK, second one (index 1) is what causing the issue:
    destructor TContosoEditCellViewInfo.Destroy; begin if (EditContainer nil) and not EditContainer.IsDestroying then // here // ... end; Here is the problem: EditContainer is actually the Owner, and it points to already deleted object - the one that was deleted on the step 2 inside the TContosoCustomEditorRowProperties.Destroy.
Short recap:
  1. Customer's code deletes an item from the collection;
  2. The item deletes its field;
  3. The collection notifies about item's deletion;
  4. The notification callback tries to clear associated information and accesses the deleted field in process.
So, here is our bug: accessing an already deleted object.

Are you asking how the code was working "flawlessly" before adding EurekaLog to the project? Well, simple: the deleted object remained unchanged in the memory, so the TContosoEditCellViewInfo.Destroy could successfully access the already deleted object and read unchanged data from it. Adding EurekaLog to the project with default settings (enabled memory checks) changes this behaviour by actually erasing deleted object/memory.

So, is it a bug in the Contoso library? While it certainly does look that way, we can not be certain for sure, as we are not experts with that library. So it is also entirely possible that it is a customer's error.

Customer reported that this issue will be taken to the Contoso library support.

P.S. Read more stories like this one or read feedback from our customers.

Weiterlesen...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz