Vir*_*xEC 4 c python cpython python-3.x
我有一个Windows fatal exception: code 0xc0000374- 是的,有多重处理(等待但是......)。Google 表示异常代码 0xc0000374 表示堆损坏。是的,多处理是必须具备的。它是我正在使用的框架的一部分,因为每个机器人都有可能拥有自己的核心来运行。TL;DR 我无法改变存在多处理的事实。但是,我的机器人仅在一个线程上运行,因此实际上应该不会出现问题,而且事实上,这个问题相对较新。
我想我已经找到了问题所在,但这并没有多大意义。我正在用 C 扩展 Python,以缩短运行时间,我认为这就是错误所在。我已将其范围缩小到一个名为 的函数ground_shot_is_viable,因为当我在 Python 中注释掉它时,错误永远不会发生。然而,当我尝试打印垃圾邮件时(在这种情况下,我实际上写入了一个文件,因为这更适合数百次打印),我发现该功能成功完成。我认为错误在于该函数超出了它的内存边界,这会损坏部分数据,导致崩溃回溯指向其他地方。(在这种情况下,这是我正在使用的框架中的一个无辜的行 -File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\utils\rendering\rendering_manager.py", line 104 in end_rendering它将变量设置为False)
我还对其他功能进行了测试,由于某种原因它们不会导致此问题。有一个很小很小的潜力,因为他们没有像 那样频繁地被调用ground_shot_is_viable。
该错误仅在几分钟后发生,概率总计至少几百次,也许一千次。(机器人的运行速度高达 120tps,因此该函数有可能每秒被调用 120 次。)
我只能通过将环境变量 PYTHONFAULTHANLDER 设置为 1 来获得回溯 - 当我没有这样做时,我的程序只是默默地崩溃了。
当我使用 python.exe 启动程序时,我也没有得到故障转储,但使用 pythonw.exe 确实得到了故障转储。
追溯:
Windows fatal exception: code 0xc0000374
Thread 0x00008004 (most recent call first):
File "G:\RLBotGUIX\Python37\lib\threading.py", line 296 in wait
File "G:\RLBotGUIX\Python37\lib\multiprocessing\queues.py", line 224 in _feed
File "G:\RLBotGUIX\Python37\lib\threading.py", line 870 in run
File "G:\RLBotGUIX\Python37\lib\threading.py", line 926 in _bootstrap_inner
File "G:\RLBotGUIX\Python37\lib\threading.py", line 890 in _bootstrap
Current thread 0x000031e0 (most recent call first):
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\utils\rendering\rendering_manager.py", line 104 in end_rendering
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\botmanager\bot_manager_struct.py", line 69 in call_agent
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\botmanager\bot_manager.py", line 250 in perform_tick
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\botmanager\bot_manager.py", line 206 in run
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\setup_manager.py", line 617 in run_agent
File "G:\RLBotGUIX\Python37\lib\multiprocessing\process.py", line 99 in run
File "G:\RLBotGUIX\Python37\lib\multiprocessing\process.py", line 297 in _bootstrap
File "G:\RLBotGUIX\Python37\lib\multiprocessing\spawn.py", line 118 in _main
File "G:\RLBotGUIX\Python37\lib\multiprocessing\spawn.py", line 105 in spawn_main
File "<string>", line 1 in <module>
Run Code Online (Sandbox Code Playgroud)
崩溃转储:
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ffb96b7dace (ucrtbase!abort+0x000000000000004e)
ExceptionCode: c0000409 (Security check failure or stack buffer overrun)
ExceptionFlags: 00000001
NumberParameters: 1
Parameter[0]: 0000000000000007
Subcode: 0x7 FAST_FAIL_FATAL_APP_EXIT
PROCESS_NAME: pythonw.exe
ERROR_CODE: (NTSTATUS) 0xc0000409 - The system detected an overrun of a stack-based buffer in this application. This overrun could potentially allow a malicious user to gain control of this application.
EXCEPTION_CODE_STR: c0000409
EXCEPTION_PARAMETER1: 0000000000000007
STACK_TEXT:
000000d4`287ef660 00007ffb`2baf1bb7 : 00000295`00000003 00000000`00000003 00000000`ffffffff 00007ffb`2bc0a3d8 : ucrtbase!abort+0x4e
000000d4`287ef690 00007ffb`2baf17c3 : 000000d4`287ef9a0 000000d4`287ef800 00000000`00000000 00000000`00000000 : python37!Py_RestoreSignals+0x14b
000000d4`287ef6d0 00007ffb`2b9e94a9 : 000000d4`287ef9a0 00000000`00000000 00000295`edd52050 00000000`00000000 : python37!Py_FatalInitError+0x1f
000000d4`287ef700 00007ffb`2b9a09ce : 000000d4`287ef9a0 00000295`edd52050 00000000`00000000 00000000`00000000 : python37!PyErr_NoMemory+0x2ad5d
000000d4`287ef930 00007ffb`2b9a09b6 : 0000ab32`10364489 00007ff7`28481e7e 00000000`00000000 00007ffb`96b29f66 : python37!Py_Main+0x6e
000000d4`287ef960 00007ff7`28481277 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : python37!Py_Main+0x56
000000d4`287efa10 00007ffb`97f07c24 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : pythonw+0x1277
000000d4`287efa50 00007ffb`98f8d4d1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x14
000000d4`287efa80 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
SYMBOL_NAME: ucrtbase!abort+4e
MODULE_NAME: ucrtbase
IMAGE_NAME: ucrtbase.dll
STACK_COMMAND: ~0s ; .ecxr ; kb
FAILURE_BUCKET_ID: FAIL_FAST_FATAL_APP_EXIT_c0000409_ucrtbase.dll!abort
Run Code Online (Sandbox Code Playgroud)
最小可重现示例(实际上未经测试,但我的程序的完整版本经过了 ofc 测试)
Windows fatal exception: code 0xc0000374
Thread 0x00008004 (most recent call first):
File "G:\RLBotGUIX\Python37\lib\threading.py", line 296 in wait
File "G:\RLBotGUIX\Python37\lib\multiprocessing\queues.py", line 224 in _feed
File "G:\RLBotGUIX\Python37\lib\threading.py", line 870 in run
File "G:\RLBotGUIX\Python37\lib\threading.py", line 926 in _bootstrap_inner
File "G:\RLBotGUIX\Python37\lib\threading.py", line 890 in _bootstrap
Current thread 0x000031e0 (most recent call first):
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\utils\rendering\rendering_manager.py", line 104 in end_rendering
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\botmanager\bot_manager_struct.py", line 69 in call_agent
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\botmanager\bot_manager.py", line 250 in perform_tick
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\botmanager\bot_manager.py", line 206 in run
File "G:\RLBotGUIX\venv\lib\site-packages\rlbot\setup_manager.py", line 617 in run_agent
File "G:\RLBotGUIX\Python37\lib\multiprocessing\process.py", line 99 in run
File "G:\RLBotGUIX\Python37\lib\multiprocessing\process.py", line 297 in _bootstrap
File "G:\RLBotGUIX\Python37\lib\multiprocessing\spawn.py", line 118 in _main
File "G:\RLBotGUIX\Python37\lib\multiprocessing\spawn.py", line 105 in spawn_main
File "<string>", line 1 in <module>
Run Code Online (Sandbox Code Playgroud)
此代码与 Python (ofc...) 和 RLBot python 包结合使用。该机器人在《火箭联盟》中运行并玩游戏。RLBot 框架本身不会崩溃,只是机器人崩溃。我通过同时运行 2 个机器人对此进行了测试,只有我的机器人崩溃了。其他机器人(实际上是机器人)不受影响。
我的系统有 20GB 的 RAM,问题发生在我的容量为 50%-75% 时,所以我的系统的 RAM 量不是问题。我不是最擅长测试内存泄漏,但它似乎每 30 秒到一分钟就会增加约 0.1MB。这并不算多,因为机器人一开始会占用大约 30MB 的内存。
这个问题已经困扰我近一个月了,我试图将其带到行刑队面前,但这该死的事情很烦人。
我非常犹豫是否要在 SO 上发布这个问题,因为我不太确定要放什么。我希望我已经提供了所需的一切!如果你想要完整的 C 程序,或者如果你想要 setup.py 文件和其他东西,只需询问,我会提供一个 hastebin 或其他东西。或者,如果您想要完整的机器人,我可以将 zip 文件上传到保管箱,因为该机器人相当大,有数千行代码和多个文件。
该错误最有可能出现在以下行中method_ground_shot_is_viable:
return (shot_viable) ? Py_True : Py_False;
Run Code Online (Sandbox Code Playgroud)
使用 注册的函数PyMethodDef必须返回一个新的引用Py_True,这意味着它们在返回像或 这样的全局对象时必须显式增加引用计数Py_False。如果不这样做,调用者会减少返回对象的引用计数,而之前不会增加该引用计数。在method_ground_shot_is_viable被调用足够多次后,True或 的引用计数False下降到零并且被释放,导致释放后使用。
可以通过在返回它们之前根据需要应用宏来增加引用Py_INCREF计数。您还可以使用返回布尔值的便利宏来处理引用计数:Py_TruePy_False
if (shot_viable)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2408 次 |
| 最近记录: |