From 033c0f2a947d4d70f8c13bbc648cf84bfe767969 Mon Sep 17 00:00:00 2001 From: "wtc@chromium.org" Date: Thu, 10 Mar 2011 22:11:40 +0000 Subject: Follow-up to r57247: when asserting that an event object is not signaled, pass important values (the return value of WaitForSingleObject and the error code) as function arguments so that they are available in crash dumps. Also cover the WaitForSingleObject call in ResetEventIfSignaled. Set event handles to 0xafafafaf after closing to detect use-after-free errors. R=eroman BUG=51950,75500 TEST=none Review URL: http://codereview.chromium.org/6627065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77710 0039d316-1c4b-4281-b951-d872f2087c98 --- net/socket/tcp_client_socket_win.cc | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'net/socket/tcp_client_socket_win.cc') diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc index 6027003..9e93bf0 100644 --- a/net/socket/tcp_client_socket_win.cc +++ b/net/socket/tcp_client_socket_win.cc @@ -27,21 +27,31 @@ namespace net { namespace { -// Assert that the (manual-reset) event object is not signaled. -void AssertEventNotSignaled(WSAEVENT hEvent) { - DWORD wait_rv = WaitForSingleObject(hEvent, 0); - if (wait_rv != WAIT_TIMEOUT) { +// Prevent the compiler from optimizing away the arguments so they appear +// nicely on the stack in crash dumps. +#pragma warning (disable: 4748) +#pragma optimize( "", off ) + +// Pass the important values as function arguments so that they are available +// in crash dumps. +void CheckEventWait(WSAEVENT hEvent, DWORD wait_rv, DWORD expected) { + if (wait_rv != expected) { DWORD err = ERROR_SUCCESS; if (wait_rv == WAIT_FAILED) err = GetLastError(); CHECK(false); // Crash. - // This LOG statement is unreachable since we have already crashed, but it - // should prevent the compiler from optimizing away the |wait_rv| and - // |err| variables so they appear nicely on the stack in crash dumps. - VLOG(1) << "wait_rv=" << wait_rv << ", err=" << err; } } +#pragma optimize( "", on ) +#pragma warning (default: 4748) + +// Assert that the (manual-reset) event object is not signaled. +void AssertEventNotSignaled(WSAEVENT hEvent) { + DWORD wait_rv = WaitForSingleObject(hEvent, 0); + CheckEventWait(hEvent, wait_rv, WAIT_TIMEOUT); +} + // If the (manual-reset) event object is signaled, resets it and returns true. // Otherwise, does nothing and returns false. Called after a Winsock function // succeeds synchronously @@ -55,7 +65,7 @@ bool ResetEventIfSignaled(WSAEVENT hEvent) { DWORD wait_rv = WaitForSingleObject(hEvent, 0); if (wait_rv == WAIT_TIMEOUT) return false; // The event object is not signaled. - CHECK_EQ(WAIT_OBJECT_0, wait_rv); + CheckEventWait(hEvent, wait_rv, WAIT_OBJECT_0); BOOL ok = WSAResetEvent(hEvent); CHECK(ok); return true; @@ -239,9 +249,9 @@ TCPClientSocketWin::Core::~Core() { write_watcher_.StopWatching(); WSACloseEvent(read_overlapped_.hEvent); - memset(&read_overlapped_, 0, sizeof(read_overlapped_)); + memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); WSACloseEvent(write_overlapped_.hEvent); - memset(&write_overlapped_, 0, sizeof(write_overlapped_)); + memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_)); } void TCPClientSocketWin::Core::WatchForRead() { -- cgit v1.1