win: Better setting of DI for register capture test

The previous approach was nice for its simplicity, but unfortunately
didn't work when the compiler decided to do some of its confounded
"optimization".

R=mark@chromium.org
BUG=crashpad:86, chromium:571144

Review URL: https://codereview.chromium.org/1563273004 .
This commit is contained in:
Scott Graham 2016-01-10 13:32:20 -08:00
parent 5af9c42638
commit 417097b91f
2 changed files with 38 additions and 6 deletions

View File

@ -26,6 +26,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "client/crashpad_client.h"
#include "util/win/critical_section_with_debug_info.h"
#include "util/win/get_function.h"
@ -90,6 +91,39 @@ void AllocateMemoryOfVariousProtections() {
}
}
DWORD WINAPI NullThreadProc(void* param) {
return 0;
}
// Creates a suspended background thread, and sets EDI/RDI to point at
// g_test_memory so we can confirm it's available in the minidump.
bool CreateThreadWithRegisterPointingToTestMemory() {
HANDLE thread = CreateThread(
nullptr, 0, &NullThreadProc, nullptr, CREATE_SUSPENDED, nullptr);
if (!thread) {
PLOG(ERROR) << "CreateThread";
return false;
}
CONTEXT context = {0};
context.ContextFlags = CONTEXT_INTEGER;
if (!GetThreadContext(thread, &context)) {
PLOG(ERROR) << "GetThreadContext";
return false;
}
#if defined(ARCH_CPU_X86_64)
context.Rdi = reinterpret_cast<DWORD64>(g_test_memory);
#elif defined(ARCH_CPU_X86)
context.Edi = reinterpret_cast<DWORD>(g_test_memory);
#endif
if (!SetThreadContext(thread, &context)) {
PLOG(ERROR) << "SetThreadContext";
return false;
}
return true;
}
void SomeCrashyFunction() {
// SetLastError and NTSTATUS so that we have something to view in !gle in
// windbg. RtlNtStatusToDosError() stores STATUS_NO_SUCH_FILE into the
@ -97,11 +131,6 @@ void SomeCrashyFunction() {
// ERROR_FILE_NOT_FOUND for GetLastError().
SetLastError(RtlNtStatusToDosError(STATUS_NO_SUCH_FILE));
// Set a register to point at some memory we can test to confirm it makes it
// into the minidump. We use __movsb as a way to set SI/DI without needing an
// external .asm file.
__movsb(g_test_memory, g_test_memory, 0);
volatile int* foo = reinterpret_cast<volatile int*>(7);
*foo = 42;
}
@ -142,6 +171,9 @@ int CrashyMain(int argc, wchar_t* argv[]) {
EnterCriticalSection(&g_test_critical_section);
}
if (!CreateThreadWithRegisterPointingToTestMemory())
return EXIT_FAILURE;
SomeCrashyFunction();
return EXIT_SUCCESS;

View File

@ -247,7 +247,7 @@ def RunTests(cdb_path,
r'FreeOwnStackAndBreak.*\nquit:',
'at correct location, no additional stack entries')
out = CdbRun(cdb_path, dump_path, '.ecxr; db /c14 edi')
out = CdbRun(cdb_path, dump_path, '.ecxr; ~1s; db /c14 edi')
out.Check(r'63 62 61 60 5f 5e 5d 5c-5b 5a 59 58 57 56 55 54 53 52 51 50',
'data pointed to by registers captured')