aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-08-16 13:23:32 -0400
committerRobert Haas <rhaas@postgresql.org>2016-08-16 13:28:10 -0400
commit0aa1e9a44db0b8f8b08acadf2833c724489bd279 (patch)
treebeff9e11056a9e4cf4dc41145f585c84934ead7c /src
parentd95a7c3fbcfd5e65802f7fb0bee31a914160d9ed (diff)
downloadpostgresql-0aa1e9a44db0b8f8b08acadf2833c724489bd279.tar.gz
postgresql-0aa1e9a44db0b8f8b08acadf2833c724489bd279.zip
Fix possible crash due to incorrect allocation context.
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execParallel.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index 380d743f6ce..5aa6f023bf7 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -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);