diff options
author | onefang | 2020-04-23 17:24:44 +1000 |
---|---|---|
committer | onefang | 2020-04-23 17:24:44 +1000 |
commit | 09a6ae541eb9398980ccf4db3b802d6748b2ef6b (patch) | |
tree | 1c2a813ee23b99329538c2dea1ea68a6022e6fbf | |
parent | Leaks-- (diff) | |
download | opensim-SC-09a6ae541eb9398980ccf4db3b802d6748b2ef6b.zip opensim-SC-09a6ae541eb9398980ccf4db3b802d6748b2ef6b.tar.gz opensim-SC-09a6ae541eb9398980ccf4db3b802d6748b2ef6b.tar.bz2 opensim-SC-09a6ae541eb9398980ccf4db3b802d6748b2ef6b.tar.xz |
Trying to track down MariaDB leaks.
Diffstat (limited to '')
-rw-r--r-- | src/sledjchisl/sledjchisl.c | 73 |
1 files 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 | |||
1021 | { | 1021 | { |
1022 | MYSQL *db; | 1022 | MYSQL *db; |
1023 | char *table, *join, *where, *order, *sql; | 1023 | char *table, *join, *where, *order, *sql; |
1024 | MYSQL_STMT *prep, *prep0; // NOTE - executing it stores state in this. | ||
1024 | qlisttbl_t *flds; | 1025 | qlisttbl_t *flds; |
1025 | int inCount, outCount, rowCount; | 1026 | int inCount, outCount, rowCount; |
1026 | char **inParams, **outParams; | 1027 | char **inParams, **outParams; |
1027 | MYSQL_STMT *prep; // NOTE - executing it stores state in this. | ||
1028 | MYSQL_BIND *inBind, *outBind; | 1028 | MYSQL_BIND *inBind, *outBind; |
1029 | rowData *rows; | 1029 | rowData *rows; |
1030 | my_ulonglong count; | 1030 | my_ulonglong count; |
@@ -1045,6 +1045,7 @@ void dbDoSomething(dbRequest *req, boolean count, ...) | |||
1045 | 1045 | ||
1046 | if (NULL == req->prep) | 1046 | if (NULL == req->prep) |
1047 | { | 1047 | { |
1048 | D("Creating prepared statement for %s - %s", req->table, req->where); | ||
1048 | req->flds = dbGetFields(req->db, req->table); | 1049 | req->flds = dbGetFields(req->db, req->table); |
1049 | if (NULL == req->flds) | 1050 | if (NULL == req->flds) |
1050 | { | 1051 | { |
@@ -1089,6 +1090,8 @@ void dbDoSomething(dbRequest *req, boolean count, ...) | |||
1089 | d("New SQL statement - %s", req->sql); | 1090 | d("New SQL statement - %s", req->sql); |
1090 | // prepare statement with the other fields | 1091 | // prepare statement with the other fields |
1091 | req->prep = mysql_stmt_init(req->db); | 1092 | req->prep = mysql_stmt_init(req->db); |
1093 | // Save the pointer before something mysteriously clobbers it, so we can close it later. | ||
1094 | req->prep0 = req->prep; | ||
1092 | if (NULL == req->prep) | 1095 | if (NULL == req->prep) |
1093 | { | 1096 | { |
1094 | E("Statement prepare init failed: %s\n", mysql_stmt_error(req->prep)); | 1097 | E("Statement prepare init failed: %s\n", mysql_stmt_error(req->prep)); |
@@ -1661,6 +1664,15 @@ end: | |||
1661 | double n = (now.tv_sec * 1000000000.0) + now.tv_nsec; | 1664 | double n = (now.tv_sec * 1000000000.0) + now.tv_nsec; |
1662 | double t = (then.tv_sec * 1000000000.0) + then.tv_nsec; | 1665 | double t = (then.tv_sec * 1000000000.0) + then.tv_nsec; |
1663 | T("dbDoSomething(%s) took %lf seconds", req->sql, (n - t) / 1000000000.0); | 1666 | T("dbDoSomething(%s) took %lf seconds", req->sql, (n - t) / 1000000000.0); |
1667 | if (NULL != req->prep) | ||
1668 | I("The prepared statement itself is NOT NULL."); | ||
1669 | else | ||
1670 | W("The prepared statement itself is NULL!"); | ||
1671 | |||
1672 | if (NULL != req->prep0) | ||
1673 | I("The prepared0 statement itself is NOT NULL."); | ||
1674 | else | ||
1675 | W("The prepared0 statement itself is NULL!"); | ||
1664 | return; | 1676 | return; |
1665 | } | 1677 | } |
1666 | 1678 | ||
@@ -1692,7 +1704,24 @@ void dbFreeRequest(dbRequest *req) | |||
1692 | { | 1704 | { |
1693 | int i; | 1705 | int i; |
1694 | 1706 | ||
1707 | // TODO - this leaks for some bizare reason. Not even req->sql survives. | ||
1695 | D("Cleaning up prepared database request %s - %s %d %d", req->table, req->where, req->outCount, req->inCount); | 1708 | D("Cleaning up prepared database request %s - %s %d %d", req->table, req->where, req->outCount, req->inCount); |
1709 | |||
1710 | if (NULL != req->prep) | ||
1711 | I("The prepared statement itself is NOT NULL."); | ||
1712 | else | ||
1713 | W("The prepared statement itself is NULL!"); | ||
1714 | |||
1715 | if (NULL != req->prep0) | ||
1716 | I("The prepared0 statement itself is NOT NULL."); | ||
1717 | else | ||
1718 | W("The prepared0 statement itself is NULL!"); | ||
1719 | |||
1720 | if (NULL != req->flds) | ||
1721 | dbFreeFields(req->flds); | ||
1722 | else | ||
1723 | D("No fields to clean up for %s - %s.", req->table, req->where); | ||
1724 | |||
1696 | if (NULL != req->outBind) | 1725 | if (NULL != req->outBind) |
1697 | { | 1726 | { |
1698 | d("Free outBind"); | 1727 | d("Free outBind"); |
@@ -1706,13 +1735,14 @@ d("Free outBind %d %s", i, req->sql); | |||
1706 | } | 1735 | } |
1707 | free(req->outBind); | 1736 | free(req->outBind); |
1708 | } | 1737 | } |
1738 | else | ||
1739 | D("No out binds to clean up for %s - %s.", req->table, req->where); | ||
1709 | if (NULL != req->inBind) | 1740 | if (NULL != req->inBind) |
1710 | { | 1741 | { |
1711 | d("Free inBind"); | 1742 | d("Free inBind"); |
1712 | for (i = 0; i < req->inCount; i++) | 1743 | for (i = 0; i < req->inCount; i++) |
1713 | { | 1744 | { |
1714 | d("Free inBind %d %s", i, req->sql); | 1745 | d("Free inBind %d %s", i, req->sql); |
1715 | // TODO - this leaks for some bizare reason. | ||
1716 | if (NULL != req->inBind[i].buffer) free(req->inBind[i].buffer); | 1746 | if (NULL != req->inBind[i].buffer) free(req->inBind[i].buffer); |
1717 | if (NULL != req->inBind[i].length) free(req->inBind[i].length); | 1747 | if (NULL != req->inBind[i].length) free(req->inBind[i].length); |
1718 | if (NULL != req->inBind[i].error) free(req->inBind[i].error); | 1748 | if (NULL != req->inBind[i].error) free(req->inBind[i].error); |
@@ -1720,15 +1750,25 @@ d("Free inBind %d %s", i, req->sql); | |||
1720 | } | 1750 | } |
1721 | free(req->inBind); | 1751 | free(req->inBind); |
1722 | } | 1752 | } |
1753 | else | ||
1754 | D("No in binds to clean up for %s - %s.", req->table, req->where); | ||
1723 | 1755 | ||
1724 | if (req->freeOutParams) free(req->outParams); | 1756 | if (req->freeOutParams) free(req->outParams); |
1757 | else | ||
1758 | D("No out params to clean up for %s - %s.", req->table, req->where); | ||
1725 | if (NULL != req->sql) free(req->sql); | 1759 | if (NULL != req->sql) free(req->sql); |
1726 | if (NULL != req->prep) | 1760 | else |
1761 | D("No SQL to clean up for %s - %s.", req->table, req->where); | ||
1762 | if (NULL != req->prep0) | ||
1727 | { | 1763 | { |
1728 | if (0 != mysql_stmt_close(req->prep)) | 1764 | // TODO - this leaks for some bizare reason. |
1729 | C("Unable to close the prepared statement!"); | 1765 | D(" Cleaning up the prepared statement."); |
1730 | free(req->prep); | 1766 | if (0 != mysql_stmt_close(req->prep0)) |
1767 | C(" Unable to close the prepared statement!"); | ||
1768 | free(req->prep0); | ||
1731 | } | 1769 | } |
1770 | else | ||
1771 | W(" The prepared statement itself is NULL!"); | ||
1732 | } | 1772 | } |
1733 | 1773 | ||
1734 | my_ulonglong dbCount(MYSQL *db, char *table, char *where) | 1774 | my_ulonglong dbCount(MYSQL *db, char *table, char *where) |
@@ -5124,7 +5164,7 @@ void inputFieldExtra(inputField *ret, signed char flags, short viewLength, short | |||
5124 | 5164 | ||
5125 | void addSession(inputForm *iF) | 5165 | void addSession(inputForm *iF) |
5126 | { | 5166 | { |
5127 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); | 5167 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! |
5128 | 5168 | ||
5129 | //d("addSession(%s)", iF->name); | 5169 | //d("addSession(%s)", iF->name); |
5130 | flds[0] = addInputField(iF, LUA_TSTRING, "hashish", "hashish", "", sessionValidate, sessionWeb); | 5170 | flds[0] = addInputField(iF, LUA_TSTRING, "hashish", "hashish", "", sessionValidate, sessionWeb); |
@@ -5140,7 +5180,7 @@ void addSession(inputForm *iF) | |||
5140 | 5180 | ||
5141 | void addEmailFields(inputForm *iF) | 5181 | void addEmailFields(inputForm *iF) |
5142 | { | 5182 | { |
5143 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); | 5183 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! |
5144 | 5184 | ||
5145 | flds[0] = addInputField(iF, LUA_TEMAIL, "email", "email", NULL, emailValidate, emailWeb); | 5185 | flds[0] = addInputField(iF, LUA_TEMAIL, "email", "email", NULL, emailValidate, emailWeb); |
5146 | inputFieldExtra(flds[0], FLD_EDITABLE, 42, 254); | 5186 | inputFieldExtra(flds[0], FLD_EDITABLE, 42, 254); |
@@ -5156,7 +5196,7 @@ void addEmailFields(inputForm *iF) | |||
5156 | 5196 | ||
5157 | void addDoBFields(inputForm *iF) | 5197 | void addDoBFields(inputForm *iF) |
5158 | { | 5198 | { |
5159 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); | 5199 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! |
5160 | 5200 | ||
5161 | flds[0] = addInputField(iF, LUA_TSTRING, "DoByear", "year", NULL, DoBValidate, DoByWeb); | 5201 | flds[0] = addInputField(iF, LUA_TSTRING, "DoByear", "year", NULL, DoBValidate, DoByWeb); |
5162 | flds[1] = addInputField(iF, LUA_TSTRING, "DoBmonth", "month", NULL, DoBValidate, DoBmWeb); | 5202 | flds[1] = addInputField(iF, LUA_TSTRING, "DoBmonth", "month", NULL, DoBValidate, DoBmWeb); |
@@ -5169,7 +5209,7 @@ void addDoBFields(inputForm *iF) | |||
5169 | 5209 | ||
5170 | void addLegalFields(inputForm *iF) | 5210 | void addLegalFields(inputForm *iF) |
5171 | { | 5211 | { |
5172 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); | 5212 | inputField *fld, **flds = xzalloc(3 * sizeof(*flds)); // LEAKY! |
5173 | 5213 | ||
5174 | flds[0] = addInputField(iF, LUA_TBOOLEAN, "adult", "I'm allegedly an adult in my country.", NULL, legalValidate, adultWeb); | 5214 | flds[0] = addInputField(iF, LUA_TBOOLEAN, "adult", "I'm allegedly an adult in my country.", NULL, legalValidate, adultWeb); |
5175 | flds[1] = addInputField(iF, LUA_TBOOLEAN, "agree", "I accept the Terms of Service.", NULL, legalValidate, agreeWeb); | 5215 | flds[1] = addInputField(iF, LUA_TBOOLEAN, "agree", "I accept the Terms of Service.", NULL, legalValidate, agreeWeb); |
@@ -5667,10 +5707,15 @@ static void cleanup(void) | |||
5667 | 5707 | ||
5668 | while (NULL != (req = (dbRequest *) dbRequests->getat(dbRequests, 0, NULL, false))) | 5708 | while (NULL != (req = (dbRequest *) dbRequests->getat(dbRequests, 0, NULL, false))) |
5669 | { | 5709 | { |
5670 | if (NULL != req->flds) | 5710 | if (NULL != req->prep) |
5671 | dbFreeFields(req->flds); | 5711 | I("The prepared statement itself is NOT NULL."); |
5672 | else | 5712 | else |
5673 | D("No fields to clean up for %s - %s.", req->table, req->where); | 5713 | W("The prepared statement itself is NULL!"); |
5714 | |||
5715 | if (NULL != req->prep0) | ||
5716 | I("The prepared0 statement itself is NOT NULL."); | ||
5717 | else | ||
5718 | W("The prepared0 statement itself is NULL!"); | ||
5674 | dbFreeRequest(req); | 5719 | dbFreeRequest(req); |
5675 | dbRequests->removefirst(dbRequests); | 5720 | dbRequests->removefirst(dbRequests); |
5676 | } | 5721 | } |