Memory leaks in c++ api
Moderators: Lapo, Bax, MBagnati
Memory leaks in c++ api
Hi,
I have found some memory problems in current version of C++ api.
1) In several files there are allocations like this:
boost::shared_ptr<unsigned char> dataCompressed (new unsigned char[sizeCompressed]);
it should be fixed like this:
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
boost::shared_ptr<unsigned char> dataCompressed (new unsigned char[sizeCompressed], array_deleter<unsigned char>());
2) In the code below there is a memory leak. And a static array of string* produces memory leak at self at program shutdown.
void SFSErrorCodes::SetErrorMessage(long int code, string message)
{
errorsByCode[code] = new string(message);
}
3) The most awful thing I have found is boost::shared_ptr used in inproper way. It leads to memory leak of the whole C++ api system. Please, see the following example:
http://stackoverflow.com/questions/1826 ... shared-ptr
Please, excuse me, but I should say that this kind of bugs are totally unacceptable in such a great product as smartfox.
I have found some memory problems in current version of C++ api.
1) In several files there are allocations like this:
boost::shared_ptr<unsigned char> dataCompressed (new unsigned char[sizeCompressed]);
it should be fixed like this:
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
boost::shared_ptr<unsigned char> dataCompressed (new unsigned char[sizeCompressed], array_deleter<unsigned char>());
2) In the code below there is a memory leak. And a static array of string* produces memory leak at self at program shutdown.
void SFSErrorCodes::SetErrorMessage(long int code, string message)
{
errorsByCode[code] = new string(message);
}
3) The most awful thing I have found is boost::shared_ptr used in inproper way. It leads to memory leak of the whole C++ api system. Please, see the following example:
http://stackoverflow.com/questions/1826 ... shared-ptr
Please, excuse me, but I should say that this kind of bugs are totally unacceptable in such a great product as smartfox.
Re: Memory leaks in c++ api
Thanks for your report.
I will follow your suggestions to investigate the issue.
I will improve the memory management in the next API version.
Thanks for your help
I will follow your suggestions to investigate the issue.
I will improve the memory management in the next API version.
Thanks for your help
Re: Memory leaks in c++ api
Thank you, looking forward for the next version!
Re: Memory leaks in c++ api
Hi,
I updated smartfox libary to version 1.1.5 and found a crash in new DIspose() functionality.
Here is call stack:
Main thread:
> Strategyd.exe!boost::detail::timeout::remaining_milliseconds() Line 204 C++
Strategyd.exe!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 554 C++
Strategyd.exe!boost::thread::join_noexcept() Line 348 C++
Strategyd.exe!boost::thread::join() Line 757 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::~ThreadManager() Line 41 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::`scalar deleting destructor'(unsigned int) C++
Strategyd.exe!boost::checked_delete<Sfs2X::Core::ThreadManager>(Sfs2X::Core::ThreadManager * x) Line 34 C++
Strategyd.exe!boost::detail::sp_counted_impl_p<Sfs2X::Core::ThreadManager>::dispose() Line 78 C++
Strategyd.exe!boost::detail::sp_counted_base::release() Line 103 C++
Strategyd.exe!boost::detail::shared_count::~shared_count() Line 375 C++
Strategyd.exe!boost::shared_ptr<Sfs2X::Core::ThreadManager>::~shared_ptr<Sfs2X::Core::ThreadManager>() C++
Strategyd.exe!boost::shared_ptr<Sfs2X::Core::ThreadManager>::operator=(boost::shared_ptr<Sfs2X::Core::ThreadManager> && r) Line 595 C++
Strategyd.exe!Sfs2X::Bitswarm::BitSwarmClient::Dispose() Line 89 C++
Strategyd.exe!Sfs2X::SmartFox::Dispose() Line 95 C++
Strategyd.exe!FoxNetworkServiceImpl::StartAsClient(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & address, int port, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & zone, bool bFull) Line 238 C++
Strategyd.exe!GameClientInterface::ChangeServer(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & address, int port, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & zone) Line 58 C++
Strategyd.exe!GameClientPeer::ProcessNetworkPacket(boost::shared_ptr<google::protobuf::Message> packet) Line 168 C++
Strategyd.exe!NetworkPeer::DoProcessNetworkPacket(boost::shared_ptr<google::protobuf::Message> packet, __int64 packetNumber) Line 73 C++
Strategyd.exe!NetworkPeer::ProcessNetworkPacket(boost::shared_ptr<google::protobuf::Message> packet, __int64 packetNumber) Line 40 C++
Strategyd.exe!FoxNetworkServiceImpl::Update() Line 114 C++
Strategyd.exe!NetworkService::Update(float dt) Line 29 C++
Strategyd.exe!GameClientInterface::Update(float dt) Line 63 C++
Strategyd.exe!GameNetworkInterface::Update(float dt) Line 150 C++
Strategyd.exe!GameServices::Update(float dt) Line 100 C++
Strategyd.exe!Game::Update(float dt) Line 152 C++
Strategyd.exe!BaseApp::DoFrame(double time) Line 150 C++
Strategyd.exe!cApp::RunInternal() Line 624 C++
Strategyd.exe!BaseApp::Run(cGameBase * game) Line 97 C++
Strategyd.exe!GameMain(const sApplicationData & data) Line 271 C++
Strategyd.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * __formal, char * lpCmdLine, int nCmdShow) Line 179 C++
Strategyd.exe!__tmainCRTStartup() Line 238 C
Strategyd.exe!WinMainCRTStartup() Line 164 C
kernel32.dll!7661338a() Unknown
ntdll.dll!777e9f72() Unknown
ntdll.dll!777e9f45() Unknown
And the crashed thread:
Strategyd.exe!_wassert(const wchar_t * expr, const wchar_t * filename, unsigned int lineno) Line 344 C
Strategyd.exe!boost::shared_ptr<Sfs2X::SmartFox>::operator->() Line 653 C++
> Strategyd.exe!Sfs2X::Bitswarm::BitSwarmClient::OnSocketError(unsigned __int64 context, boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > message, Sfs2X::Core::Sockets::SocketErrors se) Line 883 C++
Strategyd.exe!Sfs2X::Util::DelegateTwoArguments<boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,enum Sfs2X::Core::Sockets::SocketErrors>::Invoke(boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > value1, Sfs2X::Core::Sockets::SocketErrors value2) Line 55 C++
Strategyd.exe!Sfs2X::Core::Sockets::TCPSocketLayer::CallOnError(boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > msg, Sfs2X::Core::Sockets::SocketErrors se) Line 197 C++
Strategyd.exe!Sfs2X::Core::Sockets::TCPSocketLayer::HandleErrorCallback(unsigned __int64 context, boost::shared_ptr<void> state) Line 171 C++
Strategyd.exe!Sfs2X::Util::DelegateOneArgument<boost::shared_ptr<void> >::Invoke(boost::shared_ptr<void> value) Line 54 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::ProcessItem(boost::shared_ptr<std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,boost::shared_ptr<void>,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,boost::shared_ptr<void> > > > > item) Line 193 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::InThread() Line 94 C++
Strategyd.exe!boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>::operator()(Sfs2X::Core::ThreadManager * p) Line 49 C++
Strategyd.exe!boost::_bi::list1<boost::_bi::value<Sfs2X::Core::ThreadManager *> >::operator()<boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>,boost::_bi::list0>(boost::_bi::type<void> __formal, boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager> & f, boost::_bi::list0 & a, int __formal) Line 254 C++
Strategyd.exe!boost::_bi::bind_t<void,boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>,boost::_bi::list1<boost::_bi::value<Sfs2X::Core::ThreadManager *> > >::operator()() Line 21 C++
Strategyd.exe!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>,boost::_bi::list1<boost::_bi::value<Sfs2X::Core::ThreadManager *> > > >::run() Line 118 C++
Strategyd.exe!boost::`anonymous namespace'::thread_start_function(void * param) Line 217 C++
Strategyd.exe!_callthreadstartex() Line 354 C
Strategyd.exe!_threadstartex(void * ptd) Line 337 C
kernel32.dll!7661338a() Unknown
I updated smartfox libary to version 1.1.5 and found a crash in new DIspose() functionality.
Here is call stack:
Main thread:
> Strategyd.exe!boost::detail::timeout::remaining_milliseconds() Line 204 C++
Strategyd.exe!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 554 C++
Strategyd.exe!boost::thread::join_noexcept() Line 348 C++
Strategyd.exe!boost::thread::join() Line 757 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::~ThreadManager() Line 41 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::`scalar deleting destructor'(unsigned int) C++
Strategyd.exe!boost::checked_delete<Sfs2X::Core::ThreadManager>(Sfs2X::Core::ThreadManager * x) Line 34 C++
Strategyd.exe!boost::detail::sp_counted_impl_p<Sfs2X::Core::ThreadManager>::dispose() Line 78 C++
Strategyd.exe!boost::detail::sp_counted_base::release() Line 103 C++
Strategyd.exe!boost::detail::shared_count::~shared_count() Line 375 C++
Strategyd.exe!boost::shared_ptr<Sfs2X::Core::ThreadManager>::~shared_ptr<Sfs2X::Core::ThreadManager>() C++
Strategyd.exe!boost::shared_ptr<Sfs2X::Core::ThreadManager>::operator=(boost::shared_ptr<Sfs2X::Core::ThreadManager> && r) Line 595 C++
Strategyd.exe!Sfs2X::Bitswarm::BitSwarmClient::Dispose() Line 89 C++
Strategyd.exe!Sfs2X::SmartFox::Dispose() Line 95 C++
Strategyd.exe!FoxNetworkServiceImpl::StartAsClient(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & address, int port, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & zone, bool bFull) Line 238 C++
Strategyd.exe!GameClientInterface::ChangeServer(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & address, int port, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & zone) Line 58 C++
Strategyd.exe!GameClientPeer::ProcessNetworkPacket(boost::shared_ptr<google::protobuf::Message> packet) Line 168 C++
Strategyd.exe!NetworkPeer::DoProcessNetworkPacket(boost::shared_ptr<google::protobuf::Message> packet, __int64 packetNumber) Line 73 C++
Strategyd.exe!NetworkPeer::ProcessNetworkPacket(boost::shared_ptr<google::protobuf::Message> packet, __int64 packetNumber) Line 40 C++
Strategyd.exe!FoxNetworkServiceImpl::Update() Line 114 C++
Strategyd.exe!NetworkService::Update(float dt) Line 29 C++
Strategyd.exe!GameClientInterface::Update(float dt) Line 63 C++
Strategyd.exe!GameNetworkInterface::Update(float dt) Line 150 C++
Strategyd.exe!GameServices::Update(float dt) Line 100 C++
Strategyd.exe!Game::Update(float dt) Line 152 C++
Strategyd.exe!BaseApp::DoFrame(double time) Line 150 C++
Strategyd.exe!cApp::RunInternal() Line 624 C++
Strategyd.exe!BaseApp::Run(cGameBase * game) Line 97 C++
Strategyd.exe!GameMain(const sApplicationData & data) Line 271 C++
Strategyd.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * __formal, char * lpCmdLine, int nCmdShow) Line 179 C++
Strategyd.exe!__tmainCRTStartup() Line 238 C
Strategyd.exe!WinMainCRTStartup() Line 164 C
kernel32.dll!7661338a() Unknown
ntdll.dll!777e9f72() Unknown
ntdll.dll!777e9f45() Unknown
And the crashed thread:
Strategyd.exe!_wassert(const wchar_t * expr, const wchar_t * filename, unsigned int lineno) Line 344 C
Strategyd.exe!boost::shared_ptr<Sfs2X::SmartFox>::operator->() Line 653 C++
> Strategyd.exe!Sfs2X::Bitswarm::BitSwarmClient::OnSocketError(unsigned __int64 context, boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > message, Sfs2X::Core::Sockets::SocketErrors se) Line 883 C++
Strategyd.exe!Sfs2X::Util::DelegateTwoArguments<boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,enum Sfs2X::Core::Sockets::SocketErrors>::Invoke(boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > value1, Sfs2X::Core::Sockets::SocketErrors value2) Line 55 C++
Strategyd.exe!Sfs2X::Core::Sockets::TCPSocketLayer::CallOnError(boost::shared_ptr<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > msg, Sfs2X::Core::Sockets::SocketErrors se) Line 197 C++
Strategyd.exe!Sfs2X::Core::Sockets::TCPSocketLayer::HandleErrorCallback(unsigned __int64 context, boost::shared_ptr<void> state) Line 171 C++
Strategyd.exe!Sfs2X::Util::DelegateOneArgument<boost::shared_ptr<void> >::Invoke(boost::shared_ptr<void> value) Line 54 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::ProcessItem(boost::shared_ptr<std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,boost::shared_ptr<void>,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,boost::shared_ptr<void> > > > > item) Line 193 C++
Strategyd.exe!Sfs2X::Core::ThreadManager::InThread() Line 94 C++
Strategyd.exe!boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>::operator()(Sfs2X::Core::ThreadManager * p) Line 49 C++
Strategyd.exe!boost::_bi::list1<boost::_bi::value<Sfs2X::Core::ThreadManager *> >::operator()<boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>,boost::_bi::list0>(boost::_bi::type<void> __formal, boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager> & f, boost::_bi::list0 & a, int __formal) Line 254 C++
Strategyd.exe!boost::_bi::bind_t<void,boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>,boost::_bi::list1<boost::_bi::value<Sfs2X::Core::ThreadManager *> > >::operator()() Line 21 C++
Strategyd.exe!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,Sfs2X::Core::ThreadManager>,boost::_bi::list1<boost::_bi::value<Sfs2X::Core::ThreadManager *> > > >::run() Line 118 C++
Strategyd.exe!boost::`anonymous namespace'::thread_start_function(void * param) Line 217 C++
Strategyd.exe!_callthreadstartex() Line 354 C
Strategyd.exe!_threadstartex(void * ptd) Line 337 C
kernel32.dll!7661338a() Unknown
Re: Memory leaks in c++ api
Hi,
I suppose that crash depends on the concurrent execution of Dispose task while API<->SmartFoxServer connection is falling down.
Your call stack shows that while main thread is calling Dispose
the API is processing a socket error (I think the connection falldown) in a different thread's context (I think in a Windows Socket thread)
I will work to synchronize the two tasks to avoid crash.
As temporary workaround I suggest you to add a "delay" between an explicit call to disconnect client from SmartFoxServer and the Dispose request.
In other words
In your code, you should first call
and after a moment, you should call
Of course this is only a temporary workaround to avoid crash (no good have delay in software to fix crash).
The real solution will be a fix in API to synchronize the processing of socket notifications with Dispose task.
I suppose that crash depends on the concurrent execution of Dispose task while API<->SmartFoxServer connection is falling down.
Your call stack shows that while main thread is calling Dispose
Code: Select all
Strategyd.exe!Sfs2X::Bitswarm::BitSwarmClient::Dispose() Line 89 C++
Strategyd.exe!Sfs2X::SmartFox::Dispose() Line 95 C++
the API is processing a socket error (I think the connection falldown) in a different thread's context (I think in a Windows Socket thread)
Code: Select all
Strategyd.exe!Sfs2X::Bitswarm::BitSwarmClient::OnSocketError(unsigned __int64 context,
I will work to synchronize the two tasks to avoid crash.
As temporary workaround I suggest you to add a "delay" between an explicit call to disconnect client from SmartFoxServer and the Dispose request.
In other words
In your code, you should first call
Code: Select all
m_ptrSmartFox->Disconnect();
and after a moment, you should call
Code: Select all
m_ptrSmartFox->Dispose();
Of course this is only a temporary workaround to avoid crash (no good have delay in software to fix crash).
The real solution will be a fix in API to synchronize the processing of socket notifications with Dispose task.
Re: Memory leaks in c++ api
Thank you for the great response,
I think I will wait for the fix in your API.
I think I will wait for the fix in your API.
Re: Memory leaks in c++ api
We have a fix ready that we would like you to test before making it publicly available. Please contact us by email (info AT smartfoxserver DOT com). Thank you.
Paolo Bax
The SmartFoxServer Team
The SmartFoxServer Team
Re: Memory leaks in c++ api
Hi,
I tested 1.1.6 version. Nothing crashes now, just hangs. It looks like a deadlock. Callstack is in attachement.
I tested 1.1.6 version. Nothing crashes now, just hangs. It looks like a deadlock. Callstack is in attachement.
- Attachments
-
- callstacks.zip
- hang at application exit
- (4.61 KiB) Downloaded 674 times
Re: Memory leaks in c++ api
Hi,
At the end of file Bitswarm\BitSwarmClient.h
please replace
with
and rebuild API
Let me know if deadlock is solved
Thanks
At the end of file Bitswarm\BitSwarmClient.h
please replace
Code: Select all
boost::mutex lockDispose;
with
Code: Select all
boost::recursive_mutex lockDispose;
and rebuild API
Let me know if deadlock is solved
Thanks
Re: Memory leaks in c++ api
Hi,
Deadlocks are gone now.
I found one more crash. I reporduced it several times before your fix and after.
Crash log is in attachment.
Deadlocks are gone now.
I found one more crash. I reporduced it several times before your fix and after.
Crash log is in attachment.
- Attachments
-
- sfs2x (1).zip
- (1.54 KiB) Downloaded 656 times
Re: Memory leaks in c++ api
one more crash
- Attachments
-
- sfs2xlog2.zip
- (2.12 KiB) Downloaded 650 times
Re: Memory leaks in c++ api
Hi,
Our team is using the new version for about a week. It is stable, nothing crashes.
Our team is using the new version for about a week. It is stable, nothing crashes.
Re: Memory leaks in c++ api
Thanks for reporting.
Cheers
Cheers
Re: Memory leaks in c++ api
Hi Lapo, I found one more rare crash.
- Attachments
-
- 9f8e43525827147a8d761384f443e32d.log.txt.zip
- crash at iOS
- (14 KiB) Downloaded 764 times
Who is online
Users browsing this forum: No registered users and 17 guests