netcdf-c/libdap2/dapdump.c

630 lines
17 KiB
C
Raw Normal View History

2011-04-18 02:56:10 +08:00
/*********************************************************************
2018-12-07 05:21:03 +08:00
* Copyright 2018, UCAR/Unidata
2011-04-18 02:56:10 +08:00
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
2011-04-18 02:56:10 +08:00
#include "config.h"
2019-11-05 05:11:55 +08:00
#include "netcdf.h"
#include <stddef.h>
2011-04-18 02:56:10 +08:00
#ifdef USE_PARALLEL
#include "netcdf_par.h"
#endif
Primary change: add dap4 support Specific changes: 1. Add dap4 code: libdap4 and dap4_test. Note that until the d4ts server problem is solved, dap4 is turned off. 2. Modify various files to support dap4 flags: configure.ac, Makefile.am, CMakeLists.txt, etc. 3. Add nc_test/test_common.sh. This centralizes the handling of the locations of various things in the build tree: e.g. where is ncgen.exe located. See nc_test/test_common.sh for details. 4. Modify .sh files to use test_common.sh 5. Obsolete separate oc2 by moving it to be part of netcdf-c. This means replacing code with netcdf-c equivalents. 5. Add --with-testserver to configure.ac to allow override of the servers to be used for --enable-dap-remote-tests. 6. There were multiple versions of nctypealignment code. Try to centralize in libdispatch/doffset.c and include/ncoffsets.h 7. Add a unit test for the ncuri code because of its complexity. 8. Move the findserver code out of libdispatch and into a separate, self contained program in ncdap_test and dap4_test. 9. Move the dispatch header files (nc{3,4}dispatch.h) to .../include because they are now shared by modules. 10. Revamp the handling of TOPSRCDIR and TOPBUILDDIR for shell scripts. 11. Make use of MREMAP if available 12. Misc. minor changes e.g. - #include <config.h> -> #include "config.h" - Add some no-install headers to /include - extern -> EXTERNL and vice versa as needed - misc header cleanup - clean up checking for misc. unix vs microsoft functions 13. Change copyright decls in some files to point to LICENSE file. 14. Add notes to RELEASENOTES.md
2017-03-09 08:01:10 +08:00
#include "dapincludes.h"
2011-04-18 02:56:10 +08:00
#include "dapdump.h"
2011-11-14 12:20:19 +08:00
#include "dceconstraints.h"
2011-04-18 02:56:10 +08:00
#define CHECK(n) if((n) != NC_NOERR) {return (n);} else {}
static char* indentstr = " "; /* Used by dumpindent */
2011-11-14 12:20:19 +08:00
static void dumptreer(CDFnode* root, NCbytes* buf, int indent, int visible);
2011-04-18 02:56:10 +08:00
int
dumpmetadata(int ncid, NChdr** hdrp)
{
int stat,i,j;
2011-04-18 02:56:10 +08:00
NChdr* hdr = (NChdr*)calloc(1,sizeof(NChdr));
MEMCHECK(hdr,NC_ENOMEM);
hdr->ncid = ncid;
hdr->content = ncbytesnew();
if(hdrp) *hdrp = hdr;
stat = nc_inq(hdr->ncid,
&hdr->ndims,
&hdr->nvars,
&hdr->ngatts,
&hdr->unlimid);
CHECK(stat);
#ifdef DEBUG2
2011-04-18 02:56:10 +08:00
fprintf(stdout,"ncid=%d ngatts=%d ndims=%d nvars=%d unlimid=%d\n",
hdr->ncid,hdr->ngatts,hdr->ndims,hdr->nvars,hdr->unlimid);
#endif
hdr->gatts = (NCattribute*)calloc(1, (size_t)hdr->ngatts*sizeof(NCattribute));
2011-04-18 02:56:10 +08:00
MEMCHECK(hdr->gatts,NC_ENOMEM);
if(hdr->ngatts > 0)
fprintf(stdout,"global attributes:\n");
for(i=0;i<hdr->ngatts;i++) {
NCattribute* att = &hdr->gatts[i];
char attname[NC_MAX_NAME];
nc_type nctype;
size_t typesize;
size_t nvalues;
stat = nc_inq_attname(hdr->ncid,NC_GLOBAL,i,attname);
CHECK(stat);
att->name = nulldup(attname);
stat = nc_inq_att(hdr->ncid,NC_GLOBAL,att->name,&nctype,&nvalues);
CHECK(stat);
att->etype = nctypetodap(nctype);
typesize = nctypesizeof(att->etype);
fprintf(stdout,"\t[%d]: name=%s type=%s values(%lu)=",
i,att->name,nctypetostring(octypetonc(att->etype)),
(unsigned long)nvalues);
if(nctype == NC_CHAR) {
size_t len = typesize*nvalues;
char* values = (char*)malloc(len+1);/* for null terminate*/
MEMCHECK(values,NC_ENOMEM);
stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values);
CHECK(stat);
values[len] = '\0';
fprintf(stdout," '%s'",values);
} else {
size_t len = typesize*nvalues;
char* values = (char*)malloc(len);
MEMCHECK(values,NC_ENOMEM);
stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values);
CHECK(stat);
for(size_t k=0;k<nvalues;k++) {
2011-04-18 02:56:10 +08:00
fprintf(stdout," ");
dumpdata1(octypetonc(att->etype),k,values);
}
}
fprintf(stdout,"\n");
}
hdr->dims = (Dim*)malloc((size_t)hdr->ndims*sizeof(Dim));
2011-04-18 02:56:10 +08:00
MEMCHECK(hdr->dims,NC_ENOMEM);
for(i=0;i<hdr->ndims;i++) {
hdr->dims[i].dimid = i;
stat = nc_inq_dim(hdr->ncid,
hdr->dims[i].dimid,
hdr->dims[i].name,
&hdr->dims[i].size);
CHECK(stat);
fprintf(stdout,"dim[%d]: name=%s size=%lu\n",
i,hdr->dims[i].name,(unsigned long)hdr->dims[i].size);
2019-11-05 05:11:55 +08:00
}
hdr->vars = (Var*)malloc((size_t)hdr->nvars*sizeof(Var));
2011-04-18 02:56:10 +08:00
MEMCHECK(hdr->vars,NC_ENOMEM);
for(i=0;i<hdr->nvars;i++) {
Var* var = &hdr->vars[i];
nc_type nctype;
var->varid = i;
stat = nc_inq_var(hdr->ncid,
var->varid,
var->name,
&nctype,
&var->ndims,
var->dimids,
&var->natts);
CHECK(stat);
var->nctype = (nctype);
fprintf(stdout,"var[%d]: name=%s type=%s |dims|=%d",
i,
var->name,
nctypetostring(var->nctype),
var->ndims);
fprintf(stdout," dims={");
for(j=0;j<var->ndims;j++) {
fprintf(stdout," %d",var->dimids[j]);
}
fprintf(stdout,"}\n");
var->atts = (NCattribute*)malloc((size_t)var->natts*sizeof(NCattribute));
2011-04-18 02:56:10 +08:00
MEMCHECK(var->atts,NC_ENOMEM);
for(j=0;j<var->natts;j++) {
NCattribute* att = &var->atts[j];
char attname[NC_MAX_NAME];
size_t typesize;
char* values;
nc_type nctype;
size_t nvalues;
stat = nc_inq_attname(hdr->ncid,var->varid,j,attname);
CHECK(stat);
att->name = nulldup(attname);
stat = nc_inq_att(hdr->ncid,var->varid,att->name,&nctype,&nvalues);
CHECK(stat);
att->etype = nctypetodap(nctype);
typesize = nctypesizeof(att->etype);
values = (char*)malloc(typesize*nvalues);
MEMCHECK(values,NC_ENOMEM);
stat = nc_get_att(hdr->ncid,var->varid,att->name,values);
CHECK(stat);
fprintf(stdout,"\tattr[%d]: name=%s type=%s values(%lu)=",
j,att->name,nctypetostring(octypetonc(att->etype)),(unsigned long)nvalues);
for(size_t k=0;k<nvalues;k++) {
2011-04-18 02:56:10 +08:00
fprintf(stdout," ");
dumpdata1(octypetonc(att->etype),k,values);
}
fprintf(stdout,"\n");
}
2019-11-05 05:11:55 +08:00
}
2011-04-18 02:56:10 +08:00
fflush(stdout);
return NC_NOERR;
}
void
dumpdata1(nc_type nctype, size_t index, char* data)
{
switch (nctype) {
case NC_CHAR:
fprintf(stdout,"'%c' %hhd",data[index],data[index]);
break;
case NC_BYTE:
fprintf(stdout,"%hhdB",((signed char*)data)[index]);
2011-04-18 02:56:10 +08:00
break;
case NC_UBYTE:
fprintf(stdout,"%hhuB",((unsigned char*)data)[index]);
2011-04-18 02:56:10 +08:00
break;
case NC_SHORT:
fprintf(stdout,"%hdS",((short*)data)[index]);
break;
case NC_USHORT:
fprintf(stdout,"%hdUS",((unsigned short*)data)[index]);
break;
case NC_INT:
fprintf(stdout,"%d",((int*)data)[index]);
break;
case NC_UINT:
fprintf(stdout,"%uU",((unsigned int*)data)[index]);
break;
case NC_FLOAT:
fprintf(stdout,"%#gF",((float*)data)[index]);
break;
case NC_DOUBLE:
fprintf(stdout,"%#gD",((double*)data)[index]);
break;
case NC_STRING:
fprintf(stdout,"\"%s\"",((char**)data)[index]);
break;
default:
fprintf(stdout,"Unknown type: %i",nctype);
break;
}
fflush(stdout);
}
/* Following should be kept consistent with
the makeXXXstring3 routines in constraints3.c
*/
/* Convert an NCprojection instance into a string
that can be used with the url
*/
char*
dumpprojections(NClist* projections)
{
2011-11-14 12:20:19 +08:00
char* tmp;
tmp = dcelisttostring(projections,",");
return tmp;
2011-04-18 02:56:10 +08:00
}
char*
dumpprojection(DCEprojection* proj)
{
2011-11-14 12:20:19 +08:00
char* tmp;
tmp = dcetostring((DCEnode*)proj);
return tmp;
2011-04-18 02:56:10 +08:00
}
char*
dumpselections(NClist* selections)
{
return dcelisttostring(selections,"&");
}
char*
dumpselection(DCEselection* sel)
{
return dcetostring((DCEnode*)sel);
}
char*
dumpconstraint(DCEconstraint* con)
{
2011-11-14 12:20:19 +08:00
char* tmp;
tmp = dcetostring((DCEnode*)con);
return tmp;
2011-04-18 02:56:10 +08:00
}
char*
dumpsegments(NClist* segments)
{
return dcelisttostring(segments,".");
}
char*
dumppath(CDFnode* leaf)
{
NClist* path = nclistnew();
NCbytes* buf = ncbytesnew();
char* result;
size_t i;
2011-04-18 02:56:10 +08:00
if(leaf == NULL) return nulldup("");
collectnodepath(leaf,path,!WITHDATASET);
2011-04-18 02:56:10 +08:00
for(i=0;i<nclistlength(path);i++) {
CDFnode* node = (CDFnode*)nclistget(path,i);
if(i > 0) ncbytescat(buf,".");
2011-11-14 12:20:19 +08:00
ncbytescat(buf,node->ncbasename);
2011-04-18 02:56:10 +08:00
}
result = ncbytesdup(buf);
ncbytesfree(buf);
nclistfree(path);
return result;
}
static void
dumpindent(int indent, NCbytes* buf)
{
int i;
for(i=0;i<indent;i++) ncbytescat(buf,indentstr);
}
static void
dumptreer1(CDFnode* root, NCbytes* buf, int indent, char* tag, int visible)
{
size_t i;
2011-04-18 02:56:10 +08:00
dumpindent(indent,buf);
ncbytescat(buf,tag);
ncbytescat(buf," {\n");
for(i=0;i<nclistlength(root->subnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(root->subnodes,i);
if(visible && root->invisible) continue;
2011-04-18 02:56:10 +08:00
if(root->nctype == NC_Grid) {
if(i==0) {
dumpindent(indent+1,buf);
ncbytescat(buf,"Array:\n");
} else if(i==1) {
dumpindent(indent+1,buf);
ncbytescat(buf,"Maps:\n");
}
dumptreer(node,buf,indent+2,visible);
} else {
dumptreer(node,buf,indent+1,visible);
}
}
dumpindent(indent,buf);
ncbytescat(buf,"} ");
2013-02-26 12:31:06 +08:00
ncbytescat(buf,(root->ncbasename?root->ncbasename:"<?>"));
2011-04-18 02:56:10 +08:00
}
static void
dumptreer(CDFnode* root, NCbytes* buf, int indent, int visible)
{
size_t i;
2011-04-18 02:56:10 +08:00
char* primtype = NULL;
2011-11-14 12:20:19 +08:00
NClist* dimset = NULL;
if(visible && root->invisible) return;
2011-04-18 02:56:10 +08:00
switch (root->nctype) {
case NC_Dataset:
dumptreer1(root,buf,indent,"Dataset",visible);
break;
case NC_Sequence:
dumptreer1(root,buf,indent,"Sequence",visible);
break;
case NC_Structure:
dumptreer1(root,buf,indent,"Structure",visible);
break;
case NC_Grid:
dumptreer1(root,buf,indent,"Grid",visible);
break;
case NC_Atomic:
2011-04-18 02:56:10 +08:00
switch (root->etype) {
case NC_BYTE: primtype = "byte"; break;
case NC_CHAR: primtype = "char"; break;
case NC_SHORT: primtype = "short"; break;
case NC_INT: primtype = "int"; break;
case NC_FLOAT: primtype = "float"; break;
case NC_DOUBLE: primtype = "double"; break;
case NC_UBYTE: primtype = "ubyte"; break;
case NC_USHORT: primtype = "ushort"; break;
case NC_UINT: primtype = "uint"; break;
case NC_INT64: primtype = "int64"; break;
case NC_UINT64: primtype = "uint64"; break;
case NC_STRING: primtype = "string"; break;
default: break;
}
dumpindent(indent,buf);
ncbytescat(buf,primtype);
ncbytescat(buf," ");
2013-02-26 12:31:06 +08:00
ncbytescat(buf,(root->ncbasename?root->ncbasename:"<?>"));
2011-04-18 02:56:10 +08:00
break;
2019-11-05 05:11:55 +08:00
default: break;
2011-04-18 02:56:10 +08:00
}
2011-11-14 12:20:19 +08:00
if(nclistlength(root->array.dimsetplus) > 0) dimset = root->array.dimsetplus;
else if(nclistlength(root->array.dimset0) > 0) dimset = root->array.dimset0;
if(dimset != NULL) {
for(i=0;i<nclistlength(dimset);i++) {
CDFnode* dim = (CDFnode*)nclistget(dimset,i);
2011-04-18 02:56:10 +08:00
char tmp[64];
ncbytescat(buf,"[");
2011-11-14 12:20:19 +08:00
if(dim->ncbasename != NULL) {
ncbytescat(buf,dim->ncbasename);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,"=");
}
snprintf(tmp,sizeof(tmp),"%lu",(unsigned long)dim->dim.declsize);
ncbytescat(buf,tmp);
ncbytescat(buf,"]");
}
}
ncbytescat(buf,";\n");
}
char*
dumptree(CDFnode* root)
{
NCbytes* buf = ncbytesnew();
char* result;
dumptreer(root,buf,0,0);
result = ncbytesdup(buf);
ncbytesfree(buf);
return result;
}
char*
dumpvisible(CDFnode* root)
{
NCbytes* buf = ncbytesnew();
char* result;
dumptreer(root,buf,0,1);
result = ncbytesdup(buf);
ncbytesfree(buf);
return result;
}
/* Provide detailed data on a CDFnode */
char*
dumpnode(CDFnode* node)
{
NCbytes* buf = ncbytesnew();
char* result;
size_t i;
2011-04-18 02:56:10 +08:00
char* nctype = NULL;
char* primtype = NULL;
char tmp[1024];
switch (node->nctype) {
case NC_Dataset: nctype = "Dataset"; break;
case NC_Sequence: nctype = "Sequence"; break;
case NC_Structure: nctype = "Structure"; break;
case NC_Grid: nctype = "Grid"; break;
case NC_Atomic:
2011-04-18 02:56:10 +08:00
switch (node->etype) {
case NC_BYTE: primtype = "byte"; break;
case NC_CHAR: primtype = "char"; break;
case NC_SHORT: primtype = "short"; break;
case NC_INT: primtype = "int"; break;
case NC_FLOAT: primtype = "float"; break;
case NC_DOUBLE: primtype = "double"; break;
case NC_UBYTE: primtype = "ubyte"; break;
case NC_USHORT: primtype = "ushort"; break;
case NC_UINT: primtype = "uint"; break;
case NC_INT64: primtype = "int64"; break;
case NC_UINT64: primtype = "uint64"; break;
case NC_STRING: primtype = "string"; break;
default: break;
}
break;
2019-11-05 05:11:55 +08:00
default: break;
2011-04-18 02:56:10 +08:00
}
snprintf(tmp,sizeof(tmp),"%s %s {\n",
2011-11-14 12:20:19 +08:00
(nctype?nctype:primtype),node->ocname);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
Support MSYS2/Mingw platform re: The current netcdf-c release has some problems with the mingw platform on windows. Mostly they are path issues. Changes to support mingw+msys2: ------------------------------- * Enable option of looking into the windows registry to find the mingw root path. In aid of proper path handling. * Add mingw+msys as a specific platform in configure.ac and move testing of the platform to the front so it is available early. * Handle mingw X libncpoco (dynamic loader) properly even though mingw does not yet support it. * Handle mingw X plugins properly even though mingw does not yet support it. * Alias pwd='pwd -W' to better handle paths in shell scripts. * Plus a number of other minor compile irritations. * Disallow the use of multiple nc_open's on the same file for windows (and mingw) because windows does not seem to handle these properly. Not sure why we did not catch this earlier. * Add mountpoint info to dpathmgr.c to help support mingw. * Cleanup dpathmgr conversions. Known problems: --------------- * I have not been able to get shared libraries to work, so plugins/filters must be disabled. * There is some kind of problem with libcurl that I have not solved, so all uses of libcurl (currently DAP+Byterange) must be disabled. Misc. other fixes: ------------------ * Cleanup the relationship between ENABLE_PLUGINS and various other flags in CMakeLists.txt and configure.ac. * Re-arrange the TESTDIRS order in Makefile.am. * Add pseudo-breakpoint to nclog.[ch] for debugging. * Improve the documentation of the path manager code in ncpathmgr.h * Add better support for relative paths in dpathmgr.c * Default the mode args to NCfopen to include "b" (binary) for windows. * Add optional debugging output in various places. * Make sure that everything builds with plugins disabled. * Fix numerous (s)printf inconsistencies betweenb the format spec and the arguments.
2021-12-24 13:18:56 +08:00
snprintf(tmp,sizeof(tmp),"ocnode=%p\n",node->ocnode);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"container=%s\n",
2011-11-14 12:20:19 +08:00
(node->container?node->container->ocname:"null"));
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"root=%s\n",
2011-11-14 12:20:19 +08:00
(node->root?node->root->ocname:"null"));
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"ncbasename=%s\n",node->ncbasename);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"ncfullname=%s\n",node->ncfullname);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"|subnodes|=%u\n",(unsigned)nclistlength(node->subnodes));
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"externaltype=%d\n",node->externaltype);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"ncid=%d\n",node->ncid);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"maxstringlength=%ld\n",node->maxstringlength);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"sequencelimit=%ld\n",node->sequencelimit);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"usesequence=%d\n",node->usesequence);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"elided=%d\n",node->elided);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"invisible=%d\n",node->invisible);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"attachment=%s\n",
2011-11-14 12:20:19 +08:00
(node->attachment?node->attachment->ocname:"null"));
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp),"rank=%u\n",(unsigned)nclistlength(node->array.dimset0));
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
2011-11-14 12:20:19 +08:00
for(i=0;i<nclistlength(node->array.dimset0);i++) {
CDFnode* dim = (CDFnode*)nclistget(node->array.dimset0,i);
snprintf(tmp,sizeof(tmp),"dims[%zu]={\n",i);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
2011-11-14 12:20:19 +08:00
snprintf(tmp,sizeof(tmp)," ocname=%s\n",dim->ocname);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp)," ncbasename=%s\n",dim->ncbasename);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp)," dimflags=%u\n",
(unsigned int)dim->dim.dimflags);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp)," declsize=%lu\n",
(unsigned long)dim->dim.declsize);
ncbytescat(buf,tmp);
snprintf(tmp,sizeof(tmp)," }\n");
ncbytescat(buf,tmp);
}
result = ncbytesdup(buf);
ncbytesfree(buf);
return result;
}
char*
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-16 01:00:38 +08:00
dumpalign(NCD2alignment* ncalign)
2011-04-18 02:56:10 +08:00
{
char* result;
char tmp[1024];
if(ncalign == NULL)
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-16 01:00:38 +08:00
result = nulldup("NCD2alignment{size=-- alignment=-- offset=--}");
2011-04-18 02:56:10 +08:00
else {
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-16 01:00:38 +08:00
snprintf(tmp,sizeof(tmp),"NCD2alignment{size=%lu alignment=%lu offset=%lu}",
2011-04-18 02:56:10 +08:00
ncalign->size,ncalign->alignment,ncalign->offset);
result = nulldup(tmp);
}
return result;
}
char*
dumpcachenode(NCcachenode* node)
{
char* result = NULL;
char tmp[8192];
size_t i;
2011-04-18 02:56:10 +08:00
NCbytes* buf;
if(node == NULL) return strdup("cachenode{null}");
buf = ncbytesnew();
result = dcebuildconstraintstring(node->constraint);
Support MSYS2/Mingw platform re: The current netcdf-c release has some problems with the mingw platform on windows. Mostly they are path issues. Changes to support mingw+msys2: ------------------------------- * Enable option of looking into the windows registry to find the mingw root path. In aid of proper path handling. * Add mingw+msys as a specific platform in configure.ac and move testing of the platform to the front so it is available early. * Handle mingw X libncpoco (dynamic loader) properly even though mingw does not yet support it. * Handle mingw X plugins properly even though mingw does not yet support it. * Alias pwd='pwd -W' to better handle paths in shell scripts. * Plus a number of other minor compile irritations. * Disallow the use of multiple nc_open's on the same file for windows (and mingw) because windows does not seem to handle these properly. Not sure why we did not catch this earlier. * Add mountpoint info to dpathmgr.c to help support mingw. * Cleanup dpathmgr conversions. Known problems: --------------- * I have not been able to get shared libraries to work, so plugins/filters must be disabled. * There is some kind of problem with libcurl that I have not solved, so all uses of libcurl (currently DAP+Byterange) must be disabled. Misc. other fixes: ------------------ * Cleanup the relationship between ENABLE_PLUGINS and various other flags in CMakeLists.txt and configure.ac. * Re-arrange the TESTDIRS order in Makefile.am. * Add pseudo-breakpoint to nclog.[ch] for debugging. * Improve the documentation of the path manager code in ncpathmgr.h * Add better support for relative paths in dpathmgr.c * Default the mode args to NCfopen to include "b" (binary) for windows. * Add optional debugging output in various places. * Make sure that everything builds with plugins disabled. * Fix numerous (s)printf inconsistencies betweenb the format spec and the arguments.
2021-12-24 13:18:56 +08:00
snprintf(tmp,sizeof(tmp),"cachenode%s(%p){size=%lu; constraint=%s; vars=",
node->isprefetch?"*":"",
Support MSYS2/Mingw platform re: The current netcdf-c release has some problems with the mingw platform on windows. Mostly they are path issues. Changes to support mingw+msys2: ------------------------------- * Enable option of looking into the windows registry to find the mingw root path. In aid of proper path handling. * Add mingw+msys as a specific platform in configure.ac and move testing of the platform to the front so it is available early. * Handle mingw X libncpoco (dynamic loader) properly even though mingw does not yet support it. * Handle mingw X plugins properly even though mingw does not yet support it. * Alias pwd='pwd -W' to better handle paths in shell scripts. * Plus a number of other minor compile irritations. * Disallow the use of multiple nc_open's on the same file for windows (and mingw) because windows does not seem to handle these properly. Not sure why we did not catch this earlier. * Add mountpoint info to dpathmgr.c to help support mingw. * Cleanup dpathmgr conversions. Known problems: --------------- * I have not been able to get shared libraries to work, so plugins/filters must be disabled. * There is some kind of problem with libcurl that I have not solved, so all uses of libcurl (currently DAP+Byterange) must be disabled. Misc. other fixes: ------------------ * Cleanup the relationship between ENABLE_PLUGINS and various other flags in CMakeLists.txt and configure.ac. * Re-arrange the TESTDIRS order in Makefile.am. * Add pseudo-breakpoint to nclog.[ch] for debugging. * Improve the documentation of the path manager code in ncpathmgr.h * Add better support for relative paths in dpathmgr.c * Default the mode args to NCfopen to include "b" (binary) for windows. * Add optional debugging output in various places. * Make sure that everything builds with plugins disabled. * Fix numerous (s)printf inconsistencies betweenb the format spec and the arguments.
2021-12-24 13:18:56 +08:00
node,
2011-04-18 02:56:10 +08:00
(unsigned long)node->xdrsize,
2011-11-14 12:20:19 +08:00
result);
2011-04-18 02:56:10 +08:00
ncbytescat(buf,tmp);
if(nclistlength(node->vars)==0)
ncbytescat(buf,"null");
else for(i=0;i<nclistlength(node->vars);i++) {
CDFnode* var = (CDFnode*)nclistget(node->vars,i);
if(i > 0) ncbytescat(buf,",");
ncbytescat(buf,makecdfpathstring(var,"."));
2011-04-18 02:56:10 +08:00
}
ncbytescat(buf,"}");
result = ncbytesdup(buf);
ncbytesfree(buf);
return result;
}
char*
dumpcache(NCcache* cache)
{
char* result = NULL;
char tmp[8192];
size_t i;
2011-04-18 02:56:10 +08:00
NCbytes* buf;
if(cache == NULL) return strdup("cache{null}");
buf = ncbytesnew();
snprintf(tmp,sizeof(tmp),"cache{limit=%lu; size=%lu;\n",
(unsigned long)cache->cachelimit,
(unsigned long)cache->cachesize);
ncbytescat(buf,tmp);
if(cache->prefetch) {
ncbytescat(buf,"\tprefetch=");
ncbytescat(buf,dumpcachenode(cache->prefetch));
ncbytescat(buf,"\n");
}
if(nclistlength(cache->nodes) > 0) {
for(i=0;i<nclistlength(cache->nodes);i++) {
NCcachenode* node = (NCcachenode*)nclistget(cache->nodes,i);
ncbytescat(buf,"\t");
ncbytescat(buf,dumpcachenode(node));
ncbytescat(buf,"\n");
}
}
ncbytescat(buf,"}");
result = ncbytesdup(buf);
ncbytesfree(buf);
return result;
}
/* This should be consistent with makeslicestring3 in constraints3.c */
char*
dumpslice(DCEslice* slice)
{
char buf[8192];
char tmp[8192];
buf[0] = '\0';
if(slice->last > slice->declsize && slice->declsize > 0)
slice->last = slice->declsize - 1;
if(slice->count == 1) {
snprintf(tmp,sizeof(tmp),"[%lu]",
(unsigned long)slice->first);
} else if(slice->stride == 1) {
snprintf(tmp,sizeof(tmp),"[%lu:%lu]",
(unsigned long)slice->first,
(unsigned long)slice->last);
} else {
snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu]",
(unsigned long)slice->first,
(unsigned long)slice->stride,
(unsigned long)slice->last);
}
strlcat(buf,tmp,sizeof(buf));
return strdup(tmp);
2011-04-18 02:56:10 +08:00
}
char*
dumpslices(DCEslice* slice, unsigned int rank)
{
int i;
NCbytes* buf;
char* result = NULL;
buf = ncbytesnew();
for(i=0;i<rank;i++,slice++) {
char* sslice = dumpslice(slice);
2014-04-08 03:00:47 +08:00
if(sslice != NULL) {
ncbytescat(buf,sslice);
free(sslice);
}
2011-04-18 02:56:10 +08:00
}
result = ncbytesdup(buf);
ncbytesfree(buf);
return result;
}
2011-11-14 12:20:19 +08:00
void
dumpraw(void* o)
{
fprintf(stderr,"%s\n",dcerawtostring(o));
fflush(stderr);
}
void
dumplistraw(NClist* l)
{
fprintf(stderr,"%s\n",dcerawlisttostring(l));
fflush(stderr);
}
/* For debugging */
void
dumpstringlist(NClist* l)
{
size_t i;
for(i=0;i<nclistlength(l);i++) {
const char* s = (const char*)nclistget(l,i);
fprintf(stderr,"[%zu]: |%s|\n",i,s);
}
fflush(stderr);
}