-
Notifications
You must be signed in to change notification settings - Fork 154
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
Correctly handle kernel addresses in an x86 stack trace #241
Conversation
@microsoft-github-policy-service agree |
Hi there, I'm looking at the code in schema.hpp and your change does not work correctly in the case that the frames are 32bit. The following function also needs to be updated so that in the 64bit case only one value is pushed and in the 32bit case, the address is widened before it is pushed. inline std::vector<ULONG_PTR> schema::stack_trace() const
{
std::vector<ULONG_PTR> call_stack;
if (record_.ExtendedDataCount != 0) {
for (USHORT i = 0; i < record_.ExtendedDataCount; i++)
{
auto item = record_.ExtendedData[i];
if (item.ExtType == EVENT_HEADER_EXT_TYPE_STACK_TRACE64) {
auto stacktrace = reinterpret_cast<PEVENT_EXTENDED_ITEM_STACK_TRACE64>(item.DataPtr);
auto stack_length = (item.DataSize - sizeof(ULONG64)) / sizeof(ULONG64);
for (size_t j = 0; j < stack_length; j++)
{
call_stack.push_back(stacktrace->Address[j]);
}
}
else if (item.ExtType == EVENT_HEADER_EXT_TYPE_STACK_TRACE32) {
auto stacktrace = reinterpret_cast<PEVENT_EXTENDED_ITEM_STACK_TRACE32>(item.DataPtr);
auto stack_length = (item.DataSize - sizeof(ULONG64)) / sizeof(ULONG);
for (size_t j = 0; j < stack_length; j++)
{
call_stack.push_back(stacktrace->Address[j]);
}
}
}
}
return call_stack;
} |
Hi there, I was testing on an x64 system with an x86 (WoW64) application. The issue I encountered is that 8-byte long addresses (particularly kernel addresses due to the x64 system) are being truncated because of the ULONG_PTR vector type, which is 4 bytes long in an x86 application. When the header type is x64, the stack_length corresponds to the number of stack addresses, each being ULONG64 (8 bytes). In the loop, Regarding the function you mentioned, I believe it does not need to be updated, as the upcast to ULONG64 will happen automatically in the case of 4-byte addresses. My proposed solution is to change the vector to contain only 8-byte long values. This way, it can accommodate both 4-byte and 8-byte addresses without issues. Please let me know if I’m overlooking something. I’ve tested this approach, and it behaves as expected. |
Ok, I looked closer at the stack track function and the two types EVENT_EXTENDED_ITEM_STACK_TRACE32 and EVENT_EXTENDED_ITEM_STACK_TRACE64. You're right, the function is correct. Widening the vector should work. I'm not sure why we used ULONG_PTR here instead of ULONG or ULONG64. Looks good. Thanks for the PR! |
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.
Looks good! Thanks for the PR.
@mihai12p would you mind updating the version numbers and release notes in the .nuspec files so we can publish an updated version after merging your change? Thanks! |
Also, looks like we have a build failure - have you taken a look at the compilation error? |
I’ve fixed the build issues and updated the release notes as requested. I’m looking forward to more improvements as I’ll be using krabsetw extensively. Thank you! |
On an x86 application, ULONG_PTR is 4 bytes long, which means it cannot handle 8-byte long kernel addresses used by a 64-bit system.