Skip to content

Commit 017d222

Browse files
Fix issue where only part of a process name was being compared
The issue was that when a process was identified, it was only being compared to the first n characters of the -exclude and -process_name names, where n was the identified process name's length after any directory and .exe extension had been removed. e.g., using -exclude code.exe would also cause cod.exe to be excluded (through, not vice versa). See issue #172.
1 parent 3cc6971 commit 017d222

File tree

4 files changed

+74
-38
lines changed

4 files changed

+74
-38
lines changed

PresentMon/CommandLine.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2017,2019-2022 Intel Corporation
1+
// Copyright (C) 2017,2019-2023 Intel Corporation
22
// SPDX-License-Identifier: MIT
33

44
#include <generated/version.h>
@@ -244,7 +244,7 @@ bool ParseValue(char** argv, int argc, int* i, char const** value)
244244
return true;
245245
}
246246

247-
bool ParseValue(char** argv, int argc, int* i, std::vector<char const*>* value)
247+
bool ParseValue(char** argv, int argc, int* i, std::vector<std::string>* value)
248248
{
249249
char const* v = nullptr;
250250
if (!ParseValue(argv, argc, i, &v)) return false;
@@ -554,19 +554,19 @@ bool ParseCommandLine(int argc, char** argv)
554554
" output, and recording arguments.\n");
555555
}
556556

557-
// Prune any directory and ".exe" off of the provided process names. This
558-
// is primarily because the ProcessStart event typically has a full path
559-
// including "\\Device\\..." and ProcessStop event sometimes is missing
560-
// part of the extension.
557+
// Convert the provided process names into a canonical form used for comparison.
558+
// The comparison is not case-sensitive, and does not include any directory nor
559+
// extension.
560+
//
561+
// This is because the different paths for obtaining process information return
562+
// different image name strings. e.g., the ProcessStart event typically has a
563+
// full path including "\\Device\\..." and ProcessStop event sometimes is
564+
// missing part of the extension.
561565
for (auto& name : args->mTargetProcessNames) {
562-
auto pr = GetProcessNameComparisonRange(name, strlen(name));
563-
name += pr.first;
564-
((char*) name)[pr.second] = '\0';
566+
CanonicalizeProcessName(&name);
565567
}
566568
for (auto& name : args->mExcludeProcessNames) {
567-
auto pr = GetProcessNameComparisonRange(name, strlen(name));
568-
name += pr.first;
569-
((char*) name)[pr.second] = '\0';
569+
CanonicalizeProcessName(&name);
570570
}
571571

572572
return true;

PresentMon/OutputThread.cpp

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019-2022 Intel Corporation
1+
// Copyright (C) 2019-2023 Intel Corporation
22
// SPDX-License-Identifier: MIT
33

44
#include "PresentMon.hpp"
@@ -91,40 +91,35 @@ static void UpdateRecordingToggles(size_t nextIndex)
9191
static std::unordered_map<uint32_t, ProcessInfo> gProcesses;
9292
static uint32_t gTargetProcessCount = 0;
9393

