Subject | Segmentation fault in FreePascal program when using 2.5.x client library on Linux |
---|---|
Author | Stefan Sinne |
Post date | 2011-10-27T16:53:53Z |
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/fpc-devel@.../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
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/fpc-devel@.../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