#1 2013-11-26 00:35:27

richard6688
Member
Registered: 2011-04-05
Posts: 31

OCI AV when OracleConnection free

I just test Orcale DB access. I found AV when db free. I use XE/Ora 11g. Here is a simple code.

var fProps: TSQLDBOracleConnectionProperties;
_sql: RAWUTF8;
Rows: ISQLDBRows;
begin
  fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage(fOraTNS,
    fOraUser, fOraPass,0);
  fProps.ForcedSchemaName:= fOraUser;
  try
    _sql:='select * from dual';
    Rows:= fProps.Execute(_sql,[],nil) ;
    With Rows Do
    While Step Do
    Begin 
      Memo1.Lines.Add(ColumnString(0));
    End; 
    Rows:=nil;
  finally
    fProps.Free;
  end;

After  fProps.Free ,  AV of OCI in TSQLDBOracleStatement.FreeHandles was fired.

folowing code also have AV problem

  fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage(fOraTNS,
    fOraUser, fOraPass,0);
  fProps.ForcedSchemaName:= fOraUser;
  try
    _sql:='select * from dual where rownum=?';
    With fProps.Execute(_sql,[1],nil) Do
    While Step Do
    Begin 
      Memo1.Lines.Add(ColumnString(0));
    End; 
  finally
    fProps.Free;
  end;

But the strange thing is  Execute() function, the following code works no problem.

  try
    _sql:='select * from dual where rownum=?';
    Rows:= fProps.Execute(_sql,[1],nil) ;
    With Rows Do
    While Step Do
    Begin 
      Memo1.Lines.Add(ColumnString(0));
    End; 
    Rows:=nil;
  finally
    fProps.Free;
  end;

the param there or empty is differ.

Is there something I missed or a bug?

Last edited by richard6688 (2013-11-26 00:38:17)

Offline

#2 2013-11-26 07:07:10

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

Re: OCI AV when OracleConnection free

I do not have Oracle here since end of this week to reproduce it.

Please debug your code, checking how interfaces memory are handled.
Use the CPU view to check the context - perhaps your Rows := nil is not enough in some cases.
Or at least use F7 to step by step and find WHERE the AV occurs, in which stack trace.
Your statement is certainly released after the fProps is freed.

Offline

#3 2013-11-26 07:36:01

richard6688
Member
Registered: 2011-04-05
Posts: 31

Re: OCI AV when OracleConnection free

Thanks for your replay.

I do debug the code, I think the problem is cache used. AV code found at

  if fStatement<>nil then begin
    if fUseServerSideStatementCache then
      OCI.Check(OCI.StmtRelease(fStatement,fError,nil,0,OCI_DEFAULT),fError) else
      OCI.HandleFree(fStatement,OCI_HTYPE_STMT);

usecache property seems readonly, so cannot change
maybe , I will wait you to reproduce the error.

Last edited by richard6688 (2013-11-26 07:36:27)

Offline

#4 2013-12-04 02:11:40

richard6688
Member
Registered: 2011-04-05
Posts: 31

Re: OCI AV when OracleConnection free

after digging code, this error is not related to mORMot but delphi XE compiler. following is delphi code generated:

smain.pas.47: Rows:= fProps.Execute(_sql,[],nil);
0056BBA6 6AFF             push $ff
0056BBA8 6A00             push $00
0056BBAA 8D45E4           lea eax,[ebp-$1c]
0056BBAD 50               push eax
0056BBAE 8D4DE4           lea ecx,[ebp-$1c]
0056BBB1 8B55F4           mov edx,[ebp-$0c]
0056BBB4 8B45F8           mov eax,[ebp-$08]
0056BBB7 E89C96FEFF       call TSQLDBConnectionProperties.Execute
0056BBBC 8B55E4           mov edx,[ebp-$1c]
0056BBBF 8D45F0           lea eax,[ebp-$10]
0056BBC2 E861EFE9FF       call @IntfCopy
0056BBC7 EB24             jmp $0056bbed
--------------------------------------------------------
smain.pas.47: Rows:= fProps.Execute(_sql,[1],nil);
0056BBA3 6A00             push $00
0056BBA5 6A00             push $00
0056BBA7 8D45F0           lea eax,[ebp-$10]
0056BBAA 50               push eax
0056BBAB C745E001000000   mov [ebp-$20],$00000001
0056BBB2 C645E400         mov byte ptr [ebp-$1c],$00
0056BBB6 8D4DE0           lea ecx,[ebp-$20]
0056BBB9 8B55F4           mov edx,[ebp-$0c]
0056BBBC 8B45F8           mov eax,[ebp-$08]
0056BBBF E89496FEFF       call TSQLDBConnectionProperties.Execute
0056BBC4 EB24             jmp $0056bbea

call fProps.Execute with no parameter in open array will make ISQLDBRows interface refcount increase 1, which will result a AV.
anyone has experient about this? how to resolve?

any feedback is welcome?

Offline

#5 2013-12-04 14:12:08

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

Re: OCI AV when OracleConnection free

This is just some weird behavior of the Delphi compiler automatic reference counting of interfaces.

In fact, Delphi creates an hidden local ISQLDBRows interface variable, which is copied to Rows, and is still there after fProps.Free...

procedure TForm1.btn1Click(Sender: TObject);
var Rows: ISQLDBRows;
    LocalVariable: ISQLDBRows;  // code generated by the compiler
begin
  fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage('OCTB',
    'MIS', 'mis',0);
  LocalVariable := fProps.Execute('select * from dual',[],nil);
  Rows := LocalVariable; // code generated by the compiler
  while Rows.Step do
    mmo1.Lines.Add(Rows.ColumnUTF8(0));
  Rows := nil; // but LocalVariable is still set!
  fProps.Free; // release the statement
  LocalVariable := nil; // code generated by the compiler -> here AV since the statement is already released!!!
end;

There is no known workaround, unless we change the fProps.Execute() from one function into a procedure with an var/out parameter....
No so convenient.

Usual code is the following:

procedure TForm1.FormCreate(Sender: TObject);
begin
  fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage('tnsname',
    'username', 'password',0);
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
  with fProps.Execute('select * from dual',[],nil) do
  while Step do
    mmo1.Lines.Add(ColumnString(0));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  fProps.Free;
end;

There is no problem.

You should always use a share fProps instance in your application.
Individual connections will then be handled by the SynDB* classes.
The same fProps instance can be used between all threads, without any problem.

Offline

#6 2013-12-04 23:50:42

richard6688
Member
Registered: 2011-04-05
Posts: 31

Re: OCI AV when OracleConnection free

Thank you for your kind reply.

To konw such weird behavior, we can avoid similar situation. for mORMot, we have many solution here. using TSQLDBStatement, or do that as the code you show.

Anyway, Thank you again.

Offline

Board footer

Powered by FluxBB