Как узнать, откуда вызывается функция (backtrace / stacktrace)?

10

Я столкнулся с проблемой, что регион деактивирован (в режиме переходных меток). Функция deactivate-markвызывается, и я хотел бы выяснить, откуда (и почему) она вызывается.

Я попытался, M-x debug-on-entry RET deactivate-markи это останавливается, но я не нашел способа узнать звонящего. Вся отображаемая трассировка стека:

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

Я пытался, M-x edebug-eval-defunно Edebug тоже не показывает звонящего.

Как мне узнать, почему (откуда) deactivate-markназывается? Я ищу функциональность backtrace или stacktrace.

РЕДАКТИРОВАТЬ:

advice-addТрюк:

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

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

производит nilв *Messages*.

Изменить: дополнительная информация о deactivate-mark: http://emacshorrors.com/posts/deactivate-mark.html

Грачан Полак
источник
1
Я могу воспроизвести описанное поведение и вывод. Запустите emacs -Q, включите отладку M-x debug-on-entry deactivate-mark, активируйте отметку C-<SPC>, введите символ.
Эндрю Суонн
Вы можете посоветовать deactiveate-markи в своей функции совета использовать backtrace-framesдля просмотра всего стека вызовов, если edebug не показывает то, что вы ожидаете.
Джордон Биондо,
Добавлено редактирование о advice-addи backtrace-frame. Это не помогло.
Грачан Полак
Что касается воспроизведения из @AndrewSwann, то стоит отметить, что типизация символов обычно выполняется, self-insert-commandи «self-insert-command - это интерактивная встроенная функция в« исходном коде C »». Это, вместе с другим поведением, отмеченным до сих пор, предполагает, что с ним придется отлаживать gdb.
Джо Корнели
1
После прочтения вопроса звучало, как будто Марк неожиданно отключается. Между тем поведение, описанное @AndrewSwann, вполне ожидаемо (регион деактивируется, когда вы что-то печатаете). Если поведение, которое вы получаете, соответствует поведению Эндрю, уточните, что вы хотите сделать.
Малабарба

Ответы:

4

Из command_loop_1в 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
  ...

Кажется, это единственное место, где все Qdeactivate_markэто называется src/*.c. Так что я думаю, что это то, что вы сталкиваетесь.


Обратите внимание, я не специалист по Emacs C. Я пошарил с gdb --args src/emacs -Qпосле прочтения Как скомпилировать Emacs с отладочной? ,

Джо Корнели
источник