Bug#19454: Some values of MaxNoOfTriggers can stop a server

correct segment fault in setSize(), 
and improve the error message with displaying the specific parameter's name if malloc fail
parent 0192e8ab
...@@ -310,7 +310,7 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) ...@@ -310,7 +310,7 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
c_storedProcPool.setSize(noOfStoredProc); c_storedProcPool.setSize(noOfStoredProc);
c_buildIndexPool.setSize(c_noOfBuildIndexRec); c_buildIndexPool.setSize(c_noOfBuildIndexRec);
c_triggerPool.setSize(noOfTriggers); c_triggerPool.setSize(noOfTriggers, false, true, true, CFG_DB_NO_TRIGGERS);
c_extent_hash.setSize(1024); // 4k c_extent_hash.setSize(1024); // 4k
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <ErrorReporter.hpp> #include <ErrorReporter.hpp>
#include <NdbMem.h> #include <NdbMem.h>
#include <Bitmask.hpp> #include <Bitmask.hpp>
#include <mgmapi.h>
template <class T> class Array; template <class T> class Array;
...@@ -43,7 +44,8 @@ public: ...@@ -43,7 +44,8 @@ public:
* *
* Note, can currently only be called once * Note, can currently only be called once
*/ */
bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true, bool guard = true); bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true,
bool guard = true, Uint32 paramId = 0);
bool set(T*, Uint32 cnt, bool align = false); bool set(T*, Uint32 cnt, bool align = false);
void clear() { theArray = 0; } void clear() { theArray = 0; }
...@@ -221,13 +223,19 @@ template <class T> ...@@ -221,13 +223,19 @@ template <class T>
inline inline
bool bool
ArrayPool<T>::setSize(Uint32 noOfElements, ArrayPool<T>::setSize(Uint32 noOfElements,
bool align, bool exit_on_error, bool guard){ bool align, bool exit_on_error, bool guard, Uint32 paramId){
if(size == 0){ if(size == 0){
if(noOfElements == 0) if(noOfElements == 0)
return true; return true;
Uint64 real_size = (Uint64)noOfElements * sizeof(T);
size_t req_size = (size_t)real_size;
Uint64 real_size_align = real_size + sizeof(T);
size_t req_size_align = (size_t)real_size_align;
if(align) if(align)
{ {
alloc_ptr = ndbd_malloc((noOfElements+1) * sizeof(T)); if((Uint64)req_size_align == real_size_align && req_size_align > 0)
alloc_ptr = ndbd_malloc(req_size_align);
UintPtr p = (UintPtr)alloc_ptr; UintPtr p = (UintPtr)alloc_ptr;
UintPtr mod = p % sizeof(T); UintPtr mod = p % sizeof(T);
if (mod) if (mod)
...@@ -236,14 +244,23 @@ ArrayPool<T>::setSize(Uint32 noOfElements, ...@@ -236,14 +244,23 @@ ArrayPool<T>::setSize(Uint32 noOfElements,
} }
theArray = (T *)p; theArray = (T *)p;
} }
else else if((Uint64)req_size == real_size && req_size > 0)
theArray = (T *)(alloc_ptr = ndbd_malloc(noOfElements * sizeof(T))); theArray = (T *)(alloc_ptr = ndbd_malloc(req_size));
if(theArray == 0) if(theArray == 0)
{ {
char errmsg[255] = "ArrayPool<T>::setSize malloc failed";
struct ndb_mgm_param_info param_info;
size_t size = sizeof(ndb_mgm_param_info);
if (!exit_on_error) if (!exit_on_error)
return false; return false;
ErrorReporter::handleAssert("ArrayPool<T>::setSize malloc failed",
if(0 != paramId && 0 == ndb_mgm_get_db_parameter_info(paramId, &param_info, &size)) {
BaseString::snprintf(errmsg, sizeof(errmsg),
"ArrayPool<T>::setSize malloc parameter %s failed", param_info.m_name);
}
ErrorReporter::handleAssert(errmsg,
__FILE__, __LINE__, NDBD_EXIT_MEMALLOC); __FILE__, __LINE__, NDBD_EXIT_MEMALLOC);
return false; // not reached return false; // not reached
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment