Pytest debug/C++ debug

Python/C++ debug

debug的方式有很多最簡單的方式是打印log,看log,這個的缺點是比較慢,尤其是用加log的方式來縮小懷疑的範圍。因爲這是一個不斷迭代的過程,最主要的原因,一開始不知道代碼哪個地方有問題。只能在所有可能有問題的地方加打印log。然後逐步的縮小懷疑範圍。下邊介紹一種快速的debug方法。

UT debug

什麼是UT

一半正兒八經的公司,一定會設計UT,UT是對單個功能測試的一種手段,相對於C++來說,測試單位是C++類的所有public方法,private方法通過public方法測試。

UT debug

UT的價值是可以發現之前肉眼沒有發現的錯誤。這也是TDD(測試開發驅動)這麼火的一個原因。

現在C++的UT大多都是GTest, Unitest已經很少有人用。GTest現在可以編譯出UT單獨的binary,直接使用gdb調試即可。

gdb binary # no args
gdb --args binary arg1 arg2 # has args.

在gdb內部使用gdb的命令即可。
包括如下常用命令。

# 下一步,不進入函數體
n/next
# 下一步,如果是子函數,那麼進入子函數
s/step
# 繼續運行代碼,直到代碼結束,或者遇到斷點
c/continue
# 打斷點 在main函數的90行打斷點
b main.cpp:90
# 查看當前上下文的變量值
info locals
# 查看當前函數傳入的形參值
info args

NOTE

  1. 有時候在使用gdb單步調試的時候,會出現明明是下一步,卻出現gdb向回跑的想象。
    原因:gcc在編譯代碼的時候加入了優化選項,比如-Os等等,去掉這些編譯選項,重新編譯即可。

SCT debug

什麼是SCT

MT測試的level比UT高,關注點不再是單個的類,而是在類之間的交互上,SCT的測試level比MT高,在整個binary上。
基本上相當於模擬整個binary的運行環境,進行測試。

業界公共一般使用pytest框架,這是一個python語言的框架,用這個框架將測試對象,也就是我們自己的binary 運行起來,然後等待外界輸入,也就是需要的測試交互。

SCT debug

startup binary under pytest

用C++代碼寫成的binary,會在pytest內部啓動。一般使用subprocess模塊啓動:如下命令啓動

self.__proc = subprocess.Popen(self.start_command, shell=True)

start_command:指的是運行自己binary的命令。例如下:

helloWorld arg

當然不僅僅是起來binary,你所有需要啓動這個binary的工作都要在pytest裏面搞定,具體如何使用就需要參照pytest自己的doc.

pytest case

參照pytest的doc寫case。

pytest breakpoint – pdb

首先給pytest的case打斷點, 有兩種方式

  1. 在case要斷點的位置,加入如下兩行代碼
import pdb
pdb.set_trace()
  1. 可以在運行pytest case的時候加入–trace選項
pytest --trace test_hello.py

gdb attach

由於我們自己的binary已經在pytest上啓動,也就是說不需要從gdb再次啓動,可以使用gdb attach的方式來attach到這個進程

實現的腳本如下:

gdbhelloworld.py

import os
import subprocess
pid = subprocess.check_output("pgrep helloworld", shell=True).strip()
print(pid)
gdb.execute('file ' + 'path of binary')
gdb.execute('attach ' + pid.decode('ascii'))

解釋:

  1. 使用pgrep helloworld獲取binary運行的進程號,
  2. 加載運行的binary來獲取符號表, file + binary
  3. attach + pid of binary即可

gdbhelloworld

#!/bin/bash

cgdb -x path of gdbhelloworld.py

解釋:
爲了方便使用,加入一個腳本,使用cgdb,方便看到調試代碼上下文。cgdb可以認爲是對gdb的一個封裝。可以一邊調試,一邊方便的看到當前正在運行的代碼上下文

調試

執行順序

  1. 執行帶有斷點的pytest.
  2. 然後執行 ./gdbhelloworld
  3. 在./gdbhelloworld中打斷點,如
b main.cpp:10
  1. 在3的基礎上輸入c,讓binary持續運行。
  2. 在pytest的pdb中單步調試,正在合適的時候就會執行到gdb的斷點位置。
  3. 然後就可以happy的玩耍了。

參考

None

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章