Jump to content

Anders Melander

Members
  • Content Count

    2749
  • Joined

  • Last visited

  • Days Won

    146

Everything posted by Anders Melander

  1. Anders Melander

    how to filter on source files using VTune?

    Assuming you're using map2pdb to generate the PDB-file for VTune, you can specify on the map2pdb command line which units to include and which to exclude. For example, I often use these filters (excludes DevExpress, the VCL, Indy, etc.): -include:0001 -exclude:dx*;cx*;winapi.*;vcl.*;data.*;firedac.*;soap.*;web.*;datasnap.*;id*;vcltee.* However, that will not prevent VTune from profiling that code. It just can't resolve the addresses in those units. As far as I know, the only way to filter data in VTune is to either use the filter fields at the bottom of the Window or to select the lines you'd like to exclude/include, right click and then select Filter In by Selection/Filter Out by Selection from the context menu. https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/2024-2/context-menu-grid.html
  2. Anders Melander

    How to debug a Not Responding program element

    Possible but unlikely. I can compile SuperLemmix but I can't run it since I'm missing all the external assets. So instead I went back and looked at the original FastMM leak report. TGadgetMetaAccessor is owned and destroyed by TGadgetMetaInfo. TGadgetMetaInfo is created in 3 different places; Two of them are inside TGadgetMetaInfoList (a TObjectList) and those appear to be fine. The last is in TNeoPieceManager where we have a case of exception swallowing that will lead to a leak: function TNeoPieceManager.ObtainObject(Identifier: String): Integer; var ObjectLabel: TLabelRecord; MO: TGadgetMetaInfo; begin try ObjectLabel := SplitIdentifier(Identifier); Result := fObjects.Count; MO := TGadgetMetaInfo.Create; MO.Load(ObjectLabel.GS, ObjectLabel.Piece, fTheme); // Leak if exception here fObjects.Add(MO); except Result := -1; end; end; So there's (unsurprisingly) problems with exception handling. With that in mind I searched for "except" and reviewed all the cases of explicit exception handling. Many are misguided but harmless but there are a few serious problems. For example in TBaseAnimationSet.LoadMetaData there's a double-free in case of exception: procedure TBaseAnimationSet.LoadMetaData(aColorDict: TColorDict; aShadeDict: TShadeDict); begin Parser := TParser.Create; try [...] try [...] except Parser.Free; raise EParserError.Create('TBaseAnimationSet: Error loading lemming animation metadata for ' + ANIM_NAMES[i] + '.') end; [...] finally Parser.Free; end; end; In TNeoLevelEntry.LoadLevelFileData there's a leak on exception: procedure TNeoLevelEntry.LoadLevelFileData(aExtent: TNeoLevelLoadState); [...] try TalInfoLevel.LoadFromFile(Path); for i := 0 to TalInfoLevel.Talismans.Count-1 do begin CloneTal := TTalisman.Create; CloneTal.Clone(TalInfoLevel.Talismans[i]); // Leak if exception here fTalismans.Add(CloneTal); end; except // Fail silently. end; [...] TNeoLevelGroup.CleanseLevels is a complete mess and can leak a TStringList on exception. TNeoLevelGroup.LoadUserData will leak a TParser on exception.
  3. Anders Melander

    How to debug a Not Responding program element

    TList<T>.Clear is declared inline and inlined functions will not appear in the call stack. If you compile with inlining disabled it will appear. It can't (unless you disable inlining), but in this case we weren't really interested in where Clear was being called from but rather where/when the object was being destroyed. So, as expected, there's more than one problem. Look at here the Access Violation occurs, examine the call stack, rinse, repeat. The absence of errors without madExcept does not mean that aren't any errors. You just can't see them...
  4. Anders Melander

    How to debug a Not Responding program element

    Oh, I see... So TGadgetAnimations is in fact declared as derived from TObjectList<TGadgetAnimation>. This means that you can catch the destruction of a TGadgetAnimation by overriding the TObjectList<T>.Notify method: type TGadgetAnimations = class(TObjectList<TGadgetAnimation>) [...] protected procedure Notify(const Value: TGadgetAnimation; Action: TCollectionNotification); override; [...] end; procedure TGadgetAnimations.Notify(const Value: TGadgetAnimation; Action: TCollectionNotification); begin if (Action in [cnExtracting, cnDeleting]) and (Value = fPrimaryAnimation) then fPrimaryAnimation := nil; inherited; end; The call to Clear destroys all the objects contained in the list. The call stack shows you exactly how you got from TGadgetAnimations.Clear to TGadgetAnimation.Destroy.
  5. Anders Melander

    How to debug a Not Responding program element

    FWIW, it can be set through the constructor too. Yes but then I would have expected TGadgetAnimation to be in the leak list too. As far as I can tell from the screenshot the list only contained the string. Anyway, the string leak is definitely a secondary leak and the problem lies elsewhere.
  6. Anders Melander

    How to debug a Not Responding program element

    This indicates that fPrimaryAnimation has been destroyed but fPrimaryAnimation has not been nilled. If you place a breakpoint in the TGadgetAnimation destructor you should be able to see where it is destroyed (Could it possibly be in TGadgetAnimations.Clear ?). if it is TGadgetAnimations itself, or some code that has access to TGadgetAnimations, that destroy the TGadgetAnimation object then you can just have that code clear the fPrimaryAnimation reference. Otherwise TGadgetAnimation will need to store a reference back to the TGadgetAnimations that owns it. This way the TGadgetAnimation destructor can clear the reference when it is destroyed. Something like this: destructor TGadgetAnimation.Destroy; begin [...] // FOwner is a reference to the TGadgetAnimations that contains this object if fPrimary then FOwner.fPrimaryAnimation := nil; inherited; end;
  7. Anders Melander

    How to debug a Not Responding program element

    So you are reading or writing from/to memory that has been free'd. That's a bug. The call stack tells you the unit and exact line number (if you ran it in the debugger you would get the same information) and it should be easy to see what the problem is. Start by fixing the bugs surfaced by the buffer overrun detection. Once they are fixed you can focus on the leaks. The leaks are probably insignificant. The other bugs are definitely not. With regard to FreeAndNil you need to understand what it does and what the purpose of using it is (in this case, not generally) and then it should become self-evident where to use it. But do that later.
  8. Anders Melander

    How to debug a Not Responding program element

    My guess is that it's the TGadgetAnimation.fName string which is leaked (based on the string content and the call to UpperCase) but that it a bit strange because strings are reference counted and it's usually pretty impossible to leak them. It's also strange that madExcept only reports the string leaked and not the object(s) that references the string. I don't think I've seen that before. I think you maybe have several bugs in play which messes with the resource tracking. If possible, try to build and run with "Instantly crash on buffer (*) overrun" enabled. I would suspect that there are problems with objects being referenced after they have been destroyed. One easy thing you can do to catch some of those cases is to use FreeAndNil instead of Free when destroying objects. Don't bother doing it on local vars (i.e. vars declared in a function/method). Do it on member vars (i.e. declared in a class).
  9. Anders Melander

    Anyone using Clever Components?

    To me it looks like it's a Russian company pretending to be a US company - If it's even a company.
  10. Anders Melander

    Parallel.For optimization

    Exactly. The memory manager is not the problem. If anything, a better performing memory manager will just make it harder to locate and fix the problem. The goal is to not be reliant on a faster memory manager (and FWIW, FastMM4 isn't slow).
  11. Anders Melander

    Cross platform color picker and palette library

    Because the thing video editing tools really, desperately need is a color picker with HTML and process print color values...
  12. Anders Melander

    Parallel.For optimization

    I don't know how SamplingProfiler works but I would think that it should be able to show you the call stack leading to NtDelayExecution. That should tell you from where and why it's being called.
  13. Anders Melander

    Is jedimath still maintained?

    Do you mean this one?: https://github.com/project-jedi/jcl/blob/master/jcl/source/common/JclMath.pas If the file is not in the Github repo then I think it's safe to assume it's unmaintained (or even more unmaintained than the files in the repo).
  14. Anders Melander

    How to debug a Not Responding program element

    You don't need to uninstall it; Just disable it for the project (i.e. uncheck the "enable madExcept" checkbox). It doesn't do anything and there's no overhead when it isn't enabled for the project. A significant overhead is expected, both in terms of performance and memory usage, when resource tracking is enabled and it's even worse when buffer overrun detection is enabled. So you should only enable these two features during debug, either to track down a suspected leak/overwrite or to occasionally verify that there aren't any once you get there. The core functionality, which is exception handling/stack tracing, doesn't cause any performance overhead. Those are almost certainly errors in your code. madExcept should produce a call stack that points to the origin of the exception. If it doesn't (i.e. the exception is only visible in the debugger) then it's because the code is actively swallowing the exception. A practice that unfortunately is quite common in legacy code: try ...lots and lots of code here... except // I can't figure out why the code above fails occasionally // so let's just pretend there's no problem :-/ end; No. New version are backward compatible; You don't need to install an older version.
  15. Anders Melander

    Threadvar "per object"

    The suitability of TMultiReadExclusiveWriteSynchronizer depends on how you use it and what your needs are and only you know the answer to that. There's a more lightweight and faster alternative available in the RTL of recent Delphi versions. Google, or the help, will find the name for you. TMultiReadExclusiveWriteSynchronizer got broken when Danny Thorpe rewrote it for D6. I believe it was fixed in D7. Before the rewrite it supported lock promotion which opened up for deadlocks in some usage patterns - not because it was buggy but because people didn't know what they were doing.
  16. Anders Melander

    Threadvar "per object"

    Search broken again? https://en.delphipraxis.net/search/?q=TMultiReadExclusiveWriteSynchronizer https://www.google.com/search?q=TMultiReadExclusiveWriteSynchronizer
  17. Anders Melander

    F1 context help to WinAPI ?

    I can relate to that. I've used a Gnome Sort from time to time when performance wasn't critical. Simply because it looks nice. var i := 0; while (i < High(Values)) do if (i = 0) or (Values[i] >= Values[i-1]) then begin Inc(i); end else begin Swap(Values[i], Values[i-1]); Dec(i); end;
  18. Anders Melander

    F1 context help to WinAPI ?

    Nicely avoids the problem of integrating with the IDE help system - by not integrating with the IDE help system 🙂 Also contains the only instance of a cocktail shaker bubble sort that I've seen used in practice. "Outdated help is better than no help" - apparently.
  19. Anders Melander

    F1 context help to WinAPI ?

    I have an IDE wizard lying around somewhere on my HD that AFAIR will can redirect the help request to an URL if the other help providers fail to resolve it. It was made for Delphi 5 or 6 (so it's 20-25 years old) and from back when the MSDN help was distributed on CDs. I'll see if I can locate it and get it to compile with a newer Delphi... Yup it works; I just had to update the default search URL. However, for some reason it only works if I search on a keyword the standard help doesn't resolve. Otherwise the IDE help lookup fails with an exception. I can post the source if anyone wants to have a go at it.
  20. Anders Melander

    How to debug a Not Responding program element

    Give madExcept a try again; It's much easier.
  21. Anders Melander

    Quality Portal going to be moved

    I have migrated countless JIRA instances from server to cloud and it has never been "a significant effort". The only problem I can think of is if they had modified their server so much that it couldn't be migrated automatically. Indeed. Normally this wouldn't be that big of an issue as lack of features and bug are to be expected, this being a relatively new product. But the problem with Atlassian is that the suckage only ever increases. I think they hate their users. Eventually Github will eat their lunch.
  22. Anders Melander

    Essential Delphi Addins survey

    A single item for me so YMMV on the "essentialness".
  23. Anders Melander

    MAP2PDB - Profiling with VTune

    A google search would have told you that. Or the IDE insight: or the help... Command line. Replace <map-filename> with the name of your map file. Run VTune, configure your project there, launch the application from within VTune. But before you do anything, please read some VTune documentation. You don't need to post anything to get notifications. Just click the Following dropdown.
  24. Anders Melander

    RAD Studio v12.1 Toolbars Wonky Behavior

    I think not...
  25. Anders Melander

    List Of Property Editors

    source\Property Editors\FmxStyleLookup.pas
×