Opened 10 years ago

Closed 10 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: master
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 10 years ago.

Download all attachments as: .zip

Change History (4)

by realityexists, 10 years ago

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

comment:1 by pramsey, 10 years ago

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 by pramsey, 10 years ago

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 by pramsey, 10 years ago

Resolution: fixed
Status: newclosed

Fixed at r10183

Note: See TracTickets for help on using tickets.