repalloc bug

Lists: pgsql-bugs
From: Giacomo Cariello <jwk(at)bug(dot)it>
To: pgsql-bugs(at)postgresql(dot)org
Subject: repalloc bug
Date: 2003-08-19 18:31:30
Message-ID: 5.1.1.6.2.20030819202148.02511898@mail.energy.local
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

Your name: Giacomo Cariello
Your email address: jwk(at)bug(dot)it

System Configuration
---------------------
Architecture (example: Intel Pentium) : CHOST="i686-pc-linux-gnu",
CPU=athlon-xp

Operating System (example: Linux 2.0.26 ELF) : Gentoo Linux 1.4 (kernel
version 2.4.20, ELF, glibc 2.3.2)

PostgreSQL version (example: PostgreSQL-7.3.4): PostgreSQL-7.3.4

Compiler used (example: gcc 2.95.2) : from gcc -v: gcc version
3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r2, propolice)

Please enter a FULL description of your problem:
------------------------------------------------
Using repalloc in some functions in a shared library I load, the effect is
not the desidered one: the allocated area gets overwritten and causes
segfault once the function returns or calls SPI_finish()

Please describe a way to repeat the problem. Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------
hrm...I noticed some memory areas palloc'ed during a SRF initialization get
overwritten. Also backend tends to crash randomly.
As of now I fixed using palloc/memcpy variant to achieve the same result.

If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------
no clue.

Giacomo Cariello, jwk(at)bug(dot)it
KeyID: 3072/1024/0x409C9044
Fingerprint: 7984 10FD 0460 4202 BF90 3881 CDE4 D78E 409C 9044

"Put that mic in my hand and let me kick out the jams!" - MC5


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Giacomo Cariello <jwk(at)bug(dot)it>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: repalloc bug
Date: 2003-08-21 13:24:16
Message-ID: 3941.1061472256@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

Giacomo Cariello <jwk(at)bug(dot)it> writes:
> Using repalloc in some functions in a shared library I load, the effect is
> not the desidered one: the allocated area gets overwritten and causes
> segfault once the function returns or calls SPI_finish()

The odds that this is a bug in repalloc, and not in your own code, are
nil.

regards, tom lane


From: Giacomo Cariello <jwk(at)bug(dot)it>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: repalloc bug
Date: 2003-08-21 19:19:56
Message-ID: 5.1.1.6.2.20030821204738.026abdd0@mail.energy.local
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs


>The odds that this is a bug in repalloc, and not in your own code, are
>nil.
>
> regards, tom lane

Dear Tom Lane,
Thanks for quick response. Trying to focus what kind of bug could infest my
code, I reduced the code to a small example that illustrates the infaust
effect. I've tried to follow as much as possible the manual, so I'm trying
to figure what's wrong.

This is the source code:
---> snip <---
#include <postgres.h>
#include <fmgr.h>
#include <funcapi.h>
#include <commands/trigger.h>
#include <executor/spi.h>
#include <catalog/pg_type.h>
#include <sys/types.h>
#include <ctype.h>

typedef struct
{
TupleDesc tupdesc;
u_int32_t size;
u_int8_t *buf;
} repalloc_test_t;

void repalloc_bubble(u_int8_t *buf, u_int32_t s)
{
buf = repalloc(buf, s);
bzero(buf, s);
}

PG_FUNCTION_INFO_V1(repalloc_test);

Datum repalloc_test(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
repalloc_test_t *d;
u_int32_t i;
MemoryContext oldcontext;

funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
d = funcctx->user_fctx = (repalloc_test_t *)
palloc(sizeof(repalloc_test_t));
bzero(d, sizeof(repalloc_test_t));
d->tupdesc = RelationNameGetTupleDesc("repalloc_type");
d->size = 32;
d->buf = palloc(d->size);
bzero(d->buf, d->size);
for(i = 0; i < d->size; i++)
elog(WARNING, "TEST A: d->buf[%d] = %d", i, d->buf[i]);
d->size = 64;
repalloc_bubble(d->buf, d->size);
for(i = 0; i < d->size; i++)
elog(WARNING, "TEST B: d->buf[%d] = %d", i, d->buf[i]);
funcctx->slot = TupleDescGetSlot(d->tupdesc);
MemoryContextSwitchTo(oldcontext);
funcctx = SRF_PERCALL_SETUP();
SRF_RETURN_DONE(funcctx);
}
----> snip <-----

I've then created the following script to load the library and execute it:

---> snip <---
CREATE TYPE "repalloc_type" AS
(
"count" integer,
"size" integer
);
CREATE OR REPLACE FUNCTION repalloc_test() RETURNS setof repalloc_type AS
'path/to/lib.so' LANGUAGE C IMMUTABLE WITH (isStrict);
SELECT * FROM repalloc_test();
DROP FUNCTION repalloc_test();
DROP TYPE repalloc_type;
---> snip <---

This is the output of the WARNING messages:

---> snip <---
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[0] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[1] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[2] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[3] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[4] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[5] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[6] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[7] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[8] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[9] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[10] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[11] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[12] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[13] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[14] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[15] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[16] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[17] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[18] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[19] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[20] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[21] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[22] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[23] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[24] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[25] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[26] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[27] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[28] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[29] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[30] = 0
psql:repalloc_test.sql:7: WARNING: TEST A: d->buf[31] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[0] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[1] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[2] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[3] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[4] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[5] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[6] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[7] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[8] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[9] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[10] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[11] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[12] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[13] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[14] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[15] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[16] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[17] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[18] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[19] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[20] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[21] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[22] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[23] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[24] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[25] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[26] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[27] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[28] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[29] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[30] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[31] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[32] = 248
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[33] = 196
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[34] = 49
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[35] = 8
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[36] = 128
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[37] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[38] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[39] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[40] = 179
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[41] = 104
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[42] = 236
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[43] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[44] = 99
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[45] = 111
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[46] = 117
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[47] = 110
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[48] = 116
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[49] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[50] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[51] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[52] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[53] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[54] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[55] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[56] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[57] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[58] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[59] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[60] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[61] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[62] = 0
psql:repalloc_test.sql:7: WARNING: TEST B: d->buf[63] = 0
---> snip <---

As you may notice, I never write into d->buf, nor I "overflow" any of the
other values and all the buffers are correctly allocated, but still d->buf
gets overwritten. I may be possibly using the API incorrectly, so could you
please help me understand what's actually failing?

Giacomo Cariello, jwk(at)bug(dot)it
KeyID: 3072/1024/0x409C9044
Fingerprint: 7984 10FD 0460 4202 BF90 3881 CDE4 D78E 409C 9044

"Put that mic in my hand and let me kick out the jams!" - MC5


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Giacomo Cariello <jwk(at)bug(dot)it>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: repalloc bug
Date: 2003-08-21 19:33:02
Message-ID: 21462.1061494382@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

Giacomo Cariello <jwk(at)bug(dot)it> writes:
> void repalloc_bubble(u_int8_t *buf, u_int32_t s)
> {
> buf = repalloc(buf, s);
> bzero(buf, s);
> }

> repalloc_bubble(d->buf, d->size);

This doesn't update d->buf in the calling function; the result of
repalloc is only assigned to repalloc_bubble's local variable buf.

regards, tom lane