摘要:背景這幾天一直在查一個線上程序住的問題這個程序總是在運(yùn)行分鐘后住通過以下的一些調(diào)試手段發(fā)現(xiàn)是打日志的時候因為滿被了日志是默認(rèn)打到的無論日志級別而我這個程序是被另一個程序調(diào)起的父進(jìn)程沒有接收子進(jìn)程的導(dǎo)致了被打滿在調(diào)試的過程中用到了以下幾種調(diào)試
FROM http://kamushin.github.io/debug/python.html
背景這幾天一直在查一個線上程序 hang 住的問題. 這個程序總是在運(yùn)行50分鐘后 hang 住, 通過以下的一些調(diào)試手段,發(fā)現(xiàn)是打日志的時候因為 buffer 滿被 block 了.
Python 日志是默認(rèn)打到 stderr 的, 無論日志級別. 而我這個程序是被另一個程序調(diào)起的, 父進(jìn)程沒有接收子進(jìn)程的 stderr, 導(dǎo)致了 buffer 被打滿.
在調(diào)試的過程中, 用到了以下幾種 Python 調(diào)試手段, 于是記錄以下.
GDB是一個廣為人知的調(diào)試器, 而且線上可用, 非常贊. 但是默認(rèn)配置的 GDB 并不能打印 Python 當(dāng)前調(diào)用棧. 我們需要對其做些配置.
首先進(jìn)行g(shù)db的安裝, 需要gdb7以上版本
sudo yum install gdb python-debuginfo
然后下載這份 gdb 配置文件 http://svn.python.org/projects/python/trunk/Misc/gdbinit 到 ~/.gdbinit
對于一個線上已經(jīng)hang住的程序來說, 可以用 gdb -p pid 的形式進(jìn)行 attach, 打印出當(dāng)前調(diào)用棧.
一般來說, 必須是帶debug symbol的Python 編譯版本才能打印出足夠多的信息, 但是線上的 Python 版本往往是不帶debug symbol 的, 于是我們要修改下上述的配置文件
<<<< if $pc > PyEval_EvalFrameEx && $pc < PyEval_EvalCodeEx >>>> if $pc > PyEval_EvalFrameEx && $pc < PyEval_EvalCodeEx && $fp != 0
對~/.gdbinit 進(jìn)行上述修改, 即可成功打印出當(dāng)前 hang住進(jìn)程的調(diào)用棧.
具體到我這次遇到的問題, 在打出調(diào)用棧后發(fā)現(xiàn)是卡死在 log 模塊的 emit 上, 于是 strace 下看到果然是卡死在 write 的系統(tǒng)調(diào)用上, 順利找到了原因.
更多的用法可以看https://wiki.python.org/moin/DebuggingWithGdb, 不過大部分的用法依然需要debug symbol, 按照 wiki 來,不一定可以順利實現(xiàn).
PDB是 Python 自帶的一個調(diào)試模塊. 可以以python -m pdf xxx.py 的形式, 以調(diào)試模式啟動一個 Python 進(jìn)程.
雖然似乎不能 attach 到已運(yùn)行的進(jìn)程上, 但是提供了一個簡單快速的調(diào)試方式.
上述的方式都是不需要侵入代碼的, 這里再提供一種侵入代碼的方式.
import code, traceback, signal def debug(sig, frame): """Interrupt running process, and provide a python prompt for interactive debugging.""" d={"_frame":frame} # Allow access to frame object. d.update(frame.f_globals) # Unless shadowed by global d.update(frame.f_locals) i = code.InteractiveConsole(d) message = "Signal received : entering python shell. Traceback: " message += "".join(traceback.format_stack(frame)) i.interact(message) def listen(): signal.signal(signal.SIGUSR1, debug) # Register handler
基本原理是給SIGUSR1信號加上一個handler, handler 執(zhí)行時會把當(dāng)前的變量加載到一個交互式窗口, 然后開啟交互式console, 接下來就像打開一個 REPL 一樣了, 可以查看當(dāng)前的變量值, 可以改變變量值, 可以調(diào)用函數(shù)看看結(jié)果是什么, 查看完后^d離開, 就可以讓程序繼續(xù)執(zhí)行下去.
在加好 handler 后, 我們可以用os.kill(pid, signal.SIGUSR1)的方式, 調(diào)起 handler, 進(jìn)行調(diào)試.
值得注意的是, 由于和console 的交互需要 stdout 的支持, 而父子進(jìn)程默認(rèn)是不共享 stdout 的,所以當(dāng)要調(diào)試子進(jìn)程的時候, 需要重定向子進(jìn)程的 stdout 到父進(jìn)程的 stdout, 這個很簡單,就不貼代碼了.
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37948.html
摘要:調(diào)試器可幫助程序員分析完整的代碼。我們將使用標(biāo)準(zhǔn)庫中的模塊調(diào)試我們的腳本。例外是程序執(zhí)行期間發(fā)生的錯誤。設(shè)置斷點并檢查堆棧幀,并列出源代碼。輸入以繼續(xù)調(diào)試。分析和計時程序分析程序意味著測量程序的執(zhí)行時間。的模塊用于分析程序。 showImg(https://segmentfault.com/img/remote/1460000018807029?w=902&h=442); 來源 | ...
摘要:通過單元測試,開發(fā)者可以為構(gòu)成程序的每一個元素例如,獨(dú)立的函數(shù),方法,類以及模塊編寫一系列獨(dú)立的測試用例。在每個測試中,斷言可以用來對不同的條件進(jìn)行檢查。當(dāng)退出調(diào)試器時,調(diào)試器會自動恢復(fù)程序的執(zhí)行。 Python已經(jīng)演化出了一個廣泛的生態(tài)系統(tǒng),該生態(tài)系統(tǒng)能夠讓Python程序員的生活變得更加簡單,減少他們重復(fù)造輪的工作。同樣的理念也適用于工具開發(fā)者的工作,即便他們開發(fā)出的工具并沒有出現(xiàn)...
摘要:安裝一個的版本。選一個的解釋器想要在中運(yùn)行代碼必須要告訴使用哪個解釋器才行。運(yùn)行文件最簡單的方法是點擊右鍵選擇在終端運(yùn)行。然后選擇調(diào)試工具欄上的設(shè)置圖標(biāo)。該命令打開一個可用調(diào)試器的菜單,顯示和。選擇,這個會創(chuàng)建一個包含許多配置的文件。 開始 安裝 Python extension 。 安裝一個python3的版本。 選一個python的解釋器 想要在vscode中運(yùn)行python代...
摘要:上一篇文章第三章概念及應(yīng)用第三節(jié)客戶端編程下一篇文章第四章網(wǎng)站部署第二節(jié)靜態(tài)文件之前著重講解的編程知識點,所有之前的例子都使用最簡單的啟動方式運(yùn)行。 上一篇文章:Python:Tornado 第三章:HTML5 WebSocket概念及應(yīng)用:第三節(jié):客戶端編程下一篇文章:Python:Tornado 第四章:Tornado網(wǎng)站部署:第二節(jié):靜態(tài)文件 之前著重講解Tornado的編程知...
摘要:最近由于工作關(guān)系,開始寫程序,同事有用的,有用的。第一種適合及以上版本,因為在版本起,出現(xiàn)了文件,配置可以寫成用文件啟動程序,實測可以觸發(fā)斷點。 最近由于工作關(guān)系,開始寫flask web程序,同事有用Vim的,有用PyCharm的。在調(diào)研了一通python的編輯器,IDE之后,發(fā)現(xiàn)Visual Studio Code相對比較適合我。 VSC有相對較全的功能,比較好看舒服的主題,良好的...
閱讀 2623·2021-11-16 11:40
閱讀 3421·2021-11-08 13:26
閱讀 889·2021-10-28 09:32
閱讀 3545·2021-09-13 10:26
閱讀 816·2019-08-30 15:55
閱讀 791·2019-08-30 15:44
閱讀 1917·2019-08-30 15:44
閱讀 1764·2019-08-30 13:48