Skip to content

Instantly share code, notes, and snippets.

@pavelmash
Created January 4, 2019 18:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pavelmash/fa61a01f2e890873a1dd80a18f459d42 to your computer and use it in GitHub Desktop.
Save pavelmash/fa61a01f2e890873a1dd80a18f459d42 to your computer and use it in GitHub Desktop.
Gist to reproduce a AV in SynDBOra
program SynDBOarAV;
{$I Synopse.inc} // without Synopse.inc strange compiler error on line FHttpServer.OnRequest := DoOnRequest
{$define USESYN}
uses
{.$I SynDprUses.inc} // with SynDprUses AV exists
// cmem, // with cmem AV exists
cthreads,
SynCrtSock,
SynDB,
{$ifdef USESYN}SynDBOracle{$ELSE}SynDBZeos{$ENDIF};
type
{ TubSQLDBOracleConnectionProperties }
TConnectionManager = class({$ifdef USESYN}TSQLDBOracleConnectionProperties{$else}TSQLDBZEOSConnectionProperties{$endif})
public
function NewConnection: TSQLDBConnection; override;
end;
{ TmySevice }
TmySevice = class
private
FHttpServer: THttpServer;
FConnectionManager: TConnectionManager;
protected
function DoOnRequest(Ctxt: THttpServerRequest): cardinal;
public
constructor Create;
destructor Destroy; override;
end;
{ TConnectionManager }
function TConnectionManager.NewConnection: TSQLDBConnection;
var fakeVarJustToBeAllocatedInStack: byte; // if I comment out this var (change a stack) AV disappear
begin
//for SynDBOracle:
// -O1 optimization: AV inside TSQLDBOracleConnection.Connect during call to EnvNlsCreate (but in real project works);
// -O2 optimization: work as expected (but in real project AV);
// - works for ZEOS, but I think only because of var... inside TZOracleConnection.Open
Result:=inherited NewConnection;
end;
{ TmySevice }
constructor TmySevice.Create;
begin
inherited Create();
{$ifdef USESYN}
FConnectionManager := TConnectionManager.Create('doesn''t matter', '', '', '');
{$else}
FConnectionManager := TConnectionManager.Create('zdbc:oracle:(doesn''t matter)?LibLocation=libclntsh.so', '', '', '');
{$endif}
FHttpServer := THttpServer.Create('8881', nil, nil,{HttpThreadTerminate,} 'Server', 2, 0);
FHttpServer.OnRequest := DoOnRequest;
end;
destructor TmySevice.Destroy;
begin
FHttpServer.Free;
FConnectionManager.Destroy;
inherited Destroy;
end;
function TmySevice.DoOnRequest(Ctxt: THttpServerRequest): cardinal;
var
conn: TSQLDBConnection;
begin
conn := FConnectionManager.ThreadSafeConnection;
conn.Connect;
Result := 200;
end;
begin
with TmySevice.Create() do try
// works in case called from main thread
// DoOnRequest(nil);
HttpGet('http://localhost:8881/init', nil); // call itself to create DB connection inside thread
writeln('press Enter to stop');
readln;
finally
Free;
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment