Thread: Foreign memory context read
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
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
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.linnakangas@enterprisedb.com> wrote:
On 23.05.2011 13:44, Vaibhav Kaushal wrote:There's always a memory context active, it just might not be the correct one.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.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.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?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.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).
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
Vaibhav Kaushal wrote: > Do you think its the 'slot_getattr' causing the seg-fault? On many platforms it's not hard to get a core file out of a segfault (perhaps by using ulimit), and then get a stack trace (using gdb or similar) to see exactly where it is happening. -Kevin
<p>Thanks for the suggestion. I will look into that shortly and let you know. By the way i am on fedora 13. <p>--<br /> Sentfrom my Android<div class="gmail_quote">On 23 May 2011 17:28, "Kevin Grittner" <<a href="mailto:Kevin.Grittner@wicourts.gov">Kevin.Grittner@wicourts.gov</a>>wrote:<br type="attribution" />> VaibhavKaushal wrote:<br /> > <br />>> Do you think its the 'slot_getattr' causing the seg-fault?<br />> <br/>> On many platforms it's not hard to get a core file out of a segfault<br />> (perhaps by using ulimit), and thenget a stack trace (using gdb or<br /> > similar) to see exactly where it is happening.<br />> <br />> -Kevin<br/>> <br /></div>
Vaibhav Kaushal <vaibhavkaushal123@gmail.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
<p>Oh...well... I messed it up! Thanks a lot for that. The problem I think is the bool pointer. Will check it soon.<p>--<br/> Sent from my Android<div class="gmail_quote">On 23 May 2011 19:28, "Tom Lane" <<a href="mailto:tgl@sss.pgh.pa.us">tgl@sss.pgh.pa.us</a>>wrote:<br type="attribution" />> Vaibhav Kaushal <<a href="mailto:vaibhavkaushal123@gmail.com">vaibhavkaushal123@gmail.com</a>>writes:<br /> >> My mind started wanderingafter that error. Now, actually, i was trying to<br />>> do something like this:<br />> <br />>>*last_result = palloc0(sizeof(Datum));<br />>> bool *isnnuull = true;<br />>> *last_result = slot_getattr(slot,num_atts, *isnnuull);<br /> > <br />> This seems utterly confused about data types. The first linethinks<br />> that last_result is of type Datum ** (ie, pointer to pointer to Datum),<br />> since it's storinga pointer-to-Datum through it. The third line<br /> > however is treating last_result as of type Datum *, sinceit's storing<br />> a Datum (not pointer to Datum) through it. And the second line is<br />> assigning "true"(a bool value) to a variable declared as pointer to<br /> > bool, which you then proceed to incorrectly dereferencewhile passing it<br />> as the last argument to slot_getattr. The code will certainly crash on<br />> thatderef, independently of the multiple other bugs here.<br /> > <br />> Recommendation: gcc is your friend. Pay attentionto the warnings it<br />> gives you.<br />> <br />> regards, tom lane<br /></div>
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@gmail.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