* * *

Author Topic: Is there any way to name my threads for debugging?  (Read 5865 times)

avra

  • Hero Member
  • *****
  • Posts: 1251
    • Additional info
Is there any way to name my threads for debugging?
« on: May 25, 2016, 11:45:59 am »
I have tried to do it Delphi way but unfortunately this is not possible yet. According to http://www.freepascal.org/docs-html/rtl/classes/tthread.namethreadfordebugging.html it seams that NameThreadForDebugging() "is not implemented for any FPC platform and is supported for Delphi compatibility only". Is there any other way to name my threads so that I can see their names in debugger? Right now I just care for Win32.
ct2laz - Easily convert components and projects between Lazarus and CodeTyphon

GetMem

  • Hero Member
  • *****
  • Posts: 2750
Re: Is there any way to name my threads for debugging?
« Reply #1 on: May 25, 2016, 12:11:20 pm »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1891
Re: Is there any way to name my threads for debugging?
« Reply #2 on: May 25, 2016, 03:28:46 pm »
I'm wondering if something like this could be achieved via using "threadvars" with using a variable (of shortstring type?) to stored the name and inspecting the value of the variable during the debugging. Should be a cross-platform solution :)
« Last Edit: May 25, 2016, 03:30:51 pm by skalogryz »

avra

  • Hero Member
  • *****
  • Posts: 1251
    • Additional info
Re: Is there any way to name my threads for debugging?
« Reply #3 on: June 07, 2016, 02:31:57 pm »
Perhaps this: http://stackoverflow.com/a/9090608
Unfortunately not. MS_VC_EXCEPTION is raised and app ends, but thread name is not updated in threads debug window. Just tested on WinXP SP3 with CT 5.7.
ct2laz - Easily convert components and projects between Lazarus and CodeTyphon

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6016
Re: Is there any way to name my threads for debugging?
« Reply #4 on: June 07, 2016, 02:37:25 pm »
Try recompiling FPC with -dTEST_WIN32_SEH

Pascal

  • Hero Member
  • *****
  • Posts: 589
Re: Is there any way to name my threads for debugging?
« Reply #5 on: January 08, 2018, 02:30:13 pm »
This does not seem to work for win64/x86_64. Any hint to set the names for the thread window?

I use this code to set the name in the Execute procedure:
Code: Pascal  [Select]
  1. procedure NameThreadForDebugging(const pName: String);
  2.   type
  3.     TThreadNameInfo =
  4.       record
  5.         RecType: LongWord;
  6.         Name: PAnsiChar;
  7.         ThreadID: LongWord;
  8.         Flags: LongWord;
  9.       end;
  10. var
  11.     info:TThreadNameInfo;
  12.     AnsiName: AnsiString;
  13.  
  14. begin
  15.     AnsiName:= pName;
  16.     info.RecType := $1000;
  17.     info.Name := PAnsiChar(AnsiName);
  18.     info.ThreadID := $FFFFFFFF;
  19.     info.Flags := 0;
  20.     try
  21.         RaiseException($406D1388, 0,
  22.         SizeOf(info) div SizeOf(LongWord), PDWord(@info));
  23.     except
  24.     end;
  25. end;
« Last Edit: January 08, 2018, 03:12:09 pm by Pascal »
laz trunk - fpc trunk 32bit - Windows 10 Pro x64

Thaddy

  • Hero Member
  • *****
  • Posts: 5387
