22 Feb
Winning the debugging race

It is not clear why the debugger sometimes locks up at startup.

* a race condition between the IDE and the debugger for a resource ?

* an infinite loop in output message events ?

* a deadlock with threads ?

* The Antivirus ? 

no way to know for sure ... but since reducing CPU affinity helps, my favorite is #1. With only 1 CPU we a have a winner and no photo finish :)


EDIT : here is the thread that lead me to this solution, and indeed I have F-Secure AntiVirus.... https://stackoverflow.com/questions/51623474/delphi-10-2-3-hangs-when-starting-with-debugging-a-32-bit-application

Since then, I'm now in RIO 10.3 but F-secure did not fix the issue yet ... and disabling the AV is hardly a solution. Time to send a mail to F-secure, but in the meantime... let's try to code the affinity trick.


Okay, and what do we code now ? Hey, just set the affinity by code and we are good to go !

Let's try to create a package the IDE will load every time :

Create a new package and name it "CPUIAffinityPack", the dpk should look like this :

package CPUAffinityPack;

{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO OFF}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS OFF}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO OFF}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE RELEASE}
{$ENDIF IMPLICITBUILDING}
{$DESCRIPTION 'CPU Affinity Pack'}
{$DESIGNONLY}
{$IMPLICITBUILD ON}


requires
  rtl,
  vcl,
  designide;


contains
  Affinity in 'Affinity.pas';
end.

And add a new unit named "Affinity.pas" written like this ::

unit Affinity;


{$IFDEF SINGLE}
{$DESCRIPTION 'CPU Affinity Pack Single Core One'}
{$ENDIF}


interface


implementation


Uses
 Winapi.Windows, Winapi.Messages, ToolsAPI, System.SysUtils, System.Variants, System.Types, 
 System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, StrUtils, Math, Menus;


var
    p: word;
    cpus: string;
    affinity_mask: DWORD_PTR;
    c: TStringDynArray;


procedure SetAffinity(vMaskProcess: DWORD_PTR);
var
  vHandle: Cardinal;
begin
  vHandle := GetCurrentProcess;
  if not SetProcessAffinityMask(vHandle, vMaskProcess) then showmessage(sysErrorMessage(getLastError));
end;




procedure InitializeAffinity;
begin
{$IFDEF DEBUG}
  ShowMessage('Affinity package loaded');
{$ENDIF}




{$IFDEF SINGLE}
  cpus := '1';
{$ELSE}
  cpus := '';
{$ENDIF}
  for p := 1 to paramcount do
  begin
     if uppercase(copy(paramstr(p), 1, 10))='-AFFINITY:' then
     begin
        cpus := copy(paramstr(p), 11, length(paramstr(p))-10);
        break;
     end;
  end;


  if cpus<>'' then
  begin
{$IFDEF DEBUG}
     ShowMessage('Affinity '+cpus);
{$ENDIF}


     affinity_mask := 0;
     c := SplitString(cpus, ',');
     for p := low(c) to high(c) do
     begin
        if StrToIntDef(c[p], -1)>-1 then affinity_mask := affinity_mask or (1 shl StrToIntDef(c[p], 0));
     end;


     if affinity_mask>0 then SetAffinity(affinity_mask);


{$IFDEF DEBUG}
     ShowMessage('Affinity mask '+inttostr(affinity_mask));
{$ENDIF}


     SetLength(c, 0);
  end;
end;


initialization
  InitializeAffinity;
end.

Build and install the package.

Use the conditional defines SINGLE to force single core.

or edit the rad studio shortcut and add the new parameter -AFFINITY:1,3 to specify the cores number you want to activate (but leave only one if you want to fix the debugger issue)


Check affinity with the task manager 

Tada ! Enjoy !


Comments
* The email will not be published on the website.
I BUILT MY SITE FOR FREE USING