Skip to content

Commit

Permalink
Work around a segfault during handle destruction.
Browse files Browse the repository at this point in the history
This patch fixes perl5-dbi#111

During global destruction, the function dbd_dr_destroy is sometimes called
before all handles are destroyed.  It frees resources uses in the handle
DESTROY function, causing a segfault when the handle DESTROY function tries
to disconnect the handle.

This patch simply sets a flag in dbd_dr_destroy which makes per-handle
DESTROY functions skip trying to disconnect the handle.
  • Loading branch information
dfskoll committed Aug 12, 2020
1 parent dc7492c commit 5d98d93
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions dbdimp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ ub2 utf8_csid = 871;
ub2 al32utf8_csid = 873;
ub2 al16utf16_csid = 2000;

static int dbd_dr_destroy_called = 0;

typedef struct sql_fbh_st sql_fbh_t;
struct sql_fbh_st {
Expand Down Expand Up @@ -199,6 +200,7 @@ dbd_init(dbistate_t *dbistate)
dTHX;
DBIS = dbistate;
dbd_init_oci(dbistate);
dbd_dr_destroy_called = 0;
}


Expand All @@ -208,6 +210,8 @@ dbd_dr_destroy(SV *drh, imp_drh_t *imp_drh)
dTHX;
sword status;

dbd_dr_destroy_called = 1;

/* We rely on the DBI dispatcher to destroy all child handles before we get here (DBI >= 1.623). */

if (imp_drh->leak_state) {
Expand Down Expand Up @@ -1167,6 +1171,11 @@ dbd_db_disconnect(SV *dbh, imp_dbh_t *imp_dbh)
/* since most errors imply already disconnected. */
DBIc_ACTIVE_off(imp_dbh);

/* If dbd_dr_destroy has been called, it's completely */
/* unsafe to do anything with the handle, so just return */
if (dbd_dr_destroy_called) {
return 1;
}
/* Oracle will commit on an orderly disconnect. */
/* See DBI Driver.xst file for the DBI approach. */

Expand Down

0 comments on commit 5d98d93

Please sign in to comment.