#ifdef ODU_MEMORY_DEBUG_LOG
#define MAC_MEM_LOG(_macro, _file, _line, _func, _size, _datPtr)\
{\
- printf("\n%s=== %s +%d, %s, %lu, %p \n", \
- _macro, _file, _line, _func, (uint64_t)_size, _datPtr); \
+ printf("\n%s,=== %s +%d, %s, %lu, %p \n", \
+ _macro, _file, _line, _func, (uint64_t)_size, _datPtr); \
}
#else
-#define MAC_MEM_LOG(_macro, _file, _line, _func, _size, _dataPtr){\
-}
+#define MAC_MEM_LOG(_macro, _file, _line, _func, _size, _dataPtr) {}
#endif
/* allocate and zero out a MAC static buffer */
if(_ret == ROK) \
{ \
memset(_datPtr, 0, _size); \
- MAC_MEM_LOG("MAC_ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
+ MAC_MEM_LOG("MAC,ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
} \
else \
{ \
{ \
if(_datPtr) \
{ \
- MAC_MEM_LOG("MAC_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
+ MAC_MEM_LOG("MAC,FREE", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
SPutSBuf(MAC_MEM_REGION, MAC_POOL, \
(Data *)_datPtr, _size); \
_datPtr = NULLP; \
if(SGetStaticBuffer(MAC_MEM_REGION, MAC_POOL, \
(Data **)&_buf, (Size) _size, 0) == ROK) \
{ \
- MAC_MEM_LOG("MAC_ALLOC_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ MAC_MEM_LOG("MAC,ALLOC_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
memset((_buf), 0, _size); \
} \
else \
{ \
if (_buf != NULLP) \
{ \
- MAC_MEM_LOG("MAC_FREE_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ MAC_MEM_LOG("MAC,FREE_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutStaticBuffer(_region, _pool, \
(Data *) _buf, (Size) _size, 0); \
_buf = NULLP; \
#ifdef ODU_MEMORY_DEBUG_LOG
#define RLC_MEM_LOG(_macro, _file, _line, _func, _size, _datPtr)\
{\
- printf("\n%s=== %s +%d, %s, %lu, %p \n", \
+ printf("\n%s,=== %s +%d, %s, %lu, %p \n", \
_macro, _file, _line, _func, (uint64_t)_size, _datPtr); \
}
#else
if (SGetSBuf(_cb->init.region, _cb->init.pool, (Data **)&_buf, \
(Size) _size) == ROK) \
{ \
- RLC_MEM_LOG("RLC_ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
memset((_buf), 0, _size); \
} \
else \
{ \
if (_buf != NULLP) \
{ \
- RLC_MEM_LOG("RLC_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,FREE", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutSBuf(_cb->init.region, _cb->init.pool, \
(Data *) _buf, (Size) _size); \
_buf = NULLP; \
{ \
if (_buf != NULLP) \
{ \
- RLC_MEM_LOG("RLC_FREE_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,FREE_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutStaticBuffer(_region, _pool, \
(Data *) _buf, (Size) _size, 0); \
_buf = NULLP; \
#define RLC_FREE_SHRABL_BUF_WC(_region, _pool,_buf, _size) \
{ \
if (_buf != NULLP){\
- RLC_MEM_LOG("RLC_FREE_SHRABL_BUF_WC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,FREE_SHRABL_BUF_WC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutStaticBuffer(_region, _pool, \
(Data *) _buf, (Size) _size, 0); \
_buf = NULLP; \
if(SGetStaticBuffer(_region, _pool, (Data **)&_buf, \
(Size) _size, 0)==ROK) \
{\
- RLC_MEM_LOG("RLC_ALLOC_SHRABL_BUF_WC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,ALLOC_SHRABL_BUF_WC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
}\
else\
{\
if (SGetStaticBuffer(_region, _pool, (Data **)&_buf, \
(Size) _size, 0) == ROK) \
{ \
- RLC_MEM_LOG("RLC_ALLOC_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,ALLOC_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
memset((_buf), 0, _size); \
} \
else \
{\
if(SGetSBuf(_cb->init.region, _cb->init.pool, (Data **)&_buf, (Size) _size) == ROK)\
{\
- RLC_MEM_LOG("RLC_ALLOC_WC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,ALLOC_WC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
}\
}
{ \
if(_sdu->mBuf) \
{ \
- RLC_MEM_LOG("RLC_REMOVE_SDU", __FILE__, __LINE__, __FUNCTION__, _sdu->sduSz, _sdu->mBuf);\
+ RLC_MEM_LOG("RLC,REMOVE_SDU", __FILE__, __LINE__, __FUNCTION__, _sdu->sduSz, _sdu->mBuf);\
ODU_PUT_MSG_BUF(_sdu->mBuf); \
} \
cmLListDelFrm(_sduQ,&_sdu->lstEnt); \
{ \
if (_buf != NULLP) \
{ \
- RLC_MEM_LOG("RLC_PST_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,PST_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutSBuf(_region, _pool, \
(Data *) _buf, (Size) _size); \
_buf = NULLP; \
{ \
if (_buf != NULLP) \
{ \
- RLC_MEM_LOG("RLC_SHRABL_STATIC_BUF_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,SHRABL_STATIC_BUF_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutStaticBuffer(_region, _pool, \
(Data *) _buf, (Size) _size, 0); \
_buf = NULLP; \
{ \
SGetStaticBuffer(_region, _pool, (Data **)&_buf, \
(Size) _size, 0); \
- RLC_MEM_LOG("RLC_SHRABL_STATIC_BUF_ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ RLC_MEM_LOG("RLC,SHRABL_STATIC_BUF_ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
}
#endif
#ifdef ODU_MEMORY_DEBUG_LOG
#define SCH_MEM_LOG(_macro, _file, _line, _func, _size, _datPtr)\
{\
- printf("\n%s=== %s +%d, %s, %lu, %p \n", \
+ printf("\n%s,=== %s +%d, %s, %lu, %p \n", \
_macro, _file, _line, _func, (uint64_t)_size, (void *)_datPtr); \
}
#else
-#define SCH_MEM_LOG(_macro, _file, _line, _func, _size, _dataPtr){\
-}
+#define SCH_MEM_LOG(_macro, _file, _line, _func, _size, _dataPtr) {}
#endif
#define SCH_ALLOC(_datPtr, _size) \
(Data **)&_datPtr, _size); \
if(_ret == ROK) \
{ \
+ SCH_MEM_LOG("SCH,ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
memset(_datPtr, 0, _size); \
- SCH_MEM_LOG("SCH_ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
} \
else \
{ \
{ \
if(_datPtr) \
{\
- SCH_MEM_LOG("SCH_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
+ SCH_MEM_LOG("SCH,FREE", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
SPutSBuf(SCH_MEM_REGION, SCH_POOL, \
(Data *)_datPtr,(Size) _size); \
_datPtr = NULLP; \
#ifdef ODU_MEMORY_DEBUG_LOG
if (strncmp(func,"cmInetRecvMsg",sizeof("cmInetRecvMsg")))
{
- printf("\nCM_ALLOC=== SGetSBufNewForDebug %s +%d, %s, %d, %p \n",\
+ printf("\nCM,ALLOC,=== SGetSBufNewForDebug %s +%d, %s, %d, %p \n",\
file, line, func, size, *ptr);
}
#endif
#ifdef ODU_MEMORY_DEBUG_LOG
if (strncmp(func,"cmInetRecvMsg",sizeof("cmInetRecvMsg")))
{
- printf("\nCM_FREE=== SPutSBufNewForDebug %s +%d, %s, %d, %p \n",\
+ printf("\nCM,FREE,=== SPutSBufNewForDebug %s +%d, %s, %d, %p \n",\
file, line, func, size, ptr);
}
#endif
if(SGetStaticBuffer(region, pool, ptr, size, memType) == ROK)
{
#ifdef ODU_MEMORY_DEBUG_LOG
- printf("\nCM_ALLOC=== SGetStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
+ printf("\nCM,ALLOC,=== SGetStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
file, line, func, size, *ptr);
#endif
return ROK;
if(SPutStaticBuffer(region, pool, ptr, size, memType) == ROK)
{
#ifdef ODU_MEMORY_DEBUG_LOG
- printf("\nCM_FREE=== SPutStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
+ printf("\nCM,FREE,=== SPutStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
file, line, func, size, ptr);
#endif
return ROK;
#ifdef ODU_MEMORY_DEBUG_LOG
#define DU_MEM_LOG(_macro, _file, _line, _func, _size, _datPtr)\
{\
- printf("\n%s=== %s +%d, %s, %lu, %p \n", \
+ printf("\n%s,=== %s +%d, %s, %lu, %p \n", \
_macro, _file, _line, _func, (uint64_t)_size, _datPtr); \
}
#else
-#define DU_MEM_LOG(_macro, _file, _line, _func, _size, _dataPtr) {\
-}
+#define DU_MEM_LOG(_macro, _file, _line, _func, _size, _dataPtr) {}
#endif
#define DU_ALLOC(_datPtr, _size) \
(Data **)&_datPtr, _size); \
if(_ret == ROK) \
{\
- DU_MEM_LOG("DU_ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
+ DU_MEM_LOG("DU,ALLOC", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
memset(_datPtr, 0, _size); \
}\
else \
{ \
if(_datPtr != NULLP) \
{ \
- DU_MEM_LOG("DU_FREE", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
+ DU_MEM_LOG("DU,FREE", __FILE__, __LINE__, __FUNCTION__, _size, _datPtr);\
SPutSBuf(DU_APP_MEM_REGION, DU_POOL, \
(Data *)_datPtr, _size); \
_datPtr = NULLP; \
if(SGetStaticBuffer(DU_APP_MEM_REGION, DU_POOL, \
(Data **)&_buf, (Size) _size, 0) == ROK) \
{ \
- DU_MEM_LOG("DU_ALLOC_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ DU_MEM_LOG("DU,ALLOC_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
memset((_buf), 0, _size); \
} \
else \
{ \
if (_buf != NULLP) \
{ \
- DU_MEM_LOG("DU_FREE_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
+ DU_MEM_LOG("DU,FREE_SHRABL_BUF", __FILE__, __LINE__, __FUNCTION__, _size, _buf);\
(Void) SPutStaticBuffer(_region, _pool, \
(Data *) _buf, (Size) _size, 0); \
_buf = NULLP; \
-sudo apt install -y libsctp-dev;cd odu;make clean_odu MACHINE=BIT64 MODE=TDD;make odu MACHINE=BIT64 MODE=TDD COVERAGE=1
+#!/bin/bash
+
+set -euxo pipefail
+
+echo "---> unit_test.sh"
+
+echo "Present working directory: "; pwd
+
+# Platform-specific install methods
+if (grep Ubuntu /etc/os-release > /dev/null 2>&1); then
+ echo "Installing libsctp-dev dependency for Ubuntu"
+ sudo apt-get update
+ sudo apt-get install -y libsctp-dev
+elif (grep RedHat /etc/os-release > /dev/null 2>&1) || \
+ (grep CentOS /etc/os-release > /dev/null 2>&1); then
+ echo "Installing lksctp-tools-devel dependency for CentOS/RedHat"
+ sudo yum install -y lksctp-tools-devel
+else
+ echo "Unmatched OS/Distribution"
+ echo "Missing sctp library not installed"
+fi
+
+echo "Running job"
+cd odu;make clean_odu MACHINE=BIT64 MODE=TDD;make odu MACHINE=BIT64 MODE=TDD COVERAGE=1
--- /dev/null
+Overview:
+This tool is used to identify memory leaks and invalid memory-handling operations present in ODU-High code. It helps in resolving segmentation fault and undefinded behaviour occuring due to memory corruption.
+
+Execution Steps
+1. Enable the platform flag in makefile of ODU-H binary.
+ a. vim l2/build/odu/makefile
+ b. Update the following line to enable flag "ODU_MEMORY_DEBUG_LOG"
+ PLTFRM_FLAGS= -UMSPD -DODU -DINTEL_FAPI -DODU_MEMORY_DEBUG_LOG
+
+2. Enable the CLA use-case in ODU-H flow i.e. add the trigger to bring the cell down.
+ (This is a hack to help us execute the complete scenario from Cell up to Down so that we can capture the memory status between them)
+ a. vim l2/src/du_app/du_egtp.c
+ In function egtpRecvMsg(), disable the infinite loop (while loop) of receiver EGTP thread.
+
+ b. vim l2/src/du_app/du_f1ap_msg_hdl.c
+ At the end of BuildAndSendUeContextModRsp() i.e. after sending UE Context Modification Response, add following line :
+ BuildAndSendDUConfigUpdate(SERV_CELL_TO_DELETE);
+
+2. Compile and generate all the three binaries : ODU, CU_STUB and RIC_STUB
+
+3. Execute the RIC_STUB and CU_STUB binaries first. Then execute ODU and capture its console logs.
+
+4. Once CELL down is complete at ODU, stop/kill the ODU binary and save the log file.
+
+5. Download this log file in your local system. Here we will segregate the logs for memory allocation and memory free.
+
+ a. Download Text Editor tool "TextAnalysisTool.NET.exe" placed at :
+ https://radisyscorp.sharepoint.com/sites/ODU/Shared%20Documents/General/Tools/TextAnalysisTool.NET.exe
+ b. Execute the tool and open the log file in this tool(File->Open)
+ c. Filter out the ALLOC and FREE log prints by following steps:
+ i. Filters -> Add New Filters. In the Pop-up window, enter "ALLOC". Check the box to enable "Case-sensitive". Press OK to add this filter.
+ ii. Repeat this step for "FREE" keyword
+ iii. Go to "View -> Show only Filtered Lines".
+ iv. Now enable ALLOC filters by clicking on the checkbox. The result will show only those lines from log_file
+ that contain substring "ALLOC". Copy all the filtered lines in excel sheet 1.
+ v. Uncheck filter for ALLOC and check the filter for FREE. The newly filtered lines show logs for memory free.
+ Copy these lines to excel sheet 2.
+
+ d. We need to filter out only memory size and address from filtered data copied to excel sheet
+ i. In excel, go to "Data -> Text to Columns". A pop-up window will show.
+ Step 1 : Choose "Delimited" , CLick Next>
+ Step 2 : Enable following Delimiters
+ Tabs, Semicolon, Comma
+ Step 3 : Click Finish
+ ii. Repeat above steps for both sheets
+ iii. Delete columns C and D to remove unwanted text. Now, the allocation/free type, size and address will be in columns B, C and D.
+ Copy all rows containing data of these columns (Ctrl+shift+Down arrow).
+
+6. Now we will pass the filtered data (from excel sheet) into Memory_Leak_Detetctor
+ a. Remove/delete following output files, if present from previous executions : "freeoutput.txt" and "allocoutput.txt"
+ b. Clean alloc.txt file for any prevoius entries. Now paste here, columns B, C and D copied from excel sheet 1.
+ c. Remove any double spaces in alloc.txt using vi editor command (:%s/ / /g). Use this command twice.
+ d. Follow above two steps for file "free.txt".
+ e. Execute ./a.out . Output files "freeoutput.txt" and "allocoutput.txt" are generated.
+
+7. Ideally, "freeoutput.txt" and "allocoutput.txt" should be empty.
+ a. Any entry in freeoutput.txt shows a memory block which is freed without any prior allocation.
+ b. Any entry in allocoutput.txt shows a memory leak i.e. a memory block which was allocated but not freed.
+
+NOTE : Some static memory blocks are allocated when the stack is intitialized. These are freed only when the binary is
+ stopped/killed. Since we are executing our binary up to cell down, these initially alloacted memory are not yet
+ freed and will be visible in allocoutput.txt. We can ignored these.
+
+ However, "freeoutput.txt" must be empty.
+
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+typedef struct _p{
+char *func;
+int size;
+char *add;
+}Alloc;
+
+int allocline;
+int freeline;
+Alloc alloc[1000000];
+Alloc freemem[1000000];
+
+char allocStr1[] = "ALLOC";
+char allocStr2[] = "ALLOC_WC";
+char freeStr[] = "FREE";
+char shrbAllocStr1[] = "ALLOC_SHRABL_BUF";
+char shrbAllocStr2[] = "ALLOC_SHRABL_BUF_WC";
+char shrbAllocStr3[] = "SHRABL_STATIC_BUF_ALLOC";
+char shrbFreeStr1[] = "FREE_SHRABL_BUF";
+char shrbFreeStr2[] = "SHRABL_STATIC_BUF_FREE";
+
+int main()
+{
+ char buffer[10000];
+ int i=0;
+
+ /* Open input file pointer */
+ FILE *allocfp=fopen("alloc.txt","r");
+ FILE *freefp=fopen("free.txt","r");
+
+ /* Open output file pointer */
+ FILE *allocop=fopen("allocoutput.txt","w");
+ FILE *freeop=fopen("freeoutput.txt","w");
+
+ /* If alloc.txt is open, scan line by line and store "memory size" and
+ * "memory address" in alloc[] structure */
+ if (!allocfp)
+ {
+ return 0;
+ }
+ while(fgets(buffer, 10000, allocfp))
+ {
+ alloc[i].func=malloc(20);
+ alloc[i].add=malloc(20);
+ sscanf(buffer,"%s %d %s", (alloc[i].func), &(alloc[i].size), (alloc[i].add));
+ //printf("%d %s\n",alloc[i].size, alloc[i].add);
+ i++;
+ }
+ allocline=i;
+
+ /* If free.txt is open, scan line by line and store "memory size" and
+ * "memory address" in freemem[] structure */
+ i=0;
+ if (!freefp)
+ {
+ return 0;
+ }
+ while(fgets(buffer, 10000, freefp))
+ {
+ freemem[i].func= malloc(20);
+ freemem[i].add=malloc(20);
+ sscanf(buffer,"%s %d %s", (freemem[i].func), &(freemem[i].size), (freemem[i].add));
+ //printf("%d %s\n",freemem[i].size, freemem[i].add);
+ i++;
+ }
+ freeline=i;
+
+ /* Scan through all entries in alloc[] and freemem[].
+ * If an entry is found in both array, with same size and address, remove this
+ * entry from both */
+ int count1=0;
+ int count2=0;
+ for(count1; count1<allocline; count1++)
+ {
+ for(count2=0; count2<freeline; count2++)
+ {
+ if(( alloc[count1].size == freemem[count2].size ) &&
+ ( !(strcmp(alloc[count1].add,freemem[count2].add)))
+ )
+ {
+ if(
+ (!(strcmp(alloc[count1].func, allocStr1) && strcmp(alloc[count1].func, allocStr2)) && !(strcmp(freemem[count2].func, freeStr))) ||
+ (!(strcmp(alloc[count1].func, shrbAllocStr1) && strcmp(alloc[count1].func, shrbAllocStr2) && strcmp(alloc[count1].func, shrbAllocStr3))\
+ && !(strcmp(freemem[count2].func, shrbFreeStr1) && strcmp(freemem[count2].func, shrbFreeStr2)))
+ )
+ {
+ //printf("%d %s\n",alloc[count1].size, alloc[count1].add);
+ freemem[count2].size=-1;
+ free(freemem[count2].func);
+ freemem[count2].func = 0;
+ free(freemem[count2].add);
+ freemem[count2].add=0;
+
+ alloc[count1].size=-1;
+ free(alloc[count1].func);
+ alloc[count1].func=0;
+ free(alloc[count1].add);
+ alloc[count1].add=0;
+ break;
+ }
+ }
+ else
+ {
+ }
+ }
+ if (count2 == freeline)
+ {
+ //printf("%d %s\n",alloc[count1].size, alloc[count1].add);
+ }
+ }
+
+ /* Add the remaining entries of array[] in allocoutput.txt. These are memory
+ * addresses allocated but not freed */
+ printf("=========== %d %d\n",allocline,freeline);
+ for(count1=0; count1<allocline; count1++)
+ {
+ if( (alloc[count1].size!=-1) && (alloc[count1].add !=0) )
+ {
+ fprintf(allocop,"%d %s\n",alloc[count1].size, alloc[count1].add);
+ }
+ }
+
+ /* Add the remaining entries of freemem[] in freeoutput.txt. These are memory
+ * addresses freed but not allocated */
+ for(count2=0; count2<freeline; count2++)
+ {
+ if( (freemem[count2].size!=-1) && (freemem[count2].add !=0) )
+ {
+ fprintf(freeop,"%d %s\n",freemem[count2].size, freemem[count2].add);
+ }
+ }
+ return 0;
+}