Hello,

I'm getting a segmentation fault for a FreePascal program,
that connects to a FB 2.5 database inside a thread.
The segmentation fault just occurs, when there is a
Firebird exception caught inside the thread.

The example code below should illustrate the situation.

There are no problems on Windows, nor on Linux when using
a 2.1 client library, the fault just happens for Linux and the 2.5 client.

I posted the error first on the fpc-devel list, where they told me that
this should be an error in the Firebird client dll:
http://www.mail-archive.com/[email protected]/msg24051.html

To avoid this problem, I now connect to the FB 2.5 database with the old 2.1 
client.
Is this safe, assuming that every thread uses its own connection?

<code>
program fbthreadtest;
{$IFDEF FPC}
   {$MODE DELPHI}{$H+}
{$ENDIF}

{$APPTYPE CONSOLE}

uses
   {$IFDEF UNIX}
   cthreads,
   cwstring,
   {$ENDIF}
   Classes,
   IBConnection, sqldb;

type
   TFBThread = class(TThread)
   private
   protected
     procedure Execute; override;
   public
     constructor Create;
   end;

constructor TFBThread.Create;
begin
   inherited Create(True);
   FreeOnTerminate := False;
   Resume;
end;

procedure TFBThread.Execute;
var
   db: TIBConnection;
   tr: TSQLTransaction;
   q: TSQLQuery;
begin
   db := TIBConnection.Create(nil);
   try
     db.DatabaseName := 'localhost:/home/data/Database/ssstst.gdb';
     db.LoginPrompt := False;
     db.HostName := '';
     db.UserName := 'SYSDBA';
     db.Password := 'masterkey';
     db.Connected := TRUE;
     tr := TSQLTransaction.Create(nil);
     try
       tr.DataBase := db;
       tr.Action   := caCommit;
       tr.Params.Clear;
       tr.Params.Add('isc_tpb_read_committed');
       tr.Params.Add('isc_tpb_rec_version');
       tr.Params.Add('isc_tpb_nowait');
       db.Transaction := tr;
       tr.Active := True;
       q := TSQLQuery.Create(nil);
       try
         q.Database    := db;
         q.Transaction := tr;

         try
           Writeln('select...');
           // the following line raises an exception because rdb$databases
doesn't exist.
           q.SQL.Text := 'select count(*) from rdb$databases';
           q.Prepare;
         except
           Writeln('...exception');
         end;
       finally
         q.Free;
       end;
     finally
       tr.Commit;
       tr.Free;
     end;
   finally
     db.Connected := False;
     db.Free;
   end;
end;

begin
   with TFBThread.Create do begin
     WaitFor;
     Free;
   end;
end.
</code>


Thanks,

Stefan

Reply via email to