[Python] एक चल रहे पायथन एप्लिकेशन से स्टैक ट्रेस दिखा रहा है


Answers

सिग्नल हैंडलर स्थापित करने का सुझाव एक अच्छा है, और मैं इसका बहुत उपयोग करता हूं। उदाहरण के लिए, डिफ़ॉल्ट रूप से bzr एक सिग्क्विट हैंडलर स्थापित करता है जो आपको pdb.set_trace() को तुरंत pdb प्रॉम्प्ट में छोड़ने के लिए आमंत्रित करता है। (सटीक विवरण के लिए bzrlib.breakin मॉड्यूल का स्रोत देखें।) bzrlib.breakin साथ आप न केवल मौजूदा स्टैक ट्रेस प्राप्त कर सकते हैं बल्कि चर, आदि का निरीक्षण भी कर सकते हैं।

हालांकि, कभी-कभी मुझे एक प्रक्रिया को डीबग करने की आवश्यकता होती है जिसमें सिग्नल हैंडलर को स्थापित करने के लिए दूरदर्शिता नहीं थी। लिनक्स पर, आप प्रक्रिया में जीडीबी संलग्न कर सकते हैं और कुछ जीडीबी मैक्रोज़ के साथ एक अजगर स्टैक ट्रेस प्राप्त कर सकते हैं। ~/.gdbinit में http://svn.python.org/projects/python/trunk/Misc/gdbinit ~/.gdbinit , फिर:

  • जीडीबी संलग्न करें: gdb -p PID
  • पाइथन स्टैक ट्रेस प्राप्त करें: pystack

दुर्भाग्य से यह पूरी तरह से भरोसेमंद नहीं है, लेकिन यह ज्यादातर समय काम करता है।

आखिरकार, strace को जोड़ना अक्सर आपको एक अच्छा विचार दे सकता है कि एक प्रक्रिया क्या कर रही है।

Question

मेरे पास यह पायथन एप्लिकेशन है जो समय-समय पर अटक जाता है और मुझे पता नहीं चल सकता है।

क्या आपके पास चल रहे सटीक कोड को दिखाने के लिए पाइथन दुभाषिया को सिग्नल करने का कोई तरीका है?

कुछ प्रकार के ऑन-द-फ्लाई स्टैकट्रस?

संबंधित सवाल:




मैंने कुछ टूल एक साथ हैक किया जो एक चल रहे पायथन प्रक्रिया में संलग्न है और पाइथन खोल पाने के लिए कुछ कोड इंजेक्ट करता है।

यहां देखें: https://github.com/albertz/pydbattach




पायथन 3 में, पीडीबी डीबगर में पहली बार सी (ओएनटी (इन्यू)) का उपयोग करते समय एक सिग्नल हैंडलर स्थापित करेगा। कंट्रोल-सी दबाकर बाद में आपको वहां वापस छोड़ दिया जाएगा। पायथन 2 में, यहां एक-लाइनर है जो अपेक्षाकृत पुराने संस्करणों में भी काम करना चाहिए (2.7 में परीक्षण किया गया लेकिन मैंने पाइथन स्रोत को 2.4 पर वापस देखा और यह ठीक लग रहा था):

import pdb, signal
signal.signal(signal.SIGINT, lambda sig, frame: pdb.Pdb().set_trace(frame))

पीडीबी सीखने लायक है अगर आप पाइथन को डीबग करने में कितना समय बिताते हैं। इंटरफ़ेस थोड़ा उलझन में है लेकिन किसी भी व्यक्ति से परिचित होना चाहिए जिसने gdb जैसे समान टूल का उपयोग किया है।




मैं अपने धागे को डीबग करने के लिए एक समाधान के लिए थोड़ी देर की तलाश में था और मैंने इसे यहां haridsv के लिए धन्यवाद पाया। मैं traceback.print_stack () को नियोजित थोड़ा सरलीकृत संस्करण का उपयोग करता हूं:

import sys, traceback, signal
import threading
import os

def dumpstacks(signal, frame):
  id2name = dict((th.ident, th.name) for th in threading.enumerate())
  for threadId, stack in sys._current_frames().items():
    print(id2name[threadId])
    traceback.print_stack(f=stack)

signal.signal(signal.SIGQUIT, dumpstacks)

os.killpg(os.getpgid(0), signal.SIGQUIT)

मेरी जरूरतों के लिए मैं धागे को नाम से भी फ़िल्टर करता हूं।




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




