mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
win: Don’t appear to be a client connecting in end_to_end_test.py
end_to_end_test.py was producing these error messages 6 times (32-bit x86) and 7 times (x86_64) per run: [pid:tid:yyyymmdd,hhmmss.mmm:ERROR file_io.cc:89] ReadExactly: expected 36, observed 0 These messages were being produced by crashpad_handler, in the LoggingReadFileExactly() call in ExceptionHandlerServer::ServiceClientConnection(). sizeof(ClientToServerMessage) is 36. crashpad_handler believed that a client was connecting, but the client sent no data. This was tracked down to the use of os.path.exists() in end_to_end_test.py to wait for crashpad_handler’s named pipe to be created. Checking named pipe existence in this way appeared to be a client connecting to the the pipe server in crashpad_handler, although of course no real client was connecting and no message was forthcoming. I found that running “dir” on the named pipe’s path produced the same result. Using WaitNamedPipe() is an alternative that can be used to signal when the named pipe’s path exists. Furthermore, it tests more than mere creation, it indicates that the pipe server has become ready to service clients. That’s not necessary in this case as proper clients already need to deal with this on their own, but checking it in end_to_end_test.py should be harmless. Test: end_to_end_test.py Change-Id: Ida29a3d2325368f58930cdf8fb053449f621ea52 Reviewed-on: https://chromium-review.googlesource.com/703276 Reviewed-by: Leonard Mosescu <mosescu@chromium.org>
This commit is contained in:
parent
31df2acb12
commit
93c88d87f0
@ -16,6 +16,7 @@
|
||||
|
||||
import os
|
||||
import platform
|
||||
import pywintypes
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
@ -23,6 +24,8 @@ import sys
|
||||
import tempfile
|
||||
import time
|
||||
import win32con
|
||||
import win32pipe
|
||||
import winerror
|
||||
|
||||
|
||||
g_temp_dirs = []
|
||||
@ -81,6 +84,28 @@ def GetCdbPath():
|
||||
return None
|
||||
|
||||
|
||||
def NamedPipeExistsAndReady(pipe_name):
|
||||
"""Returns False if pipe_name does not exist. If pipe_name does exist, blocks
|
||||
until the pipe is ready to service clients, and then returns True.
|
||||
|
||||
This is used as a drop-in replacement for os.path.exists() and os.access() to
|
||||
test for the pipe's existence. Both of those calls tickle the pipe in a way
|
||||
that appears to the server to be a client connecting, triggering error
|
||||
messages when no data is received.
|
||||
|
||||
Although this function only needs to test pipe existence (waiting for
|
||||
CreateNamedPipe()), it actually winds up testing pipe readiness
|
||||
(waiting for ConnectNamedPipe()). This is unnecessary but harmless.
|
||||
"""
|
||||
try:
|
||||
win32pipe.WaitNamedPipe(pipe_name, win32pipe.NMPWAIT_WAIT_FOREVER)
|
||||
except pywintypes.error, e:
|
||||
if e[0] == winerror.ERROR_FILE_NOT_FOUND:
|
||||
return False
|
||||
raise
|
||||
return True
|
||||
|
||||
|
||||
def GetDumpFromProgram(
|
||||
out_dir, pipe_name, executable_name, expect_exit_code, *args):
|
||||
"""Initialize a crash database, and run |executable_name| connecting to a
|
||||
@ -108,20 +133,20 @@ def GetDumpFromProgram(
|
||||
|
||||
# Wait until the server is ready.
|
||||
printed = False
|
||||
while not os.path.exists(pipe_name):
|
||||
while not NamedPipeExistsAndReady(pipe_name):
|
||||
if not printed:
|
||||
print 'Waiting for crashpad_handler to be ready...'
|
||||
printed = True
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.001)
|
||||
|
||||
exit_code = subprocess.call(
|
||||
[os.path.join(out_dir, executable_name), pipe_name] + list(args))
|
||||
command = [os.path.join(out_dir, executable_name), pipe_name] + list(args)
|
||||
else:
|
||||
exit_code = subprocess.call(
|
||||
[os.path.join(out_dir, executable_name),
|
||||
os.path.join(out_dir, 'crashpad_handler.com'),
|
||||
test_database] +
|
||||
list(args))
|
||||
command = ([os.path.join(out_dir, executable_name),
|
||||
os.path.join(out_dir, 'crashpad_handler.com'),
|
||||
test_database] +
|
||||
list(args))
|
||||
print 'Running %s' % os.path.basename(command[0])
|
||||
exit_code = subprocess.call(command)
|
||||
if exit_code != expect_exit_code:
|
||||
raise subprocess.CalledProcessError(exit_code, executable_name)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user