PG_RETURN_TEXT_P crash server process

Started by Pavel Stehuleover 23 years ago6 messagesbugs
Jump to latest
#1Pavel Stehule
pavel.stehule@gmail.com

Hi

I found some problem with PG_RETURN_TEXT_P. I have function for creating
html list from table column (I use SPI). With small lists function works
fine, but when items is more then 300 (returned text is great then 8K)
For items < 200 is all ok. Increasing of page size helps.

Source code is in attachement. Function is registered

create or replace function html_list (cstring, cstring, int, int) returns
text as 'html_list.so', 'html_list' language 'C';

parameters is
1. SQL query
2. column's name
3. max items (0 - all)
4. page size

SELECT html_list('select jmeno from jmena','jmeno',100,2000); -- ok
SELECT length(html_list('select jmeno from jmena','jmeno',200,2000)); ok
NOTICE: before alloc 4000
NOTICE: after alloc
NOTICE: Alokovan 137108256
NOTICE: after memcpy
NOTICE: befor pfree
NOTICE: after pfree
NOTICE: before alloc 6000
NOTICE: after alloc
NOTICE: Alokovan 137114320
NOTICE: after memcpy
NOTICE: befor pfree
NOTICE: after pfree
NOTICE: before alloc 8000
NOTICE: after alloc
NOTICE: Alokovan 137124648
NOTICE: after memcpy
NOTICE: befor pfree
NOTICE: after pfree
NOTICE: BEFORE finish
NOTICE: AFTER FINISH
length
--------
6674
(1 ��dka)

SELECT html_list('select jmeno from jmena','jmeno',0,2000); -- crash

NOTICE: before alloc 4000
NOTICE: after alloc
NOTICE: Alokovan 137067288
NOTICE: after memcpy
NOTICE: befor pfree
NOTICE: after pfree
NOTICE: before alloc 6000
NOTICE: after alloc
NOTICE: Alokovan 137073352
NOTICE: after memcpy
NOTICE: befor pfree
NOTICE: after pfree
NOTICE: before alloc 8000
NOTICE: after alloc
NOTICE: Alokovan 137083680
NOTICE: after memcpy
NOTICE: befor pfree
NOTICE: after pfree
NOTICE: BEFORE finish
NOTICE: AFTER FINISH
LOG: server process (pid 6955) was terminated by signal 11
LOG: terminating any other active server processes
WARNING: Message from PostgreSQL backend:
The Postmaster has informed me that some other backend
died abnormally and possibly corrupted shared memory.
I have rolled back the current transaction and am
going to terminate your database system connection and exit.
Please reconnect to the database system and repeat your query.

SELECT html_list('select jmeno from jmena','jmeno',0,8000); --ok

Why? What is wrong in my code. Page size has importatnt only for speed,
not for functionality (I think).

I have RedHat 7.2, PostgreSQL 7.3b3 (in 7.3b1 is this problem too)

Pavel Stehule

Attachments:

html_list.ctext/plain; CHARSET=US-ASCII; NAME=html_list.cDownload
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#1)
Re: PG_RETURN_TEXT_P crash server process

Pavel Stehule <stehule@kix.fsv.cvut.cz> writes:

I found some problem with PG_RETURN_TEXT_P.

Fix your code to not scribble on memory that doesn't belong to it,
and all will be well. I can see at least two buffer-overrun bugs,
and there may be more:

txtn = (text *) palloc (ma); -- forgot to add VARHDRSZ

strcpy (*str_pointer, str); -- copies one byte too many

regards, tom lane

#3Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#2)
Re: PG_RETURN_TEXT_P crash server process

You have true. When I modify code on

long ma = ((*saved_chars + l + VARHDRSZ) / page_size + 1) * page_size;
*allocated_free = ma - *saved_chars - VARHDRSZ;

my function works well. Thank you wery much. One night I lost with this
:->

On Tue, 12 Nov 2002, Tom Lane wrote:

Show quoted text

Pavel Stehule <stehule@kix.fsv.cvut.cz> writes:

I found some problem with PG_RETURN_TEXT_P.

Fix your code to not scribble on memory that doesn't belong to it,
and all will be well. I can see at least two buffer-overrun bugs,
and there may be more:

txtn = (text *) palloc (ma); -- forgot to add VARHDRSZ

strcpy (*str_pointer, str); -- copies one byte too many

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org

#4John Liu
johnl@synthesys.com
In reply to: Tom Lane (#2)
bug?

Hi, Tom,
we're using version 7.2.

I've a document table, the cdi column is indexed.
I tried to do a query by using cdi in two ways -

1. the simple query as expected is using index scan
edbs=# explain select emrxid from document where cdi='1031-15402';
NOTICE: QUERY PLAN:

Index Scan using document_cdi_key on document (cost=0.00..4.43 rows=1
width=27)

2. the one using plsql function is not using index scan!
EXPLAIN
edbs=# explain select getEmrxid('1031-15402') from document;
NOTICE: QUERY PLAN:

Seq Scan on document (cost=0.00..447377.72 rows=13018272 width=0)

here's the simple fuction -
create FUNCTION getEmrxid(text)
RETURNS text AS'
DECLARE
cdi_in ALIAS FOR $1;
docrec document%ROWTYPE;
BEGIN
select into docrec * from document where cdi = cdi_in;
RETURN docrec.emrxid;
END;
'LANGUAGE 'plpgsql';

This is not what I expected. If it's normal in pgsql, would you
providing some suggestions how to let function use index.

thanks in advance.

john

#5Stephan Szabo
sszabo@megazone23.bigpanda.com
In reply to: John Liu (#4)
Re: bug?

On Tue, 12 Nov 2002, John Liu wrote:

Hi, Tom,
we're using version 7.2.

I've a document table, the cdi column is indexed.
I tried to do a query by using cdi in two ways -

1. the simple query as expected is using index scan
edbs=# explain select emrxid from document where cdi='1031-15402';
NOTICE: QUERY PLAN:

Index Scan using document_cdi_key on document (cost=0.00..4.43 rows=1
width=27)

2. the one using plsql function is not using index scan!
EXPLAIN
edbs=# explain select getEmrxid('1031-15402') from document;
NOTICE: QUERY PLAN:

These two queries don't do the same thing.
The first gets presumably one emrxid from the table at the particular row.
The second gets one copy of that emrxid from each row in document.
I think you want:
select getEmrxid('1031-15402');

#6Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#3)
Re: PG_RETURN_TEXT_P crash server process (solved)

Hi

PG_RETURN_TEXT_P works well. I made beginer error. I allocated memory by
palloc and before PG_RETURN_TEXT_P deallocated by SPI_finish. After change
SPI_palloc between palloc my function works.

Thank you
Pavel

On Tue, 12 Nov 2002, Pavel Stehule wrote:

Show quoted text

You have true. When I modify code on

long ma = ((*saved_chars + l + VARHDRSZ) / page_size + 1) * page_size;
*allocated_free = ma - *saved_chars - VARHDRSZ;

my function works well. Thank you wery much. One night I lost with this
:->

On Tue, 12 Nov 2002, Tom Lane wrote:

Pavel Stehule <stehule@kix.fsv.cvut.cz> writes:

I found some problem with PG_RETURN_TEXT_P.

Fix your code to not scribble on memory that doesn't belong to it,
and all will be well. I can see at least two buffer-overrun bugs,
and there may be more:

txtn = (text *) palloc (ma); -- forgot to add VARHDRSZ

strcpy (*str_pointer, str); -- copies one byte too many

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo@postgresql.org so that your
message can get through to the mailing list cleanly