Jump to content

Kas Ob.

Members
  • Content Count

    534
  • Joined

  • Last visited

  • Days Won

    9

Everything posted by Kas Ob.

  1. These two do make things very hard and even impossible to put in an algorithm, i mean going form wider range (arbitrary strings with special characters) of data to narrower output range (only Latin and digits) and while keeping length. You have to drop one of them or accept some degree of length increase ! I can't think of an alternative approach or existing algorithm, unless the length of your strings are long enough (must be big and long, or may be with repeated words and parts) to add compression layer that decrease the input strings to a sufficient length to do the presentation with Latin and digits.
  2. Kas Ob.

    Memory leak on TParallel.For

    1) How many loop are there in the code in that DLL ? and many iteration being executed ? and compare that to the reported leaks numbers ? 2) Empty loops does produce leaks ? this means broken logic in TThreadPool, yet doesn't mean it is buggy yet, it could be MM, at least try FastMM4 for both EXE and DLL, make sure you are using the same MM. 3) Not bad idea to use the manually induced leaks, this will consolidate the numbers, like i explained above, you should make sure of consistency of the report, if you have more than one loop. 4) in my opinion, TThreadPoolMonitor is the one behind all these leaks, this easily can happen if it is was locked and corrupted or overwritten, that is your target and the direct cause in this bug hunt, it is reported as leak in your log, and as you pointed to. Yet unless someone can confirm and reproduce it, i am inclined to assume your project environment (setup) is responsible for it. Unfortunately, that is good news, and means replicating or reproducing a smaller and stripped project (the smallest new project) to reproduce this bug is feasible, so please try ! Just one thought, lets imagine one thread belongs to TThreadPool was stuck/frozen/looping, how one thread being would affect the pool exiting and cleaning after the threads, does its position affect the pool behavior, like if it was the first, last or in the middle... I don't have an answer for this, so i suggest to dump pall the threads on exit, also don't know how madshi, but i know eurekalog can do this and triggered by hand or by option and manually induced an exception, in any case try to dump all the threads and their stacks to see if there is a thread is still do something or simply unhinged somewhere. The best way to do this is to introduce any unit to the project that has finalization and here you will trigger the threads dump (to get all threads stacks), make sure this unit is the highest place in the dpr uses clause, right after MM, and of course right after the exception tool you will use.
  3. @Eric Grange How about hooking TDX11Context.DoSetShaders ? Wait a second !, TDX11Context is private and non accessible, at least on my XE8, that is bad design to hide a critical and OS dependent class, was the designer so confident it is bug free and it does include everything could be needed from DirectX11 even in the future. From the name DX11, there will be DX12 and even DX13, and they will break compatibility in huge way, so a private one is like, NO update your IDE framework and wait for our updated design...
  4. Kas Ob.

    VSoft.UUIDv7 - a Delphi implementation of UUIDv7 (RFC 9562)

    Where is Byte[7] ?!! Anyway, try this for fair comparison function NewGuidV7: TGUID; var LUnixMSec: Int64; LUnixMSecBytes: array[0..7] of Byte absolute LUnixMSec; LBytes: array[0..15] of Byte; I: Integer; begin for I := 0 to 15 do LBytes[I] := Random($FF); LUnixMSec := DateTimeToMilliseconds(TTimeZone.Local.ToUniversalTime(Now)) - Int64(UnixDateDelta + DateDelta) * MSecsPerDay; LBytes[0] := LUnixMSecBytes[5]; LBytes[1] := LUnixMSecBytes[4]; LBytes[2] := LUnixMSecBytes[3]; LBytes[3] := LUnixMSecBytes[2]; LBytes[4] := LUnixMSecBytes[1]; LBytes[5] := LUnixMSecBytes[0]; {LBytes[0] := (LUnixMSec shr 40) and $FF; LBytes[1] := (LUnixMSec shr 32) and $FF; LBytes[2] := (LUnixMSec shr 24) and $FF; LBytes[3] := (LUnixMSec shr 16) and $FF; LBytes[4] := (LUnixMSec shr 8) and $FF; LBytes[5] := LUnixMSec and $FF;} LBytes[6] := (LBytes[6] and $0F) or $70; LBytes[8] := (LBytes[8] and $3F) or $80; Result := TGuid.Create(LBytes, 0, True); end; Fix LByte[7] as should, because in my sample it is missing too ! In case you did a benchmark then please share the result with us, (i didn't)
  5. Kas Ob.

    Memory leak on TParallel.For

    @terran i see you updated you post with a log Yes that log does shows memory leaks, and you didn't do what i asked for and suggested, but yet more information is needed to pin point the problem, i do understand you can't share codes, But as curtesy and respect for our time as yours, read what people write you and if you don't understand their reasons and logic, then you can ask, you might learn something or two. So here what i see with the little provided: I put your log in Notepad++ and searched for all the occurrences of "The allocation number is", the result is Line 28: The allocation number is: 3155 Line 60: The allocation number is: 504725 Line 92: The allocation number is: 504689 Line 124: The allocation number is: 504673 Line 156: The allocation number is: 504650 Line 188: The allocation number is: 504623 Line 220: The allocation number is: 504604 Line 252: The allocation number is: 502198 Line 284: The allocation number is: 486818 Line 316: The allocation number is: 486791 Line 348: The allocation number is: 486093 Line 380: The allocation number is: 504750 Line 412: The allocation number is: 504747 Line 444: The allocation number is: 504733 Line 476: The allocation number is: 504727 Line 508: The allocation number is: 504694 Line 540: The allocation number is: 504690 Line 572: The allocation number is: 504678 Line 604: The allocation number is: 504674 Line 636: The allocation number is: 504656 Line 668: The allocation number is: 504652 Line 700: The allocation number is: 504630 Line 732: The allocation number is: 504625 Line 764: The allocation number is: 504608 Line 796: The allocation number is: 504605 Line 828: The allocation number is: 502202 Line 860: The allocation number is: 502199 Line 892: The allocation number is: 486839 Line 924: The allocation number is: 486795 Line 956: The allocation number is: 486792 Line 988: The allocation number is: 486099 Line 1020: The allocation number is: 486094 Line 1052: The allocation number is: 486819 Line 1084: The allocation number is: 484903 Line 1116: The allocation number is: 484900 Line 1148: The allocation number is: 2221 Line 1180: The allocation number is: 2293 Line 1212: The allocation number is: 2127 Line 1244: The allocation number is: 2087 Line 1276: The allocation number is: 2047 Line 1308: The allocation number is: 504746 Line 1340: The allocation number is: 2018 Line 1372: The allocation number is: 1971 Line 1404: The allocation number is: 3168 Line 1436: The allocation number is: 1944 Line 1468: The allocation number is: 1896 Line 1500: The allocation number is: 1873 Line 1532: The allocation number is: 1860 Line 1564: The allocation number is: 1888 Line 1596: The allocation number is: 1850 Line 1628: The allocation number is: 484899 Line 1660: The allocation number is: 1902 Line 1694: The allocation number is: 504748 Line 1728: The allocation number is: 504729 Line 1762: The allocation number is: 504691 Line 1796: The allocation number is: 504675 Line 1830: The allocation number is: 504653 Line 1864: The allocation number is: 504627 Line 1898: The allocation number is: 504606 Line 1932: The allocation number is: 502200 Line 1966: The allocation number is: 486829 Line 2000: The allocation number is: 486793 Line 2034: The allocation number is: 486096 Line 2068: The allocation number is: 3170 Line 2102: The allocation number is: 484901 Line 2136: The allocation number is: 3157 Line 2170: The allocation number is: 2295 Line 2204: The allocation number is: 2223 Line 2238: The allocation number is: 2131 Line 2272: The allocation number is: 2020 Line 2306: The allocation number is: 2090 Line 2340: The allocation number is: 1946 Line 2374: The allocation number is: 1974 Line 2408: The allocation number is: 1899 Line 2442: The allocation number is: 2049 Line 2476: The allocation number is: 1875 Line 2510: The allocation number is: 1890 Line 2544: The allocation number is: 1862 Line 2578: The allocation number is: 1853 Line 2612: The allocation number is: 1989 Line 2654: The allocation number is: 3169 Line 2686: The allocation number is: 2297 Line 2718: The allocation number is: 2225 Line 2750: The allocation number is: 2294 Line 2782: The allocation number is: 2136 Line 2814: The allocation number is: 2222 Line 2846: The allocation number is: 2092 Line 2878: The allocation number is: 2129 Line 2910: The allocation number is: 2051 Line 2942: The allocation number is: 2088 Line 2974: The allocation number is: 3173 Line 3006: The allocation number is: 2022 Line 3038: The allocation number is: 2019 Line 3070: The allocation number is: 1976 Line 3102: The allocation number is: 2048 Line 3134: The allocation number is: 3159 Line 3166: The allocation number is: 1948 Line 3198: The allocation number is: 1972 Line 3230: The allocation number is: 3156 Line 3262: The allocation number is: 1901 Line 3294: The allocation number is: 1945 Line 3326: The allocation number is: 1892 Line 3358: The allocation number is: 1897 Line 3390: The allocation number is: 1877 Line 3422: The allocation number is: 1889 Line 3454: The allocation number is: 1864 Line 3486: The allocation number is: 1874 Line 3518: The allocation number is: 1855 Line 3550: The allocation number is: 1851 Line 3582: The allocation number is: 1861 Line 3614: The allocation number is: 504739 Line 3650: The allocation number is: 504703 Line 3686: The allocation number is: 504687 Line 3722: The allocation number is: 504661 Line 3758: The allocation number is: 504635 Line 3794: The allocation number is: 502167 Line 3830: The allocation number is: 486073 Line 3866: The allocation number is: 486801 Line 3902: The allocation number is: 486575 Line 3938: The allocation number is: 504614 Line 3974: The allocation number is: 3164 Line 4010: The allocation number is: 2174 Line 4046: The allocation number is: 3113 Line 4082: The allocation number is: 2065 Line 4118: The allocation number is: 2107 Line 4154: The allocation number is: 2236 Line 4190: The allocation number is: 1997 Line 4226: The allocation number is: 2031 Line 4262: The allocation number is: 1960 Line 4298: The allocation number is: 1934 Line 4334: The allocation number is: 1893 Line 4365: The allocation number is: 1978 Line 4401: The allocation number is: 1865 Line 4437: The allocation number is: 1878 Line 4473: The allocation number is: 1857 Line 4509: The allocation number is: 1848 Line 4545: The allocation number is: 484882 Line 4581: The allocation number is: 504587 Line 4617: The allocation number is: 504749 Line 4657: The allocation number is: 504731 Line 4697: The allocation number is: 504692 Line 4737: The allocation number is: 504676 Line 4777: The allocation number is: 504655 Line 4817: The allocation number is: 504629 Line 4857: The allocation number is: 504607 Line 4897: The allocation number is: 502201 Line 4937: The allocation number is: 486836 Line 4977: The allocation number is: 486794 Line 5017: The allocation number is: 484902 Line 5057: The allocation number is: 486098 Line 5097: The allocation number is: 3171 Line 5137: The allocation number is: 3158 Line 5177: The allocation number is: 2296 Line 5217: The allocation number is: 2224 Line 5257: The allocation number is: 2133 Line 5297: The allocation number is: 2091 Line 5337: The allocation number is: 2050 Line 5377: The allocation number is: 2021 Line 5417: The allocation number is: 1975 Line 5457: The allocation number is: 1947 Line 5497: The allocation number is: 1900 Line 5537: The allocation number is: 1891 Line 5577: The allocation number is: 1876 Line 5617: The allocation number is: 1863 Line 5657: The allocation number is: 1854 This shows two group of leaks, one group happen very early, while the other was very late, both group are condensed, meaning they do happen on specific event. I followed what i think is the first (the oldest reported leak) with number 1848, and here is it --------------------------------2024-09-02 17:00:36-------------------------------- A memory block has been leaked. The size is: 68 This block was allocated by thread 0xA44, and the stack trace (return addresses) at the time was: 0542E4D2 [fastmm5.pas][FastMM5][FastMM_DebugGetMem$qqri][7820] 054170D2 [System.pas][System][@GetMem$qqri][4962] 05418F9B [System.pas][System][TObject.NewInstance][18331] 0541969E [System.pas][System][@ClassCreate$qqrpvzc][19661] 05517233 [System.Threading.pas][System.Threading][Threading.TThreadPool.TQueueWorkerThread.Create][3479] 0541970C [System.pas][System][@AfterConstruction$qqrxp14System.TObject][19710] 05516998 [System.Threading.pas][System.Threading][Threading.TThreadPool.CreateWorkerThread][3223] 05516B19 [System.Threading.pas][System.Threading][Threading.TThreadPool.GrowWorkerPool][3269] 05516E1F [System.Threading.pas][System.Threading][Threading.TThreadPool.QueueWorkItem][3357] 05513D9B [System.Threading.pas][System.Threading][Threading.TTask.QueueEvents][2715] 055145C1 [System.Threading.pas][System.Threading][Threading.TParallel.TReplicableTask.QueueEvents][2972] 0551419B [System.Threading.pas][System.Threading][Threading.TTask.Start][2779] 05510F1A [System.Threading.pas][System.Threading][Threading.TParallel.ForWorker][1483] 056D8CF2 [ImageCompare.dpr][ImageCompare][ResizeCanvas$qqrp33Imagingcanvases.TFastARGB32Canvasp30Imagingcanvases.TImagingCanvasiiii][1069] 05653BA6 [ImagingCanvases.pas][ImagingCanvases][TImagingCanvas.ResetClipRect][954] 056CA19D [Imaging.pas][Imaging][GetImageFormatInfo$qqr25Imagingtypes.TImageFormatr29Imagingtypes.TImageFormatInfo][2812] 05653B76 [ImagingCanvases.pas][ImagingCanvases][TImagingCanvas.UpdateCanvasState][949] 056C432E [Imaging.pas][Imaging][TestImage$qqrrx23Imagingtypes.TImageData][921] 056D97E9 [ImageCompare.dpr][ImageCompare][TProcessFile.GetdHash$qqrr22Imagecompare.TLastInfox20System.UnicodeStringiii][1200] 77911B2C [Unknown function at RtlpNtEnumerateSubKey] The block is currently used for an object of class: System.Threading.TThreadPool.TQueueWorkerThread The allocation number is: 1848 Current memory dump of 76 bytes starting at pointer address 72AE3A0: AC 3C 50 05 A4 9E 00 00 CC 03 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 FB 2C 07 40 4F 21 07 40 EB 22 07 64 FB 2C 07 68 FB 2C 07 00 CB 27 07 00 00 00 00 D4 2F 2C 8D D2 E4 42 05 . < P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . @ O ! . @ . " . d . , . h . , . . . ' . . . . . . / , . . . B . Now this proof you are wrong about none of your code is involved ! All start in your ImageCompare.dpr, so more information is needed here, Is that ImageCompare.dpr belongs to a DLL or an EXE ? Another thing, is there any thing prohibited you from do what i suggested about deliberately invoked leaks ? Again and for the last time, put TMyObjectX before such loops you pasted above, replace X with a number (1,2,3..) so they can be named and recognized in the log, and put this simple line in the loop "TMyObject.Create;" no variable, no thing, this is enough to cause a leak to report. Depending on the number of reported leaks for these TMyObject1, TMyObject2.... you and we can see a little more, because in your first post there was very interesting numbers 27 and 54, yet the loop is 11 ! This must be addressed also, to get the bigger picture or at least identify a method to catch and categorize the problem, is it a Compiler/RTL bug or some mishandling code. Another thing, Why ImageCompare.dpr does show in the log to begin with ? in case it is a DLL then you must not initialize long process or an even more dangerous process like multithreading, when the thread is Loaded/Attcached, like such process that depend on and identify the calling thread as main one, the calling thread here (in case with DLL) is an OS one that will be created and will be destroyed by the OS, and this will confuse your code with the Process Main Thread, causing all sort of problem. And good luck !
  6. Kas Ob.

    Memory leak on TParallel.For

    I don't have an answer, just one to do about thing this Add a fake (not used) TMyObject to your code, create it inside that loop you are doubting, then don't free it ! See if the report is consistent and reliable, with 11 leaked TMyObject. This might save time.
  7. Kas Ob.

    Undeclared identifier: '_CONTEXT'

    Cross your fingers and restart the IDE and.
  8. I posted about default language extension specially for the default value for fields and variables, but this completely will depend on compiler intervention, will of course to simplify and solidify the generated code and prevent cascade of malpractices and bugs.
  9. No, hold your horses here! Default is right with its own definition, there is no default value in Pascal/Delphi to begin with except nil and zero, asking Default to finalize what by might not be initialized is wrong and outside of its usage, Default can't every know what it is clearing, because this what should be called Clearing or Zeroing. Untill we have default value for declared fields and the compiler put these values when ever a field/variable used then Default should be used as zeroing only.
  10. That is one ugly big mess of a call stack, i can see these crucial point of events [794F1030]{rtl290.bpl } System.TMonitor.TryEnter (Line 20340, "System.pas" + 10) + $0 // there is no Exit but also no rentry for this one [794F0B50]{rtl290.bpl } System.TMonitor.Enter (Line 20001, "System.pas" + 4) + $2 [028AED7C]{vcl290.bpl } Vcl.Controls.TControl.Perform (Line 7698, "Vcl.Controls.pas" + 10) + $8 [028AD786]{vcl290.bpl } Vcl.Controls.TControl.SetVisible (Line 6724, "Vcl.Controls.pas" + 5) + $C [029F7D5D]{vcl290.bpl } Vcl.Forms.TCustomForm.SetVisible (Line 6143, "Vcl.Forms.pas" + 9) + $4 [029FE52E]{vcl290.bpl } Vcl.Forms.TCustomForm.Hide (Line 9721, "Vcl.Forms.pas" + 0) + $2 [029F67A3]{vcl290.bpl } Vcl.Forms.TCustomForm.BeforeDestruction (Line 5411, "Vcl.Forms.pas" + 6) + $14 [794F07B5]{rtl290.bpl } System.@BeforeDestruction (Line 19744, "System.pas" + 10) + $0 [029F67BA]{vcl290.bpl } Vcl.Forms.TCustomForm.Destroy (Line 5421, "Vcl.Forms.pas" + 0) + $6 [794F0084]{rtl290.bpl } System.TObject.Free (Line 18403, "System.pas" + 1) + $4 [7890B734]{coreide290.bpl} FileFind.TThreadSearch.KillSearchProgress (Line 399, "FileFind.pas" + 1) + $5 // TThreadSearch.KillSearchProgress ?!!! [79610026]{rtl290.bpl } System.Classes.CheckSynchronize (Line 16334, "System.Classes.pas" + 32) + $9 // not so much of evil here <-- [02A047A4]{vcl290.bpl } Vcl.Forms.TApplication.DoActionIdle (Line 13828, "Vcl.Forms.pas" + 3) + $13 [02A04992]{vcl290.bpl } Vcl.Forms.TApplication.Idle (Line 13897, "Vcl.Forms.pas" + 30) + $11 [02A03977]{vcl290.bpl } Vcl.Forms.TApplication.HandleMessage (Line 13312, "Vcl.Forms.pas" + 1) + $11 [02A03CA9]{vcl290.bpl } Vcl.Forms.TApplication.Run (Line 13451, "Vcl.Forms.pas" + 27) + $3 [005B8AD2]{bds.exe } bds.bds + $DE That TThreadSearch.KillSearchProgress is closing what ?!! , is it trying to killing/closing objects that own a CustomForm, yet these form is calling SetVisible, SetVisible in turn is Performing a Message event like call and locking the whole damn thing,.... And that is not it yet, here comes this part (gem) [7961477C]{rtl290.bpl } System.Classes.StdWndProc (Line 19085, "System.Classes.pas" + 9) + $2 [029FB6FD]{vcl290.bpl } Vcl.Forms.TCustomForm.SetWindowFocus (Line 8182, "Vcl.Forms.pas" + 10) + $8 [029FB828]{vcl290.bpl } Vcl.Forms.TCustomForm.SetActive (Line 8219, "Vcl.Forms.pas" + 12) + $3 [029FC712]{vcl290.bpl } Vcl.Forms.TCustomForm.WMActivate (Line 8695, "Vcl.Forms.pas" + 6) + $A [7891F7EC]{coreide290.bpl} MainWorkFrm.TMainWorkForm.WMActivate (Line 140, "MainWorkFrm.pas" + 0) + $0 [00578A30]{bds.exe } AppMain.TAppBuilder.WMActivate + $C [028AF146]{vcl290.bpl } Vcl.Controls.TControl.WndProc (Line 7920, "Vcl.Controls.pas" + 91) + $6 [029BC5BF]{vcl290.bpl } Vcl.Themes.TStyleManager.GetStyle (Line 5822, "Vcl.Themes.pas" + 7) + $D [794F1800]{rtl290.bpl } System.@TryFinallyExit (Line 23793, "System.pas" + 8) + $0 [029BC6AD]{vcl290.bpl } Vcl.Themes.TStyleManager.GetStyle (Line 5833, "Vcl.Themes.pas" + 18) + $1E Starts with GetStyle then again try to Activate the Main IDE Form Then comes a lot of stuff and hot mess, with many messages and code, then comes this gem which is shown on the stack 3 times [79579F09]{rtl290.bpl } System.SyncObjs.CoWaitForMultipleHandles (Line 716, "System.SyncObjs.pas" + 3) + $B [7957A1DD]{rtl290.bpl } System.SyncObjs.THandleObject.WaitForMultiple (Line 855, "System.SyncObjs.pas" + 14) + $18 [786C0D17]{coreide290.bpl} ParserThread.TParseThread.Lock (Line 398, "ParserThread.pas" + 12) + $15 [79610891]{rtl290.bpl } System.Classes.TThread.SetPriority (Line 16713, "System.Classes.pas" + 1) + $13 [786C0E36]{coreide290.bpl} ParserThread.TParseThread.CancelAndLock (Line 441, "ParserThread.pas" + 4) + $2 CancelAndLock is called, SetPriority then Lock then wait, why it is waiting ? and, on what is waiting ? and why it is recursive 3 times ? Who knows ! And that is not it, comes this part after first locking [794F0084]{rtl290.bpl } System.TObject.Free (Line 18403, "System.pas" + 1) + $4 [786DE822]{coreide290.bpl} ProjectGroup.TProjectGroupWrapper.Close (Line 2848, "ProjectGroup.pas" + 2) + $5 [00568245]{bds.exe } AppMain.TAppBuilder.DestroyProjectGroup + $1A9 [0056C0C8]{bds.exe } AppMain.TAppBuilder.WindowCloseQuery + $4CC .............. [786DE822]{coreide290.bpl} ProjectGroup.TProjectGroupWrapper.Close (Line 2848, "ProjectGroup.pas" + 2) + $5 [00568245]{bds.exe } AppMain.TAppBuilder.DestroyProjectGroup + $1A9 [0056C0C8]{bds.exe } AppMain.TAppBuilder.WindowCloseQuery + $4CC .............. [794F0084]{rtl290.bpl } System.TObject.Free (Line 18403, "System.pas" + 1) + $4 [7890D720]{coreide290.bpl} FileFind.TerminateFindInFiles (Line 1124, "FileFind.pas" + 2) + $5 [00568339]{bds.exe } AppMain.TAppBuilder.CanCloseProjectGroup + $59 [0056BCFC]{bds.exe } AppMain.TAppBuilder.WindowCloseQuery + $100 Finally we reach the end part [787830FB]{coreide290.bpl} ProjectModule.TBaseProject.PromptForSave (Line 1668, "ProjectModule.pas" + 1) + $1B [78784795]{coreide290.bpl} ProjectModule.TCustomProject.Save (Line 2093, "ProjectModule.pas" + 5) + $F [786DF5B3]{coreide290.bpl} ProjectGroup.TProjectGroupWrapper.GetCanCloseMiscProjects (Line 3116, "ProjectGroup.pas" + 12) + $8 [00568339]{bds.exe } AppMain.TAppBuilder.CanCloseProjectGroup + $59 [0056BD0E]{bds.exe } AppMain.TAppBuilder.WindowCloseQuery + $112 So yes the IDE is closed, and is trying to ask you by a prompt to save or not while checking of any lock, even after DestroyProjectGroup is called, it is trying to execute GetCanCloseMiscProjects... Simply put, it is a hot mess, yet it must me easy to find and fix, the looking for the culprit starts here TThreadSearch.KillSearchProgress and finding why is leading to close the IDE ? I can suggest few things to try : (for you of course) 1) I don't see any 3rd-party code involvement, so it is IDE bug, unless a hooked code involved without being exist in the stack call, which would be strange. 2) Theming and that change your IDE theme or disable it, i don't have any of these shiny new IDEs with shiny looking themes, so not sure what can be done here. 3) Go to administrative tools -> services and disable the Windows "Themes" service, it could have something to do with all of this bug and/or buggy skinning part of the code. 4) Where is the cursor when this happen, i mean what item in the IDE did have the focus when this happen, and does the text input cursor something to do with this ? This function is very strange here which called once : [02A09B70]{vcl290.bpl } Vcl.Forms.TScrollingStyleHook.WndProc (Line 16714, "Vcl.Forms.pas" + 0) + $0 For me it is like trying to scroll and update, i would double check why it is there to begin with, because after it the stack start to make no sense, thanks to ThemeEngine or what ever theming code called.
  11. Kas Ob.

    Sending message to previous instance

    1) Use ClassName instead of WindowName in FindWindow, more reliable as your main form title most likely is not "myVCLApplication", unless you are using this as example here, in all cases, use the class name, which is the Delphi class name for your main form, like TForm1 or TMyMainForm... 2) and yes find and send to the main window/form. 3) Don't use ShowWindow and SetForegroundWindow here , these should be on the receiving part, so this part of detect and send/post message, should be only post PostMessage, nothing more. When in doubt and for testing this, PostMessage should work locally form the same app, so test it in-place, if it does work then will work from any other application/process, to test it add timer with something like 10 second interval, then find the window and post this message to your main form, in other words, use the same code that you will use from another instances, minimize your application and see if it does receive and behave as you want.
  12. Kas Ob.

    Handling TCP send buffer overflow the right way

    You picked the one of the worst also outdated socket library, literally it is not installed by default in the IDE for many years, it is deprecated. You can't hit that messages limit easily, in fact i doubt that even possible if you tried to do so, to be able to hit that limit with socket messages would be an accomplishment. SOMAXCONN has nothing to do with max connection server can serve or connect, it is about backlog, how many sockets trying to connect at the same exact time (literally at the same millisecond or microsecond), the rest at this exact time will be dropped. You have many to pick from Indy, ICS, mORMot/mORMot2, RealThinClient, these are opensource
  13. The price you see after clicking buy is not for only for SIP, /nsoftware website only offer Red Carpet license, a license for everything in their products page https://www.nsoftware.com/subscriptions , for individual package you have to contact their sales, don't know now but they used to offer license with source code for individual library too.
  14. Kas Ob.

    Handling TCP send buffer overflow the right way

    Stupid me !, not confirming the negation, sorry for that, and you know.. what you can go with loop or without it, the difference is little and close to none, for any non very intensive socket usage like sending/receiving large data (like huge files) also i missed to point the need to remove ioctlsocket , even you are not asking for the available data, ReceiveBuf uselessly internally is doing it, this can be removed by using your own RecvData.
  15. Kas Ob.

    Handling TCP send buffer overflow the right way

    This is long story !, in short the answer is yes, loop is way better and will yield better throughput. The little longer one with a suggestion , There is very popular wrong practice of checking for the length of available data over socket then allocate a buffer then perform the receive (recv) on that buffer with the already (assumed) known length, this is waste of time ! i suggest to pre-allocate buffers for TCP, it could be 64kb (exactly 1024*64), or 16kb (any size will work but it is better to have a multiple of 4kb size and not less than 8kb), but it depends on how you expect you traffic speed, anyway.. with that allocated buffer just perform recv with the largest size your buffer can handle/fit, no need to check for available data length. Will work as expected and will squeeze speed and relax the network (vertically cascade) drivers (and TCP stack and provider) from this extra useless operation, operation that go into the kernel with afd driver then return empty handed, while you can recv as much as you can and it will not behave any different, on the contrary will give you all what is there to receive in one shot.
  16. Kas Ob.

    Handling TCP send buffer overflow the right way

    And one more thing as reminder, about socket send API https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send You always need to check the result of sent bytes, compare with your own data length, this is standard usage, but keep in mind if send sent part of the packet, this doesn't not mean that the next send for the rest will return fail with WSAEWOULDBLOCK, No, send can partially send for many other situations like busy/full locally or the network driver imposing interrupt moderation... and none of these situations does/should concern you, Just keep in mind unless send return SOCKET_ERROR and WSAEWOULDBLOCK is the WSAGetLastError, then you can safely try to send more, i always use loops. I saw this bad design that caused sluggishness in sending out of wrong assumptions !
  17. Kas Ob.

    Handling TCP send buffer overflow the right way

    Hi, Well, i have this feeling that you are hesitating to do the right out of fear of braking things, i suggest to stop looking at these part of code as fragile as glass vase. Remy brilliantly explained all what do you need to know, now step back to look to the big picture here, you need functionality out of these TClientSocket and TServerClient, they are nice but far from best or very practical design, so .. adjust them to your need and this is the whole point of OOP to begin with. Example, SendBuf do raise exceptions unless you suppress them by changing the ErrorCode in the event, do you need this functionality ? it is not a big deal, but why not add your own function like SendData which takes care of the buffer too, this will simplify the buffering, also if needed add your own events, add somting like buffering triggered to signal traffic congestion, slowness, not responding peer... utilize this in you GUI, nice to see colored stuff indicating connection status. If you see what is going inside SendBuf, all what is needed to extended or replace it with better version is two things 1) Dont forget to Lock then Unlock, accessible "ClientSocket1.Socket.Lock" .. 2) you have the SocketHandle to pass to "send" (the API), also accessible "ClientSocket1.Socket.SocketHandle" Extend them from outside, or if you prefer OOP then things way simpler. For your question about handling errors for Listen in TServerSocket, these are shortcoming in the design, try follow DoActivate logic, and i think you have all what you need to overload these functions with better and more suitable functionality. You can override TCustomWinSocket.Listen with your own, that raise exception in case your (added) event OnServerError is not assigned. In other words, have faith in your self, you got it ! I really suggest to stay away from this, as it is utilizing a threadvar, unless you really know what are you doing, you must know exactly when and who is accessing it, as you described it, can go messy very quick. Good luck and happy coding !
  18. Hi, From what i see, and i am guessing here, that exception is not from this code you pasted, but from one or two different places not shown here: One raised : EInvalidPointer : Invalid pointer operation The other raised EAccessViolation : Access violation at address 0047C27C in module 'VRMEditor.exe'. Read of address FFFFFFFx The second exception does look like managed type variable wrongly or unsafely accessed, in other words it was uninitialized yet there was something trying to access or may be just clean it up, or it could be overwritten on the stack and had corrupted value and the exception was triggered in the hidden part of "end;", (aka clean up) Try to extended logging within self.Log(... itself , there most likely your broken code, track memory corruption too.
  19. A small correction for this GPT answer: Not every local variable is allocated on the stack, so LObj could be on the stack, or due to optimization have a dedicated CPU register to use. In other words, LObj is either on the stack or in a register, but the result will be the same, the stack might hold data (Value) previously been written (or zero if the stack is never being reached before at this depth), and a register will have a Value from the last usage being from this procedure/function or a previous one. Delphi compiler is less optimized for this registers usage (optimization) for local variable then FPC and less than most other languages compilers, yet it does it sometimes.
  20. Alas, that is the case, and this is why when performance is the target i don't use any managed type, a small record with size, count and a pointer where the item[0] are reference to raw record, with a record helper to provide addition and deteletion. All memory manager i know including system Heap ones, do 16 bytes aligning, the problem in outdated and inefficient RTL managed types design, these should be updated, no memory manager can help with unaligned structure to begin with.
  21. Well that is possible, but it might be an unneeded extra work. What i meant is something like this Just include the batch file which can have relative path, also it can take a parameter for the output path, even the name of the output file. and from the dproj file <PropertyGroup Condition="'$(Base)'!=''"> <PostBuildEvent><![CDATA[BuildConst.bat $(PostBuildEvent)]]></PostBuildEvent> Also i did always prefer using the inc files in place for naming and versioning, over batch files, thus i have their content in the project and in the EXE description ...
  22. True for almost all cases but not all, there still some few edge cases. Another point, it will works for old and new CPU. Another point, it will help any new optimized memory copy functions to use the SIMD version without going through the first and unaligned 16 bytes, but for this it should be aligned to 16bytes to get the most of juice, meaning that record should be 32bytes.
  23. Something like this set filename=MyAppConsts.pas @echo on echo building %filename% @echo off (echo unit Unit1;& echo.& echo interface& echo.& echo const) > %filename% echo APPLICATION_APP_NAME = 'MyApp';>> %filename% echo APPLICATION_COMPANY_NAME = 'MyCompany';>> %filename% (echo.& echo implementation& echo.& echo end.) >> %filename% @echo on @echo done building %filename% #exit 0 the result a file "MyAppConsts.pas" unit Unit1; interface const APPLICATION_APP_NAME = 'MyApp'; APPLICATION_COMPANY_NAME = 'MyCompany'; implementation end. there is no earlier than that !
  24. Another thing, having a record with 17 bytes is little strange, and means you are using packed record, if you are tying to save some performance and minimize time used in copying, then let me assure you are doing the opposite. Remove the packed and/or make sure it is padded to multiple of 4 bytes, meaning 20 bytes should be your minimum, you might see better a little performance right away, even if it is very small it is better, or remove the packed modifier from the record and let the compiler align it for you, unless you are using and exchanging the same records between 32bit and 64bit version, in that case you see how the compiler did it, and replicate the padding yourself with the packed one.
  25. Even when that is the case, i mean allocate new and copy the content, FastMM has very nice algorithm to recycle the system allocated blocks, FastMM request and allocate chunks from OS, lets say we have 1 MB allocated, FastMM will slice it into smaller chunks and provide the application with requested sizes, when a requested size is not available, it will request another big check 1MB and repeat, the probability of you cause fragmentation is very low, as it only will happen with the 1MB(s) chunks, and to do this you will have to requested and not freed too many blocks (huge amount of small sizes) , then free have of them in specific order to cause, but when your lets say list will grow above certain size then FastMM will not utilize the sliced chunks, it will request new form the OS and free (return it to OS) it when done, hence no matter how you changed or resize your list or even tens/hundreds of them you will not be able to cause any memory fragmentation, nor memory access degradation, the performance will more or less stay the same. Relocating on single delete as Stefan pointed is a problem, so do as Dalija suggested or implement you own raw list which will perform relocate on delete, it is easy. One more thing, many thinks linked lists are good and fast, and they are but only when the items count reach something around 500k item. Another thing, if your list doesn't need to be ordered, then on delete move/copy the last item on top the deleted one and decrease the count, hence remove few overheads, in such case your list will need size (capacity) and count (actual items count), grow and resize only when count is equal to size, and never downsize !, the logic is simple here, this size needed once so it could be needed again.
×