Gdb 如何在调试器下列出boost::asio::io_服务中注册的处理程序?

Gdb 如何在调试器下列出boost::asio::io_服务中注册的处理程序?,gdb,boost-asio,Gdb,Boost Asio,给定正在运行的应用程序,我想提取有关当前注册的完整处理程序的信息 处理程序已由类A注册。例如: boost::asio::async_read(s, b, boost::bind(&A::F, this->shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 在调试器下,我可以访问相应的io_服务变量。如何为尚未完成的操作找出(A:

给定正在运行的应用程序,我想提取有关当前注册的完整处理程序的信息

处理程序已由类A注册。例如:

boost::asio::async_read(s, b, boost::bind(&A::F, this->shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

在调试器下,我可以访问相应的io_服务变量。如何为尚未完成的操作找出(A::F,this,s,b)。

我想稍微扩大问题的范围,以涵盖我认为最终目标的替代方案:调试异步处理程序


示例程序 要通过示例显示调试,让我们从侦听端口4321的基本UDP echo服务器开始:

#包括
#包括
#包括
使用boost::asio::ip::udp;
类udp_echo
{
公众:
udp_echo(boost::asio::io_服务和服务,
无符号整数端口)
:套接字(服务,udp::端点(udp::v4(),端口))
{
套接字异步接收来自(
boost::asio::buffer(buffer_uu)、sender_u、,
boost::bind(&udp_-echo::handle_-receive,
boost::asio::占位符::错误,
boost::asio::占位符::字节(已传输);
}
无效句柄接收(常量boost::system::error\u代码和错误,
std::大小(传输的字节数)
{
套接字异步发送到(
boost::asio::buffer(buffer\uu,字节\u传输),sender\uu,
boost::bind(&udp_-echo::handle_-send,
boost::asio::占位符::错误,
boost::asio::占位符::字节(已传输);
}
无效句柄发送(const boost::system::error\u代码和错误,
std::大小(传输的字节数)
{
插座关闭();
}
私人:
udp::套接字;
阵列缓冲区;
udp::端点发送器;
};
int main()
{
boost::asio::io_服务;
udp_回声(服务,4321);
service.run();
}
此简单程序有一个异步调用链:

udp_echo::udp_echo()
{
套接字异步接收来自(…);--。
}                                    |
.-----------------------'
v
void udp_echo::handle_receive(…)
{
套接字异步发送到(…);----。
}                                    |
.-----------------------'
v
void udp_echo::handle_send()
{
插座关闭();
}

处理程序跟踪 增压1.47。只需定义
BOOST\u ASIO\u ENABLE\u HANDLER\u TRACKING
和BOOST即可。ASIO将调试输出(包括时间戳)写入标准错误流。运行编程并通过UDP发送“hello world”产生以下输出:

@asio | 1363273821.846895 | 0*1|socket@0xbf8c4e3c.async_receive_from // 1
@asio | 1363273829.288883 |>1 | ec=系统:0,传输的字节数=12//2
@asio | 1363273829.288931 | 1*2|socket@0xbf8c4e3c.async_send_to      // 3
@asio | 1363273829.289013 | 2 | ec=系统:0,传输的字节数=12//5
@asio | 1363273829.289035 | 2|socket@0xbf8c4e3c.close                // 6
@asio | 1363273829.289075|
套接字信息:

(gdb)p$op.socket\u
$9 = 10
(gdb)p echo.socket_u.implementation.socket_u
$10 = 10
在这种情况下,操作只知道本机套接字表示(文件描述符)。确定它是什么套接字的一种有用方法是查询lsof

$/usr/sbin/lsof-i-P | grep a.out
a、 out 4265 ghost 10u IPv4 1166143 UDP*:4321

因此,文件描述符10正在侦听UDP 4321。

再次感谢您的详细回答。我自己设法找到了注册的描述符。沮丧是我错过的东西。我几乎没有时间阅读boost::asio代码,也无法理解它。你能详细说明一下为什么需要这种悲观情绪吗?我还假设您使用的是1.47版;我使用的是1.51,最后一步有点不同:$op.handler\uu。handler\uu是必需的。我是根据最近对主干的拉动进行构建的。需要向下转换,因为只有最派生的操作包含提取所需数据的所有类型和成员。操作的基类没有关于用户处理程序的类型信息,允许反应器对操作进行常规操作。GDB可能需要
set print object
查看所有vtables信息。 (gdb) p service.service_registry_.init_keytab init_key init_key<boost::asio::datagram_socket_service<boost::asio::ip::udp> > init_key<boost::asio::detail::epoll_reactor> init_key<boost::asio::detail::task_io_service> (gdb) set $service = *('boost::asio::detail::epoll_reactor'*) $service (gdb) set $ops = $service.registered_descriptors_.live_list_.op_queue_ (gdb) set $op = $ops.front_ (gdb) p *$op $3 = {<boost::asio::detail::task_io_service_operation> = {next_ = 0x0, func_ = 0x804c256 <boost::asio::detail::reactive_socket_recvfrom_op< boost::asio::mutable_buffers_1, boost::asio::ip::basic_endpoint< boost::asio::ip::udp>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, udp_echo, boost::system::error_code const&, unsigned int>, boost::_bi::list3<boost::_bi::value<udp_echo*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >:: do_complete(boost::asio::io_service::io_service_impl*, boost::asio::detail::epoll_reactor::descriptor_state::operation*, boost::system::error_code const&, size_t)>, task_result_ = 0}, ec_ = { m_val = 11, m_cat = 0x13b2c8}, bytes_transferred_ = 0, perform_func_ = 0x80514c8 <boost::asio::detail::reactive_socket_recvfrom_op_base< boost::asio::mutable_buffers_1, boost::asio::ip::basic_endpoint<boost::asio::ip::udp> >::do_perform(boost::asio::detail::reactor_op*)>} (gdb) set $op = *('boost::asio::detail::reactive_socket_recvfrom_op< boost::asio::mutable_buffers_1, boost::asio::ip::basic_endpoint< boost::asio::ip::udp>, boost::_bi::bind_t<void, boost::_mfi::mf2< void, udp_echo, boost::system::error_code const&, unsigned int>, boost::_bi::list3<boost::_bi::value<udp_echo*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >'*) $op