รับ backtrace จากข้อผิดพลาดทางโปรแกรม


12

หากมีข้อผิดพลาดจะส่งสัญญาณในรหัส Emacs Lisp และdebug-on-errorคือtฉันได้รับบัฟเฟอร์ backtrace ที่ทำให้ง่ายต่อการคิดออกที่เกิดข้อผิดพลาด อย่างไรก็ตามสำหรับข้อผิดพลาดที่เกิดขึ้นขณะประมวลผลการตอบสนองจากเครือข่ายแบบอะซิงโครนัสมันจะน่ารำคาญถ้ามีบัฟเฟอร์ backtrace ปรากฏขึ้นดังนั้นฉันอยากจะจับข้อผิดพลาดด้วยcondition-caseและเข้าสู่ระบบ

ดังนั้นเมื่อฉันจัดการข้อผิดพลาดcondition-caseมีวิธีเข้าถึง backtrace ที่จุดของข้อผิดพลาดหรือไม่? การเรียกใช้backtraceฟังก์ชันรับ 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ฟังก์ชั่นของฉันทำสิ่งที่คล้ายกับที่ฉันคิด แต่ตอนนี้ฉันไม่ได้ใช้คอมพิวเตอร์ มันอาจช่วยโดยไม่คำนึงถึง
ฌอน Allred

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 ของคุณจะบอกคุณว่าเกิดอะไรขึ้น

หมายเหตุ: รหัสนี้มีสองปัญหา (แก้ไขได้) ที่ฉันจะปล่อยให้คุณ ก่อนอื่นคุณอาจต้องการตัดกรอบสแต็กสองสามตัวแรกเนื่องจากเกี่ยวข้องกับการเรียกbacktraceใช้ ประการที่สองคุณจะได้รับข้อความที่ระบุถึงข้อผิดพลาด (เช่นในกรณีข้างต้น "ให้: นิยามฟังก์ชันของสัญลักษณ์เป็นโมฆะ: foobar") ไม่มีปัญหาใหญ่ แต่ฉันไม่ต้องการที่จะตอบสนองของฉันเต็มไปด้วยโคลน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.