Обсуждение: repalloc bug

Поиск
Список
Период
Сортировка

repalloc bug

От
Giacomo Cariello
Дата:
Your name: Giacomo Cariello
Your email address: jwk@bug.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@bug.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

Re: repalloc bug

От
Tom Lane
Дата:
Giacomo Cariello <jwk@bug.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

Re: repalloc bug

От
Tom Lane
Дата:
Giacomo Cariello <jwk@bug.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

Re: repalloc bug

От
Giacomo Cariello
Дата:
>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@bug.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