Hello people,
We are implementing in-memory index. As a part of that, during
index callbacks, under CurTransactionContext, we cache all the DMLs of a
transaction in dlist(postgres's doubly linked list).
We registered transaction callback, and in transaction pre-commit
event(XACT_EVENT_PRE_COMMIT), we iterate through all cached DMLs(dlist) and
populate in my in-memory data structure.
--> For detailed explanation of our implementation, please look
into below thread.
https://www.postgresql.org/message-id/15f4ea99b34.e69a4e1b633.8937474039794097334%40zohocorp.com
--> It was working fine until I was greeted with a segmentation
fault while accessing dlist!
--> On further examining I found that dlist head is not NULL and
it is pointing to some address, but the container I extracted is pointing to
0x7f7f7f7f7f7f7f5f, and I was not able to access any members in my container.
-->
https://wiki.postgresql.org/wiki/Developer_FAQ#Why_are_my_variables_full_of_0x7f_bytes.3F
From the above wiki, we came to a conclusion that the memory
context in which that dlist was present was freed.
And yes CLOBBER_FREED_MEMORY is enabled by passing --enable-cassert
to enable asserts in my code.
--> Normally the memory context inside XACT_EVENT_PRE_COMMIT is
TopTransactionContext but in this particular case, the memory context was
'MessageContext'. Little unusual! Not sure why!
--> So basically CurTransactionContext shouldn't get freed before
transaction COMMIT.
--> So what has actually happened here??? Kindly help us with
your insights!
For your reference, a code snippet of our implementation is pasted below:
Sample code snippet:
/*** Code snippet starts ***/
dlist_head DMLInfo = {{NULL, NULL}};
Insert_callback()
{
old_context = MemoryContextSwitchTo(CurTransactionContext);
GraphIndex_InsertInfo *current;
current = (GraphIndex_InsertInfo *)palloc(sizeof(GraphIndex_InsertInfo));
current->tableOid = tableOid;
current->subTransactionID = GetCurrentSubTransactionId();
current->colValue = (long)values[0]; // Varies with column type
current->ctid = ctid;
dlist_push_head(&DMLInfo, &current->list_node);
MemoryContextSwitchTo(old_context);
return TRUE;
}
static void GraphIndex_xactCallback(XactEvent event, void *arg)
{
GraphIndex_Table *tableInfo;
GraphIndex_InsertInfo *current;
dlist_iter iter;
switch (event)
{
case XACT_EVENT_PRE_PREPARE:
case XACT_EVENT_PRE_COMMIT:
PG_TRY();
{
if(DMLInfo.head.next)
{
dlist_reverse_foreach(iter, &DMLInfo)
{
current =
dlist_container(GraphIndex_InsertInfo, list_node, iter.cur);
DMLProcessingFunction(current); // This is
giving me the ERROR (while accessing members of current)
}
DMLInfo.head.next = NULL;
}
}
PG_CATCH();
{
/* Do cleanup */
}
PG_END_TRY();
break;
case XACT_EVENT_ABORT:
case XACT_EVENT_PARALLEL_ABORT:
/* No cleanup Necessary(No structure created) */
break;
default:
return;
}
}
/*** Code snippet ends ***/
Regards
G. Sai Ram