!for_each_function
The !for_each_function extension executes a debugger command for each function, in a specified module, whose name matches a specified pattern.
!for_each_function -m:ModuleName -p:Pattern -c:CommandString
!for_each_function -?
Parameters
-m:ModuleName
Specifies the module name. This name is typically the file name without the file name extension. In some cases, the module name differs significantly from the file name.
-p:Pattern
Specifies the pattern to be matched.
-c:CommandString
Specifies the debugger command to execute for each function, in the specified module, that matches the pattern.
You can use the following aliases in CommandString.
Alias | Data type | Value |
---|---|---|
@#SymbolName |
string |
The symbol name. |
@#SymbolAddress |
ULONG64 |
The symbol address. |
@#ModName |
string |
The module name. |
@#FunctionName |
string |
The function name. |
-?
Displays help for this extension.
DLL
Ext.dll
Remarks
The following example shows how to list all function names, in the PCI module, that match the pattern *read*.
1: kd> !for_each_function -m:pci -p:*read* -c:.echo @#FunctionName
PciReadDeviceConfig
PciReadDeviceSpace
PciReadSlotIdData
PciExternalReadDeviceConfig
PiRegStateReadStackCreationSettingsFromKey
VmProxyReadDevicePathsFromRegistry
PpRegStateReadCreateClassCreationSettings
ExpressRootPortReadConfigSpace
PciReadRomImage
PciDevice_ReadConfig
PciReadDeviceConfigEx
PciReadSlotConfig
If an alias is not preceded and followed by a blank space, you must put the alias inside the ${} Alias Interpreter token.
The following example shows how to list all symbols, in all modules, whose function names match the pattern *CreateFile*. The alias @#ModuleName is not preceded by a blank space. Therefore, it is put inside the ${} Alias Interpreter token.
Note Do not confuse the @#ModuleName alias with the @#ModName alias. The @#ModuleName alias belongs to the !for_each_module extension, and the @#ModName alias belongs to the !for_each_function extension.
1: kd> !for_each_module !for_each_function -m:${@#ModuleName} -p:*CreateFile* -c:.echo @#SymbolName
nt!BiCreateFileDeviceElement
nt!NtCreateFile
...
Wdf01000!FxFileObject::_CreateFileObject
fltmgr!FltCreateFileEx2$fin$0
fltmgr!FltCreateFileEx2
...
Ntfs!TxfIoCreateFile
Ntfs!NtfsCreateFileLock
...
MpFilter!MpTxfpCreateFileEntryUnsafe
mrxsmb10!MRxSmbFinishLongNameCreateFile
...
srv!SrvIoCreateFile
You can put a sequence of commands in a command file, and use $$>< (Run Script File) to execute those commands for each function that matches the pattern. Suppose that a file named Commands.txt contains the following commands:
.echo
.echo @#FunctionName
u @#SymbolAddress L1
In the following example, the commands in the Commands.text file are executed for each function, in the PCI module, that matches the pattern *read*.
1: kd> !for_each_function -m:pci -p:*read* -c:$$><Commands.txt
PciReadDeviceConfig
pci!PciReadDeviceConfig [d:\wmm1\drivers\busdrv\pci\config.c @ 349]:
fffff880`00f7b798 48895c2408 mov qword ptr [rsp+8],rbx
PciReadDeviceSpace
pci!PciReadDeviceSpace [d:\wmm1\drivers\busdrv\pci\config.c @ 1621]:
fffff880`00f7c044 48895c2408 mov qword ptr [rsp+8],rbx
...
See also
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for