[asio] reported memory leaks when using MFC
Hi there, I have been spending some hour now on trackign down memory issues that are reported from MFC. In my client program I'm calling io_service::post( ... ) quite often and is seems to me that it allocates memory that is never been deallocated afterwards. Every call of post( ... ) will result in one memory leak. The allocation takes place in the file handler_alloc_helpers.hpp in line 39. Setting a breakpoint here shows that every post(...) call allocates some memory. The deallocation which is right below in the file is never called. Is this an known issue? Regards, Christian
Hi Christian, Christian Henning writes:
Hi there, I have been spending some hour now on trackign down memory issues that are reported from MFC.
In my client program I'm calling io_service::post( ... ) quite often and is seems to me that it allocates memory that is never been deallocated afterwards. Every call of post( ... ) will result in one memory leak.
The allocation takes place in the file handler_alloc_helpers.hpp in line 39. Setting a breakpoint here shows that every post(...) call allocates some memory. The deallocation which is right below in the file is never called.
That's very odd.
Is this an known issue?
Presumably this is a side effect of using MFC, because there is no leak in a standalone program. I don't use MFC, but do have access to it, so if you can send me a VC7.1 or VC8 solution that reproduces the issue I can take a quick look at it next week. Cheers, Chris
Hi Christopher, attached to this email is a server and a client
program. They are console program but they are using MFC's new
operator. It's assumed that boost is in c:\boost and the libs are in
c:\boost\stage\lib . If that is not correct on your machine you need
to change some settings.
It's OK to run them just a few seconds. MFC will report quite a few
memory leaks. Also Purify is reporting the leaks.
Let me know when you are having any issues.
Thanks,
Christian
On 10/18/06, Christopher Kohlhoff
Hi Christian,
Christian Henning writes:
Hi there, I have been spending some hour now on trackign down memory issues that are reported from MFC.
In my client program I'm calling io_service::post( ... ) quite often and is seems to me that it allocates memory that is never been deallocated afterwards. Every call of post( ... ) will result in one memory leak.
The allocation takes place in the file handler_alloc_helpers.hpp in line 39. Setting a breakpoint here shows that every post(...) call allocates some memory. The deallocation which is right below in the file is never called.
That's very odd.
Is this an known issue?
Presumably this is a side effect of using MFC, because there is no leak in a standalone program. I don't use MFC, but do have access to it, so if you can send me a VC7.1 or VC8 solution that reproduces the issue I can take a quick look at it next week.
Cheers, Chris
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Christian, Christian Henning wrote:
Hi Christopher, attached to this email is a server and a client program. They are console program but they are using MFC's new operator. It's assumed that boost is in c:\boost and the libs are in c:\boost\stage\lib . If that is not correct on your machine you need to change some settings.
It's OK to run them just a few seconds. MFC will report quite a few memory leaks. Also Purify is reporting the leaks.
Let me know when you are having any issues.
I haven't got to the point of reproducing it yet, but I do have a couple of questions: - Am I supposed to shut the processes down using Control-C? If so, there will almost certainly be leaks unless you have installed a "console control handler". - I notice that the '#define new DEBUG_NEW' line occurs after the inclusion of stdafx.h. Doesn't this mean it won't affect the uses of 'new' in the Boost.Asio header files? Sorry if these are stupid questions -- I don't know anything about the MFC leak tracking. Cheers, Chris
Hi Christopher, I think we can drop that issue for now. I cannot find
my MFC program that produced the leaks. I'm sure that if there is a
problem with MFC's leak detector it will come up again. Sorry for the
noise.
Christian
On 10/24/06, Christopher Kohlhoff
Hi Christian,
Christian Henning wrote:
Hi Christopher, attached to this email is a server and a client program. They are console program but they are using MFC's new operator. It's assumed that boost is in c:\boost and the libs are in c:\boost\stage\lib . If that is not correct on your machine you need to change some settings.
It's OK to run them just a few seconds. MFC will report quite a few memory leaks. Also Purify is reporting the leaks.
Let me know when you are having any issues.
I haven't got to the point of reproducing it yet, but I do have a couple of questions:
- Am I supposed to shut the processes down using Control-C? If so, there will almost certainly be leaks unless you have installed a "console control handler".
- I notice that the '#define new DEBUG_NEW' line occurs after the inclusion of stdafx.h. Doesn't this mean it won't affect the uses of 'new' in the Boost.Asio header files?
Sorry if these are stupid questions -- I don't know anything about the MFC leak tracking.
Cheers, Chris
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Christian, Christian Henning wrote:
Hi Christopher, I think we can drop that issue for now. I cannot find my MFC program that produced the leaks. I'm sure that if there is a problem with MFC's leak detector it will come up again. Sorry for the noise.
Well, I did manage to reproduce a leak report, and it always seemed to be related to an operation started in image_quality_source::do_write(). In that function you're sending data from a std::string local variable called "msg". This is wrong since you need to ensure that the data being sent is valid until the asynchronous write's callback handler is called, so perhaps it should be using a class data member instead of a local variable. Cheers, Chris
Hi Christopher, thanks for putting so much time into this issue. I
changed the code as you requested, namely I added a new members to my
connection class. But unfortunately nothing has changed. I still have
memory leaks reported. Did you do the change on your machine?
Christian
On 10/26/06, Christopher Kohlhoff
Hi Christian,
Christian Henning wrote:
Hi Christopher, I think we can drop that issue for now. I cannot find my MFC program that produced the leaks. I'm sure that if there is a problem with MFC's leak detector it will come up again. Sorry for the noise.
Well, I did manage to reproduce a leak report, and it always seemed to be related to an operation started in image_quality_source::do_write(). In that function you're sending data from a std::string local variable called "msg". This is wrong since you need to ensure that the data being sent is valid until the asynchronous write's callback handler is called, so perhaps it should be using a class data member instead of a local variable.
Cheers, Chris
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Christian, Christian Henning wrote:
Hi Christopher, thanks for putting so much time into this issue. I changed the code as you requested, namely I added a new members to my connection class.
I found another similar problem in image_source::do_write(). I've just implemented a feature for the next version that uses MSVC's iterator debugging to check the buffer validity. These program bugs show up as an assertion failure when this new "buffer debugging" feature is enabled.
But unfortunately nothing has changed. I still have memory leaks reported. Did you do the change on your machine?
I have now, and I found what I think is the cause of the leak.
Can you please try the following change to
asio/detail/win_iocp_io_service.hpp:
@@ -74,10 +74,11 @@
DWORD_PTR completion_key = 0;
#endif
LPOVERLAPPED overlapped = 0;
- ::GetQueuedCompletionStatus(iocp_.handle,
+ ::SetLastError(0);
+ BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle,
&bytes_transferred, &completion_key, &overlapped, 0);
DWORD last_error = ::GetLastError();
- if (last_error == WAIT_TIMEOUT)
+ if (!ok && overlapped == 0 && last_error == WAIT_TIMEOUT)
break;
if (overlapped)
static_cast
On 10/30/06, Christopher Kohlhoff
Hi Christian,
Christian Henning wrote:
Hi Christopher, thanks for putting so much time into this issue. I changed the code as you requested, namely I added a new members to my connection class.
I found another similar problem in image_source::do_write(). I've just implemented a feature for the next version that uses MSVC's iterator debugging to check the buffer validity. These program bugs show up as an assertion failure when this new "buffer debugging" feature is enabled.
I did make the change to all my source classes. A do_write operation now looks like this: void do_write() { int i = 9; std::ostringstream archive_stream; boost::archive::binary_oarchive archive( archive_stream ); archive & i; _outbound_data = archive_stream.str(); std::ostringstream header_stream; header_stream << std::setw( 8 ) << std::hex << _outbound_data.size(); _outbound_header = header_stream.str(); std::vectorboost::asio::const_buffer buffers; buffers.push_back(boost::asio::buffer( _outbound_header )); buffers.push_back(boost::asio::buffer( _outbound_data )); boost::asio::async_write( _socket , buffers , boost::bind( &image_quality_source::handle_write , this , boost::asio::placeholders::error )); } Both the _outbound_heaser and _outbound_data are members of the class.
But unfortunately nothing has changed. I still have memory leaks reported. Did you do the change on your machine?
I have now, and I found what I think is the cause of the leak. Can you please try the following change to asio/detail/win_iocp_io_service.hpp:
@@ -74,10 +74,11 @@ DWORD_PTR completion_key = 0; #endif LPOVERLAPPED overlapped = 0; - ::GetQueuedCompletionStatus(iocp_.handle, + ::SetLastError(0); + BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, &completion_key, &overlapped, 0); DWORD last_error = ::GetLastError(); - if (last_error == WAIT_TIMEOUT) + if (!ok && overlapped == 0 && last_error == WAIT_TIMEOUT) break; if (overlapped) static_cast
(overlapped)->destroy();
This is most likely offtopic, but how do apply that patch to a source file? Have never done that. Is there a program I should use? Thanks Christian
# chhenning@gmail.com / 2006-10-30 09:49:31 -0500:
On 10/30/06, Christopher Kohlhoff
wrote: Can you please try the following change to asio/detail/win_iocp_io_service.hpp:
@@ -74,10 +74,11 @@ DWORD_PTR completion_key = 0; #endif LPOVERLAPPED overlapped = 0; - ::GetQueuedCompletionStatus(iocp_.handle, + ::SetLastError(0); + BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, &completion_key, &overlapped, 0); DWORD last_error = ::GetLastError(); - if (last_error == WAIT_TIMEOUT) + if (!ok && overlapped == 0 && last_error == WAIT_TIMEOUT) break; if (overlapped) static_cast
(overlapped)->destroy(); This is most likely offtopic, but how do apply that patch to a source file? Have never done that. Is there a program I should use?
Diffs (or patches, these are synonyms) are applied with a program called "patch". The text above is only a fragment of a complete diff, and patch won't process it. Your best bet is to "apply" it by hand: replace the lines marked with "-" with those beginning with "+". The block displayed above begins on line 74 in asio/detail/win_iocp_io_service.hpp. -- How many Vietnam vets does it take to screw in a light bulb? You don't know, man. You don't KNOW. Cause you weren't THERE. http://bash.org/?255991
participants (3)
-
Christian Henning
-
Christopher Kohlhoff
-
Roman Neuhauser