From 09a6ae541eb9398980ccf4db3b802d6748b2ef6b Mon Sep 17 00:00:00 2001 From: onefang Date: Thu, 23 Apr 2020 17:24:44 +1000 Subject: Trying to track down MariaDB leaks. --- src/sledjchisl/sledjchisl.c | 73 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c index 95d03fc..d7b57c3 100644 --- a/src/sledjchisl/sledjchisl.c +++ b/src/sledjchisl/sledjchisl.c @@ -1021,10 +1021,10 @@ struct _dbRequest { MYSQL *db; char *table, *join, *where, *order, *sql; + MYSQL_STMT *prep, *prep0; // NOTE - executing it stores state in this. qlisttbl_t *flds; int inCount, outCount, rowCount; char **inParams, **outParams; - MYSQL_STMT *prep; // NOTE - executing it stores state in this. MYSQL_BIND *inBind, *outBind; rowData *rows; my_ulonglong count; @@ -1045,6 +1045,7 @@ void dbDoSomething(dbRequest *req, boolean count, ...) if (NULL == req->prep) { + D("Creating prepared statement for %s - %s", req->table, req->where); req->flds = dbGetFields(req->db, req->table); if (NULL == req->flds) { @@ -1089,6 +1090,8 @@ void dbDoSomething(dbRequest *req, boolean count, ...) d("New SQL statement - %s", req->sql); // prepare statement with the other fields req->prep = mysql_stmt_init(req->db); + // Save the pointer before something mysteriously clobbers it, so we can close it later. + req->prep0 = req->prep; if (NULL == req->prep) { E("Statement prepare init failed: %s\n", mysql_stmt_error(req->prep)); @@ -1661,6 +1664,15 @@ end: double n = (now.tv_sec * 1000000000.0) + now.tv_nsec; double t = (then.tv_sec * 1000000000.0) + then.tv_nsec; T("dbDoSomething(%s) took %lf seconds", req->sql, (n - t) / 1000000000.0); + if (NULL != req->prep) + I("The prepared statement itself is NOT NULL."); + else + W("The prepared statement itself is NULL!"); + + if (NULL != req->prep0) + I("The prepared0 statement itself is NOT NULL."); + else + W("The prepared0 statement itself is NULL!"); return; } @@ -1692,7 +1704,24 @@ void dbFreeRequest(dbRequest *req) { int i; +// TODO - this leaks for some bizare reason. Not even req->sql survives. D("Cleaning up prepared database request %s - %s %d %d", req->table, req->where, req->outCount, req->inCount); + + if (NULL != req->prep) + I("The prepared statement itself is NOT NULL."); + else + W("The prepared statement itself is NULL!"); + + if (NULL != req->prep0) + I("The prepared0 statement itself is NOT NULL."); + else + W("The prepared0 statement itself is NULL!"); + + if (NULL != req->flds) + dbFreeFields(req->flds); + else + D("No fields to clean up for %s - %s.", req->table, req->where); + if (NULL != req->outBind) { d("Free outBind"); @@ -1706,13 +1735,14 @@ d("Free outBind %d %s", i, req->sql); } free(req->outBind); } + else + D("No out binds to clean up for %s - %s.", req->table, req->where); if (NULL != req->inBind) { d("Free inBind"); for (i = 0; i < req->inCount; i++) { d("Free inBind %d %s", i, req->sql); -// TODO - this leaks for some bizare reason. if (NULL != req->inBind[i].buffer) free(req->inBind[i].buffer); if (NULL != req->inBind[i].length) free(req->inBind[i].length); if (NULL != req->inBind[i].error) free(req->inBind[i].error); @@ -1720,15 +1750,25 @@ d("Free inBind %d %s", i, req->sql); } free(req->inBind); } + else + D("No in binds to clean up for %s - %s.", req->table, req->where); if (req->freeOutParams) free(req->outParams); + else + D("No out params to clean up for %s - %s.", req->table, req->where); if (NULL != req->sql) free(req->sql); - if (NULL != req->prep) + else + D("No SQL to clean up for %s - %s.", req->table, req->where); + if (NULL != req->prep0) { - if (0 != mysql_stmt_close(req->prep)) - C("Unable to close the prepared statement!"); - free(req->prep); +// TODO - this leaks for some bizare reason. + D(" Cleaning up the prepared statement."); + if (0 != mysql_stmt_close(req->prep0)) + C(" Unable to close the prepared statement!"); + free(req->prep0); } + else + W(" The prepared statement itself is NULL!"); } my_ulonglong dbCount(MYSQL *db, char *table, char *where) @@ -5124,7 +5164,7 @@ void inputFieldExtra(inputField *ret, signed char flags, short viewLength, short void addSession(inputForm *iF) { - inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); + inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! //d("addSession(%s)", iF->name); flds[0] = addInputField(iF, LUA_TSTRING, "hashish", "hashish", "", sessionValidate, sessionWeb); @@ -5140,7 +5180,7 @@ void addSession(inputForm *iF) void addEmailFields(inputForm *iF) { - inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); + inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! flds[0] = addInputField(iF, LUA_TEMAIL, "email", "email", NULL, emailValidate, emailWeb); inputFieldExtra(flds[0], FLD_EDITABLE, 42, 254); @@ -5156,7 +5196,7 @@ void addEmailFields(inputForm *iF) void addDoBFields(inputForm *iF) { - inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); + inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! flds[0] = addInputField(iF, LUA_TSTRING, "DoByear", "year", NULL, DoBValidate, DoByWeb); flds[1] = addInputField(iF, LUA_TSTRING, "DoBmonth", "month", NULL, DoBValidate, DoBmWeb); @@ -5169,7 +5209,7 @@ void addDoBFields(inputForm *iF) void addLegalFields(inputForm *iF) { - inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); + inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! flds[0] = addInputField(iF, LUA_TBOOLEAN, "adult", "I'm allegedly an adult in my country.", NULL, legalValidate, adultWeb); flds[1] = addInputField(iF, LUA_TBOOLEAN, "agree", "I accept the Terms of Service.", NULL, legalValidate, agreeWeb); @@ -5667,10 +5707,15 @@ static void cleanup(void) while (NULL != (req = (dbRequest *) dbRequests->getat(dbRequests, 0, NULL, false))) { - if (NULL != req->flds) - dbFreeFields(req->flds); - else - D("No fields to clean up for %s - %s.", req->table, req->where); + if (NULL != req->prep) + I("The prepared statement itself is NOT NULL."); + else + W("The prepared statement itself is NULL!"); + + if (NULL != req->prep0) + I("The prepared0 statement itself is NOT NULL."); + else + W("The prepared0 statement itself is NULL!"); dbFreeRequest(req); dbRequests->removefirst(dbRequests); } -- cgit v1.1