[GRASS-dev] d.thematic.area: need for a bit of help in C-programming/debugging

Hello,

I'm having a problem with the d.thematic.area module I just committed in a modified version.

When I use the discontinuities algorithm for calculating the class breaks, I get segmentation faults, depending on the number of classes I ask for and on the variable I try to class.

For example, using a local copy of the censusblk_swwake in an sqlite mapset, I run:

for var in HH_SIZE MEDIAN_AGE TOTAL_POP; do for i in 5 6 7 8 9 10; do echo "$var, $i: "; d.thematic.area ilots colu=$var algo=dis nbcla=$i color=254:240:217,253:204:138,252:141:89,227:74:51,179:0:0,254:240:217,253:204:138,252:141:89,227:74:51,179:0:0; done; done

which gives me:

HH_SIZE, 5:
HH_SIZE, 6:
Segmentation fault
HH_SIZE, 7:
HH_SIZE, 8:
HH_SIZE, 9:
Segmentation fault
HH_SIZE, 10:
Segmentation fault
MEDIAN_AGE, 5:
MEDIAN_AGE, 6:
Segmentation fault
MEDIAN_AGE, 7:
MEDIAN_AGE, 8:
MEDIAN_AGE, 9:
Segmentation fault
MEDIAN_AGE, 10:
TOTAL_POP, 5:
TOTAL_POP, 6:
Segmentation fault
TOTAL_POP, 7:
TOTAL_POP, 8:
TOTAL_POP, 9:
Segmentation fault
TOTAL_POP, 10:
Segmentation fault

It seems to be linked to the class_discont function in lib/arraystats/class.c, as this only happens with this algorithm. However, when I do the same test with d.thematic.areas -nl flags (i.e. don't plot the map, but only output legend info), I don't get the segfaults, so there is some problem between this function and the display functions.

I seem to have tracked it down to the call to Vect_new_line_struct() on line 32 in display/d.thematic.area/area.c and from there to (I think) Vect__new_line_struct in lib/vector/Vlib/line.c.

I imagine it is just some stupid C-novice error, probably memory allocation somewhere, so I would really appreciate if someone with the relevant knowledge could just glance over the code to see if there is something obvious...

Moritz

Moritz Lennert wrote:

I'm having a problem with the d.thematic.area module I just committed in
a modified version.

It seems to be linked to the class_discont function in
lib/arraystats/class.c, as this only happens with this algorithm.
However, when I do the same test with d.thematic.areas -nl flags (i.e.
don't plot the map, but only output legend info), I don't get the
segfaults, so there is some problem between this function and the
display functions.

Or you just get lucky in that case.

I seem to have tracked it down to the call to Vect_new_line_struct() on
line 32 in display/d.thematic.area/area.c and from there to (I think)
Vect__new_line_struct in lib/vector/Vlib/line.c.

Vect_new_line_struct() just malloc()s a block of memory. If it's
crashing there, then it's because the heap has been corrupted, by
overrunning another heap buffer.

I suggest using glibc's mprobe() function:

-- Function: enum mcheck_status mprobe (void *POINTER)
     The `mprobe' function lets you explicitly check for inconsistencies
     in a particular allocated block. You must have already called
     `mcheck' at the beginning of the program, to do its occasional
     checks; calling `mprobe' requests an additional consistency check
     to be done at the time of the call.

     The argument POINTER must be a pointer returned by `malloc' or
     `realloc'. `mprobe' returns a value that says what inconsistency,
     if any, was found. The values are described below.

-- Data Type: enum mcheck_status
     This enumerated type describes what kind of inconsistency was
     detected in an allocated block, if any. Here are the possible
     values:

    `MCHECK_DISABLED'
          `mcheck' was not called before the first allocation. No
          consistency checking can be done.

    `MCHECK_OK'
          No inconsistency detected.

    `MCHECK_HEAD'
          The data immediately before the block was modified. This
          commonly happens when an array index or pointer is
          decremented too far.

    `MCHECK_TAIL'
          The data immediately after the block was modified. This
          commonly happens when an array index or pointer is
          incremented too far.

    `MCHECK_FREE'
          The block was already freed.

To use it, you need to link the program with -lmcheck (this ensures
that mcheck() is called before the first malloc()), then call mprobe()
on any malloc()d block which you suspect may be getting overrun (those
in class_discont() would seem like an obvious choice).

--
Glynn Clements <glynn@gclements.plus.com>

On 24/07/08 21:39, Glynn Clements wrote:
  > To use it, you need to link the program with -lmcheck (this ensures

that mcheck() is called before the first malloc()),

Sorry, need some help on this one. Tried adding -lmcheck to CFLAGS1 in include/Make/Platform.make, but get the following during compilation:

gcc: -lmcheck: linker input file unused because linking not done

How do I link ?

Moritz

On 29/07/08 10:01, Moritz Lennert wrote:

On 24/07/08 21:39, Glynn Clements wrote:
> To use it, you need to link the program with -lmcheck (this ensures

that mcheck() is called before the first malloc()),

Sorry, need some help on this one. Tried adding -lmcheck to CFLAGS1 in include/Make/Platform.make, but get the following during compilation:

gcc: -lmcheck: linker input file unused because linking not done

How do I link ?

Duh, obviously this message appears only each of the individual .c files. Linking is done afterwards...

Sorry for the noise,

Moritz

Moritz Lennert wrote:

> > To use it, you need to link the program with -lmcheck (this ensures
>> that mcheck() is called before the first malloc()),
>
> Sorry, need some help on this one. Tried adding -lmcheck to CFLAGS1 in
> include/Make/Platform.make, but get the following during compilation:
>
> gcc: -lmcheck: linker input file unused because linking not done
>
> How do I link ?

Duh, obviously this message appears only each of the individual .c
files. Linking is done afterwards...

Sorry for the noise,

Actually, I should have said LINK_FLAGS rather than CFLAGS1.

--
Glynn Clements <glynn@gclements.plus.com>

On 29/07/08 15:40, Glynn Clements wrote:

Moritz Lennert wrote:

> To use it, you need to link the program with -lmcheck (this ensures

that mcheck() is called before the first malloc()),

Sorry, need some help on this one. Tried adding -lmcheck to CFLAGS1 in include/Make/Platform.make, but get the following during compilation:

gcc: -lmcheck: linker input file unused because linking not done

How do I link ?

Duh, obviously this message appears only each of the individual .c files. Linking is done afterwards...

Sorry for the noise,

Actually, I should have said LINK_FLAGS rather than CFLAGS1.

Yes, found that one out in the meantime. I seem to have narrowed the problem down to a particular pointer, but haven't had the time to see where exactly it overflows.

Thanks!

Moritz