virtual memory中文翻譯,virtual memory是什么意思,virtual memory發(fā)音、用法及例句
- 內容導航:
- 1、virtual memory
- 2、Windows內核調試器的WinDBG
1、virtual memory
virtual memory發(fā)音
英: 美:
virtual memory中文意思翻譯
常見(jiàn)釋義:
虛擬內存
virtual memory雙語(yǔ)使用場(chǎng)景
1、Let's look at virtual memory.───我們來(lái)看看虛擬內存。
2、The actual schema of the table (Listing 1) used in the Informix port of this agent includes how much virtual memory is allocated and used.───該代理的Informix端口中使用的表的實(shí)際模式(清單1)包括分配和使用多少虛擬內存。
3、It is how much page file space would be used if all the private committed virtual memory in the system had to be paged out all at once.───換言之,如果系統中所有的私有提交虛擬內存不得不一次性全部被換出去的話(huà),將用到多少頁(yè)面文件空間。
4、Before executing, the test adjusts its total memory usage according to how much real and virtual memory exist on the system.───在執行之前,測試會(huì )根據系統中存在多少物理和虛擬內存來(lái)調整其總的內存使用情況。
5、Reserved memory is the virtual memory space reserved for the application but no disk or main memory pages have been used.───保留內存是為應用程序保留(但尚未使用任何磁盤(pán)或主內存頁(yè))的虛擬內存空間。
6、Virtual Memory management.───虛擬內存管理。
7、Virtual memory interaction.───虛擬內存交互。
8、AIX newbies are sometimes surprised to hear that the VMM services all memory requests from the system, not just virtual memory.───有時(shí)候,令AIX新手感到困惑的是,VMM服務(wù)如何處理系統中所有的內存請求,而不僅僅是虛擬內存本身。
9、If the disk is the same as the one used for virtual memory, then it might be a problem with lack of memory and too much swapping.───如果該磁盤(pán)同時(shí)用作虛擬內存,那么可能是因為缺少內存和過(guò)多的交換的問(wèn)題。
virtual memory相似詞語(yǔ)短語(yǔ)
1、virtual currency───虛擬貨幣
2、virtual tourism───虛擬旅游
3、virtual images───[光][天]虛像;[醫]虛象
4、bazar virtual───虛擬基地
5、virtual environment───[計]虛擬環(huán)境
6、virtual piano───虛擬鋼琴
7、virtual───adj.[計]虛擬的;實(shí)質(zhì)上的,事實(shí)上的(但未在名義上或正式獲承認)
8、virtual slime───虛擬黏液
9、virtual machine───[計]虛擬機,[計]虛擬計算機;虛擬計算機; 虛擬機
2、Windows內核調試器的WinDBG
WinDBG和用戶(hù)調試器一點(diǎn)很大不同是內核調試器在一臺機器上啟動(dòng),通過(guò)串口調試另一個(gè)相聯(lián)系的以Debug方式啟動(dòng)的系統,這個(gè)系統可以是虛擬機上的系統,也可以是另一臺機器上的系統(這只是微軟推薦和實(shí)現的方法,其實(shí)象SoftICE這類(lèi)內核調試器可以實(shí)現單機調試)。很多人認為主要功能都是在WinDBG里實(shí)現,事實(shí)上并不是那么一回事,windows已經(jīng)把內核調試的機制集成進(jìn)了內核,WinDBG、kd之類(lèi)的內核調試器要做的僅僅是通過(guò)串行發(fā)送特定格式數據包來(lái)進(jìn)行聯(lián)系,比如中斷系統、中斷點(diǎn)、顯示內存數據等等。然后把收到的數據包經(jīng)過(guò)WinDBG處理顯示出來(lái)。
在進(jìn)一步介紹WinDBG之前,先介紹兩個(gè)函數:KdpTrace、KdpStub,我在《windows異常處理流程》一文里簡(jiǎn)單提過(guò)這兩個(gè)函數?,F在再提一下,當異常發(fā)生于內核態(tài)下,會(huì )調用KiDebugRoutine兩次,異常發(fā)生于用戶(hù)態(tài)下,會(huì )調用KiDebugRoutine一次,而且第一次調用都是剛開(kāi)始處理異常的時(shí)候。
當WinDBG未被加載時(shí)KiDebugRoutine為KdpStub,處理也很簡(jiǎn)單,主要是對由int 0x2d引起的異常如DbgPrint、DbgPrompt、加載卸載SYMBOLS(關(guān)于int 0x2d引起的異常將在后面詳細介紹)等,把Context.Eip加1,跳過(guò)int 0x2d后面跟著(zhù)的int 0x3指令。
真正實(shí)現了WinDBG功能的函數是KdpTrap,它負責處理所有STATUS_BREAKPOINT和STATUS_SINGLE_STEP(單步)異常。STATUS_BREAKPOINT的異常包括int 0x3、DbgPrint、DbgPrompt、加載卸載SYMBOLS。DbgPrint的處理最簡(jiǎn)單,KdpTrap直接向調試器發(fā)含有字符串的包。DbgPrompt因為是要輸出并接收字符串,所以先將含有字符串的包發(fā)送出去,再陷入循環(huán)等待接收來(lái)自調試器的含有回復字符串的包。SYMBOLS的加載和卸載通過(guò)調用KdpReportSymbolsStateChange,int 0x3斷點(diǎn)異常和int 0x1單步異常(這兩個(gè)異?;旧鲜莾群苏{試器處理得最多的異常)通過(guò)調用KdpReportExceptionStateChange,這兩個(gè)函數很相似,都是通過(guò)調用KdpSendWaitContinue函數。KdpSendWaitContinue可以說(shuō)是內核調試器功能的大管家,負責各個(gè)功能的分派。這個(gè)函數向內核調試器發(fā)送要發(fā)送的信息,比如當前所有寄存器狀態(tài),每次單步后我們都可以發(fā)現寄存器的信息被更新,就是內核調試器接受它發(fā)出的包含最新機器狀態(tài)的包;還有SYMBOLS的狀態(tài),這樣加載和卸載了SYMBOLS我們都能在內核調試器里看到相應的反應。然后KdpSendWaitContinue等待從內核調試器發(fā)來(lái)的包含命令的包,決定下一步該干什么。讓我們來(lái)看看KdpSendWaitContinue都能干些什么:
case DbgKdReadVirtualMemoryApi:
KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadVirtualMemory64Api:
KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteVirtualMemoryApi:
KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteVirtualMemory64Api:
KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadPhysicalMemoryApi:
KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWritePhysicalMemoryApi:
KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdGetContextApi:
KdpGetContext(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSetContextApi:
KdpSetContext(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteBreakPointApi:
KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdRestoreBreakPointApi:
KdpRestoreBreakpoin(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadControlSpaceApi:
KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteControlSpaceApi:
KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadIoSpaceApi:
KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteIoSpaceApi:
KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdContinueApi:
if (NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) != FALSE) {
return ContinueSuccess;
} else {
return ContinueError;
}
break;
case DbgKdContinueApi2:
if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) != FALSE) {
KdpGetStateChange(&ManipulateState,ContextRecord);
return ContinueSuccess;
} else {
return ContinueError;
}
break;
case DbgKdRebootApi:
KdpReboot();
break;
case DbgKdReadMachineSpecificRegister:
KdpReadMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteMachineSpecificRegister:
KdpWriteMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSetSpecialCallApi:
KdSetSpecialCall(&ManipulateState,ContextRecord);
break;
case DbgKdClearSpecialCallsApi:
KdClearSpecialCalls();
break;
case DbgKdSetInternalBreakPointApi:
KdSetInternalBreakpoint(&ManipulateState);
break;
case DbgKdGetInternalBreakPointApi:
KdGetInternalBreakpoint(&ManipulateState);
break;
case DbgKdGetVersionApi:
KdpGetVersion(&ManipulateState);
break;
case DbgKdCauseBugCheckApi:
KdpCauseBugCheck(&ManipulateState);
break;
case DbgKdPageInApi:
KdpNotSupported(&ManipulateState);
break;
case DbgKdWriteBreakPointExApi:
Status = KdpWriteBreakPointEx(&ManipulateState,
&MessageData,
ContextRecord);
if (Status) {
ManipulateState.ApiNumber = DbgKdContinueApi;
ManipulateState.u.Continue.ContinueStatus = Status;
return ContinueError;
}
break;
case DbgKdRestoreBreakPointExApi:
KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSwitchProcessor:
KdPortRestore ();
ContinueStatus = KeSwitchFrozenProcessor(ManipulateState.Processor);
KdPortSave ();
return ContinueStatus;
case DbgKdSearchMemoryApi:
KdpSearchMemory(&ManipulateState,&MessageData,ContextRecord);
break;
讀寫(xiě)內存、搜索內存、設置/恢復斷點(diǎn)、繼續執行、重啟等等,WinDBG里的功能是不是都能實(shí)現了?呵呵。
每次內核調試器接管系統是通過(guò)調用在KiDispatchException里調用KiDebugRoutine(KdpTrace),但我們知道要讓系統執行到KiDispatchException必須是系統發(fā)生了異常。而內核調試器與被調試系統之間只是通過(guò)串口聯(lián)系,串口只會(huì )發(fā)生中斷,并不會(huì )讓系統引發(fā)異常。那么是怎么讓系統產(chǎn)生一個(gè)異常呢?答案就在KeUpdateSystemTime里,每當發(fā)生時(shí)鐘中斷后在HalpClockInterrupt做了一些底層處理后就會(huì )跳轉到這個(gè)函數來(lái)更新系統時(shí)間(因為是跳轉而不是調用,所以在WinDBG斷下來(lái)后回溯堆棧是不會(huì )發(fā)現HalpClockInterrupt的地址的),是系統中調用最頻繁的幾個(gè)函數之一。在KeUpdateSystemTime里會(huì )判斷KdDebuggerEnable是否為T(mén)RUE,若為T(mén)RUE則調用KdPollBreakIn判斷是否有來(lái)自?xún)群苏{試器的包含中斷信息的包,若有則調用DbgBreakPointWithStatus,執行一個(gè)int 0x3指令,在異常處理流程進(jìn)入了KdpTrace后將根據處理不同向內核調試器發(fā)包并無(wú)限循環(huán)等待內核調試的回應?,F在能理解為什么在WinDBG里中斷系統后堆?;厮菘梢砸来伟l(fā)現KeUpdateSystemTime->RtlpBreakWithStatusInstruction,系統停在了int 0x3指令上(其實(shí)int 0x3已經(jīng)執行過(guò)了,只不過(guò)Eip被減了1而已),實(shí)際已經(jīng)進(jìn)入KiDispatchException->KdpTrap,將控制權交給了內核調試器。
系統與調試器交互的方法除了int 0x3外,還有DbgPrint、DbgPrompt、加載和卸載symbols,它們共同通過(guò)調用DebugService獲得服務(wù)。
NTSTATUS DebugService(
ULONG ServiceClass,
PVOID Arg1,
PVOID Arg2
)
{
NTSTATUS Status;
__asm {
mov eax,ServiceClass
mov ecx,Arg1
mov edx,Arg2
int 0x2d
int 0x3
mov Status,eax
}
return Status;
}
ServiceClass可以是BEAKPOINT_PRINT(0x1)、BREAKPOINT_PROMPT(0x2)、BREAKPOINT_LOAD_SYMBOLS(0x3)、BREAKPOINT_UNLOAD_SYMBOLS(0x4)。為什么后面要跟個(gè)int 0x3,M$的說(shuō)法是為了和int 0x3共享代碼(我沒(méi)弄明白啥意思-_-),因為int 0x2d的陷阱處理程序是做些處理后跳到int 0x3的陷阱處理程序中繼續處理。但事實(shí)上對這個(gè)int 0x3指令并沒(méi)有任何處理,僅僅是把Eip加1跳過(guò)它。所以這個(gè)int 0x3可以換成任何字節。
int 0x2d和int 0x3生成的異常記錄結(EXCEPTION_RECORD)ExceptionRecord.ExceptionCode都是STATUS_BREAKPOINT(0x80000003),不同是int 0x2d產(chǎn)生的異常的ExceptionRecord.NumberParameters>0且ExceptionRecord.ExceptionInformation對應相應的ServiceClass比如BREAKPOINT_PRINT等。事實(shí)上,在內核調試器被掛接后,處理DbgPrint等發(fā)送字符給內核調試器不再是通過(guò)int 0x2d陷阱服務(wù),而是直接發(fā)包。用M$的話(huà)說(shuō),這樣更安全,因為不用調用KdEnterDebugger和KdExitDebugger。
最后說(shuō)一下被調試系統和內核調試器之間的通信。被調試系統和內核調試器之間通過(guò)串口發(fā)數據包進(jìn)行通信,Com1的IO端口地址為0x3f8,Com2的IO端口地址為0x2f8。在被調試系統準備要向內核調試器發(fā)包之前先會(huì )調用KdEnterDebugger暫停其它處理器的運行并獲取Com端口自旋鎖(當然,這都是對多處理器而言的),并設置端口標志為保存狀態(tài)。發(fā)包結束后調用KdExitDebugger恢復。每個(gè)包就象網(wǎng)絡(luò )上的數據包一樣,包含包頭和具體內容。包頭的格式如下:
typedef struct _KD_PACKET {
ULONG PacketLeader;
USHORT PacketType;
USHORT ByteCount;
ULONG PacketId;
ULONG Checksum;
} KD_PACKET,*PKD_PACKET;
PacketLeader是四個(gè)相同字節的標識符標識發(fā)來(lái)的包,一般的包是0x30303030,控制包是0x69696969,中斷被調試系統的包是0x62626262。每次讀一個(gè)字節,連續讀4次來(lái)識別出包。中斷系統的包很特殊,包里數據只有0x62626262。包標識符后是包的大小、類(lèi)型、包ID、檢測碼等,包頭后面就是跟具體的數據。這點(diǎn)和網(wǎng)絡(luò )上傳輸的包很相似。還有一些相似的地方比如每發(fā)一個(gè)包給調試器都會(huì )收到一個(gè)ACK答復包,以確定調試器是否收到。若收到的是一個(gè)RESEND包或者很長(cháng)時(shí)間沒(méi)收到回應,則會(huì )再發(fā)一次。對于向調試器發(fā)送輸出字符串、報告SYMBOL情況等的包都是一接收到ACK包就立刻返回,系統恢復執行,系統的表現就是會(huì )卡那么短短一下。只有報告狀態(tài)的包才會(huì )等待內核調試器的每個(gè)控制包并完成對應功能,直到發(fā)來(lái)的包包含繼續執行的命令為止。無(wú)論發(fā)包還是收包,都會(huì )在包的末尾加一個(gè)0xaa,表示結束。
現在我們用幾個(gè)例子來(lái)看看調試流程。
記得我以前問(wèn)過(guò)jiurl為什么WinDBG的單步那么慢(相對softICE),他居然說(shuō)沒(méi)覺(jué)得慢?*$&$^$^(&(&;(我ft?,F在可以理解為什么WinDBG的單步和從操作系統正常執行中斷下來(lái)為什么那么慢了。單步慢是因為每單步一次除了必要的處理外,還得從串行收發(fā)包,怎么能不慢。中斷系統慢是因為只有等到時(shí)鐘中斷發(fā)生執行到KeUpdateSystemTime后被調試系統才會(huì )接受來(lái)自WinDBG的中斷包?,F在我們研究一下為什么在KiDispatchException里不能下斷點(diǎn)卻可以用單步跟蹤KiDispatchException的原因。如果在KiDispatchException中某處下了斷點(diǎn),執行到斷點(diǎn)時(shí)系統發(fā)生異常又重新回到KiDispatchException處,再執行到int 0x3,如此往復造成了死循環(huán),無(wú)法不能恢復原來(lái)被斷點(diǎn)int 0x3所修改的代碼。但對于int 0x1,因為它的引起是因為EFLAG寄存中TF位被置位,并且每次都自動(dòng)被復位,所以系統可以被繼續執行而不會(huì )死循環(huán)?,F在我們知道了內部機制,我們就可以調用KdXXX函數實(shí)現一個(gè)類(lèi)似WinDBG之類(lèi)的內核調試器,甚至可以替換KiDebugRoutine(KdpTrap)為自己的函數來(lái)自己實(shí)現一個(gè)功能更強大的調試器,呵呵。
版權聲明: 本站僅提供信息存儲空間服務(wù),旨在傳遞更多信息,不擁有所有權,不承擔相關(guān)法律責任,不代表本網(wǎng)贊同其觀(guān)點(diǎn)和對其真實(shí)性負責。如因作品內容、版權和其它問(wèn)題需要同本網(wǎng)聯(lián)系的,請發(fā)送郵件至 舉報,一經(jīng)查實(shí),本站將立刻刪除。