Fix tests when running on Win10

The Windows 10 loader starts a few extra threads before main(). In a few
of the test cases, the tests were relying on thread ordering (generally,
the test thread being at index #1). Instead, use other signals to find
the correct thread to verify.

R=mark@chromium.org

Change-Id: Icb1f5a8fdf3a0ea6d82ab65960dbcb650965f269
Reviewed-on: https://chromium-review.googlesource.com/407073
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Scott Graham 2016-11-03 11:35:19 -07:00
parent c4cdec3d72
commit b47bf6c250
3 changed files with 36 additions and 12 deletions

View File

@ -46,13 +46,13 @@ bool CrashAndDumpTarget(const CrashpadClient& client, HANDLE process) {
return false; return false;
} }
int thread_count = 0;
do { do {
if (te32.th32OwnerProcessID == target_pid) { if (te32.th32OwnerProcessID == target_pid) {
thread_count++; // We set the thread priority of "Thread1" to a non-default value before
if (thread_count == 2) { // going to sleep. Dump and blame this thread. For an explanation of
// Nominate this lucky thread as our blamee, and dump it. This will be // "9", see
// "Thread1" in the child. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms685100.aspx.
if (te32.tpBasePri == 9) {
ScopedKernelHANDLE thread( ScopedKernelHANDLE thread(
OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID)); OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID));
if (!client.DumpAndCrashTargetProcess( if (!client.DumpAndCrashTargetProcess(

View File

@ -22,6 +22,9 @@
#include "client/crashpad_info.h" #include "client/crashpad_info.h"
DWORD WINAPI Thread1(LPVOID dummy) { DWORD WINAPI Thread1(LPVOID dummy) {
// We set the thread priority up by one as a hacky way to signal to the other
// test program that this is the thread we want to dump.
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
Sleep(INFINITE); Sleep(INFINITE);
return 0; return 0;
} }

View File

@ -185,6 +185,14 @@ class CdbRun(object):
global g_had_failures global g_had_failures
g_had_failures = True g_had_failures = True
def Find(self, pattern, re_flags=0):
match_obj = re.search(pattern, self.out, re_flags)
if match_obj:
# Matched. Consume up to end of match.
self.out = self.out[match_obj.end(0):]
return match_obj
return None
def RunTests(cdb_path, def RunTests(cdb_path,
dump_path, dump_path,
@ -267,9 +275,15 @@ def RunTests(cdb_path,
r'FreeOwnStackAndBreak.*\nquit:', r'FreeOwnStackAndBreak.*\nquit:',
'at correct location, no additional stack entries') 'at correct location, no additional stack entries')
# Switch to the other thread after jumping to the exception, and examine # Dump memory pointed to be EDI on the background suspended thread. We don't
# memory. # know the index of the thread because the system may have started other
out = CdbRun(cdb_path, dump_path, '.ecxr; ~1s; db /c14 edi') # threads, so first do a run to extract the thread index that's suspended, and
# then another run to dump the data pointed to by EDI for that thread.
out = CdbRun(cdb_path, dump_path, '.ecxr;~')
match_obj = out.Find(r'(\d+)\s+Id: [0-9a-f.]+ Suspend: 1 Teb:')
if match_obj:
thread = match_obj.group(1)
out = CdbRun(cdb_path, dump_path, '.ecxr;~' + thread + 's;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', 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') 'data pointed to by registers captured')
@ -330,10 +344,17 @@ def RunTests(cdb_path,
'other program dump exception code') 'other program dump exception code')
out.Check('!Sleep', 'other program reasonable location') out.Check('!Sleep', 'other program reasonable location')
out.Check('hanging_program!Thread1', 'other program dump right thread') out.Check('hanging_program!Thread1', 'other program dump right thread')
out.Check('\. 1 Id.*Suspend: 0 ', count = 0
'other program exception on correct thread and correct suspend') while True:
out.Check(' 4 Id.*Suspend: 0 ', match_obj = out.Find(r'Id.*Suspend: (\d+) ')
'other program injection thread correct suspend') if match_obj:
if match_obj.group(1) != '0':
out.Check(r'FAILED', 'all suspend counts should be 0')
else:
count += 1
else:
break
assert count > 2
out = CdbRun(cdb_path, other_program_no_exception_path, '.ecxr;k') out = CdbRun(cdb_path, other_program_no_exception_path, '.ecxr;k')
out.Check('Unknown exception - code 0cca11ed', out.Check('Unknown exception - code 0cca11ed',