Skip to content

Commit 356fc9e

Browse files
authored
[ETW] Fix infinite loop in ETWProvider::close (#3827)
1 parent 25b9adc commit 356fc9e

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Increment the:
1515

1616
## [Unreleased]
1717

18+
* [ETW] Fix infinite loop in ETWProvider::close
19+
[#3827](https://github.com/open-telemetry/opentelemetry-cpp/pull/3827)
20+
1821
* [CONFIGURATION] File configuration - remove zipkin
1922
[#3804](https://github.com/open-telemetry/opentelemetry-cpp/pull/3804)
2023

exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ class ETWProvider
210210
auto &data = it->second;
211211
unsigned long result = STATUS_OK;
212212

213+
if (data.refCount == 0)
214+
{
215+
return STATUS_ERROR;
216+
}
217+
213218
data.refCount--;
214219
if (data.refCount == 0)
215220
{
@@ -232,6 +237,7 @@ class ETWProvider
232237
}
233238
return result;
234239
}
240+
++it;
235241
}
236242
return STATUS_ERROR;
237243
}

exporters/etw/test/etw_provider_test.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,36 @@ TEST(ETWProvider, CheckCloseSuccess)
6161
ASSERT_FALSE(etw.is_registered(providerName));
6262
}
6363

64+
TEST(ETWProvider, CheckCloseInfiniteLoop)
65+
{
66+
std::string providerName1 = "Provider1";
67+
std::string providerName2 = "Provider2";
68+
69+
static ETWProvider etw;
70+
auto handle1 = etw.open(providerName1.c_str());
71+
auto handle2 = etw.open(providerName2.c_str());
72+
73+
// This should not hang
74+
auto result2 = etw.close(handle2);
75+
ASSERT_EQ(result2, etw.STATUS_OK);
76+
ASSERT_FALSE(etw.is_registered(providerName2));
77+
78+
auto result1 = etw.close(handle1);
79+
ASSERT_EQ(result1, etw.STATUS_OK);
80+
ASSERT_FALSE(etw.is_registered(providerName1));
81+
}
82+
83+
TEST(ETWProvider, CheckCloseRefCountUnderflow)
84+
{
85+
std::string providerName = "OpenTelemetry-ETW-Provider-Underflow";
86+
static ETWProvider etw;
87+
auto handle = etw.open(providerName.c_str());
88+
auto result = etw.close(handle);
89+
ASSERT_EQ(result, etw.STATUS_OK);
90+
91+
// Subsequent close should fail
92+
result = etw.close(handle);
93+
ASSERT_EQ(result, etw.STATUS_ERROR);
94+
}
95+
6496
#endif

0 commit comments

Comments
 (0)