Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Псевдонимы функций — это уникальное короткое имя, с помощью которого пользователь отладчика может получить доступ к функциям, определенным в расширении отладчика (написанном на C++ или в некоторых средах сценариев, таких как JavaScript). Это короткое имя связано с объектом функции модели данных (объект, реализующий IModelMethod). Эта функция принимает произвольное число аргументов и возвращает одно значение. Эффект вызова псевдонима функции и того, что делается с этим значением, зависит от того, как вызывается псевдоним функции и какой отладчик узла вызывается внутри.
В этом разделе предполагается, что читатель знаком с объектной моделью отладчика и JavaScript. Сведения об использовании объектов отладчика с JavaScript см. в собственных объектов отладки в расширениях JavaScript.
В некоторых примерах, приведенных здесь, используется команда dx, дополнительные сведения о работе с командой dx см. в dx (выражение объектной модели отладчика). Кроме того, используется LINQ, описанный в разделе Using LINQ Withобъектов отладчика.
Использование псевдонима функции в качестве команд расширения
Все псевдонимы функций, созданные в 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")
Пример потоков обработки
Объекты отладчика проецируются в пространство имен, корневом элементе "Отладчик". Процессы, модули, потоки, стеки, кадры стека и локальные переменные доступны для использования в запросе 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]
[...]
См. также
dx (выражение объектной модели отладчика)
Использование LINQ с объектами отладчика
собственные объекты отладчика в NatVis
собственные объекты отладчика в расширениях JavaScript