अजगर: क्या एक चल रही प्रक्रिया में एक कंसोल संलग्न करना संभव है


81

मैं सिर्फ प्रक्रिया की स्थिति को देखना चाहता हूं, क्या प्रक्रिया में एक कंसोल को संलग्न करना संभव है, इसलिए मैं प्रक्रिया के अंदर कार्यों को लागू कर सकता हूं और कुछ वैश्विक चर देख सकता हूं।

यह बेहतर है कि प्रक्रिया प्रभावित हुए बिना चल रही है (निश्चित रूप से प्रदर्शन थोड़ा कम हो सकता है)


7
मूल रूप से, एक डिबगर?
— 11:00

कमांड लाइन दुभाषिया python.exe की तरह कुछ
— बिन चेन

जवाबों:


42

यदि आपके पास कार्यक्रम के स्रोत-कोड तक पहुंच है, तो आप इस कार्यक्षमता को अपेक्षाकृत आसानी से जोड़ सकते हैं।

रेसिपी 576515 देखें :Debugging a running python process by interrupting and providing an interactive prompt (Python)

उद्धरण के लिए:

यह किसी भी अजगर कार्यक्रम को अनुमति देने के लिए कोड प्रदान करता है जो इसे वर्तमान बिंदु पर बाधित करने के लिए उपयोग करता है, और एक सामान्य अजगर इंटरएक्टिव कंसोल के माध्यम से संचार करता है। यह स्थानीय लोगों, ग्लोबल्स और संबद्ध कार्यक्रम राज्य की जांच करने की अनुमति देता है, साथ ही साथ मनमाने कार्यों और कक्षाओं को बुलाता है।

उपयोग करने के लिए, एक प्रक्रिया को मॉड्यूल आयात करना चाहिए, और स्टार्टअप के दौरान किसी भी बिंदु पर कॉल () सुनना चाहिए। इस प्रक्रिया को बाधित करने के लिए, स्क्रिप्ट को सीधे चलाया जा सकता है, प्रक्रिया की प्रक्रिया आईडी को पैरामीटर के रूप में डीबग करने के लिए दे रही है।


लगभग एक ही अवधारणा का एक और कार्यान्वयन rconsole द्वारा प्रदान किया गया है । प्रलेखन से:

rconsole ऑटो कम्प्लीट होने के साथ एक रिमोट पायथन कंसोल है, जिसका उपयोग रनिंग स्क्रिप्ट के नामस्थान का निरीक्षण और संशोधन करने के लिए किया जा सकता है।

एक स्क्रिप्ट में आह्वान करने के लिए:

from rfoo.utils import rconsole
rconsole.spawn_server()

एक शेल से संलग्न करने के लिए:

$ rconsole

सुरक्षा नोट: rconsole श्रोता ने spawn_server () के साथ शुरू किया, जो किसी भी स्थानीय कनेक्शन को स्वीकार करेगा और इसलिए साझा होस्टिंग या समान वातावरण में उपयोग करने के लिए असुरक्षित हो सकता है!


2
यह वास्तव में एक बहुत अच्छा नुस्खा है। इनपुट और आउटपुट के लिए पाइप और फ़ाइलों का उपयोग करना वास्तव में चतुर है और मुझे लगता है कि इस तरह की कार्यक्षमता से किसी भी सभ्य परियोजना को फायदा होगा।
— एर्गमेनेन

2
हालांकि यह बहुत असुरक्षित है, इसलिए देखभाल के साथ उपयोग करें
— हस्ताक्षर करें

मैंने नुस्खा की कोशिश की और इसने मेरे अजगर को स्थापित कर दिया। 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता नहीं है 'गेटम्रो'
— विक्टर 'क्रिस'

मैंने स्टेक को कोड में जोड़ने और आरपीसी सर्वर शुरू करने के बाद साइथन एक्सटेंशन को संकलित किया, लेकिन रेकसोल हमेशा किसी भी ऑपरेशन पर अपमानजनक रूप से टूट जाएगा। rfoo._rfoo.EofError: 0
— सजुक

60

यह आपकी प्रक्रिया को बाधित करेगा (जब तक कि आप इसे एक सूत्र में शुरू नहीं करते), लेकिन आप codeपायथन कंसोल को शुरू करने के लिए मॉड्यूल का उपयोग कर सकते हैं :

import code
code.interact()

यह तब तक ब्लॉक रहेगा जब तक कि उपयोगकर्ता इंटरैक्टिव कंसोल को निष्पादित करके बाहर नहीं निकलता है exit()।

codeमॉड्यूल कम से कम अजगर v2.6, शायद दूसरों में उपलब्ध है।

मैं अपने लिनक्स काम के लिए संकेतों के साथ संयोजन में इस दृष्टिकोण का उपयोग करता हूं (विंडोज के लिए, नीचे देखें)। मैं इसे अपनी पायथन लिपियों में सबसे ऊपर रखता हूँ:

import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())

और फिर इसे शेल से ट्रिगर करें kill -SIGUSR2 <PID>, जहां <PID>प्रक्रिया आईडी है। प्रक्रिया तब जो कुछ भी कर रही है उसे रोकता है और एक कंसोल प्रस्तुत करता है:

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 की तरह एक दूरस्थ डिबगर के सर्वर-साइड घटक को लोड करूँगा ।

विंडोज एक POSIX -compliant OS नहीं है, और इसलिए यह लिनक्स के समान संकेत प्रदान नहीं करता है। हालाँकि, 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()
        )

इस दृष्टिकोण के लाभ:

  • कोई बाहरी मॉड्यूल (सभी मानक पायथन सामान)
  • ट्रिगर होने तक किसी भी संसाधन का उपभोग करता है (2x आयात)

यहाँ मैं अपने उत्पादन वातावरण में कोड का उपयोग करता हूं जो WinPDB (यदि उपलब्ध हो) के सर्वर-साइड को लोड करेगा और पायथन कंसोल को खोलने के लिए वापस आ जाएगा।

# 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

क्या आप पायथन कंसोल होने के बाद WinPDB के सर्वर-साइड घटक को लोड करने के तरीके के बारे में अधिक जानकारी दे सकते हैं?
— क्रिश्चियन लॉन्ग

1
मैंने उत्तर में अपना उत्पादन कोड जोड़ा है, लेकिन अनिवार्य रूप से आपको केवल एक कंसोल पर निम्नलिखित दर्ज करने की आवश्यकता है: '' rpdb2 आयात करें; rpdb2.start_embedded_debugger ("फ़ॉबर", ट्रू, ट्रू) '' और तब पासवर्ड के साथ WinPDB GUI लॉन्च करें जब संकेत दिया जाए
— RobM

26

पायरसाइट-शेल का उपयोग करें । मुझे विश्वास नहीं होता कि यह इतना अच्छा काम करता है, लेकिन यह करता है। " इसे पिला दो, एक खोल दो "।

$ 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'

यह पायथन शेल को ग्लोबल्स () और स्थानीय (उस चल रहे अजगर प्रक्रिया के चर) और अन्य अद्भुत चीजों तक पहुंच के साथ लॉन्च करता है।

केवल इसे व्यक्तिगत रूप से उबंटू पर परीक्षण किया गया है, लेकिन यह ओएसएक्स के लिए भी पूरा करता है।

इस उत्तर से अनुकूलित ।

नोट: ptrace_scopeसंपत्ति को स्विच करने वाली लाइन केवल गुठली / सिस्टम के लिए आवश्यक है जिसे इसके साथ बनाया CONFIG_SECURITY_YAMAगया है। संवेदनशील वातावरण में ptrace_scope के साथ खिलवाड़ करने का ध्यान रखें क्योंकि यह कुछ सुरक्षा कमजोरियों का परिचय दे सकता है। देखें यहाँ जानकारी के लिए।


@ मुझे लगता है कि ptrace_scope एक प्रक्रिया को किसी अन्य असंबंधित प्रक्रिया का पता लगाने / बातचीत करने की अनुमति देने के लिए आवश्यक है।
— python1981

जाहिर है कि केवल उन प्रणालियों पर है जिनके पास YAMA है। संपादित किया गया और मेरी मूल टिप्पणी को हटा दिया गया। (यह भी कुछ समय के भीतर जाने के लिए।)
— डिर्क

डॉकर में उपयोग करने के लिए यहां देखें: stackoverflow.com/questions/37072468/…
— माइकल स्टाइनबर्ग

4

बस pdb मॉड्यूल का उपयोग क्यों नहीं किया जाता है ? यह आपको एक स्क्रिप्ट को रोकने, तत्वों के मूल्यों का निरीक्षण करने और कोड लाइन को लाइन से निष्पादित करने की अनुमति देता है। और चूंकि यह पायथन इंटरप्रेटर पर बनाया गया है, इसलिए यह क्लासिक दुभाषिया द्वारा प्रदान की गई सुविधाओं को भी प्रदान करता है। इसका उपयोग करने के लिए, बस अपने कोड में ये 2 लाइनें डालें, जहाँ आप इसे रोकना और उसका निरीक्षण करना चाहते हैं:

import pdb
pdb.set_trace()

3
क्या आप जानते हैं कि इसे थ्रेडिंग के एक थ्रेड के लिए कैसे लॉन्च किया जाए।
— yucer

4

एक और संभावना, अजगर लिपियों में सामान जोड़े बिना, यहाँ वर्णित है:

https://wiki.python.org/moin/DebuggingWithGdb

दुर्भाग्य से, इस समाधान के लिए कुछ पूर्वाभास की आवश्यकता होती है, कम से कम इस हद तक कि आपको इसमें प्रतीकों को डिबग करने के साथ अजगर के एक संस्करण का उपयोग करने की आवश्यकता होती है।


अधिकांश लिनक्स वितरण के लिए, अजगर डिबगिंग प्रतीकों के साथ बनाया गया है, लेकिन डिबगिंग प्रतीकों एक अलग पैकेज में रहते हैं। डिबगिंग सिंबल पैकेज को आपके पाइथन लिपि के शुरू होने के बाद स्थापित किया जा सकता है।
— डब्ल्यू। एमएन

1

PyCharm का उपयोग करते हुए, मुझे उबंटू में प्रक्रिया से जुड़ने में विफलता मिल रही थी। इसके लिए फिक्स YAMA को अक्षम करना है। अधिक जानकारी के लिए Askubuntu देखें

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.