#1 2023-11-30 13:41:40

Wytze
Member
Registered: 2018-03-07
Posts: 6

Log error when starting a new thread after close several threads

Only with x86_64-linux (Delphi 7 and x86_64-win64 are ok)
TSynLog.GetThreadContextAndDisableExceptions gives runtime error 216 and stays in critical section. This locks the application.

procedure TSynLog.GetThreadContextAndDisableExceptions;
var
  id: TThreadID;
begin
  id := GetCurrentThreadId;
  // most of the time, the thread didn't change so this method is inlined
  if id <> fThreadID then <== values are equal, perhaps fThreadID needed a reset?
    // quickly switch fThreadContext/fThreadIndex to the new thread
    GetThreadContextInternal(PtrUInt(id))
  {$ifndef NOEXCEPTIONINTERCEPT}
  else
    fExceptionIgnoredBackup := fExceptionIgnoreThreadVar^;  <== here fExceptionIgnoreThreadVar is not assigned to ExceptionIgnorePerThread this gives runtime error 216
  // caller should always perform in its finally ... end block an eventual:
  // fExceptionIgnoreThreadVar^ := fExceptionIgnoredBackup;
  fExceptionIgnoreThreadVar^ := true;
  // any exception within logging process will be ignored from now on
  {$endif NOEXCEPTIONINTERCEPT}
end;


reproduction:

I use Postman (performance runner) to start a view threads then I wait for the threads to stop.
When I post a new request I get the error.

program TestLog;

{$MODE Delphi}
uses
  {$I mormot.uses.inc}
  classes,
  mormot.core.base,
  mormot.core.os,
  mormot.core.log,
  mormot.net.server,
  mormot.net.http;
type
  TTest = class
  private
    fServer: THttpServer;
    function Request(Ctxt: THttpServerRequestAbstract): cardinal;
    procedure Stop(Sender: TThread);
    procedure Start(Sender: TThread);
  end;

function TTest.Request(Ctxt: THttpServerRequestAbstract): cardinal;
begin
  TSynLog.Add.Log(sllTrace, 'Start request');
  Result := HTTP_SUCCESS;
  TSynLog.Add.Log(sllTrace, 'End request');
end;

procedure TTest.Stop(Sender: TThread);
begin
  TSynLog.Add.Log(sllTrace, 'End thread');
end;

procedure TTest.Start(Sender: TThread);
begin
  TSynLog.Add.Log(sllTrace, 'Start thread');
end;

begin
  with TSynLog.Family do
  begin
    Level := LOG_VERBOSE;
    EchoToConsole := LOG_VERBOSE;
    //PerThreadLog := ptIdentifiedInOneFile;
    //AutoFlushTimeOut := 10;
  end;
  with TTest.Create do
  try
    fServer := THttpServer.Create('8088', start, stop, '', 0);
    fServer.WaitStarted();
    fServer.OnRequest := Request;
    writeln('Server is now running');
    ConsoleWaitForEnterKey;
  finally
    Free;
  end;
end.

Offline

#2 2023-11-30 15:57:02

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,238
Website

Re: Log error when starting a new thread after close several threads

Thanks a lot for the detailed report.

Please try with
https://github.com/synopse/mORMot2/commit/491822ba

Offline

#3 2023-12-01 14:25:39

Wytze
Member
Registered: 2018-03-07
Posts: 6

Re: Log error when starting a new thread after close several threads

Thanks for the great support.

At first the supplied reproduction still did not work.
Because NotifyThreadEnded was never called (setting TTest.Stop overrules the default behaviour?).
So I added it to TTest.Stop and now it works fine.

procedure TTest.Stop(Sender: TThread);
begin
  TSynLog.Add.Log(sllTrace, 'End thread');
  TSynLog.Add.NotifyThreadEnded;
end;

Offline

#4 2023-12-01 15:30:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,238
Website

Re: Log error when starting a new thread after close several threads

This is why
- inheriting from TLoggedThread
or
- using TLoggedWorkThread.Create() with a method
could be a good idea, instead of using a plain TThread.

Offline

Board footer

Powered by FluxBB