PythonでGDBを使用して転載をデバッグ

11719 ワード

約1年前、JavaのBtraceがオンラインJVMの稼働状況をダウンタイムなく表示できる特性に触れてうらやましくなりました.また、強力なjStackとjConsoleが運行期間の偵察を行い、JVMの工業級強度はやはり蓋ではない.
当時、会社の技術面でもいくつかのボトルネックに直面し、一部の原因はCPython自身のIOモデルの問題であり、一方では初期のコードの書かれた極めて不細工と関係がなかった.仕方なく、私たちはJythonで主要業務を覆してやり直し、効果はすぐに現れたが、同時に真実の問題を回避した.
その後、私たちはJVMの指導の下で、康庄通りを歩いた.しかし、私の心の中には、性能がボトルネックになっているPython Processをオンラインで検出したいという梗塞があります.この文章は最初の一歩だ.
PS:この文章は理論的には可能ですが、私の機械(Ubuntu 12.04/システムにPythonが付属している)が正常に実行できないと、unable to read python frame informationの問題が爆発します.解決方法は次の文章に書きます.ここでは単純に原文を翻訳します.
原文は移動可能https://wiki.python.org/moin/DebuggingWithGdb.
Pythonを使用して直接debugを行うのは難しいタイプのbugsがあります.例えば、
セグメントエラー(キャプチャできないPython異常)引っかかるプロセス(この場合はpdbを用いて追跡できない).
制御以外のバックグラウンド処理daemonプロセスこれらの場合、gdbを使用して試してみることができます.
の準備を
システムにgdbとPython debug拡張をインストールする必要があります.Python debug拡張には、いくつかのdebugコマンドが含まれており、gdbにPython固有のコマンドが追加されています.主流のLinuxリリースでは、簡単にインストールできます.
Fedora:
1
sudo yum install gdb python-debuginfo

Ubunt:
1
sudo apt-get install gdb python2.7-dbg

いくつかの古いシステムでは、gdbも使用できます.具体的には、文章の末尾を見てください.GDBの使用
2つの方法があります.
最初からgdbを使用してアプリケーションを起動する.
実行中のPythonプロセスに接続gdbの下でPythonを起動するには、2つの方法があります.
対話型:
1
2
3
$ gdb python
...
(gdb) run .py 

自動:
1
$ gdb -ex r --args python .py 

これにより、終了、セグメントエラー、または人為的な停止まで動作します(Ctrl+Cを使用).
プロセスがすでに実行されている場合は、PIDでアクセスできます.
1
$ gdb python 

デバッグプロセス
プログラムセグメントが間違っている場合は、gdbが自動的にプログラムを一時停止し、gdbコマンドラインに切り替えてステータスを確認できます.Ctrl+Cを人為的に使用してプログラムの実行を一時停止することもできます.
EasierpythonDebuggingでgdbのPythonコマンドのリストを表示します.
C呼び出しスタックの表示
debugセグメントでエラーが発生した場合、最もやりたいことはC呼び出しスタックを表示することです.gdbのコマンドラインでは、コマンドを実行するだけです.
1
2
3
4
5
6
7
8
9
10
(gdb) bt
#0  0x0000002a95b3b705 in raise () from /lib/libc.so.6
#1  0x0000002a95b3ce8e in abort () from /lib/libc.so.6
#2  0x00000000004c164f in posix_abort (self=0x0, noargs=0x0)
    at ../Modules/posixmodule.c:7158
#3  0x0000000000489fac in call_function (pp_stack=0x7fbffff110, oparg=0)
    at ../Python/ceval.c:3531
#4  0x0000000000485fc2 in PyEval_EvalFrame (f=0x66ccd8)
    at ../Python/ceval.c:2163
...

運が良ければ、問題がどこにあるかを直接見ることができます.提供された情報が直接問題を解決できない場合は、呼び出しスタックを追跡し続けてみてください.変調の結果はdebug情報の有効度に依存する.
Python呼び出しスタックの表示
Python拡張機能がインストールされている場合は、
1
(gdb) py-bt

