Jump to content

Stefan Glienke

Members
  • Content Count

    908
  • Joined

  • Last visited

  • Days Won

    66

Everything posted by Stefan Glienke

  1. Stefan Glienke

    64bit Debugger Not Handling Memory Problems

    That dialog there is definitely not from the debugger. Make sure you did not accidentally disable breaking on exceptions.
  2. Stefan Glienke

    RegEx performance

    Opinions on regex differ - however for this case using a regex is like using a bucket-wheel excavator to plant a pansy.
  3. Stefan Glienke

    RegEx performance

    Just skip any spaces and then check if it's '(' or not: function IsFunctionInString(const aFunction, aStr: string): boolean; var vPos: Integer; p: PChar; begin vPos := Pos(aFunction, aStr); if vPos > 0 then begin p := @aStr[vPos + aFunction.Length]; while p^ = ' ' do Inc(p); Result := p^ = '('; end else Result := False; end;
  4. Stefan Glienke

    Forum for Spring4D

    But what if I would not answer there 😉 Seriously - I understand people getting their area here if they don't have their own place already - Spring4D already has its own place.
  5. Stefan Glienke

    Forum for Spring4D

    https://groups.google.com/g/spring4d as I get an email notification - but I also watch SO and this forum.
  6. Stefan Glienke

    Is a "bare-minimum" EurekaLog possible?

    That's what the madCompileBugReport tool is for - you use madExcept with minimal debug info then the bugreport the application produces does not contain function names and such but using the tool turns it back into that - you need to have archived the map files for your released binaries though.
  7. While it certainly looks impressive and pas2js has come a long way it is still far from being able to just take your existing code (non VCL dependant of course) and compile/run that.
  8. Stefan Glienke

    SetLength TBytes Memory Leak

    Fair point - I've seen some glitches with unloaded DLL in the past - fortunately, we don't explicitly unload our own DLLs that were loaded with LoadLibrary. It's not a big issue, don't spend your valuable time on that - since we have a madExcept license anyway I will try out fulldebugmode.dll using that.
  9. Stefan Glienke

    SetLength TBytes Memory Leak

    That work only needs to be done when the report is being generated and I think that is not a point where raw speed matters that much but accuracy - on collecting the stack trace I agree that should be as fast as possible. I think I have seen a Jcl function that returns the address of the call instruction which then could be used to correct the displayed one to match the call instruction. Anyhow if you are not able to correct this we still have the option to use madExcept for the FullDebugMode dll which I will consider using 🤷‍♂️
  10. Stefan Glienke

    SetLength TBytes Memory Leak

    @Pierre le Riche It might work many times but when I saw this mentioned I remembered cases where I had seen leak reports with some weird looking call stacks in them which were kinda confusing as they were impossible (like in this case). I think simply walking up the stack and taking all addresses as a potential return address is the issue. This is the callstack when the code arrives in FastMM_DebugGetMem (10.3.3): and this is how the stack looks like: Looking at 00406E08 will find this: which is why LStrFromPWCharLen is being reported. So you are right - there should be a check if that potential return address is a valid one. Another thing I just noticed with the addresses in your vs the addresses reported from madExcept: madExcept reports the address of the call - you report the return address. IMO reporting the address of the call instruction is the better option - what do you think?
  11. Stefan Glienke

    Is a "bare-minimum" EurekaLog possible?

    I just checked: The hooking that madExcept is doing in Exception.RaisingException causes Exception.SetInnerException to never be called - and that method is responsible to set the FInnerException field. Regardless of the use case, I call this a bug.
  12. Stefan Glienke

    Planning for V4 (FMX support)

    I think you mean RTL but only certain platforms (Windows in V3) because I don't see any *visual* components in OTL (OmniThreadLibraryRuntime.dpk also only requires rtl.bpl). Because technically you can build a Windows-only application using FMX with OTL just fine.
  13. You got it almost - when using type inference on inline variables from pointers are no typed pointers but untyped so you have to explicitly state the type PFoo for your Foo variable.
  14. Stefan Glienke

    SetLength TBytes Memory Leak

    @Remy Lebeau The LStrFromPWCharLen entry indeed looks wrong - but the lines before and after that exactly match with the 10.3.3 code - I just checked. Maybe it's just a glitch in the stack walking code done by FastMM_FullDebugMode.dll Edit: Yep - I can repro the wrong entry in the call stack with this code: uses FastMM5, System.SysUtils; var x: TBytes; s: string; r: RawByteString; begin s := 'test'; r := RawByteString(s); SetLength(x, 10); Pointer(x) := nil; ReportMemoryLeaksOnShutdown := True; end. and get this report: This block was allocated by thread 0x432C, and the stack trace (return addresses) at the time was: 004128BA [FastMM5.pas][FastMM5][FastMM_DebugGetMem$qqri][7717] 0040476D [System.pas][System][@ReallocMem$qqrrpvi][5022] 00408181 [System.pas][System][DynArraySetLength$qqrrpvpvipi][36046] 00406E08 [System.pas][System][@LStrFromPWCharLen$qqrr27System.%AnsiStringT$us$i0$%pbius][26213] <-- ?!?! 004082C2 [System.pas][System][@DynArraySetLength$qqrv][36150] 004265D9 7732FA29 [BaseThreadInitThunk] 77E87C7E [RtlGetAppContainerNamedObjectPath] 77E87C4E [RtlGetAppContainerNamedObjectPath] My guess would be that the: PUSH ESP ADD dword ptr [ESP],4 in _DynArraySetLength is not properly handled by the stack walking code. Obviously, a defect in JclDebug LogStackTrace in FastMM_FullDebugMode.dpr - compiling FastMM_FullDebugMode.dll with madExcept gives this call stack as it just passes to madStackTrace.FastMM_LogStackTrace which seems to do a better job: 004128b5 +015 Project53.exe FastMM5 7717 +4 FastMM_DebugGetMem 00404767 +03f Project53.exe System 5022 +91 @ReallocMem 0040817c +16c Project53.exe System 36046 +70 DynArraySetLength 004082bd +005 Project53.exe System 36150 +3 @DynArraySetLength 7732fa27 +017 KERNEL32.DLL BaseThreadInitThunk Probably the bug is in GetRawStackTrace and madExcept is just able to fix it - I am not entirely sure - as far as I can see there is no method in JclDebug that can build a call stack from the data that FastMM_FullDebugMode GetRawStackTrace collects - that is why LogStackTrace simply iterates the entries and calls GetLocationInfo on each of them and just concats them. @Pierre le Riche fyi
  15. Stefan Glienke

    SetLength TBytes Memory Leak

    Important: a memleak report just tells where the memory was allocated that got leaked not the code that actually caused the leak. You need to review the code in NodeGetBase64Value and check what it does with the result of Mime64Decode and where it passes that.
  16. Stefan Glienke

    TLightweightMREW considerations

    If you mean object destruction when you write class destruction, then yes. On Windows you can simply put an Assert(Pointer(lock) = nil) because when it does not hold any lock, then its 0. On other platforms you have to check the documentation of the posix API being used. You can even count the number of readlocks or if there is a write lock - they both set specific bits.
  17. Stefan Glienke

    TLightweightMREW considerations

    There is no magic to it - it behaves exactly like SRW Locks and very similar on other platforms. And similar to TMREWSync it won't magically untangle any deadlocks or pending locks you had at the point of its destruction. The benefit of SRW locks is that they are very small - sizeof(pointer) - and can be embedded within the memory of the object which improves its performance - no memory indirection, cache locality.
  18. https://delphisorcery.blogspot.com/2021/03/how-to-hide-codeinsight-status-panel.html
  19. Stefan Glienke

    MAP2PDB - Profiling with VTune

    Profiling map2pdb with VTune using a pdb built with the map file from map2pdb 🤯 I guess that is fixable.
  20. Stefan Glienke

    List of usable RegEx for source code

    Not even to parse HTML?
  21. Stefan Glienke

    Decrease Your Build Time

    While LLVM certainly is part of the situation it suffers from the same sickness that makes most C++ code compile terribly slow: templates - err, I should say generics. (precompiled headers anyone?) Especially FMX uses them like everywhere if it makes sense or not. Everything is a TList<something> and there are many generic types within FMX itself. So the compiler has to build all these generics for each and every unit. Yes, if you have 1000 units using TList<TComponent> then that code is being emitted into 1000 dcu files and in case of LLVM also .o files including all that RTTI and possibly gigantic debug information for that TList<T>. The linker later eliminates any duplicates so the final binary does contains the code and RTTI only once. I know this from refactoring spring4d where I redesigned the generic collections to produce as little code as possible and turned off RTTI for all the implementing classes which improvided compile time on some projects by a factor of 4. Unfortunately even with the new intrinsics introduced in XE7 that were for reducing binary size because it enables compiletime optimizations for the code (GetTypeKind and alike) there is some significant bloat happening as I reported some time ago. When you fancy and look into a map file for a typical FMX application you can see that a huge chunk alone is from system.generics.collections and most of that code is dead code because it's only in the binary because RTTI is turned on for those classes. Even if they are used as private fields in some classes and all that is ever called on them is Add and Delete the entire code is emitted by the compiler. So a significant part of the compiletime is being used producing garbage (emitting code into dcu/o files) that the linker later has to find and eliminate. Edit: To emphasize: generics alone are not bad - its the overuse of them and making them fatter than they need to be and having RTTI being turned on for them. Often in places where a class reference would have been enough instead of some fancy<T: TSomethingclass>
  22. Stefan Glienke

    Introducing Delphi Uses Helper

    Introducing "Uses Helper" - some little but incredibly helpful IDE plugin https://delphisorcery.blogspot.com/2021/03/introducing-delphi-uses-helper.html
  23. Stefan Glienke

    List of usable RegEx for source code

    David unfortunately suffers from a severe chronic heap allocation intolerance 😞 Joking aside: awareness of (hidden) heap allocations is usually a good thing though.
  24. Stefan Glienke

    MAP2PDB - Profiling with VTune

    All I can say is that it did not work properly for me - when clicking on the method I mentioned above it wanted to open Spring.pas and marked an obviously completely wrong line.
  25. Stefan Glienke

    MAP2PDB - Profiling with VTune

    Very nice! - Just a thing about the map file parsing - and actually that's an issue that I've seen with most map file analyzing tools as they do it wrong - relating symbols from generics to the correct type and unit - example: Spring.{System.Generics.Collections}TDictionary<System.Pointer,System.Classes.TList>.GetBucketIndex This means the code for this method because its a generic was compiled into the Spring.dcu because I used that TDictionary from the RTL in Spring.pas - but the source will not be found there but in the unit in the curly brackets: System.Generics.Collections
×