sql: clear clnt->thd before handing the client back - fix for 'cldeadlock' test - #6173
sql: clear clnt->thd before handing the client back - fix for 'cldeadlock' test#6173markhannum wants to merge 1 commit into
Conversation
roborivers
left a comment
There was a problem hiding this comment.
Cbuild submission: Error ⚠.
Regression testing: Success ✓.
The first 10 failing tests are:
sc_resume_logicalsc_generated **quarantined**
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**
ab080e4 to
abf4b7b
Compare
roborivers
left a comment
There was a problem hiding this comment.
Cbuild submission: Error ⚠.
Regression testing: Success ✓.
The first 10 failing tests are:
sc_truncate [db unavailable at finish]
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**
clnt->thd outlives the sqlthdstate it points at, which is alloca'd on the pool thread's stack. Clear it before signal_clnt_as_done(). Hardening: the common path is already covered by done_cb_evbuffer() marking clnt->done. Signed-off-by: Mark Hannum <[email protected]>
abf4b7b to
db0fc1e
Compare
roborivers
left a comment
There was a problem hiding this comment.
Cbuild submission: Error ⚠.
Regression testing: Success ✓.
The first 10 failing tests are:
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**
clnt->thdpoints at thesqlthdstatethe query ran under, which isalloca'd on the pool thread's stack. Nothing cleared it, so it outlives the frame.cldeadlock reaches it by orphaning handles mid-statement. When the client vanishes
send_columns()fails; for a non-selectsqlinterfaces.c:4042setsquery_rc = CDB2ERR_IO_ERROR, anddone_cb_evbuffer()returns on that value before settingclnt->done = 1. The connection is left withdone == 0and a staleclnt->thd, and the once-a-second watchdog scan dereferences it after the pool thread exits.Adds
clnt_detach_thd(), called beforesignal_clnt_as_done()insqlengine_work_appsock()andsqlengine_work_lua_thread(). Skipped on nested replay, where the outer frame still owns thd. Not done on theRC_INTERNAL_RETRYpath:enqueue_sql_query()has already clearedclnt->thdand the new owner may have freed clnt.Fallout:
reqlog_long_running_clnt()readsclnt->thdonce rather than three times;recover_deadlock_flags()takes the sql_thread from TLS asrecover_deadlock_flags_int()already does;osql_clean_sqlclntstate()preservesin_replay_nestedacross its bzero.Fixes issue discovered by
cldeadlock.