|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* $LynxId: LYLeaks.c,v 1.41 2018/03/30 00:27:58 tom Exp $
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Copyright (c) 1994, University of Kansas, All Rights Reserved
|
|
Packit |
f574b8 |
* (this file was rewritten twice - 1998/1999 and 2003/2004)
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* This code will be used only if LY_FIND_LEAKS is defined.
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
* 10-30-97 modified to handle StrAllocCopy() and
|
|
Packit |
f574b8 |
* StrAllocCat(). - KW & FM
|
|
Packit |
f574b8 |
* 07-23-07 free leaks of THIS module too -TD
|
|
Packit |
f574b8 |
* 02-09-12 add bstring functions -TD
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Disable the overriding of the memory routines for this file.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
#define NO_MEMORY_TRACKING
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#include <HTUtils.h>
|
|
Packit |
f574b8 |
#include <LYexit.h>
|
|
Packit |
f574b8 |
#include <LYLeaks.h>
|
|
Packit |
f574b8 |
#include <LYUtils.h>
|
|
Packit |
f574b8 |
#include <LYGlobalDefs.h>
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef LY_FIND_LEAKS
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static AllocationList *ALp_RunTimeAllocations = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#define LEAK_SUMMARY
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef LEAK_SUMMARY
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static size_t now_allocated = 0;
|
|
Packit |
f574b8 |
static size_t peak_alloced = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static size_t total_alloced = 0;
|
|
Packit |
f574b8 |
static size_t total_freed = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static long count_mallocs = 0;
|
|
Packit |
f574b8 |
static long count_frees = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static void CountMallocs(size_t size)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
++count_mallocs;
|
|
Packit |
f574b8 |
total_alloced += size;
|
|
Packit |
f574b8 |
now_allocated += size;
|
|
Packit |
f574b8 |
if (peak_alloced < now_allocated)
|
|
Packit |
f574b8 |
peak_alloced = now_allocated;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static void CountFrees(size_t size)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
++count_frees;
|
|
Packit |
f574b8 |
total_freed += size;
|
|
Packit |
f574b8 |
now_allocated -= size;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
#define CountMallocs(size) ++count_mallocs
|
|
Packit |
f574b8 |
#define CountFrees(size) /* nothing */
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Add a new allocation item to the list.
|
|
Packit |
f574b8 |
* Arguments: ALp_new The new item to add.
|
|
Packit |
f574b8 |
* Return Value: void
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* Static function made to make code reusable in projects beyond
|
|
Packit |
f574b8 |
* Lynx (some might ask why not use HTList).
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
static void AddToList(AllocationList * ALp_new)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Just make this the first item in the list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->ALp_Next = ALp_RunTimeAllocations;
|
|
Packit |
f574b8 |
ALp_RunTimeAllocations = ALp_new;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Find the place in the list where vp_find is currently
|
|
Packit |
f574b8 |
* tracked.
|
|
Packit |
f574b8 |
* Arguments: vp_find A pointer to look for in the list.
|
|
Packit |
f574b8 |
* Return Value: AllocationList * Either vp_find's place in the
|
|
Packit |
f574b8 |
* list or NULL if not found.
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* Static function made to make code reusable in projects outside
|
|
Packit |
f574b8 |
* of Lynx (some might ask why not use HTList).
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
static AllocationList *FindInList(void *vp_find)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
AllocationList *ALp_find = ALp_RunTimeAllocations;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Go through the list of allocated pointers until end of list or vp_find
|
|
Packit |
f574b8 |
* is found.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
while (ALp_find != NULL) {
|
|
Packit |
f574b8 |
if (ALp_find->vp_Alloced == vp_find) {
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
ALp_find = ALp_find->ALp_Next;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
return (ALp_find);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Remove the specified item from the list.
|
|
Packit |
f574b8 |
* Arguments: ALp_del The item to remove from the list.
|
|
Packit |
f574b8 |
* Return Value: void
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* Static function made to make code reusable in projects outside
|
|
Packit |
f574b8 |
* of Lynx (some might ask why not use HTList).
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
static void RemoveFromList(AllocationList * ALp_del)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
AllocationList *ALp_findbefore = ALp_RunTimeAllocations;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* There is one special case, where the item to remove is the first in the
|
|
Packit |
f574b8 |
* list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (ALp_del == ALp_findbefore) {
|
|
Packit |
f574b8 |
ALp_RunTimeAllocations = ALp_del->ALp_Next;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Loop through checking all of the next values, if a match don't
|
|
Packit |
f574b8 |
* continue. Always assume the item will be found.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
while (ALp_findbefore->ALp_Next != ALp_del) {
|
|
Packit |
f574b8 |
ALp_findbefore = ALp_findbefore->ALp_Next;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* We are one item before the one to get rid of. Get rid of it.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_findbefore->ALp_Next = ALp_del->ALp_Next;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Make the malloc-sequence available for debugging/tracing.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
#ifndef LYLeakSequence
|
|
Packit |
f574b8 |
long LYLeakSequence(void)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
return count_mallocs;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Print a report of all memory left unallocated by
|
|
Packit |
f574b8 |
* Lynx code or attempted unallocations on
|
|
Packit |
f574b8 |
* pointers that are not valid and then free
|
|
Packit |
f574b8 |
* all unfreed memory.
|
|
Packit |
f574b8 |
* Arguments: void
|
|
Packit |
f574b8 |
* Return Value: void
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* This function should be registered for execution with the
|
|
Packit |
f574b8 |
* atexit (stdlib.h) function as the first statement
|
|
Packit |
f574b8 |
* in main.
|
|
Packit |
f574b8 |
* All output of this function is sent to the file defined in
|
|
Packit |
f574b8 |
* the header LYLeaks.h (LEAKAGE_SINK).
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void LYLeaks(void)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
AllocationList *ALp_head;
|
|
Packit |
f574b8 |
size_t st_total = (size_t) 0;
|
|
Packit |
f574b8 |
FILE *Fp_leakagesink;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
CTRACE((tfp, "entering LYLeaks, flag=%d\n", LYfind_leaks));
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks == FALSE) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Free MY leaks too, in case someone else is watching.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
while (ALp_RunTimeAllocations != NULL) {
|
|
Packit |
f574b8 |
ALp_head = ALp_RunTimeAllocations;
|
|
Packit |
f574b8 |
ALp_RunTimeAllocations = ALp_head->ALp_Next;
|
|
Packit |
f574b8 |
free(ALp_head);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Open the leakage sink to take all the output. Recreate the file each
|
|
Packit |
f574b8 |
* time. Do nothing if unable to open the file.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
Fp_leakagesink = LYNewTxtFile(LYLeaksPath);
|
|
Packit |
f574b8 |
if (Fp_leakagesink == NULL) {
|
|
Packit |
f574b8 |
return;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
while (ALp_RunTimeAllocations != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Take the head off of the run time allocation list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_head = ALp_RunTimeAllocations;
|
|
Packit |
f574b8 |
ALp_RunTimeAllocations = ALp_head->ALp_Next;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Print the type of leak/error. Release memory when we no longer
|
|
Packit |
f574b8 |
* need it.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (ALp_head->vp_Alloced == NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If there is realloc information on the bad request, then it was
|
|
Packit |
f574b8 |
* a bad pointer value in a realloc statement.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s.\n",
|
|
Packit |
f574b8 |
gettext("Invalid pointer detected."));
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%ld\n",
|
|
Packit |
f574b8 |
gettext("Sequence:"),
|
|
Packit |
f574b8 |
ALp_head->st_Sequence);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%p\n",
|
|
Packit |
f574b8 |
gettext("Pointer:"), ALp_head->vp_BadRequest);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Don't free the bad request, it is an invalid pointer. If the
|
|
Packit |
f574b8 |
* free source information is empty, we should check the realloc
|
|
Packit |
f574b8 |
* information too since it can get passed bad pointer values also.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (ALp_head->SL_memory.cp_FileName == NULL) {
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%s\n",
|
|
Packit |
f574b8 |
gettext("FileName:"),
|
|
Packit |
f574b8 |
ALp_head->SL_realloc.cp_FileName);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%d\n",
|
|
Packit |
f574b8 |
gettext("LineCount:"),
|
|
Packit |
f574b8 |
ALp_head->SL_realloc.ssi_LineNumber);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%s\n",
|
|
Packit |
f574b8 |
gettext("FileName:"),
|
|
Packit |
f574b8 |
ALp_head->SL_memory.cp_FileName);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%d\n",
|
|
Packit |
f574b8 |
gettext("LineCount:"),
|
|
Packit |
f574b8 |
ALp_head->SL_memory.ssi_LineNumber);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
size_t i_counter;
|
|
Packit |
f574b8 |
char *value = (char *) (ALp_head->vp_Alloced);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Increment the count of total memory lost and then print the
|
|
Packit |
f574b8 |
* information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
st_total += ALp_head->st_Bytes;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\n",
|
|
Packit |
f574b8 |
gettext("Memory leak detected."));
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%ld\n",
|
|
Packit |
f574b8 |
gettext("Sequence:"),
|
|
Packit |
f574b8 |
ALp_head->st_Sequence);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%p\n",
|
|
Packit |
f574b8 |
gettext("Pointer:"),
|
|
Packit |
f574b8 |
ALp_head->vp_Alloced);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t",
|
|
Packit |
f574b8 |
gettext("Contains:"));
|
|
Packit |
f574b8 |
for (i_counter = 0;
|
|
Packit |
f574b8 |
i_counter < ALp_head->st_Bytes &&
|
|
Packit |
f574b8 |
i_counter < MAX_CONTENT_LENGTH;
|
|
Packit |
f574b8 |
i_counter++) {
|
|
Packit |
f574b8 |
if (isprint(UCH(value[i_counter]))) {
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%c", value[i_counter]);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "|");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "\n");
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%d\n",
|
|
Packit |
f574b8 |
gettext("ByteSize:"),
|
|
Packit |
f574b8 |
(int) (ALp_head->st_Bytes));
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%s\n",
|
|
Packit |
f574b8 |
gettext("FileName:"),
|
|
Packit |
f574b8 |
ALp_head->SL_memory.cp_FileName);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%d\n",
|
|
Packit |
f574b8 |
gettext("LineCount:"),
|
|
Packit |
f574b8 |
ALp_head->SL_memory.ssi_LineNumber);
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Give the last time the pointer was realloced if it happened
|
|
Packit |
f574b8 |
* also.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (ALp_head->SL_realloc.cp_FileName != NULL) {
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%s\n",
|
|
Packit |
f574b8 |
gettext("realloced:"),
|
|
Packit |
f574b8 |
ALp_head->SL_realloc.cp_FileName);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%d\n",
|
|
Packit |
f574b8 |
gettext("LineCount:"),
|
|
Packit |
f574b8 |
ALp_head->SL_realloc.ssi_LineNumber);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
fflush(Fp_leakagesink);
|
|
Packit |
f574b8 |
FREE(ALp_head->vp_Alloced);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Create a blank line and release the memory held by the item.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "\n");
|
|
Packit |
f574b8 |
FREE(ALp_head);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Give a grand total of the leakage. Close the output file.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink, "%s\t%u\n",
|
|
Packit |
f574b8 |
gettext("Total memory leakage this run:"),
|
|
Packit |
f574b8 |
(unsigned) st_total);
|
|
Packit |
f574b8 |
#ifdef LEAK_SUMMARY
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink,
|
|
Packit |
f574b8 |
"%s\t%lu\n", gettext("Peak allocation"), (unsigned long) peak_alloced);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink,
|
|
Packit |
f574b8 |
"%s\t%lu\n", gettext("Bytes allocated"), (unsigned long) total_alloced);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink,
|
|
Packit |
f574b8 |
"%s\t%ld\n", gettext("Total mallocs"), count_mallocs);
|
|
Packit |
f574b8 |
fprintf(Fp_leakagesink,
|
|
Packit |
f574b8 |
"%s\t%ld\n", gettext("Total frees"), count_frees);
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
fclose(Fp_leakagesink);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSYS_purge(LEAKAGE_SINK);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Capture allocations using malloc (stdlib.h) and track
|
|
Packit |
f574b8 |
* the information in a list.
|
|
Packit |
f574b8 |
* Arguments: st_bytes The size of the allocation requested
|
|
Packit |
f574b8 |
* in bytes.
|
|
Packit |
f574b8 |
* cp_File The file from which the request for
|
|
Packit |
f574b8 |
* allocation came from.
|
|
Packit |
f574b8 |
* ssi_Line The line number in cp_File where the
|
|
Packit |
f574b8 |
* allocation request came from.
|
|
Packit |
f574b8 |
* Return Value: void * A pointer to the allocated memory or NULL on
|
|
Packit |
f574b8 |
* failure as per malloc (stdlib.h)
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* If no memory is allocated, then no entry is added to the
|
|
Packit |
f574b8 |
* allocation list.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void *LYLeakMalloc(size_t st_bytes, const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
void *vp_malloc;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks == FALSE) {
|
|
Packit |
f574b8 |
vp_malloc = (void *) malloc(st_bytes);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Do the actual allocation.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
vp_malloc = (void *) malloc(st_bytes);
|
|
Packit |
f574b8 |
CountMallocs(st_bytes);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Only on successful allocation do we track any information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (vp_malloc != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Further allocate memory to store the information. Just return
|
|
Packit |
f574b8 |
* on failure to allocate more.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AllocationList *ALp_new = typecalloc(AllocationList);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (ALp_new != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Copy over the relevant information. There is no need to
|
|
Packit |
f574b8 |
* allocate more memory for the file name as it is a static
|
|
Packit |
f574b8 |
* string anyway.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->st_Sequence = count_mallocs;
|
|
Packit |
f574b8 |
ALp_new->vp_Alloced = vp_malloc;
|
|
Packit |
f574b8 |
ALp_new->st_Bytes = st_bytes;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the new item to the allocation list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AddToList(ALp_new);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return (vp_malloc);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Add information about new allocation to the list,
|
|
Packit |
f574b8 |
* after a call to malloc or calloc or an equivalent
|
|
Packit |
f574b8 |
* function which may or may not have already created
|
|
Packit |
f574b8 |
* a list entry.
|
|
Packit |
f574b8 |
* Arguments: vp_malloc The pointer to newly allocated memory.
|
|
Packit |
f574b8 |
* Arguments: st_bytes The size of the allocation requested
|
|
Packit |
f574b8 |
* in bytes.
|
|
Packit |
f574b8 |
* cp_File The file from which the request for
|
|
Packit |
f574b8 |
* allocation came from.
|
|
Packit |
f574b8 |
* ssi_Line The line number in cp_File where the
|
|
Packit |
f574b8 |
* allocation request came from.
|
|
Packit |
f574b8 |
* Return Value: void * A pointer to the allocated memory or NULL on
|
|
Packit |
f574b8 |
* failure.
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* If no memory is allocated, then no entry is added to the
|
|
Packit |
f574b8 |
* allocation list.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 1999-02-08 created, modelled after LYLeakMalloc - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AllocationList *LYLeak_mark_malloced(void *vp_malloced,
|
|
Packit |
f574b8 |
size_t st_bytes,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
AllocationList *ALp_new = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks != FALSE) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* The actual allocation has already been done!
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Only on successful allocation do we track any information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (vp_malloced != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* See if there is already an entry. If so, just update the source
|
|
Packit |
f574b8 |
* location info.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new = FindInList(vp_malloced);
|
|
Packit |
f574b8 |
if (ALp_new) {
|
|
Packit |
f574b8 |
ALp_new->SL_memory.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Further allocate memory to store the information. Just
|
|
Packit |
f574b8 |
* return on failure to allocate more.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new = typecalloc(AllocationList);
|
|
Packit |
f574b8 |
if (ALp_new != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Copy over the relevant information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->vp_Alloced = vp_malloced;
|
|
Packit |
f574b8 |
ALp_new->st_Bytes = st_bytes;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the new item to the allocation list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AddToList(ALp_new);
|
|
Packit |
f574b8 |
CountMallocs(st_bytes);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return (ALp_new);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Capture allocations by calloc (stdlib.h) and
|
|
Packit |
f574b8 |
* save relevant information in a list.
|
|
Packit |
f574b8 |
* Arguments: st_number The number of items to allocate.
|
|
Packit |
f574b8 |
* st_bytes The size of each item.
|
|
Packit |
f574b8 |
* cp_File The file which wants to allocation.
|
|
Packit |
f574b8 |
* ssi_Line The line number in cp_File requesting
|
|
Packit |
f574b8 |
* the allocation.
|
|
Packit |
f574b8 |
* Return Value: void * The allocated memory, or NULL on failure as
|
|
Packit |
f574b8 |
* per calloc (stdlib.h)
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* If no memory can be allocated, then no entry will be added
|
|
Packit |
f574b8 |
* to the list.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void *LYLeakCalloc(size_t st_number, size_t st_bytes, const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
void *vp_calloc;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks == FALSE) {
|
|
Packit |
f574b8 |
vp_calloc = (void *) calloc(st_number, st_bytes);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Allocate the requested memory.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
vp_calloc = (void *) calloc(st_number, st_bytes);
|
|
Packit |
f574b8 |
CountMallocs(st_bytes * st_number);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Only if the allocation was a success do we track information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (vp_calloc != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Allocate memory for the item to be in the list. If unable, just
|
|
Packit |
f574b8 |
* return.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AllocationList *ALp_new = typecalloc(AllocationList);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (ALp_new != NULL) {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Copy over the relevant information. There is no need to
|
|
Packit |
f574b8 |
* allocate memory for the file name as it is a static string
|
|
Packit |
f574b8 |
* anyway.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->st_Sequence = count_mallocs;
|
|
Packit |
f574b8 |
ALp_new->vp_Alloced = vp_calloc;
|
|
Packit |
f574b8 |
ALp_new->st_Bytes = (st_number * st_bytes);
|
|
Packit |
f574b8 |
ALp_new->SL_memory.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the item to the allocation list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AddToList(ALp_new);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return (vp_calloc);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Capture any realloc (stdlib.h) calls in order to
|
|
Packit |
f574b8 |
* properly keep track of our run time allocation
|
|
Packit |
f574b8 |
* table.
|
|
Packit |
f574b8 |
* Arguments: vp_Alloced The previously allocated block of
|
|
Packit |
f574b8 |
* memory to resize. If NULL,
|
|
Packit |
f574b8 |
* realloc works just like
|
|
Packit |
f574b8 |
* malloc.
|
|
Packit |
f574b8 |
* st_newBytes The new size of the chunk of memory.
|
|
Packit |
f574b8 |
* cp_File The file containing the realloc.
|
|
Packit |
f574b8 |
* ssi_Line The line containing the realloc in cp_File.
|
|
Packit |
f574b8 |
* Return Value: void * The new pointer value (could be the same) or
|
|
Packit |
f574b8 |
* NULL if unable to resize (old block
|
|
Packit |
f574b8 |
* still exists).
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* If unable to resize vp_Alloced, then no change in the
|
|
Packit |
f574b8 |
* allocation list will be made.
|
|
Packit |
f574b8 |
* If vp_Alloced is an invalid pointer value, the program will
|
|
Packit |
f574b8 |
* exit after one last entry is added to the allocation list.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void *LYLeakRealloc(void *vp_Alloced,
|
|
Packit |
f574b8 |
size_t st_newBytes,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
void *vp_realloc;
|
|
Packit |
f574b8 |
AllocationList *ALp_renew;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks == FALSE) {
|
|
Packit |
f574b8 |
vp_realloc = (void *) realloc(vp_Alloced, st_newBytes);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (vp_Alloced == NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If we are asked to resize a NULL pointer, this is just a malloc
|
|
Packit |
f574b8 |
* call.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
vp_realloc = LYLeakMalloc(st_newBytes, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Find the current vp_Alloced block in the list. If NULL, this is an
|
|
Packit |
f574b8 |
* invalid pointer value.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_renew = FindInList(vp_Alloced);
|
|
Packit |
f574b8 |
if (ALp_renew == NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Track the invalid pointer value and then exit. If unable to
|
|
Packit |
f574b8 |
* allocate, just exit.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AllocationList *ALp_new = typecalloc(AllocationList);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (ALp_new == NULL) {
|
|
Packit |
f574b8 |
exit_immediately(EXIT_FAILURE);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Set the information up; no need to allocate file name since it is a
|
|
Packit |
f574b8 |
* static string.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->vp_Alloced = NULL;
|
|
Packit |
f574b8 |
ALp_new->vp_BadRequest = vp_Alloced;
|
|
Packit |
f574b8 |
ALp_new->SL_realloc.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the item to the list. Exit.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AddToList(ALp_new);
|
|
Packit |
f574b8 |
exit_immediately(EXIT_FAILURE);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Perform the resize. If not NULL, record the information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
vp_realloc = (void *) realloc(vp_Alloced, st_newBytes);
|
|
Packit |
f574b8 |
CountFrees(ALp_renew->st_Bytes);
|
|
Packit |
f574b8 |
CountMallocs(st_newBytes);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (vp_realloc != NULL) {
|
|
Packit |
f574b8 |
ALp_renew->st_Sequence = count_mallocs;
|
|
Packit |
f574b8 |
ALp_renew->vp_Alloced = vp_realloc;
|
|
Packit |
f574b8 |
ALp_renew->st_Bytes = st_newBytes;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Update the realloc information, too. No need to allocate file name,
|
|
Packit |
f574b8 |
* static string.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_renew->SL_realloc.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_renew->SL_realloc.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return (vp_realloc);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Add information about reallocated memory to the list,
|
|
Packit |
f574b8 |
* after a call to realloc or an equivalent
|
|
Packit |
f574b8 |
* function which has not already created or updated
|
|
Packit |
f574b8 |
* a list entry.
|
|
Packit |
f574b8 |
* Arguments: ALp_old List entry for previously allocated
|
|
Packit |
f574b8 |
* block of memory to resize. If NULL,
|
|
Packit |
f574b8 |
* mark_realloced works just like
|
|
Packit |
f574b8 |
* mark_malloced.
|
|
Packit |
f574b8 |
* vp_realloced The new pointer, after resizing.
|
|
Packit |
f574b8 |
* st_newBytes The new size of the chunk of memory.
|
|
Packit |
f574b8 |
* cp_File The file to record.
|
|
Packit |
f574b8 |
* ssi_Line The line to record.
|
|
Packit |
f574b8 |
* Return Value: Pointer to new or updated list entry
|
|
Packit |
f574b8 |
* for this memory block.
|
|
Packit |
f574b8 |
* NULL on allocation error.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 1999-02-11 created kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
#if defined(LY_FIND_LEAKS) && defined(LY_FIND_LEAKS_EXTENDED)
|
|
Packit |
f574b8 |
static AllocationList *mark_realloced(AllocationList * ALp_old, void *vp_realloced,
|
|
Packit |
f574b8 |
size_t st_newBytes,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If there is no list entry for the old allocation, treat this as if a new
|
|
Packit |
f574b8 |
* allocation had happened.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (ALp_old == NULL) {
|
|
Packit |
f574b8 |
return (LYLeak_mark_malloced(vp_realloced, st_newBytes, cp_File, ssi_Line));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* ALp_old represents the memory block before reallocation. Assume that if
|
|
Packit |
f574b8 |
* we get here, there isn't yet a list entry for the new, possibly
|
|
Packit |
f574b8 |
* different, address after realloc, that is our list hasn't been updated -
|
|
Packit |
f574b8 |
* so we're going to do that now.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (vp_realloced != NULL) {
|
|
Packit |
f574b8 |
ALp_old->vp_Alloced = vp_realloced;
|
|
Packit |
f574b8 |
ALp_old->st_Bytes = st_newBytes;
|
|
Packit |
f574b8 |
ALp_old->SL_realloc.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_old->SL_realloc.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
return (ALp_old);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* not LY_FIND_LEAKS and LY_FIND_LEAKS_EXTENDED */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: Capture all requests to free information and also
|
|
Packit |
f574b8 |
* remove items from the allocation list.
|
|
Packit |
f574b8 |
* Arguments: vp_Alloced The memory to free.
|
|
Packit |
f574b8 |
* cp_File The file calling free.
|
|
Packit |
f574b8 |
* ssi_Line The line of cp_File calling free.
|
|
Packit |
f574b8 |
* Return Value: void
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* If the pointer value is invalid, then an item will be added
|
|
Packit |
f574b8 |
* to the list and nothing else is done.
|
|
Packit |
f574b8 |
* I really like the name of this function and one day hope
|
|
Packit |
f574b8 |
* that Lynx is Leak Free.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void LYLeakFree(void *vp_Alloced,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
AllocationList *ALp_free;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks == FALSE) {
|
|
Packit |
f574b8 |
free(vp_Alloced);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Find the pointer in the allocated list. If not found, bad pointer.
|
|
Packit |
f574b8 |
* If found, free list item and vp_Alloced.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_free = FindInList(vp_Alloced);
|
|
Packit |
f574b8 |
if (ALp_free == NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Create the final entry before exiting marking this error. If
|
|
Packit |
f574b8 |
* unable to allocate more memory just exit.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AllocationList *ALp_new = typecalloc(AllocationList);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (ALp_new == NULL) {
|
|
Packit |
f574b8 |
exit_immediately(EXIT_FAILURE);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Set up the information, no memory need be allocated for the file
|
|
Packit |
f574b8 |
* name since it is a static string.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->vp_Alloced = NULL;
|
|
Packit |
f574b8 |
ALp_new->vp_BadRequest = vp_Alloced;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_memory.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the entry to the list and then return.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AddToList(ALp_new);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Free off the memory. Take entry out of allocation list.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
CountFrees(ALp_free->st_Bytes);
|
|
Packit |
f574b8 |
RemoveFromList(ALp_free);
|
|
Packit |
f574b8 |
FREE(ALp_free);
|
|
Packit |
f574b8 |
free(vp_Alloced);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Check for leaked strdup() results -TD
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
char *LYLeakStrdup(const char *source,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
size_t length = strlen(source) + 1;
|
|
Packit |
f574b8 |
char *target = (char *) LYLeakMalloc(length, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (target != 0) {
|
|
Packit |
f574b8 |
memcpy(target, source, length);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return target;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Allocates a new copy of a string, and returns it.
|
|
Packit |
f574b8 |
* Tracks allocations by using other LYLeakFoo functions.
|
|
Packit |
f574b8 |
* Equivalent to HTSACopy in HTString.c - KW
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
char *LYLeakSACopy(char **dest,
|
|
Packit |
f574b8 |
const char *src,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
if (src != NULL && src == *dest) {
|
|
Packit |
f574b8 |
CTRACE((tfp,
|
|
Packit |
f574b8 |
"LYLeakSACopy: *dest equals src, contains \"%s\"\n",
|
|
Packit |
f574b8 |
src));
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
if (*dest) {
|
|
Packit |
f574b8 |
LYLeakFree(*dest, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
*dest = NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (src) {
|
|
Packit |
f574b8 |
*dest = (char *) LYLeakMalloc(strlen(src) + 1, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
if (*dest == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYLeakSACopy");
|
|
Packit |
f574b8 |
strcpy(*dest, src);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return *dest;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* String Allocate and Concatenate.
|
|
Packit |
f574b8 |
* Tracks allocations by using other LYLeakFoo functions.
|
|
Packit |
f574b8 |
* Equivalent to HTSACat in HTUtils.c - KW
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
char *LYLeakSACat(char **dest,
|
|
Packit |
f574b8 |
const char *src,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
if (src && *src) {
|
|
Packit |
f574b8 |
if (src == *dest) {
|
|
Packit |
f574b8 |
CTRACE((tfp,
|
|
Packit |
f574b8 |
"LYLeakSACat: *dest equals src, contains \"%s\"\n",
|
|
Packit |
f574b8 |
src));
|
|
Packit |
f574b8 |
} else if (*dest) {
|
|
Packit |
f574b8 |
size_t length = strlen(*dest);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
*dest = (char *) LYLeakRealloc(*dest,
|
|
Packit |
f574b8 |
(length + strlen(src) + 1),
|
|
Packit |
f574b8 |
cp_File,
|
|
Packit |
f574b8 |
ssi_Line);
|
|
Packit |
f574b8 |
if (*dest == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYLeakSACat");
|
|
Packit |
f574b8 |
strcpy(*dest + length, src);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
*dest = (char *) LYLeakMalloc((strlen(src) + 1),
|
|
Packit |
f574b8 |
cp_File,
|
|
Packit |
f574b8 |
ssi_Line);
|
|
Packit |
f574b8 |
if (*dest == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYLeakSACat");
|
|
Packit |
f574b8 |
strcpy(*dest, src);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return *dest;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/******************************************************************************/
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Equivalents for bstring functions in HTString.c -TD
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
/* same as HTSABAlloc */
|
|
Packit |
f574b8 |
void LYLeakSABAlloc(bstring **dest,
|
|
Packit |
f574b8 |
int len,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
if (*dest == 0) {
|
|
Packit |
f574b8 |
*dest = LYLeakCalloc(1, sizeof(bstring), cp_File, ssi_Line);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if ((*dest)->len != len) {
|
|
Packit |
f574b8 |
(*dest)->str = (char *) LYLeakRealloc((*dest)->str,
|
|
Packit |
f574b8 |
(size_t) len,
|
|
Packit |
f574b8 |
cp_File,
|
|
Packit |
f574b8 |
ssi_Line);
|
|
Packit |
f574b8 |
if ((*dest)->str == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYLeakSABalloc");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
(*dest)->len = len;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* same as HTSABCopy */
|
|
Packit |
f574b8 |
void LYLeakSABCopy(bstring **dest,
|
|
Packit |
f574b8 |
const char *src,
|
|
Packit |
f574b8 |
int len,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
bstring *t;
|
|
Packit |
f574b8 |
unsigned need = (unsigned) (len + 1);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
CTRACE2(TRACE_BSTRING,
|
|
Packit |
f574b8 |
(tfp, "HTSABCopy(%p, %p, %d)\n",
|
|
Packit |
f574b8 |
(void *) dest, (const void *) src, len));
|
|
Packit |
f574b8 |
LYLeakSABFree(dest, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
if (src) {
|
|
Packit |
f574b8 |
if (TRACE_BSTRING) {
|
|
Packit |
f574b8 |
CTRACE((tfp, "=== %4d:", len));
|
|
Packit |
f574b8 |
trace_bstring2(src, len);
|
|
Packit |
f574b8 |
CTRACE((tfp, "\n"));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if ((t = (bstring *) LYLeakMalloc(sizeof(bstring), cp_File, ssi_Line))
|
|
Packit |
f574b8 |
== NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "HTSABCopy");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if ((t->str = (char *) LYLeakMalloc(need, cp_File, ssi_Line)) == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "HTSABCopy");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
MemCpy(t->str, src, len);
|
|
Packit |
f574b8 |
t->len = len;
|
|
Packit |
f574b8 |
t->str[t->len] = '\0';
|
|
Packit |
f574b8 |
*dest = t;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (TRACE_BSTRING) {
|
|
Packit |
f574b8 |
CTRACE((tfp, "=> %4d:", BStrLen(*dest)));
|
|
Packit |
f574b8 |
trace_bstring(*dest);
|
|
Packit |
f574b8 |
CTRACE((tfp, "\n"));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* same as HTSABCopy0 */
|
|
Packit |
f574b8 |
void LYLeakSABCopy0(bstring **dest,
|
|
Packit |
f574b8 |
const char *src,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
LYLeakSABCopy(dest, src, (int) strlen(src), cp_File, ssi_Line);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* same as HTSABCat */
|
|
Packit |
f574b8 |
void LYLeakSABCat(bstring **dest,
|
|
Packit |
f574b8 |
const char *src,
|
|
Packit |
f574b8 |
int len,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
bstring *t = *dest;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
CTRACE2(TRACE_BSTRING,
|
|
Packit |
f574b8 |
(tfp, "HTSABCat(%p, %p, %d)\n",
|
|
Packit |
f574b8 |
(void *) dest, (const void *) src, len));
|
|
Packit |
f574b8 |
if (src) {
|
|
Packit |
f574b8 |
unsigned need = (unsigned) (len + 1);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (TRACE_BSTRING) {
|
|
Packit |
f574b8 |
CTRACE((tfp, "=== %4d:", len));
|
|
Packit |
f574b8 |
trace_bstring2(src, len);
|
|
Packit |
f574b8 |
CTRACE((tfp, "\n"));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (t) {
|
|
Packit |
f574b8 |
unsigned length = (unsigned) t->len + need;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
t->str = (char *) LYLeakRealloc(t->str, length, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
if ((t = (bstring *) LYLeakCalloc(1, sizeof(bstring), cp_File,
|
|
Packit |
f574b8 |
ssi_Line)) == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "HTSACat");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
t->str = (char *) LYLeakMalloc(need, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (t->str == NULL)
|
|
Packit |
f574b8 |
outofmem(__FILE__, "HTSACat");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
MemCpy(t->str + t->len, src, len);
|
|
Packit |
f574b8 |
t->len += len;
|
|
Packit |
f574b8 |
t->str[t->len] = '\0';
|
|
Packit |
f574b8 |
*dest = t;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (TRACE_BSTRING) {
|
|
Packit |
f574b8 |
CTRACE((tfp, "=> %4d:", BStrLen(*dest)));
|
|
Packit |
f574b8 |
trace_bstring(*dest);
|
|
Packit |
f574b8 |
CTRACE((tfp, "\n"));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* same as HTSABCat0 */
|
|
Packit |
f574b8 |
void LYLeakSABCat0(bstring **dest,
|
|
Packit |
f574b8 |
const char *src,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
LYLeakSABCat(dest, src, (int) strlen(src), cp_File, ssi_Line);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* same as HTSABFree */
|
|
Packit |
f574b8 |
void LYLeakSABFree(bstring **ptr,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
if (*ptr != NULL) {
|
|
Packit |
f574b8 |
if ((*ptr)->str)
|
|
Packit |
f574b8 |
LYLeakFree((*ptr)->str, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
LYLeakFree(*ptr, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
*ptr = NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/******************************************************************************/
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#if defined(LY_FIND_LEAKS) && defined(LY_FIND_LEAKS_EXTENDED)
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
const char *leak_cp_File_hack = __FILE__;
|
|
Packit |
f574b8 |
short leak_ssi_Line_hack = __LINE__;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Purpose: A wrapper around StrAllocVsprintf (the workhorse of
|
|
Packit |
f574b8 |
* HTSprintf/HTSprintf0, implemented in HTString.c) that
|
|
Packit |
f574b8 |
* tries to make sure that our allocation list is always
|
|
Packit |
f574b8 |
* properly updated, whether StrAllocVsprintf itself was
|
|
Packit |
f574b8 |
* compiled with memory tracking or not (or even a mixture,
|
|
Packit |
f574b8 |
* like tracking the freeing but not the new allocation).
|
|
Packit |
f574b8 |
* Some source files can be compiled with LY_FIND_LEAKS_EXTENDED
|
|
Packit |
f574b8 |
* in effect while others only have LY_FIND_LEAKS in effect,
|
|
Packit |
f574b8 |
* and as long as HTString.c is complied with memory tracking
|
|
Packit |
f574b8 |
* (of either kind) string objects allocated by HTSprintf/
|
|
Packit |
f574b8 |
* HTSprintf0 (or otherwise) can be passed around among them and
|
|
Packit |
f574b8 |
* manipulated both ways.
|
|
Packit |
f574b8 |
* Arguments: dest As for StrAllocVsprintf.
|
|
Packit |
f574b8 |
* cp_File The source file of the caller (i.e. the
|
|
Packit |
f574b8 |
* caller of HTSprintf/HTSprintf0, hopefully).
|
|
Packit |
f574b8 |
* ssi_Line The line of cp_File calling.
|
|
Packit |
f574b8 |
* inuse,fmt,ap As for StrAllocVsprintf.
|
|
Packit |
f574b8 |
* Return Value: The char pointer to resulting string, as set
|
|
Packit |
f574b8 |
* by StrAllocVsprintf, or
|
|
Packit |
f574b8 |
* NULL if dest==0 (wrong use!).
|
|
Packit |
f574b8 |
* Remarks/Portability/Dependencies/Restrictions:
|
|
Packit |
f574b8 |
* The price for generality is severe inefficiency: several
|
|
Packit |
f574b8 |
* list lookups are done to be on the safe side.
|
|
Packit |
f574b8 |
* We don't get the real allocation size, only a minimum based
|
|
Packit |
f574b8 |
* on the string length of the result. So the amount of memory
|
|
Packit |
f574b8 |
* leakage may get underestimated.
|
|
Packit |
f574b8 |
* If *dest is an invalid pointer value on entry (i.e. was not
|
|
Packit |
f574b8 |
* tracked), the program will exit after one last entry is added
|
|
Packit |
f574b8 |
* to the allocation list.
|
|
Packit |
f574b8 |
* If StrAllocVsprintf fails to return a valid string via the
|
|
Packit |
f574b8 |
* indirect string pointer (its first parameter), invalid memory
|
|
Packit |
f574b8 |
* access will result and the program will probably terminate
|
|
Packit |
f574b8 |
* with a signal. This can happen if, on entry, *dest is NULL
|
|
Packit |
f574b8 |
* and fmt is empty or NULL, so just Don't Do That.
|
|
Packit |
f574b8 |
* Revision History:
|
|
Packit |
f574b8 |
* 1999-02-11 created kw
|
|
Packit |
f574b8 |
* 1999-10-15 added comments kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
static char *LYLeakSAVsprintf(char **dest,
|
|
Packit |
f574b8 |
const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line,
|
|
Packit |
f574b8 |
size_t inuse,
|
|
Packit |
f574b8 |
const char *fmt,
|
|
Packit |
f574b8 |
va_list * ap)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
AllocationList *ALp_old;
|
|
Packit |
f574b8 |
void *vp_oldAlloced;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
const char *old_cp_File = __FILE__;
|
|
Packit |
f574b8 |
short old_ssi_Line = __LINE__;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (!dest)
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (LYfind_leaks == FALSE) {
|
|
Packit |
f574b8 |
StrAllocVsprintf(dest, inuse, fmt, ap);
|
|
Packit |
f574b8 |
return (*dest);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
vp_oldAlloced = *dest;
|
|
Packit |
f574b8 |
if (!vp_oldAlloced) {
|
|
Packit |
f574b8 |
StrAllocVsprintf(dest, inuse, fmt, ap);
|
|
Packit |
f574b8 |
LYLeak_mark_malloced(*dest, strlen(*dest) + 1, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
return (*dest);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
void *vp_realloced;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
ALp_old = FindInList(vp_oldAlloced);
|
|
Packit |
f574b8 |
if (ALp_old == NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Track the invalid pointer value and then exit. If unable to
|
|
Packit |
f574b8 |
* allocate, just exit.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AllocationList *ALp_new = typecalloc(AllocationList);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (ALp_new == NULL) {
|
|
Packit |
f574b8 |
exit_immediately(EXIT_FAILURE);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Set the information up; no need to allocate file name since it
|
|
Packit |
f574b8 |
* is a static string.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ALp_new->vp_Alloced = NULL;
|
|
Packit |
f574b8 |
ALp_new->vp_BadRequest = vp_oldAlloced;
|
|
Packit |
f574b8 |
ALp_new->SL_realloc.cp_FileName = cp_File;
|
|
Packit |
f574b8 |
ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the item to the list. Exit.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
AddToList(ALp_new);
|
|
Packit |
f574b8 |
exit_immediately(EXIT_FAILURE);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
old_cp_File = ALp_old->SL_memory.cp_FileName;
|
|
Packit |
f574b8 |
old_ssi_Line = ALp_old->SL_memory.ssi_LineNumber;
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* DO THE REAL WORK, by calling StrAllocVsprintf. If result is not
|
|
Packit |
f574b8 |
* NULL, record the information.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
StrAllocVsprintf(dest, inuse, fmt, ap);
|
|
Packit |
f574b8 |
vp_realloced = (void *) *dest;
|
|
Packit |
f574b8 |
if (vp_realloced != NULL) {
|
|
Packit |
f574b8 |
AllocationList *ALp_new = FindInList(vp_realloced);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (!ALp_new) {
|
|
Packit |
f574b8 |
/* Look up again, list may have changed! - kw */
|
|
Packit |
f574b8 |
ALp_old = FindInList(vp_oldAlloced);
|
|
Packit |
f574b8 |
if (ALp_old == NULL) {
|
|
Packit |
f574b8 |
LYLeak_mark_malloced(*dest, strlen(*dest) + 1, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
return (*dest);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
mark_realloced(ALp_old, *dest, strlen(*dest) + 1, cp_File, ssi_Line);
|
|
Packit |
f574b8 |
return (*dest);
|
|
Packit |
f574b8 |
}
|
|
Packit Service |
5cb6ae |
ALp_new->SL_memory.cp_FileName = old_cp_File;
|
|
Packit Service |
5cb6ae |
ALp_new->SL_memory.ssi_LineNumber = old_ssi_Line;
|
|
Packit Service |
5cb6ae |
ALp_new->SL_realloc.cp_FileName = cp_File;
|
|
Packit Service |
5cb6ae |
ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return (*dest);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Note: the following may need updating if HTSprintf in HTString.c
|
|
Packit |
f574b8 |
* is changed. - kw */
|
|
Packit |
f574b8 |
static char *LYLeakHTSprintf(char **pstr, const char *fmt,...)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
char *str;
|
|
Packit |
f574b8 |
size_t inuse = 0;
|
|
Packit |
f574b8 |
va_list ap;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
LYva_start(ap, fmt);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (pstr != 0 && *pstr != 0)
|
|
Packit |
f574b8 |
inuse = strlen(*pstr);
|
|
Packit |
f574b8 |
str = LYLeakSAVsprintf(pstr, leak_cp_File_hack, leak_ssi_Line_hack,
|
|
Packit |
f574b8 |
inuse, fmt, &ap);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
va_end(ap);
|
|
Packit |
f574b8 |
return str;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Note: the following may need updating if HTSprintf0 in HTString.c
|
|
Packit |
f574b8 |
* is changed. - kw */
|
|
Packit |
f574b8 |
static char *LYLeakHTSprintf0(char **pstr, const char *fmt,...)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
char *str;
|
|
Packit |
f574b8 |
va_list ap;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
LYva_start(ap, fmt);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
str = LYLeakSAVsprintf(pstr, leak_cp_File_hack, leak_ssi_Line_hack,
|
|
Packit |
f574b8 |
0, fmt, &ap);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
va_end(ap);
|
|
Packit |
f574b8 |
return str;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* HTSprintf and HTSprintf0 will be defined such that they effectively call one
|
|
Packit |
f574b8 |
* of the following two functions that store away a copy to the File & Line
|
|
Packit |
f574b8 |
* info in temporary hack variables, and then call the real function (which is
|
|
Packit |
f574b8 |
* returned here as a function pointer) to the regular HTSprintf/HTSprintf0
|
|
Packit |
f574b8 |
* arguments. It's probably a bit inefficient, but that shouldn't be
|
|
Packit |
f574b8 |
* noticeable compared to all the time that memory tracking takes up for list
|
|
Packit |
f574b8 |
* traversal. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
HTSprintflike *Get_htsprintf_fn(const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
leak_cp_File_hack = cp_File;
|
|
Packit |
f574b8 |
leak_ssi_Line_hack = ssi_Line;
|
|
Packit |
f574b8 |
return &LYLeakHTSprintf;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintflike *Get_htsprintf0_fn(const char *cp_File,
|
|
Packit |
f574b8 |
const short ssi_Line)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
leak_cp_File_hack = cp_File;
|
|
Packit |
f574b8 |
leak_ssi_Line_hack = ssi_Line;
|
|
Packit |
f574b8 |
return &LYLeakHTSprintf0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#endif /* LY_FIND_LEAKS and LY_FIND_LEAKS_EXTENDED */
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
/* Standard C forbids an empty file */
|
|
Packit |
f574b8 |
void no_leak_checking(void);
|
|
Packit |
f574b8 |
void no_leak_checking(void)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* LY_FIND_LEAKS */
|