Re: Foreign memory context read

Lists: pgsql-hackers
From: Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Foreign memory context read
Date: 2011-05-23 10:44:27
Message-ID: BANLkTi=VN93FCH1rp_jyqFL1AfZZFtiFAQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Hello,

I made some code changes, compilation went fine but the database could not
start with the message:

LOG: server process (PID 17684) was terminated by signal 11: Segmentation
fault

I think this is because of memory allocation outside of any memory context.

Is it possible to create some variable in a memory context (say
"cut_context") and then access the variable in that context from a piece of
code which is working with variables in a different context (say the
"per_query" context)?

If yes, then how?

My first guess is a Memory Context switch. But then, I need to bring in the
value of the variable from the cut_context (which was formed earlier) to the
per_query context which was created later on.

Precisely I am trying to create a small array of Datums (before the ExecQual
is called inside ExecScan) and then use the array inside the ExecEvalVar
(which obviously is inside the executer).

Any help pointers towards the solution of this problem?

Regards,
Vaibhav


From: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
To: Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Foreign memory context read
Date: 2011-05-23 11:23:33
Message-ID: 4DDA43B5.9000403@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 23.05.2011 13:44, Vaibhav Kaushal wrote:
> Hello,
>
> I made some code changes, compilation went fine but the database could not
> start with the message:
>
> LOG: server process (PID 17684) was terminated by signal 11: Segmentation
> fault
>
> I think this is because of memory allocation outside of any memory context.

There's always a memory context active, it just might not be the correct
one.

> Is it possible to create some variable in a memory context (say
> "cut_context") and then access the variable in that context from a piece of
> code which is working with variables in a different context (say the
> "per_query" context)?
>
> If yes, then how?

Sure, for accessing a variable, it doesn't matter which memory context
it was allocated in. As long as you make sure you allocate things in
sufficiently long-lived memory contexts, so that your allocations are
not free'd too early, while they're still needed by some code.

> My first guess is a Memory Context switch. But then, I need to bring in the
> value of the variable from the cut_context (which was formed earlier) to the
> per_query context which was created later on.
>
> Precisely I am trying to create a small array of Datums (before the ExecQual
> is called inside ExecScan) and then use the array inside the ExecEvalVar
> (which obviously is inside the executer).

Switching to the right memory context before the palloc() call is the
key. Sounds like you want to allocate your array in the per-query memory
context. If you need to move a value from one memory context to another,
like if you need to take a Datum that's already been allocated in some
other memory context, and store it in that array, you need to copy the
Datum to the right memory context.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com


From: Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com>
To: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Foreign memory context read
Date: 2011-05-23 11:33:52
Message-ID: BANLkTinnZL9gS31vhGTfBnQ6Gi288jRp-A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Well, I had thought of the same what you said.

My mind started wandering after that error. Now, actually, i was trying to
do something like this:

*last_result = palloc0(sizeof(Datum));
bool *isnnuull = true;
*last_result = slot_getattr(slot, num_atts, *isnnuull);
elog(INFO, "Last result for slot_getattr = %d", (int)last_result);

Just before:

