2014-04-18 6 views
5

मैं बहु-थ्रेड स्क्रिप्ट को डिबग करने का प्रयास कर रहा हूं। एक बार जब अपवाद उठाया है मैं चाहता हूँ:मल्टी-थ्रेड स्क्रिप्ट्स के पोस्ट मॉर्टम डिबगिंग

  1. निगरानी प्रणाली के लिए रिपोर्ट में यह (सिर्फ उदाहरण निम्नलिखित में मुद्रित)
  2. एक में पूरी स्क्रिप्ट (सभी अन्य धागे सहित) को रोकने के
  3. कॉल पोस्टमार्टम डिबगर शीघ्र परिप्रेक्ष्य उठाया अपवाद

मैं बहुत जटिल उदाहरण तैयार दिखाने के लिए कि कैसे मैं इसे हल करने की कोशिश की:

#!/usr/bin/env python 

import threading 
import inspect 
import traceback 
import sys 
import os 
import time 


def POST_PORTEM_DEBUGGER(type, value, tb): 
    traceback.print_exception(type, value, tb) 
    print 
    if hasattr(sys, 'ps1') or not sys.stderr.isatty(): 
     import rpdb 
     rpdb.pdb.pm() 
    else: 
     import pdb 
     pdb.pm() 

sys.excepthook = POST_PORTEM_DEBUGGER 



class MyThread(threading.Thread): 

    def __init__(self): 

     threading.Thread.__init__(self) 
     self.exception = None 
     self.info = None 
     self.the_calling_script_name = os.path.abspath(inspect.currentframe().f_back.f_code.co_filename) 

    def main(self): 
     "Virtual method to be implemented by inherited worker" 
     return self 

    def run(self): 
     try: 
      self.main() 
     except Exception as exception: 
      self.exception = exception 
      self.info = traceback.extract_tb(sys.exc_info()[2])[-1] 
      # because of bug http://bugs.python.org/issue1230540 
      # I cannot use just "raise" under threading.Thread 
      sys.excepthook(*sys.exc_info()) 

    def __del__(self): 
     print 'MyThread via {} catch "{}: {}" in {}() from {}:{}: {}'.format(self.the_calling_script_name, type(self.exception).__name__, str(self.exception), self.info[2], os.path.basename(self.info[0]), self.info[1], self.info[3]) 




class Worker(MyThread): 

    def __init__(self): 
     super(Worker, self).__init__() 

    def main(self): 
     """ worker job """ 
     counter = 0 
     while True: 
      counter += 1 
      print self 
      time.sleep(1.0) 
      if counter == 3: 
       pass # print 1/0 


def main(): 

    Worker().start() 

    counter = 1 
    while True: 
     counter += 1 
     time.sleep(1.0) 
     if counter == 3: 
      pass # print 1/0 

if __name__ == '__main__': 
    main() 

sys.excepthook = POST_PORTEM_DEBUGGER 

काम करता है पूरी तरह से अगर कोई सूत्र शामिल कर रहे हैं के साथ चाल। मैंने पाया है कि फोन करके बहु धागा स्क्रिप्ट के मामले में मैं debuggig के लिए rpdb उपयोग कर सकते हैं:

import rpdb; rpdb.set_trace() 

यह परिभाषित ब्रेकप्वाइंट के लिए पूरी तरह से काम करता है, लेकिन मैं ( बहु धागा स्क्रिप्ट पोस्टमार्टम डिबग करने के लिए uncatched अपवाद के बाद चाहते हैं उठाया गया है)। मैं निम्नलिखित मिल जब मैं बहु धागा आवेदन के साथ POST_PORTEM_DEBUGGER समारोह में rpdb इस्तेमाल करने की कोशिश:

Exception in thread Thread-1: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner 
     self.run() 
    File "./demo.py", line 49, in run 
     sys.excepthook(*sys.exc_info()) 
    File "./demo.py", line 22, in POST_PORTEM_DEBUGGER 
     pdb.pm() 
    File "/usr/lib/python2.7/pdb.py", line 1270, in pm 
     post_mortem(sys.last_traceback) 
AttributeError: 'module' object has no attribute 'last_traceback' 

मैं

sys.excepthook(*sys.exc_info()) 

कैसा दिखता raise आदेश करता है पूरी तरह तैयार नहीं था। यदि मैं प्रारंभिक थ्रेड के तहत मुख्य() में अपवाद उठाया गया है तो मैं वही व्यवहार चाहता हूं।

उत्तर

0

(मैं अपने जवाब का परीक्षण नहीं किया है, लेकिन यह मुझे लगता है कि ...)

pdb.pm (बजे = "पोस्टमार्टम") करने के लिए कॉल बस में विफल रहता है क्योंकि वहाँ कोई "मार्टम किया गया था "इससे पहले। अर्थात। कार्यक्रम अभी भी चल रहा है।

def pm(): 
    post_mortem(sys.last_traceback) 

जो मुझे लगता है कि क्या आप वास्तव में क्या करना चाहते हैं कोई आर्ग के साथ कॉल pdb.post_mortem() है बनाता है:

pdb स्रोत कोड को देखते हुए, आप pdb.pm के कार्यान्वयन पाते हैं। ऐसा लगता है कि डिफ़ॉल्ट व्यवहार आपको वही करता है जो आपको चाहिए।

कुछ और स्रोत कोड (नोटिस t = sys.exc_info()[2] लाइन):

def post_mortem(t=None): 
    # handling the default 
    if t is None: 
     # sys.exc_info() returns (type, value, traceback) if an exception is 
     # being handled, otherwise it returns None 
     t = sys.exc_info()[2] 
     if t is None: 
      raise ValueError("A valid traceback must be passed if no " 
               "exception is being handled") 

    p = Pdb() 
    p.reset() 
    p.interaction(None, t) 
+0

टिप के लिए धन्यवाद। लेकिन यह ValeError अपवाद के साथ समाप्त होता है ('टी कोई नहीं है ')। ऐसा लगता है कि 'sys.excepthook (* sys.exc_info())' कॉल 'सेट नहीं करता है जो' raise 'करता है। –

0

यह आपकी मदद कर सकते हैं:

import sys 
from IPython.core import ultratb 

sys.excepthook = ultratb.FormattedTB(mode='Verbose', color_scheme='Linux', 
    call_pdb=True, ostream=sys.__stdout__) 
संबंधित मुद्दे