UDF Writing a blob with blob_put_segment crash the Server XE7 64 bit [Edit]

(Tested with 12.0.3.337)

Hello,

I'm using InterBase XE7 Win 32 bit for some months. Now it is time to prepare the switch to Win 64 bit platform. I use my own extensive UDF library. I have this changed to 64 bit (with Delphi XE6 and XE7).

I have one problem with the blob functions. Reading a blob works fine. But writing crashed the server. The write functions works fine on 32 bit. Same in 64 bit crashed.

Please take a look on my code:

  TBlobGetSegment = function (AHandle: pointer; const ABuffer: PByte; ABufSize: Word; var AResultSize: word): SmallInt; cdecl;
  TBlobPutSegment = procedure(AHandle: pointer; const ABuffer: PByte; ABufSize: Word); cdecl;

  PBlob = ^TBlob;
  TBlob = packed record
    BlobGetSegment: TBlobGetSegment;
    BlobHandle: pointer;
    NumberSegments: Cardinal; //32 bit on all platforms
    MaxSegLen: Cardinal;
    TotalSize: Cardinal;
    BlobPutSegment: TBlobPutSegment;
  end;

function InternalWriteBlob(ADestination: PBlob): boolean;
const
  Buf = AnsiString('Test');
begin
  if ADestination=NIL then
    Exit(false);

  ADestination.BlobPutSegment(ADestination.BlobHandle, @Buf[1], 4);
  Result:=True;
end;

I call the UDF simple with "select udf_str_to_blob('xxxxxxxxxx') from rdb$database". And (only for test) the input data string will be skipped.

The blob handle is not NIL. Exact the BlobPutSegment crashed the server.

I'm not sure about the first and second parameter in BlobPutSegment. It's a pointer. On 32 bit the pointer is 32 Bit, on 64 bit it's 64 bit. I've read the C header files in the installation directory. I could not see any difference between 32 and 64 bit declarations. I'm not sure. Because, take the point Totalsize property. IB XE7 supports more than 4 GB blob data. The property TotalSize is a long (a integer), 32 bit. Signed So we can support max 31 bit blob size. There is a theoretical consideration. But
 it confused me in the use of declarations.

First I've read the IB documentation for developer and the delivered IB source code. But, is not really helpful in the point of 64 bit switch. And asked Google and Google and Google.

I hope I get one idea here.

Jens
0
Jens
6/22/2015 2:43:18 PM
embarcadero.interbase.general 923 articles. 0 followers. Follow

7 Replies
951 Views

Similar Articles

[PageSpeed] 44
Get it on Google Play
Get it on Apple App Store

Jens Hoyer wrote:
> (Tested with 12.0.3.337)
> 
> Hello,
> 
> I'm using InterBase XE7 Win 32 bit for some months. Now it is time to prepare the switch to Win 64 bit platform. I use my own extensive UDF library. I have this changed to 64 bit (with Delphi XE6 and XE7).
> 
> I have one problem with the blob functions. Reading a blob works fine. But writing crashed the server. The write functions works fine on 32 bit. Same in 64 bit crashed.
> 
> Please take a look on my code:
> 
>   TBlobGetSegment = function (AHandle: pointer; const ABuffer: PByte; ABufSize: Word; var AResultSize: word): SmallInt; cdecl;
>   TBlobPutSegment = procedure(AHandle: pointer; const ABuffer: PByte; ABufSize: Word); cdecl;
> 
>   PBlob = ^TBlob;
>   TBlob = packed record
>     BlobGetSegment: TBlobGetSegment;
>     BlobHandle: pointer;
>     NumberSegments: Cardinal; //32 bit on all platforms
>     MaxSegLen: Cardinal;
>     TotalSize: Cardinal;
>     BlobPutSegment: TBlobPutSegment;
>   end;
> 
> function InternalWriteBlob(ADestination: PBlob): boolean;
> const
>   Buf = AnsiString('Test');
> begin
>   if ADestination=NIL then
>     Exit(false);
> 
>   ADestination.BlobPutSegment(ADestination.BlobHandle, @Buf[1], 4);
>   Result:=True;
> end;
> 
> I call the UDF simple with "select udf_str_to_blob('xxxxxxxxxx') from rdb$database". And (only for test) the input data string will be skipped.
> 
> The blob handle is not NIL. Exact the BlobPutSegment crashed the server.
> 
> I'm not sure about the first and second parameter in BlobPutSegment. It's a pointer. On 32 bit the pointer is 32 Bit, on 64 bit it's 64 bit. I've read the C header files in the installation directory. I could not see any difference between 32 and 64 bit declarations. I'm not sure. Because, take the point Totalsize property. IB XE7 supports more than 4 GB blob data. The property TotalSize is a long (a integer), 32 bit. Signed So we can support max 31 bit blob size. There is a theoretical consideration. B
ut
>  it confused me in the use of declarations.
> 
> First I've read the IB documentation for developer and the delivered IB source code. But, is not really helpful in the point of 64 bit switch. And asked Google and Google and Google.
> 
> I hope I get one idea here.
> 
> Jens