if (!qual || ExecQual(qual, econtext, false))
{
/*
* Found a satisfactory scan tuple.
*/
in ExecScan.

Do you think its the 'slot_getattr' causing the seg-fault?

Regards,
Vaibhav

On Mon, May 23, 2011 at 4:53 PM, Heikki Linnakangas <
heikki(dot)linnakangas(at)enterprisedb(dot)com> wrote:

> On 23.05.2011 13:44, Vaibhav Kaushal wrote:
>
>> Hello,
>>
>> I made some code changes, compilation went fine but the database could not
>> start with the message:
>>
>> LOG: server process (PID 17684) was terminated by signal 11: Segmentation
>> fault
>>
>> I think this is because of memory allocation outside of any memory
>> context.
>>
>
> There's always a memory context active, it just might not be the correct
> one.
>
>
> Is it possible to create some variable in a memory context (say
>> "cut_context") and then access the variable in that context from a piece
>> of
>> code which is working with variables in a different context (say the
>> "per_query" context)?
>>
>> If yes, then how?
>>
>
> Sure, for accessing a variable, it doesn't matter which memory context it
> was allocated in. As long as you make sure you allocate things in
> sufficiently long-lived memory contexts, so that your allocations are not
> free'd too early, while they're still needed by some code.
>
>
> My first guess is a Memory Context switch. But then, I need to bring in
>> the
>> value of the variable from the cut_context (which was formed earlier) to
>> the
>> per_query context which was created later on.
>>
>> Precisely I am trying to create a small array of Datums (before the
>> ExecQual
>> is called inside ExecScan) and then use the array inside the ExecEvalVar
>> (which obviously is inside the executer).
>>
>
> Switching to the right memory context before the palloc() call is the key.
> Sounds like you want to allocate your array in the per-query memory context.
> If you need to move a value from one memory context to another, like if you
> need to take a Datum that's already been allocated in some other memory
> context, and store it in that array, you need to copy the Datum to the right
> memory context.
>
> --
> Heikki Linnakangas
> EnterpriseDB http://www.enterprisedb.com
>


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Foreign memory context read
Date: 2011-05-23 13:58:24
Message-ID: 12184.1306159104@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com> writes:
> My mind started wandering after that error. Now, actually, i was trying to
> do something like this:

> *last_result = palloc0(sizeof(Datum));
> bool *isnnuull = true;
> *last_result = slot_getattr(slot, num_atts, *isnnuull);

This seems utterly confused about data types. The first line thinks
that last_result is of type Datum ** (ie, pointer to pointer to Datum),
since it's storing a pointer-to-Datum through it. The third line
however is treating last_result as of type Datum *, since it's storing
a Datum (not pointer to Datum) through it. And the second line is
assigning "true" (a bool value) to a variable declared as pointer to
bool, which you then proceed to incorrectly dereference while passing it
as the last argument to slot_getattr. The code will certainly crash on
that deref, independently of the multiple other bugs here.

Recommendation: gcc is your friend. Pay attention to the warnings it
gives you.

regards, tom lane


From: Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Foreign memory context read
Date: 2011-05-23 14:51:38
Message-ID: BANLkTina2ZXKh1EDHSTGQFJbqw8a-Cqbng@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Oh...well... I messed it up! Thanks a lot for that. The problem I think is
the bool pointer. Will check it soon.

--
Sent from my Android
On 23 May 2011 19:28, "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com> writes:
>> My mind started wandering after that error. Now, actually, i was trying
to
>> do something like this:
>
>> *last_result = palloc0(sizeof(Datum));
>> bool *isnnuull = true;
>> *last_result = slot_getattr(slot, num_atts, *isnnuull);
>
> This seems utterly confused about data types. The first line thinks
> that last_result is of type Datum ** (ie, pointer to pointer to Datum),
> since it's storing a pointer-to-Datum through it. The third line
> however is treating last_result as of type Datum *, since it's storing
> a Datum (not pointer to Datum) through it. And the second line is
> assigning "true" (a bool value) to a variable declared as pointer to
> bool, which you then proceed to incorrectly dereference while passing it
> as the last argument to slot_getattr. The code will certainly crash on
> that deref, independently of the multiple other bugs here.
>
> Recommendation: gcc is your friend. Pay attention to the warnings it
> gives you.
>
> regards, tom lane


From: Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Foreign memory context read
Date: 2011-05-24 06:19:27
Message-ID: 1306217967.2434.1.camel@localhost
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Indeed I was acting weird there. I had completely forgotten about the
bool pointer. Moreover, I actually got confused about the palloc0's
return type...whether it was a datum or a pointer to datum. Looked back
at the expansion and got it clear.

Thanks a lot Mr. Tom.

Regards,
Vaibhav

On Mon, 2011-05-23 at 09:58 -0400, Tom Lane wrote:
> Vaibhav Kaushal <vaibhavkaushal123(at)gmail(dot)com> writes:
> > My mind started wandering after that error. Now, actually, i was trying to
> > do something like this:
>
> > *last_result = palloc0(sizeof(Datum));
> > bool *isnnuull = true;
> > *last_result = slot_getattr(slot, num_atts, *isnnuull);
>
> This seems utterly confused about data types. The first line thinks
> that last_result is of type Datum ** (ie, pointer to pointer to Datum),
> since it's storing a pointer-to-Datum through it. The third line
> however is treating last_result as of type Datum *, since it's storing
> a Datum (not pointer to Datum) through it. And the second line is
> assigning "true" (a bool value) to a variable declared as pointer to
> bool, which you then proceed to incorrectly dereference while passing it
> as the last argument to slot_getattr. The code will certainly crash on
> that deref, independently of the multiple other bugs here.
>
> Recommendation: gcc is your friend. Pay attention to the warnings it
> gives you.
>
> regards, tom lane