Segfault using heap_form_tuple
Greetings,
I'm having a problem using heap_form_tuple. I'm trying to form a HeapTuple to use it later with simple_heap_insert. My code looks like this:
------------------
Datum *values;
bool *nulls;
int natts;
TupleDesc tupDesc;
HeapTuple tuple;
...
tupDesc = RelationGetDescr(...my previously opened relation...);
natts = tupDesc->natts;
values = (Datum *)palloc(natts*sizeof(Datum *));
nulls = (bool *)palloc(natts*sizeof(bool *));
memset(nulls, false, natts * sizeof(nulls));
values[0] = ...GetDatum(...my datum...);
...
values[natts-1] = ...GetDatum(...my datum...);
...
tuple = heap_form_tuple(tupDesc, values, nulls);
------------------
When I come to last line, I get these errors (I'm using valgrind):
==25850== Source and destination overlap in memcpy(0x8BCB070, 0x4CF2480, 496753820)
==25850== at 0x4024586: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==25850== by 0x808C811: heap_fill_tuple (in /usr/local/pgsql/bin/postgres)
==25850== by 0x808D72F: heap_form_tuple (in /usr/local/pgsql/bin/postgres)
...
==25850== Invalid read of size 1
==25850== at 0x40245A1: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==25850== by 0x808C811: heap_fill_tuple (in /usr/local/pgsql/bin/postgres)
==25850== by 0x808D72F: heap_form_tuple (in /usr/local/pgsql/bin/postgres)
...
==25850== Address 0x8BCB027 is 1 bytes before a block of size 496,753,892 alloc'd
==25850== at 0x4022825: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==25850== by 0x82BE278: AllocSetAlloc (in /usr/local/pgsql/bin/postgres)
==25850== by 0x82BEE91: MemoryContextAllocZero (in /usr/local/pgsql/bin/postgres)
==25850== by 0x808D694: heap_form_tuple (in /usr/local/pgsql/bin/postgres)
...
==25850== Address 0x8BCB027 is 2 bytes before a block of size 496,753,892 alloc'd
...
==25850== Address 0x8BCB027 is 3 bytes before a block of size 496,753,892 alloc'd
...
==25850== Address 0x8BCB027 is 4 bytes before a block of size 496,753,892 alloc'd
...
==25850== Process terminating with default action of signal 11 (SIGSEGV)
==25850== Access not within mapped region at address 0x8BCAFFF
==25850== at 0x40245A1: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==25850== by 0x808C811: heap_fill_tuple (in /usr/local/pgsql/bin/postgres)
==25850== by 0x808D72F: heap_form_tuple (in /usr/local/pgsql/bin/postgres)
If I work on tables with only 1 attribute, I use normal variables (Datum values, bool nulls) instead of arrays, and using heap_form_tuple(TupleDesc td, &values, &nulls) works flawlessly. What am i missing?
Thanks in advance for help,
Claudio Rossi
On Wed, Apr 9, 2008 at 10:48 PM, Claudio Rossi <wind.claudio@inwind.it> wrote:
nulls = (bool *)palloc(natts*sizeof(bool *));
May not be related to segfault you are seeing, but this looks completely wrong.
You want array of bool and not (bool *).
Thanks,
Pavan
--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com
"Claudio Rossi" <wind.claudio@inwind.it> writes:
values[0] = ...GetDatum(...my datum...);
...
values[natts-1] = ...GetDatum(...my datum...);
You've omitted the details that probably matter. My guess is that
you're inappropriately converting one of these values to a Datum,
or converting it to a Datum that's not really of the type the
tuple descriptor specifies.
regards, tom lane
nulls = (bool *)palloc(natts*sizeof(bool *));
May not be related to segfault you are seeing, but this looks completely wrong.
You want array of bool and not (bool *).
Yeah, you are right but in the original code it's:
values = (Datum *) palloc(natts * sizeof(Datum));
nulls = (bool *) palloc(natts * sizeof(bool));
I just typed it wrong, I didn't copy and paste. I also forgot to add this line (from valgrind log) at the beginning of error sequence:
==30549== Warning: set address range perms: large range 496753892 (undefined)
I'm clueless, any hints?
Import Notes
Resolved by subject fallback
You've omitted the details that probably matter. My guess is that
you're inappropriately converting one of these values to a Datum,
or converting it to a Datum that's not really of the type the
tuple descriptor specifies.regards, tom lane
Mate, you just won a beer :)
You guessed it right, I was trying to "CStringGetDatum" into a text field, now i solved it with
values[n] = DirectFunctionCall1(textin, CStringGetDatum(...string...));
Thank you very much!
Claudio Rossi
Import Notes
Resolved by subject fallback
"Claudio Rossi" <wind.claudio@inwind.it> writes:
You guessed it right, I was trying to "CStringGetDatum" into a text field, now i solved it with
values[n] = DirectFunctionCall1(textin, CStringGetDatum(...string...));
If you're working in CVS HEAD there's an easier way --- see
CStringGetTextDatum.
regards, tom lane