The TBlob structure is not packed for one.  Since it is a record your 
ADestination will never be NULL, doesn't mean the blob handle is not null.  Show 
all the code of the UDF please.

IBX has the definitions different than yours.

   TISC_BlobGetSegment = function(BlobHandle: ISC_BLOB_HANDLE;
                                  Buffer: PByte;
                                  BufferSize: Long;
                                  var ResultLength: long): Short; cdecl;
   TISC_BlobPutSegment = procedure(BlobHandle: ISC_BLOB_HANDLE;
                                   Buffer: PByte;
                                   BufferLength: Short); cdecl;
   TBlob = record
     GetSegment         : TISC_BlobGetSegment;
     BlobHandle         : ISC_BLOB_HANDLE;
     SegmentCount       : Long;
     MaxSegmentLength   : Long;
     TotalSize          : Long;
     PutSegment         : TISC_BlobPutSegment;
   end;
   PBlob = ^TBlob;

TBlob is not a packed record.  Unfortunately TISC_BlobGetSegment and 
TISC_BlobPutSegment's data types are not defined in the documentation but the 
above are working for me in my little example.

Using those definitions this works for me in 64 bit InterBase

//  DECLARE EXTERNAL FUNCTION str_to_blob
//  CString(2048),
//  BLOB
//  RETURNS PARAMETER 2
//  ENTRY_POINT 'fn_str_to_blob' MODULE_NAME 'UDFLIB';

procedure fn_str_to_blob(s : PAnsiChar; var ABlob : TBlob) cdecl;
begin
   if ABlob.BlobHandle = nil then
     exit;
   ABlob.PutSegment(ABlob.BlobHandle, PByte(s), System.AnsiStrings.StrLen(s));
end;


This SQL returns a blob

select str_to_blob('123456789') from rdb$database

This shows that the blob contains the right data

select cast(str_to_blob('123456789') as VarChar(2048)) from rdb$database

IBX.IBExternals already has these definitions for you and pulls nothing more in 
than just System.Types.

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
6/22/2015 8:09:28 PM
Hi Jeff,

I've changed the record definition from packed to non packed and after a few tests it works fine.

I will test more intensively all functions now on 64 and 32 bit. 

For now, thank you.

Jens
0
Jens
6/22/2015 9:10:47 PM
> {quote:title=Jeff Overcash (TeamB) wrote:}{quote}
>    TISC_BlobGetSegment = function(BlobHandle: ISC_BLOB_HANDLE;
>                                   Buffer: PByte;
>                                   BufferSize: Long;
>                                   var ResultLength: long): Short; cdecl;

Jeff, I think that's not quite right. I've found the same declaration on my Delphi installation, but I don't know if it's right. 

In my view BufferSize should be a Short and not a Long. Because, sometimes the value is totally wrong, much larger than expected. Then if I look at the value as binary I can see that the first 16 bit are correct and the upper 16 bits are randomly wrong.

It's too much guessing, unfortunately.

Jens
0
Jens
6/23/2015 5:35:38 PM
Jens and Jeff,
Thanks to you both for highlighting this issue.

