プロセスの状態を確認したいだけです。コンソールをプロセスにアタッチして、プロセス内の関数を呼び出して、いくつかのグローバル変数を確認することは可能ですか。
プロセスは影響を受けずに実行されている方が良いです(もちろん、パフォーマンスは少し低下する可能性があります)
プロセスの状態を確認したいだけです。コンソールをプロセスにアタッチして、プロセス内の関数を呼び出して、いくつかのグローバル変数を確認することは可能ですか。
プロセスは影響を受けずに実行されている方が良いです(もちろん、パフォーマンスは少し低下する可能性があります)
回答:
プログラムのソースコードにアクセスできる場合は、この機能を比較的簡単に追加できます。
レシピ576515を参照してください:Debugging a running python process by interrupting and providing an interactive prompt (Python)
引用するには:
これは、それを使用するすべてのPythonプログラムが現在の時点で中断され、通常のPythonインタラクティブコンソールを介して通信できるようにするコードを提供します。これにより、ローカル、グローバル、および関連するプログラムの状態を調査したり、任意の関数やクラスを呼び出したりすることができます。
使用するには、プロセスがモジュールをインポートし、起動中の任意の時点でlisten()を呼び出す必要があります。このプロセスを中断するには、スクリプトを直接実行して、デバッグするプロセスのプロセスIDをパラメーターとして指定します。
ほぼ同じ概念の別の実装がrconsoleによって提供されます。ドキュメントから:
rconsoleは、オートコンプリート機能を備えたリモートPythonコンソールであり、実行中のスクリプトの名前空間を検査および変更するために使用できます。
スクリプトで呼び出すには、次のようにします。
from rfoo.utils import rconsole
rconsole.spawn_server()
シェルからアタッチするには、次のようにします。
$ rconsole
セキュリティに関する注意:spawn_server()で開始されたrconsoleリスナーはすべてのローカル接続を受け入れるため、共有ホスティングまたは同様の環境での使用は安全でない可能性があります。
rfoo._rfoo.EofError: 0
これによりプロセスが中断されますが(スレッドで開始しない限り)、codeモジュールを使用してPythonコンソールを開始できます。
import code
code.interact()
これは、ユーザーがを実行してインタラクティブコンソールを終了するまでブロックされexit()ます。
このcodeモジュールは、少なくともPython v2.6、おそらく他のバージョンで利用できます。
私はこのアプローチをLinux作業のシグナルと組み合わせて使用する傾向があります(Windowsの場合は以下を参照)。Pythonスクリプトの先頭でこれを叩きます:
import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())
次にkill -SIGUSR2 <PID>、<PID>はプロセスIDであるシェルからトリガーします。次に、プロセスは実行中の処理をすべて停止し、コンソールを表示します。
Python 2.6.2 (r262:71600, Oct 9 2009, 17:53:52)
[GCC 3.4.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
通常、そこから、優れたWinPDBのようなリモートデバッガーのサーバー側コンポーネントをロードします。
WindowsはPOSIX準拠のOSではないため、Linuxと同じ信号を提供しません。ただし、Python v2.2以降では、Windows固有のシグナルが公開されますSIGBREAK(CTRL+を押すとトリガーされPause/Breakます)。これは通常の+ ()操作に干渉しないため、便利な代替手段です。CTRLCSIGINT
したがって、上記のポータブルで少し醜いバージョンは次のとおりです。
import code
import signal
signal.signal(
vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"),
lambda sig, frame: code.interact()
)
このアプローチの利点:
これは、WinPDBのサーバー側(利用可能な場合)をロードし、Pythonコンソールを開くことにフォールバックする本番環境で使用するコードです。
# Break into a Python console upon SIGUSR1 (Linux) or SIGBREAK (Windows:
# CTRL+Pause/Break). To be included in all production code, just in case.
def debug_signal_handler(signal, frame):
del signal
del frame
try:
import rpdb2
print
print
print "Starting embedded RPDB2 debugger. Password is 'foobar'"
print
print
rpdb2.start_embedded_debugger("foobar", True, True)
rpdb2.setbreak(depth=1)
return
except StandardError:
pass
try:
import code
code.interact()
except StandardError as ex:
print "%r, returning to normal program flow" % ex
import signal
try:
signal.signal(
vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR1"),
debug_signal_handler
)
except ValueError:
# Typically: ValueError: signal only works in main thread
pass
ピラサイトシェルを使用します。うまくいくとは信じられませんが、うまくいきます。「それにpidを与えて、シェルを手に入れなさい」。
$ sudo pip install pyrasite
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # If YAMA activated, see below.
$ pyrasite-shell 16262
Pyrasite Shell 2.0
Connected to 'python my_script.py'
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> globals()
>>> print(db_session)
>>> run_some_local_function()
>>> some_existing_local_variable = 'new value'
これにより、実行中のpythonプロセスのglobals()変数とlocals()変数、およびその他のすばらしいものにアクセスできるpythonシェルが起動します。
これはUbuntuで個人的にテストしただけですが、OSXにも対応しているようです。
この答えから適応。
注:ptrace_scopeプロパティをオフにする回線は、CONFIG_SECURITY_YAMAオンで構築されたカーネル/システムにのみ必要です。特定のセキュリティの脆弱性が発生する可能性があるため、機密性の高い環境でptrace_scopeをいじることに注意してください。詳細はこちらをご覧ください。
単にpdbモジュールを使用しないのはなぜですか?これにより、スクリプトを停止し、要素の値を検査し、コードを1行ずつ実行できます。また、Pythonインタープリターに基づいて構築されているため、従来のインタープリターが提供する機能も提供します。これを使用するには、コードに次の2行を入れて、停止して検査します。
import pdb
pdb.set_trace()
Pythonスクリプトに何かを追加せずに、別の可能性をここで説明します。
https://wiki.python.org/moin/DebuggingWithGdb
残念ながら、このソリューションには、少なくともデバッグシンボルを含むバージョンのPythonを使用する必要がある限り、ある程度の事前の考慮が必要です。
PyCharmを使用して、Ubuntuのプロセスに接続できませんでした。これに対する修正は、YAMAを無効にすることです。詳細については、askubuntuを参照してください
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope