2012-12-19 19 views
5

में क्रैशिंग (शायद ही कभी) एप्लिकेशन लॉन्च करने के लिए कैसे मुझे पाइथन एप्लिकेशन मिल रहा है जिसे दिन में लगभग 20 000 बार स्वामित्व एप्लिकेशन (जो समय-समय पर दुर्घटनाग्रस्त) निष्पादित करने की आवश्यकता होती है।सबप्रोसेस

समस्या तब होती है जब एप्लिकेशन क्रैश हो जाता है, विंडोज स्वचालित रूप से WerFault ट्रिगर करता है जो प्रोग्राम लटकता रहेगा, इस प्रकार python's subprocess.call() उपयोगकर्ता इनपुट के लिए हमेशा के लिए इंतजार करेगा (उस एप्लिकेशन को सप्ताहांत पर, छुट्टियों पर, 24/7 पर चलना होगा ... तो यह है स्वीकार्य नहीं है)।

तो sleep; poll; kill; terminate का उपयोग कर, लेकिन वह communicate() उपयोग करने की क्षमता खोने का मतलब होगा के बारे में, आवेदन 2 घंटे के लिए कुछ मिलीसेकंड से चला सकते हैं, हालांकि, तो सेटिंग तय समय समाप्ति अप्रभावी

मैं भी turning on automatic debugging की कोशिश की हो जाएगा (एक स्क्रिप्ट जायें जो कि का उपयोग किसी एप्लिकेशन का क्रैश डंप लें और आईडी को समाप्त करें), लेकिन किसी भी तरह यह कैसे मेरे सर्वर पर काम नहीं करता है (WerFault अभी भी दिखाई देता है और उपयोगकर्ता इनपुट के लिए प्रतीक्षा करता है)।

this जैसे कई अन्य ट्यूटोरियल ने कोई प्रभाव नहीं लिया।

प्रश्न: क्या वेरफ़ॉल्ट को प्रदर्शित करने से रोकने के लिए एक तरीका है (उपयोगकर्ता इनपुट के लिए प्रतीक्षा)? इस अधिक तो प्रोग्रामिंग प्रश्न प्रणाली है

वैकल्पिक प्रश्न: वहाँ एक सुंदर अजगर में जिस तरह से कैसे अनुप्रयोग क्रैश पता लगाने के लिए (चाहे WerFault प्रदर्शित किया गया था)

+0

आप बहिष्करण सूची को बाहर करने के लिए क्रैशिंग एप्लिकेशन जोड़ सकते हैं और फिर क्रैश डंप के लिए स्थानीय डंप पर निर्भर कर सकते हैं। Http://msdn.microsoft.com/en-us/library/windows/desktop/bb513617%28v=vs.85%29.aspx – nanda

+0

पर आपने देखा है http://stackoverflow.com/questions/5069224/handling -subprocess-crash-in-windows – n611x007

उत्तर

2

सरल (और बदसूरत) जवाब है, समय से WerFault.exe उदाहरण के लिए समय पर, विशेष रूप से अपमानजनक आवेदन की PID के साथ जुड़े एक निगरानी। और इसे मार डालो। WerFault.exe से निपटना जटिल है लेकिन आप इसे अक्षम नहीं करना चाहते हैं - Windows Error Reporting सेवा देखें।

  1. WerFault.exe से मेल खाने वाले नामों की प्रक्रियाओं की एक सूची प्राप्त करें। मैं psutil पैकेज का उपयोग करता हूं। psutil से सावधान रहें क्योंकि प्रक्रियाओं को कैश किया गया है, psutil.get_pid_list() का उपयोग करें।
  2. argparse का उपयोग कर अपनी कमांड लाइन डीकोड करें। यह अधिक हो सकता है लेकिन यह मौजूदा पायथन पुस्तकालयों का लाभ उठाता है।
  3. अपनी PID के अनुसार अपना आवेदन धारण करने वाली प्रक्रिया की पहचान करें।

यह एक सरल कार्यान्वयन है।

def kill_proc_kidnapper(self, child_pid, kidnapper_name='WerFault.exe'): 
    """ 
    Look among all instances of 'WerFault.exe' process for an specific one 
    that took control of another faulting process. 
    When 'WerFault.exe' is launched it is specified the PID using -p argument: 

    'C:\\Windows\\SysWOW64\\WerFault.exe -u -p 5012 -s 68' 
          |    | 
          +-> kidnapper +-> child_pid 

    Function uses `argparse` to properly decode process command line and get 
    PID. If PID matches `child_pid` then we have found the correct parent 
    process and can kill it. 
    """ 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-u', action='store_false', help='User name') 
    parser.add_argument('-p', type=int, help='Process ID') 
    parser.add_argument('-s', help='??') 

    kidnapper_p = None 
    child_p = None 

    for proc in psutil.get_pid_list(): 
     if kidnapper_name in proc.name: 
      args, unknown_args = parser.parse_known_args(proc.cmdline) 
      print proc.name, proc.cmdline 

      if args.p == child_pid: 
       # We found the kidnapper, aim. 
       print 'kidnapper found: {0}'.format(proc.pid) 
       kidnapper_p = proc 

    if psutil.pid_exists(child_pid): 
     child_p = psutil.Process(child_pid) 

    if kidnapper_p and child_pid: 
     print 'Killing "{0}" ({1}) that kidnapped "{2}" ({3})'.format(
      kidnapper_p.name, kidnapper_p.pid, child_p.name, child_p.pid) 
     self.taskkill(kidnapper_p.pid) 
     return 1 
    else: 
     if not kidnapper_p: 
      print 'Kidnapper process "{0}" not found'.format(kidnapper_name) 
     if not child_p: 
      print 'Child process "({0})" not found'.format(child_pid) 

    return 0 

अब, taskkill समारोह सही PID साथ taskkill commmand invokes।

def taskkill(self, pid): 
    """ 
    Kill task and entire process tree for this process 
    """ 
    print('Task kill for PID {0}'.format(pid)) 
    cmd = 'taskkill /f /t /pid {0}'.format(pid) 
    subprocess.call(cmd.split()) 
+1

बहुत अच्छा पहला जवाब :) मैं मूल रूप से ऐसा कुछ कर रहा हूं, लेकिन प्रक्रिया को मारने के बजाय मैं नागोस के माध्यम से व्यवस्थापक को सूचित करता हूं ताकि वे क्रैश डंप या ऐसा कर सकें। – Vyktor

-2

मैं करने के लिए के रूप में कोई कारण नहीं दिखाई देता है आपके प्रोग्राम को क्रैश करने की आवश्यकता क्यों है, कोड के अपमानजनक टुकड़े को ढूंढें, और इसे एक कोशिश-कथन में डाल दें।

http://docs.python.org/3.2/tutorial/errors.html#handling-exceptions

+0

समस्या मालिकाना अनुप्रयोग के साथ है जो क्रैश हो रही है। हम इसके बारे में कुछ भी नहीं कर सकते (खराब समर्थन) :( – Vyktor

+0

एप्लिकेशन क्रैश। यह जीवन का एक तथ्य है। भले ही यह आपका आवेदन है और आप दुर्घटना को ठीक कर सकते हैं, यह अक्सर दुर्घटनाओं को संभालने के लिए समझ में आता है। इस मामले में यह तीसरा पक्ष आवेदन है जिसे वैसे भी तय नहीं किया जा सकता है। –

संबंधित मुद्दे