Registration disabled at the moment Read more...
×


hukmac
Members-
Content Count
10 -
Joined
-
Last visited
-
Days Won
1
Everything posted by hukmac
-
Hello! 🙂 I'm working in Delphi 12.1 CE (patch 1) @Win10 22H2. For many weeks Delphi IDE was running fine, but today it sudenly started showing message "Debugger Assertion Failure "" in pcntrlsrv.cpp at line 449" (in 64bit mode). I reverted changes in my project to the state in which this was not happening previously but this was not helpful. The exe of my app is being built properly and when run outside IDE it behaves correctly. But there is no possibility to run the code inside IDE with debugger (both in debug and in release mode IDE shows the above message). "Run without debugging" works fine, debugging in 32 bit mode also works fine. Do you have any ideas what can be the reason for such behaviour and how to make the IDE/debugger to work properly in 64 bit mode again ? Restart of IDE, switching target, release/debug modes, erasing all dcus and restarting OS was not helpful. Remark: I have found that similar problems were reported in the past but I found nothing about my failure (https://martinvirgil.wordpress.com/2012/09/05/delphi-assertion-failure-using-windows-7-64bit/)
-
D12.1: Debugger Assertion Failure in pcntrlsrv.cpp
hukmac replied to hukmac's topic in Delphi IDE and APIs
Thank you for the idea. No antivirus/security in the system except the Win built-in one. But I will investigate it. Update: Some Win Defender rules were related to the Embarcadero Debugger Kernel (pointing to: \embarcadero\studio\23.0\bin\dbkw64_29_0.exe). I set those rules to allow all activity and additionally added new rules for this program to allow all connections. Unfortunately, this didn’t solve the problem. Other things that didn't help: - excluding \Embarcadero\Studio\23.0\ dir from real time protection, - switching off the Win Defender completely, - memory integrity protection/ core isolation setting set to off, - running IDE with Admin priviledges. Additionally, in the Event Viewer the following entry can be seen at the time of unsuccessful run of debugger in 64bit mode: Faulting application name: dbkw64_29_0.exe, version: 290.2109.10.30909, timestamp: 0x62896680 Faulting module name: KERNELBASE.dll, version: 10.0.19041.6157, timestamp: 0x817d6404 Exception code: 0x0000192f Fault offset: 0x0000000000025369 Faulting process ID: 0x33e4 Faulting application start time: 0x01dc0dee21c41406 Faulting application path: C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\dbkw64_29_0.exe Faulting module path: C:\Windows\System32\KERNELBASE.dll The problem appeared just before or just after (I'm not 100% sure) the installation of this Win update: https://support.microsoft.com/pl-pl/topic/12-sierpnia-2025-r-kb5063709-kompilacje-systemu-operacyjnego-19044-6216-i-19045-6216-96d99cf6-f8b5-4798-9892-4e3eb8f11548 Success 🙂 Uninstalling this kb5063709 system update fixed the problem (OS restart required) - now 64 bit debugger of Delphi 12.1 CE works fine. I hope this will be helpful to someone. 🙂 Related debugger app crash report is attached. report.wer -
D12.1: Debugger Assertion Failure in pcntrlsrv.cpp
hukmac replied to hukmac's topic in Delphi IDE and APIs
Update: I have done additional check - created new project (one form, one button). Unfortunately behaviour is exactly as described above. So it is not related with the project. Any ideas how to fix it? Have anyone had such an issue and maybe fixed it by reinstalling IDE? -
Hello 🙂I have the following code in Delphi12, with slow functions PerformCalculations and SaveDataToDisk: function MutexBarrier(resource_mutex_id :String) :THandle; var Mutex :THandle; begin Mutex:=CreateMutex(nil,false,PChar(resource_mutex_id)); WaitForSingleObject(Mutex,INFINITE); result:=Mutex; end; procedure Main; //process main code (N processes are being run): var mutex :THandle; begin repeat mutex:=MutexBarrier('Mutex1_constant_unique_name'); try Prepare; finally ReleaseMutex(mutex); CloseHandle(mutex); end; PerformCalculations; mutex:=MutexBarrier('Mutex2_constant_unique_name'); try SaveDataToDisk; finally ReleaseMutex(mutex); CloseHandle(mutex); end; until False; end; I'm running N processes with this code, each on separate core (set with affinity, the number of cores > N). Processes do not create additional threads. Processes are run by a separate script like "proc.exe -core=x", where x is the expected affinity. Affinity is set correctly. But the effect of usage of mutexes is strange: 1. Initially all N processes quickly create queue on Mutex1, go through it one after another and then in parallel they are performing calculations on separate cores. 2. Then all N processes start to wait on Mutex2, and one of them (lets name it Process A) gets to the critical section of Mutex2. This is ok. 3. Then the process A which passed critical section of Mutex2 is going through Mutex1 and is performing calculations. At the same time all other processes still wait on Mutex1. - this is strange. 4. Only when process A finishes calculations and enters Mutex2 queue then some other process (name it process B) is entering the critical section of Mutex2. - This is very strange to me. 5. Then process B goes through Mutex1 and performs calculations., etc. In the effect, starting from point 3 only one process is performing calculations at a time. This is very strange to me. Why Mutex2 behaves like that. It is Win10. Remark 1: When SaveDataToDisk is fast (or not called at all - empty critical section of Mutex2), the problem is not happening - and all processes execute PerformCalculations in parallel. Remark 2: I have also verified that Prepare, PerformCalculations and SaveDataToDisk are not failing. I'm searching how to make Mutex2 to behave like expected, but no success till now. Maybe someone has some idea?
-
Strange problem with mutexes
hukmac replied to hukmac's topic in Algorithms, Data Structures and Class Design
OK, so... I have checked that the above has nothing to do with hyperthreading. I have also revisited my observations. Somehow earlier I assumed that the time of single PerformCalculation is at least twice the time of executing SaveDataToDisk - it was the opposite. Thus, the observed behaviour is expected. SaveDataToDisk is a real bottleneck. Processes are entering Mutex2 critical section as fast as possible and nothing strange is with Mutex2. When I artificially increased the time of PerformCalculation to be 10 times the SaveDataToDisk, it nicely performs SaveDataToDisk during PerformCalculation on other cores - and PerformCalculation in all processes uses almost 100% time of the CPU. I will check if I can speed up the SaveDataToDisk. In the example I'm working with each 3s calculation creates 800MB of data to save. Saving this takes ~7s. I'm working on Samsung EVO 970 Plus with 3300MB/s write speed so there is room for improvement. Thank you Remy for making me thinking. -
Strange problem with mutexes
hukmac replied to hukmac's topic in Algorithms, Data Structures and Class Design
Dear Remy, thank you for your question and proposed code. So here I go with the answer and clarification. > Why are you creating and destroying the mutexes over and over? First reason: the situation presented above is a simplification (I thought it will be more clear to present the problem in this form). In my real code, for important reasons, each process is performing calculations and writing results only specified number of times (so the above Main loop would not be infinite). When the work is done then the process creates its child process assigned to the same core and self-terminates. Thus at the end of the process the mutex handle would be closed by the OS anyway. To make things clear I'm doing it manually. Second reason: The named mutex in the OS will exist till at least one handle to it will exist in any of the processes. So while the Mutex2 queue is not empty the mutex is not destroyed by the OS. It is created just once and opened many times by processes if/as the queue is formed. If given queue is emptied the mutex will be destroyed. But creation/destruction of the mutex by the OS is not costly, especially in comparison with the time cores need to spend in crtical sections (in Mutex2 - many seconds). So in my case the problematic Mutex2 - as its queue is almost always full of waiting processes - is in fact created once and not destroyed till the last process is destroyed. And only local handles to the mutex are created/destroyed as processes are hitting/passing the barrier. The problem is that the Mutex2 queue is not working as expected: none of processes waiting in Mutex2 is entering Mutex2 critical section till the last process which was in this critical section - or its child process - will hit this barrier again. Expected behaviour is: when process A leaves the Mutex2 critical section and starts doing other things, some other process waiting in Mutex2 enters its critical section (even if process A is calculating), etc. Is this mutex improperly created or some Win10 mechanism needs additional configuration to make it working as expected? Second thought: my CPU is i9-9900K in a hyperthreading mode - can the problem be related with the hyperthreading? If process A is assigned to logical core 0 and next process in a Mutex2 queue (name it B) is assigned to the logical core 1 (both logical cores 0 and 1 are simulated by the same SMT unit - physical core 0), then: if process A is leaving Mutex2 critical section and starts calculating faster than process B will get to Mutex2 critical section, then maybe OS will not like to switch the context of the physical core 0 (simulating hyperthreading cores 0 and 1) and will not release process B to critical section - and none of other waiting processes which are lower in the queue. I will switch off hyperthreading and check it. -
Hello 🙂 At the beginning: thanks to all of you for many very informative discussions on this forum. When working in D7 in most cases Ctrl+F1 was the right answer to most problems. But now I'm more and more frequently saved by the info provided by members of Delphi-PRAXiS 🙂 And now my actual pain: I'm using Delphi 11 CE ver 28.0. While working with quite simple code I have encountered two strange, fully reproducible problems. The description and related code are below. Additionally all the details and both problems are presented within a short video: https://drive.google.com/file/d/147uSLerfnu-3DZME1jHQ8nsnlAdqtNRi (the code is compiled without optimization). Maybe someone wise can shed some light on the sources of those problems and how to get rid of them (excluding "Embarcadero" problem) ? All the best! --------- >>> The example task: The square matrix TConfusionMatrix = array[0..x,0..x] of Extended is created in two ways (please see the code below): - with primitive functions such as Cmtx33() or Cmtx22() which place the right values in the right cells of the matrix, or - by splitting string representation of the matrix (with function MtxStr2ConfusionMatrix). Example string representation of the 3x3 matrix is: '[0,1,2, 3,4,5, 6,7,8]' (rows concatenation, spaces and brackets do not matter). Created matrices should represent structure "array of rows" and oboth methods should fill the matrix in the same way. For example, if cmtx and cmtx2 are of TConfusionMatrix type then after calls: MtxStr2ConfusionMatrix('[43,0,1,0,45,0,2,0,44]', cmtx, class_cnt); cmtx2:=Cmtx33(43,0,1,0,45,0,2,0,44); variables cmtx and cmtx2 should include the same values in the same elements of matrices (among those which were modified by both functions). Additionally class_cnt will include the size of the row/column of the matrix (in this example class_cnt will be equal 3). It is assumed that strings representing the matrix will always have correct structure and that will include the right number of elements to create a square matrix (so we do not need to think about such things here). >>> Encountered problems: 1.) The first problem ("the inspection problem"): Depending on the order of calls to MtxStr2ConfusionMatrix() and Cmtx33() the results of the former function differ. Sometimes after the call of MtxStr2ConfusionMatrix() the created matrix is displayed in inspection window as it would be (improperly) transposed. But after next call of Cmtx33() the matrix set by MtxStr2ConfusionMatrix() starts to look properly. Further comparison of matrices created with both functions indicate that they are equal and related code execution reacts accordingly. 2.) The second problem ("the wtf problem"): But sometimes - for exactly the same data - the matrix being the result of MtxStr2ConfusionMatrix() permanently stays improperly transposed and the matrices created with both methods are recognised as different. Then this breaks the logic of the code. I'm blind or something but I can't see any obvious reason for such behaviour. Results from primitive functions Cmtx33(), Cmtx22() are always correct and presented properly. ---------- >>> The code: const MAX_CLASSES = 50; type TConfusionMatrix = array[0..MAX_CLASSES,0..MAX_CLASSES] of Extended; //transforms square matrix in the form of string to a table of rows; //cmtx_str = '[0,1,2,3,4,5,6,7,8]' => [[0,1,2][3,4,5][6,7,8]] //(row and column of index=0 are left for other purposes) function MtxStr2ConfusionMatrix(cmtx_str :String; var cmtx :TConfusionMatrix; var class_cnt :Word) :Boolean; var i,j :Word; splittedString : TStringDynArray; res :Boolean; begin res:=True; try RemoveChar(cmtx_str,' '); RemoveChar(cmtx_str,'['); RemoveChar(cmtx_str,']'); class_cnt:=0; splittedString:=SplitString(cmtx_str, ','); if Length(splittedString)<4 then res:=False else begin if Frac(Sqrt(Length(splittedString)))<0.01 then class_cnt:=Round(Sqrt(Length(splittedString))) else res:=False; end; if class_cnt>=2 then begin EraseConfusionMatrix(cmtx,class_cnt,MAX_CLASSES,0); for i:=1 to class_cnt do for j:=1 to class_cnt do cmtx[i,j]:= StrToFloat(splittedString[i+(j-1)*class_cnt - 1]); end; except res:=False; end; result:=res; end; function CompareConfusionMatrices(c1,c2 :TConfusionMatrix; class_cnt :Word) :Boolean; var i,j :Integer; ok :Boolean; begin ok:=True; for i:=1 to class_cnt do for j:=1 to class_cnt do if c1[i,j]<>c2[i,j] then begin ok:=False; break; end; result:=ok; end; function Cmtx33(c11,c12,c13,c21,c22,c23,c31,c32,c33 :LongInt) :TConfusionMatrix; begin cmtx[1,1]:=c11; cmtx[1,2]:=c12; cmtx[1,3]:=c13; cmtx[2,1]:=c21; cmtx[2,2]:=c22; cmtx[2,3]:=c23; cmtx[3,1]:=c31; cmtx[3,2]:=c32; cmtx[3,3]:=c33; result:=cmtx; end; function Cmtx22(c11,c12,c21,c22 :LongInt) :TConfusionMatrix; begin cmtx[1,1]:=c11; cmtx[1,2]:=c12; cmtx[2,1]:=c21; cmtx[2,2]:=c22; result:=cmtx; end; procedure RemoveChar(var s :String; ch :Char); var d :String; i,ls :LongInt; begin d:=''; ls:=Length(s); i:=1; for i:=1 to ls do if s[i]<>ch then d:=d+s[i]; s:=d; end; procedure EraseConfusionMatrix(var cmtx :TConfusionMatrix; num_classes, max_classes :Word; value :Integer); var i,j :Word; begin if num_classes<=max_classes then begin for i:=0 to num_classes do for j:=0 to num_classes do cmtx[i,j]:=value; end else ShowMessage('Confusion Matrix can not be greater than '+IntToStr(max_classes)+'x'+IntToStr(max_classes)); end; ===EOT===
-
Dear Peter Below. Thank you for pointing out the usage of global cmtx variable in cmtx22/cmtx33 functions. I need to check, but most probably this is the cause of at least part of the observed problem. I was blinded by the spaghetti 🙂 Btw. The way of data representation and the fact that the code is almost fully procedural (no OOP) is here by purpose - to achieve very high speed of computation - and the result is more than good. This includes also usage of global variables in some cases. The price: much higher cost of maintenance and the related pain.
-
Dear Anders Melander. Thank you for your time developing map2pdb project. In my case it works great with Delphi 11 Community Edition and VTune 2024.0.1. It is a very useful tool 🙂
-
Dear Uwe Raabe, I just found your great software MMX - and downloaded version 13.03 (I'm still working with Delphi7 and WinXP). The software looks great. Thank you for your work and long support for Delphi 7. I think I will discover the usefulness of MMX with pleasure :) Best regards, Maciej