Re: Is there any way to name my threads for debugging?
« Reply #6 on: January 08, 2018, 04:07:05 pm »
Try recompiling FPC with -dTEST_WIN32_SEH
does not matter: not implemented.
Code: Pascal  [Select]
  1. {$ifdef THREADNAME_IS_ANSISTRING}
  2. { the platform implements the AnsiString variant and the UnicodeString variant
  3.   simply calls the AnsiString variant }
  4. class procedure TThread.NameThreadForDebugging(aThreadName: UnicodeString; aThreadID: TThreadID);
  5. begin
  6.   NameThreadForDebugging(AnsiString(aThreadName), aThreadID);
  7. end;
  8.  
  9.   {$ifndef HAS_TTHREAD_NAMETHREADFORDEBUGGING}
  10. class procedure TThread.NameThreadForDebugging(aThreadName: AnsiString; aThreadID: TThreadID);
  11. begin
  12.   { empty }
  13. end;
  14.   {$endif}
  15. {$else}
  16.   {$ifndef HAS_TTHREAD_NAMETHREADFORDEBUGGING}
  17. { the platform implements the UnicodeString variant and the AnsiString variant
  18.   simply calls the UnicodeString variant }
  19. class procedure TThread.NameThreadForDebugging(aThreadName: UnicodeString; aThreadID: TThreadID);
  20. begin
  21.   { empty }
  22. end;
  23.   {$endif}
  24.  
  25.  
  26. class procedure TThread.NameThreadForDebugging(aThreadName: AnsiString; aThreadID: TThreadID);
  27. begin
  28.   NameThreadForDebugging(UnicodeString(aThreadName), aThreadID);
  29. end;
  30. {$endif}

At least on Windows, iit should not be too diificult:
https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
or better:
https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
« Last Edit: January 08, 2018, 04:12:07 pm by Thaddy »
High(Methusalem) - 1;

Pascal

  • Hero Member
  • *****
  • Posts: 589
Re: Is there any way to name my threads for debugging?
« Reply #7 on: January 08, 2018, 04:20:26 pm »
At least on Windows, iit should not be too diificult:
https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
or better:
https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
That's what i did. Don't get confused by the Name i used. I used a procedure in an common unit and und used unit name to reference.
Code: Pascal  [Select]
  1. myunit.NameThreadForDebugging('myname');
laz trunk - fpc trunk 32bit - Windows 10 Pro x64

Thaddy

  • Hero Member
  • *****
  • Posts: 5387
Re: Is there any way to name my threads for debugging?
« Reply #8 on: January 08, 2018, 04:38:02 pm »
At least on Windows, iit should not be too diificult:
https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
or better:
https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
That's what i did. Don't get confused by the Name i used. I used a procedure in an common unit and und used unit name to reference.
Code: Pascal  [Select]
  1. myunit.NameThreadForDebugging('myname');

<Ok, grumpy,  >:D >:D> you are not paying attention:
The implementation for this is missing in the RTL:
This is the relevant part if you analyze codeflow:
Code: Pascal  [Select]
  1. class procedure TThread.NameThreadForDebugging(aThreadName: UnicodeString; aThreadID: TThreadID);
  2. begin
  3.   { empty }
  4. end;

You you can call what you like: nothing happens.
High(Methusalem) - 1;

Pascal

  • Hero Member
  • *****
  • Posts: 589
Re: Is there any way to name my threads for debugging?
« Reply #9 on: January 08, 2018, 06:17:46 pm »
At least on Windows, iit should not be too diificult:
https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
or better:
https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
That's what i did. Don't get confused by the Name i used. I used a procedure in an common unit and und used unit name to reference.
Code: Pascal  [Select]
  1. myunit.NameThreadForDebugging('myname');

<Ok, grumpy,  >:D >:D> you are not paying attention:
The implementation for this is missing in the RTL:
This is the relevant part if you analyze codeflow:
Code: Pascal  [Select]
  1. class procedure TThread.NameThreadForDebugging(aThreadName: UnicodeString; aThreadID: TThreadID);
  2. begin
  3.   { empty }
  4. end;

You you can call what you like: nothing happens.

Sorry, Thaddy, in this case you didn't pay attention to my original post. I didn't call the procedure you mentioned. I called my own, which just has the same name!
laz trunk - fpc trunk 32bit - Windows 10 Pro x64

Pascal

  • Hero Member
  • *****
  • Posts: 589
Re: Is there any way to name my threads for debugging?
« Reply #10 on: January 09, 2018, 12:38:00 pm »
If i understand the Microsoft documentaion aright, this is only a hack to pass the name to the debugger.
Is GDB aware of this special exception? Has anyone manged to get this working?
laz trunk - fpc trunk 32bit - Windows 10 Pro x64

