Access violation on application close

Hi!

MQTT gives me errors upon closing the application. Not always, but lets say every 4-th closing.

The executed code is this

procedure TfrmMain.Closeform(Sender: TComponent);

begin
   ...
    Logger.Log(llInfo, 'Shuttng down MQTT client...');
    while mqttEasyClient.IsConnected do begin
      Application.ProcessMessages;
    end;
    Ptr(false);
    Logger.Log(llInfo, 'MQTT client closed');
    ...
end;

The waiting loop if my try to solve the exception :slight_smile:

MadExcept stack, if helps

> date/time          : 2020-11-25, 14:02:06, 317ms
> computer name      : 
> wts client name    : 
> user name          : 
> registered owner   : 
> operating system   : Windows 10 x64 build 17763
> system language    : Slovenian
> system up time     : 
> program up time    : 
> processors         : 8x Intel(R) Xeon(R) CPU E5-2680 0 @ 2.70GHz
> physical memory    : 10440/16376 MB (free/total)
> free disk space    : (C:) 2,53 GB
> display mode       : 3440x1440, 32 bit
> process id         : $4e8
> allocated memory   : 124,41 MB
> largest free block : 847,60 MB
> command line       : "Easy.exe"
> executable         : Easy.exe
> exec. date/time    : 2020-11-25 12:30
> version            : 2020.11.25.4
> compiled with      : Delphi 10.3 Rio
> madExcept version  : 5.1.0
> callstack crc      : $00000000, $00000000, $1fdf6966
> exception number   : 1
> exception class    : EInvalidPointer
> exception message  : Invalid pointer operation.
> 
> thread $354:
> >> stack not accessible, exception location:
> 0040a2dd +11 Easy.exe System 4773 +0 TObject.FreeInstance
> 
> thread $21c0 (TTMSMQTTKeepAliveThread):
> 778939d5 +45 KERNELBASE.dll                                    SleepEx
> 7789397a +0a KERNELBASE.dll                                    Sleep
> 0055a215 +01 Easy.exe       System.Classes                     TThread.Sleep
> 0156753d +29 Easy.exe       TMS.MQTT.Client.Threading  636 +11 TTMSMQTTWorkerThread.Execute
> 004bb8bf +2b Easy.exe       madExcept                          HookedTThreadExecute
> 00559489 +49 Easy.exe       System.Classes                     ThreadProc
> 0040c220 +28 Easy.exe       System                    4773  +0 ThreadWrapper
> 004bb7a5 +0d Easy.exe       madExcept                          CallThreadProcSafe
> 004bb80a +32 Easy.exe       madExcept                          ThreadExceptFrame
> 76750417 +17 KERNEL32.DLL                                      BaseThreadInitThunk
> >> created by thread $354 at:
> 0055954c +18 Easy.exe       System.Classes                     TThread.Create
> 
> thread $c3c (TTMSMQTTWriterThread):
> 778939d5 +45 KERNELBASE.dll                                    SleepEx
> 7789397a +0a KERNELBASE.dll                                    Sleep
> 0055a215 +01 Easy.exe       System.Classes                     TThread.Sleep
> 0156753d +29 Easy.exe       TMS.MQTT.Client.Threading  636 +11 TTMSMQTTWorkerThread.Execute
> 004bb8bf +2b Easy.exe       madExcept                          HookedTThreadExecute
> 00559489 +49 Easy.exe       System.Classes                     ThreadProc
> 0040c220 +28 Easy.exe       System                    4773  +0 ThreadWrapper
> 004bb7a5 +0d Easy.exe       madExcept                          CallThreadProcSafe
> 004bb80a +32 Easy.exe       madExcept                          ThreadExceptFrame
> 76750417 +17 KERNEL32.DLL                                      BaseThreadInitThunk
> >> created by thread $354 at:
> 0055954c +18 Easy.exe       System.Classes                     TThread.Create
> 
> thread $1374 (TTMSMQTTReaderThread):
> 778939d5 +45 KERNELBASE.dll                                    SleepEx
> 7789397a +0a KERNELBASE.dll                                    Sleep
> 0055a215 +01 Easy.exe       System.Classes                     TThread.Sleep
> 0156753d +29 Easy.exe       TMS.MQTT.Client.Threading  636 +11 TTMSMQTTWorkerThread.Execute
> 004bb8bf +2b Easy.exe       madExcept                          HookedTThreadExecute
> 00559489 +49 Easy.exe       System.Classes                     ThreadProc
> 0040c220 +28 Easy.exe       System                    4773  +0 ThreadWrapper
> 004bb7a5 +0d Easy.exe       madExcept                          CallThreadProcSafe
> 004bb80a +32 Easy.exe       madExcept                          ThreadExceptFrame
> 76750417 +17 KERNEL32.DLL                                      BaseThreadInitThunk
> >> created by thread $354 at:
> 0055954c +18 Easy.exe       System.Classes                     TThread.Create
> 
> thread $2698:
> 76750417 +17 KERNEL32.DLL  BaseThreadInitThunk
> 
> thread $323c:
> 76750417 +17 KERNEL32.DLL  BaseThreadInitThunk
> 
> thread $1c5c:
> 76750417 +17 KERNEL32.DLL  BaseThreadInitThunk
> 
> stack dump:
> >> internal error in GetStackDump:
> 004b5fd0 +114 Easy.exe madExcept +0 GetStackDump

