We have a simple stored procedure call to DB2, where one of the parameters is a BINARY output parameter. We have tried both leaving the Data as the default string type and setting it to a Buffer; in both cases, node crashes due to a double memory free. This bug report is for the case of using a String type, although I believe it will fail in the same way with any non-Buffer type. I opened #942 for Buffer types, since it's a different bug.
This bug was introduced in version 3.0 of ibm_db. I confirmed this by testing different levels of ibm_db (all with version 11.5.8 of the ODBC driver). Version 2.8.1 and 2.8.2 ran under load for 24 hours each with no crashes. Versions 3.0 and 3.2.1 crashed approx every 30 minutes under load with various messages:
The issue is that in this case, Nan::NewBuffer() will be used in GetOutputParameter() to return the data, but isBuffer will not be set to true, and FREE_PARAMS() will free the memory.
If the input parameter is NOT a Buffer (as in this case, where it's a string), then e.g. GetStringParam() will be called from GetParametersFromArray(), and isBuffer will remain false.
Later, in GetOutputParameter(), after the query completes, is this code:
if(sqlTypeBinary || prm.c_type == SQL_C_BINARY) {
//str = Nan::NewOneByteString((uint8_t *) prm.buffer, prm.length).ToLocalChecked();
//prm.buffer will be freed by Garbage collector, no need to free here.
return scope.Escape(Nan::NewBuffer((char *)prm.buffer, prm.length).ToLocalChecked());
}
The issue is that prm.c_type is SQL_C_BINARY, so this code will be executed, however, prm.isBuffer is false, so the test in the FREE_PARAMS() macro will not fire, and it will free the memory:
if (prm = params[i], prm.buffer != NULL && !prm.isBuffer) { \
// <either a delete or free here>
} \
I confirmed this by adding a logging statement inside that if() statement in GetOutputParameter():
I've also noticed that the output string is also random every time you execute the query; that is also a manifestation of the same bug, using memory that technically is freed and being used by something else.
System: Linux x86_64 (Bullseye), node v18.16.1
We have a simple stored procedure call to DB2, where one of the parameters is a BINARY output parameter. We have tried both leaving the Data as the default string type and setting it to a Buffer; in both cases, node crashes due to a double memory free. This bug report is for the case of using a String type, although I believe it will fail in the same way with any non-Buffer type. I opened #942 for Buffer types, since it's a different bug.
This bug was introduced in version 3.0 of ibm_db. I confirmed this by testing different levels of ibm_db (all with version 11.5.8 of the ODBC driver). Version 2.8.1 and 2.8.2 ran under load for 24 hours each with no crashes. Versions 3.0 and 3.2.1 crashed approx every 30 minutes under load with various messages:
This is the DB2 query:
The parameters are:
The call to ibm_db looks like:
The issue is that in this case, Nan::NewBuffer() will be used in GetOutputParameter() to return the data, but
isBuffer
will not be set to true, and FREE_PARAMS() will free the memory.If the input parameter is NOT a Buffer (as in this case, where it's a string), then e.g. GetStringParam() will be called from GetParametersFromArray(), and
isBuffer
will remain false.Later, in GetOutputParameter(), after the query completes, is this code:
The issue is that prm.c_type is SQL_C_BINARY, so this code will be executed, however, prm.isBuffer is false, so the test in the FREE_PARAMS() macro will not fire, and it will free the memory:
I confirmed this by adding a logging statement inside that if() statement in GetOutputParameter():
And you can see it show up in the log:
I've also noticed that the output string is also random every time you execute the query; that is also a manifestation of the same bug, using memory that technically is freed and being used by something else.
I created PR #945 to fix this.