Thaddy

  • Hero Member
  • *****
  • Posts: 5387
Re: Is there any way to name my threads for debugging?
« Reply #11 on: January 09, 2018, 12:59:07 pm »
The pragma is simply the same as {$PUSH} {$ALIGN 8} The record {$POP}. SEH expects 8 byte alignment for the records.
Of course it works.
And of course only on windows.
« Last Edit: January 09, 2018, 01:01:31 pm by Thaddy »
High(Methusalem) - 1;

Pascal

  • Hero Member
  • *****
  • Posts: 589
Re: Is there any way to name my threads for debugging?
« Reply #12 on: January 09, 2018, 01:51:25 pm »
Sorry, i didn't get it working:

Here is the procedure i use in the threads execute method:
Code: Pascal  [Select]
  1. {$PUSH} {$ALIGN 8}
  2. procedure NameThreadForDebugging(const pName: String);
  3.  type
  4.   TThreadNameInfo = record
  5.     RecType: LongWord;
  6.     Name: PAnsiChar;
  7.     ThreadID: LongWord;
  8.     Flags: LongWord;
  9.   end;
  10. var
  11.   info:TThreadNameInfo;
  12.   AnsiName: AnsiString;
  13. begin
  14.   AnsiName:= pName;
  15.   info.RecType := $1000;
  16.   info.Name := PAnsiChar(AnsiName);
  17.   info.ThreadID := $FFFFFFFF;
  18.   info.Flags := 0;
  19.   try
  20.       RaiseException($406D1388, 0,
  21.       SizeOf(info) div SizeOf(LongWord), LPDWORD(@info));
  22.   except
  23.   end;
  24.   DebugLn('NameThreadForDebugging(''' + pName + ''')');
  25. end;
  26. {$POP}  

gdb 8.0.1 x86_64
fpc is compiled with OPT="-gl -dTEST_WIN32_SEH"
laz trunk - fpc trunk 32bit - Windows 10 Pro x64

Thaddy

  • Hero Member
  • *****
  • Posts: 5387
Re: Is there any way to name my threads for debugging?
« Reply #13 on: January 09, 2018, 04:16:04 pm »
That's because the translation is incorrect. I don't have my code ready here, but this should come close:
- It needs to be a member of a TThread derived class
- You can't allocate nor define the record inside the procedure, it needs to be on the heap (global) and not on the stack (local) anyway
= You should use stdcall
- You should use PWideChar (the routine calls the widechar version anyway as per MSDN)
- You should copy in the Pwidechar, not assign the pointer.

AND this need SEH enabled for your complete FPC build (*everything* full fpc build, full library build) and I seem to remember I also protected the WideChar with a critical section, although that should not be necessary.
At least w/o being able to test this is much closer.
I'll give the proper code later.
First get this outside the procedure:
 type
{$push}{align 8}
  TThreadNameInfo = record
    RecType: LongWord;
    Name: PAnsiChar;
    ThreadID: LongWord;
    Flags: LongWord;
  end;
{$pop}

Note it was not an easy task to get it to work.
« Last Edit: January 09, 2018, 04:31:55 pm by Thaddy »
High(Methusalem) - 1;

Pascal

  • Hero Member
  • *****
  • Posts: 589
Re: Is there any way to name my threads for debugging?
« Reply #14 on: January 09, 2018, 08:50:21 pm »
According compiler\options.pas SEH is used by default for x86_64/win64 and it only has to be enabled for i386_win32:
Code: Pascal  [Select]
  1. {$ifndef DISABLE_WIN64_SEH}
  2.     if target_info.system=system_x86_64_win64 then
  3.       def_system_macro('FPC_USE_WIN64_SEH');
  4. {$endif DISABLE_WIN64_SEH}
  5.  
  6. {$ifdef TEST_WIN32_SEH}
  7.     if target_info.system=system_i386_win32 then
  8.       def_system_macro('FPC_USE_WIN32_SEH');
  9. {$endif TEST_WIN32_SEH}

Is it possible that this only works for i386/win32?
laz trunk - fpc trunk 32bit - Windows 10 Pro x64

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus