関数エイリアスは、デバッガーのユーザーがデバッガー拡張機能で定義されている機能にアクセスできる一意の短い名前です (C++ または JavaScript などの一部のスクリプト環境で記述されているかどうか)。 この短い名前は、データ モデル関数オブジェクト (IModelMethod を実装するオブジェクト) に関連付けられます。 この関数は任意の数の引数を受け取り、1 つの値を返します。 関数エイリアスを呼び出すことと、その値で何が行われるかは、関数エイリアスの呼び出し方法と、その関数内で呼び出されるホスト デバッガーによって異なります。
このトピックでは、リーダーがデバッガー オブジェクト モデルと JavaScript に精通していることを前提としています。 JavaScript でデバッガー オブジェクトを使用する方法の詳細については、「JavaScript 拡張機能 でのネイティブ デバッガー オブジェクトの」を参照してください。
ここで示す一部の例では dx コマンドを使用します。dx コマンドの操作の詳細については、「dx (Display Debugger Object Model Expression)」を参照してください。 さらに、LINQ を使用する方法については、「デバッガー オブジェクトでの LINQ の使用」で説明されています。
関数エイリアスを拡張コマンドとして使用する
WinDbg で作成されたすべての関数エイリアスは、デバッグ拡張機能であるかのように呼び出すことができます。"bang" コマンドを します。 関数が引数を受け取っていない場合は、!aliasName を呼び出すだけで関数が呼び出され、結果の値が表示されます。 例として (JavaScript 拡張機能を使用して作成)
例として、この関数は、pi と e 2 つの定数値を提供します。
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
関数に引数がある場合は、関数エイリアス コマンド自体の後に指定できます。 関数エイリアス コマンドの後に来るものは式と見なされ、そのように評価されることに注意してください。 テキスト文字列は関数に直接渡されません。 1 つの引数式の場合、関数エイリアス コマンド自体の後に記述できます。 複数の引数の場合は、次の例に示すように、関数呼び出しであるかのようにかっこで分ける必要があります。
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")];
}
次に示すように、これら 2 つの関数を呼び出すことができます。
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)
...
関数エイリアスを使用する利点の 1 つは、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]
[...]
こちらもご覧ください
デバッガー オブジェクトでの LINQ の使用 の
NatVis でのネイティブ デバッガー オブジェクトの
JavaScript 拡張機能 でのネイティブ デバッガー オブジェクトの