Ottieni backtrace dall'errore a livello di codice


12

Se viene segnalato un errore nel codice Lisp di Emacs, ed debug-on-errorè t, ottengo un buffer di backtrace che rende facile capire dove si è verificato l'errore. Tuttavia, per gli errori che si verificano durante l'elaborazione asincrona di una risposta dalla rete, sarebbe fastidioso far apparire il buffer backtrace, quindi preferirei catturare l'errore condition-casee registrarlo.

Quindi, quando sto gestendo un errore condition-case, c'è un modo per ottenere l'accesso al backtrace nel punto dell'errore? Chiamare la backtracefunzione ottiene il backtrace del codice all'interno del gestore, che non è quello che sto cercando.

(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-errorPenso che la mia funzione faccia qualcosa di simile a questo, ma al momento non sono al computer. Può aiutare a prescindere.
Sean Allred,

1
Questo è un problema generale con qualsiasi linguaggio che gestisca il suo stack in modo simile. Un modo per gestirlo è quello di segnalare un errore a cui sono già associate informazioni sullo stack. Vale a dire nel tuo caso, avresti do-something-that-might-failgenerato stack-trace e allegarlo all'errore che genera.
wvxvw,

1
debbugs.gnu.org/cgi/bugreport.cgi?bug=24617#8 ha un suggerimento (non l'ho provato da solo)
npostavs,

Risposte:


1

La cosa più semplice da fare è creare il proprio debugger nell'ambiente in cui si verifica l'errore. Va qualcosa del genere:

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

L' letambiente utilizza questa funzione di debugger personalizzata my-debuggerper la durata del codice al suo interno, quindi se si riscontra un errore non gestito, verrà eseguito il "debugger", che essenzialmente stampa solo il messaggio. Questo debugger viene eseguito nell'ambiente in cui si è verificato l'errore, quindi il backtrace ti dirà cosa è successo.

Nota: questo codice presenta due problemi (risolvibili) che lascerò per te. In primo luogo, probabilmente si desidera eliminare i primi pochi stack frame, poiché riguardano l'invocazione di backtrace. In secondo luogo, verrà visualizzato un messaggio che indica anche l'errore (ad esempio, nel caso precedente, "let: la definizione della funzione del simbolo è nulla: foobar"). Né ci sono enormi problemi, ma non volevo confondere la mia risposta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.