0

Позже отредактируйте: После более подробного изучения Windows Updates и OpenGL DLL были красные сельди. Причиной этих симптомов был отказ LoadLibrary() с GetLastError() == ERROR_NOT_ENOUGH_MEMORY. См. Мой ответ, как решить такие проблемы. Ниже приведен оригинальный вопрос об историческом интересе. /редактироватьОшибка LoadLibrary() с ошибкой 8 (ERROR_NOT_ENOUGH_MEMORY)

карты зритель я писал в Python/WxPython для Windows, с бекендом C++ вдруг перестал работать, без каких-либо изменений коды или даже перекомпиляции. Те же самые исполняемые файлы работали несколько недель назад (такие же Python, те же DLL, ...).

Теперь при запросе Windows, для формата пикселя для использования с OpenGL (с ChoosePixelFormat()), я получаю MessageBox говоря: отображается

LoadLibrary failed with error 8: 
Not enough storage is available to process this command 

Сообщение об ошибке при выполнении следующего фрагмента кода:

void DevContext::SetPixelFormat() { 
    PIXELFORMATDESCRIPTOR pfd; 
    memset(&pfd, 0, sizeof(pfd)); 
    pfd.nSize  = sizeof(pfd); 
    pfd.nVersion  = 1; 
    pfd.dwFlags  = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 
    pfd.iPixelType = PFD_TYPE_RGBA; 
    pfd.cColorBits = 32; 

    int pf = ChoosePixelFormat(m_hdc, &pfd); // <-- ERROR OCCURS IN HERE 
    if (pf == 0) { 
     throw std::runtime_error("No suitable pixel format."); 
    } 

    if (::SetPixelFormat(m_hdc, pf, &pfd) == FALSE) { 
     throw std::runtime_error("Cannot set pixel format."); 
    } 
} 

Это фактически DLL-драйвер ATI GL, отображающий окно сообщения. Соответствующая часть стека вызовов заключается в следующем:

    ... More MessageBox stuff 
0027e860 770cfcf1 USER32!MessageBoxTimeoutA+0x76 
0027e880 770cfd36 USER32!MessageBoxExA+0x1b 
*** ERROR: Symbol file not found. Defaulted to export symbols for C:\Windows\SysWOW64\atiglpxx.dll - 
0027e89c 58471df1 USER32!MessageBoxA+0x18 
0027e9d4 58472065 atiglpxx+0x1df1 
0027e9dc 57acaf0b atiglpxx!DrvValidateVersion+0x13 
0027ea00 57acb0f3 OPENGL32!wglSwapMultipleBuffers+0xc5e 
0027edf0 57acb1a9 OPENGL32!wglSwapMultipleBuffers+0xe46 
0027edf8 57acc6a4 OPENGL32!wglSwapMultipleBuffers+0xefc 
0027ee0c 57ad5658 OPENGL32!wglGetProcAddress+0x45f 
0027ee28 57ad5dd4 OPENGL32!wglGetPixelFormat+0x70 
0027eec8 57ad6559 OPENGL32!wglDescribePixelFormat+0xa2 
0027ef48 751c5ac7 OPENGL32!wglChoosePixelFormat+0x3e 
0027ef60 57c78491 GDI32!ChoosePixelFormat+0x28 
0027f0b0 57c7867a OutdoorMapper!DevContext::SetPixelFormat+0x71 [winwrap.cpp @ 42] 
0027f1a0 57ce3120 OutdoorMapper!OGLContext::OGLContext+0x6a [winwrap.cpp @ 61] 
0027f224 1e0acdf2 maplib_sip!func_CreateOGLDisplay+0xc0 [maps.sip @ 96] 
0027f240 1e0fac79 python33!PyCFunction_Call+0x52 
        ... More Python stuff 

Я сделал обновления Windows две недели назад, и заметил, что некоторые глюки (например, при изменении размеров окна), но моя программа по-прежнему работал в основном в порядке. Только сейчас я перезагружен, Windows установила еще 1 обновление, и я больше не получаю ChoosePixelFormat(). Однако последнее установленное обновление было KB2998527, обновление часового пояса в России ?!

Вещи, которые я уже проверил:

  • Перекомпиляция не делает его работу.
  • Перезагрузка и запуск без работы других программ не работает.
  • Объем памяти моей программы составляет всего 67 МБ, я не из памяти.
  • Свободное место на диске (~ 50 ГБ).
  • HDC m_hdc получен из панели дисплея HWND и представляется действительным.
  • Changing my linker commandline не работает.

Должен ли я обновлять графические драйверы или откатывать обновления? Любые другие идеи?

Дамп системных данных: Windows 7 Ultimate SP1 x64, 4 ГБ ОЗУ; HP EliteBook 8470p; Python 3.3, wxPython 3.0.1.dev76673 msw (феникс); доступ к структурам данных C++ через SIP 4.15.4; Код C++, скомпилированный с помощью Visual Studio 2010 Express, сборка Debug с /MDd.

ответ

4

У меня заканчивалось виртуальное адресное пространство.

По умолчанию LibTIFF считывает TIF изображения, картография памяти их (mmap() или CreateFileMapping()).Это хорошо для фотографий вашей жены, но оказалось, что это плохая идея для гигабайтов, стоящих на топографических растровых картах Альп.

Это было трудно диагностировать, потому что LibTIFF молча упал до read(), если отображение памяти не удалось, поэтому прежде не было явной ошибки. Кроме того, сопоставленная память не учитывается как операционная память Windows, поэтому диспетчер задач отображает 67 МБ, когда фактически практически все виртуальное адресное пространство используется.

Это взорвалось сейчас, потому что я добавил недавно несколько изображений TIF в свою базу данных. LoadLibrary() начал сбой, потому что он не смог найти адресное пространство для размещения новой библиотеки. GetLastError() вернулся 8, что составляет ERROR_NOT_ENOUGH_MEMORY. То, что это произошло в библиотеке OpenGL ATI, было просто совпадением.

Решение должно было передать "m" как флаг в TiffOpen(), чтобы отключить отображение IO с памятью.

Диагностировать это легко с помощью инструмента Windows Sysinternals VMMap (documentation link), который показывает вам, сколько виртуального адресного пространства процесса поднято кода/кучного/стек/отображаются файлы/разделяемых данных/и т.д. ,

Это должно быть первое, что нужно проверить, если LoadLibrary() или CreateFileMapping() сбой ERROR_NOT_ENOUGH_MEMORY.

+0

При работе с очень большими наборами изображений я рекомендую использовать Vips: http://www.vips.ecs.soton.ac.uk/index.php?title=VIPS – datenwolf