目錄

廣告 AD

Python Debug:用 GDB 來 Debug Python!

Python Debug 的方法很多種

但你有試過用 GDB Debug Python 嗎?

廣告 AD

平常在寫 Python 的程式時,你都怎麼 Debug 的?

使用 “無限 Print 大法”? PDB? 還是使用 “通靈之術”? 亦或是找 ChatGPT 求助?

這些方法都很不錯,但有時候程式卡在某個 function 出不去,你想要看看目前程式內部的數值

這時候你可以試試看以下介紹的方法~


這邊以一個簡單的 Python 程式作範例:

python

def binary_search(arr: list[int], start: int, end: int, target: int):
    while start <= end:
        mid = (end - start) // 2 + start
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            start = mid
        else:
            end = mid

arr = [1,3,6,7,9,14,16,18,20]
target = 20

idx = binary_search(arr, 0, len(arr) - 1, 20)
print(f"{target} is at index {idx}")

並將他運行起來

bash

python3 test.py

你會發現程式卡住了,久久都停不下來,我們來試試看新方法吧~


由於目前最廣泛使用的 Python 直譯器是由 C 實作的,所以我們可以使用 GDB 來幫助我們除錯

要使用 GDB 之前,我們要先安裝 GDB (如果你還沒安裝的話)

bash

sudo apt install gdb

我們都知道,我們平常撰寫的是 Python 腳本,透過 Python Interpreter 來讀取腳本執行裡所寫的內容

所以我們要讓 GDB 偵錯的對象就是 python3,另外我們需要給上正在運行的 python3 的 pid

我們可以透過指令查詢目標程式的 pid

bash

ps aux | grep python3

ps aux | grep python3

查詢完後執行 GDB,pid 需要替換成自己查詢到的 pid,上方範例的 pid 為 4117

bash

gdb python3 <pid>

這時,目標的程式就停止了,我們可以看到當前正在執行的函式是什麼

也可以列出目前的 call stack

但你會發現,這些都是 Python 內部的函式,根本看不懂是什麼,還有一堆的 ??

這時候你就會需要 Python GDB 擴充功能


我們先安裝 python3-dbg 來將 CPython 直譯器資訊新增到 GDB 上

bash

sudo apt install python3-dbg

之後重複上節的操作,我們進入到 GDB 內部,我們就可以使用擴充功能的指令:

  • py-list
  • py-up / py-down
  • py-bt
  • py-print
  • py-locals

列出當前執行的程式碼段落,正在執行的行前面有 >

py-list


切換執行的 frame,類似 GDB 的 up 和 down

py-up / py-down


印出目前的 call stack

py-bt


印出某個變數的數值

py-print


印出目前 frame 內的區域變數數值

py-locals


如果你不想影響到目前的程式運行,你可以產生完 core file 然後繼續讓他跑

在 GDB 內部輸入 generate-core-file,接著會產生 core file,我們就可以關閉 GDB 了

後續如果我們要讀取 core file 可以用以下的指令,就可以用當時的環境來 debug 了

bash

gdb python3 <core file>


廣告 AD