2019/08/23

oversea remote debug 遠端除錯 怎麼做呢? Windows

通常有兩種方式建立兩地的遠端Debug, 第一種是 teamviewer, 第二種windbg

第一種 teamviewer

就是透過網路的方式可以讓你看到另一台電腦的螢幕, 並且能夠操作那台電腦, 但缺點是如果你的issue必須重新開機或是該issue跟網路與顯示有關的話, 通常連線就可能中斷, 無法繼續分析下去!

這時候就是透過第二種方式吧, windbg remote debugging

微軟其實也有寫得很詳細, 大致上就是建立如下圖的環境

解釋一下,
Debugging Server負責處理整個debug活動順利進行的平台: Host Computer
Debugging Client負責從遠端來控制debug session進行: Remote Computer
為了建立遠端的除錯, 第一個要設定好 debugging server, 然後才讓Client從遠端啟動.

這個地方要特別說一下, Target就是運行著要被除錯程式碼的電腦!
Target與 Host Computer 有時可以是同一台電腦, 有時候必須是分開的兩部電腦, 主要取決於你要除厝的程式碼是kernel mode還是user mode, 講到這裡大家應該可猜出答案, 對啦! 如果是kernel mode系統可能會隨時掛掉, 因此建議要分兩台電腦, 如果是user mode的debugging, 是可以勉強在同一台電腦OK的

介於兩端的連線協定, 有多種選擇: TCP, NPIPE, SPIPE, SSL,或是 COM Port.
假設我透過TCP連線, 並且使用winDbg軟體在 debugging Server/Client兩台電腦上, 作遠端kernel-mode除錯, 可以參考以下步驟:

1. 在 Host電腦, 開啟 windbg 並建立與Target之間的 kernel-mode debugging session

兩種方式:
#1. WinDbg Menu:
如果Windbg處於休眠狀態你可以選單File下拉, 選 Kernel Debug (或直接快捷鍵CTRL+K), 然後當 Kernel Debugging 對話窗出現時, 點選你建立的連線方式: NET, 1394, USB, COM, or Local.

#2. Command Prompt:
如果透過指令介面, 啟動WinDbg後輸入以下指令:

  • windbg [-y SymbolPath] -k net:port=PortNumber,key=Key[,target=TargetIPAddress|TargetMachineName]
  • windbg [-y SymbolPath] -k 1394:channel=1394Channel[,symlink=1394Protocol]
  • windbg [-y SymbolPath] -k usb:targetname=USBString
  • windbg [-y SymbolPath] -k com:port=ComPort,baud=BaudRate
  • windbg [-y SymbolPath] -k com:pipe,port=\\VMHost\pipe\PipeName[,resets=0][,reconnect]
  • windbg [-y SymbolPath] -k com:modem
  • windbg [-y SymbolPath] -kl
  • windbg [-y SymbolPath] -k

2. 暫時中斷,

從Debug選單選取Break, 或直接按 CTRL-Break.

3. 在視窗 Debugger Command Window, 輸入指令做連線


指令:
.server tcp:port=5005
(這個 port number 5005 可以根據你的狀況改變)

4. WinDbg將會回應如下面訊息

dbgcmd

Server started.  Client can connect with any of these command lines0:  -remote tcp:Port=5005,Server=YourHostComputer

5. 到了遠端電腦(remote computer)

開啟 WinDbg, 從選單File下拉, 選取 Connect to Remote Session

6. 在 Connection String 底下,

輸入
tcp:Port=5005,Server=YourHostComputer
這裡的 YourHostComputer 就必須視HOST電腦的名稱(debugging server).
再按 OK

2019/08/06

關於 Linear Aperture-Space Segments

轉錄自 小小paul

線性aperture空間段類似於線性內存空間段.但是線性aperture段只是一段虛擬地址空間而不能真正保存數據。爲了保存數據必須分配系統內存頁,而這段虛擬地址空間也必須被重定向到這些頁上。小端口驅動必須實現 DxgkDdiBuildPagingBuffer中的DXGK_OPERATION_MAP_APERTURE_SEGMENT 和 DXGK_OPERATION_UNMAP_APERTURE_SEGMENT操作來處理地址的重定向而且必須按照DriverEntry of Display Miniport Driver描述的方式暴露這個函數。DxgkDdiBuildPagingBuffer會收到需要被重定向的地址範圍和被分配的系統物理內存頁所引用的MDL。

顯卡小驅動程序通常通過編程一個頁表來完成地址空間範圍的重定向,而視頻內存管理器並不知道這個頁表。

