在 Windows 上进行 OpenGL 缓冲区清除时,GPU SIFT 特征提取发生崩溃(堆内存损坏)
作者: jeffdaily创建于 2026年8月11日更新于 2026年8月11日
在 Windows 上,运行 GPU SIFT 特征提取器在 OpenGL 缓冲区清理期间会发生堆损坏错误 (STATUS_HEAP_CORRUPTION, 0xc0000374),在 GPU 计算完成后,GPU 计算本身已经成功完成。失败的单元测试是 `ExtractSiftFeaturesGPU.Nominal` 在 `src/colmap/feature/sift_test.cc` 中;在启用 GPU SIFT 的情况下通过正常管线提取特征时也会发生同样的崩溃。崩溃发生在 SiftGPU 的金字塔销毁器中,在调用 `glDeleteBuffers` 释放其像素缓冲对象 (`PyramidCU` 在 `src/thirdparty/SiftGPU`) 时发生。此时 GPU 描述符计算已经完成并将其结果复制回主机;仅剩下 OpenGL 清理。这看起来像是一个 OpenGL 上下文生命周期问题,而不是一个计算错误。`OpenGLContextManager` 在 `src/colmap/util/opengl_utils.cc` 中通过 `context_.moveToThread(...)` 使用 `Qt::BlockingQueuedConnection` 将共享 GL 上下文移动到多个线程之间,而 `RunThreadWithOpenGLContext` 在单独的 `std::thread` 上运行工作线程,而调用线程则驱动 Qt 事件循环。SiftGPU 缓冲区似乎在清理期间被删除,而没有在运行销毁器的线程上具有当前的上下文,调用 `glDeleteBuffers` 而没有当前上下文则是不定行为。
内容来源: colmap/colmap