[GRASS-dev] [GRASS GIS] #3062: Segmentation fault with r.buffer

GRASS GIS trac at osgeo.org
Sat Jun 18 05:18:21 PDT 2016


#3062: Segmentation fault with r.buffer
-----------------------+-------------------------
  Reporter:  escheper  |      Owner:  grass-dev@…
      Type:  defect    |     Status:  new
  Priority:  blocker   |  Milestone:  7.0.5
 Component:  Raster    |    Version:  7.0.4
Resolution:            |   Keywords:  r.buffer
       CPU:  Other     |   Platform:  Linux
-----------------------+-------------------------

Comment (by escheper):

 Replying to [comment:10 annakrat]:
 > I would say it is related to the fact that `to_ptr` is unsigned char, so
 it can overflow fast, although I don't understand the algorithm there.
 Note the comment in the code:
 > {{{
 > /* if MAPTYPE is changed to unsigned short, MAX_DIST can be set to
 2^16-2
 >  * (if short is 2 bytes)
 >  */
 > }}}
 > So I would try to change it to unsigned short. Unfortunately I can't
 easily test the testcase, I have little memory right now.


 Thanks to your tip I found the solution.

 Changing the MAPTYPE didn't solve the problem. But the problem was another
 overflow.

 I'm using a 64,800 x 129,600 grid which results in 8,398,080,000 cells (or
 bytes). This is far beyond the maxint (2,147,483,647) and causes the
 overflow.

 After changing most int variables in the r.buffer code in long types the
 segmentation fault disappeared :).

 I didn't check the output visually, that's what I need to do next. Having
 no segmentation fault is very promising.

 Except from changing the integer types to long, I have changed some "=" to
 "==" in "if" statements in process_left.c, process_at.c and
 process_rite.c. This didn't solve the segmentation fault but in my opinion
 the original code seems not to be correct.

 I found some other lines that may not be correct too. But I'm not sure
 about it. These lines are:

 {{{
 process_rite.c(90): *to_ptr = (first_zone = i) + ZONE_INCR;
 process_row.c(34): for (r = row; r >= 0 && (first_zone =
 find_distances(r)) >= 0; r--)
 process_row.c(47): r < window.rows && (first_zone = find_distances(r)) >=
 0; r++) {
 read_map.c(65): if ((*ptr++ = (*cell++ != 0))) {
 read_map.c(81): if ((*ptr++ = !Rast_is_c_null_value(cell++))) {
 }}}

 Can anyone confirm this?

 Remains the following questions:
 - How are other GRASS modules dealing with large grids? Do they have the
 same problem?
 - What will be the impact on the output raster after changing some "=" to
 "=="? Do we get other result buffers?
 - In what way should I do a "pull request" of my changes in de code.

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/3062#comment:11>
GRASS GIS <https://grass.osgeo.org>



More information about the grass-dev mailing list