PG-613: Postgresql crashes with Segmentation fault when query plan is enabled on large queries
The return value for snprintf was incorrectly being recorded as plan length. That's been resolved. As part of this fix, we've also elminated the possibility of a potential memory leak when plan text was being saved. Co-authored-by: Hamid Akhtar <hamid.akhtar@percona.com> Co-authored-by: Muhammad Usama <muhammad.usama@percona.com>pull/399/head
parent
7623f15e68
commit
2ceb47e3cd
|
@ -692,11 +692,32 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
|
||||||
/* Extract the plan information in case of SELECT statement */
|
/* Extract the plan information in case of SELECT statement */
|
||||||
if (queryDesc->operation == CMD_SELECT && pgsm_enable_query_plan)
|
if (queryDesc->operation == CMD_SELECT && pgsm_enable_query_plan)
|
||||||
{
|
{
|
||||||
plan_info.plan_len = snprintf(plan_info.plan_text, PLAN_TEXT_LEN, "%s", pgsm_explain(queryDesc));
|
int rv;
|
||||||
|
MemoryContext oldctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Making sure it is a per query context so that there's no memory
|
||||||
|
* leak when executor ends.
|
||||||
|
*/
|
||||||
|
oldctx = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
|
||||||
|
|
||||||
|
rv = snprintf(plan_info.plan_text, PLAN_TEXT_LEN, "%s", pgsm_explain(queryDesc));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If snprint didn't write anything or there was an error, let's keep
|
||||||
|
* planinfo as NULL.
|
||||||
|
*/
|
||||||
|
if (rv > 0)
|
||||||
|
{
|
||||||
|
plan_info.plan_len = (rv < PLAN_TEXT_LEN) ? rv : PLAN_TEXT_LEN - 1;
|
||||||
plan_info.planid = pgsm_hash_string(plan_info.plan_text, plan_info.plan_len);
|
plan_info.planid = pgsm_hash_string(plan_info.plan_text, plan_info.plan_len);
|
||||||
plan_ptr = &plan_info;
|
plan_ptr = &plan_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Switch back to old context */
|
||||||
|
MemoryContextSwitchTo(oldctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(exec_nested_level))
|
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(exec_nested_level))
|
||||||
{
|
{
|
||||||
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *) queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *) queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
||||||
|
|
Loading…
Reference in New Issue