Django从WSGI切换到ASGI后,CircleCI测试通过却报双向链表损坏错误
Django Channels + CircleCI: 测试通过后触发"corrupted double-linked list"核心转储错误
问题背景
基于Django构建的项目,为支持WebSockets引入Django Channels并切换至ASGI服务器daphne。本地开发环境、AWS开发/预发布部署均运行正常,本地pytest测试全部通过,但在CircleCI中出现以下异常:
================== 955 passed, 2 skipped in 216.09s (0:03:36) ================== corrupted double-linked list /bin/bash: line 2: 278 Aborted (core dumped) poetry run coverage run -m pytest $TESTFILES -vv --junitxml htmlcov/junit.xml Exited with code exit status 134 CircleCI received exit code 134
所有测试实际已通过,但该错误导致任务标记失败;且该问题曾在CircleCI的migrate步骤(poetry run python manage.py migrate)中出现,说明并非仅与pytest相关。尝试为异步测试添加@pytest.mark.asyncio装饰器、移除异步测试均无效,本地无法复现该问题。
排查与解决方向
1. 对齐环境依赖与系统差异
corrupted double-linked list是C层面的内存错误,大概率和环境不一致有关:
- 检查Python版本:确保CircleCI使用的Python版本与本地完全一致(比如本地用3.10,CircleCI不要用3.11),部分C扩展在不同Python版本下可能存在内存管理兼容问题
- 锁定依赖版本:通过
poetry lock确保CircleCI安装的依赖和本地完全一致,重点排查带C扩展的依赖(如redis、uvloop、channels-redis等) - 核对系统环境:本地如果是MacOS,CircleCI默认用Ubuntu,不同系统的libc版本差异可能触发内存错误,可尝试在CircleCI中切换与本地更接近的系统镜像
2. 清理ASGI/Channels残留资源
测试结束后未正确释放ASGI相关资源可能导致内存泄漏:
- 在
conftest.py中添加测试会话结束后的资源清理逻辑,强制关闭事件循环:import asyncio def pytest_sessionfinish(session, exitstatus): loop = asyncio.get_event_loop() if not loop.is_closed(): loop.close() - 确保测试环境的Channels配置使用内存层,避免外部服务连接残留:
# settings.py (测试环境) CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer" } }
3. 调整CircleCI资源限制
CircleCI默认容器内存/CPU不足可能触发内存错误:
- 切换到
machineexecutor替代默认的dockerexecutor,获得更高的资源配额 - 在docker配置中显式增加内存限制:
# .circleci/config.yml jobs: test: docker: - image: cimg/python:3.10 environment: PYTHONUNBUFFERED: 1 resources: cpu: 2 memory: 8GB
4. 排除Coverage工具干扰
错误在coverage run命令后触发,可临时禁用Coverage验证:
- 改为直接执行
poetry run pytest $TESTFILES -vv --junitxml htmlcov/junit.xml,如果错误消失,说明Coverage与异步代码/扩展存在兼容问题:- 升级Coverage到最新版本
- 对异步相关代码添加Coverage排除规则
内容的提问来源于stack exchange,提问作者TWGerard
相关产品推荐
相关产品推荐