सोलारिस पर, आप पस्टैक का उपयोग कर सकते हैं (1) पायथन कोड में कोई बदलाव आवश्यक नहीं है। जैसे।

# pstack 16000 | grep : | head
16000: /usr/bin/python2.6 /usr/lib/pkg.depotd --cfg svc:/application/pkg/serv
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:282 (_wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:295 (wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:242 (block) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/_init_.py:249 (quickstart) ]
[ /usr/lib/pkg.depotd:890 (<module>) ]
[ /usr/lib/python2.6/threading.py:256 (wait) ]
[ /usr/lib/python2.6/Queue.py:177 (get) ]
[ /usr/lib/python2.6/vendor-packages/pkg/server/depot.py:2142 (run) ]
[ /usr/lib/python2.6/threading.py:477 (run)
etc.



चल रहे पायथन प्रक्रिया में हुक करने और उचित परिणाम प्राप्त करने का कोई तरीका नहीं है। यदि प्रक्रिया लॉक हो जाती है तो मैं क्या कर रहा हूं और यह पता लगाने की कोशिश कर रहा हूं कि वास्तव में क्या हो रहा है।

दुर्भाग्य से अक्सर पर्यवेक्षक पर्यवेक्षक है जो दौड़ की स्थिति को "ठीक करता है" ताकि आउटपुट भी बेकार हो।




आप फाउथंडलर मॉड्यूल को आजमा सकते हैं। pip install faulthandler का उपयोग करके इसे स्थापित करें और जोड़ें:

import faulthandler, signal
faulthandler.register(signal.SIGUSR1)

आपके कार्यक्रम की शुरुआत में। फिर मानक प्रक्रिया में सभी धागे के पाइथन ट्रेसबैक को प्रदर्शित करने के लिए अपनी प्रक्रिया में SIGUSR1 भेजें (उदा: kill -USR1 42 )। अधिक विकल्पों के लिए प्रलेखन पढ़ें (उदा: फ़ाइल में लॉग इन करें) और ट्रेसबैक प्रदर्शित करने के अन्य तरीकों।

मॉड्यूल अब पायथन 3.3 का हिस्सा है। पायथन 2 के लिए, http://faulthandler.readthedocs.org/ देखें




मैं इसे हरिड्स की प्रतिक्रिया पर टिप्पणी के रूप में जोड़ूंगा , लेकिन मुझे ऐसा करने की प्रतिष्ठा नहीं है:

हम में से कुछ अभी भी 2.6 से पुराने पायथन के संस्करण पर फंस गए हैं (थ्रेड.डेंट के लिए आवश्यक), इसलिए मुझे पाइथन 2.5 में काम करने वाला कोड मिला (हालांकि थ्रेड नाम प्रदर्शित किए बिना):

import traceback
import sys
def dumpstacks(signal, frame):
    code = []
    for threadId, stack in sys._current_frames().items():
            code.append("\n# Thread: %d" % (threadId))
        for filename, lineno, name, line in traceback.extract_stack(stack):
            code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
            if line:
                code.append("  %s" % (line.strip()))
    print "\n".join(code)

import signal
signal.signal(signal.SIGQUIT, dumpstacks)



एक अपरिपक्व पायथन प्रोग्राम का एक स्टैक ट्रेस प्राप्त करना, डिबगिंग प्रतीकों के बिना स्टॉक पायथन में चलना pyrasite साथ किया जा सकता है। उबंटू ट्रस्टी में मेरे लिए एक आकर्षण की तरह काम किया:

$ sudo pip install pyrasite
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
$ sudo pyrasite 16262 dump_stacks.py # dumps stacks to stdout/stderr of the python program

(हैट टिप @ एल्बर्ट, जिसका जवाब अन्य उपकरणों के बीच एक सूचक था।)




traceback मॉड्यूल में उनके कुछ अच्छे फ़ंक्शन हैं: print_stack:

import traceback

traceback.print_stack()



मैं पाइथन एक्सटेंशन के साथ जीडीबी शिविर में हूं। https://wiki.python.org/moin/DebuggingWithGdb का पालन https://wiki.python.org/moin/DebuggingWithGdb , जिसका अर्थ है

  1. dnf install gdb python-debuginfo या sudo apt-get install gdb python2.7-dbg
  2. gdb python <pid of running process>
  3. py-bt

info threads और thread apply all py-bt पर भी विचार thread apply all py-bt