簡體   English   中英

調試和自由執行中的信號處理

[英]Signal handling in debug and in free execution

我必須在使用 Boost.Asio 的程序中處理SIGINTSIGTERM boost::asio::signal_set::async_wait()使用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() ProxyioContext_開始處理事件。 如果我們只是簡單地運行程序並在終端中執行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 提示符。 您將不得不依賴預設斷點和其他機制。

如果你想更高級,你可以使用catchcommands來確定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; continuing\n", $_siginfo._sifields._kill.si_pid
    signal SIGINT
  end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM