GDB的妙用

June 21st, 2006 by vgod

今天有個同學跑來跟我求救。他說有隻重要的程式在工作站上面跑,但沒有放在screen裡面,可是Windows的鍵盤滑鼠都卡死了,有沒有辦法能重新開機(也就是關掉windows上的terminal, putty)而且讓程式能繼續跑下去..。
其實我以前也遇過同樣的問題,只是一直沒去想怎麼解決,後來都習慣用screen,就自然不會遇到這問題了。可是我最近發現,其實有不少人都不知道UNIX上有screen這個好東西,於是只要跑些重要的程式,就得擺一個terminal在桌面上,而且千千萬萬不能關掉,否則跑了數天的結果就這樣白費了。

今天再次碰到這個問題時,仔細想了一下,terminal關掉會讓程式中斷的關鍵在於,程式會在terminal關閉時收到SIGHUP這個signal,而不處理這個signal的結果就是結束程式。在以前還不知道screen這東西前,都得用nohup這個指令來事先攔截SIGHUP。

那現在碰到的問題就是,有沒有辦法在程式執行到一半的時候,先在它收到SIGHUP之前把這signal擋下來?或是直接在它執行中修改它的程式碼,讓它忽略SIGHUP…?

想在runtime時變更程式的行為,讓我馬上想到gdb這個好東西。gdb可以在程式執行到一半時,attach到它的process上,接著就能做所有gdb能做的事情..。gdb能做的當然不只是debug啦,gdb可以在runtime改變程式的執行流程和行為,還能攔截程式本來應該要收到的signal…,咦,這好像就是解答了嘛!

Debugging with GDB可以查到,只要在gdb裡輸入這樣的指令,底下的程式就不會收到SIGHUP了。


handle SIGHUP nopass

所以這問題的解法很簡單。

  1. 從另一台電腦連上正在跑重要程式的工作站
  2. 用ps和grep找出那個程式的pid
  3. 用gdb attach它: gdb [program] [pid]
  4. 在gdb內輸入: handle SIGHUP nopass
  5. 把當掉的windows重新開機,在gdb內輸入continue讓程式繼續執行
  6. 你會看到gdb攔截到SIGHUP的訊息,再輸入continue就可以了

“GDB的妙用” 有3則留言

  1. MyAvatars 0.2 ShepJeng::Blog | links for 2006-06-21 說:

    [...] GDB的妙用 厲害, 連這種東西都有解. [...]

  2. MyAvatars 0.2 -TMA-1- » links for 2006-06-22 說:

    [...] vgod’s blog » GDB的妙用 (tags: Tech Programming GDB) [...]

  3. MyAvatars 0.2 vgod’s blog » retty: 攔截tty輸出 說:

    [...] 之前我在GDB的妙用這篇文章提到怎麼攔截執行中程式的signal,有人問我那有沒有辦法攔截執行中程式的輸出呢? 我本來也不知道答案,直到剛看到Jserv介紹的retty : 攔截終端機輸出的工具,才知道原來已經有這麼好用的工具能做到了 [...]

留下您的意見

To comment, click below to log in.

或是留下您的資料: