Help Finding Strange Memory Bug (Code linked to C library)

Rémy Mouëza remy.moueza at gmail.com
Sat Dec 7 15:11:37 PST 2013


My strategy here would be to:
A.  run the program in a debugger, say GDB, to get a exhaustive 
stacktrace for hints about where to look at.
B. have a quick look at the library directly (the "Use the Source Luke" 
strategy).

Since I was curious about your problem (you had everything correct - 
this should not fail), and have no access to your code, I checked out 
the shapelib code from its cvs public repository and found out that the 
last pointer, `double * padfMaxBound` is actually a pointer to an array 
of 4 elements: in shapelib/shpopen.c: SHPGetInfo: starting line 823:
     for( i = 0; i < 4; i++ )
     {
         if( padfMinBound != NULL )
             padfMinBound[i] = psSHP->adBoundsMin[i];
         if( padfMaxBound != NULL )
             padfMaxBound[i] = psSHP->adBoundsMax[i];
     }

This also explains why it does not segfault when you pass a null 
pointer: no array out of bounds happen then.

padfMaxBound should point to a `double []` or `double [4]` instead of a 
mere `double`.

I also ended checking the API documentation 
(http://shapelib.maptools.org/shp_api.html) and they do document that 
padfMinBound and padfMaxbound are pointers to 4 values X, Y, Z and M in 
a four entry array.
You may want to check if there isn't any other of those "C tricks" 
hiding in your D bindings.



On 12/07/2013 04:29 PM, Craig Dillabaugh wrote:
> Hello,
> I recently wrote bindings to the C-library Shapelib (it reads/writes a
> common file format used in Geographic Information Systems).
>
> I've been trying to write a small test program to make sure my bindings
> 'work' and I've come across a bizarre memory bug.  I THINK I've
> identified the code that causes the problem, but I have no idea why.
>
> My test-suite includes this function:
>
> void shapeRead(string filename) {
>    SHPHandle hShp = SHPOpen( std.string.toStringz( filename ), "rb" );
>
>    int n, shp_type;
>    double pad_min_bound, pad_max_bound;
>
>    SHPGetInfo( hShp, &n, &shp_type, &pad_min_bound, &pad_max_bound);
>
>    SHPClose( hShp );
> }
>
> If I comment out the SHPGetInfo call, then the segmentation fault
> doesn't happen, but if its there then the program segfaults AFTER the
> shapeRead function exits (eg. SHPClose runs fine) ).
>
> In fact if I call SHPGetInfo as follows, the crash doesn't occur:
> SHPGetInfo( hShp, &n, &shp_type, &pad_min_bound, null); //NULL pointer
> last arg.
>
> So in C the function SHPGetInfo is:
>
> void SHPAPI_CALL
>        SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
>                    double * padfMinBound, double * padfMaxBound );
>
> While my D binding is (pretty much the same):
>
> extern( C ) void SHPGetInfo( SHPHandle hSHP, int* pnEntities,
>        int* pnShapeType, double* padfMinBound, double* padfMaxBound );
>
>
> I have no idea what is going on.  The sizes of ints and doubles are 4
> and 8 bytes using gcc on my system (which is how I compiled my C
> library) so those match the sizes of the corresponding D types [I
> thought maybe there was a type-size mismatch and that was causing
> something to be overwritten, but it doesn't appear that way].
>
> Any hints on where to look next would be appreciated.
>
> Craig
>
>
>



More information about the Digitalmars-d-learn mailing list