[GRASS-dev] Addons: r.sun2 segfault

Glynn Clements glynn at gclements.plus.com
Wed Oct 22 10:31:32 EDT 2008


Markus Neteler wrote:

> Running it on a different machine with 16GB RAM it starts and
> then crashed at 0.x%:
> 
> (gdb) r -s pat_dtm_5m horizon=horangle horizonstep=15
> aspin=pat_dtm_5m.as slopein=pat_dtm_5m.sl day=180
> insol_time=photoperiodo_d180
> Starting program: /home/neteler/binaries/grass-6.4.svn/bin/r.sun2 -s
> pat_dtm_5m horizon=horangle horizonstep=15 aspin=pat_dtm_5m.as
> slopein=pat_dtm_5m.sl day=180 insol_time=photoperiodo_d180
> [Thread debugging using libthread_db enabled]
> Mode 2: integrated daily irradiation
> [New Thread 47358322518032 (LWP 1627)]
> 
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 47358322518032 (LWP 1627)]
> 0x0000000000404fb8 in INPUT_part (offset=0, zmax=0x7fff33a95a38) at main.c:979
> 979                         horizonpointer[i] = (char)(rint(SCALING_FACTOR *
> (gdb) bt
> #0  0x0000000000404fb8 in INPUT_part (offset=0, zmax=0x7fff33a95a38)
> at main.c:979
> #1  0x00000000004076ac in calculate
> (singleSlope=3.6565798448710657e-319,
> singleAspect=1.90389130408995e-314,
>     singleAlbedo=0.20000000000000001, singleLinke=3, gridGeom=
>       {xp = 6.9531864307740289e-310, yp = 1.0909214257054157e-312, xx0
> = 0, yy0 = 2.3398120197805848e-310, xg0 = 2.339812019231579e-310, yg0
> = 2.0760929936980226e-317, stepx = 5, stepy = 5, deltx = 117610, delty
> = 97545, stepxy = 5, sinlat = 2.3398112026541087e-310, coslat =
> 6.9531864307767956e-310}) at main.c:1880
> #2  0x0000000000404457 in main (argc=9, argv=0x7fff33a95df8) at main.c:759
> (gdb)

	    for (row = m - offset - 1; row >= finalRow; row--) {

		row_rev = m - row - 1;
		rowrevoffset = row_rev - offset;

		horizonpointer = horizonarray + arrayNumInt * n * rowrevoffset;

The worst-case situation is when row == 0:

	m = cellhd.rows = 19509
	n = cellhd.cols = 23522
	arrayNumInt = 360 / horizonStep = 360/15 = 24
	row_rev = m - row - 1 = 19509 - 0 - 1 = 19508 (for row==0)
	rowrevoffset = row_rev - offset = 19508 - 0 = 19508

	arrayNumInt * n * rowrevoffset = 24 * 23522 * 19508 = 11,012,812,224

arrayNumInt, n and rowrevoffset are all "int"s, which is presumably
only 32 bits. After 2GiB, the calculation will wrap and produce large
negative values.

If this is the problem, the immediate segfault can be fixed by casting
to a wider type, e.g.:

		horizonpointer = horizonarray + (ssize_t) arrayNumInt * n * rowrevoffset;

But the code could be littered with such issues (calculating offsets
which won't fit into an "int").

Most of GRASS is immune to this issue by virtue of only holding a
small number of rows in memory at any given time. But any module which
stores an entire map (or, more generally, stores data proportional to
rows*cols) is at risk of having similar issues with large maps.

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


More information about the grass-dev mailing list