驅動程序必須在DXGK_SEGMENTDESCRIPTOR結構的Flags成員中設置Aperture位域標誌來指定一個線性Aperture空間段。驅動程序還可以設置以下位域標誌,以表明額外的段支持:

CpuVisible表示這個段CPU可以訪問
CacheCoherent表示段與段重定向到的頁面保持CPU緩存一致性。
下圖顯示了線性Aperture空間段的可視化表示。

2019/08/02

到底什麼是 .NET Framework 呢 ?

微軟有個願景,他幫全世界的網民化個大餅,這個大餅叫做 .NET。
為了這個遠景,所以微軟在 Windows 加上一層平台,因為是要達成 .NET 的遠景,所以取名叫做 .NET Framework。

那這層平台式做什麼的。
PC 什麼都沒裝,只有 BIOS 的運作,所以您可以用組合語言燒在晶片下一些指令教電腦做事。

您也可以裝上 DOS ,這時候可以執行一些 DOS 的指令或 DOS 版的程式。
如果你要執行 Windows 的程式,那您必須在 DOS 上加裝 Windows 系統。
同樣的,如果您要執行 .NET 的程式,那麼您就必須在 Windows 上加裝 .NET Framework。

.NET Framework相當於 J2EE,其中 .NET Framework 裡面有個 CLR (Common Language Runtime),就類似於 Java Virtual Machine。其他的 ADO.NET, ASP.NET, XML…可以想像是 .NET Framework裡的模組,讓您可以更快的完成程式開發。

至於您所說的 VB.NET, ADO.NET…,這些都是 .NET Framework 的一部份。

簡單的說,以前寫 ASP ,您可以使用 ADO 來存取資料庫,在 .NET Framework 有一個更方便更強的存取方式,就是透過 ADO.NET。

以前寫 Windows 上執行的程式用 VB6,如果要寫 .NET Framework 上執行的程式,那就要用 VB.NET。

例外 .NET Framework 是跨語言的,所以 VB, C , C#, Perl…共有 26 種語言可用。

.NET Framework是由Microsoft專為Windows所開發的平台,解決同一程式在不同版本或是不同台電腦的Windows作業系統中的相容性。.NET也提供程式開發工具(Visual Studio),以強大的物件導向功能與多樣化的類別庫彙整多種程式語言,像是C、VB.NET、C++、Python。.NET Framework的概念其實與Oracle的JAVA很相近,彼此也是競爭對手。

然後
可以看這篇文章:
ASP.NET and ASP.NET Core, .NET Framework and .NET core and .NET Standard

參考:
.NET Framework 使用者入門

[轉]凝視散記: COM - Microsoft物件導向開發架構的基礎

(轉錄自 凝視、散記 )

COM是Microsoft物件導向架構的基礎,本文主要是重點介紹COM的理論及運作機制。基礎理論包括:COM的概念、應用及定義。運作機制探討COM底層的運作,將提到:COM的介面、識別及呼叫,更進一步探討跨行程及跨機器時如何呼叫。最後很簡要的介紹COM以外另外CORBA及JAVA的做法。

什麼是元件(Component)?

元件是一種有公開的屬性、方法、事件,可以在應用程式中呼叫的二進位檔案。主要的目的是為了在程式開發時可以「重複使用」這些已經編譯好的檔案,以提高開發效率降低成本。此外,因為元件的發行與使用都是二進位檔案,所以在安裝及使用時都是看不到原始碼的,也可以達到保護source code的目的。再就Internet的應用而言,由於元件已經經過編譯,所以在執行的速度上會比ASP指令檔(Script)來得快,因此較佳的執行效能也是使用元件的原因之一。

如果我們將應用程式想成是一件產品;元件就好像是產品的零件。當你完成產品的需求規劃後,不需要自行撰寫所有的程式,只要選取或購買符合需求的元件進行組裝便能完成專案。這種系統開發的哲學就是所謂的CBSE—Component Based System Engineering。CBSE發展應用程式的流程如下:定義應用程式的功能à設計使用者介面à查詢軟體元件目錄尋找符合功能的軟體元件à查詢各軟體元件的介面(interface)à撰寫應用程式組合各軟體元件à輸入各軟體元件的介面值à呼叫各軟體元件à完成系統功能。

什麼是COM (Component Object Model)

每個元件都可視為是一段獨立的副程式,讓應用程式透過Run Time時與元件的相互連結而完成系統功能,便是Microsoft發展COM主要的目的。Microsoft COM的架構也是CBSE的實現,程式開發者只要有軟體元件的清單及清楚定義的介面,便可在應用程式中重複使用這些現成的元件。