94-
std::pair<size_t, size_t> GetProcessNameComparisonRange(char const* name, size_t length)
94+
// Removes any directory and extension, and converts the remaining name to
95+
// lower case.
96+
void CanonicalizeProcessName(std::string* name)
9597
{
96-
std::pair<size_t, size_t> pr(0, length);
97-
98-
if (pr.second >= 4 && _stricmp(name + pr.second - 4, ".exe") == 0) {
99-
pr.second -= 4;
100-
}
101-
for (size_t i = pr.second; i--; ) {
102-
if (name[i] == '/' || name[i] == '\\') {
103-
pr.first = i + 1;
104-
break;
105-
}
98+
size_t i = name->find_last_of("./\\");
99+
if (i != std::string::npos && (*name)[i] == '.') {
100+
name->resize(i);
101+
i = name->find_last_of("/\\");
106102
}
107103

108-
pr.second = pr.second - pr.first;
109-
return pr;
104+
*name = name->substr(i + 1);
105+
106+
std::transform(name->begin(), name->end(), name->begin(),
107+
[](unsigned char c) { return (unsigned char) ::tolower((int) c); });
110108
}
111109

112110
static bool IsTargetProcess(uint32_t processId, std::string const& processName)
113111
{
114112
auto const& args = GetCommandLineArgs();
115113

116-
char const* compareName = nullptr;
117-
size_t compareLength = 0;
114+
std::string compareName;
118115
if (args.mExcludeProcessNames.size() + args.mTargetProcessNames.size() > 0) {
119-
compareName = processName.c_str();
120-
auto pr = GetProcessNameComparisonRange(compareName, processName.size());
121-
compareName += pr.first;
122-
compareLength = pr.second;
116+
compareName = processName;
117+
CanonicalizeProcessName(&compareName);
123118
}
124119

125120
// -exclude
126121
for (auto excludeProcessName : args.mExcludeProcessNames) {
127-
if (_strnicmp(excludeProcessName, compareName, compareLength) == 0) {
122+
if (excludeProcessName == compareName) {
128123
return false;
129124
}
130125
}
@@ -141,7 +136,7 @@ static bool IsTargetProcess(uint32_t processId, std::string const& processName)
141136

142137
// -process_name
143138
for (auto targetProcessName : args.mTargetProcessNames) {
144-
if (_strnicmp(targetProcessName, compareName, compareLength) == 0) {
139+
if (targetProcessName == compareName) {
145140
return true;
146141
}
147142
}

PresentMon/PresentMon.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2017,2019-2022 Intel Corporation
1+
// Copyright (C) 2017,2019-2023 Intel Corporation
22
// SPDX-License-Identifier: MIT
33

44
#pragma once
@@ -42,8 +42,8 @@ enum class ConsoleOutput {
4242
};
4343

4444
struct CommandLineArgs {
45-
std::vector<const char*> mTargetProcessNames;
46-
std::vector<const char*> mExcludeProcessNames;
45+
std::vector<std::string> mTargetProcessNames;
46+
std::vector<std::string> mExcludeProcessNames;
4747
const char *mOutputCsvFileName;
4848
const char *mEtlFileName;
4949
const char *mSessionName;
@@ -137,7 +137,7 @@ void ExitMainThread();
137137
void StartOutputThread();
138138
void StopOutputThread();
139139
void SetOutputRecordingState(bool record);
140-
std::pair<size_t, size_t> GetProcessNameComparisonRange(char const* name, size_t length);
140+
void CanonicalizeProcessName(std::string* path);
141141

142142
// Privilege.cpp:
143143
bool InPerfLogUsersGroup();

Tools/run_tests.cmd

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ if %do_realtime_tests% EQU 1 (
152152

153153
call :realtime_multicsv_test
154154

155+
call :realtime_exclude_test
156+
155157
echo.
156158
)
157159

@@ -380,3 +382,42 @@ exit /b 0
380382

381383
exit /b 0
382384

385+
:: -----------------------------------------------------------------------------
386+
:realtime_exclude_test
387+
call :start_target_app /width=320 /height=240
388+
if %errorlevel% NEQ 0 (
389+
echo error: realtime PresentBench tests cannot run with a process named PresentBench.exe already running
390+
set /a errorcount=%errorcount%+1
391+
exit /b 0
392+
)
393+
394+
set saw_excluded=0
395+
set saw_nonexcluded=0
396+
for /f "tokens=1 delims=," %%a in ('"%pmdir%\build\%test_config%\PresentMon-%version%-x64.exe" -exclude presentbench -output_stdout -timed 2 -terminate_after_timed 2^>NUL') do (
397+
if "%%a" EQU "PresentBench.exe" (
398+
set saw_excluded=1
399+
)
400+
)
401+
for /f "tokens=1 delims=," %%a in ('"%pmdir%\build\%test_config%\PresentMon-%version%-x64.exe" -exclude presentbench2 -output_stdout -timed 2 -terminate_after_timed 2^>NUL') do (
402+
if "%%a" EQU "PresentBench.exe" (
403+
set saw_nonexcluded=1
404+
)
405+
)
406+
407+
call :stop_target_app
408+
409+
if %saw_nonexcluded% EQU 0 (
410+
echo error: -exclude PresentBench2 did not record any presents
411+
set /a errorcount=%errorcount%+1
412+
exit /b 0
413+
)
414+
if %saw_excluded% EQU 1 (
415+
echo error: -exclude PresentBench recorded presents
416+
set /a errorcount=%errorcount%+1
417+
exit /b 0
418+
)
419+
420+
echo. -exclude presentbench
421+
echo. -exclude presentbench2
422+
exit /b 0
423+

0 commit comments

Comments
 (0)