Dev/server malloc check (#1023)

* usleep in communication to actually relay the err message of memory allocation to the client (weird but test for now), function in server to handle memory allcoation issues (updates mess, ret and sendsit to the client and returns prior from function implementatin, setting fnum in client for the speicific functions that send to detector each argument separtely, they need to remember the fnum else they throw with the incorrect fnum
* server: every malloc must check if it succeeded, rearranging so that the free is clear as well (only in funcs so far)
* fixed malloc checks in other places other than funcs.c
This commit is contained in:
2024-11-18 09:46:21 +01:00
committed by GitHub
parent 5088e5a205
commit e1497f9cb9
14 changed files with 353 additions and 282 deletions

View File

@ -140,7 +140,7 @@ void checkVirtual9MFlag();
void setupFebBeb();
#endif
#if defined(EIGERD) || defined(MYTHEN3D)
void allocateDetectorStructureMemory();
int allocateDetectorStructureMemory();
#endif
void setupDetector();
#if defined(CHIPTESTBOARDD)

View File

@ -11,6 +11,8 @@
// initialization functions
int updateModeAllowedFunction(int file_des);
int printSocketReadError();
int sendError(int file_des);
void setMemoryAllocationErrorMessage();
void init_detector();
int decode_function(int);
const char *getRetName();

View File

@ -590,13 +590,16 @@ int Server_SendResult(int fileDes, intType itype, void *retval,
sendData(fileDes, &ret1, sizeof(ret1), INT32);
if (ret == FAIL) {
// send error message
if (strlen(mess))
if (strlen(mess)) {
sendData(fileDes, mess, MAX_STR_LENGTH, OTHER);
usleep(0); // test
}
// debugging feature. should not happen.
else
else {
LOG(logERROR, ("No error message provided for this failure in %s "
"server. Will mess up TCP.\n",
(isControlServer ? "control" : "stop")));
}
}
// send return value
sendData(fileDes, retval, retvalSize, itype);

View File

@ -115,6 +115,28 @@ int printSocketReadError() {
return FAIL;
}
int sendError(int file_des) {
ret = FAIL;
LOG(logERROR, (mess));
Server_SendResult(file_des, INT32, NULL, 0);
return ret;
}
void setMemoryAllocationErrorMessage() {
struct sysinfo info;
sysinfo(&info);
sprintf(
mess,
"Memory allocation error (%s). Available space: %d MB. Please reboot",
getFunctionNameFromEnum((enum detFuncs)fnum),
(int)(info.freeram / (1024 * 1024)));
#ifdef EIGERD
strcat(mess, ".\n");
#else
strcat(mess, " using sls_detector_put rebootcontroller.\n");
#endif
}
void init_detector() {
memset(udpDetails, 0, sizeof(udpDetails));
#ifdef VIRTUAL
@ -1728,67 +1750,45 @@ int get_module(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
sls_detector_module module;
int *myDac = NULL;
int *myChan = NULL;
module.dacs = NULL;
module.chanregs = NULL;
#if !defined(MYTHEN3D) && !defined(EIGERD)
functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0);
#else
// allocate to receive module structure
// allocate dacs
myDac = malloc(getNumberOfDACs() * sizeof(int));
// error
if (getNumberOfDACs() > 0 && myDac == NULL) {
ret = FAIL;
sprintf(mess, "Could not allocate dacs\n");
LOG(logERROR, (mess));
} else
module.dacs = myDac;
// allocate chans
if (ret == OK) {
myChan = malloc(getTotalNumberOfChannels() * sizeof(int));
if (getTotalNumberOfChannels() > 0 && myChan == NULL) {
ret = FAIL;
strcpy(mess, "Could not allocate chans\n");
LOG(logERROR, (mess));
} else
module.chanregs = myChan;
int ndac = getNumberOfDACs();
int nchan = getTotalNumberOfChannels();
if (ndac <= 0 || nchan <= 0) {
strcpy(mess, "Invalid number of dacs/channels to set module\n");
return sendError(file_des);
}
// receive module structure
if (ret == OK) {
module.nchip = getNumberOfChips();
module.nchan = getTotalNumberOfChannels();
module.ndac = getNumberOfDACs();
// ensure nchan is not 0, else trimbits not copied
if (module.nchan == 0) {
strcpy(mess, "Could not get module as the number of channels to "
"copy is 0\n");
LOG(logERROR, (mess));
return FAIL;
}
getModule(&module);
}
#endif
Server_SendResult(file_des, INT32, NULL, 0);
if (ret != FAIL) {
if (sendModule(file_des, &module) < 0) {
ret = FAIL;
strcpy(mess, "Could not send module data\n");
LOG(logERROR, (mess));
}
}
if (myChan != NULL)
free(myChan);
if (myDac != NULL)
sls_detector_module module;
module.dacs = NULL;
module.chanregs = NULL;
int *myDac = malloc(ndac * sizeof(int));
int *myChan = malloc(nchan * sizeof(int));
if (myDac == NULL || myChan == NULL) {
free(myDac);
free(myChan);
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
module.dacs = myDac;
module.ndac = ndac;
module.chanregs = myChan;
module.nchan = nchan;
module.nchip = getNumberOfChips();
getModule(&module);
Server_SendResult(file_des, INT32, NULL, 0);
if (ret == OK && sendModule(file_des, &module) < 0) {
strcpy(mess, "Could not send module data\n");
ret = FAIL;
LOG(logERROR, (mess));
}
free(myChan);
free(myDac);
return ret;
#endif
}
int set_module(int file_des) {
@ -1798,63 +1798,53 @@ int set_module(int file_des) {
#if !(defined(MYTHEN3D) || defined(EIGERD))
functionNotImplemented();
#else
int ndac = getNumberOfDACs();
int nchan = getTotalNumberOfChannels();
if (ndac <= 0 || nchan <= 0) {
strcpy(mess, "Invalid number of dacs/channels to set module\n");
return sendError(file_des);
}
sls_detector_module module;
int *myDac = NULL;
int *myChan = NULL;
module.dacs = NULL;
module.chanregs = NULL;
// allocate to receive arguments
// allocate dacs
myDac = malloc(getNumberOfDACs() * sizeof(int));
// error
if (getNumberOfDACs() > 0 && myDac == NULL) {
ret = FAIL;
strcpy(mess, "Could not allocate dacs\n");
LOG(logERROR, (mess));
} else
module.dacs = myDac;
// allocate chans
if (ret == OK) {
myChan = malloc(getTotalNumberOfChannels() * sizeof(int));
if (getTotalNumberOfChannels() > 0 && myChan == NULL) {
ret = FAIL;
strcpy(mess, "Could not allocate chans\n");
LOG(logERROR, (mess));
} else
module.chanregs = myChan;
int *myDac = malloc(ndac * sizeof(int));
int *myChan = malloc(nchan * sizeof(int));
if (myDac == NULL || myChan == NULL) {
free(myDac);
free(myChan);
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
// receive arguments
if (ret == OK) {
module.nchip = getNumberOfChips();
module.nchan = getTotalNumberOfChannels();
module.ndac = getNumberOfDACs();
int ts = receiveModule(file_des, &module);
if (ts < 0) {
free(myChan);
free(myDac);
return printSocketReadError();
}
LOG(logDEBUG1, ("module register is %d, nchan %d, nchip %d, "
"ndac %d, iodelay %d, tau %d, eV %d\n",
module.reg, module.nchan, module.nchip, module.ndac,
module.iodelay, module.tau, module.eV[0]));
// should at least have a dac
if (ts <= (int)sizeof(sls_detector_module)) {
ret = FAIL;
strcpy(mess, "Cannot set module. Received incorrect number of "
"dacs or channels\n");
LOG(logERROR, (mess));
}
module.dacs = myDac;
module.ndac = ndac;
module.chanregs = myChan;
module.nchan = nchan;
module.nchip = getNumberOfChips();
int ts = receiveModule(file_des, &module);
if (ts < 0) {
free(myChan);
free(myDac);
return printSocketReadError();
}
LOG(logDEBUG1, ("module register is %d, nchan %d, nchip %d, "
"ndac %d, iodelay %d, tau %d, eV %d\n",
module.reg, module.nchan, module.nchip, module.ndac,
module.iodelay, module.tau, module.eV[0]));
// should at least have a dac
if (ts <= (int)sizeof(sls_detector_module)) {
strcpy(mess, "Cannot set module. Received incorrect number of "
"dacs or channels\n");
free(myChan);
free(myDac);
return sendError(file_des);
}
// only set
if (ret == OK && Server_VerifyLock() == OK) {
if (Server_VerifyLock() == OK) {
// check index
// setsettings
// setsettings
#ifndef MYTHEN3D
// m3 uses reg for chip (not settings)
validate_settings((enum detectorSettings)(module.reg));
@ -1867,10 +1857,8 @@ int set_module(int file_des) {
#endif
LOG(logDEBUG1, ("Settings: %d\n", retval));
}
if (myChan != NULL)
free(myChan);
if (myDac != NULL)
free(myDac);
free(myChan);
free(myDac);
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
@ -2957,6 +2945,7 @@ int get_frames_left(int file_des) {
retval = getNumFramesLeft();
LOG(logDEBUG1, ("retval num frames left %lld\n", (long long int)retval));
#endif
return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
}
@ -6549,6 +6538,10 @@ int set_veto_photon(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
int args[2] = {-1, -1};
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
@ -6556,14 +6549,17 @@ int set_veto_photon(int file_des) {
const int numChannels = args[1];
int *gainIndices = malloc(sizeof(int) * numChannels);
if (receiveData(file_des, gainIndices, sizeof(int) * numChannels, INT32) <
0) {
int *values = malloc(sizeof(int) * numChannels);
if (gainIndices == NULL || values == NULL) {
free(gainIndices);
return printSocketReadError();
free(values);
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
int *values = malloc(sizeof(int) * numChannels);
if (receiveData(file_des, values, sizeof(int) * numChannels, INT32) < 0) {
if ((receiveData(file_des, gainIndices, sizeof(int) * numChannels, INT32) <
0) ||
(receiveData(file_des, values, sizeof(int) * numChannels, INT32)) < 0) {
free(gainIndices);
free(values);
return printSocketReadError();
@ -6572,9 +6568,6 @@ int set_veto_photon(int file_des) {
LOG(logINFO, ("Setting Veto Photon: [chipIndex:%d, nch:%d]\n", chipIndex,
numChannels));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
if (numChannels != NCHAN) {
@ -6621,66 +6614,60 @@ int set_veto_photon(int file_des) {
}
}
}
free(gainIndices);
free(values);
#endif
if (gainIndices != NULL) {
free(gainIndices);
}
if (values != NULL) {
free(values);
}
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_veto_photon(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = -1;
int *retvals = NULL;
int *gainRetvals = NULL;
#ifndef GOTTHARD2D
functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0);
#else
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Getting veto photon [chip Index:%d]\n", arg));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
retvals = malloc(sizeof(int) * NCHAN);
gainRetvals = malloc(sizeof(int) * NCHAN);
int *retvals = malloc(sizeof(int) * NCHAN);
int *gainRetvals = malloc(sizeof(int) * NCHAN);
if (gainRetvals == NULL || retvals == NULL) {
free(gainRetvals);
free(retvals);
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
memset(retvals, 0, sizeof(int) * NCHAN);
memset(gainRetvals, 0, sizeof(int) * NCHAN);
if (retvals == NULL || gainRetvals == NULL) {
// get only
int chipIndex = arg;
if (chipIndex < -1 || chipIndex >= NCHIP) {
ret = FAIL;
strcpy(
mess,
"Could not get veto photon. Could not allocate memory in server\n");
sprintf(mess, "Could not get veto photon. Invalid chip index %d\n",
chipIndex);
LOG(logERROR, (mess));
} else {
// get only
int chipIndex = arg;
if (chipIndex < -1 || chipIndex >= NCHIP) {
ret = FAIL;
sprintf(mess, "Could not get veto photon. Invalid chip index %d\n",
chipIndex);
ret = getVetoPhoton(chipIndex, retvals, gainRetvals);
if (ret == FAIL) {
strcpy(mess, "Could not get veto photon for chipIndex -1. Not the "
"same for all chips. Select specific chip index "
"instead.\n");
LOG(logERROR, (mess));
} else {
ret = getVetoPhoton(chipIndex, retvals, gainRetvals);
if (ret == FAIL) {
strcpy(mess,
"Could not get veto photon for chipIndex -1. Not the "
"same for all chips. Select specific chip index "
"instead.\n");
LOG(logERROR, (mess));
} else {
for (int i = 0; i < NCHAN; ++i) {
LOG(logDEBUG1,
("%d:[%d, %d]\n", i, retvals[i], gainRetvals[i]));
}
for (int i = 0; i < NCHAN; ++i) {
LOG(logDEBUG1,
("%d:[%d, %d]\n", i, retvals[i], gainRetvals[i]));
}
}
}
#endif
Server_SendResult(file_des, INT32, NULL, 0);
if (ret != FAIL) {
int nch = NCHAN;
@ -6688,13 +6675,10 @@ int get_veto_photon(int file_des) {
sendData(file_des, gainRetvals, sizeof(int) * NCHAN, INT32);
sendData(file_des, retvals, sizeof(int) * NCHAN, INT32);
}
if (retvals != NULL) {
free(retvals);
}
if (gainRetvals != NULL) {
free(gainRetvals);
}
free(retvals);
free(gainRetvals);
return ret;
#endif
}
int set_veto_reference(int file_des) {
@ -7864,16 +7848,19 @@ int set_pattern(int file_des) {
functionNotImplemented();
#else
patternParameters *pat = malloc(sizeof(patternParameters));
if (pat == NULL) {
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
memset(pat, 0, sizeof(patternParameters));
// ignoring endianness for eiger
if (receiveData(file_des, pat, sizeof(patternParameters), INT32) < 0) {
if (pat != NULL)
free(pat);
free(pat);
return printSocketReadError();
}
if (receiveData(file_des, args, MAX_STR_LENGTH, OTHER) < 0) {
if (pat != NULL)
free(pat);
free(pat);
return printSocketReadError();
}
@ -7881,8 +7868,7 @@ int set_pattern(int file_des) {
LOG(logDEBUG1, ("Setting Pattern from structure\n"));
ret = loadPattern(mess, logINFO, pat, args);
}
if (pat != NULL)
free(pat);
free(pat);
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
@ -7918,6 +7904,10 @@ int get_pattern(int file_des) {
#else
patternParameters *pat = malloc(sizeof(patternParameters));
if (pat == NULL) {
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
memset(pat, 0, sizeof(patternParameters));
if (Server_VerifyLock() == OK) {
@ -7927,8 +7917,7 @@ int get_pattern(int file_des) {
// ignoring endianness for eiger
int ret =
Server_SendResult(file_des, INT32, pat, sizeof(patternParameters));
if (pat != NULL)
free(pat);
free(pat);
return ret;
#endif
}
@ -8036,10 +8025,13 @@ int set_scan(int file_des) {
if (ret == OK) {
scan = 1;
numScanSteps = (abs(stop - start) / abs(step)) + 1;
if (scanSteps != NULL) {
free(scanSteps);
}
// freed only at startup of the next scan
free(scanSteps);
scanSteps = malloc(numScanSteps * sizeof(int));
if (scanSteps == NULL) {
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
for (int i = 0; i != numScanSteps; ++i) {
scanSteps[i] = start + i * step;
LOG(logDEBUG1, ("scansteps[%d]:%d\n", i, scanSteps[i]));
@ -8313,55 +8305,54 @@ int set_adc_config(int file_des) {
int get_bad_channels(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int nretvals = 0;
int *retvals = NULL;
LOG(logDEBUG1, ("Getting bad channels\n"));
#if !defined(GOTTHARD2D) && !defined(MYTHEN3D)
functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0);
#else
// get only
retvals = getBadChannels(&nretvals);
int nretvals = 0;
int *retvals = getBadChannels(&nretvals);
if (nretvals == -1) {
ret = FAIL;
strcpy(mess, "Could not get bad channels. Memory allcoation error\n");
LOG(logERROR, (mess));
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
#endif
Server_SendResult(file_des, INT32, NULL, 0);
if (ret != FAIL) {
sendData(file_des, &nretvals, sizeof(nretvals), INT32);
if (nretvals > 0) {
sendData(file_des, retvals, sizeof(int) * nretvals, INT32);
}
}
if (retvals != NULL) {
free(retvals);
sendData(file_des, &nretvals, sizeof(nretvals), INT32);
if (nretvals > 0) {
sendData(file_des, retvals, sizeof(int) * nretvals, INT32);
}
free(retvals);
return ret;
#endif
}
int set_bad_channels(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int nargs = 0;
int *args = NULL;
if (receiveData(file_des, &nargs, sizeof(nargs), INT32) < 0)
return printSocketReadError();
if (nargs > 0) {
args = malloc(nargs * sizeof(int));
if (receiveData(file_des, args, nargs * sizeof(int), INT32) < 0)
return printSocketReadError();
}
LOG(logDEBUG1, ("Setting %d bad channels\n", nargs));
#if !defined(GOTTHARD2D) && !defined(MYTHEN3D)
functionNotImplemented();
#else
int nargs = 0;
if (receiveData(file_des, &nargs, sizeof(nargs), INT32) < 0)
return printSocketReadError();
int *args = NULL;
if (nargs > 0) {
args = malloc(nargs * sizeof(int));
if (args == NULL) {
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
if (receiveData(file_des, args, nargs * sizeof(int), INT32) < 0) {
free(args);
return printSocketReadError();
}
}
LOG(logDEBUG1, ("Setting %d bad channels\n", nargs));
// only set
if (Server_VerifyLock() == OK) {
// validate bad channel number
@ -8390,11 +8381,11 @@ int set_bad_channels(int file_des) {
int nretvals = 0;
int *retvals = getBadChannels(&nretvals);
if (nretvals == -1) {
ret = FAIL;
strcpy(mess, "Could not get bad channels. Memory "
"allcoation error\n");
LOG(logERROR, (mess));
} else if (nretvals != nargs) {
free(args);
setMemoryAllocationErrorMessage();
return sendError(file_des);
}
if (nretvals != nargs) {
ret = FAIL;
sprintf(mess,
"Could not set bad channels. Set %d channels, but "
@ -8403,15 +8394,11 @@ int set_bad_channels(int file_des) {
nargs, nretvals);
LOG(logERROR, (mess));
}
if (retvals != NULL) {
free(retvals);
}
free(retvals);
}
}
}
if (args != NULL) {
free(args);
}
free(args);
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
@ -9940,14 +9927,9 @@ void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
src = malloc(MAX_BLACKFIN_PROGRAM_SIZE);
if (src == NULL) {
fclose(fd);
struct sysinfo info;
sysinfo(&info);
sprintf(mess,
"Could not %s. Memory allocation failure. Free "
"space: %d MB\n",
functionType, (int)(info.freeram / (1024 * 1024)));
LOG(logERROR, (mess));
setMemoryAllocationErrorMessage();
ret = FAIL;
LOG(logERROR, (mess));
}
}
Server_SendResult(file_des, INT32, NULL, 0);
@ -10090,6 +10072,7 @@ void receive_program_default(int file_des, enum PROGRAM_INDEX index,
}
Server_SendResult(file_des, INT32, NULL, 0);
if (ret == FAIL) {
free(src);
return;
}