Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FBCLIENT.DLL forces Delphi to ignore EZeroDivide exceptions [CORE4043] #4373

Open
firebird-automations opened this issue Feb 7, 2013 · 9 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Pablo Romero (pabloromero)

Votes: 3

I have a Delphi database application that is currently running on FB 2.5 server. Application was working OK for several years on previous FB versions. I switched
to FB 2.5 early when it was released.

This year I noticed a couple of cases when there was "INF" value written in double precision field in database. I also noticed, that Delphi Try / Except / End
block was not catching EZeroDivide etc. exceptions. This is big problem.

Imagine a case like this:

var
A,B,C: Real;

try
C := A / B; // B is zero here
except
C := 0;
end

Exception is not raised on C calculation and C is calculated as INF "infinity" number.

Well: I can change that and check if B is zero and do workaround, but there is Delphi VCL that depends on exception being raised!

By default, Delphi sets FPU Control Word to raise exceptions.

You can read more about that here:
http://qc.embarcadero.com/wc/qcmain.aspx?d=5928

So, when I was looking for DLL that my application loads that disables FPU exceptions, I realised that it is Firebird Client library or its MSVC RTL.

Every time you connect to a database, all exceptions are disabled. You execute a query, and all exceptions are disabled.

What I found out is that my Delphi application catches exceptions, working ok, if I use FB client from version 1.5 up to version 2.1.4.

With Fbclient.dll 2.5 there are problems.

¿Is FB Client that is builded with disabled FPU exceptions catching or is it MSVC RTL?. I dont know if MSVC RTL changed from FB 2.1.4 to FB 2.5 or it is the same.

If I set FPU control manualy in my application it works only for a couple of lines, until another "Select..." of code, and it is back disabled again, so this is not a solution.

Currently I am using 2.1.4 client to be on the safe side.

Regards

Pablo Romero
Cordoba, Argentina

Commits: 0ade3f4

@firebird-automations
Copy link
Collaborator Author

Modified by: Pablo Romero (pabloromero)

summary: FBCLIENT.DLL => FBCLIENT.DLL forces Delphi to ignore EZeroDivide exceptions

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Suppose first of all we should confirm an issue - there is a change in fb 2.5 that may cause such a behavior. On the other hand in trivial case (single thread) state of FPU was designed to be restored when leaving client. Can someone re-check it on windows?

On the other hand looking once again at the code looks like in MT case we have definite bug. Moreover - for embedded case if one thread works inside fb engine but another in user's code they have different FPU control word requirements, and probably changin it in our code is bad idea in generic.

@firebird-automations
Copy link
Collaborator Author

firebird-automations commented Feb 23, 2013

Commented by: Simon (daytripper)

Hi all,

Most of this ticket is my report on Firebird-Support:
http://tech.groups.yahoo.com/group/firebird-support/message/115149 (archive)
... so I guess I can confirm this issue.

FB 2.5 Client library is a no-go for Delphi users that relay on catching EZeroDivide errors.
I reverted to FB 2.1 client for all my applications - it is just too many places in Delphi code to change them all - many in Delphi VCL, RTL code and Third party components. This is a little time bomb that waits on Delphi users who upgrade to 2.5 - it was the only thing in my upgrade that caused me problems because the worst thing about it is that many times doesn't surface the first moment with big error message in aplication, but simply puts wrong data in database for example (INF...), or calculates wrong results. This issue is not just Firebird related - it changes the way FPU works with exceptions.

Best regards,
Simon

@firebird-automations
Copy link
Collaborator Author

Commented by: Attila Molnár (e_pluribus_unum)

Hi!

I can confirm, it's definitely a firebird client bug.

@firebird-automations
Copy link
Collaborator Author

Commented by: michalk1 (michalk1)

I can also confirm the issue. I tested basic single thread operations and found that most fbclient functions change the masks. FPU returns with all masks except DM set (bits 0,2,3,4 and 5). There are few "local" functions that keep the settings untouched (isc_decode_date, isc_dsql_describe, isc_vax_integer, isc_interprete etc.), but all other are affected (isc_database_info, isc_attach_database, isc_dsql_execute2, isc_dsql_fetch, isc_dsql_free_statement, isc_commit_transaction, isc_service_start etc.). The problem is specific to FB 2.5 client library, FB 2.1 is ok.

@firebird-automations
Copy link
Collaborator Author

Commented by: @hvlad

The quick (and incomplete) solution is committed into v2.5.3. Single-threaded applications should be OK now.
Complete solution should be MT-safe and sooner of all requires FP-exception handling code in the engine.

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

Vlad, this commit has broken Win64 builds, as __control87_2 is not supported there.

@firebird-automations
Copy link
Collaborator Author

Commented by: @hvlad

Dmitry,

thanks, it is fixed now.

@firebird-automations
Copy link
Collaborator Author

Commented by: Jared Davison (jared)

We have found a problem that the FPU control word mask is not preserved between calls to FBCLIENT.dll functions such isc_attach_database().

This results in unexpected behavior in the calling application.

We observed this bug under Win32 fbclient.dll 2.5.0.26074, 2.5.2.6539.

We have observed that this has been *fixed* in release Firebird 2.5.3 release (2.5.3.26778). We cannot find a description of the fix in the release notes possibly because this is an incomplete solution and workaround.
http://www.firebirdsql.org/file/documentation/release_notes/html/rlsnotes253.html#bug-253.

We have found the following comments inside src\common\classes\FpeControl.h which suggests the resolution of this is issue incomplete.

r57758
Restore previous code for Win64 platform as it missed __control87_2() routine.
---------------------
r57741
Fixed the way floating point exceptions are masked.
This is quick and incomplete solution for the CORE4043 (FBCLIENT.DLL forces Delphi to ignore EZeroDivide exceptions).
Complete solution should be MT-safe and sooner of all requires FP-exception handling code in the engine.
---------------------

This subtle bug can have serious consequences in an application that uses floating point. We suggest a unit test around this issue to ensure this is not broken in future.

Mutithreaded support is mandatory to resolve this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant