pretty code

顯示具有 Windows 標籤的文章。 顯示所有文章
顯示具有 Windows 標籤的文章。 顯示所有文章

2023年9月22日 星期五

KMODE_EXCEPTION_NOT_HANDLED

公司電腦從上星期安裝某個更新後,在自動時間內重開機安裝更新時就發生不明錯誤,接著便會一直在打完密碼進入桌面後發生 blue screen,因為沒有管理者權限,沒辦法做些修復的動作,只能選擇移除先前的更新,但還是會一直重開機,故最後選擇關機先去吃飯,過了一個多小時回來後開機便正常,接著將剛移除的兩個更新安裝回來,這次便不需重開機便可以安裝完畢。


昨天在 Youtube 看 RISC-V 訪談影片時電腦又無預警當機,一樣在重開機無數次後,選擇關機等待幾分鐘的方式來解決此問題。


從上面可以看到,dump file 位在 C:\Windows,我們需要 WinDbg 工具才可以看些東西,可以選擇在 Windows SDK 中只安裝 debug tool 的方式來取得工具。

開啟 WinDbg -> File -> Open Crash Dump,選擇檔案位置,然後在下面指令列中下!analyze -v 便可以做初步分析。


我這個錯誤的參數 1 如下所述,但我不是做底層的,即使 trace stack 對我來說也看不出什麼東東?目前先這樣吧,反正我會覺得比較像記憶體的問題,故使用冷開機的方式便可以恢復正常。


0x80000003:STATUS_BREAKPOINT
未將核心偵錯工具附加至系統時,遇到中斷點或 ASSERT。

剛試著在重開機時執行記憶體診斷工具,目前確實是有問題,等有空再來跑 MemTest86。


2023/09/22 下午更新

早上想想還是跑 MT86 確認好了,果不期然發生很多錯誤,錯誤都集中在 bit1, bit31。總共跑了快 4 個小時。


由於不是主機板廠商,也不確定 UEFI 的 memory mapping 是否可以看出錯誤位址屬於哪一根 DIMM,只好使用老辦法一根一根做測試,還好透過先前的 MT86,我們可以得知問題多半來自 Test 7, Test 8,這次就只針對這兩個選項跑即可。

原本認為是 9 年多前公司採購電腦那根 DIMM 有問題,但直到跑完一個錯誤都沒看到,幸好在跑我幾年前自己買的那根 DIMM 時真的會看到錯誤(2019/09/24 購買)。


解決方式也很簡單,先把有問題的 DIMM 移除即可。

2023/09/25 更新

MemTest86 v10 以上,配合支援的 chipset,可以 decode error DIMM(>= DDR4),簡言之,會告訴你是哪一個插槽的哪一個 rank 有問題,詳此處

2023年7月20日 星期四

vcpkg + cmake + x64-windows-static

vcpkg + cmake 的方式在 build VC 專案時,預設是動態連結,而 vcpkg 的機制也很貼心的會將相關 DLL 複製一份到你的輸出資料夾中。

但如果我們想要靜態編譯又該如何做呢?

以下是使用 PCL example 裡面的 qt_visualizer 為例說明:

注意:不是每個函式庫都能靜態編譯,像 qt5-webengine 就不支援

01. 先安裝 x64-windows-static 相關函式庫,C 槽至少要有 300 GB 空間比較保險。

vcpkg install pcl[core, qt, vtk]:x64-windows-static

中間有遇到某些函式庫會安裝失敗,但去 buildtrees 下的 log 又看不出所以然,我的解決方式是單獨編譯就會成功,但如果是有相關性的不能這樣單獨編譯,否則可能會失敗,但這可能又跟電腦環境有關,故只能 by case 解決。

02. 在 CMakeLists.txt 加上相關指令。

project(pcl_visualizer)
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) 

上面這個是讓 VS 專案使用靜態編譯,雖然 CMake 有另一個 MSVC_RUNTIME_LIBRARY 可以設定 property,但據我測試的結果無法成功。

add_executable(${PROJECT_NAME} ${project_SOURCES})
target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES} ${QTX}::Widgets)
target_link_libraries(XYZ C:/src/vcpkg/installed/x64-windows-static/lib/pcl_io_ply.lib) 

如果有遇到 pcl visualizer parse 相關的 link 錯誤,可以加上上面指令,根據這篇文章說法,可能跟編譯 pcl 順序有關?

03. 產生 VS 專案檔。

cmake . -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static

04. 編譯程式

msbuild pcl_visualizer.sln /p:Configuration=Release

我有試過將 A 台電腦(Windows 10 Pro)編譯出來的執行檔 pcl_visualizer.exe 拿到另一台電腦執行(Windows 10 Pro),確實是靜態編譯無誤。

但如果是用 GCP 新開一台 VM(Windows Server 2022 + Desktop Experiences),則會有找不到 opengl32sw.dll 的問題,但程式是可以執行起來無誤,只是相關 UI 元件無法渲染,故只有一個灰底的執行畫面以及 CMD 畫面。

QWindowsEGLStaticContext::create: Failed to load and resolve libEGL functions
Failed to load opengl32sw.dll (The specified module could not be found.)
Failed to load and resolve WGL/OpenGL functions 

如果我將 Windows 10 的 opengl32sw.dll 複製到 VM 中,則是會產生 init GLEW 失敗的相關訊息(GLEW could not be initialized: Missing GL version),我個人猜測跟顯卡驅動程式有關?又或許是 Windows Server 無法使用之類的?

另外拿一台新電腦重灌 Windows 10 並更新顯卡驅動程式後,這次就可以順利執行成功。

以上就是相關的注意事項,如果本身就是使用 C/C++ 的開發者,我想有關編譯的問題應該也難不倒這些高手XD 

2020年5月27日 星期三

Windows DLL 相關名詞備忘

很久沒有寫 DLL 了,剛吃飯時跟同事聊到 Windows DLL,有些討論雖然意思對,但名詞錯,顯得有些不專業,趕快 Google 惡補一下。


2020/05/28 更新

早上趁著拍片時翻了一下《程式設計師的自我修養:連結、載入、程式庫》,因為太趕,沒有看到作者有特別著墨這些名詞。

圖片的中文翻譯有點差,還是來看看英文版好了。


2020/06/04 更新

A dynamic-link library (DLL) is a module that contains functions and data that can be used by another module (application or DLL).

DLL 的函數有分內部及外部 (定義給其他 module) 用。
因為 DLL 內容會被載入到呼叫者的記憶體空間,故那些內部使用的函數是無法保護的。
所有的呼叫者會共享 DLL Code,故可以減少系統記憶體使用。

Types of Dynamic Linking

1. In load-time dynamic linking
    呼叫者用起來就像自己的 local functions,故呼叫者在編譯程式時,要拿到 .h 和 .lib 兩個檔案。

2. In run-time dynamic linking 
    呼叫者使用 LoadLibrary 和 GetProcAddress 來載入 DLL 以及使用函數 (function pointers),故只需要 DLL 檔。

DLL 比 static linking 優秀的地方

只要 DLL 的 function arguments, calling conventions, return values 沒有改變,呼叫者不需要重新編譯 (In load-time dynamic linking 也是嗎?)