Alias Fungsi Model Data Debugger

Alias fungsi adalah nama pendek unik di mana pengguna debugger dapat mengakses fungsionalitas yang ditentukan dalam ekstensi debugger (baik ditulis di C++ atau beberapa lingkungan skrip seperti JavaScript). Nama pendek ini dikaitkan dengan objek fungsi model data (objek yang mengimplementasikan IModelMethod). Fungsi tersebut mengambil jumlah argumen arbitrer dan mengembalikan satu nilai. Efek memanggil alias fungsi dan apa yang dilakukan dengan nilai tersebut tergantung pada bagaimana alias fungsi dipanggil dan debugger host apa yang dipanggil di dalamnya.

Topik ini mengasumsikan pembaca terbiasa dengan model objek debugger dan JavaScript. Untuk informasi tentang menggunakan objek debugger dengan JavaScript, lihat Objek Debugger Asli di Ekstensi JavaScript.

Beberapa contoh yang ditampilkan di sini menggunakan perintah dx, untuk informasi selengkapnya tentang bekerja dengan perintah dx, lihat dx (Ekspresi Model Objek Debugger Tampilan). Selain itu LINQ digunakan yang dijelaskan dalam Menggunakan LINQ Dengan objek debugger.

Menggunakan alias fungsi sebagai perintah ekstensi

Semua alias fungsi yang dibuat di WinDbg dapat dipanggil seolah-olah mereka adalah ekstensi debug ! perintah "bang". Jika fungsi tidak mengambil argumen, cukup panggil !aliasName akan menyebabkan fungsi dipanggil dan nilai hasil ditampilkan. Sebagai contoh (dibuat dengan ekstensibilitas JavaScript)

Sebagai contoh, fungsi ini menyediakan dua nilai konstanta, pi dan 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")];
}

Hasil panggilan alias fungsi ditunjukkan di sini.

0:000> !constants
@$constants()                 : [object Object]
    math_constants   : [object Object]
    description      : Archimedes' pi and Euler's number e

Tautan DML ke objek kompleks akan dihasilkan secara otomatis. Mengklik math_constants yang ditunjukkan di atas akan menghasilkan output berikut.

0:000> dx -r1 @$constants().math_constants
@$constants().math_constants                 : [object Object]
    pi               : 3.141593
    e                : 2.718282

Jika fungsi memiliki argumen, fungsi tersebut dapat disediakan setelah perintah alias fungsi itu sendiri. Perhatikan bahwa apa pun yang muncul setelah perintah alias fungsi dianggap sebagai ekspresi dan dievaluasi seperti itu. String teks tidak diteruskan langsung ke fungsi . Untuk ekspresi argumen tunggal, itu bisa datang setelah perintah alias fungsi itu sendiri. Untuk beberapa argumen, argumen harus dikurung seolah-olah itu adalah panggilan fungsi seperti yang diilustrasikan dalam contoh berikutnya ini.

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")];
}

Kedua fungsi ini dapat dipanggil seperti yang ditunjukkan di sini.

0:000> !neg 42
@$neg(42)        : -42

0:000> !add (5, 7)
@$add(5, 7)      : 0xc

Penggunaan alias fungsi dengan evaluator ekspresi dx

Selain ekstensi debug ! sintaks perintah "bang" untuk memanggil fungsi alias, semua nama yang terkait dengan alias fungsi tersedia langsung dalam evaluator ekspresi dx saat diawali oleh @$ seperti yang ditunjukkan di sini.

0:000> dx @$neg(42)
@$neg(42)        : -42

0:000> dx @$add(99, 77)
@$add(99, 77)    : 0xb0

Pertimbangan desain alias fungsi

Alias fungsi tidak boleh menjadi satu-satunya cara di mana fungsionalitas di sebagian besar ekstensi model data diekspos. Ekstensi model data (baik itu di C++ atau JavaScript) hampir selalu menyertakan data yang diekspos terkait dengan jenis atau konsep debugger lainnya. Hal-hal yang terkait dengan proses harus berada di bawah Debugger.Models.Process atau sub-namespace objek tersebut. Alias fungsi dapat menjadi cara mudah untuk mendapatkan (atau mengubah) data yang mungkin memerlukan kueri yang jauh lebih lama.

Sebagai contoh mode kernel, kueri berikut mengambil pohon perangkat PnP dan meratakannya ke dalam daftar datar sederhana perangkat:

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)
    [...]     

Kode JavaScript ini menunjukkan bagaimana ini dapat diimplementasikan sebagai alias fungsi.

function __flatDevices()
{
    return host.currentSession.Devices.DeviceTree.Flatten(n => n.Children);
}

function initializeScript()
{
    return [new host.functionAlias(__flatDevices, "devices")];
}

Alias fungsi kemudian dapat dipanggil sebagai perintah ekstensi debug.

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)

    ...

Salah satu keuntungan dengan menggunakan alias fungsi, adalah dapat disempurnakan lebih lanjut menggunakan sintaks dx. Dalam contoh ini, klausa where ditambahkan untuk mencari simpul perangkat yang berisi "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

Perintah LINQ seperti berikut ini dapat digunakan dengan alias fungsi - . Semua. Apapun, . Hitung. Pertama. Ratakan. GroupBy, . Terakhir. OrderBy, . OrderByDescending, . Pilih, dan . Mana. Metode ini mengikuti (sedekat mungkin) formulir metode C# LINQ. Untuk informasi selengkapnya, lihat Menggunakan LINQ Dengan objek debugger.

Tampilan Kisi

Seperti halnya perintah dx lainnya, Anda dapat mengklik kanan pada perintah setelah dijalankan dan klik "Tampilkan sebagai kisi" atau tambahkan "-g" ke perintah untuk mendapatkan tampilan kisi hasil. Anda kemudian dapat mengklik kolom apa pun untuk mengurutkan, misalnya di InstancePath.

0: kd> dx -g @$devices().OrderBy(obj => obj.@"InstancePath")

Cuplikan layar output kisi alias fungsi objek debugger dengan baris yang diurutkan.

Contoh Alur Proses

Objek debugger diproyeksikan ke dalam namespace yang berakar pada "Debugger". Proses, modul, utas, tumpukan, bingkai tumpukan, dan variabel lokal semuanya tersedia untuk digunakan dalam kueri LINQ.

Contoh JavaScript ini memperlihatkan cara menampilkan jumlah utas untuk proses sesi saat ini:

function __Processes()
{
    return host.currentSession.Processes.Select(p => ({Name: p.Name, ThreadCount: p.Threads.Count()}));
}

function initializeScript()
{
    return [new host.functionAlias(__Processes, "Processes")];
}

Ini menunjukkan contoh output dengan ! Memproses alias fungsi.

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]

...    

Dalam contoh ini, proses 5 teratas dengan jumlah utas terbesar ditampilkan.

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]
    [...]   

Lihat juga

dx (Ekspresi Model Objek Debugger Tampilan)

Menggunakan LINQ Dengan objek debugger

Objek Debugger Asli di NatVis

Objek Debugger Asli di ekstensi JavaScript