Jak dowiedzieć się, skąd funkcja jest wywoływana (backtrace / stacktrace)?

10

Wystąpił problem polegający na tym, że region jest dezaktywowany (w trybie znaku przejściowego). Funkcja deactivate-markjest wywoływana i chciałbym dowiedzieć się, skąd (i dlaczego) jest ona wywoływana.

Próbowałem M-x debug-on-entry RET deactivate-marki przestało, ale nie znalazłem sposobu, aby dowiedzieć się, kto dzwoni. Cały wyświetlany stacktrace to:

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

Próbowałem, M-x edebug-eval-defunale Edebug też nie pokazuje dzwoniącego.

Jak dowiedzieć się, dlaczego (skąd) deactivate-markjest wywoływany? Szukam funkcjonalności śledzenia wstecznego lub stosu.

EDYTOWAĆ:

advice-addTrick:

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

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

produkuje nilw *Messages*.

Edycja: więcej informacji na temat deactivate-mark: http://emacshorrors.com/posts/deactivate-mark.html

Gracjan Polak
źródło
1
Potrafię odtworzyć opisane zachowanie i wyniki. Uruchom emacs -Q, włącz debugowanie M-x debug-on-entry deactivate-mark, aktywuj znak C-<SPC>, wpisz postać.
Andrew Swann
Możesz doradzić, deactiveate-markkorzystając z funkcji porad, backtrace-framesaby uzyskać widok całego stosu wywołań, jeśli edebug nie pokazuje tego, czego oczekujesz.
Jordon Biondo,
Dodano edycję o advice-addi backtrace-frame. To nie pomogło.
Gracjan Polak
Jeśli chodzi o reprodukcję z @AndrewSwann, warto zauważyć, że wpisanie znaku zwykle działa self-insert-commandi „self-insert-command to interaktywna wbudowana funkcja w„ kodzie źródłowym C ”.” To, wraz z innymi zaobserwowanymi do tej pory zachowaniami, sugeruje, że trzeba będzie debugować gdb.
Joe Corneli
1
Po przeczytaniu pytania brzmiało to, jakby znak został niespodziewanie wyłączony. Tymczasem zachowanie opisane przez @AndrewSwann jest całkowicie oczekiwane (region jest dezaktywowany po wpisaniu czegoś). Jeśli zachowanie, które otrzymujesz, pasuje do zachowania Andrew, wyjaśnij, co chcesz zrobić.
Malabarba

Odpowiedzi:

4

Od command_loop_1w 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
  ...

Wydaje się, że jest to jedyne miejsce, w którym Qdeactivate_markjest się nazywanym src/*.c. Domyślam się, że na to właśnie wpadłeś.


Uwaga: nie jestem ekspertem od Emacsa C. Rozglądałem się gdb --args src/emacs -Qpo przeczytaniu Jak skompilować emacsa za pomocą symboli debugowania? .

Joe Corneli
źródło