Dapatkan backtrace dari kesalahan secara terprogram

12

Jika kesalahan sinyal dalam kode Emacs Lisp, dan debug-on-erroradalah t, saya mendapatkan buffer backtrace yang membuatnya mudah untuk mencari tahu di mana kesalahan terjadi. Namun, untuk kesalahan yang terjadi saat memproses respons dari jaringan secara tidak sinkron, akan sangat menyebalkan jika buffer backtrace muncul, jadi saya lebih suka menangkap kesalahan dengan condition-casedan mencatatnya.

Jadi ketika saya menangani kesalahan condition-case, apakah ada cara untuk mendapatkan akses ke backtrace di titik kesalahan? Memanggil backtracefungsi mendapat jejak kode di dalam handler, yang bukan yang saya cari.

(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))))))
legoscia
sumber
1
magithub-errorFungsi saya melakukan sesuatu yang mirip dengan ini saya pikir, tapi saya tidak di komputer saat ini. Apa pun itu bisa membantu.
Sean Allred
1
Itu masalah umum dengan bahasa apa pun yang mengelola tumpukannya dengan cara yang sama. Cara untuk mengatasinya adalah dengan memberi sinyal kesalahan yang sudah memiliki informasi tumpukan yang melekat padanya. Misalnya, Anda harus do-something-that-might-failmembuat stack-trace dan melampirkannya pada kesalahan yang ditimbulkannya.
wvxvw
1
debbugs.gnu.org/cgi/bugreport.cgi?bug=24617#8 memiliki saran (belum mencobanya sendiri)
npostavs

Jawaban:

1

Hal termudah untuk dilakukan adalah membuat debugger Anda sendiri di lingkungan di mana kesalahan terjadi. Itu kira-kira seperti ini:

(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!

The letlingkungan menggunakan fungsi debugger kebiasaan ini my-debuggerselama kode di dalamnya, jadi jika Anda menemukan kesalahan un-ditangani, "debugger" akan berjalan, yang pada dasarnya hanya mencetak pesan. Debugger ini berjalan di lingkungan di mana kesalahan terjadi, sehingga backtrace Anda akan memberi tahu Anda apa yang terjadi.

Catatan: Kode ini memiliki dua masalah (yang dapat dipecahkan) yang akan saya tinggalkan untuk Anda. Pertama, Anda mungkin ingin menghapus beberapa frame stack pertama, karena berkaitan dengan permohonan backtrace. Kedua, Anda akan mendapatkan pesan yang juga menunjukkan kesalahan (misalnya, dalam kasus di atas, "biarkan: Definisi fungsi simbol adalah batal: foobar"). Tidak ada masalah besar, tetapi saya tidak ingin mengacaukan respons saya.

cyberbisson
sumber