Recent

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

440bx

  • Hero Member
  • *****
  • Posts: 1897
Re: Is there any way to name my threads for debugging?
« Reply #60 on: April 10, 2020, 05:09:32 pm »
We are talking about the NameThreadForDebugging method.  <snip> ... cause thread variables aren't that easily accessed from the debugger (I don't even know if FPC generates correct debug information for them).
Thank you.  I appreciate the clarification.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Bi0T1N

  • New Member
  • *
  • Posts: 33
Re: Is there any way to name my threads for debugging?
« Reply #61 on: April 10, 2020, 08:09:37 pm »
As I said, compiles and works fine with Free Pascal Compiler version 3.3.1-r44644 [2020/04/08] for x86_64. Also no need to add Windows unit.
So I guess your compiling 32-bit?
Sorry, I missed about 3.3.1.
Of course 64 bit
Test with fpc 3.3.1 64bit, rev.44675. In Lazarus 2.1.0 rev 62926 and outside it.
1. Run app from console:
<snip>
2. Run from IDE. Gdb 7.3.50.
<snip>
I wait about 15 seconds, the threads window shows only one thread without a name. After that, the program terminates itself with a similar heap trace.
1. It should also work with older FPC versions (read 3.0.4) if you do the typecast PascalDragon mentioned.
2. The console output just gives some extra infos but the threadnames can only be seen in a debugger which supports threadnames by MS_VC_EXCEPTION. I've used x64dbg as debugger to verify the method for older Windows on my Win10 system.
3. You need at least gdb 8.0 or newer as mentioned before. Older versions doesn't support the exception type from point 2)
4. Not sure what Lazarus shows in its thread window but normally it shouldn't support it (at least not through gdb with your version)
5. It's a PoC so I didn't really paid attention if everything is freed correctly.
« Last Edit: April 10, 2020, 08:14:29 pm by Bi0T1N »

ASerge

  • Hero Member
  • *****
  • Posts: 1618
Re: Is there any way to name my threads for debugging?
« Reply #62 on: April 10, 2020, 11:17:51 pm »
1. It should also work with older FPC versions (read 3.0.4) if you do the typecast PascalDragon mentioned.
2. The console output just gives some extra infos but the threadnames can only be seen in a debugger which supports threadnames by MS_VC_EXCEPTION. I've used x64dbg as debugger to verify the method for older Windows on my Win10 system.
3. You need at least gdb 8.0 or newer as mentioned before. Older versions doesn't support the exception type from point 2)
4. Not sure what Lazarus shows in its thread window but normally it shouldn't support it (at least not through gdb with your version)
5. It's a PoC so I didn't really paid attention if everything is freed correctly.
1. Oddly enough, I check and you don't. Not compiled in 3.0.4. without Windows.
2. Cast will not help, THandle is 64 bit, but the parameter is DWORD. I checked - the value is really more than 32 bits.
3. I only use the debugger that comes with the latest official version of Lazarus. And of course, in the context of the Lazarus forum, it is unusual to discuss that this is not appropriate for it.
4. The heap trace shows that the release is incorrect.
5. Under the debugger, the program does not work at all.

PascalDragon

  • Hero Member
  • *****
  • Posts: 1768
  • Compiler Developer
Re: Is there any way to name my threads for debugging?
« Reply #63 on: April 11, 2020, 02:36:50 pm »
1. Oddly enough, I check and you don't. Not compiled in 3.0.4. without Windows.
2. Cast will not help, THandle is 64 bit, but the parameter is DWORD. I checked - the value is really more than 32 bits.

