mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 18:43:54 -06:00
Start investigating an UIA object leak
This commit is contained in:
parent
224ac9de47
commit
62312a8943
35
README.md
35
README.md
@ -1,3 +1,38 @@
|
||||
# LMAO
|
||||
|
||||
`NonDelegatingAddRef` in `base.h` line 7576.
|
||||
|
||||
```cpp
|
||||
{
|
||||
std::string trace;
|
||||
|
||||
const auto process = GetCurrentProcess();
|
||||
SymInitialize(process, NULL, TRUE);
|
||||
|
||||
void* stack[100];
|
||||
const auto frames = CaptureStackBackTrace(0, 100, stack, NULL);
|
||||
|
||||
const auto symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
|
||||
symbol->MaxNameLen = 255;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
|
||||
for (int i = 0; i < frames; i++)
|
||||
{
|
||||
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
|
||||
trace.append(symbol->Name);
|
||||
trace.append("\n");
|
||||
}
|
||||
|
||||
free(symbol);
|
||||
|
||||
if (trace.find("XamlUiaTextRange") != std::string::npos)
|
||||
{
|
||||
trace.append("\n");
|
||||
OutputDebugStringA(trace.c_str());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
[](https://dev.azure.com/shine-oss/terminal/_build/latest?definitionId=1&branchName=main)
|
||||
|
||||
@ -616,7 +616,7 @@ namespace
|
||||
auto safeArray{ SafeArrayCreateVector(VT_BSTR, 0, 1) };
|
||||
LONG index{ 0 };
|
||||
auto indexBstr{ wil::make_bstr(indexString.c_str()) };
|
||||
(void)SafeArrayPutElement(safeArray, &index, indexBstr.release());
|
||||
(void)SafeArrayPutElement(safeArray, &index, indexBstr.get());
|
||||
*ppData = safeArray;
|
||||
return S_OK;
|
||||
}
|
||||
@ -669,7 +669,7 @@ namespace
|
||||
auto safeArray{ SafeArrayCreateVector(VT_BSTR, 0, 1) };
|
||||
LONG index{ 0 };
|
||||
auto dataNameBstr{ wil::make_bstr(L"index") };
|
||||
(void)SafeArrayPutElement(safeArray, &index, dataNameBstr.release());
|
||||
(void)SafeArrayPutElement(safeArray, &index, dataNameBstr.get());
|
||||
*names = safeArray;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -189,8 +189,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parent.as<IAutomationPeerProtected>().ProviderFromPeer(parent));
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
return winrt::make<XamlUiaTextRange>(returnVal, parent.as<IAutomationPeerProtected>().ProviderFromPeer(parent));
|
||||
};
|
||||
|
||||
// Method Description:
|
||||
|
||||
@ -29,14 +29,28 @@ namespace XamlAutomation
|
||||
using winrt::Windows::UI::Xaml::Automation::Text::TextUnit;
|
||||
}
|
||||
|
||||
static std::atomic<int64_t> refCount_XamlUiaTextRange;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
XamlUiaTextRange::XamlUiaTextRange(::ITextRangeProvider* uiaProvider, Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider) :
|
||||
_parentProvider{ std::move(parentProvider) }
|
||||
{
|
||||
_uiaProvider.attach(uiaProvider);
|
||||
refCount_XamlUiaTextRange.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
XamlUiaTextRange::~XamlUiaTextRange()
|
||||
{
|
||||
_uiaProvider.reset();
|
||||
refCount_XamlUiaTextRange.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider XamlUiaTextRange::Clone() const
|
||||
{
|
||||
UIA::ITextRangeProvider* pReturn;
|
||||
THROW_IF_FAILED(_uiaProvider->Clone(&pReturn));
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(pReturn, _parentProvider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
return winrt::make<XamlUiaTextRange>(pReturn, _parentProvider);
|
||||
}
|
||||
|
||||
bool XamlUiaTextRange::Compare(XamlAutomation::ITextRangeProvider pRange) const
|
||||
@ -85,8 +99,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
THROW_IF_FAILED(_uiaProvider->FindText(queryText.get(), searchBackward, ignoreCase, &pReturn));
|
||||
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(pReturn, _parentProvider);
|
||||
return *xutr;
|
||||
return winrt::make<XamlUiaTextRange>(pReturn, _parentProvider);
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable XamlUiaTextRange::GetAttributeValue(int32_t textAttributeId) const
|
||||
@ -175,10 +188,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
winrt::com_array<double> result{ vec };
|
||||
returnValue = std::move(result);
|
||||
|
||||
THROW_IF_FAILED(SafeArrayUnaccessData(pReturnVal));
|
||||
THROW_IF_FAILED(SafeArrayDestroy(pReturnVal));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
XamlAutomation::IRawElementProviderSimple XamlUiaTextRange::GetEnclosingElement()
|
||||
|
||||
@ -30,11 +30,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
public winrt::implements<XamlUiaTextRange, Windows::UI::Xaml::Automation::Provider::ITextRangeProvider>
|
||||
{
|
||||
public:
|
||||
XamlUiaTextRange(::ITextRangeProvider* uiaProvider, Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider) :
|
||||
_parentProvider{ parentProvider }
|
||||
{
|
||||
_uiaProvider.attach(uiaProvider);
|
||||
}
|
||||
XamlUiaTextRange(::ITextRangeProvider* uiaProvider, Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider);
|
||||
~XamlUiaTextRange();
|
||||
|
||||
#pragma region ITextRangeProvider
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider Clone() const;
|
||||
|
||||
@ -322,9 +322,11 @@ std::vector<wil::com_ptr<T>> SafeArrayToOwningVector(SAFEARRAY* safeArray)
|
||||
std::vector<wil::com_ptr<T>> result{ gsl::narrow<std::size_t>(count) };
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
result[i].attach(pVals[i]);
|
||||
result[i] = pVals[i];
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(SafeArrayUnaccessData(safeArray));
|
||||
THROW_IF_FAILED(SafeArrayDestroy(safeArray));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ namespace
|
||||
auto safeArray{ SafeArrayCreateVector(VT_BSTR, 0, 1) };
|
||||
LONG index{ 0 };
|
||||
auto indexBstr{ wil::make_bstr(indexString.c_str()) };
|
||||
(void)SafeArrayPutElement(safeArray, &index, indexBstr.release());
|
||||
(void)SafeArrayPutElement(safeArray, &index, indexBstr.get());
|
||||
*ppData = safeArray;
|
||||
return S_OK;
|
||||
}
|
||||
@ -179,7 +179,7 @@ namespace
|
||||
auto safeArray{ SafeArrayCreateVector(VT_BSTR, 0, 1) };
|
||||
LONG index{ 0 };
|
||||
auto dataNameBstr{ wil::make_bstr(L"index") };
|
||||
(void)SafeArrayPutElement(safeArray, &index, dataNameBstr.release());
|
||||
(void)SafeArrayPutElement(safeArray, &index, dataNameBstr.get());
|
||||
*names = safeArray;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -234,7 +234,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
|
||||
UiaTracing::TextProvider::GetSelection(*this, *range.Get());
|
||||
|
||||
LONG currentIndex = 0;
|
||||
hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range.Detach());
|
||||
hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range.Get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
@ -278,7 +278,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
|
||||
UiaTracing::TextProvider::GetVisibleRanges(*this, *range.Get());
|
||||
|
||||
LONG currentIndex = 0;
|
||||
hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range.Detach());
|
||||
hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range.Get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
@ -328,6 +328,11 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::get_DocumentRange(_COM_Outptr_result_m
|
||||
RETURN_IF_FAILED(utr->ExpandToEnclosingUnit(TextUnit::TextUnit_Document));
|
||||
RETURN_IF_FAILED(utr.CopyTo(ppRetVal));
|
||||
UiaTracing::TextProvider::get_DocumentRange(*this, *utr.Get());
|
||||
|
||||
utr.Reset();
|
||||
|
||||
assert((*ppRetVal)->AddRef() == 2);
|
||||
assert((*ppRetVal)->Release() == 1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -134,6 +134,16 @@ try
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
static std::atomic<int64_t> refCount_UiaTextRangeBase;
|
||||
|
||||
Microsoft::Console::Types::UiaTextRangeBase::UiaTextRangeBase() {
|
||||
refCount_UiaTextRangeBase.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
Microsoft::Console::Types::UiaTextRangeBase::~UiaTextRangeBase() {
|
||||
refCount_UiaTextRangeBase.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
til::point UiaTextRangeBase::GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept
|
||||
{
|
||||
switch (endpoint)
|
||||
|
||||
@ -70,7 +70,31 @@ namespace Microsoft::Console::Types
|
||||
UiaTextRangeBase(UiaTextRangeBase&&) = delete;
|
||||
UiaTextRangeBase& operator=(const UiaTextRangeBase&) = delete;
|
||||
UiaTextRangeBase& operator=(UiaTextRangeBase&&) = delete;
|
||||
~UiaTextRangeBase() = default;
|
||||
|
||||
UiaTextRangeBase();
|
||||
~UiaTextRangeBase();
|
||||
|
||||
STDMETHOD_(ULONG, AddRef)()
|
||||
{
|
||||
return InternalAddRef();
|
||||
}
|
||||
|
||||
STDMETHOD_(ULONG, Release)()
|
||||
{
|
||||
ULONG ref = InternalRelease();
|
||||
if (ref == 0)
|
||||
{
|
||||
delete this;
|
||||
|
||||
auto modulePtr = ::Microsoft::WRL::GetModuleBase();
|
||||
if (modulePtr != nullptr)
|
||||
{
|
||||
modulePtr->DecrementObjectCount();
|
||||
}
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
til::point GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept;
|
||||
bool SetEndpoint(TextPatternRangeEndpoint endpoint, const til::point val) noexcept;
|
||||
@ -115,7 +139,6 @@ namespace Microsoft::Console::Types
|
||||
IFACEMETHODIMP GetChildren(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal) noexcept override;
|
||||
|
||||
protected:
|
||||
UiaTextRangeBase() = default;
|
||||
Render::IRenderData* _pData{ nullptr };
|
||||
|
||||
IRawElementProviderSimple* _pProvider{ nullptr };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user