Im'm stuck any suggestion would be appreciated :slight_smile:

Sorry, wrong topic - can you move it to MQTT..?

It is not clear what exactly you try to do here.
What is ptr(false)?
Is see nowhere a call to mqttEasyClient.Disconnect?

Ups, copy/paste mistake. Heres' the code I wanted you to see

    mqttEasyClient.Disconnect;   
    while mqttEasyClient.IsConnected do begin
      Application.ProcessMessages;  // This is my try to solve the problem - it's not working :)
    end;

It's called upon form closing (OnClose) and the result is that sometimes it generates the error in thread TTMSMQTTKeepAliveThread.

The component itself is configured like this

  object mqttEasyClient: TTMSMQTTClient
    OnConnectedStatusChanged = mqttEasyClientConnectedStatusChanged
    OnPublishReceived = mqttEasyClientPublishReceived
    OnSubscriptionAcknowledged = mqttEasyClientSubscriptionAcknowledged
    Version = '1.2.0.2'
    Left = 760
    Top = 281
  end

OnConnectedStatusChanged and OnSubscriptionAcknowledged methods:

procedure TfrmMain.mqttEasyClientConnectedStatusChanged(ASender: TObject; const AConnected: Boolean; AStatus: TTMSMQTTConnectionStatus);
var I: integer;
begin
  if not AConnected then begin
    Logger.Log(llInfo, 'MQTT: Disconnected from '+ AppSettings.Server.Mqtt.Host+':'+IntToStr(AppSettings.Server.Mqtt.Port));
  end else begin
    Logger.Log(llInfo, 'MQTT: Connected.');
    Logger.Log(llInfo, 'MQTT: subscribing to '+AppSettings.Server.Mqtt.Subscriptions.CommaText);

    for I := 0 to AppSettings.Server.Mqtt.Subscriptions.Count-1 do begin
      mqttEasyClient.Subscribe(AppSettings.Server.Mqtt.Subscriptions[I], qosExactlyOnce);

      if I=0 then
        MqttManager.DefaultTopic := AppSettings.Server.Mqtt.Subscriptions[0];
    end;
  end;

  case AStatus of
    csConnectionRejected_InvalidProtocolVersion,
    csConnectionRejected_InvalidIdentifier: Logger.Log(llError, 'MQTT: Failure: Invalid protocol or invalid indentifier');
    csConnectionRejected_ServerUnavailable: Logger.Log(llError, 'MQTT: Failure: Server unavailable');
    csConnectionRejected_InvalidCredentials: Logger.Log(llError, 'MQTT: Failure: Invalid credentials');
    csConnectionRejected_ClientNotAuthorized: begin
      Logger.Log(llError, 'MQTT: Failure: Not Authorised'); // the connection is rejected by broker
      barStatus.Panels[4].Text := ' Povezava v sporočilni sistem ni uspela - napačni prijavni podatki.';
    end;

    csConnectionLost: Logger.Log(llError, 'MQTT: Failure: connection lost'); // the connection with the broker is lost
    csConnecting: ;     // The client is trying to connect to the broker
    csReconnecting: ;   // The client is trying to reconnect to the broker
  end;
end;

procedure TfrmMain.mqttEasyClientSubscriptionAcknowledged(ASender: TObject;
  APacketID: Word; ASubscriptions: TTMSMQTTSubscriptions);
begin
  if ASubscriptions[0].Accepted then begin
    Logger.Log(llInfo, 'MQTT: Success subscribing to '+ASubscriptions[0].Topic);
  end;
end;

Could you isolate this and send us a sample source project with which we can reproduce?

I'll try to do it for tomorrow. I can't guarantee that it will be possible, because this is a little bigger project :)