Wie finde ich heraus, woher eine Funktion aufgerufen wird (Backtrace / Stacktrace)?

10

Ich habe ein Problem festgestellt, dass die Region deaktiviert ist (im Transient-Mark-Modus). Die Funktion deactivate-markwird aufgerufen und ich möchte herausfinden, woher (und warum) sie aufgerufen wird.

Ich habe es versucht M-x debug-on-entry RET deactivate-markund es hört auf, aber ich habe keine Möglichkeit gefunden, den Anrufer herauszufinden. Die gesamte angezeigte Stapelverfolgung ist:

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

Ich habe es versucht, M-x edebug-eval-defunaber Edebug zeigt den Anrufer auch nicht an.

Wie finde ich heraus, warum (woher) gerufen deactivate-markwird? Ich suche nach Backtrace- oder Stacktrace-Funktionalität.

BEARBEITEN:

Ein advice-addTrick:

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

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

produziert nilin *Messages*.

Bearbeiten: Weitere Informationen zu deactivate-mark: http://emacshorrors.com/posts/deactivate-mark.html

Gracjan Polak
quelle
1
Ich kann das beschriebene Verhalten und die Ausgabe reproduzieren. Ausführen emacs -Q, Debug M-x debug-on-entry deactivate-markaktivieren, Markierung aktivieren, Zeichen eingeben C-<SPC>.
Andrew Swann
Sie können beraten deactiveate-markund in Ihrer Beratungsfunktion verwenden backtrace-frames, um einen Überblick über den gesamten Aufrufstapel zu erhalten, wenn edebug nicht anzeigt, was Sie erwarten.
Jordon Biondo
Bearbeitung über advice-addund hinzugefügt backtrace-frame. Es hat nicht geholfen.
Gracjan Polak
In Bezug auf die Reproduktion von @AndrewSwann ist anzumerken, dass die Eingabe eines Zeichens normalerweise ausgeführt wird self-insert-commandund "Self-Insert-Command eine interaktive integrierte Funktion in 'C-Quellcode' ist." Dies, zusammen mit dem anderen Verhalten, das bisher festgestellt wurde, deutet darauf hin, dass man mit debuggen muss gdb.
Joe Corneli
1
Nach dem Lesen der Frage klang es, als würde Mark unerwartet deaktiviert. In der Zwischenzeit wird das von @AndrewSwann beschriebene Verhalten perfekt erwartet (die Region wird deaktiviert, wenn Sie etwas eingeben). Wenn das Verhalten, das Sie erhalten, mit dem von Andrew übereinstimmt, klären Sie bitte, was Sie tun möchten.
Malabarba

Antworten:

4

Von command_loop_1in 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
  ...

Das scheint der einzige Ort zu sein, an dem Qdeactivate_markin allen aufgerufen wird src/*.c. Ich vermute also, dass dies das ist, worauf Sie stoßen.


Beachten Sie , ich bin kein Experte für Emacs C. Ich stocherte mit gdb --args src/emacs -Qnach dem Lesen Wie Emacs mit Debug - Symbolen zu kompilieren? .

Joe Corneli
quelle