おなじみのPythonソースコードを入手できます.
保留中のプロセスにメスを入れる
プロセスが詰まっているように見える場合は、ロックやIOなど、何かを待っている可能性があります.必死にループしている可能性もあります.このプロセスに接続して、呼び出しスタックをチェックすると役に立つかもしれません.
プロセスがクレイジーループしている場合は、まずそれをしばらく実行させ、contコマンドを使用し、Ctrl+Cを使用して一時停止し、呼び出しスタックを印刷することができます.
スレッドが詰まっている場合は、次のコマンドが役立ちます.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(gdb) info threads
  Id   Target Id         Frame
  37   Thread 0xa29feb40 (LWP 17914) "NotificationThr" 0xb7fdd424 in __kernel_vsyscall ()
  36   Thread 0xa03fcb40 (LWP 17913) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
  35   Thread 0xa0bfdb40 (LWP 17911) "QProcessManager" 0xb7fdd424 in __kernel_vsyscall ()
  34   Thread 0xa13feb40 (LWP 17910) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
  33   Thread 0xa1bffb40 (LWP 17909) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
  31   Thread 0xa31ffb40 (LWP 17907) "QFileInfoGather" 0xb7fdd424 in __kernel_vsyscall ()
  30   Thread 0xa3fdfb40 (LWP 17906) "QInotifyFileSys" 0xb7fdd424 in __kernel_vsyscall ()
  29   Thread 0xa481cb40 (LWP 17905) "QFileInfoGather" 0xb7fdd424 in __kernel_vsyscall ()
  7    Thread 0xa508db40 (LWP 17883) "QThread" 0xb7fdd424 in __kernel_vsyscall ()
  6    Thread 0xa5cebb40 (LWP 17882) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
  5    Thread 0xa660cb40 (LWP 17881) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
  3    Thread 0xabdffb40 (LWP 17876) "gdbus" 0xb7fdd424 in __kernel_vsyscall ()
  2    Thread 0xac7b7b40 (LWP 17875) "dconf worker" 0xb7fdd424 in __kernel_vsyscall ()
* 1    Thread 0xb7d876c0 (LWP 17863) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()

現在実行されているスレッドは*とマークされています.Pythonコードがどこで実行されているかを表示するには、py-listを使用して表示します.
1
2
3
4
5
6
7
8
9
10
11
12
(gdb) py-list
2025        # Open external files with our Mac app
2026        if sys.platform == "darwin" and 'Spyder.app' in __file__:
2027            main.connect(app, SIGNAL('open_external_file(QString)'),
2028                         lambda fname: main.open_external_file(fname))
2029
>2030        app.exec_()
2031        return main
2032
2033
2034    def __remove_temp_session():
2035        if osp.isfile(TEMP_SESSION_PATH):

すべてのプロセスのPythonコードの場所を表示します.
“` (gdb) thread apply all py-list … 200 201 def accept(self):
202 sock, addr = self.sock.accept() 203 return socketobject(sock=sock), addr 204 accept.doc = realsocket.accept.doc 205 206 def dup(self): 207 “”“dup() -> socket object
Thread 35 (Thread 0xa0bfdb40 (LWP 17911)): Unable to locate python frame
Thread 34 (Thread 0xa13feb40 (LWP 17910)): 197 for method in delegate_methods: 198 setattr(self, method, dummy) 199 close.doc =realsocket.close.doc 200 201 def accept(self):
202 sock, addr = self.sock.accept() 203 return socketobject(_sock=sock), addr …
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
##    ##
* [http://fedoraproject.org/wiki/Features/EasierPythonDebugging](http://fedoraproject.org/wiki/Features/EasierPythonDebugging)
* [https://code.google.com/p/spyderlib/wiki/HowToDebugDeadlock](https://code.google.com/p/spyderlib/wiki/HowToDebugDeadlock)
##       GDB ##
               `gdb`,            :
### GDB Macros ###
     Python     GDB          Python   。
     Python       `Misc/gdbinit`      `~/.gdbinit`,
    [Subversion](http://svn.python.org/view/python/branches/release27-maint/Misc/gdbinit?view=log)
     。      Python,           ,            。
        GDB       debug             。
      Ubuntu     gcc 4.5.2    ,     
`No symbol "co" in current context.`,    `call_function`  
[PyEval_EvalFrameEx](https://wiki.python.org/moin/EvalFrameEx)  
[PyEval_EvalCodeEx](https://wiki.python.org/moin/EvalCodeEx)   。
     `make "CFLAGS=-g -fno-inline -fno-strict-aliasing"`
   Python         。
###    Python Stack Traces GDB    ##
  gdb     ,       Python stack trace:

(gdb) pystack
1
2
   ,       stack frame   Python   :

(gdb) pystackv “`
より多くのgdbinitで定義されていない有用なスクリプトは、ここで見つけることができます.
http://web.archive.org/web/20070915134837/http://www.mashebali.com/?Python_GDB_macros:The_Macros
著作権所有© 2010転載当駅の文章は明記してください:Log 4 Dの原文のリンクから転載します:http://blog.log4d.com/2013/11/python-gdb/当サイトの文章を自由に転載することができますが、目立つ位置にソースと当サイトのリンクを明記する必要があります.当サイトの文章を商業化して使用したり、修正したり、変換したり、本作品をベースに創作したりすることはできません.3a1ff193cee606bd1e2ea554a16353ee