函式別名是一個唯一的簡短名稱,調試程式的使用者可以存取調試程式延伸模組中定義的功能(無論是以 C++ 撰寫,還是某些腳本環境,例如 JavaScript)。 這個簡短名稱會與數據模型函式對象相關聯(實作 IModelMethod 的物件)。 該函式會接受任意數目的自變數,並傳回單一值。 叫用函式別名以及使用該值完成的工作,取決於叫用函式別名的方式,以及叫用函式內的主機調試程式。
本主題假設讀者熟悉調試程序物件模型和 JavaScript。 如需搭配 JavaScript 使用除錯程式物件的詳細資訊,請參閱 javaScript 延伸模組中的 原生調試程式物件。
如需使用 dx 命令的詳細資訊,請參閱 dx (顯示除錯程式物件模型表示式)。 此外,使用 LINQ,如使用 LINQ 搭配調試程式物件 中所述。
使用函式別名作為擴充命令
在 WinDbg 中建立的所有函式別名都可以叫用,就像是偵錯擴充功能 ! 「bang」 命令。 如果函式不接受任何自變數,只要叫用 !aliasName,就會呼叫函式並顯示結果值。 作為範例(使用 JavaScript 擴充性建立)
例如,此函式提供兩個常數值,pi 和 e。
function __constants()
{
return { math_constants : { pi : 3.1415926535 , e : 2.7182818284}, description : "Archimedes' pi and Euler's number e" };
}
function initializeScript()
{
return [new host.functionAlias(__constants, "constants")];
}
呼叫函式別名的結果如下所示。
0:000> !constants
@$constants() : [object Object]
math_constants : [object Object]
description : Archimedes' pi and Euler's number e
將會自動產生複雜物件的 DML 連結。 按兩下上述math_constants會導致下列輸出。
0:000> dx -r1 @$constants().math_constants
@$constants().math_constants : [object Object]
pi : 3.141593
e : 2.718282
如果函式有自變數,則可以在函式別名命令本身之後提供它們。 請注意,函式別名命令之後的任何內容都會被視為表達式,因此會評估為 。 文字字串不會直接傳遞至 函式。 對於單一自變數表示式,它可以在函式別名命令本身之後。 針對多個自變數,它們應該以括弧括起,如同下一個範例所示的函式呼叫。
function __oneArgument(x)
{
return -x;
}
function __twoArguments(x, y)
{
return x + y;
}
function initializeScript()
{
return [new host.functionAlias(__oneArgument, "neg"),
new host.functionAlias(__twoArguments, "add")];
}
這兩個函式可以呼叫,如下所示。
0:000> !neg 42
@$neg(42) : -42
0:000> !add (5, 7)
@$add(5, 7) : 0xc
函式別名搭配 dx 運算式評估工具使用
除了偵錯延伸模組 ! 叫用別名函式的 「bang」 命令語法中,所有與函式別名相關聯的名稱都會直接在 dx 表達式評估 @$ 工具中使用,如這裡所示。
0:000> dx @$neg(42)
@$neg(42) : -42
0:000> dx @$add(99, 77)
@$add(99, 77) : 0xb0
函式別名設計考慮
函式別名絕對不應該是公開絕大多數數據模型延伸模組中功能的唯一方式。 數據模型延伸模組(在 C++ 或 JavaScript 中)應該幾乎一律包含與類型或其他調試程式概念相關聯的數據。 與進程相關聯的專案應位在 Debugger.Models.Process 或該物件的子命名空間底下。 函式別名是取得(或轉換)數據所需的便利方式,可能需要相當長的時間查詢。
作為核心模式範例,下列查詢會採用 PnP 裝置樹狀結構,並將其扁平化為簡單的一般裝置清單:
0: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children),5
@$cursession.Devices.DeviceTree.Flatten(n => n.Children),5
[0x0] : HTREE\ROOT\0
[0x1] : ROOT\volmgr\0000 (volmgr)
[0x2] : ROOT\BasicDisplay\0000 (BasicDisplay)
[0x3] : ROOT\CompositeBus\0000 (CompositeBus)
[0x4] : ROOT\vdrvroot\0000 (vdrvroot)
[...]
此 JavaScript 程式代碼示範如何實作為函式別名。
function __flatDevices()
{
return host.currentSession.Devices.DeviceTree.Flatten(n => n.Children);
}
function initializeScript()
{
return [new host.functionAlias(__flatDevices, "devices")];
}
然後,可以將函式別名叫用為偵錯擴充功能命令。
0: kd> !devices
@$devices()
[0x0] : HTREE\ROOT\0
[0x1] : ROOT\volmgr\0000 (volmgr)
[0x2] : ROOT\BasicDisplay\0000 (BasicDisplay)
[0x3] : ROOT\CompositeBus\0000 (CompositeBus)
[0x4] : ROOT\vdrvroot\0000 (vdrvroot)
[0x5] : ROOT\spaceport\0000 (spaceport)
...
使用函式別名的優點之一,就是可以使用 dx 語法進一步精簡。 在此範例中,會新增 where 子句來尋找包含 「Harddisk」 的裝置節點。
0: kd> dx @$devices().Where(n => n.InstancePath.Contains("Harddisk"))
@$devices().Where(n => n.InstancePath.Contains("Harddisk"))
[0x0] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot1
[0x1] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot2
[0x2] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot3
[0x3] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot4
[0x4] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot5
[0x5] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot6
下列 LINQ 命令可以搭配功能別名使用 - 。都。任何。計數。第一。扁平 化。GroupBy, 。最後。OrderBy, 。OrderByDescending, 。選取 與 。哪裡。 這些方法會遵循 C# LINQ 方法形式(盡可能接近)。 如需詳細資訊,請參閱 使用 LINQ 搭配除錯程式物件。
方格顯示
如同其他 dx 命令,您可以在命令執行後以滑鼠右鍵按下命令,然後按兩下 [顯示為方格] 或將 “-g” 新增至命令,以取得結果的方格檢視。 接著,您可以按下任何數據行來排序,例如 InstancePath。
0: kd> dx -g @$devices().OrderBy(obj => obj.@"InstancePath")
進程線程範例
調試程式物件會投影到根目錄為 「Debugger」 的命名空間。 進程、模組、線程、堆疊、堆疊框架和局部變數全都可用於LINQ查詢。
此範例 JavaScript 示範如何顯示目前工作階段行程的線程計數:
function __Processes()
{
return host.currentSession.Processes.Select(p => ({Name: p.Name, ThreadCount: p.Threads.Count()}));
}
function initializeScript()
{
return [new host.functionAlias(__Processes, "Processes")];
}
這會顯示具有 的範例輸出!處理函式別名。
0: kd> !Processes
@$Processes()
[0x0] : [object Object]
[0x4] : [object Object]
[0x1b4] : [object Object]
[0x248] : [object Object]
[0x2c4] : [object Object]
[0x340] : [object Object]
[0x350] : [object Object]
[0x3d4] : [object Object]
[0x3e8] : [object Object]
[0x4c] : [object Object]
[0x214] : [object Object]
[0x41c] : [object Object]
[0x494] : [object Object]
...
在此範例中,會顯示具有最大線程計數的前5個進程。
0: kd> dx -r1 @$Processes().OrderByDescending(p =>p.ThreadCount),5
@$Processes().OrderByDescending(p =>p.ThreadCount),5
[0x4] : [object Object]
[0x180] : [object Object]
[0x978] : [object Object]
[0xda4] : [object Object]
[0x3e8] : [object Object]
[...]
另請參閱
在 NatVis 中 原生調試程序物件