प्रोग्रामेटिक रूप से त्रुटि से बैकट्रेस प्राप्त करें


12

यदि कोई त्रुटि Emacs लिस्प कोड में संकेतित है, और debug-on-errorहै t, तो मुझे एक बैकट्रेस बफर मिलता है जो यह पता लगाना आसान बनाता है कि त्रुटि कहां हुई। हालाँकि, त्रुटियों के लिए जो नेटवर्क से एक प्रतिक्रिया को असिंक्रोनस रूप से संसाधित करते समय होती है, यह बैकट्रेस बफर को पॉप अप करने के लिए कष्टप्रद होगा, इसलिए मैं त्रुटि को पकड़ता हूं condition-caseऔर इसे लॉग करता हूं ।

इसलिए जब मैं एक त्रुटि को संभाल रहा हूं condition-case, तो क्या त्रुटि के बिंदु पर बैकट्रेस तक पहुंचने का एक तरीका है? backtraceफ़ंक्शन को कॉल करने से हैंडलर के अंदर कोड का बैकट्रेस हो जाता है, जो कि मैं नहीं देख रहा हूं।

(condition-case e
    (do-something-that-might-fail)
  (error
    (message "%s"
             ;; This gets the wrong backtrace!
             (with-temp-buffer
               (let ((standard-output (current-buffer)))
                 (backtrace)
                 (buffer-string))))))

1
मेरा magithub-errorकार्य ऐसा ही कुछ करता है जो मुझे लगता है, लेकिन मैं अभी कंप्यूटर पर नहीं हूं। यह मदद कर सकता है।
सीन ऑल्रेड

1
यह किसी भी भाषा के साथ एक सामान्य समस्या है जो अपने स्टैक को एक समान तरीके से प्रबंधित करती है। संभाल करने का एक तरीका एक त्रुटि को इंगित करना है जो पहले से ही स्टैक से जुड़ी जानकारी है। आपके मामले में, आपने do-something-that-might-failस्टैक-ट्रेस उत्पन्न किया होगा और इसे उस त्रुटि के साथ संलग्न करेगा जो इसे उठाती है।
wvxvw

1
debbugs.gnu.org/cgi/bugreport.cgi?bug=24617#8 का एक सुझाव है (इसे स्वयं करने की कोशिश नहीं की गई)
npostavs

जवाबों:


1

सबसे आसान काम यह है कि जिस वातावरण में त्रुटि होती है, उसी में अपना डिबगर बनाएं। यह कुछ इस तरह है:

(defun my-debugger (&rest debugger-args)
  (message "BACKTRACE: %s"
           (with-temp-buffer
             (let ((standard-output (current-buffer)))
               (backtrace)
               (buffer-string)))))

(let ((debugger #'my-debugger))
  (foobar)) ; Runs a function with no definition!

letपर्यावरण इस कस्टम डिबगर फ़ंक्शन का उपयोग करता my-debuggerइसके अंदर कोड की अवधि के लिए, इसलिए यदि आप एक गैर-संभाला त्रुटि का सामना करना, "डिबगर" चलेंगे, जो अनिवार्य सिर्फ संदेश बाहर प्रिंट करता है। यह डिबगर उस वातावरण में चलता है जहां त्रुटि हुई थी, इसलिए आपका बैकट्रेस आपको बताएगा कि क्या हुआ था।

नोट: इस कोड में दो (सॉल्वेबल) समस्याएं हैं, जिन्हें मैं आपके लिए छोड़ूंगा। सबसे पहले, आप शायद पहले कुछ स्टैक फ्रेम को बंद करना चाहते हैं, क्योंकि वे के आह्वान से संबंधित हैं backtrace। दूसरा, आपको एक संदेश मिलेगा जो त्रुटि का संकेत देता है (उदाहरण के लिए, ऊपर के मामले में, "चलो: प्रतीक की फ़ंक्शन परिभाषा शून्य है: foobar")। न तो बहुत बड़ी समस्याएं हैं, लेकिन मैं अपनी प्रतिक्रिया को खराब नहीं करना चाहता था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.