From 4a4be152a02505f732a92caa2a5592f2ec70b9ae Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Mon, 2 Jan 2023 16:22:53 +0530 Subject: [PATCH] [Task-ID: ODUHIGH-485] Memory Leak Detector Tool Signed-off-by: lal.harshita Change-Id: Ia3febb9db288fdd10f7d85bf89108ae35b8445b5 Signed-off-by: lal.harshita --- src/5gnrmac/mac_utils.h | 15 ++-- src/5gnrrlc/rlc_utils.h | 24 +++---- src/5gnrsch/sch_utils.h | 9 ++- src/cm/common_def.c | 8 +-- src/du_app/du_utils.h | 13 ++-- test/unit_test.sh | 25 ++++++- tools/Memory_Leak_Detector/README | 65 +++++++++++++++++ tools/Memory_Leak_Detector/alloc.txt | 0 tools/Memory_Leak_Detector/free.txt | 0 tools/Memory_Leak_Detector/scan.c | 136 +++++++++++++++++++++++++++++++++++ 10 files changed, 258 insertions(+), 37 deletions(-) create mode 100644 tools/Memory_Leak_Detector/README create mode 100644 tools/Memory_Leak_Detector/alloc.txt create mode 100644 tools/Memory_Leak_Detector/free.txt create mode 100644 tools/Memory_Leak_Detector/scan.c diff --git a/src/5gnrmac/mac_utils.h b/src/5gnrmac/mac_utils.h index 8f55814b3..09ce1976d 100644 --- a/src/5gnrmac/mac_utils.h +++ b/src/5gnrmac/mac_utils.h @@ -26,12 +26,11 @@ #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 */ @@ -43,7 +42,7 @@ 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 \ { \ @@ -56,7 +55,7 @@ { \ 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; \ @@ -70,7 +69,7 @@ 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 \ @@ -84,7 +83,7 @@ { \ 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; \ diff --git a/src/5gnrrlc/rlc_utils.h b/src/5gnrrlc/rlc_utils.h index 490916922..caf2c7e94 100755 --- a/src/5gnrrlc/rlc_utils.h +++ b/src/5gnrrlc/rlc_utils.h @@ -107,7 +107,7 @@ extern "C" { #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 @@ -119,7 +119,7 @@ extern "C" { 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 \ @@ -132,7 +132,7 @@ extern "C" { { \ 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; \ @@ -143,7 +143,7 @@ extern "C" { { \ 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; \ @@ -153,7 +153,7 @@ extern "C" { #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; \ @@ -165,7 +165,7 @@ extern "C" { 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\ {\ @@ -178,7 +178,7 @@ extern "C" { 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 \ @@ -191,7 +191,7 @@ extern "C" { {\ 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);\ }\ } @@ -199,7 +199,7 @@ extern "C" { { \ 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); \ @@ -211,7 +211,7 @@ extern "C" { { \ 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; \ @@ -261,7 +261,7 @@ extern "C" { { \ 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; \ @@ -272,7 +272,7 @@ extern "C" { { \ 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 diff --git a/src/5gnrsch/sch_utils.h b/src/5gnrsch/sch_utils.h index b01c9ea26..094a1b721 100644 --- a/src/5gnrsch/sch_utils.h +++ b/src/5gnrsch/sch_utils.h @@ -51,12 +51,11 @@ #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) \ @@ -66,8 +65,8 @@ (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 \ { \ @@ -80,7 +79,7 @@ { \ 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; \ diff --git a/src/cm/common_def.c b/src/cm/common_def.c index 184d1d70f..785956ca7 100644 --- a/src/cm/common_def.c +++ b/src/cm/common_def.c @@ -283,7 +283,7 @@ uint8_t SGetSBufNewForDebug(char *file, const char *func, int line, Region regio #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 @@ -316,7 +316,7 @@ uint8_t SPutSBufNewForDebug(char *file, const char *func, int line, Region regio #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 @@ -349,7 +349,7 @@ Region region, Pool pool, Data **ptr, Size size, uint8_t memType) 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; @@ -380,7 +380,7 @@ Region region, Pool pool, Data *ptr, Size size, uint8_t memType) 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; diff --git a/src/du_app/du_utils.h b/src/du_app/du_utils.h index 9c1cc148d..e98aa43ad 100644 --- a/src/du_app/du_utils.h +++ b/src/du_app/du_utils.h @@ -47,12 +47,11 @@ #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) \ @@ -62,7 +61,7 @@ (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 \ @@ -74,7 +73,7 @@ { \ 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; \ @@ -87,7 +86,7 @@ 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 \ @@ -101,7 +100,7 @@ { \ 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; \ diff --git a/test/unit_test.sh b/test/unit_test.sh index e9af17c62..350e58a23 100644 --- a/test/unit_test.sh +++ b/test/unit_test.sh @@ -1 +1,24 @@ -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 diff --git a/tools/Memory_Leak_Detector/README b/tools/Memory_Leak_Detector/README new file mode 100644 index 000000000..6cecee944 --- /dev/null +++ b/tools/Memory_Leak_Detector/README @@ -0,0 +1,65 @@ +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. + diff --git a/tools/Memory_Leak_Detector/alloc.txt b/tools/Memory_Leak_Detector/alloc.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tools/Memory_Leak_Detector/free.txt b/tools/Memory_Leak_Detector/free.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tools/Memory_Leak_Detector/scan.c b/tools/Memory_Leak_Detector/scan.c new file mode 100644 index 000000000..de690bf3f --- /dev/null +++ b/tools/Memory_Leak_Detector/scan.c @@ -0,0 +1,136 @@ +#include +#include +#include + +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