Come scoprire da dove viene chiamata una funzione (backtrace / stacktrace)?


10

Ho riscontrato un problema per cui la regione è disattivata (in modalità contrassegno transitorio). La funzione deactivate-marksi chiama e vorrei scoprire da dove (e perché) viene chiamata.

Ho provato M-x debug-on-entry RET deactivate-marke si interrompe ma non ho trovato il modo di trovare il chiamante. L'intero stacktrace visualizzato è:

Debugger entered--entering a function:
* deactivate-mark()

Ho provato M-x edebug-eval-defunma Edebug non mostra neanche il chiamante.

Come faccio a sapere perché (da dove) deactivate-markviene chiamato? Sono alla ricerca di funzionalità backtrace o stacktrace.

MODIFICARE:

Un advice-addtrucco:

(defun message-show-backtrace ()
  (message "%s" (backtrace-frame 10)))

(advice-add deactivate-mark :before #'message-show-backtrace)

produce nilin *Messages*.

Modifica: maggiori informazioni su deactivate-mark: http://emacshorrors.com/posts/deactivate-mark.html


1
Posso riprodurre il comportamento e l'output descritti. Esegui emacs -Q, attiva il debug M-x debug-on-entry deactivate-mark, attiva il segno C-<SPC>, digita un carattere.
Andrew Swann,

È possibile consigliare deactiveate-marke utilizzare la funzione di avviso backtrace-framesper ottenere una vista dell'intero stack di chiamate se edebug non mostra ciò che ci si aspetta.
Jordon Biondo,

Aggiunta modifica su advice-adde backtrace-frame. Non ha aiutato
Gracjan Polak,

Per quanto riguarda la riproduzione da @AndrewSwann, vale la pena notare che tipicamente viene eseguito un carattere self-insert-commande "il comando di autoinserimento è una funzione integrata interattiva nel" codice sorgente C "." Questo, insieme all'altro comportamento osservato finora, suggerisce che si dovrà eseguire il debug gdb.
Joe Corneli,

1
Dalla lettura della domanda, sembrava che Mark fosse disattivato inaspettatamente. Nel frattempo il comportamento descritto da @AndrewSwann è perfettamente previsto (la regione viene disattivata quando si digita qualcosa). Se il comportamento che ottieni corrisponde a quello di Andrew, ti preghiamo di chiarire cosa vuoi fare.
Malabarba,

Risposte:


4

Da command_loop_1dentro keyboard.c.

  ...
  if (!NILP (BVAR (current_buffer, mark_active))
  && !NILP (Vrun_hooks))
{
  /* In Emacs 22, setting transient-mark-mode to `only' was a
     way of turning it on for just one command.  This usage is
     obsolete, but support it anyway.  */
  if (EQ (Vtransient_mark_mode, Qidentity))
    Vtransient_mark_mode = Qnil;
  else if (EQ (Vtransient_mark_mode, Qonly))
    Vtransient_mark_mode = Qidentity;

  if (!NILP (Vdeactivate_mark))
    /* If `select-active-regions' is non-nil, this call to
       `deactivate-mark' also sets the PRIMARY selection.  */
    call0 (Qdeactivate_mark);
  else
  ...

Quello sembra essere l'unico posto in cui Qdeactivate_markè chiamato in tutti src/*.c. Quindi la mia ipotesi è che questo è quello in cui ti imbatti.


Nota, io non sono un esperto di Emacs C. Ho curiosato con gdb --args src/emacs -Qdopo aver letto Come compilare emacs con i simboli di debug? .

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.