I have fixed the documentation in docwiki today to reflect what is correct and also add further information on the blob_get_segment()/blob_put_segment() argument and return types; http://docwiki.embarcadero.com/InterBase/XE7/en/Creating_a_Blob_Control_Structure

I think the source of the problem was also the faulty sample where the length type was long; it needs to be ISC_USHORT. Fixed this as well at http://docwiki.embarcadero.com/InterBase/XE7/en/A_Blob_UDF_Example

Best wishes,
Sriram

> {quote:title=Jens Hoyer wrote:}{quote}
> > {quote:title=Jeff Overcash (TeamB) wrote:}{quote}
> >    TISC_BlobGetSegment = function(BlobHandle: ISC_BLOB_HANDLE;
> >                                   Buffer: PByte;
> >                                   BufferSize: Long;
> >                                   var ResultLength: long): Short; cdecl;
> 
> Jeff, I think that's not quite right. I've found the same declaration on my Delphi installation, but I don't know if it's right. 
> 
> In my view BufferSize should be a Short and not a Long. Because, sometimes the value is totally wrong, much larger than expected. Then if I look at the value as binary I can see that the first 16 bit are correct and the upper 16 bits are randomly wrong.
> 
> It's too much guessing, unfortunately.
> 
> Jens
0
Sriram
6/24/2015 10:06:45 PM
> {quote:title=Sriram Balasubramanian wrote:}{quote}
> I have fixed the documentation in docwiki today to reflect what is correct and also add further information on the blob_get_segment()/blob_put_segment() argument and return types; http://docwiki.embarcadero.com/InterBase/XE7/en/Creating_a_Blob_Control_Structure
> I think the source of the problem was also the faulty sample where the length type was long; it needs to be ISC_USHORT. Fixed this as well at http://docwiki.embarcadero.com/InterBase/XE7/en/A_Blob_UDF_Example

Hello Sriram,

Many thanks for your post. This is the end of all speculation and. Now it's clear.

But, I think the source of the problem was not the documentation only. It is the wrong declaration in the IBX.IBExternals.pas. Embarcadero should fix this immediate.

Jens
0
Jens
6/30/2015 8:16:06 PM
Jens Hoyer wrote:
>> {quote:title=Sriram Balasubramanian wrote:}{quote}
>> I have fixed the documentation in docwiki today to reflect what is correct and also add further information on the blob_get_segment()/blob_put_segment() argument and return types; http://docwiki.embarcadero.com/InterBase/XE7/en/Creating_a_Blob_Control_Structure
>> I think the source of the problem was also the faulty sample where the length type was long; it needs to be ISC_USHORT. Fixed this as well at http://docwiki.embarcadero.com/InterBase/XE7/en/A_Blob_UDF_Example
> 
> Hello Sriram,
> 
> Many thanks for your post. This is the end of all speculation and. Now it's clear.
> 
> But, I think the source of the problem was not the documentation only. It is the wrong declaration in the IBX.IBExternals.pas. Embarcadero should fix this immediate.
> 
> Jens

It was fixed internally last week when I finally had real documentation as to 
the types.  This has been this way for 20 years (originally written by Gregory 
back in 1996).

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
6/30/2015 11:44:00 PM
> {quote:title=Jeff Overcash (TeamB) wrote:}{quote}
> Jens Hoyer wrote:
> It was fixed internally last week when I finally had real documentation as to 
> the types.  This has been this way for 20 years (originally written by Gregory 
> back in 1996).

It was perfect and well enough for 32 bit. It was not so long have been wrong. Since there are 64 bit.

Well done guys.
0
Jens
7/1/2015 4:29:43 AM
Reply:

Similar Artilces:

UDF Writing a blob with blob_put_segment crashed the Server XE7 64 bit [Edit]
Hello, I'm using InterBase XE7 Win 32 bit for some months. Now it is time to prepare the switch to Win 64 bit platform. I use my own extensive UDF library. I have this changed to 64 bit (with Delphi XE6 and XE7). I have one problem with the blob functions. Reading a blob works fine. But writing crashed the server. The write functions works fine on 32 bit. Same in 64 bit crashed. Please take a look on my code: TBlobGetSegment = function (AHandle: pointer; const ABuffer: PByte; ABufSize: Word; var AResultSize: word): SmallInt; cdecl; TBlobPutSegment = procedure(AHandle: poin...