1991年Microsoft提出一項新的規格 OLE (Object Linking and Embedding) 。Microsoft當時的OLE 1.0,只提供處理「複合文件」﹙compound document﹚的功能,這種以文件為中心﹙非以應用程式為中心﹚,能夠在單一文件儲存如文字、圖形、視訊與聲音等多重格式資料的規格並未被廣泛接受。到了1993年Microsoft公佈OLE 2.0版的規格,就是COM 架構,包含更多功能,最重要的,COM規範了程式間互動﹙interoperability﹚的方法與介面,融入了封裝、多型等物件導向的觀念。

其實Microsoft大部份的產品都已COM化。如:IE、OutLook、Excel等不僅都是可以獨立使用的軟體,也都是component。只要知道它們提供了哪些 API﹙Application Program Interface﹚,你便可以在程式中把它們當成元件來呼叫。你要做的只是翻翻programmer guide,查出所提供的 method,然後就可以在程式中呼叫它們來完成工作。 而且你寫的軟體也可以成為別人軟體的元件或一項功能(feature) 。在使用元件之前,必須執行「服務註冊」的指令﹙在Dos模式之下執行Regsvr32 myCom.dll﹚,向作業系統「註冊」該元件。然後就可以在有支援 COM/DCOM的開發工具,如:VB, Delphi, Visual FoxPro, C++ Builder, Active Server Page (ASP)中來使用已註冊的元件。

COM的定義

COM是一套規範,規定了製作具有動態交換能力元件的方法。它制定了用戶端程式與及元件間溝通的介面,以達到相互操作﹙Interoperability﹚所應共同遵循的一套標準。讓二進位物件程式的設計、使用以及獨立開發成為可行。事實上,COM並不只是一份規格,它還實作了一組API,叫做COM程式庫,提供所有用戶端程式與元件都會用到的元件管理服務。

COM元件包含以Win32動態連結程式庫( DLL )及以 .EXE形式存在的可執行檔,遵循COM的標準所撰寫出來的元件具備以下幾點的特性:

  • 可以用二進位的格式傳送。
  • 具有語言獨立性:可以使用任何語言撰寫,也可以呼叫任何語言的元件。
  • 是動態連結的形式。
  • 具位置透通性﹙location transparent﹚:用戶端程式可以將遠端機器上的元件當成本地端機器上的元件一樣使用。
  • 與用戶端程式獨立:可以在不干擾舊有用戶端程式的前提下進行新物件的改版。

COM的運作機制

每個COM物件都提供一個以上的介面( Interface ),每個介面都提供一些方法。client端只能透過其介面呼叫COM物件介面內的方法,來使用該物件的服務,而無法直接存取物件內的資料。

COM的介面指的是記憶體中一個包含函式指標陣列的Virtual function table,每一個陣列元素儲存指向元件所實作的函式位址的指標。COM所用來定義介面的標準為IDL—介面定義語言﹙Interface Definition Language﹚。IDL是Open Source Foundation為了在分散式計算環境中使用RPC﹙Remote Procedure Call﹚所制定的。

COM規定所有的介面都必須繼承IUnknown介面﹙註﹚,因此每個COM介面都一定包含:QueryInterface、AddRef與Release等三個函式。

每個COM Object都是屬於特定類別( class )的個體( instance )。我們必須先經由COM程式庫得知道物件的類別,才能開始執行該物件的真正個體。因為client端在使用COM物件介面的方法前,必須先取得該介面的指標﹙Pointer﹚。因此當client端尚未取得此物件所提供的任何介面指標時,會利用COM程式庫中的CoCreateInstance函式﹙註﹚來取得物件的第一個介面指標。當server便開始執行此類別的實作後,client端便可以直接向該物件要求其它所提供的介面的指標,進而使用該物件的任何方法或服務。

每個物件會利用CLSID作為鍵值在Windows的Registry登錄資料庫中記錄元件所在的DLL檔案名稱,以便讓CoCreateInstance利用CLSID作機碼查得檔案的名稱。 Registry是Windows作業系統用來紀錄系統軟、硬體、設定、以及使用者的相關資訊,必要時可以在Registry中新增紀錄或讀取資料。COM的用戶端程式就是利用Registry找出所要使用的元件。

Client端在建立物件透過CoCreateInstance取得該物件第一個介面指標後,就可以呼叫QueryInterface,並傳入該介面的IID,利用IUnknown::QueryInterface,向物件要求取得其他方法所在介面的指標。如果成功的話,就可以使用傳回的指標,便得知物件所提供某個特定介面。

