Page 1 of 1

Possible issue with Oracle, 64bit and stBigDecimal

Posted: 17.01.2024, 16:57
by MJFShark
I've included a console program below which when run in 64bit should cause an "A memory block footer has been corrupted." message. This seems to happen with bigdecimals and 64bit. I'm using FastMM5 to test for issues. I haven't been able to detect the source of the issue but data's being written past an allocation as a result of setting the bigdecimal bind variable.

Code: Select all

program ZeosOracleTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  FastMM5,
  System.SysUtils,
  ZConnection,
  ZDataset;

var
  ZConn: TZConnection;
  ZQuery: TZQuery;
begin
  FastMM_EnterDebugMode;
  try
    ZConn := TZConnection.Create(nil);
    try
      ZConn.Protocol := 'Oracle';
      ZConn.User := 'MARK';
      ZConn.Password := 'MARKSPW';
      ZConn.Database := 'mydbalias';
      {$IFDEF WIN64}
        ZConn.LibraryLocation := 'C:\U\DbClients\Oracle\21.8\64Bit\oci.dll';
      {$ELSE}
        ZConn.LibraryLocation := 'C:\U\DbClients\Oracle\21.8\32Bit\oci.dll';
      {$ENDIF}
      ZConn.Connect;
      // ZConn.ExecuteDirect('drop table otest');
      // ZConn.ExecuteDirect('create table otest (id number(38))');
      ZConn.ExecuteDirect('delete from otest');
      ZQuery := TZQuery.Create(nil);
      try
        ZQuery.Connection := ZConn;
        ZQuery.SQL.Text := 'select id from otest';
        ZQuery.Open;
        ZQuery.Insert;
        ZQuery.Fields[0].Value := 1;
        ZQuery.Post;
        ZQuery.Close;
      finally
        ZQuery.Free;
      end;
      ZConn.Disconnect;
    finally
      ZConn.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Write('Press Enter to quit...');
  ReadLn;
  FastMM_ExitDebugMode;
end.
The text of the error message:
A memory block footer has been corrupted.
The block size is 22.

