SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

The offical for ZeosLib 7.3 Report problems, ask for help, post proposals for the new version of Zeoslib 7.3/v8
Quick Info:
-We made two new drivers: odbc(raw and unicode version) and oledb
-GUID domain/field-defined support for FB
-extended error infos of Firebird
-performance ups are still in queue
In future some more feature will arrive, so stay tuned and don't hassitate to help
Post Reply
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello All,
I am facing a random access violation (program exits silently or after showing "Access violation") after running Query.Refresh
What is embarrassing most is that I failed to reproduce it with a minimal program.
It occurs in file 'source\dbc\ZDbcCache.pas' at line

Code: Select all

function TZRowAccessor.GetInt(ColumnIndex: Integer; out IsNull: Boolean): Integer;
var
  Data: PPointer;
  PW: PWideChar;
  PA: PAnsiChar absolute PW;
  Len: NativeUint;
begin
{$IFNDEF DISABLE_CHECKING}
  CheckColumnConvertion(ColumnIndex, stInteger);
{$ENDIF}
  Result := 0;
  {$R-}
  -----> if FBuffer.Columns[FColumnOffsets[ColumnIndex{$IFNDEF GENERIC_INDEX} - 1{$ENDIF}]] = bIsNotNull then begin 
The query is similar to:

Code: Select all

SELECT id,name FROM foo WHERE name IN (SELECT label FROM bar);
Then I call Query.Refresh programmatically, which gives either segmentation fault, or silent program exit, or just does the refresh.

Any help could be appreciated.
Thank you.
  • RDBM: Postgres 14
  • OS: Windows 11
  • IDE: CT 7.7
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by marsupilami »

Hello universe ;)

this somehow seems strangely familiar to me. Are you sure, you are using the latest revision of Zeos 8.0 (not trunk/master) from SVN or GIT?

Best regards,

Jan
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello,
The version is packed with Codetyphon 7.7 and is marked 8.0.0 alpha.
I will check repository, ask in CT forum, then report back.
Thank you.
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by marsupilami »

universe wrote: 16.08.2022, 12:00 The version is packed with Codetyphon 7.7 and is marked 8.0.0 alpha.
Hmmm - I am not sure, if we ever changed to beta. But we definitly have no control over the things Code Typhoon does. We don't support it. Our suggestion is to use plain Lazarus and FPC in their stable versions.
universe wrote: 16.08.2022, 12:00 I will check repository, ask in CT forum, then report back.
I suggest you uninstall Zeos from CT, get the current 8.0 version from SVN or GIT and install it.
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello,
The bad new I have the replaced all source files by those in https://github.com/frones/ZeosLib/tree/8.0-patches but the problem remains.
The good news I have reproduced the issue :) .
1. Open a ZQuery with

Code: Select all

select * from foo where name = 'test'
which must returns data.
2. Delete all data for this condition, or just truncate the table.
3. Call refresh
4. SIGSEGV raised @ GetBlob, GetPAnsiChar etc. Depending on field types returned by SELECT statement.
PS: When I call

Code: Select all

Query.Close;
Query.Open;
all goes fine.
If you could give me some hints to investigate more?
Thank you.
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello, It seems I made someone upset here :wink: ,
Well this time I get the files from https://sourceforge.net/p/zeoslib/code- ... 0-patches/ marked r7860, no mistake.
But I still have the error.

Meanwhile I am still struggling and trying to resolve the issue.
Thanks for your time.
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello,
I did a small "optimization"

Code: Select all

ColumnOffset := FColumnOffsets[ColumnIndex{$IFNDEF GENERIC_INDEX} - 1{$ENDIF}]
to locate witch array is generating the access violation, as follows,

Code: Select all

function TZRowAccessor.GetInt(ColumnIndex: Integer; out IsNull: Boolean): Integer;
var
  Data: PPointer;
  PW: PWideChar;
  PA: PAnsiChar absolute PW;
  Len: NativeUint;
  ColumnOffset: integer;