介面一旦公佈就不能再更改了。如果必須異動,只能再定義一個新的介面,新的介面可以繼承原來舊的介面,不過介面的唯一識別碼IID,就是Globally Unique Identifier ( GUID )一定是唯一的,不可以重複。

GUID ( Globally Unique Identifier )是為了讓全球程式設計師所設計的COM物件及介面不必依賴集中管理就能擁有唯一的識別。我們可以藉助Microsoft的提供的工具程式GUIDGEN.EXE或UUIDGEN.EXE來產生唯一的GUID。COM介面的GUID可由IID這個特別資料型別來表示。而Class也有自己的GUID,為了與IID區別,COM另外定義了CLSID這個資料型別,專門用來放置類別的識別碼。

使用COM物件時,客戶端會強制該物件的新個體開始執行。該如何管理物件的執行?而且通常同時會有許多client端程式使用同一物件,物件應該在何時停止執行?

這個問題由IUnknown介面所提供的AddRef以及Release所maintain的 Reference Counter而獲得解決。每個COM物件都有自己的Reference Counter,每當物件傳遞出一個介面的指標時,Reference Counter便會加一。每結束一個使用介面時,必須透過介面指標呼叫Release, Reference Counter便會減一。當物件的Reference Counter等於0的時候,物件本身便會destroy。

COM的類型

每個COM物件的實作部分都位於伺服器( Server )中。Server中含有真正用來實作物件方法的程式碼,並且負責維護物件的資料。COM有三種類型:

  • In-process Server:物件的實作係位於動態連結函式庫中,執行時與client端為於同一process中
  • Local Server:物件的實作位於與客戶端相同的機器中,但是在分開的行程內。
  • Remote Server:物件的實作位於與客戶端不同的機器內所執行的DLL或獨立行程中。跨機器的分散式系統必須借助Distributed COM ( DCOM ) ﹙註﹚的支援才得以完成。DCOM是一個高階的網路協定,建立於COM之上的規格和服務,讓位於不同電腦上的行程內之COM元件可以互相運作

對client端而言,不管物件實作是在哪一種伺服器中,都是透過介面指標,來啟動物件、取得物件介面的指標、叫用方法、釋放指標,沒有任何差別。不過server上的機制便有所不同。

第一種情形:In-process Server:COM物件的實作位於行程中的伺服器﹙如圖一﹚。
client端的介面指標直接指向物件的介面。透過vtable裡的函數指標直接呼叫物件的方法。

圖一

第二種情形:Local Server:COM物件的實作位於本地端的不同行程中﹙如圖二﹚。
由於vtable裡的函數指標無法跨行程,因此client端的介面指標無法直接指到物件的介面,因此會改為指向client端行程內的proxy介面,由proxy介面將存取要求透過RPC轉送給stub。client端將proxy介面是為object而真正的object則將stub視為client。

圖二

第三種情形:Remote Server:COM物件的實作是位於不同機器上﹙如圖三﹚。
在DCOM中所加入支援遠端伺服器的架構,client、proxy及stub間的互動與Local Server類似。

圖三

無論是跨行程或是跨機器的情形,在伺服器與client端中,都需要傳輸參數與資料的標準格式,以及進行溝通。proxy將呼叫的參數包裝為標準格式的動作稱為marshaling,透過RPC傳輸給stub,stub將收的到要求,卸除改為接收行程適用格式的相反動作,則稱為unmarshaling。Proxy與Stub的存在主要就是為了進行marshaling與unmarshaling。

Proxy與Stub的建立只要使用IDL ( Interface Description Language )來撰寫介面,就可以讓MIDL ( Microsoft IDL )編輯器幫我們產生proxy與stub DLL的程式,不需要自己動手撰寫這些程式。

元件開發的不同架構

在Microsoft的架構之下你可以利用VB及VC來開發元件.利用VB的ActiveX DLL來開發元件是最快速的方式。而MTS提供元件的管理以及交易(Transaction)的管理.這種架構在Windows 2000上已經整合為COM+。這也是Microsoft分散式應用系統設計的開發架構。

目前在元件的開發方面發展,有三大陣營 -
DCOM (Distributed Component Object Model)、CORBA (Common Object Request Broker Architecture ) 和 Java RMI (Remote Method Invocation)

Microsoft的 DCOM 就是根據其原本非分散式物件模組 COM 所進化而來的,它已被定為新一代電腦語言的發展基礎。DCOM 其實是二次元層次 (Binary Level) 的分散式物件介面標準。它既可支援 NT 及 Windows 98,此元件更可伸延到Internet之策略,Active X 就是其中的表表者。

