gpt4 book ai didi

c++ - 调试和自由执行中的信号处理

转载 作者:行者123 更新时间:2023-12-02 09:50:22 24 4
gpt4 key购买 nike

我要处理SIGINTSIGTERM在我使用 Boost.Asio 的程序中。我用 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交还控制权。但在 Debug模式下,程序会对 Ctrl+C 使用react但执行在 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

为什么它会在 Debug模式下发生,但在其他情况下不会发生?

最佳答案

这里的问题是 GDB 使用 SIGINT作为中断程序并允许您开始调试的机制。

(gdb) info signals SIGINT
Signal Stop Print Pass to program Description
SIGINT Yes Yes No Interrupt

这就是说GDB不应该通过 SIGINT s 到程序,但应该使用它来停止程序并使您进入 GDB 提示符。将其发送到您的程序的最简单机制是此时从 GDB 发送信号:
(gdb) signal SIGINT

现在您的程序应该按预期继续运行。

根据您执行此操作的频率,键入 signal SIGINT可能会不方便。幸运的是,GDB 允许您修改它的处理方式 signals .你要 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 提示符。您将不得不依赖预设断点和其他机制。

如果你想更高级,可以使用 catchcommands确定 SIGINT的来源(摘自 Debugging a program that uses SIGINT with gdb ):
catch signal SIGINT
commands
if $_siginfo._sifields._kill.si_pid == 0
print "Received SIGINT from tty"
else
printf "Received SIGINT from %d; continuing\n", $_siginfo._sifields._kill.si_pid
signal SIGINT
end
end

关于c++ - 调试和自由执行中的信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60172419/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com