SQLite Forum

[bug] sqlite3 binrary does not unregister extensions/vfs at exit()
Login

[bug] sqlite3 binrary does not unregister extensions/vfs at exit()

(1.1) Originally by Patrick Donnelly (pdonnell) with edits by Richard Hipp (drh) on 2021-06-26 18:46:52 from 1.0 [link] [source]

The sqlite3 binary evidently calls exit() directly on error. This makes some cleanup extremely difficult when VFS userdata reference structures or threads that must be torn down. This causes at least two problems for the ceph VFS [1]:

  • Any global/static structures will be destructed by C++ which can cause segmentation faults or other errors when library threads continue referencing that memory during the exit procedure.

  • Any connections with distributed systems (like Ceph) will essentially time out causing automatic fencing/blocklisting procedures. This is unnecessary expense that can be avoided.

Now, I probably will have to fix this by registering atexit handlers to tear down ceph library state for this situation. This is unsatisfactory however because I need to store VFS state in a static-duration structure. It would be much better if SQLite unregistered the VFS or called some new VFS shutdown method.

[1] https://docs.ceph.com/en/latest/rados/api/libcephsqlite/

Kind regards,

Patrick Donnelly

(2) By Richard Hipp (drh) on 2021-06-26 18:55:20 in reply to 1.1 [source]

By "sqlite3 binary", do you mean the sqlite3 command-line shell?

It seems to me that any library that is unable to deal with an abrupt process termination (such as from exit(1)) is broken. How does Ceph deal with a SIGKILL? Why should exit() work any differently than SIGKILL?

I think that application programs, such as the sqlite3 command-line shell, should be free to invoke exit() or abort() whenever appropriate without having to worry about library cleanup. Cleanup on process termination should be the responsibility of the library itself, or the operating system, not the application. Isn't that the whole point of the process abstraction in the first place?

(3) By Patrick Donnelly (pdonnell) on 2021-06-26 19:42:58 in reply to 2 [link] [source]

> By "sqlite3 binary", do you mean the sqlite3 command-line shell?

Yes

> It seems to me that any library that is unable to deal with an abrupt process termination (such as from exit(1)) is broken. How does Ceph deal with a SIGKILL? Why should exit() work any differently than SIGKILL?

Ceph deals with SIGKILL the same way it would for a network partition, eventually the process' session may be blocklisted.

exit() would be the same if it were _exit().

"Normal" process termination should not necessarily mean leave behind a mess (as with "abnormal" termination).

> I think that application programs, such as the sqlite3 command-line shell, should be free to invoke exit() or abort() whenever appropriate without having to worry about library cleanup. Cleanup on process termination should be the responsibility of the library itself, or the operating system, not the application. Isn't that the whole point of the process abstraction in the first place?

I've made an adjustment which turns out a little easier than expected:

https://github.com/ceph/ceph/pull/42035/commits/ba32d871ce2a14a6430170702716f2482d3958fd

It's possible we could have atexit handlers for Ceph library processes. I think that may be an acceptable and workable solution. So please consider the bug "withdrawn".