Zeos 8.0.0-stable (build 2024-04-07), Delphi 11 Win32, FreeTDS 1.4.12 (sybdb.dll),
SQL Server 2008.
TZAbstractDBLibStatement.FetchResults (src/dbc/ZDbcDbLibStatement.pas) ends with:
until ResultsRETCODE = NO_MORE_RESULTS;
When the DBPROCESS is dead, dbresults returns FAIL (0) and never NO_MORE_RESULTS (2),
so the loop never ends. The main thread spins at 100% of one core inside sybdb.dll and
the application has to be killed from Task Manager. Same code in master today.
DB-Library documents that the loop must also stop on FAIL: "call dbresults() until it
returns NO_MORE_RESULTS (or FAIL)".
Repro: start a query, unplug the network cable, plug it back in. With TDSDUMP enabled
the log repeats forever:
dbperror(..., 20047, 0) "DBPROCESS is dead or not enabled"
dbdead(...) [dead]
dblib_err_handler ... returns 2 (INT_CANCEL)
dbresults returning 0 (FAIL)
dbcmdrow(...)
The CheckDBLibError call inside the loop does not stop it: it returns early because
FSQLErrors and FSQLMessages are both empty. The log shows FreeTDS's own
default_err_handler answering the error, with severity 9 (EXCOMM) - which
CheckDBLibError would have mapped to EZSQLConnectionLost if it had reached it. That
looks like a second problem: the Zeos error handler is not the one being called for
this connection.
What I run here:
until (ResultsRETCODE = NO_MORE_RESULTS) or (ResultsRETCODE = DBFAIL);
if (ResultsRETCODE = DBFAIL) then
raise EZSQLConnectionLost.CreateWithCode(20047,
'DBLib: connection lost while reading results (dbresults = FAIL)');
With that the application raises an error immediately and recovers when the network
comes back, instead of freezing.
Hmm - usually the case of DBFAIL should be handeled by the following part, right after the call to dbresults:
Do you have any chance to find out, why CheckDBLibError doesn't raise an exception?
Last edit: marsupilami79 2026-09-06