Ryno Coetzee
Ryno Coetzee

Reputation: 517

TTask[n] EThreadNameException

Experts, take the following code snippet below:

var
  aAllTasks : Array [0..1] of ITask  //global private var

Procedure SetImage();
begin

  //..      
  //.. Get a URL of an image stored on a server     
  //..

  aAllTasks[0] := TTask.Run(
    Procedure
    begin
      // Download the Image and display the image
    end);

  aAllTasks[1] := TTask.Run(
    Procedure
    begin
      // Get the rating of the image from a REST server
    end);

end;

when the debugger hits

      aAllTasks[1] := TTask.Run(...);

I get

First chance exception at $001A30B5. Exception class EThreadNameException with message ''. Process APPNAME (126391)

It throws the exception but it does not seem to crash the App

This only happens when debugging/running iOS apps
iOS 9.2
RS 10 Seattle (with Update 1)
PA server 17.0 (with hotfix.. V 8.0.1.52)
Xcode version 7.2 (7C68)

What would cause this and how would I fix it?

Upvotes: 1

Views: 353

Answers (1)

David Heffernan
David Heffernan

Reputation: 613192

Your code calls, TThread.NameThreadForDebugging. That looks like this:

class procedure TThread.NameThreadForDebugging(AThreadName: string; AThreadID: TThreadID);
{$IF Defined(MSWINDOWS)}
.... // windows specific code removed
{$ELSE MSWINDOWS}
const
  cExceptionMessage = 'Type=$1000,Name=%s,ThreadID=%d,Flags=0';
  EMBDBKPRESENTNAME = 'EMB_DBK_PRESENT';
{$IF Defined(MACOS)}
  OLDEMBDBKPRESENTNAME = 'EMB_MACOSX_DBK_PRESENT';                                                                             
{$ENDIF}
begin
{$IF Defined(MACOS)}
  if (getenv(EMBDBKPRESENTNAME) <> nil) or (getenv(OLDEMBDBKPRESENTNAME) <> nil) then
{$ELSEIF Defined(ANDROID)}
  if (System.DebugHook <> 0) or (getenv(EMBDBKPRESENTNAME) <> nil) then
{$ELSE}
  if (getenv(EMBDBKPRESENTNAME) <> nil) then
{$ENDIF}
  begin
    try
      raise EThreadNameException.Create(
        Format(cExceptionMessage, [AThreadName, AThreadID]));
    except
    end;
  end;
end;
{$ENDIF !MSWINDOWS}

This function is called when you wish to give your thread a name. Now, thread objects do not have names. So when you give your thread a name, it is for debugging purposes only. The debugger keeps track of the names you provide, and associates them with thread IDs. Then when the debugger presents information about threads, it can look up the name from the ID and present that to you. But this is purely a debugger mechanism because the operating system does not support thread names.

So, how do you signal to the debugger that you wish to give a thread a name. Well, you throw a specific exception. The debugger is aware of the exception and gets the first chance to handle the exception. The debugger receives the name and the thread ID in the exception text and makes a note of that information.

Notice that the exception is swallowed immediately and so this does not interrupt the flow of the program.

So, it is normal for this exception to be raised, to be handled by the debugger, and not to impact on the behaviour of the program. What is odd is that the debugger is breaking on that exception. I would have expected that exception to be ignored by the debugger, by default.

An old QC report (QC#105310) for OSX describes exactly the behaviour that you are observing. That issue was closed and marked as fixed in XE7. Perhaps this issue has re-surfaced, or perhaps it was never fixed for the mobile platforms. I suggest that you submit a bug report to Quality Portal.

Upvotes: 3

Related Questions