讀windows核心編程

記錄下幾個以前不是很清楚的東西

1、那麼,系統在創建新的線程時,是如何知道要分配這個數據塊的呢?答案是它並不知道。系統
並不知道應用程序是用C/C++來寫的,不知道你調用的函數並非天生就是線程安全的。保證線
程安全是程序員的責任。創建新線程時,一定不要調用操作系統的CreateThread函數。相反,
必須調用C/C++運行庫函數_beginthreadex:

在多線程環境中會出問題的C/C++運行庫變量和函數有errno,_doserrno,strtok,_wcstok,
strerror,_strerror,tmpnam,tmpfile,asctime,_wasctime,gmtime,_ecvt和_fcvt等等。

 

2.(windows核心編程)所以,當你的應用程序運行時,它可能會泄漏內核對象;但當進程終止運行,系統能保證一切都被正確清除。順便說一下,這適用於所有內核對象、資源(包括GDI對象在內)以及內存塊

對於semaphore,他作爲一個內核對象,應該在程序關閉的時候關掉,但是信號並未釋放?和解?那麼如果多進程中某個進程崩潰了,那這個信號永遠不會釋放?

 

3.interlock系列函數不需要搭配volatile,這是因爲傳給interlock的是變量的地址,函數要取得值,必須從內存中獲得

 

4. 內存,virualfree只需要第一個參數就可以了,因爲系統會自己記錄,所以free不需要帶參數就行,但是delete爲啥要帶[]

虛擬內存前2g爲用戶空間,後兩層爲內核空間

進程必須有默認堆,操作系統api會調用他來分配內存,需要關注下google的tcmalloc實現方式,因爲他的malloc free等是跟線程相關的,高速

多線程創建堆時,一定不要設置heap_no_serialize,避免多線程同步

小容量可用heapalloc,>1m要用virtualalloc ,heapsize可以獲得這塊內存的實際大小

virtualalloc預訂4g空間中的地址段或者實際分配內存,根據第三個參數

heapalloc直接分配內存

(還需找本操作系統的書細讀,太久沒看了,都忘光了)

基地址重映射工具rebase


5.dll,如果dll malloc,主進程free,在某一個採用靜態鏈接的情況下free會失敗,不解,雖然靜態編譯下,每個文件都有malloc的實現代碼,但是應該是同一個版本的吧?ida後找到答案 動態鏈接的malloc是在私有堆上開闢的內存,靜態的是默認堆,所以。。。

搜索dll的目錄順序:包含可執行文件的目錄,system32,system,windows,進程當前目錄,path環境目錄,可在註冊表session manager中修改順序

延遲載入特性,前段時間寫了個雙核瀏覽器,想讓exe在缺少chrome.dll的情況下只使用ie內核,但是沒找到辦法,或許可以用這個方式實現。 delayloadapp以後看看這個代碼

 

6.seh

__try __finally除非exitthread,process,terminatethread,process 來終止,其他都會執行到finally

並不是所有的finally都可以被執行,比如棧耗盡,程序會直接dump

vista後,錯誤報告進程在另一個獨立的進程裏,是否類似breakpad?都是採用發送消息給錯誤處理程序,然後阻塞線程,等待錯誤處理完成

windows還有一套叫做重啓管理的api?

 

3.絕對不要調用的C/C++運行庫函數

C/C++運行庫還包括以下兩個函數:
unsigned long _beginthread(
void (__cdecl *start_address)(void *),
unsigned stack_size,
void *arglist);
和:
void _endthread(void);
新的_beginthreadex和_endthreadex函數已經取代了這兩個傳統的函數。如你所見,_beginthread
函數的參數較少,所以和全功能的_beginthreadex函數相比,它的侷限性較大。例如,使用
_beginthread函數,你不能創建具有安全屬性的線程,不能創建可以掛起的線程,也不能獲得
線程ID值。_endthread函數的情況與此類似:它是無參數的,這意味着線程的退出代碼被硬編
碼爲0。
_endthread函數還存在另一個鮮爲人知的問題。_endthread函數在調用ExitThread前,會調用
CloseHandle,向其傳入新線程的句柄。爲了理解這爲什麼會成爲一個問題,來看看以下代碼:
DWORD dwExitCode;
HANDLE hThread = _beginthread(...);
GetExitCodeThread(hThread, &dwExitCode);
CloseHandle(hThread);
在第一個線程調用GetExitCodeThread之前,新建的線程就可能已經執行,返回,並終止運行
了。如果發生上述情況, hThread就是無效的,因爲_endthread已關閉了新線程的句柄。不用

發佈了30 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章