begin
{$IFNDEF DISABLE_CHECKING}
  CheckColumnConvertion(ColumnIndex, stInteger);
{$ENDIF}
  Result := 0;
  {$R-}
  ColumnOffset := FColumnOffsets[ColumnIndex{$IFNDEF GENERIC_INDEX} - 1{$ENDIF}];
  if FBuffer.Columns[ColumnOffset] = bIsNotNull then begin
    Data := @FBuffer.Columns[ColumnOffset + 1]; 
And I got "Cannot read address 0x09" hint for FBuffer.Columns, while ColumnOffset is equla to zero.
Fr0sT
Zeos Dev Team
Zeos Dev Team
Posts: 280
Joined: 08.05.2014, 12:08

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by Fr0sT »

From what you discovered, I suspect the buffer is being accessed when it's actually empty because of empty dataset
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello,
Thanks for your reply.
I have started a new whole project which contains two ZQueries linked to the same table, in one I insert and delete and the other I refresh in-between, and it works.
The problem is related to my project, what is strange the "Access violation" is raised only when the dataset is empty. And there is no special thing in there, only that it's a bigger application.
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

universe wrote: 18.08.2022, 21:40 And there is no special thing in there, only that it's a bigger application.
No, there is a difference, (which was working previously with ZeosLib 7.2), that I am sending the query as parameter, after removing it the problem was solved.
Is the issue related to the assign method in ZeosLib 8.0?
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by marsupilami »

universe wrote: 17.08.2022, 18:03 Hello, It seems I made someone upset here :wink: ,
Why?
Fr0sT wrote: 18.08.2022, 08:34 From what you discovered, I suspect the buffer is being accessed when it's actually empty because of empty dataset
True. Zeos 7.2 had a row buffer in this case whereas Zeos 8 didn't. This lead to an access violation.

The problem should be fixed in the latest revision of Zeos 8 and Zeos trunk / master.
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello,
marsupilami wrote: 20.08.2022, 09:32 Why?
No, just because you didn't reply in time :)
Fr0sT wrote: 18.08.2022, 08:34 From what you discovered, I suspect the buffer is being accessed when it's actually empty because of empty dataset
Yes, and even after changing the function I used in my main program (sending statement instead of query), it worked for sometime now the Access violation is back.
What is strange is that Length(FBuffer) is always reporting 32769 even when it's nil.
marsupilami wrote: 20.08.2022, 09:32 True. Zeos 7.2 had a row buffer in this case whereas Zeos 8 didn't. This lead to an access violation.

The problem should be fixed in the latest revision of Zeos 8 and Zeos trunk / master.
I hope so, I added nil check for all

Code: Select all

if FBuffer.Columns[FColumnOffsets[ColumnIndex{$IFNDEF GENERIC_INDEX} - 1{$ENDIF}]] = bIsNotNull then begin 
with

Code: Select all

if (FBuffer<>nil) and (FBuffer.Columns[FColumnOffsets[ColumnIndex{$IFNDEF GENERIC_INDEX} - 1{$ENDIF}]] = bIsNotNull) then begin
Except for GetBlob

Code: Select all

  IsNull := (FBuffer=nil) or (FBuffer.Columns[FColumnOffsets[ColumnIndex]] = bIsNull);    
Now for time being it's working.
Still, I am testing the program.
Thank you all.
universe
Fresh Boarder
Fresh Boarder
Posts: 10
Joined: 14.08.2022, 06:58

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by universe »

Hello,
The "nill" check fixed the issue.
Thanks.
gustavototta
Fresh Boarder
Fresh Boarder
Posts: 9
Joined: 02.02.2023, 20:28

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by gustavototta »

Hi, how i can fix this issue?

I replace the lines according to your statement in my "ZDbcCache.pas", but access violation still occurs.

Could you help me, please?

Thank you!
gustavototta
Fresh Boarder
Fresh Boarder
Posts: 9
Joined: 02.02.2023, 20:28

Re: SIGSEGV in TZRowAccessor.GetInt after calling Query.Refresh

Post by gustavototta »

Hello, can you help me fix this issue?

I replace the lines according to your statement in my file "ZDbcCache.pas", but access violation still occurs. Could you help me, please?

Thank you!
You do not have the required permissions to view the files attached to this post.
Post Reply