Index: base/win/scoped_handle.cc |
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc |
index ce944e43b9fe3fb30a7b699863efeb9ab0c8ee13..f37cc4bc2484be41cf80ed4f172a762cd5acb60a 100644 |
--- a/base/win/scoped_handle.cc |
+++ b/base/win/scoped_handle.cc |
@@ -228,20 +228,39 @@ void* GetHandleVerifier() { |
namespace base { |
namespace win { |
+// A common pattern in Chrome is to create a handle using an OS function, |
grt (UTC plus 2)
2015/09/10 01:36:49
this is possibly at the wrong layer. either Generi
|
+// store it in a ScopedHandle, and then call GetLastError(). With VC++ 2015 |
+// this can fail (crbug.com/528394) because the handle tracking code may |
+// allocate memory and that may zero out the LastError value. The |
+// PreserveLastError object is used to save and restore the LastError code so |
+// that this intuitive pattern works. |
+class PreserveLastError { |
+ public: |
+ PreserveLastError() : last_error_(GetLastError()) {} |
+ ~PreserveLastError() { SetLastError(last_error_); } |
+ |
+ private: |
+ unsigned last_error_; |
rvargas (doing something else)
2015/09/10 01:39:35
DWORD (or unsigned int)
brucedawson
2015/09/10 21:52:49
In the new code I went with 'auto'. Could also do
|
+ DISALLOW_COPY_AND_ASSIGN(PreserveLastError); |
+}; |
+ |
// Static. |
bool HandleTraits::CloseHandle(HANDLE handle) { |
+ PreserveLastError error_preserver; |
grt (UTC plus 2)
2015/09/10 01:36:49
isn't this the wrong thing here? the last-error-co
rvargas (doing something else)
2015/09/10 01:39:35
I don't think we need this anywhere else but on Se
brucedawson
2015/09/10 01:46:27
The bugs are hard to track and difficult to avoid.
brucedawson
2015/09/10 01:46:27
Having been bitten by this I felt compelled to pre
brucedawson
2015/09/10 21:52:49
CloseHandle failures only cause failures under the
|
return ActiveVerifier::Get()->CloseHandle(handle); |
} |
// Static. |
void VerifierTraits::StartTracking(HANDLE handle, const void* owner, |
const void* pc1, const void* pc2) { |
+ PreserveLastError error_preserver; |
return ActiveVerifier::Get()->StartTracking(handle, owner, pc1, pc2); |
} |
// Static. |
void VerifierTraits::StopTracking(HANDLE handle, const void* owner, |
const void* pc1, const void* pc2) { |
+ PreserveLastError error_preserver; |
return ActiveVerifier::Get()->StopTracking(handle, owner, pc1, pc2); |
} |
@@ -250,6 +269,7 @@ void DisableHandleVerifier() { |
} |
void OnHandleBeingClosed(HANDLE handle) { |
+ PreserveLastError error_preserver; |
grt (UTC plus 2)
2015/09/10 01:36:49
this function is called before the handle is close
brucedawson
2015/09/10 21:52:49
I agree that the error codes should not be preserv
|
return ActiveVerifier::Get()->OnHandleBeingClosed(handle); |
} |