📄 lyleaks.c
字号:
/*** Copyright (c) 1994, University of Kansas, All Rights Reserved**** This code will be used only if LY_FIND_LEAKS is defined.*//*** Disable the overriding of the memory routines for this file.*/#define NO_MEMORY_TRACKING#include "HTUtils.h"#include "tcp.h"#include "LYexit.h"#include "LYLeaks.h"#include "LYUtils.h"#include <ctype.h>/*#include <stdio.h> included by HTUtils.h -- FM */#define FREE(x) if (x) {free(x); x = NULL;}PRIVATE AllocationList *ALp_RunTimeAllocations = NULL;PRIVATE void AddToList PARAMS(( AllocationList * ALp_new));PRIVATE AllocationList *FindInList PARAMS(( void * vp_find));PRIVATE void RemoveFromList PARAMS(( AllocationList * ALp_del));/*** Purpose: Print a report of all memory left unallocated by** Lynx code or attempted unallocations on** pointers that are not valid and then free** all unfreed memory.** Arguments: void** Return Value: void** Remarks/Portability/Dependencies/Restrictions:** This function should be registered for execution with the** atexit (stdlib.h) function as the first statement** in main.** All output of this function is sent to the file defined in** the header LYLeaks.h (LEAKAGE_SINK).** Revision History:** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe** 10-30-97 modified to handle StrAllocCopy() and** StrAllocCat(). - KW & FM*/PUBLIC void LYLeaks NOARGS{ AllocationList *ALp_head; size_t st_total = (size_t)0; FILE *Fp_leakagesink; /* * Open the leakage sink to take all the output. * Recreate the file each time. * Do nothing if unable to open the file. */ Fp_leakagesink = LYNewTxtFile(LEAKAGE_SINK); if (Fp_leakagesink == NULL) { return; } while (ALp_RunTimeAllocations != NULL) { /* * Take the head off of the run time allocation list. */ ALp_head = ALp_RunTimeAllocations; ALp_RunTimeAllocations = ALp_head->ALp_Next; /* * Print the type of leak/error. * Free off memory when we no longer need it. */ if (ALp_head->vp_Alloced == NULL) { /* * If there is realloc information on the * bad request, then it was a bad pointer * value in a realloc statement. */ fprintf(Fp_leakagesink, "Invalid pointer detected.\n"); fprintf(Fp_leakagesink, "Pointer:\t%p\n", ALp_head->vp_BadRequest); /* * Don't free the bad request, it is an invalid pointer. * If the free source information is empty, we * should check the realloc information * too since it can get passed bad pointer * values also. */ if (ALp_head->SL_memory.cp_FileName == NULL) { fprintf(Fp_leakagesink, "FileName:\t%s\n", ALp_head->SL_realloc.cp_FileName); fprintf(Fp_leakagesink, "LineCount:\t%d\n", ALp_head->SL_realloc.ssi_LineNumber); } else { fprintf(Fp_leakagesink, "FileName:\t%s\n", ALp_head->SL_memory.cp_FileName); fprintf(Fp_leakagesink, "LineCount:\t%d\n", ALp_head->SL_memory.ssi_LineNumber); } } else { size_t i_counter; /* * Increment the count of total memory lost and * then print the information. */ st_total += ALp_head->st_Bytes; fprintf(Fp_leakagesink, "Memory leak detected.\n"); fprintf(Fp_leakagesink, "Pointer:\t%p\n", ALp_head->vp_Alloced); fprintf(Fp_leakagesink, "Contains:\t"); for (i_counter = 0; i_counter < ALp_head->st_Bytes && i_counter < MAX_CONTENT_LENGTH; i_counter++) { if (isprint(((char *)(ALp_head->vp_Alloced))[i_counter])) { fprintf(Fp_leakagesink, "%c", ((char *)(ALp_head->vp_Alloced))[i_counter]); } else { fprintf(Fp_leakagesink, "|"); } } fprintf(Fp_leakagesink, "\n"); FREE(ALp_head->vp_Alloced); fprintf(Fp_leakagesink, "ByteSize:\t%d\n", (int)(ALp_head->st_Bytes)); fprintf(Fp_leakagesink, "FileName:\t%s\n", ALp_head->SL_memory.cp_FileName); fprintf(Fp_leakagesink, "LineCount:\t%d\n", ALp_head->SL_memory.ssi_LineNumber); /* * Give the last time the pointer was realloced * if it happened also. */ if (ALp_head->SL_realloc.cp_FileName != NULL) { fprintf(Fp_leakagesink, "realloced:\t%s\n", ALp_head->SL_realloc.cp_FileName); fprintf(Fp_leakagesink, "LineCount:\t%d\n", ALp_head->SL_realloc.ssi_LineNumber); } } /* * Create a blank line and release the memory held * by the item. */ fprintf(Fp_leakagesink, "\n"); FREE(ALp_head); } /* * Give a grand total of the leakage. * Close the output file. */ fprintf(Fp_leakagesink, "\nTotal memory leakage this run:\t%u\n", (unsigned)st_total); fclose(Fp_leakagesink);#ifdef VMS { char VMSfilename[256]; /* * Purge lower versions of the file. */ sprintf(VMSfilename, "%s;-1", LEAKAGE_SINK); while (remove(VMSfilename) == 0) ; /* * Reset version number. */ sprintf(VMSfilename, "%s;1", LEAKAGE_SINK); rename(LEAKAGE_SINK, VMSfilename); }#endif /* VMS */}/*** Purpose: Capture allocations using malloc (stdlib.h) and track** the information in a list.** Arguments: st_bytes The size of the allocation requested** in bytes.** cp_File The file from which the request for** allocation came from.** ssi_Line The line number in cp_File where the** allocation request came from.** Return Value: void * A pointer to the allocated memory or NULL on** failure as per malloc (stdlib.h)** Remarks/Portability/Dependencies/Restrictions:** If no memory is allocated, then no entry is added to the** allocation list.** Revision History:** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe*/PUBLIC void *LYLeakMalloc ARGS3( size_t, st_bytes, CONST char *, cp_File, CONST short, ssi_Line){ /* * Do the actual allocation. */ void *vp_malloc = (void *)malloc(st_bytes); /* * Only on successful allocation do we track any information. */ if (vp_malloc != NULL) { /* * Further allocate memory to store the information. * Just return on failure to allocate more. */ AllocationList *ALp_new = (AllocationList *)calloc(1, sizeof(AllocationList)); if (ALp_new == NULL) { return(vp_malloc); } /* * Copy over the relevant information. * There is no need to allocate more memory for the * file name as it is a static string anyhow. */ ALp_new->vp_Alloced = vp_malloc; ALp_new->st_Bytes = st_bytes; ALp_new->SL_memory.cp_FileName = cp_File; ALp_new->SL_memory.ssi_LineNumber = ssi_Line; /* * Add the new item to the allocation list. */ AddToList(ALp_new); } return(vp_malloc);}/*** Purpose: Capture allocations by calloc (stdlib.h) and** save relevant information in a list.** Arguments: st_number The number of items to allocate.** st_bytes The size of each item.** cp_File The file which wants to allocation.** ssi_Line The line number in cp_File requesting** the allocation.** Return Value: void * The allocated memory, or NULL on failure as** per calloc (stdlib.h)** Remarks/Portability/Dependencies/Restrictions:** If no memory can be allocated, then no entry will be added** to the list.** Revision History:** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe*/PUBLIC void *LYLeakCalloc ARGS4( size_t, st_number, size_t, st_bytes, CONST char *, cp_File, CONST short, ssi_Line){ /* * Allocate the requested memory. */ void *vp_calloc = (void *)calloc(st_number, st_bytes); /* * Only if the allocation was a success do we track information. */ if (vp_calloc != NULL) { /* * Allocate memory for the item to be in the list. * If unable, just return. */ AllocationList *ALp_new = (AllocationList *)calloc(1, sizeof(AllocationList)); if (ALp_new == NULL) { return(vp_calloc); } /* * Copy over the relevant information. * There is no need to allocate memory for the file * name as it is a static string anyway. */ ALp_new->vp_Alloced = vp_calloc; ALp_new->st_Bytes = (st_number * st_bytes); ALp_new->SL_memory.cp_FileName = cp_File; ALp_new->SL_memory.ssi_LineNumber = ssi_Line; /* * Add the item to the allocation list. */ AddToList(ALp_new); } return(vp_calloc);}/*** Purpose: Capture any realloc (stdlib.h) calls in order to** properly keep track of our run time allocation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -