Skip to content

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


⚠️ For multiple same processes running WindowsPerf has no method to distinguish which process exactly is the source of samples as we compare PC values against base image address. See below how two 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 for record 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)

  1. Spawn new cpython process (this process will "hop" between cores):
>cpython\PCbuild\arm64\python_d.exe -c 10**100**100
  1. Check PID (10156) of new process with Task Manager:

Screenshot_2025-10-08_132520_2

  1. 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
  1. 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

image

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) =========================================
Edited by Przemyslaw Wirkus

Merge request reports

Loading