Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Possible SIGSEGV durning aset memory tracking

未关闭
#2,130 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 3 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
25/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
c, postgresql
领域
backend

调研方向

The crash path runs through src/backend/utils/mmgr/aset.c: AllocSetContextCreateInternal, AllocSetDelete and AllocSetTransferAccounting all cast the parent context to AllocSet without checking its type. Reproduce with the test extension linked in the issue, starting from the backtrace through MemoryContextSetParent in mcxt.c. Done means the reproduction no longer crashes and the parent-type checks are in place, though the issue leaves open whether to add validation or move accounting into mcxt.c, which is a design decision for maintainers.

由索引模型根据 Issue 内容生成。

描述

Memory context allocation mostly tracked at aset.c and the code relied on the assumption that context tree is an AllocSet context tree, previously that was correct, but now the next query:

-- table test contains only i int column
select * from test order by i;

may allocate a Generation context (from tuplesort_begin_batch) in the context tree and this commit adds additional context validation.
But seems it's not enough:

Suppose that at some point there would be Generation context under the AccountingRoot (aset) context and over leaf Aset context - there would be performed an invalid type cast with further invalid writes which leads to SIGSEGV. Such cases may seems insubstantial, but postgres code base may mix context in further releases.

Here is a test extension which leads to SIGSEGV:

#include "postgres.h"

#include "access/htup_details.h"
#include "commands/async.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "lib/stringinfo.h"
#include "utils/rel.h"
#include "utils/memutils.h"
#include "utils/syscache.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(test_ctx);

Datum
test_ctx(PG_FUNCTION_ARGS)
{
	MemoryContext newAset = AllocSetContextCreate(CurrentMemoryContext,
												 "test preparent aset",
												 ALLOCSET_DEFAULT_SIZES);

	// create and remove context, so further context would be created
	// from freelist
	MemoryContext deleteAse = AllocSetContextCreate(CurrentMemoryContext,
												 "to drop aset",
												 ALLOCSET_DEFAULT_SIZES);
	MemoryContextDelete(deleteAse);

	MemoryContext newGen = GenerationContextCreate(newAset, "test mid",
													SLAB_DEFAULT_BLOCK_SIZE,
													SLAB_DEFAULT_BLOCK_SIZE,
													SLAB_DEFAULT_BLOCK_SIZE
	);

	MemoryContext asetLast = AllocSetContextCreate(newGen,
												"last aset",
												 ALLOCSET_DEFAULT_SIZES);

	MemoryContextDelete(newGen);
	elog(INFO, "last ctx addr %p", (void*)asetLast);
	PG_RETURN_VOID();
}

And here is a link to full test extension

The backtrace

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=11, no_tid=0) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (threadid=<optimized out>, signo=11) at ./nptl/pthread_kill.c:89
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=11) at ./nptl/pthread_kill.c:100
#3  0x00007e41fb245b7e in __GI_raise (sig=11) at ../sysdeps/posix/raise.c:26
#4  0x00005865986bae91 in StandardHandlerForSigillSigsegvSigbus_OnMainThread (processName=0x586598e5dabb "Master process", postgres_signal_arg=11) at elog.c:5547
#5  0x0000586598487a83 in CdbProgramErrorHandler (postgres_signal_arg=11) at postgres.c:3990
#6  0x0000586598c8e953 in wrapper_handler (postgres_signal_arg=11) at pqsignal.c:90
#7  <signal handler called>
#8  AllocSetTransferAccounting (context=0x5865b8655080, new_parent=0x0) at aset.c:1874
#9  0x000058659870899e in MemoryContextSetParent (context=0x5865b8655080, new_parent=0x0) at mcxt.c:596
#10 0x00005865987086f5 in MemoryContextDeleteImpl (context=0x5865b8655080, sfile=0x586598ec3e7f "mcxt.c", func=0x0, sline=497) at mcxt.c:468
#11 0x000058659870879d in MemoryContextDeleteChildren (context=0x5865b864f040) at mcxt.c:497
#12 0x00005865987086c8 in MemoryContextDeleteImpl (context=0x5865b864f040, sfile=0x7e41fbdcf021 "ctx.c", func=0x0, sline=40) 

The problem occurs on the debug build with --enable-cassert

For now I suppose the problem should be closed by additional validation, but seems more correct way is to move the logic of memory tracking from aset to mctx and also extend Generation context methods to support tracking.

主要语言
C
星标
1.4k
派生
262
平均合并
4 天 19 小时
30 天内合并 PR
54

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

apache/cloudberry 的其他 Issue

查看 apache/cloudberry 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。