UDF Writing a blob with blob_put_segment crashed the Server XE7 64 bit
Hello, I'm using InterBase XE7 Win 32 bit for some months. Now it is time to prepare the switch to Win 64 bit platform. I use my own extensive UDF library. I have this changed to 64 bit (with Delphi XE6 and XE7). I have one problem with the blob functions. Reading a blob works fine. But writing crashed the server. The write functions works fine on 32 bit. Same in 64 bit crashed. Please take a look on my code: TBlobGetSegment = function (AHandle: pointer; const ABuffer: PByte; ABufSize: Word; var AResultSize: word): SmallInt; cdecl; TBlobPutSegment = procedure(AHandle: poin...

InterBase XE 64 Bit server crashes on some SQL statements
Testing InterBase XE 64 Bit on a Windows 2008 64 bit system, from a Delphi client on Windows 7 (64 bit) and Windows 2000 (32 bit), I found that some SQL statements always caused the server to terminate. Example: TSSQLSVR (Server) Wed Dec 15 14:08:34 2010 SELECT POS_TEXT FROM LOADLIST_RECH_POS WHERE FK_SQLNR=? AND FK_POSTENART=? Access violation. The code attempted to access a virtual address without privilege to do so. This exception will cause the InterBase server to terminate abnormally. DDL is: CREATE TABLE LOADLIST_RECH_POS ( LOADLIST_RECH_POS_ID...

Using Delphi XE2 to write a 64-bit UDF with BLOBs
Hello, We are upgrading a product to Interbase XE (x64) and we use a UDF with BLOBs (written in Delphi). Previously (in x86 land) we have used the TBlob definition in IBExternals to allow GetSegment and PutSegment with blobs in the UDF, but in this causes an AV when we build a the UDF as a Win64 DLL in Delphi XE2 for Interbase XE (64-bit on Win7 Pro). All the other UDF functions work correctly. The TBlob definition from XE2 is below - what is wrong? Regards, Graham TISC_BlobGetSegment = function(BlobHandle: PInt; Buffer: PByte; ...

Issues writing Interbase XE 64-bit UDFs in Delphi XE2
I am having major issues trying to convert our old UDFs to 64-bit UDFs in Delphi XE2. The *only* success I have had is in returning a constant value! {*****************************************************************} {code}library SixtyFourUDF; uses SysUtils, Classes; function ReturnFive: Integer; export; begin Result := 5; end; Exports Return_Five; begin end. {code} {*****************************************************************} I can't even get a simple multiply function to work. {*****************************************************************} ...

Creating a SQL Server linked server to Interbase using 64 bit SQL Server
Hi, I am trying to use the data direct odbc driver for interbase to create a linked server in SQL Server 2008 R2 64bit however, SQL Server reports an "Arcitechure Mismatch" between the System DSN and SQL Server. This did work under 32 bit SQL Server. Is there a 64bit specific odbc driver for interbase? I have tried using the IBProvider trial as well but this fails to work in SQL Server as well. Our Interbase client(s) and server are all 64 bit installations. Thank you Julian Dawson wrote: > Is there a 64bit specific odbc driver for interbase? I think Easy...

PB11 app on Server 2008 64-bit/Sql Server 2008 R2 64-bit
I have just installed my pb11 app on a Server 2008 64-bit and a Sql Server 2008 R2 64-bit. Unfortunately when running my app on the server, the database connection fails. I am using Sql Native Client in the app and the returned error message text from SQLCA was 'Sql Native Client is not installed' - but it was installed, although it of cause is the 64-bit Native Client, and perhaps that is the problem!?. I then tried to use ODBC instead using odbcinst32.exe from the SYSWOW64 folder to ensure 32-bit setting, but with no luck, the error message from SQLCA was 'T...

64 bit client communicating with 32 bit Interbase 2007 server
Hi, I have the following set up: 1. Interbase 2007 server on a 32 bit computer(XP) 2. A java client application (2 versions : one for 32 bit(interclient for 32 bit) and one for 64 bit(interclient for 64 bit)) 3.DataDirect ODBC driver When I try to connect from 64 bit client(have tried it with both 32bit and 64bit version) to the server I get the following error: Chained exception: java.sql.SQLException: interbase.interclient.IBException: [interclient][interbas e]Unable to complete network request to host "java.net.ConnectException: Connect ion refused: connect". ...

Which one to install SQL Server 2005 Enterprise Edition
 Hello,I installed SQL Server 2005 Enterprise Edition - 62-bit   on my Windows XP and I am not able to install it.when I click on the Setup.exe file I keep getting the error :" It is not a valid Win32 application"Do I need to install the SQL Server 2005 Enterprise Edition - 32-bit  ?Thanks.   What is your windows XP, 32 Bit or 64 Bit ? This error may also happen if your installer is corrupted, or not properly or completely downloadedPlease remember to click “Mark as Answer” on the post that helps youBest RegardsBrij Mohanhttp://www.do...

Changing from 32 Bit Server to 64 Bit Server?
Hi all,we want to buy a new server but doesn't know which bitting.I've googled two days about this, and i found out that it should be a little faster then on 32 bit Servern but nothing exactly.Has anyone experience with running a webapp (32 bit) on a 64 bit Server? Is it fast as on a 32 bit Server?What about a 64 bit webapp on a 64 bit Server?! Is this webapp faster as compiled on 32 bit on a 32 bit Server?What are the differences? I know that you can run Framework 1.1 on a 64 bit Server and that you can run 32 bit webapps (with a little iis configuration :-))thanx for answering It all dep...

How to deploy 32 Bit Multi-Tier remote data module app server in 64 Bit? [Edit]
I have a Multi-Tier remote data module app server build with Delphi 7, running on Windows 7 Professional 32 Bit. My client application can connect to the app server through the Borland Socket Server, find the app server, and connects to it, Both server app and client app runs perfectly in Win 32 Bit. Now I deploy it to Windwos 7 Professional 64 Bit. I can run app server manually. But my client application can not connect to the app server through the Borland Socket Server . It appears my server app does not register properly in 64 Bit. Please advise what I need to do to get the server a...

Create a production build of Firefox for Microsoft 64-bit OSs (Vista 64, MS Windows 2008 Server 64-bit)
Name: Dmitry Viazmin Email: dmitrydotviazminattutdotby Product: Firefox Summary: Create a production build of Firefox for Microsoft 64-bit OSs (Vista 64, MS Windows 2008 Server 64-bit) Comments: Hi, It would be great to get a production build of Firefox for Microsoft 64-bit OSs (Vista 64, MS Windows 2008 Server 64-bit). Do you plan to do that? Best Regards, Dmitry Viazmin Browser Details: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3 From URL: http://hendrix.mozilla.org/ Note to readers: Hendrix gives no expectation of a...

32-bit COM server called up in 64-bit COM server
I have an existing custom COM server written in Delphi XE4 (sorry, no funds to keep up with all the new releases) and compiled for 32-bit platform. I now want to recompile this for a 64-bit platform. The problem is that this server calls up another server which is only available as 32-bit. I know it is frowned upon to mix 64-bit with 32-bit code, but this is the one allowed way of doing it. The 32-bit server is registered with the surrogate mechanisms provided by the operating system, so that the 64-bit a pp can call the 32-bit server. I use the component import wizard to build the necessary ...

32-bit COM server called up in 64-bit COM server #2
I have an existing custom COM server written in Delphi XE4 (sorry, no funds to keep up with all the new releases) and compiled for 32-bit platform. I now want to recompile this for a 64-bit platform. The problem is that this server calls up another server which is only available as 32-bit. I know it is frowned upon to mix 64-bit with 32-bit code, but this is the one allowed way of doing it. The 32-bit server is registered with the surrogate mechanisms provided by the operating system, so that the 64-bit a pp can call the 32-bit server. I use the component import wizard to build the necessary ...

Web resources about - UDF Writing a blob with blob_put_segment crash the Server XE7 64 bit [Edit] - embarcadero.interbase.general

Resources last updated: 12/29/2015 9:35:30 PM