调试和自由执行中的信号处理
Signal handling in debug and in free execution
我必须在使用Boost.Asio的程序中处理SIGINT
和SIGTERM
。我为此使用boost::asio::signal_set::async_wait()
。
问题是信号处理程序仅在我简单地运行应用程序时才获得控制权,而在调试它时则不会。
下面是一些代码:
Proxy::Proxy():
signals_(ioContext_, SIGINT, SIGTERM)
{
signals_.async_wait(
[this](const boost::system::error_code& error, int)
{
if (!error)
ioContext_.stop();
}
);
}
Proxy::run()
{
ioContext_.run();
}
当我们run()
Proxy
时,ioContext_
开始处理事件。如果我们只是简单地运行程序并在终端中执行Ctrl+C
,则信号处理程序(即 lambda(会停止ioContext_
(正如我们预期的那样(,io_context::run
将控制权交还给我们。但是在调试模式下,程序会对Ctrl+C
做出反应,但执行在epoll_wait()
的某个地方停止。如果我们继续执行,它会挂在epoll_wait()
的某个地方,依此类推。
下面是执行停止位置的堆栈跟踪:
epoll_wait
boost::asio::detail::epoll_reactor::run
boost::asio::detail::scheduler::do_one_run
boost::asio::detail::scheduler::run
boost::asio::io_context::run
Proxy::run
main
为什么它会在调试模式下发生,而在其他模式下不会发生?
这里的问题是GDB使用SIGINT
作为中断程序并允许您开始调试的机制。
(gdb) info signals SIGINT
Signal Stop Print Pass to program Description
SIGINT Yes Yes No Interrupt
这是说 GDB 不应该将SIGINT
传递给程序,而应该使用它来停止程序并将您放入 GDB 提示符。将其发送到程序的最简单机制是在此时从 GDB 发送信号:
(gdb) signal SIGINT
现在,您的程序应按预期继续运行。
根据您执行此操作的频率,键入signal SIGINT
可能会变得不方便。幸运的是,GDB 允许您修改它处理信号的方式。您希望SIGINT
不停止程序(将您放入 GDB 提示符(并将其传递给程序。
(gdb) handle SIGINT nostop pass
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y
Signal Stop Print Pass to program Description
SIGINT No Yes Yes Interrupt
我们现在处于"有点不可取"的状态,因为我们不能再使用 Ctrl+C 跳转到我们的 GDB 提示符。您必须依赖预设断点和其他机制。
如果要获得更高级,可以使用catch
和commands
来确定SIGINT
的来源(从调试使用 SIGINT 和 gdb 的程序中提取(:
catch signal SIGINT
commands
if $_siginfo._sifields._kill.si_pid == 0
print "Received SIGINT from tty"
else
printf "Received SIGINT from %d; continuingn", $_siginfo._sifields._kill.si_pid
signal SIGINT
end
end
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 有可能在信号处理程序中设置promise吗
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 调试和自由执行中的信号处理
- 通过安装信号处理程序关闭多线程应用程序
- 为什么我的信号处理程序只执行一次?
- GTK C++:找不到信号处理程序 您是否使用 -rdynamic 进行了编译?
- C++ 在信号处理程序后继续执行
- 没有信号处理程序的POSIX定时器的目的是什么?
- 为什么这个信号处理程序不能捕获 SIGHUP 或 SIGQUIT?
- 如何在C++中使用 std::bind 函数作为信号处理程序?
- 在 C++17 中,是否未定义使用无锁原子学保护从信号处理程序传递的数据?
- 如何将信号处理程序添加为方法
- 窗口上信号处理程序的异步安全写入函数
- 使用信号处理程序处理从 FIFO 接收的数据
- gtkmm/glade - 将信号处理程序连接到 MenuShell
- GTK+3 编译错误"找不到信号处理程序",您是否使用 -rdynamic 进行了编译?
- Linux 中的信号处理程序使用 sigaction (C++)
- boost::asio-signal_set处理程序仅在捕获第一个信号后执行,并忽略相同类型的连续信号