The parameter is a TThreadID, not a THandle. And a thread ID is a DWORD, even on 64-bit Windows (see the result of GetThreadID. That's why it was changed in FPC 3.2.

ASerge

  • Hero Member
  • *****
  • Posts: 1618
Re: Is there any way to name my threads for debugging?
« Reply #64 on: April 11, 2020, 03:02:39 pm »
The parameter is a TThreadID, not a THandle. And a thread ID is a DWORD, even on 64-bit Windows (see the result of GetThreadID. That's why it was changed in FPC 3.2.
I was talking about an example. It is explicitly defined in lines 64-69:
Code: Pascal  [Select][+][-]
  1. type
  2.   THREADNAME_INFO = record
  3.     dwType: DWord; // Must be 0x1000.
  4.     szName: PAnsiChar; // Pointer to name (in user addr space).
  5.     dwThreadID: DWord; // Thread ID (-1=caller thread).   <--------------- this DWORD
  6.     dwFlags: DWord; // Reserved for future use, must be zero.
  7.   end;

The NameThreadForDebuggingTest does not test AThreadId = -1 (the default value for the 64 bit parameter) for old Windows, which is what causes RunError 201 to be called when the application starts.

PascalDragon

  • Hero Member
  • *****
  • Posts: 1768
  • Compiler Developer
Re: Is there any way to name my threads for debugging?
« Reply #65 on: April 11, 2020, 06:57:04 pm »
I just tested the example from here with 3.0.4 on Win64. The only change I did was to disable the loading of SetThreadDescription (because I'm on Windows 10). Otherwise it compiled without error (even the assignment of aThreadID to dwThreadID) and when run in WinDBG I correctly saw the names even for the one that used the default parameter for the main thread.

Bi0T1N

  • New Member
  • *
  • Posts: 33
Re: Is there any way to name my threads for debugging?
« Reply #66 on: April 11, 2020, 07:14:51 pm »
I've noticed that the threads disappear after the exception is raised so following change seems appropriate
Code: Pascal  [Select][+][-]
  1.       RaiseException(MS_VC_EXCEPTION, 0, SizeOf(thrdinfo) div SizeOf(DWord), @thrdinfo);
to
Code: Pascal  [Select][+][-]
  1.           try
  2.             RaiseException(MS_VC_EXCEPTION, 0, SizeOf(thrdinfo) div SizeOf(DWord), @thrdinfo);
  3.           except
  4.           end;
and the threads remain running. Attached a screenshot of x64dbg which show that it is working fine.
Trying to bring it into the compiler now ;D

ASerge

  • Hero Member
  • *****
  • Posts: 1618
Re: Is there any way to name my threads for debugging?
« Reply #67 on: April 11, 2020, 07:49:37 pm »
I just tested the example from here with 3.0.4 on Win64. The only change I did was to disable the loading of SetThreadDescription (because I'm on Windows 10). Otherwise it compiled without error (even the assignment of aThreadID to dwThreadID) and when run in WinDBG I correctly saw the names even for the one that used the default parameter for the main thread.
I get example from last Bi0T1N message with code.
1. Get code as is
Code: [Select]
fpc project1.lpr
Free Pascal Compiler version 3.0.4 [2019/10/27] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling project1.lpr
project1.lpr(119,51) Error: Identifier not found "GetProcAddress"
project1.lpr(145,4) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: ....\lazarus64\fpc\3.0.4\bin\x86_64-win64\ppcx64.exe returned an err or exitcode

2. Add windows to uses:
Code: [Select]
d:\Users\Serge\Documents\FPC Projects\Test\DebugName>fpc project1.lpr -g -Cirot
Free Pascal Compiler version 3.0.4 [2019/10/27] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling project1.lpr
Linking project1.exe
144 lines compiled, 0.2 sec, 161328 bytes code, 6596 bytes data

3. An application running in the console does not show a RunError(201) because it overflows silently. But in Lazarus (2.0.6) it is shown under the debugger (gdb). This can be considered debugger behavior, but I agree with this-the variable is explicitly truncated, although this is not critical in a specific case.

PascalDragon

  • Hero Member
  • *****
  • Posts: 1768
  • Compiler Developer
Re: Is there any way to name my threads for debugging?
« Reply #68 on: April 11, 2020, 10:03:22 pm »
2. Add windows to uses:
Code: [Select]
d:\Users\Serge\Documents\FPC Projects\Test\DebugName>fpc project1.lpr -g -Cirot

Ah, you enabled range checking... As Bi0T1N wrote his code is a proof of concept as such enabling checks can be unwise. That said changing the assignment to dwThread to from aThreadID to DWord(aThread) solves the range check error (and with 3.2 that won't be necessary anyway).

 

TinyPortal © 2005-2018