Re: 0.82 RC4 assert(0) on failed to connect
"James K. Lowden" <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
> #4 0xb7241085 in retname (retcode=0) at util.c:292 > #5 0xb72411b4 in tdserror (tds_ctx=0x80f9e78, tds=0x80856b8, > #msgno=20009, > errnum=115) at util.c:368 > #6 0xb725c724 in tds_open_socket (tds=0x80856b8, > ip_addr=0x8085b78 "10.6.113.5", port=1433, timeout=90000) at > net.c:309 > #7 0xb7241def in tds_connect (tds=0x80856b8, connection=0x8085a58) > at login.c:428 > #8 0xb7234b16 in DbOpen (handle=0x807f738) at nsfreetds.c:270 > #9 0xb7270b99 in NsDbOpen () from ./lib/libnsdb.so > ... > > It appears that "rc" in tdserror is set from the return of the message > handler? Indeed, my custom handler messages both return "0" -- ack. > I've changed the error message handler to return TDS_INT_CANCEL. [For anyone tuning in late, this thread applies to AOLserver, which uses libtds directly. Normal applications (let's call them) use one of the three client libraries, all of which prevent the assert error in the subject.] Hi Dossy, Yes. One big change in 0.82 will be that libtds calls back to the client library's error handler to decide whether to retry or abort. The callback function's return value tells libtds what to do. You no doubt saw the comment in tdserror(): /* * Call client library handler. * The client library must return a valid code. * It is not checked again here. */ Cf. src/dblib/dblib.c::dbperror and the comments above src/tds/util.c::tdserror(). Of course the callback function is written by the user and might not return one of the specified values (as in your case!). The client library's "handler handler" (if you will) is responsible for dealing with that. In db-lib, any out-of-range return code is converted to INT_EXIT. This is actually a specific instance of the general purpose of each library's "handler handler". Each library defines its own way to deal with timeouts, and libtds doesn't care which client library happens to be in use; it has its own callback specification. It's the job of the "handler handler" to wrap the caller's handler (if any) and provide conforming behavior for libtds. Hope that's clear! > Yes, I realize that direct use of libtds isn't supported, but this > caught me by surprise. I'm sure. Over the last year or two I've worked to rationalize error handling. The philosophy is that most error detection and handling should be done by the client library, and libtds can expect to be called correctly. Life is simpler that way. For the sake of a framework, let's say errors are of two kinds: logical and runtime. Runtime errors -- server not available, library misuse -- cannot be handled at compile time. They provoke error messages that inform the user what went wrong. Logical errors are bugs embedded in the code that can be prevented by testing, etc. They are handled more simply: with a log message (maybe) and an assertion. (I'm excluding server messages -- bad SQL, etc. -- because they're not errors insofar as the library is concerned. They're just data.) The client library handles almost all runtime errors and must *prevent* logical errors. It is the job of the client library not to make invalid calls upon libtds, no matter what the application or server does. If it fails to do so, the results are, as the compiler writers say, undefined. For the most part libtds assumes (or, more and more, asserts) inputs from the client library are valid. Regards, --jkl