|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r63184 - trunk/libs/system/src
From: bdawes_at_[hidden]
Date: 2010-06-21 08:25:41
Author: bemandawes
Date: 2010-06-21 08:25:40 EDT (Mon, 21 Jun 2010)
New Revision: 63184
URL: http://svn.boost.org/trac/boost/changeset/63184
Log:
Fix #3474, memory leak on exception. First reported by Chis Kohlhoff.
Added:
trunk/libs/system/src/local_free_on_destruction.hpp (contents, props changed)
Text files modified:
trunk/libs/system/src/error_code.cpp | 27 +++++++--------------------
1 files changed, 7 insertions(+), 20 deletions(-)
Modified: trunk/libs/system/src/error_code.cpp
==============================================================================
--- trunk/libs/system/src/error_code.cpp (original)
+++ trunk/libs/system/src/error_code.cpp 2010-06-21 08:25:40 EDT (Mon, 21 Jun 2010)
@@ -29,8 +29,9 @@
# if defined( BOOST_WINDOWS_API )
# include <windows.h>
+# include "local_free_on_destruction.hpp"
# ifndef ERROR_INCORRECT_SIZE
-# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
+# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
# endif
# endif
@@ -340,25 +341,11 @@
return generic_category().message( ev );
}
# else
-// TODO:
-
-//Some quick notes on the implementation (sorry for the noise if
-//someone has already mentioned them):
-//
-//- The ::LocalFree() usage isn't exception safe.
-//
-//See:
-//
-//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup>
-//
-//in the implementation of what() for an example.
-//
-//Cheers,
-//Chris
+
std::string system_error_category::message( int ev ) const
{
# ifndef BOOST_NO_ANSI_APIS
- LPVOID lpMsgBuf;
+ LPVOID lpMsgBuf = 0;
DWORD retval = ::FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
@@ -370,13 +357,13 @@
0,
NULL
);
+ detail::local_free_on_destruction lfod(lpMsgBuf);
if (retval == 0)
return std::string("Unknown error");
std::string str( static_cast<LPCSTR>(lpMsgBuf) );
- ::LocalFree( lpMsgBuf ); // free the buffer
# else // WinCE workaround
- LPVOID lpMsgBuf;
+ LPVOID lpMsgBuf = 0;
DWORD retval = ::FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
@@ -388,6 +375,7 @@
0,
NULL
);
+ detail::local_free_on_destruction lfod(lpMsgBuf);
if (retval == 0)
return std::string("Unknown error");
@@ -397,7 +385,6 @@
return std::string("Unknown error");
std::string str( narrow_buffer );
- ::LocalFree( lpMsgBuf ); // free the buffer
# endif
while ( str.size()
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
Added: trunk/libs/system/src/local_free_on_destruction.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/system/src/local_free_on_destruction.hpp 2010-06-21 08:25:40 EDT (Mon, 21 Jun 2010)
@@ -0,0 +1,40 @@
+// local_free_on_exit.hpp ------------------------------------------------------------//
+
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2010 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid
+// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out.
+
+#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
+#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
+
+namespace boost {
+namespace system {
+namespace detail {
+
+class local_free_on_destruction
+{
+public:
+ explicit local_free_on_destruction(void* p)
+ : p_(p) {}
+
+ ~local_free_on_destruction()
+ {
+ ::LocalFree(p_);
+ }
+
+private:
+ void* p_;
+ local_free_on_destruction(const local_free_on_destruction&); // = deleted
+ local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted
+};
+
+} // namespace detail
+} // namespace system
+} // namespace boost
+
+#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk