-
Content Count
1428 -
Joined
-
Last visited
-
Days Won
141
Everything posted by Stefan Glienke
-
Is a "bare-minimum" EurekaLog possible?
Stefan Glienke replied to aehimself's topic in Delphi Third-Party
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. -
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.
-
With remover refactoring tool to IDE, Please vote this feature request:
Stefan Glienke replied to Tommi Prami's topic in Delphi IDE and APIs
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. -
SetLength TBytes Memory Leak
Stefan Glienke replied to Hafedh TRIMECHE's topic in RTL and Delphi Object Pascal
@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 -
SetLength TBytes Memory Leak
Stefan Glienke replied to Hafedh TRIMECHE's topic in RTL and Delphi Object Pascal
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. -
TLightweightMREW considerations
Stefan Glienke replied to Rollo62's topic in RTL and Delphi Object Pascal
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. -
TLightweightMREW considerations
Stefan Glienke replied to Rollo62's topic in RTL and Delphi Object Pascal
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. -
A short instruction on how to hide the codeinsight status panel
Stefan Glienke posted a topic in Tips / Blogs / Tutorials / Videos
https://delphisorcery.blogspot.com/2021/03/how-to-hide-codeinsight-status-panel.html -
MAP2PDB - Profiling with VTune
Stefan Glienke replied to Anders Melander's topic in Delphi Third-Party
Profiling map2pdb with VTune using a pdb built with the map file from map2pdb 🤯 I guess that is fixable. -
List of usable RegEx for source code
Stefan Glienke replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Not even to parse HTML? -
Decrease Your Build Time
Stefan Glienke replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
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> -
List of usable RegEx for source code
Stefan Glienke replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
David unfortunately suffers from a severe chronic heap allocation intolerance 😞 Joking aside: awareness of (hidden) heap allocations is usually a good thing though. -
MAP2PDB - Profiling with VTune
Stefan Glienke replied to Anders Melander's topic in Delphi Third-Party
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. -
MAP2PDB - Profiling with VTune
Stefan Glienke replied to Anders Melander's topic in Delphi Third-Party
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 -
I explained that in the article. DelphiAST is being used to index using the defines of a Win32 application.
-
Unicode string - how element iterating?
Stefan Glienke replied to vfbb's topic in RTL and Delphi Object Pascal
But before it did not run in an endless loop like the code from @pyscripter does 🤷♂️ -
List of usable RegEx for source code
Stefan Glienke replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
No - when the already allocated block is large enough it doesn't do much. And when it has to actually allocate it just does a lock cmpxchg on a bool field of the block types - when its already locked by another thread it simply tries the next bigger one. Speaking of FastMM4 allocation was never the problem with many threads because of this mechanism - it could only lead to a bit memory overhead because some small blocks might be little overallocated because it had to go past the currently locked sub allocators. The issue was in deallocating because that needs of course to the allocator it the memory belongs to. This is what Pierre addressed in V5. FastMM having *a* global lock is a myth. -
Unicode string - how element iterating?
Stefan Glienke replied to vfbb's topic in RTL and Delphi Object Pascal
That does not work at all - CharNext does not work well. And that article is from 2007 - did we even have emojis back then? 😄 Try yourself with the testcase here: https://docs.microsoft.com/en-us/dotnet/core/compatibility/globalization/5.0/uax29-compliant-grapheme-enumeration -
function (const arr: TArray<T>): RecWithTwoFields (Pointer, Integer) Bonus: inlining that function looks like this - go go eax, you got it eventually!
-
Delphi WAT of the day
Stefan Glienke replied to Stefan Glienke's topic in RTL and Delphi Object Pascal
Which is not what the documentation says: -
Delphi WAT of the day
Stefan Glienke replied to Stefan Glienke's topic in RTL and Delphi Object Pascal
Inspired by RSP-28311: {$APPTYPE CONSOLE} uses TypInfo; type generic = record class procedure test<T>(const value : T); static; end; class procedure generic.test<T>(const value: T); begin Writeln(GetTypeName(TypeInfo(T))); end; procedure test(a: Int32); overload; begin Writeln('Int32'); end; procedure test(a: Int64); overload; begin Writeln('Int64'); end; procedure test(a, b: Int32); overload; begin Writeln('Int32'); end; procedure test(a, b: Int64); overload; begin Writeln('Int64'); end; const one = Int64(1); two = Int64(MaxInt); three = Int64(MaxInt)+1; four: Int64 = 1; begin generic.test(one); // Int64 generic.test(two); // Int64 generic.test(three); // Int64 generic.test(four); // Int64 test(one); // Int64 test(two); // Int64 test(three); // Int64 test(four); // Int64 test(one, 1); // Int32 ?! test(two, 1); // Int32 test(three, 1); // Int64 test(four, 1); // Int64 test(one, Int64(1)); // Int64 test(Int64(1), 1); // Int32 ?! end. -
Google Tests (unit testing framework) working with Embarcadero C++ clang compiler?
Stefan Glienke replied to Roger Cigol's topic in General Help
In 1. you write that you don't have much time. Do you think that 2. or 3. would require less time?- 26 replies
-
- c++
- google tests
-
(and 1 more)
Tagged with:
-
I know how to write a debugger visualizer and how to use the IOTADebuggerVisualizerValueReplacer. What I want to achieve is creating sub nodes with values like you get when you have a dynamic array, a record or an object. However the mentioned interface only provides a method to produce a string which is printed but no way to produce some kind of sub structure. I also know about IOTADebuggerVisualizerExternalViewer as being used for TStrings where you can click on the magnifier icon to open up another window but that is not what I would like to have. I am looking for a way to dynamically create sub entries for some type which seems to be beyond the capabilities of the ToolsAPI. But we have some people that know a bit about the internals of the IDE any maybe someone is able to find a way to achieve this. To illustrate this. uses System.Generics.Collections, Spring.Collections; procedure Main; var arr: TArray<Integer>; listA: TList<Integer>; listB: IList<Integer>; begin arr := [1, 2, 3]; listA := TList<Integer>.Create; listA.AddRange(arr); listB := TCollections.CreateList<Integer>(arr); end; I get this in the local variables view (this is from 10.4.2 where visualizers for TList<T> and alike were added): When the debugger sees a dynamic array type it shows the elements as sub nodes - thus you can "cheat" the watches: So what I would like to see is the expand icon on my listB and then the elements in the list in sub nodes just like in dynamic array.
-
Delphi WAT of the day
Stefan Glienke replied to Stefan Glienke's topic in RTL and Delphi Object Pascal
Exactly - at runtime. Warning would be nice, don't you think? Edit: to be clear not because I put the -1 there which will for sure blow up but because Integer->Cardinal will blow up for 50% of the value range. We have W1023 and W1024 when comparing or combining, but assignment/parameter passing blows up at runtime... eventually, some day. -
Delphi WAT of the day
Stefan Glienke replied to Stefan Glienke's topic in RTL and Delphi Object Pascal
Inspired by that other thread: procedure TypeSafeMyAss(i: Cardinal); begin end; var i: Integer; begin i := -1; {$RANGECHECKS ON} TypeSafeMyAss(i); end.