powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поиск утечки с помощью vld
3 сообщений из 3, страница 1 из 1
Поиск утечки с помощью vld
    #38722993
The_REAL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Программа-сервер, многопоточная, не могу понять - где\в чем утечка:
включаю в код
#include "vld.h"
и получаю в консоли сотни "утечек" вида:
---------- Block 6127 at 0x00CEDF30: 76 bytes ----------
Call Stack:
c:\program files\boost\boost_1_51\boost\asio\detail\impl\strand_service.ipp (84): SkyRiverServerMT.exe!boost::asio::detail::strand_service::construct + 0x7 bytes
c:\program files\boost\boost_1_51\boost\asio\strand.hpp (97): SkyRiverServerMT.exe!boost::asio::io_service::strand::strand
d:\users\android\skyriverserver\skyriverservermt\logisticserver.cpp (140): SkyRiverServerMT.exe!connection::connection + 0x6F bytes
d:\users\android\skyriverserver\skyriverservermt\logisticserver.cpp (306): SkyRiverServerMT.exe!server3::start_accept + 0x35 bytes
d:\users\android\skyriverserver\skyriverservermt\logisticserver.cpp (321): SkyRiverServerMT.exe!server3::handle_accept
c:\program files\boost\boost_1_51\boost\bind\mem_fn_template.hpp (165): SkyRiverServerMT.exe!boost::_mfi::mf1<void,server3,boost::system::error_code const &>::operator() + 0x10 bytes
c:\program files\boost\boost_1_51\boost\bind\bind.hpp (314): SkyRiverServerMT.exe!boost::_bi::list2<boost::_bi::value<server3 *>,boost::arg<1> >::operator()<boost::_mfi::mf1<void,server3,boost::system::error_code const &>,boost::_bi::list1<boost::system::error_code const &> >
c:\program files\boost\boost_1_51\boost\bind\bind_template.hpp (48): SkyRiverServerMT.exe!boost::_bi::bind_t<void,boost::_mfi::mf1<void,server3,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<server3 *>,boost::arg<1> > >::operator()<boost::system::error_code>
c:\program files\boost\boost_1_51\boost\asio\detail\bind_handler.hpp (47): SkyRiverServerMT.exe!boost::asio::detail::binder1<boost::_bi::bind_t<void,boost::_mfi::mf1<void,server3,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<server3 *>,boost::arg<1> > >,boost::system::error_code>::operator()
c:\program files\boost\boost_1_51\boost\asio\handler_invoke_hook.hpp (65): SkyRiverServerMT.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void,boost::_mfi::mf1<void,server3,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<server3 *>,boost::arg<1> > >,boost::system::error_code> >
c:\program files\boost\boost_1_51\boost\asio\detail\handler_invoke_helpers.hpp (39): SkyRiverServerMT.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void,boost::_mfi::mf1<void,server3,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<server3 *>,boost::arg<1> > >,boost::system::error_code>,boo + 0x30 bytes
c:\program files\boost\boost_1_51\boost\asio\detail\win_iocp_socket_accept_op.hpp (142): SkyRiverServerMT.exe!boost::asio::detail::win_iocp_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ip::tcp,boost::_bi::bind_t<void,boost::_mfi::mf1<void,server3,boost::system::error_code c + 0x13 bytes
c:\program files\boost\boost_1_51\boost\asio\detail\win_iocp_operation.hpp (45): SkyRiverServerMT.exe!boost::asio::detail::win_iocp_operation::complete + 0x1A bytes
c:\program files\boost\boost_1_51\boost\asio\detail\impl\win_iocp_io_service.ipp (397): SkyRiverServerMT.exe!boost::asio::detail::win_iocp_io_service::do_one
c:\program files\boost\boost_1_51\boost\asio\detail\impl\win_iocp_io_service.ipp (159): SkyRiverServerMT.exe!boost::asio::detail::win_iocp_io_service::run + 0xE bytes
c:\program files\boost\boost_1_51\boost\asio\impl\io_service.ipp (59): SkyRiverServerMT.exe!boost::asio::io_service::run + 0xF bytes
c:\program files\boost\boost_1_51\boost\bind\mem_fn_template.hpp (49): SkyRiverServerMT.exe!boost::_mfi::mf0<unsigned int,boost::asio::io_service>::operator() + 0xC bytes
c:\program files\boost\boost_1_51\boost\bind\bind.hpp (244): SkyRiverServerMT.exe!boost::_bi::list1<boost::_bi::value<boost::asio::io_service *> >::operator()<unsigned int,boost::_mfi::mf0<unsigned int,boost::asio::io_service>,boost::_bi::list0>
c:\program files\boost\boost_1_51\boost\bind\bind_template.hpp (21): SkyRiverServerMT.exe!boost::_bi::bind_t<unsigned int,boost::_mfi::mf0<unsigned int,boost::asio::io_service>,boost::_bi::list1<boost::_bi::value<boost::asio::io_service *> > >::operator()
c:\program files\boost\boost_1_51\boost\thread\detail\thread.hpp (75): SkyRiverServerMT.exe!boost::detail::thread_data<boost::_bi::bind_t<unsigned int,boost::_mfi::mf0<unsigned int,boost::asio::io_service>,boost::_bi::list1<boost::_bi::value<boost::asio::io_service *> > > >::run
e:\installer\boost\libs\thread\src\win32\thread.cpp (191): SkyRiverServerMT.exe!boost::`anonymous namespace'::thread_start_function
f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c (348): SkyRiverServerMT.exe!_callthreadstartex + 0xF bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c (331): SkyRiverServerMT.exe!_threadstartex
0x7C80B729 (File and line number not available): kernel32.dll!GetModuleFileNameA + 0x1BA bytes

Единственное что "моё" это строки
d:\users\android\skyriverserver\skyriverservermt\logisticserver.cpp (140): SkyRiverServerMT.exe!connection::connection + 0x6F bytes
d:\users\android\skyriverserver\skyriverservermt\logisticserver.cpp (306): SkyRiverServerMT.exe!server3::start_accept + 0x35 bytes
d:\users\android\skyriverserver\skyriverservermt\logisticserver.cpp (321): SkyRiverServerMT.exe!server3::handle_accept
где
140 это конструктор connection
306 это строка new_connection_.reset(new connection(io_service_));
321 это кавычка, закрывающая handle_accept...

которые вообщем то взяты из примера библиотеки буст... весь текст:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
class connection : public boost::enable_shared_from_this<connection>, private boost::noncopyable
{
public:
	connection(boost::asio::io_service& io_service)
	  : strand_(io_service),
		socket_(io_service),
		pTerminalHandler_(NULL),
		bCloseConnect_(false)
	{
	}

	void self_delete()
	{
		boost::system::error_code ignored_ec;
		socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
		socket_.close();

		if(pTerminalHandler_)
		{
			delete pTerminalHandler_;
		}	
	}
	/// Get the socket associated with the connection.
	boost::asio::ip::tcp::socket& socket()
	{
		return socket_;
	}
	void start()
	{
		socket_.async_read_some(boost::asio::buffer(buffer_, 1024),
		  strand_.wrap(
			boost::bind(&connection::handle_read, shared_from_this(),
			  boost::asio::placeholders::error,
			  boost::asio::placeholders::bytes_transferred)));
	}
	void connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred)
	{
		if (!e)
		{
 			string strData(buffer_.data(), bytes_transferred);

			if(!pTerminalHandler_)
			{
				pTerminalHandler_ = CTerminalHandlerSelector::SelectTerminal(strData);

				if(!pTerminalHandler_)
				{
					self_delete();
					return;
				}
			}

			bCloseConnect_ = pTerminalHandler_->ReadData(strData);

			if(bCloseConnect_)
			{
				self_delete();
				return;
			}

			bCloseConnect_ = pTerminalHandler_->WriteData(strData);

			if(strData.length())
			{
				 boost::asio::async_write(socket_, boost::asio::buffer(strData.c_str(), strData.length()),
				  strand_.wrap(boost::bind(&connection::handle_write, shared_from_this(),
					  boost::asio::placeholders::error)));
			}
			else if(!bCloseConnect_)
			{
				start();			
			}
			else
			{
				self_delete();
			}
		}
	}
	void connection::handle_write(const boost::system::error_code& e)
	{
		if (!e)
		{
			if(bCloseConnect_)
			{
				self_delete();
				return;
			}
			start();
		}
	}
private:
	boost::asio::io_service::strand strand_;
	boost::asio::ip::tcp::socket socket_;
	boost::array<char, 1024> buffer_;
	
	//sean
	bool bCloseConnect_;
	CTerminalHandler* pTerminalHandler_;
};

typedef boost::shared_ptr<connection> connection_ptr;

class server3 : private boost::noncopyable
{
public:
	server3(const std::string& address, const std::string& port, std::size_t thread_pool_size)
		: thread_pool_size_(thread_pool_size),
		signals_(io_service_),
		acceptor_(io_service_),
		new_connection_()
	{
		signals_.add(SIGINT);
		signals_.add(SIGTERM);
		#if defined(SIGQUIT)
		  signals_.add(SIGQUIT);
		#endif // defined(SIGQUIT)
		signals_.async_wait(boost::bind(&server3::handle_stop, this));

		boost::asio::ip::tcp::resolver resolver(io_service_);
		boost::asio::ip::tcp::resolver::query query(address, port);
		boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
		acceptor_.open(endpoint.protocol());
		acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
		acceptor_.bind(endpoint);
		acceptor_.listen();

		start_accept();
	}

	void run()
	{
		std::vector<boost::shared_ptr<boost::thread> > threads;
		for (std::size_t i = 0; i < thread_pool_size_; ++i)
		{
			boost::shared_ptr<boost::thread> thread(new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_)));
			threads.push_back(thread);
		}

		// Wait for all threads in the pool to exit.
		for (std::size_t i = 0; i < threads.size(); ++i)
			threads[i]->join();
	}

	void start_accept()
	{
		new_connection_.reset(new connection(io_service_));
		acceptor_.async_accept(new_connection_->socket(), boost::bind(&server3::handle_accept, this, boost::asio::placeholders::error));
	}

	void handle_accept(const boost::system::error_code& e)
	{
		if (!e)
		{
			new_connection_->start();
		}

		start_accept();
	}

	void handle_stop()
	{
		io_service_.stop();
	}
private:
	std::size_t thread_pool_size_;
	boost::asio::io_service io_service_;
	boost::asio::signal_set signals_;
	boost::asio::ip::tcp::acceptor acceptor_;
	connection_ptr new_connection_;
};
...
Рейтинг: 0 / 0
Поиск утечки с помощью vld
    #38723020
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
The_REALвесь текст:
Какой же это "весь текст", когда тут как минимум нет текста main() и класса CTerminalHandlerSelector?

Из того что приведено, видно две потенциальные проблемы.
1) delete pTerminalHandler_ не всегда вызывается. Например при ошибке в connection::handle_read
Используйте деструктор для гарантированного удаления ресурсов класса.
2) Судя по названию CTerminalHandlerSelector::SelectTerminal объект pTerminalHandler_ не создается а выбирается из списка готовых. Если это так то удалять его вообще не нужно - будет обращение к удаленному объекту, что тоже в принципе утечка памяти.
...
Рейтинг: 0 / 0
Поиск утечки с помощью vld
    #38723220
The_REAL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Меня больше интересует, почему vld ругается на утечку именно в этом месте?

Anatoly Moskovsky, спасибо что глянули код - дело в том, да там есть ньюансы, но...
1) да, вписывал уничтожение в деструктор connection - проблему не решило
2) ну, там создается объект, просто класса-наследника, одного из нескольких.

дело в том, что остальной код - если заменить выделенный фрагмент на однопоточную реализацию без пула (так же есть в примерах boost asio) работает без утечек (ну может очень редких, при ошибке в connection::handle_read как вы сказали), в отличии от этого - тут память "уходит" мегабайтами в час :(
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поиск утечки с помощью vld
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]