Opened 7 years ago

Closed 7 years ago

#1951 closed defect (fixed)

Crash in ST_Distance

Reported by: realityexists Owned by: pramsey
Priority: medium Milestone: PostGIS 2.1.0
Component: postgis Version: trunk
Keywords: Cc:

Description

When I run a particular plpgsql function that calls ST_Distance the PostgreSQL backend crashes:

Program received signal SIGSEGV, Segmentation fault.
sphere_distance (s=0x9b4cea8, e=0x0) at lwgeodetic.c:758
758		double d_lon = e->lon - s->lon;

The following simplified function reproduces the crash:

CREATE OR REPLACE FUNCTION _distance_crash_repro6()
RETURNS integer AS
$BODY$
DECLARE
	line geography[];
	i integer;
	current_line geography(LineString);
	current_distance float;
BEGIN
	line := ARRAY[ 
		'POINT(-60.1529782532063 -3.00395030900105)'::geography,
		'POINT(-60.1529985502867 -3.00511933469609)'::geography,
		'POINT(-60.1529985502867 -3.00511933469609)'::geography];

	FOR i IN array_lower(line, 1) .. array_upper(line, 1) - 1 LOOP
		current_line := ST_MakeLine(line[i]::geometry, line[i + 1]::geometry)::geography;
		current_distance := ST_Distance(current_line, 'POINT(-60.1529903235046 -3.00464549022075)'::geography);
	END LOOP;

	RETURN -1;
END
$BODY$ LANGUAGE plpgsql IMMUTABLE;

SELECT _distance_crash_repro6();

I haven't been able to repro it without a function or without an array. Stack trace from the simplified repro attached.

"POSTGIS="2.1.0SVN r10181" GEOS="3.4.0dev-CAPI-1.8.0 r3703" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.0, released 2011/12/29" LIBXML="2.7.8" RASTER"

"PostgreSQL 9.1.4 on i686-pc-linux-gnu, compiled by gcc (Ubuntu/Linaro? 4.5.2-8ubuntu4) 4.5.2, 32-bit"

(also happens on Windows 7 x64)

Attachments (1)

crash-proc-paths-stack.txt (5.1 KB) - added by realityexists 7 years ago.

Download all attachments as: .zip

Change History (4)

Changed 7 years ago by realityexists

Attachment: crash-proc-paths-stack.txt added

comment:1 Changed 7 years ago by pramsey

The function has to hit the distance function twice to get the caching to kick in and thereby hit the tree. You can skip the cache by calling _ST_DistanceTree(geog, geog) directly for testing, and it goes boom:

select _st_distancetree('LINESTRING(-60.1529985502867 -3.00511933469609, -60.1529985502867 -3.00511933469609)'::geography, 'POINT(-60.1529903235046 -3.00464549022075)'::geography);

comment:2 Changed 7 years ago by pramsey

And looks like any simple version with just two duped coordinates will do. However duped coordinates in a larger line have no problems:

-- works
select _st_distancetree('LINESTRING(0.1 0,0 0,0 0)'::geography, 'POINT(0.1 0.1)'::geography);
-- works
select _st_distancetree('LINESTRING(0 0,0 0,0 0.1)'::geography, 'POINT(0.1 0.1)'::geography);
-- boom
select _st_distancetree('LINESTRING(0 0,0 0)'::geography, 'POINT(0.1 0.1)'::geography);

comment:3 Changed 7 years ago by pramsey

Resolution: fixed
Status: newclosed

Fixed at r10183

Note: See TracTickets for help on using tickets.