CORBA 是由七百多間業內的公司參與之 OMG (Object Management Group) 所制定的標準,其目的是要整合大部份的物件系統。這種物件管理架構 (OMA,Object Management Architecture) 的主要溝通機制,其中物件與物件間之溝通是透過物件訊息仲裁者 (ORB)。而 ORB 是在主從架構間提供一仲裁服務,決定訊息的流向。CORBA 規範介於物件介面的層次 (Interface Level),而物件間就以介面描述語言 (IDL, Interface Definition Language) 來描述。將介面 (Interface) 與實作 (Implementation) 分開,提供多重的繼承架構及動-靜態介面的召喚方式。

Java 是昇陽微系統 (Sun Microsystems) 所提出結合了程式語言和虛擬機器 (Virtual Machine) 的分散式物件環境。與 DCOM 和 CORBA 比較,它不能採用多種不同的程式語言來發展,不過由於其虛擬機器的環境,使 Java 容易地跨平臺運行。

[轉] 關於用戶模式驅動程序框架(UMDF)的一點感想

(轉錄自: accessory )

  
  最近又要在WINDOWS下面寫點驅動,於是學習了下目前比較流行的WDF,主要是UMDF。因為以前用過一陣WDM,所以對KERNEL MODE的KMDF興趣不是特別大。
  
  WDF的全稱是Windows Driver Foundation,其中又包括了UMDF和KMDF。前者是USER LEVEL的驅動,後者是KERNEL LEVEL。在WDF出來之前,流行的WINDOWS驅動結構叫做WDM(WINDOWS DRIVER MODEL)。在WDM之前,WIN NT和WIN 95的驅動模式是不一樣的.WIN NT的比較規範,什麼東西都只能在內核做.NT這一套一直發展下來,變成了後來的WDM,WDF。不知道未來又會出現啥新名詞.WIN 95那一套很多地方限制沒有那麼嚴,這同時也造成了OS不夠穩定。在WIN 95之前,就是WIN 3.X和純真的DOS年代了。現在的BIOS依然純真,不過馬上就要變成複雜的UEFI了…. =。=
  
  回歸正題,以前剛學WDM的時候,就被告知一切對硬件的操作都必須要在KERNEL LEVEL做才行。於是形成了一個思維定勢,只有KERNEL LEVEL才可以操作硬件。多年以後,開始學習LINUX ,驚訝的發現LINUX下面是可以允許USER LEVEL APP直接訪問硬件端口的。再看INTEL手冊,發現硬件並沒有設計成只能在KERNEL LEVEL才能訪問…這時才明白,原來WINDOWS是故意那麼設計的…
  
  LINUX下的USER LEVEL APP也是有ROOT權限才可以訪問硬件端口。同時也有一些限制,比如處理中斷和DMA。不過能訪問端口本身已經提供了很多方便。有的時候,只想寫個小程序訪問2 ,3個IO端口。這個在LINUX下很簡單,在WINDOWS下就要自己寫驅動,或者藉助其他工具和庫了。
  
  後來某一天,驚聞WINDOWS最新的UMDF也是在USER LEVEL下的驅動。於是心想,是不是WINDOWS終於想明白,要跟LINUX學,允許USER LEVEL APP訪問端口了呢?本來我以為是這樣的,但是一直沒仔細看UMDF。今天看了一下後,找了半天,也沒有看到類似LINUX那樣可以直接訪問端口的東西。最後發現,UMDF還是要用FILE OBJECT去訪問那些硬件……也就是說WINDOWS下直接在USER LEVEL APP訪問IO端口的夢想又泡湯了…
   
看來WINDOWS並沒有更改他們的設計觀念,UMDF也和LINUX下的東西有很大區別。當然,UMDF本身還是有一些優點的,讓某些驅動的編寫容易了很多,不用再工作在內核下,不再受很多限制了。另外一個有點驚訝的是,UMDF居然是基於COM的。當然也沒有用到COM的全部功能,只是用了一點。不過這個也可以看出,COM這個東西還是比較成功的。感覺UMDF這個東西就是一個APP和DEVICE DRIVER的混合體.UMDF可以提供一些設備的符號鏈接,接受其他用戶程序的調用,這點上比較像個驅動。但是在UMDF真正要訪問硬件的時候,它又不能自己幹,還要調用底層的KERNEL DEVICE DRIVER。還要用啥FILE OBJECT之類的。從這個角度看,UMDF也很像一個用戶程序。
  
WDF最早也是跟著VISTA出來的。話說VISTA從技術上說還是不錯的,可惜用戶體驗方面做的差了點,變成了一個失敗的產品。又一次驗證了光有技術是不夠的……