Fix possible crash due to incorrect allocation context.
authorRobert Haas <rhaas@postgresql.org>
Tue, 16 Aug 2016 17:23:32 +0000 (13:23 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 16 Aug 2016 17:23:32 +0000 (13:23 -0400)
Commit af33039317ddc4a0e38a02e2255c2bf453115fd2 aimed to reduce
leakage from tqueue.c, which is good.  Unfortunately, by changing the
memory context in which all of gather_readnext() executes, it also
changed the context in which ExecShutdownGatherWorkers executes, which
is not good, because that function eventually causes a call to
ExecParallelRetrieveInstrumentation, which proceeds to allocate
planstate->worker_instrument in a short-lived context, causing a
crash.

Rushabh Lathia, reviewed by Amit Kapila and by me.

src/backend/executor/execParallel.c

index 380d743f6cef4aaaa78600e76f938d9413aed021..5aa6f023bf7d516c3f9a4280f2c3611a0c17674c 100644 (file)
@@ -500,6 +500,7 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate,
    int         n;
    int         ibytes;
    int         plan_node_id = planstate->plan->plan_node_id;
+   MemoryContext oldcontext;
 
    /* Find the instumentation for this node. */
    for (i = 0; i < instrumentation->num_plan_nodes; ++i)
@@ -514,10 +515,19 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate,
    for (n = 0; n < instrumentation->num_workers; ++n)
        InstrAggNode(planstate->instrument, &instrument[n]);
 
-   /* Also store the per-worker detail. */
+   /*
+    * Also store the per-worker detail.
+    *
+    * Worker instrumentation should be allocated in the same context as
+    * the regular instrumentation information, which is the per-query
+    * context. Switch into per-query memory context.
+    */
+   oldcontext = MemoryContextSwitchTo(planstate->state->es_query_cxt);
    ibytes = mul_size(instrumentation->num_workers, sizeof(Instrumentation));
    planstate->worker_instrument =
        palloc(ibytes + offsetof(WorkerInstrumentation, instrument));
+   MemoryContextSwitchTo(oldcontext);
+
    planstate->worker_instrument->num_workers = instrumentation->num_workers;
    memcpy(&planstate->worker_instrument->instrument, instrument, ibytes);