0

稍後編輯:經過更多調查後,Windows更新和OpenGL DLL變爲紅鯡魚。造成這些症狀的原因是LoadLibrary()致電GetLastError() == ERROR_NOT_ENOUGH_MEMORY失敗。請參閱我的答案以瞭解如何解決此類問題。以下是有歷史意義的原始問題。 /編輯LoadLibrary()失敗,出現錯誤8(ERROR_NOT_ENOUGH_MEMORY)

地圖查看者我在Python/wxPython中寫道:適用於Windows與C++後端突然 停止工作,無需更改任何代碼或重新編譯,甚至。同樣的 可執行文件在數週前一直在工作(相同的Python,相同的DLL,...)。

現在,查詢窗口時的像素格式與OpenGL使用(與 ChoosePixelFormat()),我得到一個消息框說:執行下面的代碼片段時,顯示

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."); 
    } 
} 

它實際上是一個顯示消息框的ATI GL驅動程序DLL。調用堆棧的相關部分是這樣的:

    ... 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 MB,我沒有內存不足。
  • 大量的磁盤空間(〜50 GB)。
  • HDC m_hdc從顯示面板的HWND獲得,似乎是有效的。
  • Changing my linker commandline不起作用。

我應該更新我的圖形驅動程序還是回滾更新?任何其他想法?

系統數據轉儲:Windows 7 Ultimate SP1 x64,4GB RAM;惠普EliteBook 8470p; Python 3.3,wxPython 3.0.1.dev76673 msw(phoenix);通過SIP 4.15.4訪問C++數據結構;使用Visual Studio 2010 Express編譯C++代碼,使用/MDd編譯Debug。

回答

4

我用完了虛擬地址空間。

默認情況下,LibTIFF通過對它們進行內存映射(mmap()CreateFileMapping())來讀取TIF圖像。這對你的妻子的照片來說很好,但是對於阿爾卑斯山的地形柵格地圖來說,這是一個壞兆頭。

這很難診斷,因爲如果內存映射失敗,那麼LibTIFF默默地回退到read(),所以以前從未出現明確的錯誤。此外,映射的內存不被Windows視爲工作內存,所以任務管理器顯示67MB,實際上幾乎所有的虛擬地址空間都用完了。

因爲我最近添加了更多的TIF圖像到我的數據庫,所以現在已經爆炸了。 LoadLibrary()開始失敗,因爲它找不到任何地址空間來放置新庫。 GetLastError()返回8,即ERROR_NOT_ENOUGH_MEMORY。這發生在ATI的OpenGL庫中,恰巧是巧合。

解決方案是將"m"作爲標誌傳遞給TiffOpen()以禁用內存映射IO。

診斷這很容易與Windows Sysinternals的工具VMMapdocumentation link),這表明你有多少進程的虛擬地址空間是由代碼/堆/堆棧佔用/映射文件/共享數據的/ etc 。

如果LoadLibrary()CreateFileMapping()ERROR_NOT_ENOUGH_MEMORY而失敗,應該首先檢查這個問題。

+0

使用非常大的圖像集時,我建議使用Vips:http://www.vips.ecs.soton.ac.uk/index.php?title=VIPS – datenwolf 2014-09-26 00:12:10

相關問題