-
Notifications
You must be signed in to change notification settings - Fork 263
Add std::source_location support when logging error information
#1185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add std::source_location support when logging error information
#1185
Conversation
…gly and I hate it right now
…Found and fixed a bug along the way
|
I have a sample program that combines cppwinrt and WIL to validate the logging output with and without these changes. Lines 22-45 are as follows: void ThrowWinrtHresult()
{
throw winrt::hresult_error(E_INVALIDARG);
}
void CheckWinrtHresult()
{
winrt::check_hresult(E_INVALIDARG);
}
void CheckWinrtWin32Error()
{
winrt::check_win32(ERROR_ACCESS_AUDIT_BY_POLICY);
}
void ThrowWILException()
{
THROW_HR(E_INVALIDARG);
}
void CheckWILException()
{
THROW_IF_FAILED(E_INVALIDARG);
}Lines 86-124 are as follows: try
{
OutputDebugString(L"----throw winrt::hresult_error()----\r\n");
ThrowWinrtHresult();
}
CATCH_LOG();
OutputDebugString(L"----\r\n\r\n");
try
{
OutputDebugString(L"----winrt::check_hresult()----\r\n");
CheckWinrtHresult();
}
CATCH_LOG();
OutputDebugString(L"----\r\n\r\n");
try
{
OutputDebugString(L"----winrt::check_win32()----\r\n");
CheckWinrtWin32Error();
}
CATCH_LOG();
OutputDebugString(L"----\r\n\r\n");
try
{
OutputDebugString(L"----THROW_HR----\r\n");
ThrowWILException();
}
CATCH_LOG();
OutputDebugString(L"----\r\n\r\n");
try
{
OutputDebugString(L"----THROW_IF_FAILED----\r\n");
CheckWILException();
}
CATCH_LOG();
OutputDebugString(L"----\r\n\r\n");C++17 outputC++20 outputThe code was the same in both cases. The only difference was changing the C++ language standard and recompiling. The notable difference is that previously there was no logging where the exception was thrown (e.g. line 29). Now there is logging both when it is thrown and when it is caught/logged. This will greatly improve the debugging experience. |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
@kennykerr unfortunately the build is failing because the agents do not have the v143 toolset installed The C++20 support in v142 is incomplete and the compiler crashes when |
Is it just a matter of upgrading the solution to target 143 instead? |
std::source_location support when logging error information
The error makes it sound like the build agent does not have it installed. I suspect that no code changes to this PR are needed to fix the toolset. Some sort of ADO "build agent configuration" change is needed instead. Once that happens it would probably be a good thing to update everything to VS2022, but that is scope creep beyond the minimum needed for this PR. |
|
Agreed - just trying to figure out what's needed - I'll poke around and see if I can get this upgraded separately. |
…ce-information-origination
kennykerr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than the check_hresult declaration needing the default (rather than the definition), this looks great. Ideally, we can eventually apply this to the projection itself and not just to explicit calls to check_hresult and exceptions, but I think this is a good start to get some experience with this new C++20 feature before applying it more broadly. Applying it more broadly is also really ugly as this parameter needs to be added to every single API call, which is gross.
Closes #1184
Why is this change being made?
This change is being made to (greatly!) improve the error logging for exceptions that originate in cppwinrt. This is especially directed at the cases where cppwinrt and WIL are interoperating. The extension point between them has the ability to forward the file name, line number, and function name across to be logged. They always pass null.
With C++20 and
std::source_locationspecifically that can change. It is possible to capture that information in a standards-compliant way and forward it along to be logged. The result is vastly improved WIL logging output.Briefly summarize what changed
Unfortunately this change is a bit ugly and requires macros. The reason for that is because
std::source_locationis new in C++20 and because it must be constructed by the code that is calling into cppwinrt headers. The support floor for cppwinrt is C++17 so this type needs to be behind an#ifdef. That is what leads to the macros (which evaluate to nothing for C++17).The second bit of ugliness is that the calling code must be what constructs the
std::source_location. Otherwise it will get the source information for cppwinrt itself which is not helpful. This is achieved with a default parameter for every method that can originate an error. The caller silently constructs it before the call so it has accurate source information. For cases where errors hop a few times this must be forwarded so it is not lost.Other miscellaneous changes include:
hresult_error::originatewill now callwinrt_throw_hesult_handlerif it is provided. Previouslythrow winrt::hresult_error(E_WHATEVER)would not log to WIL. Now it does.#pragma detect mismatchfor whetherstd::source_locationis being used, or not.How was this change tested?
A new test file was added to the C++20 test binary. This test ensures that the source information is accurate (and in fact caught a subtle bug when the test was being written!).