netcdf-c/ncgen/bytebuffer.h
Dennis Heimbigner 751300ec59 Fix more memory leaks in netcdf-c library
This is a follow up to PR https://github.com/Unidata/netcdf-c/pull/1173

Sorry that it is so big, but leak suppression can be complex.

This PR fixes all remaining memory leaks -- as determined by
-fsanitize=address, and with the exceptions noted below.

Unfortunately. there remains a significant leak that I cannot
solve. It involves vlens, and it is unclear if the leak is
occurring in the netcdf-c library or the HDF5 library.

I have added a check_PROGRAM to the ncdump directory to show the
problem.  The program is called tst_vlen_demo.c To exercise it,
build the netcdf library with -fsanitize=address enabled. Then
go into ncdump and do a "make clean check".  This should build
tst_vlen_demo without actually executing it.  Then do the
command "./tst_vlen_demo" to see the output of the memory
checker.  Note the the lost malloc is deep in the HDF5 library
(in H5Tvlen.c).

I am temporarily working around this error in the following way.
1. I modified several test scripts to not execute known vlen tests
   that fail as described above.
2. Added an environment variable called NC_VLEN_NOTEST.
   If set, then those specific tests are suppressed.

This should mean that the --disable-utilities option to
./configure should not need to be set to get a memory leak clean
build.  This should allow for detection of any new leaks.

Note: I used an environment variable rather than a ./configure
option to control the vlen tests. This is because it is
temporary (I hope) and because it is a bit tricky for shell
scripts to access ./configure options.

Finally, as before, this only been tested with netcdf-4 and hdf5 support.
2018-11-15 10:00:38 -07:00

58 lines
1.9 KiB
C

/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
See the COPYRIGHT file for more information. */
#ifndef BYTEBUFFER_H
#define BYTEBUFFER_H 1
typedef struct Bytebuffer {
int nonextendible; /* 1 => fail if an attempt is made to extend this buffer*/
unsigned int alloc;
unsigned int length;
char* content;
} Bytebuffer;
#if defined(_CPLUSPLUS_) || defined(__CPLUSPLUS__) || defined(__CPLUSPLUS)
#define EXTERNC extern "C"
#else
#define EXTERNC extern
#endif
EXTERNC Bytebuffer* bbNew(void);
EXTERNC void bbFree(Bytebuffer*);
EXTERNC int bbSetalloc(Bytebuffer*,const unsigned int);
EXTERNC int bbSetlength(Bytebuffer*,const unsigned int);
EXTERNC int bbFill(Bytebuffer*, const char fill);
/* Produce a duplicate of the contents*/
EXTERNC char* bbDup(const Bytebuffer*);
/* Return the ith char; -1 if no such char */
EXTERNC int bbGet(Bytebuffer*,unsigned int);
/* Set the ith char */
EXTERNC int bbSet(Bytebuffer*,unsigned int,char);
EXTERNC int bbAppend(Bytebuffer*,const char); /* Add at Tail */
EXTERNC int bbAppendn(Bytebuffer*,const void*,unsigned int); /* Add at Tail */
/* Insert 1 or more characters at given location */
EXTERNC int bbInsert(Bytebuffer*,const unsigned int,const char);
EXTERNC int bbInsertn(Bytebuffer*,const unsigned int,const char*,const unsigned int);
EXTERNC int bbCat(Bytebuffer*,const char*);
EXTERNC int bbCatbuf(Bytebuffer*,const Bytebuffer*);
EXTERNC int bbSetcontents(Bytebuffer*, char*, const unsigned int);
EXTERNC int bbNull(Bytebuffer*);
EXTERNC char* bbExtract(Bytebuffer*);
/* Following are always "in-lined"*/
#define bbLength(bb) ((bb)?(bb)->length:0U)
#define bbAlloc(bb) ((bb)?(bb)->alloc:0U)
#define bbContents(bb) ((bb && bb->content)?(bb)->content:(char*)"")
#define bbExtend(bb,len) bbSetalloc((bb),(len)+(bb->alloc))
#define bbClear(bb) ((void)((bb)?(bb)->length=0:0U))
#define bbNeed(bb,n) ((bb)?((bb)->alloc - (bb)->length) > (n):0U)
#define bbAvail(bb) ((bb)?((bb)->alloc - (bb)->length):0U)
#endif /*BYTEBUFFER_H*/