Issue Details (XML | Word | Printable)

Key: CORE-5234
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Vlad Khorsun
Reporter: Beto Neto
Votes: 0
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Access violation on UDF crashes server

Created: 09/May/16 07:24 PM   Updated: 20/Apr/18 06:26 AM
Component/s: UDF
Affects Version/s: 3.0.0, 2.5.8
Fix Version/s: 3.0.1, 4.0 Alpha 1

Environment: Windows 7 x64 Professional, Firebird 3.0 x86

QA Status: Cannot be tested


 Description  « Hide
I have a UDF named jjwudf. Inside it we have this exported function:

    procedure udf_StrOfChr(Ret, Ch: PChar; var Count: integer); cdecl; export;
    var
      I: integer;
    begin
      if (Ch^ = #0) or (Count <= 0) then
        Ret^ := #0
      else begin
        for I := 1 to Count do begin
          Ret^ := Ch^;
          Inc(Ret);
        end;
        Ret^ := #0;
      end;
    end;

And this is its DDL

    DECLARE EXTERNAL FUNCTION UDF_STROFCHAR
        CSTRING(254),
        CSTRING(1),
        INTEGER
    RETURNS PARAMETER 1
    ENTRY_POINT 'udf_StrOfChr' MODULE_NAME 'jjwudf';


It returns a string of the char repeated, see a usage example:

    select udf_StrOfChr('a', 3) from rdb$database

    Returns "aaa"

When I use it on 2.x Firebird Servers, it works! But on Firebird 3.0 it crashes the server.
  

firebird.log

myvm Mon May 09 11:33:01 2016
The user defined function: UDF_STROFCHAR
referencing entrypoint: udf_StrOfChr
in module: jjwudf
caused the fatal exception: Access violation.
The code attempted to access a virtual
address without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Karol Bieniaszewski added a comment - 09/May/16 07:52 PM
It looks like support question...
Your udf doesn't allocate memory for parametr 1(ret)
You declare its max - and FB allocate only buffer for 'a' not 254 chars

but maybe i am wrong - then someone corrects me

Beto Neto added a comment - 16/May/16 12:56 PM
Karol, the case is that it works on 2.x versions. This broked the compatibility.

Vlad Khorsun added a comment - 18/May/16 04:13 PM
Beto Neto,

please check next snapshot build.

Vlad Khorsun added a comment - 18/May/16 04:14 PM
Karol,

when UDF declare output parameter as RETURNS PARAMETER N - engine allocates memory itself.

Beto Neto added a comment - 19/May/16 11:17 AM
Fixed, thanks!

Tested with Firebird-3.0.1.32524-0_Win32

Christian Pradelli added a comment - 04/Jun/16 02:39 AM - edited
I have exactly the same problem here but it is not fixed in latest snapshot build.
It is something related with freepascal 2.6 and linux.
I have an udf that works perfect for many years in firebird but now with firebird 3.0 superserver 64 bits on linux it raise exactly the same error that you post above (in firebird.log) and it crash the server.
For small resultseta the udf works as expected and returns the correct result but if you use it in a very large select, about 2 millon record, it makes the server crash.
After a complete day reworking the udf the only way i found to fix the issue was recompiling it with freepascal 3.0.

Now it works.

The problem is fixed for me but it sounds that some kind of compatibility was broken.

Vlad Khorsun added a comment - 04/Jun/16 07:23 AM
Christian,

with no details we can't even diagnose an issue. Message in firebird.log say nothing about reasons, just a fact of AV cacthed at UDF call.

Christian Pradelli added a comment - 08/Jun/16 01:22 AM - edited
Hi Vlad,

I think that the problem is with FreePascal, not with Firebird, I remember that I had this issue several times in the past years, it appears and disappears depending on the combination of Freepascal and Firebird versions.
There are several bug reports about udf's done with freepascal / kilix, for example CORE-3646, CORE-3071.

Now with Firebird 3.0 Superserver, If I compile with FreePascal 2.6.4, I can reproduce the issue with an udf so simple like:

function KPosInList(Str1, Str2: PChar): integer; cdecl;
var
  SL: TStringList;
  s1: AnsiString;
  s2: AnsiString;
begin
  if (Str1 = nil) or (Str2 = nil) then begin
    Result := 0;
    Exit;
  end;

  try
    s1 := StrPas(Str1);
    s2 := StrPas(Str2);

    SL := TStringList.Create;
    try
      SL.CommaText := s2;
      Result := SL.IndexOf(s1)+1;
    finally
      SL.Free;
    end;
  except
    Result := 0;
  end;
end;

it works fine for small resultsets, but on large resultsets it always raise:

the user defined function: K_POSINLIST
referencing entrypoint: KPosInList
in module: kibudf
caused the fatal exception: Segmentation Fault.
The code attempted to access memory
without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.

The problem disappear after compiling it with FreePascal 3.0.

The question is: is posible to avoid the Firebird Server crash and only return an error to the connection that execute the query?

Regards

Vadim Mescheryakov added a comment - 31/Oct/16 05:22 PM
I catched this error on Firebird 3.0.1.32609 / 64 bit (Windows)

But error do not ever when call udf function
 
SRV-DELFIN Mon Oct 31 13:51:58 2016
The user defined function: UDF_POS
referencing entrypoint: dfudf_Pos
in module: tbudf
caused the fatal exception: Access violation.
The code attempted to access a virtual
address without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.


SRV-DELFIN Mon Oct 31 13:51:58 2016
The user defined function: UDF_FORMATFLOAT
referencing entrypoint: dfudf_FormatFloat
in module: tbudf
caused the fatal exception: Access violation.
The code attempted to access a virtual
address without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.


SRV-DELFIN Mon Oct 31 13:51:58 2016
The user defined function: UDF_POS
referencing entrypoint: dfudf_Pos
in module: tbudf
caused the fatal exception: Access violation.
The code attempted to access a virtual
address without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.

Vlad Khorsun added a comment - 01/Nov/16 11:58 AM
Vadim,

firebird.log is clear - all AV's was catched when UDF's called
Do you have something we could look at ? Reproducible example, memory dump...

Also, it is important to know - what compiler was used to build UDF

Beto Neto added a comment - 17/Apr/18 01:38 PM
Now I'm getting this error on Firebird LI-V2.5.8.27089

This is the firebird.log

dba301515fae Tue Apr 17 08:36:11 2018
        The user defined function: UDF_TRIM
           referencing entrypoint: udf_Trim
                        in module: jjwudf
        caused the fatal exception: Segmentation Fault.
                The code attempted to access memory
                without privilege to do so.
        This exception will cause the Firebird server
        to terminate abnormally.


dba301515fae (Client) Tue Apr 17 08:36:12 2018
        /usr/local/firebird/bin/fbguard: /usr/local/firebird/bin/fb_smp_server terminated abnormally (-1)



dba301515fae (Client) Tue Apr 17 08:36:12 2018
        /usr/local/firebird/bin/fbguard: guardian starting /usr/local/firebird/bin/fb_smp_server

And this is the UDF source (lazarus/free pascal)

function udf_Trim(Str: PChar): PChar; cdecl; export;
begin
  Result := Str;
  StrPCopy(Str, Trim(Str));
end;

This crash occurrs randomly.

Vlad Khorsun added a comment - 17/Apr/18 02:37 PM
The log message is clear, isn't is ?

What is value of BugcheckAbort setting ?

Does UDF have IsMultythreaded := true ?
Or its FPC equivalent.

And, please, don't put all and every issues related with AV in UDF into this ticket.

Beto Neto added a comment - 18/Apr/18 10:57 AM
The log message is clear, isn't is ?
- Sorry, I'm not acquainted with lazarus/free pascal.

What is value of BugcheckAbort setting ?
- How can I find this? Is a compiler option?

Does UDF have IsMultythreaded := true ?
- There was no code setting this, now I have turned it on.

Or its FPC equivalent.
- ?

And, please, don't put all and every issues related with AV in UDF into this ticket.
- Sorry again.

Vlad Khorsun added a comment - 20/Apr/18 06:26 AM
> The log message is clear, isn't is ?
> - Sorry, I'm not acquainted with lazarus/free pascal.
I refer to the message from firebird.log you showed

> What is value of BugcheckAbort setting ?
> - How can I find this? Is a compiler option?
This is setting at firebird.conf

> Does UDF have IsMultythreaded := true ?
> - There was no code setting this, now I have turned it on.
Very good

Please, next time ask at fb-support list first, until you 100% sure there is a bug.