The block was allocated by thread 0x1804, and the stack trace (return addresses) at the time was:
0000000000238EDA [FastMM5.pas][FastMM5][_ZN7Fastmm532FastMM_DebugGetMem_GetDebugBlockExb][7818]
0000000000238F95 [FastMM5.pas][FastMM5][_ZN7Fastmm518FastMM_DebugGetMemEx][7845]
00000000004B11C7 [ZDbcStatement.pas][ZDbcStatement][_ZN13Zdbcstatement27TZAbstractPreparedStatement13SetParamCountEi][4138]
0000000000219984 [System.pas][System][_ZN6System7_GetMemEx][4923]
00000000006D5577 [ZDbcOracleStatement.pas][ZDbcOracleStatement][_ZN19Zdbcoraclestatement25TZAbstractOracleStatement10InitBufferEN9Zdbcintfs9TZSQLTypeEPN15Zdbcoracleutils14TZOCIBindValueEjji][637]
00000000004ACEA6 [ZDbcStatement.pas][ZDbcStatement][_ZN13Zdbcstatement27TZAbstractPreparedStatement19CheckParameterIndexERi][3132]
00000000006D39C4 [ZDbcOracleStatement.pas][ZDbcOracleStatement][_ZN19Zdbcoraclestatement25TZAbstractOracleStatement19CheckParameterIndexERi][405]
0000000000229A7E [System.pas][System][_ZN6System10_IntfClearERNS_15DelphiInterfaceINS_10IInterfaceEEE][39015]
00000000006D94C3 [ZDbcOracleStatement.pas][ZDbcOracleStatement][_ZN19Zdbcoraclestatement33TZAbstractOraclePreparedStatement13SetBigDecimalEiRKN4Data6Fmtbcd4TBcdE][1255]
00000000003FA368 [ZClasses.pas][ZClasses][_ZN8Zclasses19TZCustomElementList11SetCapacityEx][2843]
000000000031D9AA [System.Classes.pas][System.Classes][_ZN6System7Classes11TStringListD0Ev][7481]
00000000004409E5 [ZDbcCache.pas][ZDbcCache][_ZN9Zdbccache13TZRowAccessor13FillStatementEN6System15DelphiInterfaceIN9Zdbcintfs19IZPreparedStatementEEEPNS_15TZIndexPairListENS2_INS3_19IZResultSetMetadataEEE][1501]
0000000000229AB5 [System.pas][System][_ZN6System9_IntfCopyERNS_15DelphiInterfaceINS_10IInterfaceEEES2_][39048]
00000000004535F1 [ZDbcGenericResolver.pas][ZDbcGenericResolver][_ZN19Zdbcgenericresolver33TZKeyAndPreparedStatementPairList3AddEyN6System15DelphiInterfaceIN9Zdbcintfs19IZPreparedStatementEEE][1124]
0000000000452332 [ZDbcGenericResolver.pas][ZDbcGenericResolver][_ZN19Zdbcgenericresolver27TZGenerateSQLCachedResolver11PostUpdatesEN6System15DelphiInterfaceIN19Zdbccachedresultset17IZCachedResultSetEEEN9Zdbccache15TZRowUpdateTypeEPNS6_13TZR
0000000000459FAA [ZDbcCachedResultSet.pas][ZDbcCachedResultSet][_ZN19Zdbccachedresultset25TZAbstractCachedResultSet14PostRowUpdatesEPN9Zdbccache13TZRowAccessorES3_][760]
000000000045A40A [ZDbcCachedResultSet.pas][ZDbcCachedResultSet][_ZN19Zdbccachedresultset25TZAbstractCachedResultSet11PostUpdatesEv][879]
000000000045CC37 [ZDbcCachedResultSet.pas][ZDbcCachedResultSet][_ZN19Zdbccachedresultset25TZAbstractCachedResultSet9InsertRowEv][2358]
000000000086A9DD [ZAbstractDataset.pas][ZAbstractDataset][_ZN16Zabstractdataset19TZAbstractRWDataSet17InternalAddRecordEPvb][506]
000000000045C89A [ZDbcCachedResultSet.pas][ZDbcCachedResultSet][_ZN19Zdbccachedresultset25TZAbstractCachedResultSet23UpdateDefaultExpressionEiN6System13UnicodeStringE][2208]

The allocation number is: 3545

Current memory dump of 30 bytes starting at pointer address 1AF71B13480:
02 C1 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7E FF DA 8E 23 00
. . . . . . . . . . . . . . . . . . . . . . . . ~ . . . # .

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 18.01.2024, 21:30
by aehimself
Welcome to the club. Even with the dumps at hand I can not find the source of the "User requested abort of operation" error with string fields if LobCacheMode is onLoad.

There's definetly something wrong with Oracle's buffer size calculation.

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 20.01.2024, 13:46
by MJFShark
Doing some experimentation, I've noticed the following:

This is specific to 64bit and the supposedly 22 byte TOCINumber type. In this case the OCIBind.value_sz is 22 and Zeos does a getmem of exactly 22bytes for that bind buffer. If I change that buffer size to add 2 extra bytes to the end. The memory block corruption goes away.

This code is in TZAbstractOracleStatement.InitBuffer

So instead of:
GetMem(OCIBind.valuep, OCIBind.value_sz * Integer(ElementCnt));
Doing
GetMem(OCIBind.valuep, OCIBind.value_sz * Integer(ElementCnt) + 2);

Appears to solve this particular issue. I've gone over the Oracle docs, and that buffer size should be 22, so I don't know why using a buffer size of 24 solves the issue.

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 20.01.2024, 16:36
by aehimself
I can confirm that the large dataset + lcmOnLoad issue is 64-bit related too; issue does not appear if I make a 32-bit version of my program. It is NOT ASLR-related though, as the issue pops up ever if ASLR is turned off in linking.

Codepage UTF16 is broken on 32 and 64 bit as well.

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 21.01.2024, 13:56
by MJFShark
Note that as far as I know, this issue and possible fix just relates to the thread topic. Is there a simple test case for those other issues you mentioned? Granted, that's often the hardest part of tracking down a pointer or buffer issue lol! I'll be happy to take a look as I haven't run across them in any of my testing, but I think a separate thread would be better for those if they aren't directly related to bind buffers and stBigDecimal.

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 21.01.2024, 17:06
by aehimself
I know, it was not my intention to hijack the topic. I just got happy as it MIGHT have been the solution to one of mine but yeah, that's not the case.

An obfuscated dump was created and "published" and as I promised I DMed you and Jan with the details.
The offer for a beer is still valid!

Maybe I'll create two issues in the bugtracker not to forget about them...

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 21.01.2024, 23:14
by MJFShark
Can you create a new thread for the issue that you're talking about with a simple test case? I'll be happy to take a look, but it really needs to be something I can recreate fairly easily. Currently all my Oracle testing is through a free Oracle Cloud account and so the test case needs to be narrowed down as much as possible (hopefully along with a simple console test case like I used earlier.)

Re: Possible issue with Oracle, 64bit and stBigDecimal

Posted: 22.01.2024, 17:19
by aehimself
Already done :) Do a select * from xxx from the dump. It shows both issues.

UTF16: Bugtracker Thread
Win64 CLOB lcmOnLoad: Bugtracker Thread

Let me know if I should send the dump location again, but it should be in your private message inbox :)