[wperf] WPERF-1272: Detect sampled project image name (process name) by PID
Introduction
In this patch I'm introducing new functionality for sample
: we detect sampled process name (image name) by PID. New command line option is introduced -p
/ --pid
with one parameter (PID). This feature can be combined with multi-core sampling, see [wperf,wperf-driver] WPERF-1271: add multi-core... (!1051 - merged).
Note:
-p <pid>
/--pid <pid>
and--image_name <name>
should be used interchangeably.
python_d.exe
processes share same base image address:
PS> (Get-Process -Name python_d).Id
1888
10156
> wperf sample -e ld_spec:100000 --pe_file cpython\PCbuild\arm64\python_d.exe -p 10156
base address of 'python_d.exe': 0x7ff7fc5d1288, runtime delta: 0x7ff6bc5d0000
> wperf sample -e ld_spec:100000 --pe_file cpython\PCbuild\arm64\python_d.exe -p 1888
base address of 'python_d.exe': 0x7ff7fc5d1288, runtime delta: 0x7ff6bc5d0000
⚠️ This feature do not work forrecord
as recording will spawn (and pin to the core) the process declared with--
operator and knows PID of the process
Example usage (with multi-core sampling ON)
- Spawn new
cpython
process (this process will "hop" between cores):
>cpython\PCbuild\arm64\python_d.exe -c 10**100**100
- Check PID (
10156
) of new process with Task Manager:
- Use wrong PID to sample (we should not see any meaningful samples as we die not deduce or will deduce wrong image name).
>wperf sample -e ld_spec:100000 -p 1234 --pe_file cpython\PCbuild\arm64\python_d.exe
warning: image name (process name) '' deduced from --pid 1234 is different to one deduced by wperf 'python_d.exe'. Wrong PID?
warning: failed to query base address of 'python_d.exe' with 6
- Use correct PID to deduce image name
wperf sample -e ld_spec:100000 -p 10156 --pe_file cpython\PCbuild\arm64\python_d.exe
base address of 'python_d.exe': 0x7ff7fc5d1288, runtime delta: 0x7ff6bc5d0000
sampling .....Ctrl-C received, quit counting... done!
Analyzing 20,480 sample(s)..... of which 14 are resolved samples
======================== sample source: ld_spec, top 50 hot functions ========================
overhead count symbol
======== ===== ======
86.17 1558 unknown
9.57 173 x_mul:python313_d.dll
1.11 20 PyErr_CheckSignals:python313_d.dll
1.05 19 v_isub:python313_d.dll
0.66 12 x_add:python313_d.dll
0.55 10 v_iadd:python313_d.dll
0.17 3 write_size_t:python313_d.dll
0.17 3 _Py_ThreadCanHandleSignals:python313_d.dll
0.11 2 _PyLong_DigitCount:python313_d.dll
0.11 2 _PyMem_DebugCheckAddress:python313_d.dll
0.11 2 read_size_t:python313_d.dll
0.11 2 _PyErr_CheckSignalsTstate:python313_d.dll
0.06 1 _Py_DECREF_INT:python313_d.dll
0.06 1 PyInterpreterState_Get:python313_d.dll
100.00% 1808 top 14 in total
2.567 seconds time elapsed
I can also use --image_name python_d.exe
instead of -p
/ --pid
:
>wperf sample -e ld_spec:100000 --pe_file cpython\PCbuild\arm64\python_d.exe --image_name python_d.exe
base address of 'python_d.exe': 0x7ff7fc5d1288, runtime delta: 0x7ff6bc5d0000
sampling ....Ctrl-C received, quit counting... done!
Analyzing 10,240 sample(s).... of which 11 are resolved samples
...
In this patch:
- wperf: add 'Sampling model' description to README, part 3
- wperf: add 'Sampling model' description to README, part 2
- wperf: add 'Sampling model' description to README
- wperf-common: update CLI usage text
- wperf: fix wrong check for CaseInsensitiveWStringComparision() causing warning to pop up
- wperf: add warning prefix for 'failed to query base address' message
- wperf: add check if process name discovered with PID (-p/--pid) is different to one deduced by wperf
- wperf: add FindImageNameByPID() function to retrieve image name (executable name) based on PID
- wperf: support PID specification by the user from CLI
- wperf: implement -p/--pid in user_request
- wperf-common: add CheckerFuncIsPositiveInteger checker for -p/--pid
- wperf-common: minor typo / format fixes
- wperf: add -p / --pid command line parameter (to specify PID in sampling)
Testing
Docs render: https://gitlab.com/PrzemekWirkus/windowsperf/-/blob/devel_sample_by_pid/wperf/README.md#sampling-model
Unit testing
Regression testing
>pytest
===================================================== test session starts ======================================================
platform win32 -- Python 3.12.3, pytest-8.2.0, pluggy-1.5.0
rootdir: C:\Users\przemek\Workspace\5.4.0-sampling
configfile: pytest.ini
collected 1343 items / 9 skipped
wperf_cli_common_test.py ............. [ 0%]
wperf_cli_config_test.py .....ssssss.ss.. [ 2%]
wperf_cli_cpython_bench_test.py .s [ 2%]
wperf_cli_cpython_dep_record_spe_cli_test.py ............................................................................ [ 7%]
....................... [ 9%]
wperf_cli_cpython_dep_record_spe_test.py ......................... [ 11%]
wperf_cli_cpython_dep_record_test.py .................. [ 12%]
wperf_cli_cpython_dep_sample_test.py . [ 12%]
wperf_cli_custom_delim_test.py ............................. [ 15%]
wperf_cli_dmc_test.py . [ 15%]
wperf_cli_dmc_value_test.py . [ 15%]
wperf_cli_extra_events_test.py .... [ 15%]
wperf_cli_hammer_core_test.py .................. [ 16%]
wperf_cli_help_test.py .. [ 17%]
wperf_cli_info_str_test.py . [ 17%]
wperf_cli_json_validator_test.py ................. [ 18%]
wperf_cli_list_test.py ......... [ 19%]
wperf_cli_lock_test.py .. [ 19%]
wperf_cli_man_test.py ..........................................................................................ss [ 26%]
wperf_cli_man_ts_test.py ................................................................................................ [ 33%]
.............................................................. [ 37%]
wperf_cli_metrics_test.py ............. [ 38%]
wperf_cli_metrics_ts_test.py ............................................................................. [ 44%]
wperf_cli_padding_test.py ............................................................................................... [ 51%]
......................................................................................................................... [ 60%]
......................................................................................................................... [ 69%]
....... [ 70%]
wperf_cli_prettytable_test.py ..... [ 70%]
wperf_cli_record_test.py ................s [ 71%]
wperf_cli_sample_test.py .......... [ 72%]
wperf_cli_stat_multicore_test.py .... [ 72%]
wperf_cli_stat_test.py ......................................................................... [ 78%]
wperf_cli_stat_value_test.py ............................................................................................ [ 85%]
........................................................................................ [ 91%]
wperf_cli_test_test.py ........... [ 92%]
wperf_cli_timeline_test.py .............................................................. [ 97%]
wperf_cli_ustress_bench_test.py ...... [ 97%]
wperf_cli_ustress_dep_wperf_lib_timeline_test.py . [ 97%]
wperf_cli_ustress_dep_wperf_test.py ........... [ 98%]
wperf_cli_ustress_timeline_test.py .................. [ 99%]
wperf_cli_xperf_test.py s [ 99%]
wperf_lib_app_test.py . [ 99%]
wperf_lib_c_compat_test.py . [100%]
================================================ WindowsPerf Test Configuration ================================================
OS: Windows-11-10.0.26100-SP0, ARM64
CPU: 80 x ARMv8 (64-bit) Family 8 Model D0C Revision 301, Ampere(R)
Python: 3.12.3 (tags/v3.12.3:f6650f9, Apr 9 2024, 14:18:48) [MSC v.1938 64 bit (ARM64)]
Time: 08/10/2025, 12:56:31
wperf: 5.4.0.932689af+etw-app+spe+cmn
wperf-driver: 5.4.0.932689af+trace+spe+cmn
Configuration: --use=None
=================================================== short test summary info ====================================================
SKIPPED [1] wperf_cli_cmn_multi_mesh_test.py:48: unsupported configuration: no CMN-700 support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_cmninfo_test.py:54: unsupported configuration: no CMN support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_cmnlist_test.py:46: unsupported configuration: no CMN-700 support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_stat_cmn700_hammer_test.py:57: unsupported configuration: no CMN-700 support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_stat_cmn700_isolation_test.py:53: unsupported configuration: no CMN-700 support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_stat_cmn700_test.py:54: unsupported configuration: no CMN-700 support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_stat_cmn_isolation_test.py:61: unsupported configuration: no CMN support in `wperf`, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_stat_cmn_test.py:56: unsupported configuration: no CMN support in `wperf`, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_timeline_cmn700_test.py:53: unsupported configuration: no CMN-700 support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [5] wperf_cli_config_test.py:80: no CMN support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_config_test.py:106: no CMN support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [2] wperf_cli_config_test.py:137: no CMN support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_cpython_bench_test.py:80: skipping CPython rebuild procedure (already built), cleanup CPython build with 'cpython\PCbuild\clean.bat'
SKIPPED [1] wperf_cli_man_test.py:383: no CMN support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_man_test.py:416: no CMN support in HW, see cmn_device.version_name=CMN_FAMILY_UNKNOWN
SKIPPED [1] wperf_cli_record_test.py:156: this test is applicable only if `gpc_num` < `total_gpc_num`, now: gpc_num=6 and total_gpc_num=6
SKIPPED [1] wperf_cli_xperf_test.py:64: skipping XPERF test bench, enable it with `--enable-bench-xperf` command line options
======================================== 1330 passed, 22 skipped in 3697.94s (1:01:37) =========================================