recover_pdb 原理與介紹

18
PDB 的使用與原理 果凍

description

Introduce how the pdb work. And how to extend pdb function. 介紹 pdb 的原理以及如何替 pdb 擴充功能

Transcript of recover_pdb 原理與介紹

Page 1: recover_pdb 原理與介紹

PDB 的使用與原理

果凍

Page 2: recover_pdb 原理與介紹

簡介

● 中興大學學士● 任職於曼克斯● 接觸 python 時間有七年● 喜歡學習新的程式語言● C、C++、java、golang。● Linkin: http://www.linkedin.

com/pub/kao-kuo-tung/67/9a2/6b3

● About me: http://about.me/ya790206

Page 3: recover_pdb 原理與介紹

PDB 常用指令介紹

1. break2. clear3. step4. next5. return6. continue7. jump8. list9. p

*可惜 pdb 無法做到監看變數改變的功能

Page 4: recover_pdb 原理與介紹

What is frame?

● 儲存 function 執行時的相關資訊,如區域變數、函數位址等資訊。

● 作用像 C 的 call stack( run-time stack )。

Page 5: recover_pdb 原理與介紹

PyFrameObjectf_back next outer frame object (this frame’s caller)f_code code object being executed in this framef_exc_traceback traceback if raised in this frame, or Nonef_exc_type exception type if raised in this frame, or Nonef_exc_value exception value if raised in this frame, or Nonef_globals global namespace seen by this framef_lineno current line number in Python source codef_locals local namespace seen by this framef_trace tracing function for this frame, or None

REF: http://docs.python.org/2/library/inspect.html

Page 6: recover_pdb 原理與介紹

fun1 call fun2, fun2 call fun3, fun3 call fun1

fun1's frame

fun2's frame

fun3's frame

fun1's frame

f_code

f_code

fun1's code object

fun2's code object

fun3's code object

f_back

f_back

f_back

f_code

f_code

frame 未必擺在連續的記憶體上,因此需要 f_back 的存在。詳情請見 PyFrame_New。

Page 7: recover_pdb 原理與介紹

More Detailsf_trace, if not None, is a function called at the start of each source code line (this is used by the debugger)

f_lineno is the current line number of the frame — writing to this from within a trace function jumps to the given line (only for the bottom-most frame).

Page 8: recover_pdb 原理與介紹

sys._getframe([depth])¶Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. If that is deeper than the call stack, ValueError is raised. The default for depthis zero, returning the frame at the top of the call stack.

sys.settrace(tracefunc)Set the system’s trace function, which allows you to implement a Python source code debugger in Python. The function is thread-specific; for a debugger to support multiple threads, it must be registered using settrace() for each thread being debugged.

Page 9: recover_pdb 原理與介紹

why?it must be registered using settrace() for each thread being debugged.

Because: each thread have their own starck. In the python, the stack means the frame.

process

thread

process

thread thread thread

Page 10: recover_pdb 原理與介紹

看看 pdb

● break => pdb:do_break -> bdb: set_break(just create break point)

● step => pdb:do_step -> bdb: set_step -> self._set_stopinfo

● return => pdb:do_return -> bdb:set_return -> self._set_stopinfo

Page 11: recover_pdb 原理與介紹

trace function => bdb:trace_dispatch -> bdb:dispatch_line -> stop_here -> pdb:user_line(frame) -> pdb:interaction

Page 12: recover_pdb 原理與介紹

問題

A: 當離開互動模式時,最上層的 frame 是有 bug code 的 frame。就像一般程式碼的執行,他會一直執行最上層的 frame 的 code。

Q: 當有 bug 的 code 呼叫 set_trace 時, pdb 要如何執行有 bug 的 code ?

Page 13: recover_pdb 原理與介紹

問題

Q: 我只有呼叫一次 pdb 的 set_trace,那為何程式可以重複進入 pdb 的方法?

A: 因為每一層 frame 的 f_trace 都設定成 self.trace_dispatch,所以每次在執行有bug 的 code 時,都會執行 self.trace_dispatch。所以藉由這個方法,可以重複進入 pdb 的方法。

Page 14: recover_pdb 原理與介紹

問題

A: 因為 pdb 把相關資料存在物件裡(如 self.xxx = yyy) 而非 frame 裡(如 xxx=yyy)

Q: 在執行有 bug 的 code 時,都是從 pdb 的方法 return 回來的。因此 pdb 方法的 frame 會被刪除。那為何我設定的中斷點資料不會消失?

Page 15: recover_pdb 原理與介紹

問題

Q: 既然 pdb 的資料是存在物件裡。可是我的程式碼( 有 bug 的 code) 並沒有變數指向 pdb 的物件,為何他不會被回收( garbage collection )?

A: 的確你的程式碼( 有 bug 的 code ) 沒有變數指向 pdb。但是 pdb 在每個 frame 偷偷動了手腳,讓每個 frame 的 f_trace 指向 pdb 物件的trace_dispatch。這就是他長生的秘密。

Page 16: recover_pdb 原理與介紹

recoverable_pdb

● github: https://github.com/ya790206/recoverable_pdb● Like time machine, you can recover the runtime to the

point you save.● addition command:

○ save point_name: save the current frame to the point.○ restore point_name: restore frame from the frame you

saved.○ diff point_name: compare the current frame and the

another you saved.● limit:

○ same as jump command.○ it can't recover file or database.

Page 17: recover_pdb 原理與介紹

為何需要自定義一個 try_copy?

1. 因為不是每個物件都可以被 copy。如 code object。

2. 因為 dict 除了給程式設計師用外,他也會被用來表示內部結構。因此需要對他做特別處理。

ref: http://docs.python.org/2/library/copy.html

Page 18: recover_pdb 原理與介紹

Thanks all

thanks for all listener, taipei.py, and the manx.

Taipe pyi: http://www.meetup.com/Taipei-py/

The manx:http://www.themanxgroup.tw/

The manx production:http://lucky-lane.com/